diff --git a/.nojekyll b/.nojekyll
new file mode 100644
index 0000000..e69de29
diff --git a/CNAME b/CNAME
new file mode 100644
index 0000000..05bb074
--- /dev/null
+++ b/CNAME
@@ -0,0 +1 @@
+lencx.tech
\ No newline at end of file
diff --git a/assets/bg.4189c4f0.png b/assets/bg.4189c4f0.png
new file mode 100644
index 0000000..370dc03
Binary files /dev/null and b/assets/bg.4189c4f0.png differ
diff --git a/assets/error.045b384f.svg b/assets/error.045b384f.svg
new file mode 100644
index 0000000..e08bc2f
--- /dev/null
+++ b/assets/error.045b384f.svg
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/assets/fzj-desc.da5cfda0.svg b/assets/fzj-desc.da5cfda0.svg
new file mode 100644
index 0000000..ca1b847
--- /dev/null
+++ b/assets/fzj-desc.da5cfda0.svg
@@ -0,0 +1,16 @@
+
+
+ {折腾⇌迷茫⇌思考]ing,在路上
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/assets/fzj.08fd6cc8.js b/assets/fzj.08fd6cc8.js
new file mode 100644
index 0000000..277d1b5
--- /dev/null
+++ b/assets/fzj.08fd6cc8.js
@@ -0,0 +1,124 @@
+var e=Object.defineProperty,t=Object.getOwnPropertySymbols,r=Object.prototype.hasOwnProperty,n=Object.prototype.propertyIsEnumerable,o=(t,r,n)=>r in t?e(t,r,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[r]=n;import{R as s,g as a,r as i,h as l,i as c,j as u}from"./react.434ff2b9.js";import{c as f}from"./lodash.71f9f2ff.js";import{g as d,u as p}from"./graphql.8e66ecff.js";import{B as v,p as g,s as m}from"./index.f90eabce.js";function b(e){var t,r,n="";if("string"==typeof e||"number"==typeof e)n+=e;else if("object"==typeof e)if(Array.isArray(e))for(t=0;ts.createElement("svg",{className:y("spinner",e),width:"65px",height:"65px",viewBox:"0 0 66 66",xmlns:"http://www.w3.org/2000/svg"},s.createElement("circle",{className:"path",fill:"none",strokeWidth:"6",strokeLinecap:"round",cx:"33",cy:"33",r:"30"}));const x=({visible:e})=>e?s.createElement("div",{className:"loading-box"},s.createElement(h,{key:"spin"})):null;x.defaultProps={visible:!0};var E=x;const j="https://github.com/lencx/z/discussions",w=({visible:e,issues:t,type:r})=>{const n={blog:["lencx/z",`${j}`],issues:[`lencx/z #${t}`,`${j}/${t}`]}[r];return e?s.createElement("div",{className:"error-box"},s.createElement("div",null,s.createElement("img",{className:"error-icon",src:"/assets/error.045b384f.svg",alt:"Error :("}),s.createElement("p",null,s.createElement("b",null,"温馨提示")),s.createElement("p",null,"因 GitHub API 请求次数限制,暂时无法访问,点击此处可以查看原链接"),s.createElement("p",null,s.createElement("a",{href:n[1]},n[0])))):null};w.defaultProps={visible:!0,type:"blog"};var T=w;var I=function(e){var t=typeof e;return null!=e&&("object"==t||"function"==t)},O="object"==typeof f&&f&&f.Object===Object&&f,S="object"==typeof self&&self&&self.Object===Object&&self,$=O||S||Function("return this")(),L=$,N=function(){return L.Date.now()},A=/\s/;var P=function(e){for(var t=e.length;t--&&A.test(e.charAt(t)););return t},M=/^\s+/;var k=function(e){return e?e.slice(0,P(e)+1).replace(M,""):e},_=$.Symbol,F=_,J=Object.prototype,Z=J.hasOwnProperty,C=J.toString,H=F?F.toStringTag:void 0;var z=function(e){var t=Z.call(e,H),r=e[H];try{e[H]=void 0;var n=!0}catch(s){}var o=C.call(e);return n&&(t?e[H]=r:delete e[H]),o},U=Object.prototype.toString;var q=z,G=function(e){return U.call(e)},W=_?_.toStringTag:void 0;var B=function(e){return null==e?void 0===e?"[object Undefined]":"[object Null]":W&&W in Object(e)?q(e):G(e)},V=function(e){return null!=e&&"object"==typeof e};var D=k,R=I,K=function(e){return"symbol"==typeof e||V(e)&&"[object Symbol]"==B(e)},Q=/^[-+]0x[0-9a-f]+$/i,X=/^0b[01]+$/i,Y=/^0o[0-7]+$/i,ee=parseInt;var te=I,re=N,ne=function(e){if("number"==typeof e)return e;if(K(e))return NaN;if(R(e)){var t="function"==typeof e.valueOf?e.valueOf():e;e=R(t)?t+"":t}if("string"!=typeof e)return 0===e?e:+e;e=D(e);var r=X.test(e);return r||Y.test(e)?ee(e.slice(2),r?2:8):Q.test(e)?NaN:+e},oe=Math.max,se=Math.min;var ae=function(e,t,r){var n,o,s,a,i,l,c=0,u=!1,f=!1,d=!0;if("function"!=typeof e)throw new TypeError("Expected a function");function p(t){var r=n,s=o;return n=o=void 0,c=t,a=e.apply(s,r)}function v(e){return c=e,i=setTimeout(m,t),u?p(e):a}function g(e){var r=e-l;return void 0===l||r>=t||r<0||f&&e-c>=s}function m(){var e=re();if(g(e))return b(e);i=setTimeout(m,function(e){var r=t-(e-l);return f?se(r,s-(e-c)):r}(e))}function b(e){return i=void 0,d&&n?p(e):(n=o=void 0,a)}function y(){var e=re(),r=g(e);if(n=arguments,o=this,l=e,r){if(void 0===i)return v(l);if(f)return clearTimeout(i),i=setTimeout(m,t),p(l)}return void 0===i&&(i=setTimeout(m,t)),a}return t=ne(t)||0,te(r)&&(u=!!r.leading,s=(f="maxWait"in r)?oe(ne(r.maxWait)||0,t):s,d="trailing"in r?!!r.trailing:d),y.cancel=function(){void 0!==i&&clearTimeout(i),c=0,n=l=o=i=void 0},y.flush=function(){return void 0===i?a:b(re())},y};const ie=d`
+ query FZJ_LIST($first: Int, $cursor: String) {
+ repository(name: "z", owner: "lencx") {
+ discussions(first: $first, after: $cursor) {
+ totalCount
+ pageInfo {
+ # startCursor
+ # hasPreviousPage
+ endCursor
+ hasNextPage
+ }
+ edges {
+ cursor
+ node {
+ title
+ number
+ # bodyHTML
+ createdAt
+ updatedAt
+ author {
+ login
+ avatarUrl
+ url
+ }
+ category {
+ name
+ emojiHTML
+ }
+ labels(first: 100) {
+ edges {
+ node {
+ id
+ name
+ color
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+`,le=d`
+ query FZJ_ITEM($number: Int!) {
+ repository(name: "z", owner: "lencx") {
+ discussion(number: $number) {
+ id
+ title
+ bodyHTML
+ createdAt
+ updatedAt
+ category {
+ name
+ }
+ labels(first: 100) {
+ edges {
+ node {
+ id
+ name
+ }
+ }
+ }
+ reactions(first: 100) {
+ totalCount
+ edges {
+ node {
+ id
+ content
+ }
+ }
+ }
+ comments(first: 100) {
+ edges {
+ node {
+ id
+ bodyHTML
+ author {
+ login
+ avatarUrl
+ url
+ }
+ replies(first: 100) {
+ edges {
+ node {
+ id
+ author {
+ login
+ avatarUrl
+ url
+ }
+ bodyHTML
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+`,ce=d`
+ query FZJ_TAGS {
+ repository(name: "z", owner: "lencx") {
+ discussionCategories(first: 20) {
+ edges {
+ node {
+ id
+ name
+ emojiHTML
+ }
+ }
+ }
+ labels(first: 100) {
+ edges {
+ node {
+ id
+ name
+ color
+ }
+ }
+ }
+ }
+ }
+`,ue=a({key:"FZJ_LIST",default:{pageInfo:{},list:[]}}),fe=()=>{const[e,t]=i.exports.useState(null),r=l(ue),n=p(ie,{variables:{first:g,cursor:null}}),[o,s]=r,[a,{loading:c,data:u,error:f}]=n,d=i.exports.useCallback(ae((()=>{m((()=>{o.pageInfo.hasNextPage&&a({variables:{cursor:o.pageInfo.cursor}})}))}),500,{leading:!0}),[o.pageInfo]);return i.exports.useEffect((()=>{(async()=>{if(f){window.removeEventListener("scroll",d,!1);try{const e=await fetch(`${v}/discussions.json`).then((e=>e.json()));s({pageInfo:{},list:e})}catch(e){t(e)}}})()}),[f]),i.exports.useEffect((()=>(window.addEventListener("scroll",d,!1),()=>{window.removeEventListener("scroll",d,!1)})),[o.pageInfo]),i.exports.useEffect((()=>{!o.list.length&&a()}),[]),i.exports.useEffect((()=>{if(u){const{endCursor:e,hasNextPage:t}=u.repository.discussions.pageInfo;s({pageInfo:{cursor:e,hasNextPage:t},list:[...o.list,...u.repository.discussions.edges||[]]})}}),[u]),{data:o.list,loading:c,error:e}},de=a({key:"FZJ_ITEM",default:new Map}),pe=c({key:"FZJ_ITEM_VALUE",get:({get:e})=>e(de)}),ve=e=>{const[t,r]=l(de),[n,o]=i.exports.useState(!1),[s,a]=i.exports.useState(null),[c,f]=p(le,{variables:{number:parseInt(e)}}),d=u(pe);return i.exports.useEffect((()=>{d.has(e)||(o(!0),c())}),[]),i.exports.useEffect((()=>{(async()=>{var n,s;if(f.data)r(t.set(e,null==(s=null==(n=null==f?void 0:f.data)?void 0:n.repository)?void 0:s.discussion)),a(null),o(!1);else try{const n=await fetch(`${v}/issues/${e}.json`).then((e=>e.json()));r(t.set(e,n)),o(!1)}catch(i){a(i)}})()}),[f.data]),{data:t.get(e),loading:n,error:s}},ge=a({key:"FZJ_TAGS",default:{}}),me=c({key:"FZJ_TAGS_VALUE",get:({get:e})=>e(ge)}),be=()=>{const[e,s]=l(ge),a=u(me),[c,f]=p(ce),d=f,{data:v}=d,g=((e,o)=>{var s={};for(var a in e)r.call(e,a)&&o.indexOf(a)<0&&(s[a]=e[a]);if(null!=e&&t)for(var a of t(e))o.indexOf(a)<0&&n.call(e,a)&&(s[a]=e[a]);return s})(d,["data"]);return i.exports.useEffect((()=>{Object.keys(a).length?s(a):c()}),[]),i.exports.useEffect((()=>{v&&s(v)}),[v]),((e,s)=>{for(var a in s||(s={}))r.call(s,a)&&o(e,a,s[a]);if(t)for(var a of t(s))n.call(s,a)&&o(e,a,s[a]);return e})({data:e},g)};export{T as E,E as L,ve as a,be as b,y as c,fe as u};
diff --git a/assets/fzj.271820f2.css b/assets/fzj.271820f2.css
new file mode 100644
index 0000000..50ece75
--- /dev/null
+++ b/assets/fzj.271820f2.css
@@ -0,0 +1 @@
+.spinner{animation:rotator 1.4s linear infinite}@keyframes rotator{0%{transform:rotate(0)}to{transform:rotate(270deg)}}.path{stroke-dasharray:187;stroke-dashoffset:0;transform-origin:center;animation:dash 1.4s ease-in-out infinite,colors 5.6s ease-in-out infinite}@keyframes colors{0%{stroke:#4285f4}25%{stroke:#de3e35}50%{stroke:#f7c223}75%{stroke:#1b9a59}to{stroke:#4285f4}}@keyframes dash{0%{stroke-dashoffset:187}50%{stroke-dashoffset:46.75;transform:rotate(135deg)}to{stroke-dashoffset:187;transform:rotate(450deg)}}.loading-box{position:fixed;width:100%;top:0;left:0;display:flex;height:100%;justify-content:center;align-items:center}.error-box{position:fixed;width:100%;height:100%;top:0;left:0;display:flex;justify-content:center;align-items:center;text-align:center}.error-box .error-icon{width:120px;margin-top:-20vh}.error-box p{max-width:240px;color:#888}
diff --git a/assets/fzj.883a7505.svg b/assets/fzj.883a7505.svg
new file mode 100644
index 0000000..a69119f
--- /dev/null
+++ b/assets/fzj.883a7505.svg
@@ -0,0 +1,4 @@
+
+
\ No newline at end of file
diff --git a/assets/github.cf8a9345.svg b/assets/github.cf8a9345.svg
new file mode 100644
index 0000000..07213b6
--- /dev/null
+++ b/assets/github.cf8a9345.svg
@@ -0,0 +1,5 @@
+
+
+
\ No newline at end of file
diff --git a/assets/graphql.8e66ecff.js b/assets/graphql.8e66ecff.js
new file mode 100644
index 0000000..f632693
--- /dev/null
+++ b/assets/graphql.8e66ecff.js
@@ -0,0 +1,29 @@
+import{R as e,r as t}from"./react.434ff2b9.js";
+/*! *****************************************************************************
+Copyright (c) Microsoft Corporation.
+
+Permission to use, copy, modify, and/or distribute this software for any
+purpose with or without fee is hereby granted.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
+***************************************************************************** */var r=function(e,t){return(r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var r in t)t.hasOwnProperty(r)&&(e[r]=t[r])})(e,t)};function n(e,t){function n(){this.constructor=e}r(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}var i=function(){return(i=Object.assign||function(e){for(var t,r=1,n=arguments.length;r0&&i[i.length-1])||6!==o[0]&&2!==o[0])){a=0;continue}if(3===o[0]&&(!i||o[1]>i[0]&&o[1]=m)return console[e].apply(console,arguments)}}function g(e){return(g="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}(v=d||(d={})).log=b("log"),v.warn=b("warn"),v.error=b("error"),"object"!=typeof process||"object"!=typeof process.env||process;var O="function"==typeof Symbol&&null!=Symbol.toStringTag?Symbol.toStringTag:"@@toStringTag";function E(e,t){for(var r,n=/\r\n|[\n\r]/g,i=1,o=t+1;(r=n.exec(e.body))&&r.index120){for(var p=Math.floor(u/80),h=u%80,d=[],v=0;v",EOF:"",BANG:"!",DOLLAR:"$",AMP:"&",PAREN_L:"(",PAREN_R:")",SPREAD:"...",COLON:":",EQUALS:"=",AT:"@",BRACKET_L:"[",BRACKET_R:"]",BRACE_L:"{",PIPE:"|",BRACE_R:"}",NAME:"Name",INT:"Int",FLOAT:"Float",STRING:"String",BLOCK_STRING:"BlockString",COMMENT:"Comment"});function K(e){return(K="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function z(e){return G(e,[])}function G(e,t){switch(K(e)){case"string":return JSON.stringify(e);case"function":return e.name?"[function ".concat(e.name,"]"):"[function]";case"object":return null===e?"null":function(e,t){if(-1!==t.indexOf(e))return"[Circular]";var r=[].concat(t,[e]),n=function(e){var t=e[String(L)];if("function"==typeof t)return t;if("function"==typeof e.inspect)return e.inspect}(e);if(void 0!==n){var i=n.call(e);if(i!==e)return"string"==typeof i?i:G(i,r)}else if(Array.isArray(e))return function(e,t){if(0===e.length)return"[]";if(t.length>2)return"[Array]";for(var r=Math.min(10,e.length),n=e.length-r,i=[],o=0;o1&&i.push("... ".concat(n," more items"));return"["+i.join(", ")+"]"}(e,r);return function(e,t){var r=Object.keys(e);if(0===r.length)return"{}";if(t.length>2)return"["+function(e){var t=Object.prototype.toString.call(e).replace(/^\[object /,"").replace(/]$/,"");if("Object"===t&&"function"==typeof e.constructor){var r=e.constructor.name;if("string"==typeof r&&""!==r)return r}return t}(e)+"]";return"{ "+r.map((function(r){return r+": "+G(e[r],t)})).join(", ")+" }"}(e,r)}(e,t);default:return String(e)}}function Y(e,t){if(!Boolean(e))throw new Error(t)}function W(e,t){for(var r=0;r1&&void 0!==arguments[1]?arguments[1]:"GraphQL request",r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{line:1,column:1};"string"==typeof e||Y(0,"Body must be a string. Received: ".concat(z(e),".")),this.body=e,this.name=t,this.locationOffset=r,this.locationOffset.line>0||Y(0,"line in locationOffset is 1-indexed and must be positive."),this.locationOffset.column>0||Y(0,"column in locationOffset is 1-indexed and must be positive.")}var t,r,n;return t=e,(r=[{key:O,get:function(){return"Source"}}])&&W(t.prototype,r),n&&W(t,n),e}();var X=Object.freeze({QUERY:"QUERY",MUTATION:"MUTATION",SUBSCRIPTION:"SUBSCRIPTION",FIELD:"FIELD",FRAGMENT_DEFINITION:"FRAGMENT_DEFINITION",FRAGMENT_SPREAD:"FRAGMENT_SPREAD",INLINE_FRAGMENT:"INLINE_FRAGMENT",VARIABLE_DEFINITION:"VARIABLE_DEFINITION",SCHEMA:"SCHEMA",SCALAR:"SCALAR",OBJECT:"OBJECT",FIELD_DEFINITION:"FIELD_DEFINITION",ARGUMENT_DEFINITION:"ARGUMENT_DEFINITION",INTERFACE:"INTERFACE",UNION:"UNION",ENUM:"ENUM",ENUM_VALUE:"ENUM_VALUE",INPUT_OBJECT:"INPUT_OBJECT",INPUT_FIELD_DEFINITION:"INPUT_FIELD_DEFINITION"});function H(e){var t=e.split(/\r\n|[\n\r]/g),r=function(e){for(var t,r=!0,n=!0,i=0,o=null,a=0;ai&&$(t[o-1]);)--o;return t.slice(i,o).join("\n")}function $(e){for(var t=0;t31||9===o));return new V(U.COMMENT,t,s,r,n,i,a.slice(t+1,s))}function ie(e,t,r,n,i,o){var a=e.body,s=r,u=t,c=!1;if(45===s&&(s=a.charCodeAt(++u)),48===s){if((s=a.charCodeAt(++u))>=48&&s<=57)throw M(e,u,"Invalid number, unexpected digit after 0: ".concat(ee(s),"."))}else u=oe(e,u,s),s=a.charCodeAt(u);if(46===s&&(c=!0,s=a.charCodeAt(++u),u=oe(e,u,s),s=a.charCodeAt(u)),69!==s&&101!==s||(c=!0,43!==(s=a.charCodeAt(++u))&&45!==s||(s=a.charCodeAt(++u)),u=oe(e,u,s),s=a.charCodeAt(u)),46===s||function(e){return 95===e||e>=65&&e<=90||e>=97&&e<=122}(s))throw M(e,u,"Invalid number, expected digit but got: ".concat(ee(s),"."));return new V(c?U.FLOAT:U.INT,t,u,n,i,o,a.slice(t,u))}function oe(e,t,r){var n=e.body,i=t,o=r;if(o>=48&&o<=57){do{o=n.charCodeAt(++i)}while(o>=48&&o<=57);return i}throw M(e,i,"Invalid number, expected digit but got: ".concat(ee(o),"."))}function ae(e,t,r,n,i){for(var o,a,s,u,c=e.body,l=t+1,f=l,p=0,h="";l=48&&e<=57?e-48:e>=65&&e<=70?e-55:e>=97&&e<=102?e-87:-1}function ce(e,t,r,n,i){for(var o=e.body,a=o.length,s=t+1,u=0;s!==a&&!isNaN(u=o.charCodeAt(s))&&(95===u||u>=48&&u<=57||u>=65&&u<=90||u>=97&&u<=122);)++s;return new V(U.NAME,t,s,r,n,i,o.slice(t,s))}var le=function(){function e(e,t){var r=function(e){return e instanceof J}(e)?e:new J(e);this._lexer=new Z(r),this._options=t}var t=e.prototype;return t.parseName=function(){var e=this.expectToken(U.NAME);return{kind:j.NAME,value:e.value,loc:this.loc(e)}},t.parseDocument=function(){var e=this._lexer.token;return{kind:j.DOCUMENT,definitions:this.many(U.SOF,this.parseDefinition,U.EOF),loc:this.loc(e)}},t.parseDefinition=function(){if(this.peek(U.NAME))switch(this._lexer.token.value){case"query":case"mutation":case"subscription":return this.parseOperationDefinition();case"fragment":return this.parseFragmentDefinition();case"schema":case"scalar":case"type":case"interface":case"union":case"enum":case"input":case"directive":return this.parseTypeSystemDefinition();case"extend":return this.parseTypeSystemExtension()}else{if(this.peek(U.BRACE_L))return this.parseOperationDefinition();if(this.peekDescription())return this.parseTypeSystemDefinition()}throw this.unexpected()},t.parseOperationDefinition=function(){var e=this._lexer.token;if(this.peek(U.BRACE_L))return{kind:j.OPERATION_DEFINITION,operation:"query",name:void 0,variableDefinitions:[],directives:[],selectionSet:this.parseSelectionSet(),loc:this.loc(e)};var t,r=this.parseOperationType();return this.peek(U.NAME)&&(t=this.parseName()),{kind:j.OPERATION_DEFINITION,operation:r,name:t,variableDefinitions:this.parseVariableDefinitions(),directives:this.parseDirectives(!1),selectionSet:this.parseSelectionSet(),loc:this.loc(e)}},t.parseOperationType=function(){var e=this.expectToken(U.NAME);switch(e.value){case"query":return"query";case"mutation":return"mutation";case"subscription":return"subscription"}throw this.unexpected(e)},t.parseVariableDefinitions=function(){return this.optionalMany(U.PAREN_L,this.parseVariableDefinition,U.PAREN_R)},t.parseVariableDefinition=function(){var e=this._lexer.token;return{kind:j.VARIABLE_DEFINITION,variable:this.parseVariable(),type:(this.expectToken(U.COLON),this.parseTypeReference()),defaultValue:this.expectOptionalToken(U.EQUALS)?this.parseValueLiteral(!0):void 0,directives:this.parseDirectives(!0),loc:this.loc(e)}},t.parseVariable=function(){var e=this._lexer.token;return this.expectToken(U.DOLLAR),{kind:j.VARIABLE,name:this.parseName(),loc:this.loc(e)}},t.parseSelectionSet=function(){var e=this._lexer.token;return{kind:j.SELECTION_SET,selections:this.many(U.BRACE_L,this.parseSelection,U.BRACE_R),loc:this.loc(e)}},t.parseSelection=function(){return this.peek(U.SPREAD)?this.parseFragment():this.parseField()},t.parseField=function(){var e,t,r=this._lexer.token,n=this.parseName();return this.expectOptionalToken(U.COLON)?(e=n,t=this.parseName()):t=n,{kind:j.FIELD,alias:e,name:t,arguments:this.parseArguments(!1),directives:this.parseDirectives(!1),selectionSet:this.peek(U.BRACE_L)?this.parseSelectionSet():void 0,loc:this.loc(r)}},t.parseArguments=function(e){var t=e?this.parseConstArgument:this.parseArgument;return this.optionalMany(U.PAREN_L,t,U.PAREN_R)},t.parseArgument=function(){var e=this._lexer.token,t=this.parseName();return this.expectToken(U.COLON),{kind:j.ARGUMENT,name:t,value:this.parseValueLiteral(!1),loc:this.loc(e)}},t.parseConstArgument=function(){var e=this._lexer.token;return{kind:j.ARGUMENT,name:this.parseName(),value:(this.expectToken(U.COLON),this.parseValueLiteral(!0)),loc:this.loc(e)}},t.parseFragment=function(){var e=this._lexer.token;this.expectToken(U.SPREAD);var t=this.expectOptionalKeyword("on");return!t&&this.peek(U.NAME)?{kind:j.FRAGMENT_SPREAD,name:this.parseFragmentName(),directives:this.parseDirectives(!1),loc:this.loc(e)}:{kind:j.INLINE_FRAGMENT,typeCondition:t?this.parseNamedType():void 0,directives:this.parseDirectives(!1),selectionSet:this.parseSelectionSet(),loc:this.loc(e)}},t.parseFragmentDefinition=function(){var e,t=this._lexer.token;return this.expectKeyword("fragment"),!0===(null===(e=this._options)||void 0===e?void 0:e.experimentalFragmentVariables)?{kind:j.FRAGMENT_DEFINITION,name:this.parseFragmentName(),variableDefinitions:this.parseVariableDefinitions(),typeCondition:(this.expectKeyword("on"),this.parseNamedType()),directives:this.parseDirectives(!1),selectionSet:this.parseSelectionSet(),loc:this.loc(t)}:{kind:j.FRAGMENT_DEFINITION,name:this.parseFragmentName(),typeCondition:(this.expectKeyword("on"),this.parseNamedType()),directives:this.parseDirectives(!1),selectionSet:this.parseSelectionSet(),loc:this.loc(t)}},t.parseFragmentName=function(){if("on"===this._lexer.token.value)throw this.unexpected();return this.parseName()},t.parseValueLiteral=function(e){var t=this._lexer.token;switch(t.kind){case U.BRACKET_L:return this.parseList(e);case U.BRACE_L:return this.parseObject(e);case U.INT:return this._lexer.advance(),{kind:j.INT,value:t.value,loc:this.loc(t)};case U.FLOAT:return this._lexer.advance(),{kind:j.FLOAT,value:t.value,loc:this.loc(t)};case U.STRING:case U.BLOCK_STRING:return this.parseStringLiteral();case U.NAME:switch(this._lexer.advance(),t.value){case"true":return{kind:j.BOOLEAN,value:!0,loc:this.loc(t)};case"false":return{kind:j.BOOLEAN,value:!1,loc:this.loc(t)};case"null":return{kind:j.NULL,loc:this.loc(t)};default:return{kind:j.ENUM,value:t.value,loc:this.loc(t)}}case U.DOLLAR:if(!e)return this.parseVariable()}throw this.unexpected()},t.parseStringLiteral=function(){var e=this._lexer.token;return this._lexer.advance(),{kind:j.STRING,value:e.value,block:e.kind===U.BLOCK_STRING,loc:this.loc(e)}},t.parseList=function(e){var t=this,r=this._lexer.token;return{kind:j.LIST,values:this.any(U.BRACKET_L,(function(){return t.parseValueLiteral(e)}),U.BRACKET_R),loc:this.loc(r)}},t.parseObject=function(e){var t=this,r=this._lexer.token;return{kind:j.OBJECT,fields:this.any(U.BRACE_L,(function(){return t.parseObjectField(e)}),U.BRACE_R),loc:this.loc(r)}},t.parseObjectField=function(e){var t=this._lexer.token,r=this.parseName();return this.expectToken(U.COLON),{kind:j.OBJECT_FIELD,name:r,value:this.parseValueLiteral(e),loc:this.loc(t)}},t.parseDirectives=function(e){for(var t=[];this.peek(U.AT);)t.push(this.parseDirective(e));return t},t.parseDirective=function(e){var t=this._lexer.token;return this.expectToken(U.AT),{kind:j.DIRECTIVE,name:this.parseName(),arguments:this.parseArguments(e),loc:this.loc(t)}},t.parseTypeReference=function(){var e,t=this._lexer.token;return this.expectOptionalToken(U.BRACKET_L)?(e=this.parseTypeReference(),this.expectToken(U.BRACKET_R),e={kind:j.LIST_TYPE,type:e,loc:this.loc(t)}):e=this.parseNamedType(),this.expectOptionalToken(U.BANG)?{kind:j.NON_NULL_TYPE,type:e,loc:this.loc(t)}:e},t.parseNamedType=function(){var e=this._lexer.token;return{kind:j.NAMED_TYPE,name:this.parseName(),loc:this.loc(e)}},t.parseTypeSystemDefinition=function(){var e=this.peekDescription()?this._lexer.lookahead():this._lexer.token;if(e.kind===U.NAME)switch(e.value){case"schema":return this.parseSchemaDefinition();case"scalar":return this.parseScalarTypeDefinition();case"type":return this.parseObjectTypeDefinition();case"interface":return this.parseInterfaceTypeDefinition();case"union":return this.parseUnionTypeDefinition();case"enum":return this.parseEnumTypeDefinition();case"input":return this.parseInputObjectTypeDefinition();case"directive":return this.parseDirectiveDefinition()}throw this.unexpected(e)},t.peekDescription=function(){return this.peek(U.STRING)||this.peek(U.BLOCK_STRING)},t.parseDescription=function(){if(this.peekDescription())return this.parseStringLiteral()},t.parseSchemaDefinition=function(){var e=this._lexer.token,t=this.parseDescription();this.expectKeyword("schema");var r=this.parseDirectives(!0),n=this.many(U.BRACE_L,this.parseOperationTypeDefinition,U.BRACE_R);return{kind:j.SCHEMA_DEFINITION,description:t,directives:r,operationTypes:n,loc:this.loc(e)}},t.parseOperationTypeDefinition=function(){var e=this._lexer.token,t=this.parseOperationType();this.expectToken(U.COLON);var r=this.parseNamedType();return{kind:j.OPERATION_TYPE_DEFINITION,operation:t,type:r,loc:this.loc(e)}},t.parseScalarTypeDefinition=function(){var e=this._lexer.token,t=this.parseDescription();this.expectKeyword("scalar");var r=this.parseName(),n=this.parseDirectives(!0);return{kind:j.SCALAR_TYPE_DEFINITION,description:t,name:r,directives:n,loc:this.loc(e)}},t.parseObjectTypeDefinition=function(){var e=this._lexer.token,t=this.parseDescription();this.expectKeyword("type");var r=this.parseName(),n=this.parseImplementsInterfaces(),i=this.parseDirectives(!0),o=this.parseFieldsDefinition();return{kind:j.OBJECT_TYPE_DEFINITION,description:t,name:r,interfaces:n,directives:i,fields:o,loc:this.loc(e)}},t.parseImplementsInterfaces=function(){var e;if(!this.expectOptionalKeyword("implements"))return[];if(!0===(null===(e=this._options)||void 0===e?void 0:e.allowLegacySDLImplementsInterfaces)){var t=[];this.expectOptionalToken(U.AMP);do{t.push(this.parseNamedType())}while(this.expectOptionalToken(U.AMP)||this.peek(U.NAME));return t}return this.delimitedMany(U.AMP,this.parseNamedType)},t.parseFieldsDefinition=function(){var e;return!0===(null===(e=this._options)||void 0===e?void 0:e.allowLegacySDLEmptyFields)&&this.peek(U.BRACE_L)&&this._lexer.lookahead().kind===U.BRACE_R?(this._lexer.advance(),this._lexer.advance(),[]):this.optionalMany(U.BRACE_L,this.parseFieldDefinition,U.BRACE_R)},t.parseFieldDefinition=function(){var e=this._lexer.token,t=this.parseDescription(),r=this.parseName(),n=this.parseArgumentDefs();this.expectToken(U.COLON);var i=this.parseTypeReference(),o=this.parseDirectives(!0);return{kind:j.FIELD_DEFINITION,description:t,name:r,arguments:n,type:i,directives:o,loc:this.loc(e)}},t.parseArgumentDefs=function(){return this.optionalMany(U.PAREN_L,this.parseInputValueDef,U.PAREN_R)},t.parseInputValueDef=function(){var e=this._lexer.token,t=this.parseDescription(),r=this.parseName();this.expectToken(U.COLON);var n,i=this.parseTypeReference();this.expectOptionalToken(U.EQUALS)&&(n=this.parseValueLiteral(!0));var o=this.parseDirectives(!0);return{kind:j.INPUT_VALUE_DEFINITION,description:t,name:r,type:i,defaultValue:n,directives:o,loc:this.loc(e)}},t.parseInterfaceTypeDefinition=function(){var e=this._lexer.token,t=this.parseDescription();this.expectKeyword("interface");var r=this.parseName(),n=this.parseImplementsInterfaces(),i=this.parseDirectives(!0),o=this.parseFieldsDefinition();return{kind:j.INTERFACE_TYPE_DEFINITION,description:t,name:r,interfaces:n,directives:i,fields:o,loc:this.loc(e)}},t.parseUnionTypeDefinition=function(){var e=this._lexer.token,t=this.parseDescription();this.expectKeyword("union");var r=this.parseName(),n=this.parseDirectives(!0),i=this.parseUnionMemberTypes();return{kind:j.UNION_TYPE_DEFINITION,description:t,name:r,directives:n,types:i,loc:this.loc(e)}},t.parseUnionMemberTypes=function(){return this.expectOptionalToken(U.EQUALS)?this.delimitedMany(U.PIPE,this.parseNamedType):[]},t.parseEnumTypeDefinition=function(){var e=this._lexer.token,t=this.parseDescription();this.expectKeyword("enum");var r=this.parseName(),n=this.parseDirectives(!0),i=this.parseEnumValuesDefinition();return{kind:j.ENUM_TYPE_DEFINITION,description:t,name:r,directives:n,values:i,loc:this.loc(e)}},t.parseEnumValuesDefinition=function(){return this.optionalMany(U.BRACE_L,this.parseEnumValueDefinition,U.BRACE_R)},t.parseEnumValueDefinition=function(){var e=this._lexer.token,t=this.parseDescription(),r=this.parseName(),n=this.parseDirectives(!0);return{kind:j.ENUM_VALUE_DEFINITION,description:t,name:r,directives:n,loc:this.loc(e)}},t.parseInputObjectTypeDefinition=function(){var e=this._lexer.token,t=this.parseDescription();this.expectKeyword("input");var r=this.parseName(),n=this.parseDirectives(!0),i=this.parseInputFieldsDefinition();return{kind:j.INPUT_OBJECT_TYPE_DEFINITION,description:t,name:r,directives:n,fields:i,loc:this.loc(e)}},t.parseInputFieldsDefinition=function(){return this.optionalMany(U.BRACE_L,this.parseInputValueDef,U.BRACE_R)},t.parseTypeSystemExtension=function(){var e=this._lexer.lookahead();if(e.kind===U.NAME)switch(e.value){case"schema":return this.parseSchemaExtension();case"scalar":return this.parseScalarTypeExtension();case"type":return this.parseObjectTypeExtension();case"interface":return this.parseInterfaceTypeExtension();case"union":return this.parseUnionTypeExtension();case"enum":return this.parseEnumTypeExtension();case"input":return this.parseInputObjectTypeExtension()}throw this.unexpected(e)},t.parseSchemaExtension=function(){var e=this._lexer.token;this.expectKeyword("extend"),this.expectKeyword("schema");var t=this.parseDirectives(!0),r=this.optionalMany(U.BRACE_L,this.parseOperationTypeDefinition,U.BRACE_R);if(0===t.length&&0===r.length)throw this.unexpected();return{kind:j.SCHEMA_EXTENSION,directives:t,operationTypes:r,loc:this.loc(e)}},t.parseScalarTypeExtension=function(){var e=this._lexer.token;this.expectKeyword("extend"),this.expectKeyword("scalar");var t=this.parseName(),r=this.parseDirectives(!0);if(0===r.length)throw this.unexpected();return{kind:j.SCALAR_TYPE_EXTENSION,name:t,directives:r,loc:this.loc(e)}},t.parseObjectTypeExtension=function(){var e=this._lexer.token;this.expectKeyword("extend"),this.expectKeyword("type");var t=this.parseName(),r=this.parseImplementsInterfaces(),n=this.parseDirectives(!0),i=this.parseFieldsDefinition();if(0===r.length&&0===n.length&&0===i.length)throw this.unexpected();return{kind:j.OBJECT_TYPE_EXTENSION,name:t,interfaces:r,directives:n,fields:i,loc:this.loc(e)}},t.parseInterfaceTypeExtension=function(){var e=this._lexer.token;this.expectKeyword("extend"),this.expectKeyword("interface");var t=this.parseName(),r=this.parseImplementsInterfaces(),n=this.parseDirectives(!0),i=this.parseFieldsDefinition();if(0===r.length&&0===n.length&&0===i.length)throw this.unexpected();return{kind:j.INTERFACE_TYPE_EXTENSION,name:t,interfaces:r,directives:n,fields:i,loc:this.loc(e)}},t.parseUnionTypeExtension=function(){var e=this._lexer.token;this.expectKeyword("extend"),this.expectKeyword("union");var t=this.parseName(),r=this.parseDirectives(!0),n=this.parseUnionMemberTypes();if(0===r.length&&0===n.length)throw this.unexpected();return{kind:j.UNION_TYPE_EXTENSION,name:t,directives:r,types:n,loc:this.loc(e)}},t.parseEnumTypeExtension=function(){var e=this._lexer.token;this.expectKeyword("extend"),this.expectKeyword("enum");var t=this.parseName(),r=this.parseDirectives(!0),n=this.parseEnumValuesDefinition();if(0===r.length&&0===n.length)throw this.unexpected();return{kind:j.ENUM_TYPE_EXTENSION,name:t,directives:r,values:n,loc:this.loc(e)}},t.parseInputObjectTypeExtension=function(){var e=this._lexer.token;this.expectKeyword("extend"),this.expectKeyword("input");var t=this.parseName(),r=this.parseDirectives(!0),n=this.parseInputFieldsDefinition();if(0===r.length&&0===n.length)throw this.unexpected();return{kind:j.INPUT_OBJECT_TYPE_EXTENSION,name:t,directives:r,fields:n,loc:this.loc(e)}},t.parseDirectiveDefinition=function(){var e=this._lexer.token,t=this.parseDescription();this.expectKeyword("directive"),this.expectToken(U.AT);var r=this.parseName(),n=this.parseArgumentDefs(),i=this.expectOptionalKeyword("repeatable");this.expectKeyword("on");var o=this.parseDirectiveLocations();return{kind:j.DIRECTIVE_DEFINITION,description:t,name:r,arguments:n,repeatable:i,locations:o,loc:this.loc(e)}},t.parseDirectiveLocations=function(){return this.delimitedMany(U.PIPE,this.parseDirectiveLocation)},t.parseDirectiveLocation=function(){var e=this._lexer.token,t=this.parseName();if(void 0!==X[t.value])return t;throw this.unexpected(e)},t.loc=function(e){var t;if(!0!==(null===(t=this._options)||void 0===t?void 0:t.noLocation))return new Q(e,this._lexer.lastToken,this._lexer.source)},t.peek=function(e){return this._lexer.token.kind===e},t.expectToken=function(e){var t=this._lexer.token;if(t.kind===e)return this._lexer.advance(),t;throw M(this._lexer.source,t.start,"Expected ".concat(pe(e),", found ").concat(fe(t),"."))},t.expectOptionalToken=function(e){var t=this._lexer.token;if(t.kind===e)return this._lexer.advance(),t},t.expectKeyword=function(e){var t=this._lexer.token;if(t.kind!==U.NAME||t.value!==e)throw M(this._lexer.source,t.start,'Expected "'.concat(e,'", found ').concat(fe(t),"."));this._lexer.advance()},t.expectOptionalKeyword=function(e){var t=this._lexer.token;return t.kind===U.NAME&&t.value===e&&(this._lexer.advance(),!0)},t.unexpected=function(e){var t=null!=e?e:this._lexer.token;return M(this._lexer.source,t.start,"Unexpected ".concat(fe(t),"."))},t.any=function(e,t,r){this.expectToken(e);for(var n=[];!this.expectOptionalToken(r);)n.push(t.call(this));return n},t.optionalMany=function(e,t,r){if(this.expectOptionalToken(e)){var n=[];do{n.push(t.call(this))}while(!this.expectOptionalToken(r));return n}return[]},t.many=function(e,t,r){this.expectToken(e);var n=[];do{n.push(t.call(this))}while(!this.expectOptionalToken(r));return n},t.delimitedMany=function(e,t){this.expectOptionalToken(e);var r=[];do{r.push(t.call(this))}while(this.expectOptionalToken(e));return r},e}();function fe(e){var t=e.value;return pe(e.kind)+(null!=t?' "'.concat(t,'"'):"")}function pe(e){return function(e){return e===U.BANG||e===U.DOLLAR||e===U.AMP||e===U.PAREN_L||e===U.PAREN_R||e===U.SPREAD||e===U.COLON||e===U.EQUALS||e===U.AT||e===U.BRACKET_L||e===U.BRACKET_R||e===U.BRACE_L||e===U.PIPE||e===U.BRACE_R}(e)?'"'.concat(e,'"'):e}var he={Name:[],Document:["definitions"],OperationDefinition:["name","variableDefinitions","directives","selectionSet"],VariableDefinition:["variable","type","defaultValue","directives"],Variable:["name"],SelectionSet:["selections"],Field:["alias","name","arguments","directives","selectionSet"],Argument:["name","value"],FragmentSpread:["name","directives"],InlineFragment:["typeCondition","directives","selectionSet"],FragmentDefinition:["name","variableDefinitions","typeCondition","directives","selectionSet"],IntValue:[],FloatValue:[],StringValue:[],BooleanValue:[],NullValue:[],EnumValue:[],ListValue:["values"],ObjectValue:["fields"],ObjectField:["name","value"],Directive:["name","arguments"],NamedType:["name"],ListType:["type"],NonNullType:["type"],SchemaDefinition:["description","directives","operationTypes"],OperationTypeDefinition:["type"],ScalarTypeDefinition:["description","name","directives"],ObjectTypeDefinition:["description","name","interfaces","directives","fields"],FieldDefinition:["description","name","arguments","type","directives"],InputValueDefinition:["description","name","type","defaultValue","directives"],InterfaceTypeDefinition:["description","name","interfaces","directives","fields"],UnionTypeDefinition:["description","name","directives","types"],EnumTypeDefinition:["description","name","directives","values"],EnumValueDefinition:["description","name","directives"],InputObjectTypeDefinition:["description","name","directives","fields"],DirectiveDefinition:["description","name","arguments","locations"],SchemaExtension:["directives","operationTypes"],ScalarTypeExtension:["name","directives"],ObjectTypeExtension:["name","interfaces","directives","fields"],InterfaceTypeExtension:["name","interfaces","directives","fields"],UnionTypeExtension:["name","directives","types"],EnumTypeExtension:["name","directives","values"],InputObjectTypeExtension:["name","directives","fields"]},de=Object.freeze({});function ve(e,t){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:he,n=void 0,i=Array.isArray(e),o=[e],a=-1,s=[],u=void 0,c=void 0,l=void 0,f=[],p=[],h=e;do{var d=++a===o.length,v=d&&0!==s.length;if(d){if(c=0===p.length?void 0:f[f.length-1],u=l,l=p.pop(),v){if(i)u=u.slice();else{for(var y={},m=0,b=Object.keys(u);m80&&(s=a+we("(\n",Se(Oe(n,"\n")),"\n)")),Oe([s,Oe(i," "),o]," ")},Argument:function(e){return e.name+": "+e.value},FragmentSpread:function(e){return"..."+e.name+we(" ",Oe(e.directives," "))},InlineFragment:function(e){var t=e.typeCondition,r=e.directives,n=e.selectionSet;return Oe(["...",we("on ",t),Oe(r," "),n]," ")},FragmentDefinition:function(e){var t=e.name,r=e.typeCondition,n=e.variableDefinitions,i=e.directives,o=e.selectionSet;return"fragment ".concat(t).concat(we("(",Oe(n,", "),")")," ")+"on ".concat(r," ").concat(we("",Oe(i," ")," "))+o},IntValue:function(e){return e.value},FloatValue:function(e){return e.value},StringValue:function(e,t){var r=e.value;return e.block?function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",r=arguments.length>2&&void 0!==arguments[2]&&arguments[2],n=-1===e.indexOf("\n"),i=" "===e[0]||"\t"===e[0],o='"'===e[e.length-1],a="\\"===e[e.length-1],s=!n||o||a||r,u="";return!s||n&&i||(u+="\n"+t),u+=t?e.replace(/\n/g,"\n"+t):e,s&&(u+="\n"),'"""'+u.replace(/"""/g,'\\"""')+'"""'}(r,"description"===t?"":" "):JSON.stringify(r)},BooleanValue:function(e){return e.value?"true":"false"},NullValue:function(){return"null"},EnumValue:function(e){return e.value},ListValue:function(e){return"["+Oe(e.values,", ")+"]"},ObjectValue:function(e){return"{"+Oe(e.fields,", ")+"}"},ObjectField:function(e){return e.name+": "+e.value},Directive:function(e){return"@"+e.name+we("(",Oe(e.arguments,", "),")")},NamedType:function(e){return e.name},ListType:function(e){return"["+e.type+"]"},NonNullType:function(e){return e.type+"!"},SchemaDefinition:ge((function(e){var t=e.directives,r=e.operationTypes;return Oe(["schema",Oe(t," "),Ee(r)]," ")})),OperationTypeDefinition:function(e){return e.operation+": "+e.type},ScalarTypeDefinition:ge((function(e){return Oe(["scalar",e.name,Oe(e.directives," ")]," ")})),ObjectTypeDefinition:ge((function(e){var t=e.name,r=e.interfaces,n=e.directives,i=e.fields;return Oe(["type",t,we("implements ",Oe(r," & ")),Oe(n," "),Ee(i)]," ")})),FieldDefinition:ge((function(e){var t=e.name,r=e.arguments,n=e.type,i=e.directives;return t+(Te(r)?we("(\n",Se(Oe(r,"\n")),"\n)"):we("(",Oe(r,", "),")"))+": "+n+we(" ",Oe(i," "))})),InputValueDefinition:ge((function(e){var t=e.name,r=e.type,n=e.defaultValue,i=e.directives;return Oe([t+": "+r,we("= ",n),Oe(i," ")]," ")})),InterfaceTypeDefinition:ge((function(e){var t=e.name,r=e.interfaces,n=e.directives,i=e.fields;return Oe(["interface",t,we("implements ",Oe(r," & ")),Oe(n," "),Ee(i)]," ")})),UnionTypeDefinition:ge((function(e){var t=e.name,r=e.directives,n=e.types;return Oe(["union",t,Oe(r," "),n&&0!==n.length?"= "+Oe(n," | "):""]," ")})),EnumTypeDefinition:ge((function(e){var t=e.name,r=e.directives,n=e.values;return Oe(["enum",t,Oe(r," "),Ee(n)]," ")})),EnumValueDefinition:ge((function(e){return Oe([e.name,Oe(e.directives," ")]," ")})),InputObjectTypeDefinition:ge((function(e){var t=e.name,r=e.directives,n=e.fields;return Oe(["input",t,Oe(r," "),Ee(n)]," ")})),DirectiveDefinition:ge((function(e){var t=e.name,r=e.arguments,n=e.repeatable,i=e.locations;return"directive @"+t+(Te(r)?we("(\n",Se(Oe(r,"\n")),"\n)"):we("(",Oe(r,", "),")"))+(n?" repeatable":"")+" on "+Oe(i," | ")})),SchemaExtension:function(e){var t=e.directives,r=e.operationTypes;return Oe(["extend schema",Oe(t," "),Ee(r)]," ")},ScalarTypeExtension:function(e){return Oe(["extend scalar",e.name,Oe(e.directives," ")]," ")},ObjectTypeExtension:function(e){var t=e.name,r=e.interfaces,n=e.directives,i=e.fields;return Oe(["extend type",t,we("implements ",Oe(r," & ")),Oe(n," "),Ee(i)]," ")},InterfaceTypeExtension:function(e){var t=e.name,r=e.interfaces,n=e.directives,i=e.fields;return Oe(["extend interface",t,we("implements ",Oe(r," & ")),Oe(n," "),Ee(i)]," ")},UnionTypeExtension:function(e){var t=e.name,r=e.directives,n=e.types;return Oe(["extend union",t,Oe(r," "),n&&0!==n.length?"= "+Oe(n," | "):""]," ")},EnumTypeExtension:function(e){var t=e.name,r=e.directives,n=e.values;return Oe(["extend enum",t,Oe(r," "),Ee(n)]," ")},InputObjectTypeExtension:function(e){var t=e.name,r=e.directives,n=e.fields;return Oe(["extend input",t,Oe(r," "),Ee(n)]," ")}};function ge(e){return function(t){return Oe([t.description,e(t)],"\n")}}function Oe(e){var t,r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";return null!==(t=null==e?void 0:e.filter((function(e){return e})).join(r))&&void 0!==t?t:""}function Ee(e){return we("{\n",Se(Oe(e,"\n")),"\n}")}function we(e,t){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"";return null!=t&&""!==t?e+t+r:""}function Se(e){return we(" ",e.replace(/\n/g,"\n "))}function ke(e){return-1!==e.indexOf("\n")}function Te(e){return null!=e&&e.some(ke)}function xe(e,t){var r=e.directives;return!r||!r.length||function(e){var t=[];e&&e.length&&e.forEach((function(e){if(function(e){var t=e.name.value;return"skip"===t||"include"===t}(e)){var r=e.arguments;e.name.value,d(r&&1===r.length,39);var n=r[0];d(n.name&&"if"===n.name.value,40);var i=n.value;d(i&&("Variable"===i.kind||"BooleanValue"===i.kind),41),t.push({directive:e,ifArgument:n})}}));return t}(r).every((function(e){var r=e.directive,n=e.ifArgument,i=!1;return"Variable"===n.value.kind?d(void 0!==(i=t&&t[n.value.name.value]),38):i=n.value.value,"skip"===r.name.value?!i:i}))}function Ne(e,t){return function(e){var t=[];return ve(e,{Directive:function(e){t.push(e.name.value)}}),t}(t).some((function(t){return e.indexOf(t)>-1}))}function Ie(e){return e&&Ne(["client"],e)&&Ne(["export"],e)}function _e(e,t){var r=t,n=[];return e.definitions.forEach((function(e){if("OperationDefinition"===e.kind)throw new h(42);"FragmentDefinition"===e.kind&&n.push(e)})),void 0===r&&(d(1===n.length,43),r=n[0].name.value),i(i({},e),{definitions:u([{kind:"OperationDefinition",operation:"query",selectionSet:{kind:"SelectionSet",selections:[{kind:"FragmentSpread",name:{kind:"Name",value:r}}]}}],e.definitions)})}function De(e){void 0===e&&(e=[]);var t={};return e.forEach((function(e){t[e.name.value]=e})),t}function Ae(e,t){switch(e.kind){case"InlineFragment":return e;case"FragmentSpread":var r=t&&t[e.name.value];return d(r,44),r;default:return null}}function Re(e){return{__ref:String(e)}}function Fe(e){return Boolean(e&&"object"==typeof e&&"string"==typeof e.__ref)}function Ce(e,t,r,n){if(function(e){return"IntValue"===e.kind}(r)||function(e){return"FloatValue"===e.kind}(r))e[t.value]=Number(r.value);else if(function(e){return"BooleanValue"===e.kind}(r)||function(e){return"StringValue"===e.kind}(r))e[t.value]=r.value;else if(function(e){return"ObjectValue"===e.kind}(r)){var i={};r.fields.map((function(e){return Ce(i,e.name,e.value,n)})),e[t.value]=i}else if(function(e){return"Variable"===e.kind}(r)){var o=(n||{})[r.name.value];e[t.value]=o}else if(function(e){return"ListValue"===e.kind}(r))e[t.value]=r.values.map((function(e){var r={};return Ce(r,t,e,n),r[t.value]}));else if(function(e){return"EnumValue"===e.kind}(r))e[t.value]=r.value;else{if(!function(e){return"NullValue"===e.kind}(r))throw new h(53);e[t.value]=null}}var Pe=["connection","include","skip","client","rest","export"];function Me(e,t,r){if(t&&r&&r.connection&&r.connection.key){if(r.connection.filter&&r.connection.filter.length>0){var n=r.connection.filter?r.connection.filter:[];n.sort();var i={};return n.forEach((function(e){i[e]=t[e]})),r.connection.key+"("+JSON.stringify(i)+")"}return r.connection.key}var o=e;if(t){var a=function(e,t){t||(t={}),"function"==typeof t&&(t={cmp:t});var r,n="boolean"==typeof t.cycles&&t.cycles,i=t.cmp&&(r=t.cmp,function(e){return function(t,n){var i={key:t,value:e[t]},o={key:n,value:e[n]};return r(i,o)}}),o=[];return function e(t){if(t&&t.toJSON&&"function"==typeof t.toJSON&&(t=t.toJSON()),void 0!==t){if("number"==typeof t)return isFinite(t)?""+t:"null";if("object"!=typeof t)return JSON.stringify(t);var r,a;if(Array.isArray(t)){for(a="[",r=0;r1)for(var n=new ct,i=1;i1,i=!1,o=arguments[1],a=o;return new r((function(r){return t.subscribe({next:function(t){var o=!i;if(i=!0,!o||n)try{a=e(a,t)}catch(s){return r.error(s)}else a=t},error:function(e){r.error(e)},complete:function(){if(!i&&!n)return r.error(new TypeError("Cannot reduce an empty sequence"));r.next(a),r.complete()}})}))}},{key:"concat",value:function(){for(var e=this,t=arguments.length,r=new Array(t),n=0;n=0&&i.splice(e,1),a()}});i.push(o)},error:function(e){n.error(e)},complete:function(){a()}});function a(){o.closed&&0===i.length&&n.complete()}return function(){i.forEach((function(e){return e.unsubscribe()})),o.unsubscribe()}}))}},{key:bt,value:function(){return this}}],[{key:"from",value:function(t){var r="function"==typeof this?this:e;if(null==t)throw new TypeError(t+" is not an object");var n=Ot(t,bt);if(n){var i=n.call(t);if(Object(i)!==i)throw new TypeError(i+" is not an object");return function(e){return e instanceof Dt}(i)&&i.constructor===r?i:new r((function(e){return i.subscribe(e)}))}if(vt("iterator")&&(n=Ot(t,mt)))return new r((function(e){St((function(){if(!e.closed){var r=!0,i=!1,o=void 0;try{for(var a,s=n.call(t)[Symbol.iterator]();!(r=(a=s.next()).done);r=!0){var u=a.value;if(e.next(u),e.closed)return}}catch(c){i=!0,o=c}finally{try{r||null==s.return||s.return()}finally{if(i)throw o}}e.complete()}}))}));if(Array.isArray(t))return new r((function(e){St((function(){if(!e.closed){for(var r=0;r0}function Bt(e){return e.errors&&e.errors.length>0||!1}Lt(Qt);var Ut="function"==typeof WeakMap&&!("object"==typeof navigator&&"ReactNative"===navigator.product);function Kt(){for(var e=[],t=0;t=300&&Gt(e,t,"Response not successful: Received status code "+e.status),Array.isArray(t)||$t.call(t,"data")||$t.call(t,"errors")||Gt(e,t,"Server response was missing for query '"+(Array.isArray(i)?i.map((function(e){return e.operationName})):i.operationName)+"'."),t}))})).then((function(e){return r.next(e),r.complete(),e})).catch((function(e){"AbortError"!==e.name&&(e.result&&e.result.errors&&e.result.data&&r.next(e.result),r.error(e))})),function(){h&&h.abort()}}))}))},rr=function(e){function t(t){void 0===t&&(t={});var r=e.call(this,tr(t).request)||this;return r.options=t,r}return n(t,e),t}(Xt),nr=Object.prototype,ir=nr.toString,or=nr.hasOwnProperty,ar=Function.prototype.toString,sr=new Map;function ur(e,t){try{return cr(e,t)}finally{sr.clear()}}function cr(e,t){if(e===t)return!0;var r,n,i,o=ir.call(e);if(o!==ir.call(t))return!1;switch(o){case"[object Array]":if(e.length!==t.length)return!1;case"[object Object]":if(hr(e,t))return!0;var a=lr(e),s=lr(t),u=a.length;if(u!==s.length)return!1;for(var c=0;c=0&&r.indexOf(n,i)===i))}return!1}function lr(e){return Object.keys(e).filter(fr,e)}function fr(e){return void 0!==this[e]}var pr="{ [native code] }";function hr(e,t){var r=sr.get(e);if(r){if(r.has(t))return!0}else sr.set(e,r=new Set);return r.add(t),!1}var dr,vr,yr=function(e){function t(r){var n,i,o=r.graphQLErrors,a=r.networkError,s=r.errorMessage,u=r.extraInfo,c=e.call(this,s)||this;return c.graphQLErrors=o||[],c.networkError=a||null,c.message=s||(i="",Vt((n=c).graphQLErrors)&&n.graphQLErrors.forEach((function(e){var t=e?e.message:"Error message not found.";i+=t+"\n"})),n.networkError&&(i+=n.networkError.message+"\n"),i=i.replace(/\n$/,"")),c.extraInfo=u,c.__proto__=t.prototype,c}return n(t,e),t}(Error);function mr(e){return!!e&&e<7}(vr=dr||(dr={}))[vr.loading=1]="loading",vr[vr.setVariables=2]="setVariables",vr[vr.fetchMore=3]="fetchMore",vr[vr.refetch=4]="refetch",vr[vr.poll=6]="poll",vr[vr.ready=7]="ready",vr[vr.error=8]="error";var br=function(){function e(e,t,r,n){this.observer=e,this.options=t,this.fetch=r,this.shouldFetch=n}return e.prototype.reobserve=function(e,t){e?this.updateOptions(e):this.updatePolling();var r=this.fetch(this.options,t);return this.concast&&this.concast.removeObserver(this.observer,!0),r.addObserver(this.observer),(this.concast=r).promise},e.prototype.updateOptions=function(e){return Object.assign(this.options,Kt(e)),this.updatePolling(),this},e.prototype.stop=function(){this.concast&&(this.concast.removeObserver(this.observer),delete this.concast),this.pollingInfo&&(clearTimeout(this.pollingInfo.timeout),this.options.pollInterval=0,this.updatePolling())},e.prototype.updatePolling=function(){var e=this,t=this.pollingInfo,r=this.options.pollInterval;if(r){if((!t||t.interval!==r)&&(d(r,20),!1!==this.shouldFetch)){(t||(this.pollingInfo={})).interval=r;var n=function(){e.pollingInfo&&(e.shouldFetch&&e.shouldFetch()?e.reobserve({fetchPolicy:"network-only",nextFetchPolicy:e.options.fetchPolicy||"cache-first"},dr.poll).then(i,i):i())},i=function(){var t=e.pollingInfo;t&&(clearTimeout(t.timeout),t.timeout=setTimeout(n,t.interval))};i()}}else t&&(clearTimeout(t.timeout),delete this.pollingInfo)},e}(),gr=function(e){function t(t){var r=t.queryManager,n=t.queryInfo,o=t.options,a=e.call(this,(function(e){return a.onSubscribe(e)}))||this;a.observers=new Set,a.subscriptions=new Set,a.observer={next:function(e){(a.lastError||a.isDifferentFromLastResult(e))&&(a.updateLastResult(e),Mt(a.observers,"next",e))},error:function(e){a.updateLastResult(i(i({},a.lastResult),{error:e,errors:e.graphQLErrors,networkStatus:dr.error,loading:!1})),Mt(a.observers,"error",a.lastError=e)}},a.isTornDown=!1,a.options=o,a.queryId=r.generateQueryId();var s=Ue(o.query);return a.queryName=s&&s.name&&s.name.value,a.queryManager=r,a.queryInfo=n,a}return n(t,e),Object.defineProperty(t.prototype,"variables",{get:function(){return this.options.variables},enumerable:!1,configurable:!0}),t.prototype.result=function(){var e=this;return new Promise((function(t,r){var n={next:function(r){t(r),e.observers.delete(n),e.observers.size||e.queryManager.removeQuery(e.queryId),setTimeout((function(){i.unsubscribe()}),0)},error:r},i=e.subscribe(n)}))},t.prototype.getCurrentResult=function(e){void 0===e&&(e=!0);var t=this.lastResult,r=this.queryInfo.networkStatus||t&&t.networkStatus||dr.ready,n=i(i({},t),{loading:mr(r),networkStatus:r});if(this.isTornDown)return n;var o=this.options.fetchPolicy,a=void 0===o?"cache-first":o;if("no-cache"===a||"network-only"===a)delete n.partial;else if(!n.data||!this.queryManager.transform(this.options.query).hasForcedResolvers){var s=this.queryInfo.getDiff();n.data=s.complete||this.options.returnPartialData?s.result:void 0,s.complete?(n.networkStatus!==dr.loading||"cache-first"!==a&&"cache-only"!==a||(n.networkStatus=dr.ready,n.loading=!1),delete n.partial):n.partial=!0}return e&&this.updateLastResult(n),n},t.prototype.isDifferentFromLastResult=function(e){return!ur(this.lastResultSnapshot,e)},t.prototype.getLastResult=function(){return this.lastResult},t.prototype.getLastError=function(){return this.lastError},t.prototype.resetLastResults=function(){delete this.lastResult,delete this.lastResultSnapshot,delete this.lastError,this.isTornDown=!1},t.prototype.resetQueryStoreErrors=function(){this.queryManager.resetErrors(this.queryId)},t.prototype.refetch=function(e){var t={pollInterval:0},r=this.options.fetchPolicy;return"no-cache"!==r&&"cache-and-network"!==r&&(t.fetchPolicy="network-only",t.nextFetchPolicy=r||"cache-first"),e&&!ur(this.options.variables,e)&&(t.variables=this.options.variables=i(i({},this.options.variables),e)),this.newReobserver(!1).reobserve(t,dr.refetch)},t.prototype.fetchMore=function(e){var t=this,r=i(i({},e.query?e:i(i(i({},this.options),e),{variables:i(i({},this.options.variables),e.variables)})),{fetchPolicy:"no-cache"}),n=this.queryManager.generateQueryId();return r.notifyOnNetworkStatusChange&&(this.queryInfo.networkStatus=dr.fetchMore,this.observe()),this.queryManager.fetchQuery(n,r,dr.fetchMore).then((function(n){var i=n.data,o=e.updateQuery;return o?t.updateQuery((function(e){return o(e,{fetchMoreResult:i,variables:r.variables})})):t.queryManager.cache.writeQuery({query:r.query,variables:r.variables,data:i}),n})).finally((function(){t.queryManager.stopQuery(n),t.reobserve()}))},t.prototype.subscribeToMore=function(e){var t=this,r=this.queryManager.startGraphQLSubscription({query:e.document,variables:e.variables,context:e.context}).subscribe({next:function(r){var n=e.updateQuery;n&&t.updateQuery((function(e,t){var i=t.variables;return n(e,{subscriptionData:r,variables:i})}))},error:function(t){e.onError&&e.onError(t)}});return this.subscriptions.add(r),function(){t.subscriptions.delete(r)&&r.unsubscribe()}},t.prototype.setOptions=function(e){return this.reobserve(e)},t.prototype.setVariables=function(e){if(ur(this.variables,e))return this.observers.size?this.result():Promise.resolve();if(this.options.variables=e,!this.observers.size)return Promise.resolve();var t=this.options.fetchPolicy,r=void 0===t?"cache-first":t,n={fetchPolicy:r,variables:e};return"cache-first"!==r&&"no-cache"!==r&&"network-only"!==r&&(n.fetchPolicy="cache-and-network",n.nextFetchPolicy=r),this.reobserve(n,dr.setVariables)},t.prototype.updateQuery=function(e){var t,r=this.queryManager,n=e(r.cache.diff({query:this.options.query,variables:this.variables,previousResult:null===(t=this.lastResult)||void 0===t?void 0:t.data,returnPartialData:!0,optimistic:!1}).result,{variables:this.variables});n&&(r.cache.writeQuery({query:this.options.query,data:n,variables:this.variables}),r.broadcastQueries())},t.prototype.startPolling=function(e){this.getReobserver().updateOptions({pollInterval:e})},t.prototype.stopPolling=function(){this.reobserver&&this.reobserver.updateOptions({pollInterval:0})},t.prototype.updateLastResult=function(e){var t=this.lastResult;return this.lastResult=e,this.lastResultSnapshot=this.queryManager.assumeImmutableResults?e:Ct(e),Vt(e.errors)||delete this.lastError,t},t.prototype.onSubscribe=function(e){var t=this;if(e===this.observer)return function(){};try{var r=e._subscription._observer;r&&!r.error&&(r.error=Or)}catch(i){}var n=!this.observers.size;return this.observers.add(e),this.lastError?e.error&&e.error(this.lastError):this.lastResult&&e.next&&e.next(this.lastResult),n&&this.reobserve().catch((function(e){})),function(){t.observers.delete(e)&&!t.observers.size&&t.tearDownQuery()}},t.prototype.getReobserver=function(){return this.reobserver||(this.reobserver=this.newReobserver(!0))},t.prototype.newReobserver=function(e){var t=this,r=this.queryManager,n=this.queryId;return r.setObservableQuery(this),new br(this.observer,e?this.options:i({},this.options),(function(e,i){return r.setObservableQuery(t),r.fetchQueryObservable(n,e,i)}),!r.ssrMode&&function(){return!mr(t.queryInfo.networkStatus)})},t.prototype.reobserve=function(e,t){return this.isTornDown=!1,this.getReobserver().reobserve(e,t)},t.prototype.observe=function(){this.observer.next(this.getCurrentResult(!1))},t.prototype.hasObservers=function(){return this.observers.size>0},t.prototype.tearDownQuery=function(){this.isTornDown||(this.reobserver&&(this.reobserver.stop(),delete this.reobserver),this.subscriptions.forEach((function(e){return e.unsubscribe()})),this.subscriptions.clear(),this.queryManager.stopQuery(this.queryId),this.observers.clear(),this.isTornDown=!0)},t}(At);function Or(e){}Lt(gr);var Er=function(){return Object.create(null)},wr=Array.prototype,Sr=wr.forEach,kr=wr.slice,Tr=function(){function e(e,t){void 0===e&&(e=!0),void 0===t&&(t=Er),this.weakness=e,this.makeData=t}return e.prototype.lookup=function(){for(var e=[],t=0;tthis.max;)this.delete(this.oldest.key)},e.prototype.delete=function(e){var t=this.map.get(e);return!!t&&(t===this.newest&&(this.newest=t.older),t===this.oldest&&(this.oldest=t.newer),t.newer&&(t.newer.older=t.older),t.older&&(t.older.newer=t.newer),this.map.delete(e),this.dispose(t.value,e),!0)},e}(),Cr=new Dr,Pr=Object.prototype.hasOwnProperty,Mr=void 0===(Rr=Array.from)?function(e){var t=[];return e.forEach((function(e){return t.push(e)})),t}:Rr;function jr(e){var t=e.unsubscribe;"function"==typeof t&&(e.unsubscribe=void 0,t())}var Lr=[];function qr(e,t){if(!e)throw new Error(t||"assertion failure")}function Qr(e){switch(e.length){case 0:throw new Error("unknown value");case 1:return e[0];case 2:throw e[1]}}var Vr=function(){function e(t){this.fn=t,this.parents=new Set,this.childValues=new Map,this.dirtyChildren=null,this.dirty=!0,this.recomputing=!1,this.value=[],this.deps=null,++e.count}return e.prototype.peek=function(){if(1===this.value.length&&!Kr(this))return Br(this),this.value[0]},e.prototype.recompute=function(e){return qr(!this.recomputing,"already recomputing"),Br(this),Kr(this)?function(e,t){Hr(e),Cr.withValue(e,Ur,[e,t]),function(e,t){if("function"==typeof e.subscribe)try{jr(e),e.unsubscribe=e.subscribe.apply(null,t)}catch(r){return e.setDirty(),!1}return!0}(e,t)&&function(e){if(e.dirty=!1,Kr(e))return;Gr(e)}(e);return Qr(e.value)}(this,e):Qr(this.value)},e.prototype.setDirty=function(){this.dirty||(this.dirty=!0,this.value.length=0,zr(this),jr(this))},e.prototype.dispose=function(){var e=this;this.setDirty(),Hr(this),Yr(this,(function(t,r){t.setDirty(),$r(t,e)}))},e.prototype.forget=function(){this.dispose()},e.prototype.dependOn=function(e){e.add(this),this.deps||(this.deps=Lr.pop()||new Set),this.deps.add(e)},e.prototype.forgetDeps=function(){var e=this;this.deps&&(Mr(this.deps).forEach((function(t){return t.delete(e)})),this.deps.clear(),Lr.push(this.deps),this.deps=null)},e.count=0,e}();function Br(e){var t=Cr.getValue();if(t)return e.parents.add(t),t.childValues.has(e)||t.childValues.set(e,[]),Kr(e)?Wr(t,e):Jr(t,e),t}function Ur(e,t){e.recomputing=!0,e.value.length=0;try{e.value[0]=e.fn.apply(null,t)}catch(r){e.value[1]=r}e.recomputing=!1}function Kr(e){return e.dirty||!(!e.dirtyChildren||!e.dirtyChildren.size)}function zr(e){Yr(e,Wr)}function Gr(e){Yr(e,Jr)}function Yr(e,t){var r=e.parents.size;if(r)for(var n=Mr(e.parents),i=0;i0&&i===n.length&&r[i-1]===n[i-1]||e.setDirty()),Xr(e,t),Kr(e)||Gr(e)}function Xr(e,t){var r=e.dirtyChildren;r&&(r.delete(t),0===r.size&&(Lr.length<100&&Lr.push(r),e.dirtyChildren=null))}function Hr(e){e.childValues.size>0&&e.childValues.forEach((function(t,r){$r(e,r)})),e.forgetDeps(),qr(null===e.dirtyChildren)}function $r(e,t){t.parents.delete(e),e.childValues.delete(t),Xr(e,t)}var Zr={setDirty:!0,dispose:!0,forget:!0};function en(e){var t=new Map,r=e&&e.subscribe;function n(e){var n=Cr.getValue();if(n){var i=t.get(e);i||t.set(e,i=new Set),n.dependOn(i),"function"==typeof r&&(jr(i),i.unsubscribe=r(e))}}return n.dirty=function(e,r){var n=t.get(e);if(n){var i=r&&Pr.call(Zr,r)?r:"setDirty";Mr(n).forEach((function(e){return e[i]()})),t.delete(e),jr(n)}},n}function tn(){var e=new Tr("function"==typeof WeakMap);return function(){return e.lookupArray(arguments)}}tn();var rn=new Set;function nn(e,t){void 0===t&&(t=Object.create(null));var r=new Fr(t.max||Math.pow(2,16),(function(e){return e.dispose()})),n=t.keyArgs,i=t.makeCacheKey||tn(),o=function(){var o=i.apply(null,n?n.apply(null,arguments):arguments);if(void 0===o)return e.apply(null,arguments);var a=r.get(o);a||(r.set(o,a=new Vr(e)),a.subscribe=t.subscribe,a.forget=function(){return r.delete(o)});var s=a.recompute(Array.prototype.slice.call(arguments));return r.set(o,a),rn.add(r),Cr.hasValue()||(rn.forEach((function(e){return e.clean()})),rn.clear()),s};function a(e){var t=r.get(e);t&&t.setDirty()}function s(e){var t=r.get(e);if(t)return t.peek()}function u(e){return r.delete(e)}return Object.defineProperty(o,"size",{get:function(){return r.map.size},configurable:!1,enumerable:!1}),o.dirtyKey=a,o.dirty=function(){a(i.apply(null,arguments))},o.peekKey=s,o.peek=function(){return s(i.apply(null,arguments))},o.forgetKey=u,o.forget=function(){return u(i.apply(null,arguments))},o.makeCacheKey=i,o.getKey=n?function(){return i.apply(null,n.apply(null,arguments))}:i,Object.freeze(o)}var on=function(){function e(){this.getFragmentDoc=nn(_e)}return e.prototype.recordOptimisticTransaction=function(e,t){this.performTransaction(e,t)},e.prototype.transformDocument=function(e){return e},e.prototype.identify=function(e){},e.prototype.gc=function(){return[]},e.prototype.modify=function(e){return!1},e.prototype.transformForLink=function(e){return e},e.prototype.readQuery=function(e,t){return void 0===t&&(t=!!e.optimistic),this.read({rootId:e.id||"ROOT_QUERY",query:e.query,variables:e.variables,returnPartialData:e.returnPartialData,optimistic:t})},e.prototype.readFragment=function(e,t){return void 0===t&&(t=!!e.optimistic),this.read({query:this.getFragmentDoc(e.fragment,e.fragmentName),variables:e.variables,rootId:e.id,returnPartialData:e.returnPartialData,optimistic:t})},e.prototype.writeQuery=function(e){return this.write({dataId:e.id||"ROOT_QUERY",result:e.data,query:e.query,variables:e.variables,broadcast:e.broadcast})},e.prototype.writeFragment=function(e){return this.write({dataId:e.id,result:e.data,variables:e.variables,query:this.getFragmentDoc(e.fragment,e.fragmentName),broadcast:e.broadcast})},e}(),an=function(e,t,r,n,i){this.message=e,this.path=t,this.query=r,this.clientOnly=n,this.variables=i},sn=Object.prototype.hasOwnProperty,un=/^[_a-z][_0-9a-z]*/i;function cn(e){var t=e.match(un);return t?t[0]:e}function ln(e,t,r){return!(!t||"object"!=typeof t)&&(Array.isArray(t)?t.every((function(t){return ln(e,t,r)})):e.selections.every((function(e){if(Qe(e)&&xe(e,r)){var n=Le(e);return sn.call(t,n)&&(!e.selectionSet||ln(e.selectionSet,t[n],r))}return!0})))}function fn(e){return null!==e&&"object"==typeof e&&!Fe(e)&&!Array.isArray(e)}var pn,hn,dn=Object.create(null),vn=function(){return dn},yn=Object.create(null),mn=function(){function e(e,t){var r=this;this.policies=e,this.group=t,this.data=Object.create(null),this.rootIds=Object.create(null),this.refs=Object.create(null),this.getFieldValue=function(e,t){return Fe(e)?r.get(e.__ref,t):e&&e[t]},this.canRead=function(e){return Fe(e)?r.has(e.__ref):"object"==typeof e},this.toReference=function(e,t){if("string"==typeof e)return Re(e);if(Fe(e))return e;var n=r.policies.identify(e)[0];if(n){var i=Re(n);return t&&r.merge(n,e),i}}}return e.prototype.toObject=function(){return i({},this.data)},e.prototype.has=function(e){return void 0!==this.lookup(e,!0)},e.prototype.get=function(e,t){if(this.group.depend(e,t),sn.call(this.data,e)){var r=this.data[e];if(r&&sn.call(r,t))return r[t]}return"__typename"===t&&sn.call(this.policies.rootTypenamesById,e)?this.policies.rootTypenamesById[e]:this instanceof On?this.parent.get(e,t):void 0},e.prototype.lookup=function(e,t){return t&&this.group.depend(e,"__exists"),sn.call(this.data,e)?this.data[e]:this instanceof On?this.parent.lookup(e,t):this.policies.rootTypenamesById[e]?Object.create(null):void 0},e.prototype.merge=function(e,t){var r=this,n=this.lookup(e),i=new ct(En).merge(n,t);if(this.data[e]=i,i!==n&&(delete this.refs[e],this.group.caching)){var o=Object.create(null);n||(o.__exists=1),Object.keys(t).forEach((function(e){if(!n||n[e]!==i[e]){o[e]=1;var t=cn(e);t===e||r.policies.hasKeyArgs(i.__typename,t)||(o[t]=1),void 0!==i[e]||r instanceof On||delete i[e]}})),Object.keys(o).forEach((function(t){return r.group.dirty(e,t)}))}},e.prototype.modify=function(e,t){var r=this,n=this.lookup(e);if(n){var o=Object.create(null),a=!1,s=!0,u={DELETE:dn,INVALIDATE:yn,isReference:Fe,toReference:this.toReference,canRead:this.canRead,readField:function(t,n){return r.policies.readField("string"==typeof t?{fieldName:t,from:n||Re(e)}:t,{store:r})}};if(Object.keys(n).forEach((function(c){var l=cn(c),f=n[c];if(void 0!==f){var p="function"==typeof t?t:t[c]||t[l];if(p){var h=p===vn?dn:p(f,i(i({},u),{fieldName:l,storeFieldName:c,storage:r.getStorage(e,c)}));h===yn?r.group.dirty(e,c):(h===dn&&(h=void 0),h!==f&&(o[c]=h,a=!0,f=h))}void 0!==f&&(s=!1)}})),a)return this.merge(e,o),s&&(this instanceof On?this.data[e]=void 0:delete this.data[e],this.group.dirty(e,"__exists")),!0}return!1},e.prototype.delete=function(e,t,r){var n,i=this.lookup(e);if(i){var o=this.getFieldValue(i,"__typename"),a=t&&r?this.policies.getStoreFieldName({typename:o,fieldName:t,args:r}):t;return this.modify(e,a?((n={})[a]=vn,n):vn)}return!1},e.prototype.evict=function(e){var t=!1;return e.id&&(sn.call(this.data,e.id)&&(t=this.delete(e.id,e.fieldName,e.args)),this instanceof On&&(t=this.parent.evict(e)||t),(e.fieldName||t)&&this.group.dirty(e.id,e.fieldName||"__exists")),t},e.prototype.clear=function(){this.replace(null)},e.prototype.extract=function(){var e=this,t=this.toObject(),r=[];return this.getRootIdSet().forEach((function(t){sn.call(e.policies.rootTypenamesById,t)||r.push(t)})),r.length&&(t.__META={extraRootIds:r.sort()}),t},e.prototype.replace=function(e){var t=this;if(Object.keys(this.data).forEach((function(r){e&&sn.call(e,r)||t.delete(r)})),e){var r=e.__META,n=o(e,["__META"]);Object.keys(n).forEach((function(e){t.merge(e,n[e])})),r&&r.extraRootIds.forEach(this.retain,this)}},e.prototype.retain=function(e){return this.rootIds[e]=(this.rootIds[e]||0)+1},e.prototype.release=function(e){if(this.rootIds[e]>0){var t=--this.rootIds[e];return t||delete this.rootIds[e],t}return 0},e.prototype.getRootIdSet=function(e){return void 0===e&&(e=new Set),Object.keys(this.rootIds).forEach(e.add,e),this instanceof On?this.parent.getRootIdSet(e):Object.keys(this.policies.rootTypenamesById).forEach(e.add,e),e},e.prototype.gc=function(){var e=this,t=this.getRootIdSet(),r=this.toObject();t.forEach((function(n){sn.call(r,n)&&(Object.keys(e.findChildRefIds(n)).forEach(t.add,t),delete r[n])}));var n=Object.keys(r);if(n.length){for(var i=this;i instanceof On;)i=i.parent;n.forEach((function(e){return i.delete(e)}))}return n},e.prototype.findChildRefIds=function(e){if(!sn.call(this.refs,e)){var t=this.refs[e]=Object.create(null),r=new Set([this.data[e]]),n=function(e){return null!==e&&"object"==typeof e};r.forEach((function(e){Fe(e)?t[e.__ref]=!0:n(e)&&Object.values(e).filter(n).forEach(r.add,r)}))}return this.refs[e]},e.prototype.makeCacheKey=function(){for(var e=[],t=0;t0;if(p&&!c)throw f.missing[0];return{result:f.result,missing:f.missing,complete:!p}},e.prototype.isFresh=function(e,t,r,n){if(wn(n.store)&&this.knownResults.get(e)===r){var i=this.executeSelectionSet.peek(r,t,n);if(i&&e===i.result)return!0}return!1},e.prototype.execSelectionSetImpl=function(e){var t=this,r=e.selectionSet,n=e.objectOrReference,i=e.context;if(Fe(n)&&!i.policies.rootTypenamesById[n.__ref]&&!i.store.has(n.__ref))return{result:{},missing:[Sn(new h(4),i)]};var o=i.variables,a=i.policies,s=i.store,u=[],c={result:null},l=s.getFieldValue(n,"__typename");function f(){return c.missing||(c.missing=[])}function p(e){var t;return e.missing&&(t=f()).push.apply(t,e.missing),e.result}this.config.addTypename&&"string"==typeof l&&!a.rootIdsByTypename[l]&&u.push({__typename:l});var v=new Set(r.selections);return v.forEach((function(e){var r;if(xe(e,o))if(Qe(e)){var s=a.readField({fieldName:e.name.value,field:e,variables:i.variables,from:n},i),c=Le(e);i.path.push(c);var y=i.clientOnly;i.clientOnly=y||!(!e.directives||!e.directives.some((function(e){return"client"===e.name.value}))),void 0===s?et.added(e)||f().push(Sn(new h(5),i)):Array.isArray(s)?s=p(t.executeSubSelectedArray({field:e,array:s,context:i})):e.selectionSet&&null!=s&&(s=p(t.executeSelectionSet({selectionSet:e.selectionSet,objectOrReference:s,context:i}))),void 0!==s&&u.push(((r={})[c]=s,r)),i.clientOnly=y,d(i.path.pop()===c)}else{var m=Ae(e,i.fragmentMap);m&&a.fragmentMatches(m,l)&&m.selectionSet.selections.forEach(v.add,v)}})),c.result=at(u),this.knownResults.set(c.result,r),c},e.prototype.execSubSelectedArrayImpl=function(e){var t,r=this,n=e.field,i=e.array,o=e.context;function a(e,r){return e.missing&&(t=t||[]).push.apply(t,e.missing),d(o.path.pop()===r),e.result}return n.selectionSet&&(i=i.filter(o.store.canRead)),{result:i=i.map((function(e,t){return null===e?null:(o.path.push(t),Array.isArray(e)?a(r.executeSubSelectedArray({field:n,array:e,context:o}),t):n.selectionSet?a(r.executeSelectionSet({selectionSet:n.selectionSet,objectOrReference:e,context:o}),t):(d(o.path.pop()===t),e))})),missing:t}},e}(),Tn=function(){function e(e,t){this.cache=e,this.reader=t}return e.prototype.writeToStore=function(e){var t=e.query,r=e.result,n=e.dataId,o=e.store,a=e.variables,s=Ue(t),u=new ct;a=i(i({},Ye(s)),a);var c=this.processSelectionSet({result:r||Object.create(null),dataId:n,selectionSet:s.selectionSet,mergeTree:{map:new Map},context:{store:o,written:Object.create(null),merge:function(e,t){return u.merge(e,t)},variables:a,varString:JSON.stringify(a),fragmentMap:De(ze(t))}});if(!Fe(c))throw new h(7);return o.retain(c.__ref),c},e.prototype.processSelectionSet=function(e){var t=this,r=e.dataId,n=e.result,i=e.selectionSet,o=e.context,a=e.mergeTree,s=this.cache.policies,u=s.identify(n,i,o.fragmentMap),c=u[0],l=u[1];if("string"==typeof(r=r||c)){var f=o.written[r]||(o.written[r]=[]),p=Re(r);if(f.indexOf(i)>=0)return p;if(f.push(i),this.reader&&this.reader.isFresh(n,p,i,o))return p}var d=Object.create(null);l&&(d=o.merge(d,l));var v=r&&s.rootTypenamesById[r]||qe(n,i,o.fragmentMap)||r&&o.store.get(r,"__typename");"string"==typeof v&&(d.__typename=v);var y=new Set(i.selections);if(y.forEach((function(e){var r;if(xe(e,o.variables))if(Qe(e)){var i=Le(e),u=n[i];if(void 0!==u){var c=s.getStoreFieldName({typename:v,fieldName:e.name.value,field:e,variables:o.variables}),l=Nn(a,c),f=t.processFieldValue(u,e,o,l),p=e.selectionSet&&o.store.getFieldValue(f,"__typename")||void 0,m=s.getMergeFunction(v,e.name.value,p);m?l.info={field:e,typename:v,merge:m}:In(a,c),d=o.merge(d,((r={})[c]=f,r))}else if(s.usingPossibleTypes&&!Ne(["defer","client"],e))throw new h(8)}else{var b=Ae(e,o.fragmentMap);b&&s.fragmentMatches(b,v,n,o.variables)&&b.selectionSet.selections.forEach(y.add,y)}})),"string"==typeof r){var m=Re(r);return a.map.size&&(d=this.applyMerges(a,m,d,o)),o.store.merge(r,d),m}return d},e.prototype.processFieldValue=function(e,t,r,n){var i=this;return t.selectionSet&&null!==e?Array.isArray(e)?e.map((function(e,o){var a=i.processFieldValue(e,t,r,Nn(n,o));return In(n,o),a})):this.processSelectionSet({result:e,selectionSet:t.selectionSet,context:r,mergeTree:n}):e},e.prototype.applyMerges=function(e,t,r,n,o){var a,s=this;if(e.map.size&&!Fe(r)){var u,c=Array.isArray(r)||!Fe(t)&&!fn(t)?void 0:t,l=r;c&&!o&&(o=[Fe(c)?c.__ref:c]);var f=function(e,t){return Array.isArray(e)?"number"==typeof t?e[t]:void 0:n.store.getFieldValue(e,String(t))};e.map.forEach((function(e,t){o&&o.push(t);var r=f(c,t),i=f(l,t),a=s.applyMerges(e,r,i,n,o);a!==i&&(u=u||new Map).set(t,a),o&&d(o.pop()===t)})),u&&(r=Array.isArray(l)?l.slice(0):i({},l),u.forEach((function(e,t){r[t]=e})))}return e.info?this.cache.policies.runMergeFunction(t,r,e.info,n,o&&(a=n.store).getStorage.apply(a,o)):r},e}(),xn=[];function Nn(e,t){var r=e.map;return r.has(t)||r.set(t,xn.pop()||{map:new Map}),r.get(t)}function In(e,t){var r=e.map,n=r.get(t);!n||n.info||n.map.size||(xn.push(n),r.delete(t))}var _n=new Dr,Dn=new WeakMap;function An(e){var t=Dn.get(e);return t||Dn.set(e,t={vars:new Set,dep:en()}),t}function Rn(e){var t=new Set,r=new Set,n=function(o){if(arguments.length>0){if(e!==o){e=o,t.forEach((function(e){An(e).dep.dirty(n),Fn(e)}));var a=Array.from(r);r.clear(),a.forEach((function(t){return t(e)}))}}else{var s=_n.getValue();s&&(i(s),An(s).dep(n))}return e};n.onNextChange=function(e){return r.add(e),function(){r.delete(e)}};var i=n.attachCache=function(e){return t.add(e),An(e).vars.add(n),n};return n.forgetCache=function(e){return t.delete(e)},n}function Fn(e){e.broadcastWatches&&e.broadcastWatches()}function Cn(e){return void 0!==e.args?e.args:e.field?je(e.field,e.variables):null}var Pn=function(e,t){var r=e.__typename,n=e.id,i=e._id;if("string"==typeof r&&(t&&(t.keyObject=void 0!==n?{id:n}:void 0!==i?{_id:i}:void 0),void 0===n&&(n=i),void 0!==n))return r+":"+("number"==typeof n||"string"==typeof n?n:JSON.stringify(n))},Mn=function(){},jn=function(e,t){return t.fieldName},Ln=function(e,t,r){return(0,r.mergeObjects)(e,t)},qn=function(e,t){return t},Qn=function(){function e(e){this.config=e,this.typePolicies=Object.create(null),this.toBeAdded=Object.create(null),this.supertypeMap=new Map,this.fuzzySubtypes=new Map,this.rootIdsByTypename=Object.create(null),this.rootTypenamesById=Object.create(null),this.usingPossibleTypes=!1,this.config=i({dataIdFromObject:Pn},e),this.cache=this.config.cache,this.setRootTypename("Query"),this.setRootTypename("Mutation"),this.setRootTypename("Subscription"),e.possibleTypes&&this.addPossibleTypes(e.possibleTypes),e.typePolicies&&this.addTypePolicies(e.typePolicies)}return e.prototype.identify=function(e,t,r){var n=t&&r?qe(e,t,r):e.__typename;if(n===this.rootTypenamesById.ROOT_QUERY)return["ROOT_QUERY"];for(var i,o={typename:n,selectionSet:t,fragmentMap:r},a=n&&this.getTypePolicy(n),s=a&&a.keyFn||this.config.dataIdFromObject;s;){var u=s(e,o);if(!Array.isArray(u)){i=u;break}s=Kn(u)}return i=i?String(i):void 0,o.keyObject?[i,o.keyObject]:[i]},e.prototype.addTypePolicies=function(e){var t=this;Object.keys(e).forEach((function(r){var n=e[r],i=n.queryType,a=n.mutationType,s=n.subscriptionType,u=o(n,["queryType","mutationType","subscriptionType"]);i&&t.setRootTypename("Query",r),a&&t.setRootTypename("Mutation",r),s&&t.setRootTypename("Subscription",r),sn.call(t.toBeAdded,r)?t.toBeAdded[r].push(u):t.toBeAdded[r]=[u]}))},e.prototype.updateTypePolicy=function(e,t){var r=this,n=this.getTypePolicy(e),i=t.keyFields,o=t.fields;function a(e,t){e.merge="function"==typeof t?t:!0===t?Ln:!1===t?qn:e.merge}a(n,t.merge),n.keyFn=!1===i?Mn:Array.isArray(i)?Kn(i):"function"==typeof i?i:n.keyFn,o&&Object.keys(o).forEach((function(t){var n=r.getFieldPolicy(e,t,!0),i=o[t];if("function"==typeof i)n.read=i;else{var s=i.keyArgs,u=i.read,c=i.merge;n.keyFn=!1===s?jn:Array.isArray(s)?Un(s):"function"==typeof s?s:n.keyFn,"function"==typeof u&&(n.read=u),a(n,c)}n.read&&n.merge&&(n.keyFn=n.keyFn||jn)}))},e.prototype.setRootTypename=function(e,t){void 0===t&&(t=e);var r="ROOT_"+e.toUpperCase(),n=this.rootTypenamesById[r];t!==n&&(d(!n||n===e,1),n&&delete this.rootIdsByTypename[n],this.rootIdsByTypename[t]=r,this.rootTypenamesById[r]=t)},e.prototype.addPossibleTypes=function(e){var t=this;this.usingPossibleTypes=!0,Object.keys(e).forEach((function(r){t.getSupertypeSet(r,!0),e[r].forEach((function(e){t.getSupertypeSet(e,!0).add(r);var n=e.match(un);n&&n[0]===e||t.fuzzySubtypes.set(e,new RegExp(e))}))}))},e.prototype.getTypePolicy=function(e){var t=this;if(!sn.call(this.typePolicies,e)){var r=this.typePolicies[e]=Object.create(null);r.fields=Object.create(null);var n=this.supertypeMap.get(e);n&&n.size&&n.forEach((function(e){var n=t.getTypePolicy(e),i=n.fields,a=o(n,["fields"]);Object.assign(r,a),Object.assign(r.fields,i)}))}var i=this.toBeAdded[e];return i&&i.length&&this.updateTypePolicy(e,Kt.apply(void 0,i.splice(0))),this.typePolicies[e]},e.prototype.getFieldPolicy=function(e,t,r){if(e){var n=this.getTypePolicy(e).fields;return n[t]||r&&(n[t]=Object.create(null))}},e.prototype.getSupertypeSet=function(e,t){var r=this.supertypeMap.get(e);return!r&&t&&this.supertypeMap.set(e,r=new Set),r},e.prototype.fragmentMatches=function(e,t,r,n){var i=this;if(!e.typeCondition)return!0;if(!t)return!1;var o=e.typeCondition.name.value;if(t===o)return!0;if(this.usingPossibleTypes&&this.supertypeMap.has(o))for(var a=this.getSupertypeSet(t,!0),s=[a],u=function(e){var t=i.getSupertypeSet(e,!1);t&&t.size&&s.indexOf(t)<0&&s.push(t)},c=!(!r||!this.fuzzySubtypes.size),l=0;l=e.lastRequestId){if(o&&"none"===r.errorPolicy)throw e.markError(new yr({graphQLErrors:i.errors}));e.markResult(i,r,t),e.markReady()}var a={data:i.data,loading:!1,networkStatus:e.networkStatus||dr.ready};return o&&"ignore"!==r.errorPolicy&&(a.errors=i.errors),a}),(function(t){var r=t.hasOwnProperty("graphQLErrors")?t:new yr({networkError:t});throw n>=e.lastRequestId&&e.markError(r),r}))},e.prototype.fetchQueryObservable=function(e,t,r){var n=this;void 0===r&&(r=dr.loading);var i=this.transform(t.query).document,o=this.getVariables(i,t.variables),a=this.getQuery(e),s=a.networkStatus,u=t.fetchPolicy,c=void 0===u?"cache-first":u,l=t.errorPolicy,f=void 0===l?"none":l,p=t.returnPartialData,h=void 0!==p&&p,d=t.notifyOnNetworkStatusChange,v=void 0!==d&&d,y=t.context,m=void 0===y?{}:y;("cache-first"===c||"cache-and-network"===c||"network-only"===c||"no-cache"===c)&&v&&"number"==typeof s&&s!==r&&mr(r)&&("cache-first"!==c&&(c="cache-and-network"),h=!0);var b=Object.assign({},t,{query:i,variables:o,fetchPolicy:c,errorPolicy:f,returnPartialData:h,notifyOnNetworkStatusChange:v,context:m}),g=function(e){return b.variables=e,n.fetchQueryByPolicy(a,b,r)};this.fetchCancelFns.set(e,(function(e){Promise.resolve().then((function(){return O.cancel(e)}))}));var O=new Qt(this.transform(b.query).hasClientExports?this.localState.addExportedVariables(b.query,b.variables,b.context).then(g):g(b.variables));return O.cleanup((function(){n.fetchCancelFns.delete(e);var r=t.nextFetchPolicy;r&&(t.nextFetchPolicy=void 0,t.fetchPolicy="function"==typeof r?r.call(t,t.fetchPolicy||"cache-first"):r)})),O},e.prototype.fetchQueryByPolicy=function(e,t,r){var n=this,o=t.query,a=t.variables,s=t.fetchPolicy,u=t.errorPolicy,c=t.returnPartialData,l=t.context;e.init({document:o,variables:a,networkStatus:r});var f=function(){return e.getDiff(a)},p=function(t,r){void 0===r&&(r=e.networkStatus||dr.loading);var s=t.result,u=function(e){return At.of(i({data:e,loading:mr(r),networkStatus:r},t.complete?null:{partial:!0}))};return n.transform(o).hasForcedResolvers?n.localState.runResolvers({document:o,remoteResult:{data:s},context:l,variables:a,onlyRunForcedResolvers:!0}).then((function(e){return u(e.data)})):u(s)},h=function(t){return n.getResultsFromLink(e,t,{variables:a,context:l,fetchPolicy:s,errorPolicy:u})};switch(s){default:case"cache-first":return(d=f()).complete?[p(d,e.markReady())]:c?[p(d),h(!0)]:[h(!0)];case"cache-and-network":var d;return(d=f()).complete||c?[p(d),h(!0)]:[h(!0)];case"cache-only":return[p(f(),e.markReady())];case"network-only":return[h(!0)];case"no-cache":return[h(!1)];case"standby":return[]}},e.prototype.getQuery=function(e){return e&&!this.queries.has(e)&&this.queries.set(e,new Zn(this.cache)),this.queries.get(e)},e.prototype.prepareContext=function(e){void 0===e&&(e={});var t=this.localState.prepareContext(e);return i(i({},t),{clientAwareness:this.clientAwareness})},e}();function ni(e,t){return Kt(e,t,t.variables&&{variables:i(i({},e.variables),t.variables)})}var ii=function(){function e(e){var t=this;this.defaultOptions={},this.resetStoreCallbacks=[],this.clearStoreCallbacks=[];var r=e.uri,n=e.credentials,i=e.headers,o=e.cache,a=e.ssrMode,s=void 0!==a&&a,u=e.ssrForceFetchDelay,c=void 0===u?0:u,l=e.connectToDevTools,f=void 0===l?"object"==typeof window&&!window.__APOLLO_CLIENT__&&!1:l,p=e.queryDeduplication,d=void 0===p||p,v=e.defaultOptions,y=e.assumeImmutableResults,m=void 0!==y&&y,b=e.resolvers,g=e.typeDefs,O=e.fragmentMatcher,E=e.name,w=e.version,S=e.link;if(S||(S=r?new rr({uri:r,credentials:n,headers:i}):Xt.empty()),!o)throw new h(9);this.link=S,this.cache=o,this.disableNetworkFetches=s||c>0,this.queryDeduplication=d,this.defaultOptions=v||{},this.typeDefs=g,c&&setTimeout((function(){return t.disableNetworkFetches=!1}),c),this.watchQuery=this.watchQuery.bind(this),this.query=this.query.bind(this),this.mutate=this.mutate.bind(this),this.resetStore=this.resetStore.bind(this),this.reFetchObservableQueries=this.reFetchObservableQueries.bind(this),f&&"object"==typeof window&&(window.__APOLLO_CLIENT__=this),this.version="3.3.19",this.localState=new Jn({cache:o,client:this,resolvers:b,fragmentMatcher:O}),this.queryManager=new ri({cache:this.cache,link:this.link,queryDeduplication:d,ssrMode:s,clientAwareness:{name:E,version:w},localState:this.localState,assumeImmutableResults:m,onBroadcast:f?function(){t.devToolsHookCb&&t.devToolsHookCb({action:{},state:{queries:t.queryManager.getQueryStore(),mutations:t.queryManager.mutationStore||{}},dataWithOptimisticResults:t.cache.extract(!0)})}:void 0})}return e.prototype.stop=function(){this.queryManager.stop()},e.prototype.watchQuery=function(e){return this.defaultOptions.watchQuery&&(e=ni(this.defaultOptions.watchQuery,e)),!this.disableNetworkFetches||"network-only"!==e.fetchPolicy&&"cache-and-network"!==e.fetchPolicy||(e=i(i({},e),{fetchPolicy:"cache-first"})),this.queryManager.watchQuery(e)},e.prototype.query=function(e){return this.defaultOptions.query&&(e=ni(this.defaultOptions.query,e)),d("cache-and-network"!==e.fetchPolicy,10),this.disableNetworkFetches&&"network-only"===e.fetchPolicy&&(e=i(i({},e),{fetchPolicy:"cache-first"})),this.queryManager.query(e)},e.prototype.mutate=function(e){return this.defaultOptions.mutate&&(e=ni(this.defaultOptions.mutate,e)),this.queryManager.mutate(e)},e.prototype.subscribe=function(e){return this.queryManager.startGraphQLSubscription(e)},e.prototype.readQuery=function(e,t){return void 0===t&&(t=!1),this.cache.readQuery(e,t)},e.prototype.readFragment=function(e,t){return void 0===t&&(t=!1),this.cache.readFragment(e,t)},e.prototype.writeQuery=function(e){this.cache.writeQuery(e),this.queryManager.broadcastQueries()},e.prototype.writeFragment=function(e){this.cache.writeFragment(e),this.queryManager.broadcastQueries()},e.prototype.__actionHookForDevTools=function(e){this.devToolsHookCb=e},e.prototype.__requestRaw=function(e){return Ht(this.link,e)},e.prototype.resetStore=function(){var e=this;return Promise.resolve().then((function(){return e.queryManager.clearStore()})).then((function(){return Promise.all(e.resetStoreCallbacks.map((function(e){return e()})))})).then((function(){return e.reFetchObservableQueries()}))},e.prototype.clearStore=function(){var e=this;return Promise.resolve().then((function(){return e.queryManager.clearStore()})).then((function(){return Promise.all(e.clearStoreCallbacks.map((function(e){return e()})))}))},e.prototype.onResetStore=function(e){var t=this;return this.resetStoreCallbacks.push(e),function(){t.resetStoreCallbacks=t.resetStoreCallbacks.filter((function(t){return t!==e}))}},e.prototype.onClearStore=function(e){var t=this;return this.clearStoreCallbacks.push(e),function(){t.clearStoreCallbacks=t.clearStoreCallbacks.filter((function(t){return t!==e}))}},e.prototype.reFetchObservableQueries=function(e){return this.queryManager.reFetchObservableQueries(e)},e.prototype.extract=function(e){return this.cache.extract(e)},e.prototype.restore=function(e){return this.cache.restore(e)},e.prototype.addResolvers=function(e){this.localState.addResolvers(e)},e.prototype.setResolvers=function(e){this.localState.setResolvers(e)},e.prototype.getResolvers=function(){return this.localState.getResolvers()},e.prototype.setLocalStateFragmentMatcher=function(e){this.localState.setFragmentMatcher(e)},e.prototype.setLink=function(e){this.link=this.queryManager.link=e},e}(),oi=new Map,ai=new Map,si=!0,ui=!1;function ci(e){return e.replace(/[\s,]+/g," ").trim()}function li(e){var t=new Set,r=[];return e.definitions.forEach((function(e){if("FragmentDefinition"===e.kind){var n=e.name.value,i=ci((a=e.loc).source.body.substring(a.start,a.end)),o=ai.get(n);o&&!o.has(i)?si&&console.warn("Warning: fragment with name "+n+" already exists.\ngraphql-tag enforces all fragment names across your application to be unique; read more about\nthis in the docs: http://dev.apollodata.com/core/fragments.html#unique-names"):o||ai.set(n,o=new Set),o.add(i),t.has(i)||(t.add(i),r.push(e))}else r.push(e);var a})),l(l({},e),{definitions:r})}function fi(e){var t=ci(e);if(!oi.has(t)){var r=function(e,t){return new le(e,t).parseDocument()}(e,{experimentalFragmentVariables:ui});if(!r||"Document"!==r.kind)throw new Error("Not a valid GraphQL document.");oi.set(t,function(e){var t=new Set(e.definitions);t.forEach((function(e){e.loc&&delete e.loc,Object.keys(e).forEach((function(r){var n=e[r];n&&"object"==typeof n&&t.add(n)}))}));var r=e.loc;return r&&(delete r.startToken,delete r.endToken),e}(li(r)))}return oi.get(t)}function pi(e){for(var t=[],r=1;r0&&(l=new yr({graphQLErrors:c})),e=i(i({},e),{data:n,loading:o,networkStatus:u,error:l,called:!0}),o);else if(l)Object.assign(e,{data:(a.currentObservable.getLastResult()||{}).data});else{var f=a.currentObservable.options.fetchPolicy;if(t.partialRefetch&&s&&(!n||0===Object.keys(n).length)&&"cache-only"!==f)return Object.assign(e,{loading:!0,networkStatus:dr.loading}),e.refetch(),e}}e.client=a.client,a.setOptions(t,!0);var p=a.previous.result;return a.previous.loading=p&&p.loading||!1,e.previousData=p&&(p.data||p.previousData),a.previous.result=e,a.currentObservable&&a.currentObservable.resetQueryStoreErrors(),e},a.obsRefetch=function(e){var t;return null===(t=a.currentObservable)||void 0===t?void 0:t.refetch(e)},a.obsFetchMore=function(e){return a.currentObservable.fetchMore(e)},a.obsUpdateQuery=function(e){return a.currentObservable.updateQuery(e)},a.obsStartPolling=function(e){var t;null===(t=a.currentObservable)||void 0===t||t.startPolling(e)},a.obsStopPolling=function(){var e;null===(e=a.currentObservable)||void 0===e||e.stopPolling()},a.obsSubscribeToMore=function(e){return a.currentObservable.subscribeToMore(e)},a.onNewData=o,a}return n(t,e),t.prototype.execute=function(){this.refreshClient();var e=this.getOptions(),t=e.skip,r=e.query;return(t||r!==this.previous.query)&&(this.removeQuerySubscription(),this.removeObservable(!t),this.previous.query=r),this.updateObservableQuery(),this.isMounted&&this.startQuerySubscription(),this.getExecuteSsrResult()||this.getExecuteResult()},t.prototype.executeLazy=function(){return this.runLazy?[this.runLazyQuery,this.execute()]:[this.runLazyQuery,{loading:!1,networkStatus:dr.ready,called:!1,data:void 0}]},t.prototype.fetchData=function(){var e=this,t=this.getOptions();return!t.skip&&!1!==t.ssr&&new Promise((function(t){return e.startQuerySubscription(t)}))},t.prototype.afterExecute=function(e){var t=(void 0===e?{}:e).lazy,r=void 0!==t&&t;return this.isMounted=!0,r&&!this.runLazy||this.handleErrorOrCompleted(),this.previousOptions=this.getOptions(),this.unmount.bind(this)},t.prototype.cleanup=function(){this.removeQuerySubscription(),this.removeObservable(!0),delete this.previous.result},t.prototype.getOptions=function(){var t=e.prototype.getOptions.call(this);return this.lazyOptions&&(t.variables=i(i({},t.variables),this.lazyOptions.variables),t.context=i(i({},t.context),this.lazyOptions.context)),this.runLazy&&delete t.skip,t},t.prototype.ssrInitiated=function(){return this.context&&this.context.renderPromises},t.prototype.getExecuteResult=function(){var e=this.getQueryResult();return this.startQuerySubscription(),e},t.prototype.getExecuteSsrResult=function(){var e=this.getOptions(),t=e.ssr,r=e.skip,n=!1===t,o=this.refreshClient().client.disableNetworkFetches,a=i({loading:!0,networkStatus:dr.loading,called:!0,data:void 0,stale:!1,client:this.client},this.observableQueryFields());if(n&&(this.ssrInitiated()||o))return this.previous.result=a,a;if(this.ssrInitiated()){var s=this.getQueryResult()||a;return s.loading&&!r&&this.context.renderPromises.addQueryPromise(this,(function(){return null})),s}},t.prototype.prepareObservableQueryOptions=function(){var e=this.getOptions();this.verifyDocumentType(e.query,wi.Query);var t=e.displayName||"Query";return!this.ssrInitiated()||"network-only"!==e.fetchPolicy&&"cache-and-network"!==e.fetchPolicy||(e.fetchPolicy="cache-first"),i(i({},e),{displayName:t,context:e.context})},t.prototype.initializeObservableQuery=function(){if(this.ssrInitiated()&&(this.currentObservable=this.context.renderPromises.getSSRObservable(this.getOptions())),!this.currentObservable){var e=this.prepareObservableQueryOptions();this.previous.observableQueryOptions=i(i({},e),{children:null}),this.currentObservable=this.refreshClient().client.watchQuery(i({},e)),this.ssrInitiated()&&this.context.renderPromises.registerSSRObservable(this.currentObservable,e)}},t.prototype.updateObservableQuery=function(){if(this.currentObservable){if(!this.getOptions().skip){var e=i(i({},this.prepareObservableQueryOptions()),{children:null});ur(e,this.previous.observableQueryOptions)||(this.previous.observableQueryOptions=e,this.currentObservable.setOptions(e).catch((function(){})))}}else this.initializeObservableQuery()},t.prototype.startQuerySubscription=function(e){var t=this;void 0===e&&(e=this.onNewData),this.currentSubscription||this.getOptions().skip||(this.currentSubscription=this.currentObservable.subscribe({next:function(r){var n=r.loading,i=r.networkStatus,o=r.data,a=t.previous.result;a&&a.loading===n&&a.networkStatus===i&&ur(a.data,o)||e()},error:function(r){if(t.resubscribeToQuery(),!r.hasOwnProperty("graphQLErrors"))throw r;var n=t.previous.result;(n&&n.loading||!ur(r,t.previous.error))&&(t.previous.error=r,e())}}))},t.prototype.resubscribeToQuery=function(){this.removeQuerySubscription();var e=this.currentObservable;if(e){var t=e.getLastError(),r=e.getLastResult();e.resetLastResults(),this.startQuerySubscription(),Object.assign(e,{lastError:t,lastResult:r})}},t.prototype.handleErrorOrCompleted=function(){if(this.currentObservable&&this.previous.result){var e=this.previous.result,t=e.data,r=e.loading,n=e.error;if(!r){var i=this.getOptions(),o=i.query,a=i.variables,s=i.onCompleted,u=i.onError,c=i.skip;if(this.previousOptions&&!this.previous.loading&&ur(this.previousOptions.query,o)&&ur(this.previousOptions.variables,a))return;!s||n||c?u&&n&&u(n):s(t)}}},t.prototype.removeQuerySubscription=function(){this.currentSubscription&&(this.currentSubscription.unsubscribe(),delete this.currentSubscription)},t.prototype.removeObservable=function(e){this.currentObservable&&(this.currentObservable.tearDownQuery(),e&&delete this.currentObservable)},t.prototype.observableQueryFields=function(){var e;return{variables:null===(e=this.currentObservable)||void 0===e?void 0:e.variables,refetch:this.obsRefetch,fetchMore:this.obsFetchMore,updateQuery:this.obsUpdateQuery,startPolling:this.obsStartPolling,stopPolling:this.obsStopPolling,subscribeToMore:this.obsSubscribeToMore}},t}(function(){function e(e,t){this.isMounted=!1,this.previousOptions={},this.context={},this.options={},this.options=e||{},this.context=t||{}}return e.prototype.getOptions=function(){return this.options},e.prototype.setOptions=function(e,t){void 0===t&&(t=!1),t&&!ur(this.options,e)&&(this.previousOptions=this.options),this.options=e},e.prototype.unmount=function(){this.isMounted=!1},e.prototype.refreshClient=function(){var e=this.options&&this.options.client||this.context&&this.context.client;d(!!e,29);var t=!1;return e!==this.client&&(t=!0,this.client=e,this.cleanup()),{client:this.client,isNew:t}},e.prototype.verifyDocumentType=function(e,t){var r=function(e){var t,r,n=Ti.get(e);if(n)return n;d(!!e&&!!e.kind,34);var i=e.definitions.filter((function(e){return"FragmentDefinition"===e.kind})),o=e.definitions.filter((function(e){return"OperationDefinition"===e.kind&&"query"===e.operation})),a=e.definitions.filter((function(e){return"OperationDefinition"===e.kind&&"mutation"===e.operation})),s=e.definitions.filter((function(e){return"OperationDefinition"===e.kind&&"subscription"===e.operation}));d(!i.length||o.length||a.length||s.length,35),d(o.length+a.length+s.length<=1,36),r=o.length?wi.Query:wi.Mutation,o.length||a.length||(r=wi.Subscription);var u=o.length?o:a.length?a:s;d(1===u.length,37);var c=u[0];t=c.variableDefinitions||[];var l={name:c.name&&"Name"===c.name.kind?c.name.value:"data",type:r,variables:t};return Ti.set(e,l),l}(e);xi(t),xi(r.type),d(r.type===t,30)},e}());function Ii(e,r,n){void 0===n&&(n=!1);var o=t.exports.useContext(Ei()),a=t.exports.useReducer((function(e){return e+1}),0),s=a[0],u=a[1],c=r?i(i({},r),{query:e}):{query:e},l=t.exports.useRef(),f=l.current||(l.current=new Ni({options:c,context:o,onNewData:function(){f.ssrInitiated()?u():Promise.resolve().then((function(){return l.current&&u()}))}}));f.setOptions(c),f.context=o;var p,h,d,v={options:i(i({},c),{onError:void 0,onCompleted:void 0}),context:o,tick:s},y=(p=function(){return n?f.executeLazy():f.execute()},h=v,(d=t.exports.useRef()).current&&ur(h,d.current.key)||(d.current={key:h,value:p()}),d.current.value),m=n?y[1]:y;return t.exports.useEffect((function(){return function(){return f.cleanup()}}),[]),t.exports.useEffect((function(){return f.afterExecute({lazy:n})}),[m.loading,m.networkStatus,m.error,m.data]),y}function _i(e,t){return Ii(e,t,!0)}export{ii as A,Wn as I,ki as a,gi as g,_i as u};
diff --git a/assets/index.302ac48d.css b/assets/index.302ac48d.css
new file mode 100644
index 0000000..4920091
--- /dev/null
+++ b/assets/index.302ac48d.css
@@ -0,0 +1 @@
+.blog-view{max-width:960px;margin:10px auto 0}.fzj-list-box{padding:0 12px 12px}.fzj-list{height:100%}.fzj-item{margin-bottom:10px}@media screen and (min-width: 768px){.fzj-list{display:flex;flex-wrap:wrap}.fzj-item{max-width:50%;min-width:50%;padding:8px;margin:0}}.fzj-card{width:100%;height:100%;position:relative;color:#343434;margin-bottom:12px;padding:24px 20px;background-color:#fff;font-size:14px;transition:all .3s ease;cursor:pointer}.fzj-card:hover{transition:all .3s ease;box-shadow:var(--shadow-floating);background-color:#fff}.fzj-card:last-child{margin-bottom:0}.fzj-card .title{font-size:18px;margin-bottom:8px;font-weight:bold;position:relative}.fzj-card .title span{background:linear-gradient(to bottom,transparent 50%,#e2e0da 50%)}.fzj-card img{max-width:640px!important;text-align:center}.fzj-card .issues{font-size:14px;position:absolute;top:0;right:0;display:inline-block;padding:5px 10px 0;line-height:20px;font-family:"lab";vertical-align:text-bottom;color:#666}.fzj-card .labels{margin-top:12px}.data-loading{text-align:center;font-size:14px;font-weight:bold}.loading-box{position:fixed;width:100%;display:flex;justify-content:center;align-items:center;height:100%}.loading-box .error-icon{width:120px;margin-top:-20vh}
diff --git a/assets/index.39fc9160.js b/assets/index.39fc9160.js
new file mode 100644
index 0000000..61a5950
--- /dev/null
+++ b/assets/index.39fc9160.js
@@ -0,0 +1 @@
+import{R as e}from"./react.434ff2b9.js";const t=({owner:t})=>e.createElement("a",{className:"gh-stats-card",href:`https://github.com/${t}`,target:"_blank",rel:"noreferrer"},e.createElement("img",{src:`https://lencx-stats.vercel.app/api/?username=${t}&show_icons=true&bg_color=320,323031,84a59d&icon_color=b0c4b1&title_color=eec170&text_color=a2a392&include_all_commits=true`,alt:`${t} stats`}));t.defaultProps={owner:"lencx"};var l=t;const r=({owner:t})=>e.createElement("a",{className:"gh-wakatime-card",href:`https://github.com/${t}`,target:"_blank",rel:"noreferrer"},e.createElement("img",{src:`https://lencx-stats.vercel.app/api/wakatime?username=${t}&layout=compact&bg_color=150,323031,84a59d&title_color=eec170&text_color=a2a392`,alt:`${t}'s wakatime`}));r.defaultProps={owner:"lencx"};var a=r;const c=({repo:t,site:l,owner:r,name:a,desc:c})=>e.createElement("tr",null,e.createElement("td",null,e.createElement("a",{href:l||`https://github.com/${r}/${t}`},a||`${r}/${t}`)),e.createElement("td",null,c),e.createElement("td",null,e.createElement("div",null,e.createElement("img",{alt:"Stars",src:`https://img.shields.io/github/stars/${r}/${t}?style=plastic&labelColor=373f51&color=e07a5f`}))),e.createElement("td",null,e.createElement("div",null,e.createElement("img",{alt:"Forks",src:`https://img.shields.io/github/forks/${r}/${t}?style=plastic&labelColor=373f51&color=e07a5f`}))));c.defaultProps={owner:"lencx"};var n=c;function s(){return e.createElement("div",{className:"project-view"},e.createElement("h2",null,"Open Source"),e.createElement("h3",null,"Stats"),e.createElement("div",{className:"gh-card-box"},e.createElement(l,null),e.createElement(a,null)),e.createElement("h3",null,"Projects"),e.createElement("div",{className:"repos"},e.createElement("table",null,e.createElement("thead",null,e.createElement("tr",null,e.createElement("th",null,"📦 Projects"),e.createElement("th",null,"📃 Description"),e.createElement("th",null,"⭐ Stars"),e.createElement("th",null,"📚 Forks"))),e.createElement("tbody",null,e.createElement(n,{repo:"z",desc:"〽️ 浮之静"}),e.createElement(n,{repo:"awesome",desc:"😎 Awesome lists about all kinds of interesting topics"}),e.createElement(n,{repo:"create-mpl",desc:"⚡️ Create a project in seconds!"}),e.createElement(n,{repo:"vite-plugin-rsw",desc:"🦀 wasm-pack plugin for Vite"}),e.createElement(n,{repo:"download-github",desc:"⬇️ Download directory from a GitHub repo."}),e.createElement(n,{repo:"rsw-node",desc:"⚪️ `wasm-pack build` executed in remote deployment"}),e.createElement(n,{repo:"learn-wasm",desc:"🎲 Learning WebAssembly"}),e.createElement(n,{repo:"rust-learn",desc:"🦀 Learning Rust"}),e.createElement(n,{repo:"code-snippets",desc:"✍️ code - 手写系列"}),e.createElement(n,{repo:"rgd",desc:"🍱 GitHub Discussions API - RSS & JSON"}),e.createElement(n,{repo:"woap",desc:"🌀 GitHub Discussions - 生成微信文章 (支持二维码及脚注形式)"}),e.createElement(n,{repo:"monthly",desc:"📰 学习总结,输出打卡"})))))}export{s as default};
diff --git a/assets/index.3bdcf399.js b/assets/index.3bdcf399.js
new file mode 100644
index 0000000..ef3c1bc
--- /dev/null
+++ b/assets/index.3bdcf399.js
@@ -0,0 +1 @@
+import{R as e}from"./react.434ff2b9.js";function t(){return e.createElement("div",{className:"about-view"},e.createElement("img",{className:"pic",src:"https://user-images.githubusercontent.com/16164244/119298318-607bbf80-bc8f-11eb-98da-e8277efe3249.png"}),e.createElement("div",{className:"fzj-desc lencx"},e.createElement("p",{className:"notes"},"lencx {折腾 ⇌ 迷茫 ⇌ 思考]ing,在路上..."),e.createElement("p",null,"生命在于折腾,折腾多了,必然迷茫,迷茫了,就停下来思考,想通了就重新上路。"),e.createElement("p",null,"在路上会禁不住“诱惑”而去折腾,折腾了,又迷茫,迷茫了,又思考,一直在路上。"),e.createElement("p",null,"循环往复,生生不息...")),e.createElement("div",{className:"fzj-desc"},"项目 ",e.createElement("a",{href:"https://github.com/lencx/z/discussions"},"Z")," ","字母由来:取首字母 FZJ,因过于繁琐,故取其中间字母 Z,Z 是一个很有意思的字母,像弹簧,蓄力愈久,反弹的力量就愈大。很符合 «浮之静» 之本意。"))}export{t as default};
diff --git a/assets/index.4b53168e.css b/assets/index.4b53168e.css
new file mode 100644
index 0000000..449ab40
--- /dev/null
+++ b/assets/index.4b53168e.css
@@ -0,0 +1 @@
+.markdown-body .octicon{display:inline-block;fill:currentColor;vertical-align:text-bottom}.markdown-body .anchor{float:left;line-height:1;margin-left:-20px;padding-right:4px}.markdown-body .anchor:focus{outline:none}.markdown-body h1 .octicon-link,.markdown-body h2 .octicon-link,.markdown-body h3 .octicon-link,.markdown-body h4 .octicon-link,.markdown-body h5 .octicon-link,.markdown-body h6 .octicon-link{color:#1b1f23;vertical-align:middle;visibility:hidden}.markdown-body h1:hover .anchor,.markdown-body h2:hover .anchor,.markdown-body h3:hover .anchor,.markdown-body h4:hover .anchor,.markdown-body h5:hover .anchor,.markdown-body h6:hover .anchor{text-decoration:none}.markdown-body h1:hover .anchor .octicon-link,.markdown-body h2:hover .anchor .octicon-link,.markdown-body h3:hover .anchor .octicon-link,.markdown-body h4:hover .anchor .octicon-link,.markdown-body h5:hover .anchor .octicon-link,.markdown-body h6:hover .anchor .octicon-link{visibility:visible}.markdown-body h1:hover .anchor .octicon-link:before,.markdown-body h2:hover .anchor .octicon-link:before,.markdown-body h3:hover .anchor .octicon-link:before,.markdown-body h4:hover .anchor .octicon-link:before,.markdown-body h5:hover .anchor .octicon-link:before,.markdown-body h6:hover .anchor .octicon-link:before{width:16px;height:16px;content:" ";display:inline-block;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' version='1.1' width='16' height='16' aria-hidden='true'%3E%3Cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z'%3E%3C/path%3E%3C/svg%3E")}.markdown-body{-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;color:#24292e;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji;font-size:16px;line-height:1.5;word-wrap:break-word}.markdown-body details{display:block}.markdown-body summary{display:list-item}.markdown-body a{background-color:initial}.markdown-body a:active,.markdown-body a:hover{outline-width:0}.markdown-body strong{font-weight:inherit;font-weight:bolder}.markdown-body h1{font-size:2em;margin:.67em 0}.markdown-body img{border-style:none}.markdown-body code,.markdown-body kbd,.markdown-body pre{font-family:monospace,monospace;font-size:1em}.markdown-body hr{box-sizing:initial;height:0;overflow:visible}.markdown-body input{font:inherit;margin:0}.markdown-body input{overflow:visible}.markdown-body [type=checkbox]{box-sizing:border-box;padding:0}.markdown-body *{box-sizing:border-box}.markdown-body input{font-family:inherit;font-size:inherit;line-height:inherit}.markdown-body a{color:#0366d6;text-decoration:none}.markdown-body a:hover{text-decoration:underline}.markdown-body strong{font-weight:600}.markdown-body hr{height:0;margin:15px 0;overflow:hidden;background:transparent;border:0;border-bottom:1px solid #dfe2e5}.markdown-body hr:after,.markdown-body hr:before{display:table;content:""}.markdown-body hr:after{clear:both}.markdown-body table{border-spacing:0;border-collapse:collapse}.markdown-body td,.markdown-body th{padding:0}.markdown-body details summary{cursor:pointer}.markdown-body h1,.markdown-body h2,.markdown-body h3,.markdown-body h4,.markdown-body h5,.markdown-body h6{margin-top:0;margin-bottom:0}.markdown-body h1{font-size:32px}.markdown-body h1,.markdown-body h2{font-weight:600}.markdown-body h2{font-size:24px}.markdown-body h3{font-size:20px}.markdown-body h3,.markdown-body h4{font-weight:600}.markdown-body h4{font-size:16px}.markdown-body h5{font-size:14px}.markdown-body h5,.markdown-body h6{font-weight:600}.markdown-body h6{font-size:12px}.markdown-body p{margin-top:0;margin-bottom:10px}.markdown-body blockquote{margin:0}.markdown-body ol,.markdown-body ul{padding-left:0;margin-top:0;margin-bottom:0}.markdown-body ol ol,.markdown-body ul ol{list-style-type:lower-roman}.markdown-body ol ol ol,.markdown-body ol ul ol,.markdown-body ul ol ol,.markdown-body ul ul ol{list-style-type:lower-alpha}.markdown-body dd{margin-left:0}.markdown-body code,.markdown-body pre{font-family:SFMono-Regular,Consolas,Liberation Mono,Menlo,monospace;font-size:12px}.markdown-body pre{margin-top:0;margin-bottom:0}.markdown-body input::-webkit-inner-spin-button,.markdown-body input::-webkit-outer-spin-button{margin:0;-webkit-appearance:none;appearance:none}.markdown-body :checked+.radio-label{position:relative;z-index:1;border-color:#0366d6}.markdown-body .border{border:1px solid #e1e4e8!important}.markdown-body .border-0{border:0!important}.markdown-body .border-bottom{border-bottom:1px solid #e1e4e8!important}.markdown-body .rounded-1{border-radius:3px!important}.markdown-body .bg-white{background-color:#fff!important}.markdown-body .bg-gray-light{background-color:#fafbfc!important}.markdown-body .text-gray-light{color:#6a737d!important}.markdown-body .my-2{margin-top:8px!important;margin-bottom:8px!important}.markdown-body .pl-3,.markdown-body .px-3{padding-left:16px!important}.markdown-body .px-3{padding-right:16px!important}.markdown-body .f6{font-size:12px!important}.markdown-body .lh-condensed{line-height:1.25!important}.markdown-body .text-bold{font-weight:600!important}.markdown-body .pl-c{color:#6a737d}.markdown-body .pl-c1,.markdown-body .pl-s .pl-v{color:#005cc5}.markdown-body .pl-e,.markdown-body .pl-en{color:#6f42c1}.markdown-body .pl-s .pl-s1,.markdown-body .pl-smi{color:#24292e}.markdown-body .pl-ent{color:#22863a}.markdown-body .pl-k{color:#d73a49}.markdown-body .pl-pds,.markdown-body .pl-s,.markdown-body .pl-s .pl-pse .pl-s1,.markdown-body .pl-sr,.markdown-body .pl-sr .pl-cce,.markdown-body .pl-sr .pl-sra,.markdown-body .pl-sr .pl-sre{color:#032f62}.markdown-body .pl-smw,.markdown-body .pl-v{color:#e36209}.markdown-body .pl-bu{color:#b31d28}.markdown-body .pl-ii{color:#fafbfc;background-color:#b31d28}.markdown-body .pl-c2{color:#fafbfc;background-color:#d73a49}.markdown-body .pl-c2:before{content:"^M"}.markdown-body .pl-sr .pl-cce{font-weight:700;color:#22863a}.markdown-body .pl-ml{color:#735c0f}.markdown-body .pl-mh,.markdown-body .pl-mh .pl-en,.markdown-body .pl-ms{font-weight:700;color:#005cc5}.markdown-body .pl-mi{font-style:italic;color:#24292e}.markdown-body .pl-mb{font-weight:700;color:#24292e}.markdown-body .pl-md{color:#b31d28;background-color:#ffeef0}.markdown-body .pl-mi1{color:#22863a;background-color:#f0fff4}.markdown-body .pl-mc{color:#e36209;background-color:#ffebda}.markdown-body .pl-mi2{color:#f6f8fa;background-color:#005cc5}.markdown-body .pl-mdr{font-weight:700;color:#6f42c1}.markdown-body .pl-ba{color:#586069}.markdown-body .pl-sg{color:#959da5}.markdown-body .pl-corl{text-decoration:underline;color:#032f62}.markdown-body .mb-0{margin-bottom:0!important}.markdown-body .my-2{margin-bottom:8px!important}.markdown-body .my-2{margin-top:8px!important}.markdown-body .pl-0{padding-left:0!important}.markdown-body .py-0{padding-top:0!important;padding-bottom:0!important}.markdown-body .pl-1{padding-left:4px!important}.markdown-body .pl-2{padding-left:8px!important}.markdown-body .py-2{padding-top:8px!important;padding-bottom:8px!important}.markdown-body .pl-3{padding-left:16px!important}.markdown-body .pl-4{padding-left:24px!important}.markdown-body .pl-5{padding-left:32px!important}.markdown-body .pl-6{padding-left:40px!important}.markdown-body .pl-7{padding-left:48px!important}.markdown-body .pl-8{padding-left:64px!important}.markdown-body .pl-9{padding-left:80px!important}.markdown-body .pl-10{padding-left:96px!important}.markdown-body .pl-11{padding-left:112px!important}.markdown-body .pl-12{padding-left:128px!important}.markdown-body hr{border-bottom-color:#eee}.markdown-body kbd{display:inline-block;padding:3px 5px;font:11px SFMono-Regular,Consolas,Liberation Mono,Menlo,monospace;line-height:10px;color:#444d56;vertical-align:middle;background-color:#fafbfc;border:1px solid #d1d5da;border-radius:3px;box-shadow:inset 0 -1px #d1d5da}.markdown-body:after,.markdown-body:before{display:table;content:""}.markdown-body:after{clear:both}.markdown-body>:first-child{margin-top:0!important}.markdown-body>:last-child{margin-bottom:0!important}.markdown-body a:not([href]){color:inherit;text-decoration:none}.markdown-body blockquote,.markdown-body details,.markdown-body dl,.markdown-body ol,.markdown-body p,.markdown-body pre,.markdown-body table,.markdown-body ul{margin-top:0;margin-bottom:16px}.markdown-body hr{height:.25em;padding:0;margin:24px 0;background-color:#e1e4e8;border:0}.markdown-body blockquote{padding:0 1em;color:#6a737d;border-left:.25em solid #dfe2e5}.markdown-body blockquote>:first-child{margin-top:0}.markdown-body blockquote>:last-child{margin-bottom:0}.markdown-body h1,.markdown-body h2,.markdown-body h3,.markdown-body h4,.markdown-body h5,.markdown-body h6{margin-top:24px;margin-bottom:16px;font-weight:600;line-height:1.25}.markdown-body h1{font-size:2em}.markdown-body h1,.markdown-body h2{padding-bottom:.3em;border-bottom:1px solid #eaecef}.markdown-body h2{font-size:1.5em}.markdown-body h3{font-size:1.25em}.markdown-body h4{font-size:1em}.markdown-body h5{font-size:.875em}.markdown-body h6{font-size:.85em;color:#6a737d}.markdown-body ol,.markdown-body ul{padding-left:2em}.markdown-body ol ol,.markdown-body ol ul,.markdown-body ul ol,.markdown-body ul ul{margin-top:0;margin-bottom:0}.markdown-body li{word-wrap:break-all}.markdown-body li>p{margin-top:16px}.markdown-body li+li{margin-top:.25em}.markdown-body dl{padding:0}.markdown-body dl dt{padding:0;margin-top:16px;font-size:1em;font-style:italic;font-weight:600}.markdown-body dl dd{padding:0 16px;margin-bottom:16px}.markdown-body table{display:block;width:100%;overflow:auto}.markdown-body table th{font-weight:600}.markdown-body table td,.markdown-body table th{padding:6px 13px;border:1px solid #dfe2e5}.markdown-body table tr{background-color:#fff;border-top:1px solid #c6cbd1}.markdown-body table tr:nth-child(2n){background-color:#f6f8fa}.markdown-body img{max-width:100%;box-sizing:initial;background-color:#fff}.markdown-body img[align=right]{padding-left:20px}.markdown-body img[align=left]{padding-right:20px}.markdown-body code{padding:.2em .4em;margin:0;font-size:85%;background-color:#1b1f230d;border-radius:3px}.markdown-body pre{word-wrap:normal}.markdown-body pre>code{padding:0;margin:0;font-size:100%;word-break:normal;white-space:pre;background:transparent;border:0}.markdown-body .highlight{margin-bottom:16px}.markdown-body .highlight pre{margin-bottom:0;word-break:normal}.markdown-body .highlight pre,.markdown-body pre{padding:16px;overflow:auto;font-size:85%;line-height:1.45;background-color:#f6f8fa;border-radius:3px}.markdown-body pre code{display:inline;max-width:auto;padding:0;margin:0;overflow:visible;line-height:inherit;word-wrap:normal;background-color:initial;border:0}.markdown-body .commit-tease-sha{display:inline-block;font-family:SFMono-Regular,Consolas,Liberation Mono,Menlo,monospace;font-size:90%;color:#444d56}.markdown-body .full-commit .btn-outline:not(:disabled):hover{color:#005cc5;border-color:#005cc5}.markdown-body .blob-wrapper{overflow-x:auto;overflow-y:hidden}.markdown-body .blob-wrapper-embedded{max-height:240px;overflow-y:auto}.markdown-body .blob-num{width:1%;min-width:50px;padding-right:10px;padding-left:10px;font-family:SFMono-Regular,Consolas,Liberation Mono,Menlo,monospace;font-size:12px;line-height:20px;color:#1b1f234d;text-align:right;white-space:nowrap;vertical-align:top;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.markdown-body .blob-num:hover{color:#1b1f2399}.markdown-body .blob-num:before{content:attr(data-line-number)}.markdown-body .blob-code{position:relative;padding-right:10px;padding-left:10px;line-height:20px;vertical-align:top}.markdown-body .blob-code-inner{overflow:visible;font-family:SFMono-Regular,Consolas,Liberation Mono,Menlo,monospace;font-size:12px;color:#24292e;word-wrap:normal;white-space:pre}.markdown-body .pl-token.active,.markdown-body .pl-token:hover{cursor:pointer;background:#ffea7f}.markdown-body .tab-size[data-tab-size="1"]{-moz-tab-size:1;tab-size:1}.markdown-body .tab-size[data-tab-size="2"]{-moz-tab-size:2;tab-size:2}.markdown-body .tab-size[data-tab-size="3"]{-moz-tab-size:3;tab-size:3}.markdown-body .tab-size[data-tab-size="4"]{-moz-tab-size:4;tab-size:4}.markdown-body .tab-size[data-tab-size="5"]{-moz-tab-size:5;tab-size:5}.markdown-body .tab-size[data-tab-size="6"]{-moz-tab-size:6;tab-size:6}.markdown-body .tab-size[data-tab-size="7"]{-moz-tab-size:7;tab-size:7}.markdown-body .tab-size[data-tab-size="8"]{-moz-tab-size:8;tab-size:8}.markdown-body .tab-size[data-tab-size="9"]{-moz-tab-size:9;tab-size:9}.markdown-body .tab-size[data-tab-size="10"]{-moz-tab-size:10;tab-size:10}.markdown-body .tab-size[data-tab-size="11"]{-moz-tab-size:11;tab-size:11}.markdown-body .tab-size[data-tab-size="12"]{-moz-tab-size:12;tab-size:12}.markdown-body .task-list-item{list-style-type:none}.markdown-body .task-list-item+.task-list-item{margin-top:3px}.markdown-body .task-list-item input{margin:0 .2em .25em -1.6em;vertical-align:middle}.github-lencx-z{cursor:pointer;display:inline-block;width:24px;height:24px}.github-lencx-z img{overflow:hidden}.menu-btn{position:fixed;top:14px;right:10px;z-index:100;width:28px;height:28px;cursor:pointer;vertical-align:-2px}.bm-burger-bars{background:#373a47}.bm-cross-button{height:24px;width:24px}.bm-cross{background:#bdc3c7}.bm-menu-wrap{position:fixed;height:100%;top:0}.bm-menu{background:#373a47;padding:2.5em 1.5em 0;font-size:1.15em}.bm-morph-shape{fill:#373a47}.bm-item-list{color:#b8b7ad;padding:.8em}.bm-item{display:inline-block;padding:10px;font-size:1.5rem;cursor:pointer;color:#d8d8d8;outline:none;text-align:center;font-family:"lab";font-variation-settings:"size" 30,"quad" 40,"bevl" 20,"oval" 30}.bm-overlay{background:rgba(0,0,0,.3);top:0;left:0}.fzj-header{width:100%;height:60px;position:fixed;background-color:#24292e;display:flex;align-items:center;justify-content:space-between;padding:0 12px;box-shadow:1px 1px 2px #ddd;z-index:99;top:0;left:0}.fzj-header .logo-box{cursor:pointer}.fzj-header .logo{background-image:url(/assets/fzj.883a7505.svg);background-repeat:no-repeat;background-size:100%;width:61px;height:24px}.fzj-header .desc{background-image:url(/assets/fzj-desc.da5cfda0.svg);background-repeat:no-repeat;background-size:100%;width:165px;height:12px;margin-top:3px}.fzj-header .fzj-btns{width:100px}.fzj-header .fzj-rss{width:28px;vertical-align:-3px;margin-right:10px;cursor:pointer}.fzj-footer{padding:20px 0;text-align:center}.fzj-footer a{font-weight:bold}#fzj-backtop{width:42px;height:42px;position:fixed;bottom:20px;right:20px;border-radius:50%;display:flex;justify-content:center;align-items:center;transition:all .5s ease;box-shadow:inset 0 0 5px #888;cursor:pointer}@media screen and (max-width: 767px){#fzj-backtop{width:36px;height:36px}}#fzj-backtop svg{width:50%}#fzj-backtop.hide{transform:scale(0);opacity:0}#fzj-backtop.show{transform:scale(1);opacity:1}@font-face{font-family:"lab";src:url(/lab.woff2) format("woff2")}html,body,#root{margin:0;font-family:DOS,Monaco,Menlo,Consolas,"Courier New",monospace;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;min-height:100vh;scroll-behavior:smooth;font-size:14px;line-height:1.4;touch-action:pan-x pan-y}body{background-image:url(/assets/bg.4189c4f0.png);background-repeat:repeat;background-size:100px;background-color:#f5f8fa}code{font-family:source-code-pro,Menlo,Monaco,Consolas,"Courier New",monospace;background-color:#dbdee2;padding:0 5px;border-radius:3px}blockquote{border-left:solid 3px var(--blue);margin:0}blockquote>p{margin-left:8px}pre{overflow-x:auto;padding:10px;border-radius:2px;font-family:"Courier New",Courier,monospace;border:solid 2px #e0e4e8}pre code{background-color:transparent}img{max-width:100%;width:100%}:root{--theme: #3c92a8;--black: #282c34;--pink: #f87da9;--blue: #4285f4;--border-color: #e0e4e8;--border: solid 1px var(--border-color);--shadow-raised: 0 1px 2px rgba(46, 41, 51, .08), 0 2px 4px rgba(71, 63, 79, .08);--shadow-floating: 0 2px 4px rgba(46, 41, 51, .08), 0 4px 8px rgba(71, 63, 79, .16);--shadow-overlay: 0 4px 8px rgba(46, 41, 51, .08), 0 8px 16px rgba(71, 63, 79, .16);--shadow-dialog: 0 4px 16px rgba(46, 41, 51, .08), 0 8px 24px rgba(71, 63, 79, .16)}.view{padding-top:58px;min-height:100vh;max-width:960px;margin:0 auto}.view>[class*=-view]{min-height:calc(100vh - 118px)}.view>[class*=-view]:before,.view>[class*=-view]:after{display:block;content:"";clear:both}.view .fzj-emoji{display:inline-block;margin-right:5px}ul{padding-left:24px!important}li{margin-bottom:6px}a{color:var(--blue)}*{box-sizing:border-box}
diff --git a/assets/index.5119c8ec.js b/assets/index.5119c8ec.js
new file mode 100644
index 0000000..111080e
--- /dev/null
+++ b/assets/index.5119c8ec.js
@@ -0,0 +1 @@
+import{R as e}from"./react.434ff2b9.js";import{h as a,c as s}from"./index.f90eabce.js";import{c as o}from"./fzj.08fd6cc8.js";var t=({name:o,emoji:t})=>e.createElement("span",{className:"fzj-category",onClick:e=>{e.stopPropagation(),a(s(o))}},e.createElement("span",{className:"fzj-emoji",dangerouslySetInnerHTML:{__html:t}}),o);var n=({className:s,name:t,color:n})=>{const c=`https://github.com/lencx/z/discussions?discussions_q=label%3A${t}`;return e.createElement("span",{style:{background:`#${n}`},className:o("fzj-label",s),onClick:e=>{e.stopPropagation(),a(c)}},e.createElement("span",null,t))};export{t as C,n as L};
diff --git a/assets/index.54af1b7f.css b/assets/index.54af1b7f.css
new file mode 100644
index 0000000..99739f5
--- /dev/null
+++ b/assets/index.54af1b7f.css
@@ -0,0 +1 @@
+.fzj-avatar{display:inline-block;border-radius:4px;padding-right:8px;text-decoration:none;overflow:hidden;vertical-align:bottom;cursor:pointer}.fzj-avatar img{width:20px;vertical-align:middle;border-radius:4px}.fzj-avatar span{font-size:12px;font-weight:500;margin-left:4px;font-style:italic;color:#666}
diff --git a/assets/index.5f87edea.js b/assets/index.5f87edea.js
new file mode 100644
index 0000000..a8cc11c
--- /dev/null
+++ b/assets/index.5f87edea.js
@@ -0,0 +1 @@
+import{R as e}from"./react.434ff2b9.js";import{b as a,E as t,L as r}from"./fzj.08fd6cc8.js";import{C as s,L as o}from"./index.5119c8ec.js";import"./lodash.71f9f2ff.js";import"./graphql.8e66ecff.js";import"./index.f90eabce.js";function m(){const{data:m,loading:i,error:l}=a();if(l)return e.createElement(t,{type:"blog"});if(i||!m.repository)return e.createElement(r,null);const{discussionCategories:n,labels:c}=m.repository;return e.createElement("div",{className:"tags-view"},e.createElement("h2",null,"Categories & Labels"),e.createElement("div",{className:"tag-categories"},n.edges.map((({node:a})=>e.createElement(s,{key:a.id,name:a.name,emoji:a.emojiHTML})))),e.createElement("div",{className:"tag-labels"},c.edges.map((({node:a})=>e.createElement(o,{key:a.id,name:a.name,color:a.color})))))}export{m as default};
diff --git a/assets/index.6c2ed225.css b/assets/index.6c2ed225.css
new file mode 100644
index 0000000..8d94584
--- /dev/null
+++ b/assets/index.6c2ed225.css
@@ -0,0 +1 @@
+.project-view h2{padding:0 15px;margin-bottom:0;font-size:28px;font-family:"lab";font-variation-settings:"size" 30,"quad" 40,"bevl" 40,"oval" 10}.project-view h3{padding:0 15px;margin-bottom:0;font-size:20px;font-family:"lab";font-variation-settings:"size" 30,"quad" 40,"bevl" 40,"oval" 10}.project-view .gh-card-box{padding:10px;display:flex;flex-wrap:wrap}.project-view .gh-card-box .gh-stats-card,.project-view .gh-card-box .gh-wakatime-card{padding:2px}.project-view .gh-card-box .gh-repo-card{padding:2px 5px;flex-grow:2}.project-view .repos{width:100%;font-size:12px;padding:12px;font-family:-apple-system,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji}.project-view .repos table{width:100%;text-align:center;border-collapse:collapse}.project-view .repos thead{background-color:#393a3a}.project-view .repos thead th{border:solid 1px #d2d2d2;padding:10px;color:#fff}.project-view .repos thead th:first-child{border-left:solid 1px #393a3a}.project-view .repos thead th:last-child{border-right:solid 1px #393a3a}.project-view .repos tbody img{height:unset;width:unset}.project-view .repos tbody tr{background-color:#f0f0f0}.project-view .repos tbody tr:nth-child(2n){background-color:#fafafa}.project-view .repos tbody td{border:solid 1px #d2d2d2;padding:10px}.project-view .repos tbody td a{font-weight:bold}.project-view .repos tbody td>div{display:flex;height:100%;width:100%;align-items:center;justify-content:center}
diff --git a/assets/index.735d43ee.css b/assets/index.735d43ee.css
new file mode 100644
index 0000000..19ec5b5
--- /dev/null
+++ b/assets/index.735d43ee.css
@@ -0,0 +1 @@
+.comment-item{padding:3px 3px 0;margin-bottom:10px;border-bottom:solid 2px rgba(0,0,0,.3)}.comment-item:last-child{margin-bottom:0;border-bottom:none}.comment-author{line-height:0;border-radius:4px!important;background:#535d6f}.comment-author img{border-radius:0!important;border-color:transparent!important}.comment-author span{font-weight:bold;color:#eee!important}.comment-body{padding:8px 8px 0}.comment-body h2{padding-top:0!important;margin-top:5px!important}.comment-main{background-color:#fcfcfc;padding:1px 8px;border-radius:5px}.comment-replies{padding:2px 2px 12px}.comment-replies-author img{border-radius:50%;z-index:1}.comment-replies-body{position:relative;margin-left:24px;clear:both;background-color:#fcfcfc;padding:5px;border-radius:5px}.comment-replies-body:before{position:absolute;display:inline-block;content:"";width:1px;height:100%;border-left:dashed 2px rgba(0,0,0,.1);left:-15px;z-index:-1}.comment img{max-width:420px!important}.post-date{display:inline-block;margin-right:5px;font-size:12px;font-weight:400}.post-date b{background-color:#eee;border:solid 1px #eee;padding:2px;border-top-left-radius:4px;border-bottom-left-radius:4px}.post-date span{box-sizing:border-box;border:solid 1px #eee;border-top-right-radius:4px;border-bottom-right-radius:4px;padding:2px;color:#999}.fzj-reaction{border:solid 1px #d8d8d8;padding:2px 8px;margin-right:5px;border-radius:5px;color:#686868;font-weight:bold;margin-bottom:5px}.fzj-reaction .emoji{margin-right:5px}.issues-view{padding-top:0!important}.issues-view.notes p img{display:inline-block;width:unset!important}.issues-view .post{max-width:960px;margin:0 auto;min-height:calc(100vh - 150px);font-size:14px;position:relative;font-family:-apple-system,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji}.issues-view .post .fzj-post{padding:1px 12px 20px;background-color:#fff;margin-bottom:20px}.issues-view .post .fzj-comment{background-color:#2222221a;border:solid 2px rgba(0,0,0,.3)}.issues-view .post .woap{position:absolute;right:10px;top:10px;width:30px;cursor:pointer}.issues-view .post img.emoji{max-width:unset;width:unset;transform:scale(.8);vertical-align:sub}.issues-view .post h1.title{text-align:center;padding:20px 0 10px;cursor:pointer;font-family:"lab";hyphens:none}.issues-view .post h1.title>span{padding-right:5px;background:linear-gradient(to bottom,transparent 60%,#c4cfc0 40%);font-variation-settings:"size" 50,"quad" 70,"bevl" 40,"oval" 80}.issues-view .post h1.title .issues{font-size:14px;margin-right:8px;color:#fff;font-weight:bold;font-style:italic;background-color:#c4cfc0;padding:6px 10px 0;border-top-left-radius:12px;text-shadow:0 0 1px #000}@media screen and (max-width: 680px){.issues-view .post h1.title{font-size:18px;line-height:28px;font-variation-settings:"size" 400,"quad" 1000,"bevl" 1000,"oval" 1000}.issues-view .post h1.title .issues{font-size:12px}}.issues-view .post h1,.issues-view .post h2,.issues-view .post h3,.issues-view .post h4,.issues-view .post h5,.issues-view .post h6{border-bottom:none;margin-top:1rem;margin-bottom:.6rem}.issues-view .post h2{font-size:1.3rem}.issues-view .post h3{font-size:1.2rem}.issues-view .post h4{font-size:1.1rem}.issues-view .post h5{font-size:1rem}.issues-view .post h6{font-size:.9rem}.issues-view .post .date{margin-bottom:10px;text-align:center}.issues-view .post .status{margin-bottom:10px}
diff --git a/assets/index.908b2c85.css b/assets/index.908b2c85.css
new file mode 100644
index 0000000..e867356
--- /dev/null
+++ b/assets/index.908b2c85.css
@@ -0,0 +1 @@
+.fzj-category{display:inline-block;color:#f8f8f8;background:#2a2a2a;line-height:20px;font-size:12px;font-weight:bold;padding:0 8px;text-align:center;border-radius:4px;margin-right:10px;cursor:pointer;text-shadow:0 0 1px #f8f8f8}.fzj-label{margin-right:3px;padding:2px 5px;color:#fff;border-radius:3px;font-size:12px;display:inline-block;cursor:pointer}
diff --git a/assets/index.a5f9fb0d.js b/assets/index.a5f9fb0d.js
new file mode 100644
index 0000000..eeae205
--- /dev/null
+++ b/assets/index.a5f9fb0d.js
@@ -0,0 +1 @@
+import{R as a}from"./react.434ff2b9.js";import{c as e}from"./fzj.08fd6cc8.js";var r=({className:r,avatar:t,name:c,onClick:s})=>a.createElement("div",{className:e("fzj-avatar",r),onClick:a=>{a.stopPropagation(),s&&s()}},a.createElement("img",{src:t}),a.createElement("span",null,c));export{r as A};
diff --git a/assets/index.c4924ca0.css b/assets/index.c4924ca0.css
new file mode 100644
index 0000000..5190e31
--- /dev/null
+++ b/assets/index.c4924ca0.css
@@ -0,0 +1 @@
+.tags-view{padding:0 12px 20px}.tags-view h2{font-size:28px;font-family:"lab";font-variation-settings:"size" 30,"quad" 40,"bevl" 40,"oval" 10}.tags-view .fzj-category{margin-bottom:10px}.tags-view .fzj-label{margin-bottom:5px}
diff --git a/assets/index.d15a088f.css b/assets/index.d15a088f.css
new file mode 100644
index 0000000..d8254b8
--- /dev/null
+++ b/assets/index.d15a088f.css
@@ -0,0 +1 @@
+.about-view{padding:20px 12px}.about-view .pic{border-radius:4px}.about-view .fzj-desc{font-size:16px;font-weight:bold;color:#444;line-height:1.6;border-radius:0;box-shadow:inset 0 0 10px #888;padding:10px;margin-bottom:5px}.about-view .fzj-desc.lencx{font-size:12px;padding:8px;color:#888}.about-view .fzj-desc.lencx .notes{color:#000;font-size:14px}.about-view .fzj-desc.lencx p{margin:0}
diff --git a/assets/index.e0d0297d.js b/assets/index.e0d0297d.js
new file mode 100644
index 0000000..630cb3f
--- /dev/null
+++ b/assets/index.e0d0297d.js
@@ -0,0 +1 @@
+import{u as e,R as a}from"./react.434ff2b9.js";import{A as t}from"./index.a5f9fb0d.js";import{u as s,E as l,L as r}from"./fzj.08fd6cc8.js";import{C as m,L as n}from"./index.5119c8ec.js";import{h as c,d as o}from"./index.f90eabce.js";import"./lodash.71f9f2ff.js";import"./graphql.8e66ecff.js";function i(){const i=e(),{data:d,loading:f,error:E}=s();return E?a.createElement(l,{type:"blog"}):a.createElement("div",{className:"blog-view"},a.createElement("div",{className:"fzj-list-box"},a.createElement("div",{className:"fzj-list"},d.map((({node:e,cursor:s})=>{const{category:l,author:r,number:d,labels:f}=e;return a.createElement("div",{key:s,className:"fzj-item"},a.createElement("div",{className:"fzj-card",onClick:e=>((e,a)=>{e.stopPropagation(),i.push(`/issues/${a}`)})(e,d)},a.createElement("em",{className:"issues",onClick:e=>c(o(d),e)},"#",d),a.createElement("div",{className:"title"},a.createElement("span",null,e.title)),a.createElement("div",{className:"info"},a.createElement(m,{name:l.name,emoji:l.emojiHTML}),a.createElement(t,{avatar:r.avatarUrl,name:r.login,onClick:()=>c(r.url)}),a.createElement("div",{className:"labels"},f.edges.map((({node:e})=>a.createElement(n,{key:e.id,name:e.name,color:e.color})))))))})))),f&&d.length>0&&a.createElement("div",{className:"data-loading"},"Loading..."),a.createElement(r,{visible:f&&0===d.length}))}export{i as default};
diff --git a/assets/index.e5525a57.js b/assets/index.e5525a57.js
new file mode 100644
index 0000000..296bf70
--- /dev/null
+++ b/assets/index.e5525a57.js
@@ -0,0 +1 @@
+import{R as e,k as a,z as t}from"./react.434ff2b9.js";import{c as s,a as n,L as l,E as r}from"./fzj.08fd6cc8.js";import{A as m}from"./index.a5f9fb0d.js";import{h as c,f as o,r as i,d}from"./index.f90eabce.js";import"./lodash.71f9f2ff.js";import"./graphql.8e66ecff.js";const u=({data:a})=>e.createElement("div",{className:"comment-replies"},a.edges.map((({node:a},t)=>e.createElement("div",{key:+t},e.createElement(m,{className:"comment-replies-author",avatar:a.author.avatarUrl,name:a.author.login,onClick:()=>c(a.author.url)}),e.createElement("div",{className:"comment-replies-body",dangerouslySetInnerHTML:{__html:a.bodyHTML}})))));var p=({data:a})=>{const{author:t,replies:s}=a;return e.createElement("div",{className:"comment-item",key:a.id},e.createElement(m,{className:"comment-author",avatar:t.avatarUrl,name:t.login,onClick:()=>c(t.url)}),e.createElement("div",{className:"comment-body"},e.createElement("div",{className:"comment-main",dangerouslySetInnerHTML:{__html:a.bodyHTML}}),e.createElement(u,{data:s})))};const E=({type:a,date:t})=>e.createElement("div",{className:"post-date"},e.createElement("b",null,"create"===a?"📅":"🔄"),e.createElement("span",null,o(t)));E.defaultProps={type:"create"};var f=E;var v=({className:a,emoji:t,count:n})=>e.createElement("span",{className:s("fzj-reaction",a)},e.createElement("span",{className:"emoji"},t),e.createElement("span",{className:"count"},n));function N(){var m;const{issues:o}=a(),{data:u,loading:E,error:N}=n(o);if(E)return e.createElement(l,null);if(N)return e.createElement(r,{type:"issues",issues:o});if(!u)return null;const{title:g,bodyHTML:y,comments:h,reactions:j,category:b,labels:k,createdAt:w,updatedAt:L}=u,_=null==(m=null==k?void 0:k.edges)?void 0:m.some((({node:e})=>["wechat-link","wechat-post","微信杂谈"].includes(e.name)));return e.createElement("div",{className:s("issues-view",b.name.toLocaleLowerCase())},e.createElement(t,null,e.createElement("title",null,"浮之静|",g)),e.createElement("div",{className:"post markdown-body"},e.createElement("div",{className:"fzj-post"},_&&e.createElement("img",{className:"woap",src:"/assets/woap.99c96107.svg",alt:"woap",onClick:()=>{window.open(`${window.location.origin}/posts/issues-${o.toString().padStart(4,"0")}`,"__blank")}}),e.createElement("h1",{className:"title",onClick:()=>c(d(o))},e.createElement("span",null,e.createElement("span",{className:"issues"},"#",o),e.createElement("span",null,g))),e.createElement("div",{className:"date"},e.createElement(f,{date:w}),e.createElement(f,{type:"update",date:L})),e.createElement("div",{className:"status"},i(j.edges).map((a=>e.createElement(v,{key:a[0],emoji:a[0],count:a[1]})))),e.createElement("div",{dangerouslySetInnerHTML:{__html:y}})),h.edges.length>0&&e.createElement("div",{className:"fzj-comment"},h.edges.map((({node:a})=>e.createElement(p,{key:a.id,data:a}))))))}export{N as default};
diff --git a/assets/index.f90eabce.js b/assets/index.f90eabce.js
new file mode 100644
index 0000000..248e3be
--- /dev/null
+++ b/assets/index.f90eabce.js
@@ -0,0 +1 @@
+var t=Object.defineProperty,e=Object.defineProperties,n=Object.getOwnPropertyDescriptors,r=Object.getOwnPropertySymbols,a=Object.prototype.hasOwnProperty,i=Object.prototype.propertyIsEnumerable,o=(e,n,r)=>n in e?t(e,n,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[n]=r,s=(t,e)=>{for(var n in e||(e={}))a.call(e,n)&&o(t,n,e[n]);if(r)for(var n of r(e))i.call(e,n)&&o(t,n,e[n]);return t};import{R as l,r as u,p as c,a as f,u as d,b as h,z as p,c as m,S as v,d as y,H as x,e as b,f as w}from"./react.434ff2b9.js";import{I as C,A as F,a as E}from"./graphql.8e66ecff.js";import{c as O}from"./lodash.71f9f2ff.js";!function(){const t=document.createElement("link").relList;if(!(t&&t.supports&&t.supports("modulepreload"))){for(const t of document.querySelectorAll('link[rel="modulepreload"]'))e(t);new MutationObserver((t=>{for(const n of t)if("childList"===n.type)for(const t of n.addedNodes)"LINK"===t.tagName&&"modulepreload"===t.rel&&e(t)})).observe(document,{childList:!0,subtree:!0})}function e(t){if(t.ep)return;t.ep=!0;const e=function(t){const e={};return t.integrity&&(e.integrity=t.integrity),t.referrerpolicy&&(e.referrerPolicy=t.referrerpolicy),"use-credentials"===t.crossorigin?e.credentials="include":"anonymous"===t.crossorigin?e.credentials="omit":e.credentials="same-origin",e}(t);fetch(t.href,e)}}();const S=new C({typePolicies:{Query:{fields:{repository:{keyArgs:[],merge:(t,e)=>e}}}}});var T=new F({uri:"https://api.github.com/graphql",headers:{Authorization:`token ${atob("Z2hwX3d6cVptU2liWUVaQTB3VVNxUktaU05BYmFXUGxHUjJQZ2oyTw==")}`},cache:S});function A(){return l.createElement("a",{className:"github-lencx-z",href:"https://github.com/lencx/z/discussions"},l.createElement("img",{src:"/assets/github.cf8a9345.svg"}))}var M={exports:{}},k={exports:{}},B={exports:{}},N={exports:{}};!function(t,e){Object.defineProperty(e,"__esModule",{value:!0});e.default={overlay:function(t){return{position:"fixed",zIndex:1e3,width:"100%",height:"100%",background:"rgba(0, 0, 0, 0.3)",opacity:t?1:0,MozTransform:t?"":"translate3d(100%, 0, 0)",MsTransform:t?"":"translate3d(100%, 0, 0)",OTransform:t?"":"translate3d(100%, 0, 0)",WebkitTransform:t?"":"translate3d(100%, 0, 0)",transform:t?"":"translate3d(100%, 0, 0)",transition:t?"opacity 0.3s":"opacity 0.3s, transform 0s 0.3s"}},menuWrap:function(t,e,n){return{position:"fixed",right:n?0:"inherit",zIndex:1100,width:e,height:"100%",MozTransform:t?"":n?"translate3d(100%, 0, 0)":"translate3d(-100%, 0, 0)",MsTransform:t?"":n?"translate3d(100%, 0, 0)":"translate3d(-100%, 0, 0)",OTransform:t?"":n?"translate3d(100%, 0, 0)":"translate3d(-100%, 0, 0)",WebkitTransform:t?"":n?"translate3d(100%, 0, 0)":"translate3d(-100%, 0, 0)",transform:t?"":n?"translate3d(100%, 0, 0)":"translate3d(-100%, 0, 0)",transition:"all 0.5s"}},menu:function(){return{height:"100%",boxSizing:"border-box",overflow:"auto"}},itemList:function(){return{height:"100%"}},item:function(){return{display:"block"}}},t.exports=e.default}(N,N.exports);var _={};function D(){var t=Array.from(document.getElementsByClassName("bm-item")).shift();t&&t.focus()}function I(){var t=Array.from(document.getElementsByClassName("bm-item")).pop();t&&t.focus()}function j(){var t=document.getElementById("react-burger-cross-btn");t&&t.focus()}function z(t){if(document.activeElement.className.includes("bm-item")){var e=document.activeElement[t];e?e.focus():j()}else"previousElementSibling"===t?I():D()}Object.defineProperty(_,"__esModule",{value:!0}),_.focusOnFirstMenuItem=D,_.focusOnLastMenuItem=I,_.focusOnCrossButton=j,_.focusOnMenuButton=function(){var t=document.getElementById("react-burger-menu-btn");t&&t.focus()},_.focusOnMenuItem=z,_.focusOnNextMenuItem=function(){z("nextElementSibling")},_.focusOnPreviousMenuItem=function(){z("previousElementSibling")};var P={exports:{}};!function(t,e){Object.defineProperty(e,"__esModule",{value:!0});var n=Object.assign||function(t){for(var e=1;e1)for(var r=0,a=n.length;r=1&&(delete n[o],s.s=1,i--,function(e){setTimeout((function(){t("mina.finish."+e.id,e)}))}(s)),s.update()}e=!!i&&r(m)}else e||(e=r(m))},g=function(t,e,r,a,s,v,y){var x={id:o+(i++).toString(36),start:t,end:e,b:r,s:0,dur:a-r,spd:1,get:s,set:v,easing:y||g.linear,status:l,speed:u,duration:c,stop:f,pause:d,resume:h,update:p};n[x.id]=x;var b,w=0;for(b in n)if(n.hasOwnProperty(b)&&2==++w)break;return 1==w&&m(),x};return g.time=s,g.getById=function(t){return n[t]||null},g.linear=function(t){return t},g.easeout=function(t){return Math.pow(t,1.7)},g.easein=function(t){return Math.pow(t,.48)},g.easeinout=function(t){if(1==t)return 1;if(0==t)return 0;var e=.48-t/1.04,n=Math.sqrt(.1734+e*e),r=n-e,a=-n-e,i=Math.pow(Math.abs(r),1/3)*(r<0?-1:1)+Math.pow(Math.abs(a),1/3)*(a<0?-1:1)+.5;return 3*(1-i)*i*i+i*i*i},g.backin=function(t){if(1==t)return 1;var e=1.70158;return t*t*((e+1)*t-e)},g.backout=function(t){if(0==t)return 0;var e=1.70158;return(t-=1)*t*((e+1)*t+e)+1},g.elastic=function(t){return t==!!t?t:Math.pow(2,-10*t)*Math.sin((t-.075)*(2*Math.PI)/.3)+1},g.bounce=function(t){var e=7.5625,n=2.75;return t<1/n?e*t*t:t<2/n?e*(t-=1.5/n)*t+.75:t<2.5/n?e*(t-=2.25/n)*t+.9375:e*(t-=2.625/n)*t+.984375},window.mina=g,g}("undefined"==typeof eve?function(){}:eve),st=function(t){function e(t,r){if(t){if(t.nodeType)return q(t);if(M(t,"array")&&e.set)return e.set.apply(e,t);if(t instanceof U)return t;if(null==r)try{return q(t=n.doc.querySelector(String(t)))}catch(a){return null}}return new H(t=null==t?"100%":t,r=null==r?"100%":r)}e.version="0.5.1",e.toString=function(){return"Snap v"+this.version},e._={};var n={win:t.window,doc:t.window.document};e._.glob=n;var r="hasOwnProperty",a=String,i=parseFloat,o=parseInt,s=Math,l=s.max,u=s.min,c=s.abs,f=s.PI,d=Object.prototype.toString,h=/^\s*((#[a-f\d]{6})|(#[a-f\d]{3})|rgba?\(\s*([\d\.]+%?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+%?(?:\s*,\s*[\d\.]+%?)?)\s*\)|hsba?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?%?)\s*\)|hsla?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?%?)\s*\))\s*$/i;e._.separator=/[,\s]+/;var p,m,v=/[\s]*,[\s]*/,y={hs:1,rg:1},x=/([a-z])[\s,]*((-?\d*\.?\d*(?:e[\-+]?\d+)?[\s]*,?[\s]*)+)/gi,b=/([rstm])[\s,]*((-?\d*\.?\d*(?:e[\-+]?\d+)?[\s]*,?[\s]*)+)/gi,w=/(-?\d*\.?\d*(?:e[\-+]?\d+)?)[\s]*,?[\s]*/gi,C=0,F="S"+(+new Date).toString(36),E=function(t){return(t&&t.type?t.type:"")+F+(C++).toString(36)},O="http://www.w3.org/1999/xlink",S="http://www.w3.org/2000/svg",T={};function A(t,e){if(e){if("#text"==t&&(t=n.doc.createTextNode(e.text||e["#text"]||"")),"#comment"==t&&(t=n.doc.createComment(e.text||e["#text"]||"")),"string"==typeof t&&(t=A(t)),"string"==typeof e)return 1==t.nodeType?"xlink:"==e.substring(0,6)?t.getAttributeNS(O,e.substring(6)):"xml:"==e.substring(0,4)?t.getAttributeNS(S,e.substring(4)):t.getAttribute(e):"text"==e?t.nodeValue:null;if(1==t.nodeType){for(var i in e)if(e[r](i)){var o=a(e[i]);o?"xlink:"==i.substring(0,6)?t.setAttributeNS(O,i.substring(6),o):"xml:"==i.substring(0,4)?t.setAttributeNS(S,i.substring(4),o):t.setAttribute(i,o):t.removeAttribute(i)}}else"text"in e&&(t.nodeValue=e.text)}else t=n.doc.createElementNS(S,t);return t}function M(t,e){return"finite"==(e=a.prototype.toLowerCase.call(e))?isFinite(t):!("array"!=e||!(t instanceof Array||Array.isArray&&Array.isArray(t)))||("null"==e&&null===t||e==typeof t&&null!==t||"object"==e&&t===Object(t)||d.call(t).slice(8,-1).toLowerCase()==e)}function k(t,e){for(var n=0,r=t.length;n=1e3&&delete s[l.shift()],l.push(o),s[o]=t.apply(e,i),n?n(s[o]):s[o])}}function N(t){return t%360*f/180}e.url=function(t){return"url('#"+t+"')"},e._.$=A,e._.id=E,e.format=(p=/\{([^\}]+)\}/g,m=/(?:(?:^|\.)(.+?)(?=\[|\.|$|\()|\[('|")(.+?)\2\])(\(\))?/g,function(t,e){return a(t).replace(p,(function(t,n){return function(t,e,n){var r=n;return e.replace(m,(function(t,e,n,a,i){e=e||a,r&&(e in r&&(r=r[e]),"function"==typeof r&&i&&(r=r()))})),r=(null==r||r==n?t:r)+""}(t,n,e)}))}),e._.clone=function t(e){if("function"==typeof e||Object(e)!==e)return e;var n=new e.constructor;for(var a in e)e[r](a)&&(n[a]=t(e[a]));return n},e._.cacher=B,e.rad=N,e.deg=function(t){return 180*t/f%360},e.sin=function(t){return s.sin(e.rad(t))},e.tan=function(t){return s.tan(e.rad(t))},e.cos=function(t){return s.cos(e.rad(t))},e.asin=function(t){return e.deg(s.asin(t))},e.acos=function(t){return e.deg(s.acos(t))},e.atan=function(t){return e.deg(s.atan(t))},e.atan2=function(t){return e.deg(s.atan2(t))},e.angle=function t(e,n,r,a,i,o){if(null==i){var l=e-r,u=n-a;return l||u?(180+180*s.atan2(-u,-l)/f+360)%360:0}return t(e,n,i,o)-t(r,a,i,o)},e.len=function(t,n,r,a){return Math.sqrt(e.len2(t,n,r,a))},e.len2=function(t,e,n,r){return(t-n)*(t-n)+(e-r)*(e-r)},e.closestPoint=function(t,e,n){function r(t){var r=t.x-e,a=t.y-n;return r*r+a*a}for(var a,i,o,s,l=t.node,u=l.getTotalLength(),c=u/l.pathSegList.numberOfItems*.125,f=1/0,d=0;d<=u;d+=c)(s=r(o=l.getPointAtLength(d))).5;){var h,p,m,g,v,y;(m=i-c)>=0&&(v=r(h=l.getPointAtLength(m)))t-n)return e-a+t}return e},e.getRGB=B((function(t){if(!t||(t=a(t)).indexOf("-")+1)return{r:-1,g:-1,b:-1,hex:"none",error:1,toString:j};if("none"==t)return{r:-1,g:-1,b:-1,hex:"none",toString:j};if(!y[r](t.toLowerCase().substring(0,2))&&"#"!=t.charAt()&&(t=_(t)),!t)return{r:-1,g:-1,b:-1,hex:"none",error:1,toString:j};var n,c,f,d,p,m,g=t.match(h);return g?(g[2]&&(f=o(g[2].substring(5),16),c=o(g[2].substring(3,5),16),n=o(g[2].substring(1,3),16)),g[3]&&(f=o((p=g[3].charAt(3))+p,16),c=o((p=g[3].charAt(2))+p,16),n=o((p=g[3].charAt(1))+p,16)),g[4]&&(m=g[4].split(v),n=i(m[0]),"%"==m[0].slice(-1)&&(n*=2.55),c=i(m[1]),"%"==m[1].slice(-1)&&(c*=2.55),f=i(m[2]),"%"==m[2].slice(-1)&&(f*=2.55),"rgba"==g[1].toLowerCase().slice(0,4)&&(d=i(m[3])),m[3]&&"%"==m[3].slice(-1)&&(d/=100)),g[5]?(m=g[5].split(v),n=i(m[0]),"%"==m[0].slice(-1)&&(n/=100),c=i(m[1]),"%"==m[1].slice(-1)&&(c/=100),f=i(m[2]),"%"==m[2].slice(-1)&&(f/=100),("deg"==m[0].slice(-3)||"°"==m[0].slice(-1))&&(n/=360),"hsba"==g[1].toLowerCase().slice(0,4)&&(d=i(m[3])),m[3]&&"%"==m[3].slice(-1)&&(d/=100),e.hsb2rgb(n,c,f,d)):g[6]?(m=g[6].split(v),n=i(m[0]),"%"==m[0].slice(-1)&&(n/=100),c=i(m[1]),"%"==m[1].slice(-1)&&(c/=100),f=i(m[2]),"%"==m[2].slice(-1)&&(f/=100),("deg"==m[0].slice(-3)||"°"==m[0].slice(-1))&&(n/=360),"hsla"==g[1].toLowerCase().slice(0,4)&&(d=i(m[3])),m[3]&&"%"==m[3].slice(-1)&&(d/=100),e.hsl2rgb(n,c,f,d)):(n=u(s.round(n),255),c=u(s.round(c),255),f=u(s.round(f),255),d=u(l(d,0),1),(g={r:n,g:c,b:f,toString:j}).hex="#"+(16777216|f|c<<8|n<<16).toString(16).slice(1),g.opacity=M(d,"finite")?d:1,g)):{r:-1,g:-1,b:-1,hex:"none",error:1,toString:j}}),e),e.hsb=B((function(t,n,r){return e.hsb2rgb(t,n,r).hex})),e.hsl=B((function(t,n,r){return e.hsl2rgb(t,n,r).hex})),e.rgb=B((function(t,e,n,r){if(M(r,"finite")){var a=s.round;return"rgba("+[a(t),a(e),a(n),+r.toFixed(2)]+")"}return"#"+(16777216|n|e<<8|t<<16).toString(16).slice(1)}));var _=function(t){var e=n.doc.getElementsByTagName("head")[0]||n.doc.getElementsByTagName("svg")[0],r="rgb(255, 0, 0)";return(_=B((function(t){if("red"==t.toLowerCase())return r;e.style.color=r,e.style.color=t;var a=n.doc.defaultView.getComputedStyle(e,"").getPropertyValue("color");return a==r?null:a})))(t)},D=function(){return"hsb("+[this.h,this.s,this.b]+")"},I=function(){return"hsl("+[this.h,this.s,this.l]+")"},j=function(){return 1==this.opacity||null==this.opacity?this.hex:"rgba("+[this.r,this.g,this.b,this.opacity]+")"},z=function(t,n,r){if(null==n&&M(t,"object")&&"r"in t&&"g"in t&&"b"in t&&(r=t.b,n=t.g,t=t.r),null==n&&M(t,string)){var a=e.getRGB(t);t=a.r,n=a.g,r=a.b}return(t>1||n>1||r>1)&&(t/=255,n/=255,r/=255),[t,n,r]},P=function(t,n,r,a){var i={r:t=s.round(255*t),g:n=s.round(255*n),b:r=s.round(255*r),opacity:M(a,"finite")?a:1,hex:e.rgb(t,n,r),toString:j};return M(a,"finite")&&(i.opacity=a),i};e.color=function(t){var n;return M(t,"object")&&"h"in t&&"s"in t&&"b"in t?(n=e.hsb2rgb(t),t.r=n.r,t.g=n.g,t.b=n.b,t.opacity=1,t.hex=n.hex):M(t,"object")&&"h"in t&&"s"in t&&"l"in t?(n=e.hsl2rgb(t),t.r=n.r,t.g=n.g,t.b=n.b,t.opacity=1,t.hex=n.hex):(M(t,"string")&&(t=e.getRGB(t)),M(t,"object")&&"r"in t&&"g"in t&&"b"in t&&!("error"in t)?(n=e.rgb2hsl(t),t.h=n.h,t.s=n.s,t.l=n.l,n=e.rgb2hsb(t),t.v=n.b):((t={hex:"none"}).r=t.g=t.b=t.h=t.s=t.v=t.l=-1,t.error=1)),t.toString=j,t},e.hsb2rgb=function(t,e,n,r){var a,i,o,s,l;return M(t,"object")&&"h"in t&&"s"in t&&"b"in t&&(n=t.b,e=t.s,r=t.o,t=t.h),s=(l=n*e)*(1-c((t=(t*=360)%360/60)%2-1)),a=i=o=n-l,P(a+=[l,s,0,0,s,l][t=~~t],i+=[s,l,l,s,0,0][t],o+=[0,0,s,l,l,s][t],r)},e.hsl2rgb=function(t,e,n,r){var a,i,o,s,l;return M(t,"object")&&"h"in t&&"s"in t&&"l"in t&&(n=t.l,e=t.s,t=t.h),(t>1||e>1||n>1)&&(t/=360,e/=100,n/=100),s=(l=2*e*(n<.5?n:1-n))*(1-c((t=(t*=360)%360/60)%2-1)),a=i=o=n-l/2,P(a+=[l,s,0,0,s,l][t=~~t],i+=[s,l,l,s,0,0][t],o+=[0,0,s,l,l,s][t],r)},e.rgb2hsb=function(t,e,n){var r,a;return t=(n=z(t,e,n))[0],e=n[1],n=n[2],{h:((0==(a=(r=l(t,e,n))-u(t,e,n))?null:r==t?(e-n)/a:r==e?(n-t)/a+2:(t-e)/a+4)+360)%6*60/360,s:0==a?0:a/r,b:r,toString:D}},e.rgb2hsl=function(t,e,n){var r,a,i,o;return t=(n=z(t,e,n))[0],e=n[1],n=n[2],r=((a=l(t,e,n))+(i=u(t,e,n)))/2,{h:((0==(o=a-i)?null:a==t?(e-n)/o:a==e?(n-t)/o+2:(t-e)/o+4)+360)%6*60/360,s:0==o?0:r<.5?o/(2*r):o/(2-2*r),l:r,toString:I}},e.parsePathString=function(t){if(!t)return null;var n=e.path(t);if(n.arr)return e.path.clone(n.arr);var r={a:7,c:6,o:2,h:1,l:2,m:2,r:4,q:4,s:4,t:2,v:1,u:3,z:0},i=[];return M(t,"array")&&M(t[0],"array")&&(i=e.path.clone(t)),i.length||a(t).replace(x,(function(t,e,n){var a=[],o=e.toLowerCase();if(n.replace(w,(function(t,e){e&&a.push(+e)})),"m"==o&&a.length>2&&(i.push([e].concat(a.splice(0,2))),o="l",e="m"==e?"l":"L"),"o"==o&&1==a.length&&i.push([e,a[0]]),"r"==o)i.push([e].concat(a));else for(;a.length>=r[o]&&(i.push([e].concat(a.splice(0,r[o]))),r[o]););})),i.toString=e.path.toString,n.arr=e.path.clone(i),i};var L=e.parseTransformString=function(t){if(!t)return null;var n=[];return M(t,"array")&&M(t[0],"array")&&(n=e.path.clone(t)),n.length||a(t).replace(b,(function(t,e,r){var a=[];e.toLowerCase(),r.replace(w,(function(t,e){e&&a.push(+e)})),n.push([e].concat(a))})),n.toString=e.path.toString,n};function $(t){return t.node.ownerSVGElement&&q(t.node.ownerSVGElement)||e.select("svg")}function Y(t){M(t,"array")||(t=Array.prototype.slice.call(arguments,0));for(var e=0,n=0,r=this.node;this[e];)delete this[e++];for(e=0;e2?r=r.slice(0,2):2==r.length&&r.push(0,0),1==r.length&&r.push(r[0],0,0)),"skewX"==n?e.push(["m",1,0,s.tan(N(r[0])),1,0,0]):"skewY"==n?e.push(["m",1,s.tan(N(r[0])),0,1,0,0]):e.push([n.charAt(0)].concat(r)),t})),e},e._.rgTransform=/^[a-z][\s]*-?\.?\d/i,e._.transform2matrix=function(t,n){var r=L(t),i=new e.Matrix;if(r)for(var o=0,s=r.length;o1))return eve("snap.util.getattr."+t,n).firstDefined();var u={};u[t]=e,t=u}for(var c in t)t[r](c)&&eve("snap.util.attr."+c,n,t[c]);return n},e.parse=function(t){var e=n.doc.createDocumentFragment(),r=!0,i=n.doc.createElement("div");if((t=a(t)).match(/^\s*<\s*svg(?:\s|>)/)||(t=""+t+" ",r=!1),i.innerHTML=t,t=i.getElementsByTagName("svg")[0])if(r)e=t;else for(;t.firstChild;)e.appendChild(t.firstChild);return new R(e)},e.fragment=function(){for(var t=Array.prototype.slice.call(arguments,0),r=n.doc.createDocumentFragment(),a=0,i=t.length;a"),a=0,i=r.length;a")}else t&&(e+="/>");return e}}i.data=function(e,n){var r=g[this.id]=g[this.id]||{};if(0==arguments.length)return eve("snap.data.get."+this.id,this,r,null),r;if(1==arguments.length){if(t.is(e,"object")){for(var a in e)e[d](a)&&this.data(a,e[a]);return this}return eve("snap.data.get."+this.id,this,r[e],e),r[e]}return r[e]=n,eve("snap.data.set."+this.id,this,n,e),this},i.removeData=function(t){return null==t?g[this.id]={}:g[this.id]&&delete g[this.id][t],this},i.outerSVG=i.toString=v(1),i.innerSVG=v(),i.toDataURL=function(){if(window&&window.btoa){var e=this.getBBox(),n=t.format('{contents} ',{x:+e.x.toFixed(3),y:+e.y.toFixed(3),width:+e.width.toFixed(3),height:+e.height.toFixed(3),contents:this.outerSVG()});return"data:image/svg+xml;base64,"+btoa(unescape(encodeURIComponent(n)))}},a.prototype.select=i.select,a.prototype.selectAll=i.selectAll})),st.plugin((function(t,e,n,r,a){var i=Object.prototype.toString,o=String,s=Math;function l(t,e,n,r,a,o){if(null==e&&"[object SVGMatrix]"==i.call(t))return this.a=t.a,this.b=t.b,this.c=t.c,this.d=t.d,this.e=t.e,void(this.f=t.f);null!=t?(this.a=+t,this.b=+e,this.c=+n,this.d=+r,this.e=+a,this.f=+o):(this.a=1,this.b=0,this.c=0,this.d=1,this.e=0,this.f=0)}!function(e){function n(t){return t[0]*t[0]+t[1]*t[1]}function r(t){var e=s.sqrt(n(t));t[0]&&(t[0]/=e),t[1]&&(t[1]/=e)}e.add=function(t,e,n,r,a,i){if(t&&t instanceof l)return this.add(t.a,t.b,t.c,t.d,t.e,t.f);var o=t*this.a+e*this.c,s=t*this.b+e*this.d;return this.e+=a*this.a+i*this.c,this.f+=a*this.b+i*this.d,this.c=n*this.a+r*this.c,this.d=n*this.b+r*this.d,this.a=o,this.b=s,this},l.prototype.multLeft=function(t,e,n,r,a,i){if(t&&t instanceof l)return this.multLeft(t.a,t.b,t.c,t.d,t.e,t.f);var o=t*this.a+n*this.b,s=t*this.c+n*this.d,u=t*this.e+n*this.f+a;return this.b=e*this.a+r*this.b,this.d=e*this.c+r*this.d,this.f=e*this.e+r*this.f+i,this.a=o,this.c=s,this.e=u,this},e.invert=function(){var t=this,e=t.a*t.d-t.b*t.c;return new l(t.d/e,-t.b/e,-t.c/e,t.a/e,(t.c*t.f-t.d*t.e)/e,(t.b*t.e-t.a*t.f)/e)},e.clone=function(){return new l(this.a,this.b,this.c,this.d,this.e,this.f)},e.translate=function(t,e){return this.e+=t*this.a+e*this.c,this.f+=t*this.b+e*this.d,this},e.scale=function(t,e,n,r){return null==e&&(e=t),(n||r)&&this.translate(n,r),this.a*=t,this.b*=t,this.c*=e,this.d*=e,(n||r)&&this.translate(-n,-r),this},e.rotate=function(e,n,r){e=t.rad(e),n=n||0,r=r||0;var a=+s.cos(e).toFixed(9),i=+s.sin(e).toFixed(9);return this.add(a,i,-i,a,n,r),this.add(1,0,0,1,-n,-r)},e.skewX=function(t){return this.skew(t,0)},e.skewY=function(t){return this.skew(0,t)},e.skew=function(e,n){e=e||0,n=n||0,e=t.rad(e),n=t.rad(n);var r=s.tan(e).toFixed(9),a=s.tan(n).toFixed(9);return this.add(1,a,r,1,0,0)},e.x=function(t,e){return t*this.a+e*this.c+this.e},e.y=function(t,e){return t*this.b+e*this.d+this.f},e.get=function(t){return+this[o.fromCharCode(97+t)].toFixed(4)},e.toString=function(){return"matrix("+[this.get(0),this.get(1),this.get(2),this.get(3),this.get(4),this.get(5)].join()+")"},e.offset=function(){return[this.e.toFixed(4),this.f.toFixed(4)]},e.determinant=function(){return this.a*this.d-this.b*this.c},e.split=function(){var e={};e.dx=this.e,e.dy=this.f;var a=[[this.a,this.b],[this.c,this.d]];e.scalex=s.sqrt(n(a[0])),r(a[0]),e.shear=a[0][0]*a[1][0]+a[0][1]*a[1][1],a[1]=[a[1][0]-a[0][0]*e.shear,a[1][1]-a[0][1]*e.shear],e.scaley=s.sqrt(n(a[1])),r(a[1]),e.shear/=e.scaley,this.determinant()<0&&(e.scalex=-e.scalex);var i=a[0][1],o=a[1][1];return o<0?(e.rotate=t.deg(s.acos(o)),i<0&&(e.rotate=360-e.rotate)):e.rotate=t.deg(s.asin(i)),e.isSimple=!(+e.shear.toFixed(9)||e.scalex.toFixed(9)!=e.scaley.toFixed(9)&&e.rotate),e.isSuperSimple=!+e.shear.toFixed(9)&&e.scalex.toFixed(9)==e.scaley.toFixed(9)&&!e.rotate,e.noRotation=!+e.shear.toFixed(9)&&!e.rotate,e},e.toTransformString=function(t){var e=t||this.split();return+e.shear.toFixed(9)?"m"+[this.get(0),this.get(1),this.get(2),this.get(3),this.get(4),this.get(5)]:(e.scalex=+e.scalex.toFixed(4),e.scaley=+e.scaley.toFixed(4),e.rotate=+e.rotate.toFixed(4),(e.dx||e.dy?"t"+[+e.dx.toFixed(4),+e.dy.toFixed(4)]:"")+(e.rotate?"r"+[+e.rotate.toFixed(4),0,0]:"")+(1!=e.scalex||1!=e.scaley?"s"+[e.scalex,e.scaley,0,0]:""))}}(l.prototype),t.Matrix=l,t.matrix=function(t,e,n,r,a,i){return new l(t,e,n,r,a,i)}})),st.plugin((function(t,e,n,r,a){var i,o=t._.make,s=t._.wrap,l=t.is,u=t._.getSomeDefs,c=/^url\((['"]?)([^)]+)\1\)$/,f=t._.$,d=t.url,h=String,p=t._.separator;function m(n){return function(r){if(eve.stop(),r instanceof a&&1==r.node.childNodes.length&&("radialGradient"==r.node.firstChild.tagName||"linearGradient"==r.node.firstChild.tagName||"pattern"==r.node.firstChild.tagName)&&(r=r.node.firstChild,u(this).appendChild(r),r=s(r)),r instanceof e)if("radialGradient"==r.type||"linearGradient"==r.type||"pattern"==r.type){r.node.id||f(r.node,{id:r.id});var i=d(r.node.id)}else i=r.attr(n);else if((i=t.color(r)).error){var o=t(u(this).ownerSVGElement).gradient(r);o?(o.node.id||f(o.node,{id:o.id}),i=d(o.node.id)):i=r}else i=h(i);var l={};l[n]=i,f(this.node,l),this.node.style[n]=""}}t.deurl=function(t){var e=String(t).match(c);return e?e[2]:t},eve.on("snap.util.attr.mask",(function(t){if(t instanceof e||t instanceof a){if(eve.stop(),t instanceof a&&1==t.node.childNodes.length&&(t=t.node.firstChild,u(this).appendChild(t),t=s(t)),"mask"==t.type)var n=t;else(n=o("mask",u(this))).node.appendChild(t.node);!n.node.id&&f(n.node,{id:n.id}),f(this.node,{mask:d(n.id)})}})),i=function(t){if(t instanceof e||t instanceof a){eve.stop();for(var n,r=t.node;r;){if("clipPath"===r.nodeName){n=new e(r);break}if("svg"===r.nodeName){n=void 0;break}r=r.parentNode}n||((n=o("clipPath",u(this))).node.appendChild(t.node),!n.node.id&&f(n.node,{id:n.id})),f(this.node,{"clip-path":d(n.node.id||n.id)})}},eve.on("snap.util.attr.clip",i),eve.on("snap.util.attr.clip-path",i),eve.on("snap.util.attr.clipPath",i),eve.on("snap.util.attr.fill",m("fill")),eve.on("snap.util.attr.stroke",m("stroke"));var g=/^([lr])(?:\(([^)]*)\))?(.*)$/i;function v(t){eve.stop(),t==+t&&(t+="px"),this.node.style.fontSize=t}function y(t){for(var e=[],n=t.childNodes,r=0,a=n.length;r1&&(t=Array.prototype.slice.call(arguments,0));var e={};return o(t,"object")&&!o(t,"array")?e=t:null!=t&&(e={points:t}),this.el("polyline",e)},i.polygon=function(t){arguments.length>1&&(t=Array.prototype.slice.call(arguments,0));var e={};return o(t,"object")&&!o(t,"array")?e=t:null!=t&&(e={points:t}),this.el("polygon",e)},function(){var e=t._.$;function n(){return this.selectAll("stop")}function r(n,r){var a=e("stop"),i={offset:+r+"%"};n=t.color(n),i["stop-color"]=n.hex,n.opacity<1&&(i["stop-opacity"]=n.opacity),e(a,i);for(var o,s=this.stops(),l=0;lr){this.node.insertBefore(a,s[l].node),o=!0;break}}return o||this.node.appendChild(a),this}function a(){if("linearGradient"==this.type){var n=e(this.node,"x1")||0,r=e(this.node,"x2")||1,a=e(this.node,"y1")||0,i=e(this.node,"y2")||0;return t._.box(n,a,math.abs(r-n),math.abs(i-a))}var o=this.node.cx||.5,s=this.node.cy||.5,l=this.node.r||0;return t._.box(o-l,s-l,2*l,2*l)}function o(e){var n=e,r=this.stops();if("string"==typeof e&&(n=eve("snap.util.grad.parse",null,"l(0,0,0,1)"+e).firstDefined().stops),t.is(n,"array")){for(var a=0;ah;)u=M(t,e,n,r,a,i,o,s,d+=(ui){if(r&&!h.start){if(d+=["C"+a((f=x(s,l,u[1],u[2],u[3],u[4],u[5],u[6],i-p)).start.x),a(f.start.y),a(f.m.x),a(f.m.y),a(f.x),a(f.y)],o)return d;h.start=d,d=["M"+a(f.x),a(f.y)+"C"+a(f.n.x),a(f.n.y),a(f.end.x),a(f.end.y),a(u[5]),a(u[6])].join(),p+=c,s=+u[5],l=+u[6];continue}if(!n&&!r)return f=x(s,l,u[1],u[2],u[3],u[4],u[5],u[6],i-p)}p+=c,s=+u[5],l=+u[6]}d+=u.shift()+u}return h.end=d,f=n?p:r?h:E(s,l,u[0],u[1],u[2],u[3],u[4],u[5],1)}),null,t._.clone)}var w=b(1),C=b(),F=b(0,1);function E(t,e,n,r,a,i,o,s,l){var f=1-l,d=h(f,3),p=h(f,2),m=l*l,g=m*l,v=t+2*l*(n-t)+m*(a-2*n+t),y=e+2*l*(r-e)+m*(i-2*r+e),x=n+2*l*(a-n)+m*(o-2*a+n),b=r+2*l*(i-r)+m*(s-2*i+r);return{x:d*t+3*p*l*n+3*f*l*l*a+g*o,y:d*e+3*p*l*r+3*f*l*l*i+g*s,m:{x:v,y:y},n:{x:x,y:b},start:{x:f*t+l*n,y:f*e+l*r},end:{x:f*a+l*o,y:f*i+l*s},alpha:90-180*u.atan2(v-x,y-b)/c}}function O(e,n,r,a,i,o,s,l){t.is(e,"array")||(e=[e,n,r,a,i,o,s,l]);var u=U.apply(null,e);return g(u.min.x,u.min.y,u.max.x-u.min.x,u.max.y-u.min.y)}function S(t,e,n){return e>=t.x&&e<=t.x+t.width&&n>=t.y&&n<=t.y+t.height}function T(t,e){return t=g(t),S(e=g(e),t.x,t.y)||S(e,t.x2,t.y)||S(e,t.x,t.y2)||S(e,t.x2,t.y2)||S(t,e.x,e.y)||S(t,e.x2,e.y)||S(t,e.x,e.y2)||S(t,e.x2,e.y2)||(t.xe.x||e.xt.x)&&(t.ye.y||e.yt.y)}function A(t,e,n,r,a){return t*(t*(-3*e+9*n-9*r+3*a)+6*e-12*n+6*r)-3*e+3*n}function M(t,e,n,r,a,i,o,s,l){null==l&&(l=1);for(var c=(l=l>1?1:l<0?0:l)/2,f=[-.1252,.1252,-.3678,.3678,-.5873,.5873,-.7699,.7699,-.9041,.9041,-.9816,.9816],d=[.2491,.2491,.2335,.2335,.2032,.2032,.1601,.1601,.1069,.1069,.0472,.0472],h=0,p=0;p<12;p++){var m=c*f[p]+c,g=A(m,t,n,a,o),v=A(m,e,r,i,s),y=g*g+v*v;h+=d[p]*u.sqrt(y)}return c*h}function k(t,e,n,r,a,i,o,s){if(!(d(t,n)d(a,o)||d(e,r)d(i,s))){var l=(t-n)*(i-s)-(e-r)*(a-o);if(l){var u=((t*r-e*n)*(a-o)-(t-n)*(a*s-i*o))/l,c=((t*r-e*n)*(i-s)-(e-r)*(a*s-i*o))/l,h=+u.toFixed(2),p=+c.toFixed(2);if(!(h<+f(t,n).toFixed(2)||h>+d(t,n).toFixed(2)||h<+f(a,o).toFixed(2)||h>+d(a,o).toFixed(2)||p<+f(e,r).toFixed(2)||p>+d(e,r).toFixed(2)||p<+f(i,s).toFixed(2)||p>+d(i,s).toFixed(2)))return{x:u,y:c}}}}function B(t,e,n){if(!T(O(t),O(e)))return n?0:[];for(var r=~~(M.apply(0,t)/8),a=~~(M.apply(0,e)/8),i=[],o=[],s={},l=n?0:[],u=0;u=0&&b<=1&&w>=0&&w<=1&&(n?l++:l.push({x:x.x,y:x.y,t1:b,t2:w}))}}return l}function N(t,e,n){t=R(t),e=R(e);for(var r,a,i,o,s,l,u,c,f,d,h=n?0:[],p=0,m=t.length;p180),0,s,e+n*Math.sin(-a*i)]];else l=[["M",t,e],["m",0,-r],["a",n,r,0,1,1,0,2*r],["a",n,r,0,1,1,0,-2*r],["z"]];return l.toString=v,l}var j=t._unit2px,z={path:function(t){return t.attr("path")},circle:function(t){var e=j(t);return I(e.cx,e.cy,e.r)},ellipse:function(t){var e=j(t);return I(e.cx||0,e.cy||0,e.rx,e.ry)},rect:function(t){var e=j(t);return D(e.x||0,e.y||0,e.width,e.height,e.rx,e.ry)},image:function(t){var e=j(t);return D(e.x||0,e.y||0,e.width,e.height)},line:function(t){return"M"+[t.attr("x1")||0,t.attr("y1")||0,t.attr("x2"),t.attr("y2")]},polyline:function(t){return"M"+t.attr("points")},polygon:function(t){return"M"+t.attr("points")+"z"},deflt:function(t){var e=t.node.getBBox();return D(e.x,e.y,e.width,e.height)}};function P(e){var n=m(e);if(n.abs)return y(n.abs);if(i(e,"array")&&i(e&&e[0],"array")||(e=t.parsePathString(e)),!e||!e.length)return[["M",0,0]];var r,a=[],o=0,s=0,l=0,u=0,c=0;"M"==e[0][0]&&(l=o=+e[0][1],u=s=+e[0][2],c++,a[0]=["M",o,s]);for(var f,d,h=3==e.length&&"M"==e[0][0]&&"R"==e[1][0].toUpperCase()&&"Z"==e[2][0].toUpperCase(),p=c,g=e.length;p1&&(r*=w=u.sqrt(w),a*=w);var C=r*r,F=a*a,E=(o==s?-1:1)*u.sqrt(p((C*F-C*b*b-F*x*x)/(C*b*b+F*x*x))),O=E*r*b/a+(e+l)/2,S=E*-a*x/r+(n+f)/2,T=u.asin(((n-S)/a).toFixed(9)),A=u.asin(((f-S)/a).toFixed(9));(T=eA&&(T-=2*c),!s&&A>T&&(A-=2*c)}var M=A-T;if(p(M)>m){var k=A,B=l,N=f;A=T+m*(s&&A>T?1:-1),v=Y(l=O+r*u.cos(A),f=S+a*u.sin(A),r,a,i,0,s,B,N,[A,k,O,S])}M=A-T;var _=u.cos(T),D=u.sin(T),I=u.cos(A),j=u.sin(A),z=u.tan(M/4),P=4/3*r*z,L=4/3*a*z,$=[e,n],U=[e+P*D,n-L*_],R=[l+P*j,f-L*I],V=[l,f];if(U[0]=2*$[0]-U[0],U[1]=2*$[1]-U[1],d)return[U,R,V].concat(v);for(var H=[],q=0,W=(v=[U,R,V].concat(v).join().split(",")).length;q7){t[e].shift();for(var n=t[e];n.length;)f[e]="A",a&&(h[e]="A"),t.splice(e++,0,["C"].concat(n.splice(0,6)));t.splice(e,1),x=d(r.length,a&&a.length||0)}},c=function(t,e,n,i,o){t&&e&&"M"==t[o][0]&&"M"!=e[o][0]&&(e.splice(o,0,["M",i.x,i.y]),n.bx=0,n.by=0,n.x=t[o][1],n.y=t[o][2],x=d(r.length,a&&a.length||0))},f=[],h=[],p="",g="",v=0,x=d(r.length,a&&a.length||0);vr;r+=2){var i=[{x:+t[r-2],y:+t[r-1]},{x:+t[r],y:+t[r+1]},{x:+t[r+2],y:+t[r+3]},{x:+t[r+4],y:+t[r+5]}];e?r?a-4==r?i[3]={x:+t[0],y:+t[1]}:a-2==r&&(i[2]={x:+t[0],y:+t[1]},i[3]={x:+t[2],y:+t[3]}):i[0]={x:+t[a-2],y:+t[a-1]}:a-4==r?i[3]=i[2]:r||(i[0]={x:+t[r],y:+t[r+1]}),n.push(["C",(-i[0].x+6*i[1].x+i[2].x)/6,(-i[0].y+6*i[1].y+i[2].y)/6,(i[1].x+6*i[2].x-i[3].x)/6,(i[1].y+6*i[2].y-i[3].y)/6,i[2].x,i[2].y])}return n}t.path=m,t.path.getTotalLength=w,t.path.getPointAtLength=C,t.path.getSubpath=function(t,e,n){if(this.getTotalLength(t)-n<1e-6)return F(t,e).end;var r=F(t,n,1);return e?F(r,e).end:r},a.getTotalLength=function(){if(this.node.getTotalLength)return this.node.getTotalLength()},a.getPointAtLength=function(t){return C(this.attr("d"),t)},a.getSubpath=function(e,n){return t.path.getSubpath(this.attr("d"),e,n)},t._.box=g,t.path.findDotsAtSegment=E,t.path.bezierBBox=O,t.path.isPointInsideBBox=S,t.closest=function(e,n,r,a){for(var i=100,o=g(e-i/2,n-i/2,i,i),s=[],l=r[0].hasOwnProperty("x")?function(t){return{x:r[t].x,y:r[t].y}}:function(t){return{x:r[t],y:a[t]}},u=0;i<=1e6&&!u;){for(var c=0,f=r.length;cm&&(p=m,s[c].len=m,h=s[c])}return h}},t.path.isBBoxIntersect=T,t.path.intersection=function(t,e){return N(t,e)},t.path.intersectionNumber=function(t,e){return N(t,e,1)},t.path.isPointInside=function(t,e,n){var r=_(t);return S(r,e,n)&&N(t,[["M",e,n],["H",r.x2+10]],1)%2==1},t.path.getBBox=_,t.path.get=z,t.path.toRelative=function(e){var n=m(e),r=String.prototype.toLowerCase;if(n.rel)return y(n.rel);t.is(e,"array")&&t.is(e&&e[0],"array")||(e=t.parsePathString(e));var a=[],i=0,o=0,s=0,l=0,u=0;"M"==e[0][0]&&(s=i=e[0][1],l=o=e[0][2],u++,a.push(["M",i,o]));for(var c=u,f=e.length;c ',{def:r})},t.filter.blur.toString=function(){return this()},t.filter.shadow=function(e,n,r,a,i){return null==i&&(null==a?(i=r,r=4,a="#000"):(i=a,a=r,r=4)),null==r&&(r=4),null==i&&(i=1),null==e&&(e=0,n=2),null==n&&(n=e),a=t.color(a),t.format(' ',{color:a,dx:e,dy:n,blur:r,opacity:i})},t.filter.shadow.toString=function(){return this()},t.filter.grayscale=function(e){return null==e&&(e=1),t.format(' ',{a:.2126+.7874*(1-e),b:.7152-.7152*(1-e),c:.0722-.0722*(1-e),d:.2126-.2126*(1-e),e:.7152+.2848*(1-e),f:.0722-.0722*(1-e),g:.2126-.2126*(1-e),h:.0722+.9278*(1-e)})},t.filter.grayscale.toString=function(){return this()},t.filter.sepia=function(e){return null==e&&(e=1),t.format(' ',{a:.393+.607*(1-e),b:.769-.769*(1-e),c:.189-.189*(1-e),d:.349-.349*(1-e),e:.686+.314*(1-e),f:.168-.168*(1-e),g:.272-.272*(1-e),h:.534-.534*(1-e),i:.131+.869*(1-e)})},t.filter.sepia.toString=function(){return this()},t.filter.saturate=function(e){return null==e&&(e=1),t.format(' ',{amount:1-e})},t.filter.saturate.toString=function(){return this()},t.filter.hueRotate=function(e){return e=e||0,t.format(' ',{angle:e})},t.filter.hueRotate.toString=function(){return this()},t.filter.invert=function(e){return null==e&&(e=1),t.format(' ',{amount:e,amount2:1-e})},t.filter.invert.toString=function(){return this()},t.filter.brightness=function(e){return null==e&&(e=1),t.format(' ',{amount:e})},t.filter.brightness.toString=function(){return this()},t.filter.contrast=function(e){return null==e&&(e=1),t.format(' ',{amount:e,amount2:.5-e/2})},t.filter.contrast.toString=function(){return this()}})),st.plugin((function(t,e,n,r,a){var i=t._.box,o=t.is,s=/^[^a-z]*([tbmlrc])/i,l=function(){return"T"+this.dx+","+this.dy};e.prototype.getAlign=function(t,e){null==e&&o(t,"string")&&(e=t,t=null);var n=(t=t||this.paper).getBBox?t.getBBox():i(t),r=this.getBBox(),a={};switch(e=(e=e&&e.match(s))?e[1].toLowerCase():"c"){case"t":a.dx=0,a.dy=n.y-r.y;break;case"b":a.dx=0,a.dy=n.y2-r.y2;break;case"m":a.dx=0,a.dy=n.cy-r.cy;break;case"l":a.dx=n.x-r.x,a.dy=0;break;case"r":a.dx=n.x2-r.x2,a.dy=0;break;default:a.dx=n.cx-r.cx,a.dy=0}return a.toString=l,a},e.prototype.align=function(t,e){return this.transform("..."+this.getAlign(t,e))}})),st.plugin((function(t,e,n,r,a){var i=e.prototype,o=t.is,s=String,l="hasOwnProperty";function u(t,e,n){return function(r){var a=r.slice(t,e);return 1==a.length&&(a=a[0]),n?n(a):a}}var c=function(t,e,n,r){"function"!=typeof n||n.length||(r=n,n=ot.linear),this.attr=t,this.dur=e,n&&(this.easing=n),r&&(this.callback=r)};t._.Animation=c,t.animation=function(t,e,n,r){return new c(t,e,n,r)},i.inAnim=function(){var t=this,e=[];for(var n in t.anims)t.anims[l](n)&&function(t){e.push({anim:new c(t._attrs,t.dur,t.easing,t._callback),mina:t,curStatus:t.status(),status:function(e){return t.status(e)},stop:function(){t.stop()}})}(t.anims[n]);return e},t.animate=function(t,e,n,r,a,i){"function"!=typeof a||a.length||(i=a,a=ot.linear);var o=ot.time(),s=ot(t,e,o,o+r,ot.time,n,a);return i&&eve.once("mina.finish."+s.id,i),s},i.stop=function(){for(var t=this.inAnim(),e=0,n=t.length;er-1||(t.animate({path:n[e]},0===e?400:500,0===e?a.easein:a.elastic,(function(){i()})),e++)}()}},morphShape:function(t,e,n){return{position:"absolute",width:"100%",height:"100%",right:n?"inherit":0,left:n?0:"inherit",MozTransform:n?"rotateY(180deg)":"rotateY(0deg)",MsTransform:n?"rotateY(180deg)":"rotateY(0deg)",OTransform:n?"rotateY(180deg)":"rotateY(0deg)",WebkitTransform:n?"rotateY(180deg)":"rotateY(0deg)",transform:n?"rotateY(180deg)":"rotateY(0deg)"}},menuWrap:function(t,e,n){return{MozTransform:t?"translate3d(0, 0, 0)":n?"translate3d(100%, 0, 0)":"translate3d(-100%, 0, 0)",MsTransform:t?"translate3d(0, 0, 0)":n?"translate3d(100%, 0, 0)":"translate3d(-100%, 0, 0)",OTransform:t?"translate3d(0, 0, 0)":n?"translate3d(100%, 0, 0)":"translate3d(-100%, 0, 0)",WebkitTransform:t?"translate3d(0, 0, 0)":n?"translate3d(100%, 0, 0)":"translate3d(-100%, 0, 0)",transform:t?"translate3d(0, 0, 0)":n?"translate3d(100%, 0, 0)":"translate3d(-100%, 0, 0)",transition:t?"transform 0.4s 0s":"transform 0.4s"}},menu:function(t,e,n){var r=(0,i.pxToNum)(e)-140;return{position:"fixed",MozTransform:t?"":n?"translate3d("+r+", 0, 0)":"translate3d(-"+r+", 0, 0)",MsTransform:t?"":n?"translate3d("+r+", 0, 0)":"translate3d(-"+r+", 0, 0)",OTransform:t?"":n?"translate3d("+r+", 0, 0)":"translate3d(-"+r+", 0, 0)",WebkitTransform:t?"":n?"translate3d("+r+", 0, 0)":"translate3d(-"+r+", 0, 0)",transform:t?"":n?"translate3d("+r+", 0, 0)":"translate3d(-"+r+", 0, 0)",transition:t?"opacity 0.1s 0.4s cubic-bezier(.17, .67, .1, 1.27), transform 0.1s 0.4s cubic-bezier(.17, .67, .1, 1.27)":"opacity 0s 0.3s cubic-bezier(.17, .67, .1, 1.27), transform 0s 0.3s cubic-bezier(.17, .67, .1, 1.27)",opacity:t?1:0}},item:function(t,e,n,r){var a=(0,i.pxToNum)(e)-140;return{MozTransform:t?"translate3d(0, 0, 0)":n?"translate3d("+a+", 0, 0)":"translate3d(-"+a+", 0, 0)",MsTransform:t?"translate3d(0, 0, 0)":n?"translate3d("+a+", 0, 0)":"translate3d(-"+a+", 0, 0)",OTransform:t?"translate3d(0, 0, 0)":n?"translate3d("+a+", 0, 0)":"translate3d(-"+a+", 0, 0)",WebkitTransform:t?"translate3d(0, 0, 0)":n?"translate3d("+a+", 0, 0)":"translate3d(-"+a+", 0, 0)",transform:t?"translate3d(0, 0, 0)":n?"translate3d("+a+", 0, 0)":"translate3d(-"+a+", 0, 0)",transition:t?"opacity 0.3s 0.4s, transform 0.3s 0.4s":"opacity 0s 0.3s cubic-bezier(.17, .67, .1, 1.27), transform 0s 0.3s cubic-bezier(.17, .67, .1, 1.27)",opacity:t?1:0}},closeButton:function(t,e,n){var r=(0,i.pxToNum)(e)-140;return{MozTransform:t?"translate3d(0, 0, 0)":n?"translate3d("+r+", 0, 0)":"translate3d(-"+r+", 0, 0)",MsTransform:t?"translate3d(0, 0, 0)":n?"translate3d("+r+", 0, 0)":"translate3d(-"+r+", 0, 0)",OTransform:t?"translate3d(0, 0, 0)":n?"translate3d("+r+", 0, 0)":"translate3d(-"+r+", 0, 0)",WebkitTransform:t?"translate3d(0, 0, 0)":n?"translate3d("+r+", 0, 0)":"translate3d(-"+r+", 0, 0)",transform:t?"translate3d(0, 0, 0)":n?"translate3d("+r+", 0, 0)":"translate3d(-"+r+", 0, 0)",transition:t?"opacity 0.3s 0.4s cubic-bezier(.17, .67, .1, 1.27), transform 0.3s 0.4s cubic-bezier(.17, .67, .1, 1.27)":"opacity 0s 0.3s cubic-bezier(.17, .67, .1, 1.27), transform 0s 0.3s cubic-bezier(.17, .67, .1, 1.27)",opacity:t?1:0}}};e.default=(0,a.default)(o),t.exports=e.default}(ct,ct.exports);var ft={exports:{}};!function(t,e){Object.defineProperty(e,"__esModule",{value:!0});var n,r=(n=B.exports)&&n.__esModule?n:{default:n};e.default=(0,r.default)({pageWrap:function(t,e,n){return{MozTransform:t?"":n?"translate3d(-"+e+", 0, 0)":"translate3d("+e+", 0, 0)",MsTransform:t?"":n?"translate3d(-"+e+", 0, 0)":"translate3d("+e+", 0, 0)",OTransform:t?"":n?"translate3d(-"+e+", 0, 0)":"translate3d("+e+", 0, 0)",WebkitTransform:t?"":n?"translate3d(-"+e+", 0, 0)":"translate3d("+e+", 0, 0)",transform:t?"":n?"translate3d(-"+e+", 0, 0)":"translate3d("+e+", 0, 0)",transition:"all 0.5s"}},outerContainer:function(t){return{overflow:t?"":"hidden"}}}),t.exports=e.default}(ft,ft.exports);var dt={exports:{}};!function(t,e){Object.defineProperty(e,"__esModule",{value:!0});var n,r=(n=B.exports)&&n.__esModule?n:{default:n};e.default=(0,r.default)({pageWrap:function(t,e,n){return{MozTransform:t?"":n?"translate3d(-"+e+", 0, 0) rotateY(15deg)":"translate3d("+e+", 0, 0) rotateY(-15deg)",MsTransform:t?"":n?"translate3d(-"+e+", 0, 0) rotateY(15deg)":"translate3d("+e+", 0, 0) rotateY(-15deg)",OTransform:t?"":n?"translate3d(-"+e+", 0, 0) rotateY(15deg)":"translate3d("+e+", 0, 0) rotateY(-15deg)",WebkitTransform:t?"":n?"translate3d(-"+e+", 0, 0) rotateY(15deg)":"translate3d("+e+", 0, 0) rotateY(-15deg)",transform:t?"":n?"translate3d(-"+e+", 0, 0) rotateY(15deg)":"translate3d("+e+", 0, 0) rotateY(-15deg)",transformOrigin:n?"100% 50%":"0% 50%",transformStyle:"preserve-3d",transition:"all 0.5s"}},outerContainer:function(t){return{perspective:"1500px",overflow:t?"":"hidden"}}}),t.exports=e.default}(dt,dt.exports);var ht={exports:{}};!function(t,e){Object.defineProperty(e,"__esModule",{value:!0});var n,r=(n=B.exports)&&n.__esModule?n:{default:n};e.default=(0,r.default)({pageWrap:function(t,e){return{MozTransform:t?"":"translate3d(0, 0, -"+e+")",MsTransform:t?"":"translate3d(0, 0, -"+e+")",OTransform:t?"":"translate3d(0, 0, -"+e+")",WebkitTransform:t?"":"translate3d(0, 0, -"+e+")",transform:t?"":"translate3d(0, 0, -"+e+")",transformOrigin:"100%",transformStyle:"preserve-3d",transition:"all 0.5s"}},outerContainer:function(){return{perspective:"1500px"}}}),t.exports=e.default}(ht,ht.exports);var pt={exports:{}};!function(t,e){Object.defineProperty(e,"__esModule",{value:!0});var n,r=(n=B.exports)&&n.__esModule?n:{default:n};e.default=(0,r.default)({pageWrap:function(t,e,n){return{MozTransform:t?"":n?"translate3d(-100px, 0, -600px) rotateY(20deg)":"translate3d(100px, 0, -600px) rotateY(-20deg)",MsTransform:t?"":n?"translate3d(-100px, 0, -600px) rotateY(20deg)":"translate3d(100px, 0, -600px) rotateY(-20deg)",OTransform:t?"":n?"translate3d(-100px, 0, -600px) rotateY(20deg)":"translate3d(100px, 0, -600px) rotateY(-20deg)",WebkitTransform:t?"":n?"translate3d(-100px, 0, -600px) rotateY(20deg)":"translate3d(100px, 0, -600px) rotateY(-20deg)",transform:t?"":n?"translate3d(-100px, 0, -600px) rotateY(20deg)":"translate3d(100px, 0, -600px) rotateY(-20deg)",transformStyle:"preserve-3d",transition:"all 0.5s",overflow:t?"":"hidden"}},outerContainer:function(t){return{perspective:"1500px",overflow:t?"":"hidden"}}}),t.exports=e.default}(pt,pt.exports);var mt={exports:{}};!function(t,e){Object.defineProperty(e,"__esModule",{value:!0});var n,r=(n=B.exports)&&n.__esModule?n:{default:n};e.default=(0,r.default)({menuWrap:function(t){return{MozTransform:t?"":"translate3d(0, -100%, 0)",MsTransform:t?"":"translate3d(0, -100%, 0)",OTransform:t?"":"translate3d(0, -100%, 0)",WebkitTransform:t?"":"translate3d(0, -100%, 0)",transform:t?"":"translate3d(0, -100%, 0)",transition:"all 0.5s ease-in-out"}},pageWrap:function(t,e,n){return{MozTransform:t?"":n?"translate3d(-"+e+", 0, 0)":"translate3d("+e+", 0, 0)",MsTransform:t?"":n?"translate3d(-"+e+", 0, 0)":"translate3d("+e+", 0, 0)",OTransform:t?"":n?"translate3d(-"+e+", 0, 0)":"translate3d("+e+", 0, 0)",WebkitTransform:t?"":n?"translate3d(-"+e+", 0, 0)":"translate3d("+e+", 0, 0)",transform:t?"":n?"translate3d(-"+e+", 0, 0)":"translate3d("+e+", 0, 0)",transition:"all 0.5s"}},outerContainer:function(t){return{perspective:"1500px",perspectiveOrigin:"0% 50%",overflow:t?"":"hidden"}}}),t.exports=e.default}(mt,mt.exports);var gt={exports:{}};!function(t,e){Object.defineProperty(e,"__esModule",{value:!0});var n,r=(n=B.exports)&&n.__esModule?n:{default:n};e.default=(0,r.default)({menuWrap:function(t,e,n){return{MozTransform:"translate3d(0, 0, 0)",MsTransform:"translate3d(0, 0, 0)",OTransform:"translate3d(0, 0, 0)",WebkitTransform:"translate3d(0, 0, 0)",transform:"translate3d(0, 0, 0)",zIndex:t?1e3:-1}},overlay:function(t,e,n){return{zIndex:1400,MozTransform:t?n?"translate3d(-"+e+", 0, 0)":"translate3d("+e+", 0, 0)":"translate3d(0, 0, 0)",MsTransform:t?n?"translate3d(-"+e+", 0, 0)":"translate3d("+e+", 0, 0)":"translate3d(0, 0, 0)",OTransform:t?n?"translate3d(-"+e+", 0, 0)":"translate3d("+e+", 0, 0)":"translate3d(0, 0, 0)",WebkitTransform:t?n?"translate3d(-"+e+", 0, 0)":"translate3d("+e+", 0, 0)":"translate3d(0, 0, 0)",transform:t?n?"translate3d(-"+e+", 0, 0)":"translate3d("+e+", 0, 0)":"translate3d(0, 0, 0)",transition:"all 0.5s",visibility:t?"visible":"hidden"}},pageWrap:function(t,e,n){return{MozTransform:t?"":n?"translate3d(-"+e+", 0, 0)":"translate3d("+e+", 0, 0)",MsTransform:t?"":n?"translate3d(-"+e+", 0, 0)":"translate3d("+e+", 0, 0)",OTransform:t?"":n?"translate3d(-"+e+", 0, 0)":"translate3d("+e+", 0, 0)",WebkitTransform:t?"":n?"translate3d(-"+e+", 0, 0)":"translate3d("+e+", 0, 0)",transform:t?"":n?"translate3d(-"+e+", 0, 0)":"translate3d("+e+", 0, 0)",transition:"all 0.5s",zIndex:1200,position:"relative"}},burgerIcon:function(t,e,n){return{MozTransform:t?n?"translate3d("+e+", 0, 0)":"translate3d(-"+e+", 0, 0)":"translate3d(0, 0, 0)",MsTransform:t?n?"translate3d("+e+", 0, 0)":"translate3d(-"+e+", 0, 0)":"translate3d(0, 0, 0)",OTransform:t?n?"translate3d("+e+", 0, 0)":"translate3d(-"+e+", 0, 0)":"translate3d(0, 0, 0)",WebkitTransform:t?n?"translate3d("+e+", 0, 0)":"translate3d(-"+e+", 0, 0)":"translate3d(0, 0, 0)",transform:t?n?"translate3d("+e+", 0, 0)":"translate3d(-"+e+", 0, 0)":"translate3d(0, 0, 0)",transition:"all 0.1s",position:"relative",zIndex:1300}},outerContainer:function(t){return{overflow:t?"":"hidden"}}}),t.exports=e.default}(gt,gt.exports),function(t,e){Object.defineProperty(e,"__esModule",{value:!0}),e.default={slide:k.exports,stack:$.exports,elastic:rt.exports,bubble:ct.exports,push:ft.exports,pushRotate:dt.exports,scaleDown:ht.exports,scaleRotate:pt.exports,fallDown:mt.exports,reveal:gt.exports},t.exports=e.default}(M,M.exports);const vt=u.exports.createContext({}),yt=({children:t})=>{const[e,n]=u.exports.useState(!1);return l.createElement(vt.Provider,{value:{isMenuOpen:e,toggleMenu:()=>n(!e),stateChangeHandler:t=>n(t.isOpen)}},t)},xt=()=>{const t=u.exports.useContext(vt);return l.createElement("img",{className:"menu-btn",src:"/assets/menu.284d3ab8.svg",onClick:t.toggleMenu})},bt=({options:t})=>{const e=d(),n=h(),r=u.exports.useContext(vt),a=t.find((t=>t.path===n.pathname)),i="/"===(null==a?void 0:a.path);return l.createElement(l.Fragment,null,l.createElement(p,null,l.createElement("title",null,"浮之静",a&&!i?` | ${null==a?void 0:a.name}`:"")),l.createElement(M.exports.slide,{right:!0,customBurgerIcon:!1,isOpen:r.isMenuOpen,onStateChange:t=>r.stateChangeHandler(t)},t.map((t=>l.createElement("span",{key:t.path,onClick:()=>{return n=t.path,e.push(n),void r.toggleMenu();var n}},t.name)))))};const wt=({menuList:t})=>{const e=d();return l.createElement(yt,null,l.createElement("div",{className:"fzj-header"},l.createElement("div",{className:"logo-box",onClick:()=>e.push("/")},l.createElement("div",{className:"logo"})),l.createElement("div",{className:"fzj-btns"},l.createElement("img",{className:"fzj-rss",src:"/assets/rss.2a18b2d2.svg",onClick:()=>location.href="/feed.xml",alt:"RSS"}),l.createElement(A,null))),l.createElement("div",{className:"menu"},l.createElement(xt,null),l.createElement(bt,{options:t})))};wt.defaultProps={menuList:[]};function Ct(){return l.createElement("div",{className:"fzj-footer"},"© 2020 浮之静 💖 ",l.createElement("a",{href:"https://github.com/lencx"},"lencx"))}var Ft={exports:{}},Et=Ft.exports=function(){var t=1e3,e=6e4,n=36e5,r="millisecond",a="second",i="minute",o="hour",s="day",l="week",u="month",c="quarter",f="year",d="date",h="Invalid Date",p=/^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/,m=/\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,g={name:"en",weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_")},v=function(t,e,n){var r=String(t);return!r||r.length>=e?t:""+Array(e+1-r.length).join(n)+t},y={s:v,z:function(t){var e=-t.utcOffset(),n=Math.abs(e),r=Math.floor(n/60),a=n%60;return(e<=0?"+":"-")+v(r,2,"0")+":"+v(a,2,"0")},m:function t(e,n){if(e.date(){for(const[n,r]of e)t=t.replace(new RegExp(Ot(n),"g"),r);return t})(t=t.normalize(),n),t=Pt(t)}const Yt=[["&"," and "],["🦄"," unicorn "],["♥"," love "]];function Ut(t,e){if("string"!=typeof t)throw new TypeError(`Expected a string, got \`${typeof t}\``);const n=(e=s({separator:"-",lowercase:!0,decamelize:!0,customReplacements:[],preserveLeadingUnderscore:!1,preserveTrailingDash:!1},e)).preserveLeadingUnderscore&&t.startsWith("_"),r=e.preserveTrailingDash&&t.endsWith("-");t=$t(t,{customReplacements:new Map([...Yt,...e.customReplacements])}),e.decamelize&&(t=(t=>t.replace(/([A-Z]{2,})(\d+)/g,"$1 $2").replace(/([a-z\d]+)([A-Z]{2,})/g,"$1 $2").replace(/([a-z\d])([A-Z])/g,"$1 $2").replace(/([A-Z]+)([A-Z][a-z\d]+)/g,"$1 $2"))(t));let a=/[^a-zA-Z\d]+/g;return e.lowercase&&(t=t.toLowerCase(),a=/[^a-z\d]+/g),t=(t=t.replace(a,e.separator)).replace(/\\/g,""),e.separator&&(t=((t,e)=>{const n=Ot(e);return t.replace(new RegExp(`${n}{2,}`,"g"),e).replace(new RegExp(`^${n}|${n}$`,"g"),"")})(t,e.separator)),n&&(t=`_${t}`),r&&(t=`${t}-`),t}const Rt={THUMBS_UP:["👍",":+1:"],THUMBS_DOWN:["👎",":-1:"],LAUGH:["😄",":laugh:"],HOORAY:["🎉",":hooray:"],CONFUSED:["😕",":confused:"],HEART:["❤️",":heart:"],ROCKET:["🚀",":rocket:"],EYES:["👀",":eyes:"]},Vt=20,Ht="https://raw.githubusercontent.com/lencx/z/gh-pages",qt=t=>`https://github.com/lencx/z/discussions/categories/${Ut(t)}`,Wt=t=>`https://github.com/lencx/z/discussions/${t}`;function Gt(t){const e=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight),n=window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop;(window.innerHeight||Math.min(document.documentElement.clientHeight,document.body.clientHeight))+n>=e&&t()}function Xt(t,e){e&&e.stopPropagation(),window.open(t)}function Zt(t){const e=new Map;return t.forEach((({node:t})=>{const n=Rt[t.content][0];if(e.has(n)){const t=e.get(n);e.set(n,t+1)}else e.set(n,1)})),Array.from(e)}const Kt=t=>Et(t).format("YYYY.MM.DD HH:mm:ss");const Jt=({minHeight:t})=>{const[e,n]=u.exports.useState(!1),r=()=>{((t=window)=>({x:void 0!==t.pageXOffset?t.pageXOffset:t.scrollLeft,y:void 0!==t.pageYOffset?t.pageYOffset:t.scrollTop}))().y>t?e||n(!0):n(!1)};return u.exports.useEffect((()=>(window.addEventListener("scroll",r),()=>{window.removeEventListener("scroll",r)}))),l.createElement("div",{id:"fzj-backtop",className:e?"show":"hide",onClick:()=>{(document.documentElement.scrollTop||document.body.scrollTop)>0?window.scrollTo({top:0,behavior:"smooth"}):e||n(!1)}},l.createElement("svg",{viewBox:"0 0 98 125",xmlns:"http://www.w3.org/2000/svg"},l.createElement("path",{d:"m.41627505 120.505813c.36557376-2.799314 38.38567845-112.09375627 40.40633855-116.52273479 2.0206601-4.42897853 7.0443939-6.06190829 10.0049342.20172081 1.9736935 4.17575274 17.3630227 42.22464148 46.1679874 114.14666598.3068629 1.030234.4237748 1.755017.3507358 2.174348-.4483666 2.574161-2.3292736 3.429521-4.6125739 2.516093-15.0683018-6.028033-36.2681037-23.1692513-43.8663627-23.1692513-7.5982589 0-27.0568176 12.9171643-43.18383202 23.1692513-.96511235.613531-1.91473089 1.069619-2.88840599 1.149501s-2.74439509-.86628-2.37882134-3.665594z",fill:"#666",fillRule:"evenodd"})))};Jt.defaultProps={minHeight:300};const Qt=t=>l.createElement(u.exports.Suspense,{fallback:t.fallback||null},l.createElement(m,{path:t.path,render:r=>{return t.component&&l.createElement(t.component,(a=s({},r),i={routes:t.routes},e(a,n(i))));var a,i}})),te=({routes:t})=>l.createElement(v,null,t.map((t=>l.createElement(Qt,s({key:t.path},t))))),ee={},ne=function(t,e){return e&&0!==e.length?Promise.all(e.map((t=>{if((t=`/${t}`)in ee)return;ee[t]=!0;const e=t.endsWith(".css"),n=e?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${t}"]${n}`))return;const r=document.createElement("link");return r.rel=e?"stylesheet":"modulepreload",e||(r.as="script",r.crossOrigin=""),r.href=t,document.head.appendChild(r),e?new Promise(((t,e)=>{r.addEventListener("load",t),r.addEventListener("error",e)})):void 0}))).then((()=>t())):t()},re=[{path:"/",name:"Blog",component:u.exports.lazy((()=>ne((()=>import("./index.e0d0297d.js")),["assets/index.e0d0297d.js","assets/index.302ac48d.css","assets/react.434ff2b9.js","assets/index.a5f9fb0d.js","assets/index.54af1b7f.css","assets/fzj.08fd6cc8.js","assets/fzj.271820f2.css","assets/lodash.71f9f2ff.js","assets/graphql.8e66ecff.js","assets/index.5119c8ec.js","assets/index.908b2c85.css"]))),exact:!0},{path:"/issues/:issues",component:u.exports.lazy((()=>ne((()=>import("./index.e5525a57.js")),["assets/index.e5525a57.js","assets/index.735d43ee.css","assets/react.434ff2b9.js","assets/fzj.08fd6cc8.js","assets/fzj.271820f2.css","assets/lodash.71f9f2ff.js","assets/graphql.8e66ecff.js","assets/index.a5f9fb0d.js","assets/index.54af1b7f.css"]))),exact:!0},{path:"/tags",name:"Tags",component:u.exports.lazy((()=>ne((()=>import("./index.5f87edea.js")),["assets/index.5f87edea.js","assets/index.c4924ca0.css","assets/react.434ff2b9.js","assets/fzj.08fd6cc8.js","assets/fzj.271820f2.css","assets/lodash.71f9f2ff.js","assets/graphql.8e66ecff.js","assets/index.5119c8ec.js","assets/index.908b2c85.css"]))),exact:!0},{path:"/project",name:"Projects",component:u.exports.lazy((()=>ne((()=>import("./index.39fc9160.js")),["assets/index.39fc9160.js","assets/index.6c2ed225.css","assets/react.434ff2b9.js"]))),exact:!0},{path:"/about",name:"About",component:u.exports.lazy((()=>ne((()=>import("./index.3bdcf399.js")),["assets/index.3bdcf399.js","assets/index.d15a088f.css","assets/react.434ff2b9.js"]))),exact:!0}],ae=re.filter((t=>!!t.name));function ie(){return l.createElement(y,null,l.createElement(x,null,l.createElement("div",{className:"view"},l.createElement(wt,{menuList:ae}),l.createElement(te,{routes:re}),l.createElement(Ct,null),l.createElement(Jt,null))))}b.render(l.createElement(l.StrictMode,null,l.createElement(E,{client:T},l.createElement(w,null,l.createElement(ie,null)))),document.getElementById("root"));export{Ht as B,qt as c,Wt as d,Kt as f,Xt as h,Vt as p,Zt as r,Gt as s};
diff --git a/assets/lodash.71f9f2ff.js b/assets/lodash.71f9f2ff.js
new file mode 100644
index 0000000..3d62b9f
--- /dev/null
+++ b/assets/lodash.71f9f2ff.js
@@ -0,0 +1 @@
+var e="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};export{e as c};
diff --git a/assets/menu.284d3ab8.svg b/assets/menu.284d3ab8.svg
new file mode 100644
index 0000000..5e314aa
--- /dev/null
+++ b/assets/menu.284d3ab8.svg
@@ -0,0 +1,6 @@
+
+
+
\ No newline at end of file
diff --git a/assets/react.434ff2b9.js b/assets/react.434ff2b9.js
new file mode 100644
index 0000000..a36cb9d
--- /dev/null
+++ b/assets/react.434ff2b9.js
@@ -0,0 +1,27 @@
+var e=Object.defineProperty,t=Object.defineProperties,n=Object.getOwnPropertyDescriptors,r=Object.getOwnPropertySymbols,o=Object.prototype.hasOwnProperty,a=Object.prototype.propertyIsEnumerable,i=(t,n,r)=>n in t?e(t,n,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[n]=r,l=(e,t)=>{for(var n in t||(t={}))o.call(t,n)&&i(e,n,t[n]);if(r)for(var n of r(t))a.call(t,n)&&i(e,n,t[n]);return e},u=(e,r)=>t(e,n(r)),s=(e,t)=>{var n={};for(var i in e)o.call(e,i)&&t.indexOf(i)<0&&(n[i]=e[i]);if(null!=e&&r)for(var i of r(e))t.indexOf(i)<0&&a.call(e,i)&&(n[i]=e[i]);return n},c={exports:{}},f={},d=Object.getOwnPropertySymbols,p=Object.prototype.hasOwnProperty,h=Object.prototype.propertyIsEnumerable;function m(e){if(null==e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}var v=function(){try{if(!Object.assign)return!1;var e=new String("abc");if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var t={},n=0;n<10;n++)t["_"+String.fromCharCode(n)]=n;if("0123456789"!==Object.getOwnPropertyNames(t).map((function(e){return t[e]})).join(""))return!1;var r={};return"abcdefghijklmnopqrst".split("").forEach((function(e){r[e]=e})),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},r)).join("")}catch(o){return!1}}()?Object.assign:function(e,t){for(var n,r,o=m(e),a=1;a=g},o=function(){},e.unstable_forceFrameRate=function(e){0>e||125>>1,o=e[r];if(!(void 0!==o&&0E(i,n))void 0!==u&&0>E(u,i)?(e[r]=u,e[l]=n,r=l):(e[r]=i,e[a]=n,r=a);else{if(!(void 0!==u&&0>E(u,n)))break e;e[r]=u,e[l]=n,r=l}}}return t}return null}function E(e,t){var n=e.sortIndex-t.sortIndex;return 0!==n?n:e.id-t.id}var T=[],C=[],x=1,R=null,N=3,A=!1,L=!1,P=!1;function M(e){for(var t=_(C);null!==t;){if(null===t.callback)k(C);else{if(!(t.startTime<=e))break;k(C),t.sortIndex=t.expirationTime,S(T,t)}t=_(C)}}function O(e){if(P=!1,M(e),!L)if(null!==_(T))L=!0,t(V);else{var r=_(C);null!==r&&n(O,r.startTime-e)}}function V(t,o){L=!1,P&&(P=!1,r()),A=!0;var a=N;try{for(M(o),R=_(T);null!==R&&(!(R.expirationTime>o)||t&&!e.unstable_shouldYield());){var i=R.callback;if("function"==typeof i){R.callback=null,N=R.priorityLevel;var l=i(R.expirationTime<=o);o=e.unstable_now(),"function"==typeof l?R.callback=l:R===_(T)&&k(T),M(o)}else k(T);R=_(T)}if(null!==R)var u=!0;else{var s=_(C);null!==s&&n(O,s.startTime-o),u=!1}return u}finally{R=null,N=a,A=!1}}var z=o;e.unstable_IdlePriority=5,e.unstable_ImmediatePriority=1,e.unstable_LowPriority=4,e.unstable_NormalPriority=3,e.unstable_Profiling=null,e.unstable_UserBlockingPriority=2,e.unstable_cancelCallback=function(e){e.callback=null},e.unstable_continueExecution=function(){L||A||(L=!0,t(V))},e.unstable_getCurrentPriorityLevel=function(){return N},e.unstable_getFirstCallbackNode=function(){return _(T)},e.unstable_next=function(e){switch(N){case 1:case 2:case 3:var t=3;break;default:t=N}var n=N;N=t;try{return e()}finally{N=n}},e.unstable_pauseExecution=function(){},e.unstable_requestPaint=z,e.unstable_runWithPriority=function(e,t){switch(e){case 1:case 2:case 3:case 4:case 5:break;default:e=3}var n=N;N=e;try{return t()}finally{N=n}},e.unstable_scheduleCallback=function(o,a,i){var l=e.unstable_now();switch("object"==typeof i&&null!==i?i="number"==typeof(i=i.delay)&&0l?(o.sortIndex=i,S(C,o),null===_(T)&&o===_(C)&&(P?r():P=!0,n(O,i-l))):(o.sortIndex=u,S(T,o),L||A||(L=!0,t(V))),o},e.unstable_wrapCallback=function(e){var t=N;return function(){var n=N;N=t;try{return e.apply(this,arguments)}finally{N=n}}}}(Z),Y.exports=Z;
+/** @license React v17.0.2
+ * react-dom.production.min.js
+ *
+ * Copyright (c) Facebook, Inc. and its affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+var X=c.exports,J=v,ee=Y.exports;function te(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;nt}return!1}(t,n,o,r)&&(n=null),r||null===o?function(e){return!!ue.call(ce,e)||!ue.call(se,e)&&(le.test(e)?ce[e]=!0:(se[e]=!0,!1))}(t)&&(null===n?e.removeAttribute(t):e.setAttribute(t,""+n)):o.mustUseProperty?e[o.propertyName]=null===n?3!==o.type&&"":n:(t=o.attributeName,r=o.attributeNamespace,null===n?e.removeAttribute(t):(n=3===(o=o.type)||4===o&&!0===n?"":""+n,r?e.setAttributeNS(r,t,n):e.setAttribute(t,n))))}"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height".split(" ").forEach((function(e){var t=e.replace(pe,he);de[t]=new fe(t,1,!1,e,null,!1,!1)})),"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type".split(" ").forEach((function(e){var t=e.replace(pe,he);de[t]=new fe(t,1,!1,e,"http://www.w3.org/1999/xlink",!1,!1)})),["xml:base","xml:lang","xml:space"].forEach((function(e){var t=e.replace(pe,he);de[t]=new fe(t,1,!1,e,"http://www.w3.org/XML/1998/namespace",!1,!1)})),["tabIndex","crossOrigin"].forEach((function(e){de[e]=new fe(e,1,!1,e.toLowerCase(),null,!1,!1)})),de.xlinkHref=new fe("xlinkHref",1,!1,"xlink:href","http://www.w3.org/1999/xlink",!0,!1),["src","href","action","formAction"].forEach((function(e){de[e]=new fe(e,1,!1,e.toLowerCase(),null,!0,!0)}));var ve=X.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,ye=60103,ge=60106,be=60107,we=60108,Se=60114,_e=60109,ke=60110,Ee=60112,Te=60113,Ce=60120,xe=60115,Re=60116,Ne=60121,Ae=60128,Le=60129,Pe=60130,Me=60131;if("function"==typeof Symbol&&Symbol.for){var Oe=Symbol.for;ye=Oe("react.element"),ge=Oe("react.portal"),be=Oe("react.fragment"),we=Oe("react.strict_mode"),Se=Oe("react.profiler"),_e=Oe("react.provider"),ke=Oe("react.context"),Ee=Oe("react.forward_ref"),Te=Oe("react.suspense"),Ce=Oe("react.suspense_list"),xe=Oe("react.memo"),Re=Oe("react.lazy"),Ne=Oe("react.block"),Oe("react.scope"),Ae=Oe("react.opaque.id"),Le=Oe("react.debug_trace_mode"),Pe=Oe("react.offscreen"),Me=Oe("react.legacy_hidden")}var Ve,ze="function"==typeof Symbol&&Symbol.iterator;function Ie(e){return null===e||"object"!=typeof e?null:"function"==typeof(e=ze&&e[ze]||e["@@iterator"])?e:null}function De(e){if(void 0===Ve)try{throw Error()}catch(n){var t=n.stack.trim().match(/\n( *(at )?)/);Ve=t&&t[1]||""}return"\n"+Ve+e}var Ue=!1;function Fe(e,t){if(!e||Ue)return"";Ue=!0;var n=Error.prepareStackTrace;Error.prepareStackTrace=void 0;try{if(t)if(t=function(){throw Error()},Object.defineProperty(t.prototype,"props",{set:function(){throw Error()}}),"object"==typeof Reflect&&Reflect.construct){try{Reflect.construct(t,[])}catch(u){var r=u}Reflect.construct(e,[],t)}else{try{t.call()}catch(u){r=u}e.call(t.prototype)}else{try{throw Error()}catch(u){r=u}e()}}catch(u){if(u&&r&&"string"==typeof u.stack){for(var o=u.stack.split("\n"),a=r.stack.split("\n"),i=o.length-1,l=a.length-1;1<=i&&0<=l&&o[i]!==a[l];)l--;for(;1<=i&&0<=l;i--,l--)if(o[i]!==a[l]){if(1!==i||1!==l)do{if(i--,0>--l||o[i]!==a[l])return"\n"+o[i].replace(" at new "," at ")}while(1<=i&&0<=l);break}}}finally{Ue=!1,Error.prepareStackTrace=n}return(e=e?e.displayName||e.name:"")?De(e):""}function Be(e){switch(e.tag){case 5:return De(e.type);case 16:return De("Lazy");case 13:return De("Suspense");case 19:return De("SuspenseList");case 0:case 2:case 15:return e=Fe(e.type,!1);case 11:return e=Fe(e.type.render,!1);case 22:return e=Fe(e.type._render,!1);case 1:return e=Fe(e.type,!0);default:return""}}function je(e){if(null==e)return null;if("function"==typeof e)return e.displayName||e.name||null;if("string"==typeof e)return e;switch(e){case be:return"Fragment";case ge:return"Portal";case Se:return"Profiler";case we:return"StrictMode";case Te:return"Suspense";case Ce:return"SuspenseList"}if("object"==typeof e)switch(e.$$typeof){case ke:return(e.displayName||"Context")+".Consumer";case _e:return(e._context.displayName||"Context")+".Provider";case Ee:var t=e.render;return t=t.displayName||t.name||"",e.displayName||(""!==t?"ForwardRef("+t+")":"ForwardRef");case xe:return je(e.type);case Ne:return je(e._render);case Re:t=e._payload,e=e._init;try{return je(e(t))}catch(n){}}return null}function $e(e){switch(typeof e){case"boolean":case"number":case"object":case"string":case"undefined":return e;default:return""}}function He(e){var t=e.type;return(e=e.nodeName)&&"input"===e.toLowerCase()&&("checkbox"===t||"radio"===t)}function We(e){e._valueTracker||(e._valueTracker=function(e){var t=He(e)?"checked":"value",n=Object.getOwnPropertyDescriptor(e.constructor.prototype,t),r=""+e[t];if(!e.hasOwnProperty(t)&&void 0!==n&&"function"==typeof n.get&&"function"==typeof n.set){var o=n.get,a=n.set;return Object.defineProperty(e,t,{configurable:!0,get:function(){return o.call(this)},set:function(e){r=""+e,a.call(this,e)}}),Object.defineProperty(e,t,{enumerable:n.enumerable}),{getValue:function(){return r},setValue:function(e){r=""+e},stopTracking:function(){e._valueTracker=null,delete e[t]}}}}(e))}function qe(e){if(!e)return!1;var t=e._valueTracker;if(!t)return!0;var n=t.getValue(),r="";return e&&(r=He(e)?e.checked?"true":"false":e.value),(e=r)!==n&&(t.setValue(e),!0)}function Ke(e){if(void 0===(e=e||("undefined"!=typeof document?document:void 0)))return null;try{return e.activeElement||e.body}catch(t){return e.body}}function Qe(e,t){var n=t.checked;return J({},t,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:null!=n?n:e._wrapperState.initialChecked})}function Ge(e,t){var n=null==t.defaultValue?"":t.defaultValue,r=null!=t.checked?t.checked:t.defaultChecked;n=$e(null!=t.value?t.value:n),e._wrapperState={initialChecked:r,initialValue:n,controlled:"checkbox"===t.type||"radio"===t.type?null!=t.checked:null!=t.value}}function Ye(e,t){null!=(t=t.checked)&&me(e,"checked",t,!1)}function Ze(e,t){Ye(e,t);var n=$e(t.value),r=t.type;if(null!=n)"number"===r?(0===n&&""===e.value||e.value!=n)&&(e.value=""+n):e.value!==""+n&&(e.value=""+n);else if("submit"===r||"reset"===r)return void e.removeAttribute("value");t.hasOwnProperty("value")?Je(e,t.type,n):t.hasOwnProperty("defaultValue")&&Je(e,t.type,$e(t.defaultValue)),null==t.checked&&null!=t.defaultChecked&&(e.defaultChecked=!!t.defaultChecked)}function Xe(e,t,n){if(t.hasOwnProperty("value")||t.hasOwnProperty("defaultValue")){var r=t.type;if(!("submit"!==r&&"reset"!==r||void 0!==t.value&&null!==t.value))return;t=""+e._wrapperState.initialValue,n||t===e.value||(e.value=t),e.defaultValue=t}""!==(n=e.name)&&(e.name=""),e.defaultChecked=!!e._wrapperState.initialChecked,""!==n&&(e.name=n)}function Je(e,t,n){"number"===t&&Ke(e.ownerDocument)===e||(null==n?e.defaultValue=""+e._wrapperState.initialValue:e.defaultValue!==""+n&&(e.defaultValue=""+n))}function et(e,t){return e=J({children:void 0},t),(t=function(e){var t="";return X.Children.forEach(e,(function(e){null!=e&&(t+=e)})),t}(t.children))&&(e.children=t),e}function tt(e,t,n,r){if(e=e.options,t){t={};for(var o=0;o=n.length))throw Error(te(93));n=n[0]}t=n}null==t&&(t=""),n=t}e._wrapperState={initialValue:$e(n)}}function ot(e,t){var n=$e(t.value),r=$e(t.defaultValue);null!=n&&((n=""+n)!==e.value&&(e.value=n),null==t.defaultValue&&e.defaultValue!==n&&(e.defaultValue=n)),null!=r&&(e.defaultValue=""+r)}function at(e){var t=e.textContent;t===e._wrapperState.initialValue&&""!==t&&null!==t&&(e.value=t)}var it="http://www.w3.org/1999/xhtml",lt="http://www.w3.org/2000/svg";function ut(e){switch(e){case"svg":return"http://www.w3.org/2000/svg";case"math":return"http://www.w3.org/1998/Math/MathML";default:return"http://www.w3.org/1999/xhtml"}}function st(e,t){return null==e||"http://www.w3.org/1999/xhtml"===e?ut(t):"http://www.w3.org/2000/svg"===e&&"foreignObject"===t?"http://www.w3.org/1999/xhtml":e}var ct,ft,dt=(ft=function(e,t){if(e.namespaceURI!==lt||"innerHTML"in e)e.innerHTML=t;else{for((ct=ct||document.createElement("div")).innerHTML=""+t.valueOf().toString()+" ",t=ct.firstChild;e.firstChild;)e.removeChild(e.firstChild);for(;t.firstChild;)e.appendChild(t.firstChild)}},"undefined"!=typeof MSApp&&MSApp.execUnsafeLocalFunction?function(e,t,n,r){MSApp.execUnsafeLocalFunction((function(){return ft(e,t)}))}:ft);function pt(e,t){if(t){var n=e.firstChild;if(n&&n===e.lastChild&&3===n.nodeType)return void(n.nodeValue=t)}e.textContent=t}var ht={animationIterationCount:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridArea:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},mt=["Webkit","ms","Moz","O"];function vt(e,t,n){return null==t||"boolean"==typeof t||""===t?"":n||"number"!=typeof t||0===t||ht.hasOwnProperty(e)&&ht[e]?(""+t).trim():t+"px"}function yt(e,t){for(var n in e=e.style,t)if(t.hasOwnProperty(n)){var r=0===n.indexOf("--"),o=vt(n,t[n],r);"float"===n&&(n="cssFloat"),r?e.setProperty(n,o):e[n]=o}}Object.keys(ht).forEach((function(e){mt.forEach((function(t){t=t+e.charAt(0).toUpperCase()+e.substring(1),ht[t]=ht[e]}))}));var gt=J({menuitem:!0},{area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0});function bt(e,t){if(t){if(gt[e]&&(null!=t.children||null!=t.dangerouslySetInnerHTML))throw Error(te(137,e));if(null!=t.dangerouslySetInnerHTML){if(null!=t.children)throw Error(te(60));if("object"!=typeof t.dangerouslySetInnerHTML||!("__html"in t.dangerouslySetInnerHTML))throw Error(te(61))}if(null!=t.style&&"object"!=typeof t.style)throw Error(te(62))}}function wt(e,t){if(-1===e.indexOf("-"))return"string"==typeof t.is;switch(e){case"annotation-xml":case"color-profile":case"font-face":case"font-face-src":case"font-face-uri":case"font-face-format":case"font-face-name":case"missing-glyph":return!1;default:return!0}}function St(e){return(e=e.target||e.srcElement||window).correspondingUseElement&&(e=e.correspondingUseElement),3===e.nodeType?e.parentNode:e}var _t=null,kt=null,Et=null;function Tt(e){if(e=Yo(e)){if("function"!=typeof _t)throw Error(te(280));var t=e.stateNode;t&&(t=Xo(t),_t(e.stateNode,e.type,t))}}function Ct(e){kt?Et?Et.push(e):Et=[e]:kt=e}function xt(){if(kt){var e=kt,t=Et;if(Et=kt=null,Tt(e),t)for(e=0;e(r=31-Fn(r))?0:1<n;n++)t.push(e);return t}function Un(e,t,n){e.pendingLanes|=t;var r=t-1;e.suspendedLanes&=r,e.pingedLanes&=r,(e=e.eventTimes)[t=31-Fn(t)]=n}var Fn=Math.clz32?Math.clz32:function(e){return 0===e?32:31-(Bn(e)/jn|0)|0},Bn=Math.log,jn=Math.LN2;var $n=ee.unstable_UserBlockingPriority,Hn=ee.unstable_runWithPriority,Wn=!0;function qn(e,t,n,r){Pt||At();var o=Qn,a=Pt;Pt=!0;try{Nt(o,e,t,n,r)}finally{(Pt=a)||Ot()}}function Kn(e,t,n,r){Hn($n,Qn.bind(null,e,t,n,r))}function Qn(e,t,n,r){var o;if(Wn)if((o=0==(4&t))&&0=Ar),Mr=String.fromCharCode(32),Or=!1;function Vr(e,t){switch(e){case"keyup":return-1!==Rr.indexOf(t.keyCode);case"keydown":return 229!==t.keyCode;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function zr(e){return"object"==typeof(e=e.detail)&&"data"in e?e.data:null}var Ir=!1;var Dr={color:!0,date:!0,datetime:!0,"datetime-local":!0,email:!0,month:!0,number:!0,password:!0,range:!0,search:!0,tel:!0,text:!0,time:!0,url:!0,week:!0};function Ur(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return"input"===t?!!Dr[e.type]:"textarea"===t}function Fr(e,t,n,r){Ct(r),0<(t=Ao(t,"onChange")).length&&(n=new ur("onChange","change",null,n,r),e.push({event:n,listeners:t}))}var Br=null,jr=null;function $r(e){_o(e,0)}function Hr(e){if(qe(Zo(e)))return e}function Wr(e,t){if("change"===e)return t}var qr=!1;if(ie){var Kr;if(ie){var Qr="oninput"in document;if(!Qr){var Gr=document.createElement("div");Gr.setAttribute("oninput","return;"),Qr="function"==typeof Gr.oninput}Kr=Qr}else Kr=!1;qr=Kr&&(!document.documentMode||9=t)return{node:r,offset:t-e};e=n}e:{for(;r;){if(r.nextSibling){r=r.nextSibling;break e}r=r.parentNode}r=void 0}r=ao(r)}}function lo(e,t){return!(!e||!t)&&(e===t||(!e||3!==e.nodeType)&&(t&&3===t.nodeType?lo(e,t.parentNode):"contains"in e?e.contains(t):!!e.compareDocumentPosition&&!!(16&e.compareDocumentPosition(t))))}function uo(){for(var e=window,t=Ke();t instanceof e.HTMLIFrameElement;){try{var n="string"==typeof t.contentWindow.location.href}catch(r){n=!1}if(!n)break;t=Ke((e=t.contentWindow).document)}return t}function so(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&("input"===t&&("text"===e.type||"search"===e.type||"tel"===e.type||"url"===e.type||"password"===e.type)||"textarea"===t||"true"===e.contentEditable)}var co=ie&&"documentMode"in document&&11>=document.documentMode,fo=null,po=null,ho=null,mo=!1;function vo(e,t,n){var r=n.window===n?n.document:9===n.nodeType?n:n.ownerDocument;mo||null==fo||fo!==Ke(r)||("selectionStart"in(r=fo)&&so(r)?r={start:r.selectionStart,end:r.selectionEnd}:r={anchorNode:(r=(r.ownerDocument&&r.ownerDocument.defaultView||window).getSelection()).anchorNode,anchorOffset:r.anchorOffset,focusNode:r.focusNode,focusOffset:r.focusOffset},ho&&oo(ho,r)||(ho=r,0<(r=Ao(po,"onSelect")).length&&(t=new ur("onSelect","select",null,t,n),e.push({event:t,listeners:r}),t.target=fo)))}Ln("cancel cancel click click close close contextmenu contextMenu copy copy cut cut auxclick auxClick dblclick doubleClick dragend dragEnd dragstart dragStart drop drop focusin focus focusout blur input input invalid invalid keydown keyDown keypress keyPress keyup keyUp mousedown mouseDown mouseup mouseUp paste paste pause pause play play pointercancel pointerCancel pointerdown pointerDown pointerup pointerUp ratechange rateChange reset reset seeked seeked submit submit touchcancel touchCancel touchend touchEnd touchstart touchStart volumechange volumeChange".split(" "),0),Ln("drag drag dragenter dragEnter dragexit dragExit dragleave dragLeave dragover dragOver mousemove mouseMove mouseout mouseOut mouseover mouseOver pointermove pointerMove pointerout pointerOut pointerover pointerOver scroll scroll toggle toggle touchmove touchMove wheel wheel".split(" "),1),Ln(An,2);for(var yo="change selectionchange textInput compositionstart compositionend compositionupdate".split(" "),go=0;gota||(e.current=ea[ta],ea[ta]=null,ta--)}function oa(e,t){ta++,ea[ta]=e.current,e.current=t}var aa={},ia=na(aa),la=na(!1),ua=aa;function sa(e,t){var n=e.type.contextTypes;if(!n)return aa;var r=e.stateNode;if(r&&r.__reactInternalMemoizedUnmaskedChildContext===t)return r.__reactInternalMemoizedMaskedChildContext;var o,a={};for(o in n)a[o]=t[o];return r&&((e=e.stateNode).__reactInternalMemoizedUnmaskedChildContext=t,e.__reactInternalMemoizedMaskedChildContext=a),a}function ca(e){return null!=(e=e.childContextTypes)}function fa(){ra(la),ra(ia)}function da(e,t,n){if(ia.current!==aa)throw Error(te(168));oa(ia,t),oa(la,n)}function pa(e,t,n){var r=e.stateNode;if(e=t.childContextTypes,"function"!=typeof r.getChildContext)return n;for(var o in r=r.getChildContext())if(!(o in e))throw Error(te(108,je(t)||"Unknown",o));return J({},n,r)}function ha(e){return e=(e=e.stateNode)&&e.__reactInternalMemoizedMergedChildContext||aa,ua=ia.current,oa(ia,e),oa(la,la.current),!0}function ma(e,t,n){var r=e.stateNode;if(!r)throw Error(te(169));n?(e=pa(e,t,ua),r.__reactInternalMemoizedMergedChildContext=e,ra(la),ra(ia),oa(ia,e)):ra(la),oa(la,n)}var va=null,ya=null,ga=ee.unstable_runWithPriority,ba=ee.unstable_scheduleCallback,wa=ee.unstable_cancelCallback,Sa=ee.unstable_shouldYield,_a=ee.unstable_requestPaint,ka=ee.unstable_now,Ea=ee.unstable_getCurrentPriorityLevel,Ta=ee.unstable_ImmediatePriority,Ca=ee.unstable_UserBlockingPriority,xa=ee.unstable_NormalPriority,Ra=ee.unstable_LowPriority,Na=ee.unstable_IdlePriority,Aa={},La=void 0!==_a?_a:function(){},Pa=null,Ma=null,Oa=!1,Va=ka(),za=1e4>Va?ka:function(){return ka()-Va};function Ia(){switch(Ea()){case Ta:return 99;case Ca:return 98;case xa:return 97;case Ra:return 96;case Na:return 95;default:throw Error(te(332))}}function Da(e){switch(e){case 99:return Ta;case 98:return Ca;case 97:return xa;case 96:return Ra;case 95:return Na;default:throw Error(te(332))}}function Ua(e,t){return e=Da(e),ga(e,t)}function Fa(e,t,n){return e=Da(e),ba(e,t,n)}function Ba(){if(null!==Ma){var e=Ma;Ma=null,wa(e)}ja()}function ja(){if(!Oa&&null!==Pa){Oa=!0;var e=0;try{var t=Pa;Ua(99,(function(){for(;em?(v=h,h=null):v=h.sibling;var y=d(o,h,l[m],u);if(null===y){null===h&&(h=v);break}e&&h&&null===y.alternate&&t(o,h),i=a(y,i,m),null===c?s=y:c.sibling=y,c=y,h=v}if(m===l.length)return n(o,h),s;if(null===h){for(;mm?(v=h,h=null):v=h.sibling;var g=d(o,h,y.value,u);if(null===g){null===h&&(h=v);break}e&&h&&null===g.alternate&&t(o,h),i=a(g,i,m),null===c?s=g:c.sibling=g,c=g,h=v}if(y.done)return n(o,h),s;if(null===h){for(;!y.done;m++,y=l.next())null!==(y=f(o,y.value,u))&&(i=a(y,i,m),null===c?s=y:c.sibling=y,c=y);return s}for(h=r(o,h);!y.done;m++,y=l.next())null!==(y=p(h,o,m,y.value,u))&&(e&&null!==y.alternate&&h.delete(null===y.key?m:y.key),i=a(y,i,m),null===c?s=y:c.sibling=y,c=y);return e&&h.forEach((function(e){return t(o,e)})),s}(l,u,s,c);if(m&&yi(l,s),void 0===s&&!h)switch(l.tag){case 1:case 22:case 0:case 11:case 15:throw Error(te(152,je(l.type)||"Component"))}return n(l,u)}}var bi=gi(!0),wi=gi(!1),Si={},_i=na(Si),ki=na(Si),Ei=na(Si);function Ti(e){if(e===Si)throw Error(te(174));return e}function Ci(e,t){switch(oa(Ei,t),oa(ki,e),oa(_i,Si),e=t.nodeType){case 9:case 11:t=(t=t.documentElement)?t.namespaceURI:st(null,"");break;default:t=st(t=(e=8===e?t.parentNode:t).namespaceURI||null,e=e.tagName)}ra(_i),oa(_i,t)}function xi(){ra(_i),ra(ki),ra(Ei)}function Ri(e){Ti(Ei.current);var t=Ti(_i.current),n=st(t,e.type);t!==n&&(oa(ki,e),oa(_i,n))}function Ni(e){ki.current===e&&(ra(_i),ra(ki))}var Ai=na(0);function Li(e){for(var t=e;null!==t;){if(13===t.tag){var n=t.memoizedState;if(null!==n&&(null===(n=n.dehydrated)||"$?"===n.data||"$!"===n.data))return t}else if(19===t.tag&&void 0!==t.memoizedProps.revealOrder){if(0!=(64&t.flags))return t}else if(null!==t.child){t.child.return=t,t=t.child;continue}if(t===e)break;for(;null===t.sibling;){if(null===t.return||t.return===e)return null;t=t.return}t.sibling.return=t.return,t=t.sibling}return null}var Pi=null,Mi=null,Oi=!1;function Vi(e,t){var n=zs(5,null,null,0);n.elementType="DELETED",n.type="DELETED",n.stateNode=t,n.return=e,n.flags=8,null!==e.lastEffect?(e.lastEffect.nextEffect=n,e.lastEffect=n):e.firstEffect=e.lastEffect=n}function zi(e,t){switch(e.tag){case 5:var n=e.type;return null!==(t=1!==t.nodeType||n.toLowerCase()!==t.nodeName.toLowerCase()?null:t)&&(e.stateNode=t,!0);case 6:return null!==(t=""===e.pendingProps||3!==t.nodeType?null:t)&&(e.stateNode=t,!0);case 13:default:return!1}}function Ii(e){if(Oi){var t=Mi;if(t){var n=t;if(!zi(e,t)){if(!(t=Bo(n.nextSibling))||!zi(e,t))return e.flags=-1025&e.flags|2,Oi=!1,void(Pi=e);Vi(Pi,n)}Pi=e,Mi=Bo(t.firstChild)}else e.flags=-1025&e.flags|2,Oi=!1,Pi=e}}function Di(e){for(e=e.return;null!==e&&5!==e.tag&&3!==e.tag&&13!==e.tag;)e=e.return;Pi=e}function Ui(e){if(e!==Pi)return!1;if(!Oi)return Di(e),Oi=!0,!1;var t=e.type;if(5!==e.tag||"head"!==t&&"body"!==t&&!Io(t,e.memoizedProps))for(t=Mi;t;)Vi(e,t),t=Bo(t.nextSibling);if(Di(e),13===e.tag){if(!(e=null!==(e=e.memoizedState)?e.dehydrated:null))throw Error(te(317));e:{for(e=e.nextSibling,t=0;e;){if(8===e.nodeType){var n=e.data;if("/$"===n){if(0===t){Mi=Bo(e.nextSibling);break e}t--}else"$"!==n&&"$!"!==n&&"$?"!==n||t++}e=e.nextSibling}Mi=null}}else Mi=Pi?Bo(e.stateNode.nextSibling):null;return!0}function Fi(){Mi=Pi=null,Oi=!1}var Bi=[];function ji(){for(var e=0;ea))throw Error(te(301));a+=1,Qi=Ki=null,t.updateQueue=null,$i.current=xl,e=n(r,o)}while(Yi)}if($i.current=El,t=null!==Ki&&null!==Ki.next,Wi=0,Qi=Ki=qi=null,Gi=!1,t)throw Error(te(300));return e}function el(){var e={memoizedState:null,baseState:null,baseQueue:null,queue:null,next:null};return null===Qi?qi.memoizedState=Qi=e:Qi=Qi.next=e,Qi}function tl(){if(null===Ki){var e=qi.alternate;e=null!==e?e.memoizedState:null}else e=Ki.next;var t=null===Qi?qi.memoizedState:Qi.next;if(null!==t)Qi=t,Ki=e;else{if(null===e)throw Error(te(310));e={memoizedState:(Ki=e).memoizedState,baseState:Ki.baseState,baseQueue:Ki.baseQueue,queue:Ki.queue,next:null},null===Qi?qi.memoizedState=Qi=e:Qi=Qi.next=e}return Qi}function nl(e,t){return"function"==typeof t?t(e):t}function rl(e){var t=tl(),n=t.queue;if(null===n)throw Error(te(311));n.lastRenderedReducer=e;var r=Ki,o=r.baseQueue,a=n.pending;if(null!==a){if(null!==o){var i=o.next;o.next=a.next,a.next=i}r.baseQueue=o=a,n.pending=null}if(null!==o){o=o.next,r=r.baseState;var l=i=a=null,u=o;do{var s=u.lane;if((Wi&s)===s)null!==l&&(l=l.next={lane:0,action:u.action,eagerReducer:u.eagerReducer,eagerState:u.eagerState,next:null}),r=u.eagerReducer===e?u.eagerState:e(r,u.action);else{var c={lane:s,action:u.action,eagerReducer:u.eagerReducer,eagerState:u.eagerState,next:null};null===l?(i=l=c,a=r):l=l.next=c,qi.lanes|=s,Mu|=s}u=u.next}while(null!==u&&u!==o);null===l?a=r:l.next=i,no(r,t.memoizedState)||(Nl=!0),t.memoizedState=r,t.baseState=a,t.baseQueue=l,n.lastRenderedState=r}return[t.memoizedState,n.dispatch]}function ol(e){var t=tl(),n=t.queue;if(null===n)throw Error(te(311));n.lastRenderedReducer=e;var r=n.dispatch,o=n.pending,a=t.memoizedState;if(null!==o){n.pending=null;var i=o=o.next;do{a=e(a,i.action),i=i.next}while(i!==o);no(a,t.memoizedState)||(Nl=!0),t.memoizedState=a,null===t.baseQueue&&(t.baseState=a),n.lastRenderedState=a}return[a,r]}function al(e,t,n){var r=t._getVersion;r=r(t._source);var o=t._workInProgressVersionPrimary;if(null!==o?e=o===r:(e=e.mutableReadLanes,(e=(Wi&e)===e)&&(t._workInProgressVersionPrimary=r,Bi.push(t))),e)return n(t._source);throw Bi.push(t),Error(te(350))}function il(e,t,n,r){var o=Tu;if(null===o)throw Error(te(349));var a=t._getVersion,i=a(t._source),l=$i.current,u=l.useState((function(){return al(o,t,n)})),s=u[1],c=u[0];u=Qi;var f=e.memoizedState,d=f.refs,p=d.getSnapshot,h=f.source;f=f.subscribe;var m=qi;return e.memoizedState={refs:d,source:t,subscribe:r},l.useEffect((function(){d.getSnapshot=n,d.setSnapshot=s;var e=a(t._source);if(!no(i,e)){e=n(t._source),no(c,e)||(s(e),e=as(m),o.mutableReadLanes|=e&o.pendingLanes),e=o.mutableReadLanes,o.entangledLanes|=e;for(var r=o.entanglements,l=e;0n?98:n,(function(){e(!0)})),Ua(97<\/script>",e=e.removeChild(e.firstChild)):"string"==typeof r.is?e=i.createElement(n,{is:r.is}):(e=i.createElement(n),"select"===n&&(i=e,r.multiple?i.multiple=!0:r.size&&(i.size=r.size))):e=i.createElementNS(e,n),e[Wo]=t,e[qo]=r,Fl(e,t),t.stateNode=e,i=wt(n,r),n){case"dialog":ko("cancel",e),ko("close",e),o=r;break;case"iframe":case"object":case"embed":ko("load",e),o=r;break;case"video":case"audio":for(o=0;oDu&&(t.flags|=64,a=!0,Xl(r,!1),t.lanes=33554432)}else{if(!a)if(null!==(e=Li(i))){if(t.flags|=64,a=!0,null!==(n=e.updateQueue)&&(t.updateQueue=n,t.flags|=4),Xl(r,!0),null===r.tail&&"hidden"===r.tailMode&&!i.alternate&&!Oi)return null!==(t=t.lastEffect=r.lastEffect)&&(t.nextEffect=null),null}else 2*za()-r.renderingStartTime>Du&&1073741824!==n&&(t.flags|=64,a=!0,Xl(r,!1),t.lanes=33554432);r.isBackwards?(i.sibling=t.child,t.child=i):(null!==(n=r.last)?n.sibling=i:t.child=i,r.last=i)}return null!==r.tail?(n=r.tail,r.rendering=n,r.tail=n.sibling,r.lastEffect=t.lastEffect,r.renderingStartTime=za(),n.sibling=null,t=Ai.current,oa(Ai,a?1&t|2:1&t),n):null;case 23:case 24:return ms(),null!==e&&null!==e.memoizedState!=(null!==t.memoizedState)&&"unstable-defer-without-hiding"!==r.mode&&(t.flags|=4),null}throw Error(te(156,t.tag))}function eu(e){switch(e.tag){case 1:ca(e.type)&&fa();var t=e.flags;return 4096&t?(e.flags=-4097&t|64,e):null;case 3:if(xi(),ra(la),ra(ia),ji(),0!=(64&(t=e.flags)))throw Error(te(285));return e.flags=-4097&t|64,e;case 5:return Ni(e),null;case 13:return ra(Ai),4096&(t=e.flags)?(e.flags=-4097&t|64,e):null;case 19:return ra(Ai),null;case 4:return xi(),null;case 10:return Ya(e),null;case 23:case 24:return ms(),null;default:return null}}function tu(e,t){try{var n="",r=t;do{n+=Be(r),r=r.return}while(r);var o=n}catch(a){o="\nError generating stack: "+a.message+"\n"+a.stack}return{value:e,source:t,stack:o}}function nu(e,t){try{console.error(t.value)}catch(n){setTimeout((function(){throw n}))}}Fl=function(e,t){for(var n=t.child;null!==n;){if(5===n.tag||6===n.tag)e.appendChild(n.stateNode);else if(4!==n.tag&&null!==n.child){n.child.return=n,n=n.child;continue}if(n===t)break;for(;null===n.sibling;){if(null===n.return||n.return===t)return;n=n.return}n.sibling.return=n.return,n=n.sibling}},Bl=function(e,t,n,r){var o=e.memoizedProps;if(o!==r){e=t.stateNode,Ti(_i.current);var a,i=null;switch(n){case"input":o=Qe(e,o),r=Qe(e,r),i=[];break;case"option":o=et(e,o),r=et(e,r),i=[];break;case"select":o=J({},o,{value:void 0}),r=J({},r,{value:void 0}),i=[];break;case"textarea":o=nt(e,o),r=nt(e,r),i=[];break;default:"function"!=typeof o.onClick&&"function"==typeof r.onClick&&(e.onclick=Mo)}for(s in bt(n,r),n=null,o)if(!r.hasOwnProperty(s)&&o.hasOwnProperty(s)&&null!=o[s])if("style"===s){var l=o[s];for(a in l)l.hasOwnProperty(a)&&(n||(n={}),n[a]="")}else"dangerouslySetInnerHTML"!==s&&"children"!==s&&"suppressContentEditableWarning"!==s&&"suppressHydrationWarning"!==s&&"autoFocus"!==s&&(re.hasOwnProperty(s)?i||(i=[]):(i=i||[]).push(s,null));for(s in r){var u=r[s];if(l=null!=o?o[s]:void 0,r.hasOwnProperty(s)&&u!==l&&(null!=u||null!=l))if("style"===s)if(l){for(a in l)!l.hasOwnProperty(a)||u&&u.hasOwnProperty(a)||(n||(n={}),n[a]="");for(a in u)u.hasOwnProperty(a)&&l[a]!==u[a]&&(n||(n={}),n[a]=u[a])}else n||(i||(i=[]),i.push(s,n)),n=u;else"dangerouslySetInnerHTML"===s?(u=u?u.__html:void 0,l=l?l.__html:void 0,null!=u&&l!==u&&(i=i||[]).push(s,u)):"children"===s?"string"!=typeof u&&"number"!=typeof u||(i=i||[]).push(s,""+u):"suppressContentEditableWarning"!==s&&"suppressHydrationWarning"!==s&&(re.hasOwnProperty(s)?(null!=u&&"onScroll"===s&&ko("scroll",e),i||l===u||(i=[])):"object"==typeof u&&null!==u&&u.$$typeof===Ae?u.toString():(i=i||[]).push(s,u))}n&&(i=i||[]).push("style",n);var s=i;(t.updateQueue=s)&&(t.flags|=4)}},jl=function(e,t,n,r){n!==r&&(t.flags|=4)};var ru="function"==typeof WeakMap?WeakMap:Map;function ou(e,t,n){(n=ri(-1,n)).tag=3,n.payload={element:null};var r=t.value;return n.callback=function(){ju||(ju=!0,$u=r),nu(0,t)},n}function au(e,t,n){(n=ri(-1,n)).tag=3;var r=e.type.getDerivedStateFromError;if("function"==typeof r){var o=t.value;n.payload=function(){return nu(0,t),r(o)}}var a=e.stateNode;return null!==a&&"function"==typeof a.componentDidCatch&&(n.callback=function(){"function"!=typeof r&&(null===Hu?Hu=new Set([this]):Hu.add(this),nu(0,t));var e=t.stack;this.componentDidCatch(t.value,{componentStack:null!==e?e:""})}),n}var iu="function"==typeof WeakSet?WeakSet:Set;function lu(e){var t=e.ref;if(null!==t)if("function"==typeof t)try{t(null)}catch(n){Ps(e,n)}else t.current=null}function uu(e,t){switch(t.tag){case 0:case 11:case 15:case 22:return;case 1:if(256&t.flags&&null!==e){var n=e.memoizedProps,r=e.memoizedState;t=(e=t.stateNode).getSnapshotBeforeUpdate(t.elementType===t.type?n:Ha(t.type,n),r),e.__reactInternalSnapshotBeforeUpdate=t}return;case 3:return void(256&t.flags&&Fo(t.stateNode.containerInfo));case 5:case 6:case 4:case 17:return}throw Error(te(163))}function su(e,t,n){switch(n.tag){case 0:case 11:case 15:case 22:if(null!==(t=null!==(t=n.updateQueue)?t.lastEffect:null)){e=t=t.next;do{if(3==(3&e.tag)){var r=e.create;e.destroy=r()}e=e.next}while(e!==t)}if(null!==(t=null!==(t=n.updateQueue)?t.lastEffect:null)){e=t=t.next;do{var o=e;r=o.next,0!=(4&(o=o.tag))&&0!=(1&o)&&(Ns(n,e),Rs(n,e)),e=r}while(e!==t)}return;case 1:return e=n.stateNode,4&n.flags&&(null===t?e.componentDidMount():(r=n.elementType===n.type?t.memoizedProps:Ha(n.type,t.memoizedProps),e.componentDidUpdate(r,t.memoizedState,e.__reactInternalSnapshotBeforeUpdate))),void(null!==(t=n.updateQueue)&&li(n,t,e));case 3:if(null!==(t=n.updateQueue)){if(e=null,null!==n.child)switch(n.child.tag){case 5:e=n.child.stateNode;break;case 1:e=n.child.stateNode}li(n,t,e)}return;case 5:return e=n.stateNode,void(null===t&&4&n.flags&&zo(n.type,n.memoizedProps)&&e.focus());case 6:case 4:case 12:return;case 13:return void(null===n.memoizedState&&(n=n.alternate,null!==n&&(n=n.memoizedState,null!==n&&(n=n.dehydrated,null!==n&&gn(n)))));case 19:case 17:case 20:case 21:case 23:case 24:return}throw Error(te(163))}function cu(e,t){for(var n=e;;){if(5===n.tag){var r=n.stateNode;if(t)"function"==typeof(r=r.style).setProperty?r.setProperty("display","none","important"):r.display="none";else{r=n.stateNode;var o=n.memoizedProps.style;o=null!=o&&o.hasOwnProperty("display")?o.display:null,r.style.display=vt("display",o)}}else if(6===n.tag)n.stateNode.nodeValue=t?"":n.memoizedProps;else if((23!==n.tag&&24!==n.tag||null===n.memoizedState||n===e)&&null!==n.child){n.child.return=n,n=n.child;continue}if(n===e)break;for(;null===n.sibling;){if(null===n.return||n.return===e)return;n=n.return}n.sibling.return=n.return,n=n.sibling}}function fu(e,t){if(ya&&"function"==typeof ya.onCommitFiberUnmount)try{ya.onCommitFiberUnmount(va,t)}catch(a){}switch(t.tag){case 0:case 11:case 14:case 15:case 22:if(null!==(e=t.updateQueue)&&null!==(e=e.lastEffect)){var n=e=e.next;do{var r=n,o=r.destroy;if(r=r.tag,void 0!==o)if(0!=(4&r))Ns(t,n);else{r=t;try{o()}catch(a){Ps(r,a)}}n=n.next}while(n!==e)}break;case 1:if(lu(t),"function"==typeof(e=t.stateNode).componentWillUnmount)try{e.props=t.memoizedProps,e.state=t.memoizedState,e.componentWillUnmount()}catch(a){Ps(t,a)}break;case 5:lu(t);break;case 4:yu(e,t)}}function du(e){e.alternate=null,e.child=null,e.dependencies=null,e.firstEffect=null,e.lastEffect=null,e.memoizedProps=null,e.memoizedState=null,e.pendingProps=null,e.return=null,e.updateQueue=null}function pu(e){return 5===e.tag||3===e.tag||4===e.tag}function hu(e){e:{for(var t=e.return;null!==t;){if(pu(t))break e;t=t.return}throw Error(te(160))}var n=t;switch(t=n.stateNode,n.tag){case 5:var r=!1;break;case 3:case 4:t=t.containerInfo,r=!0;break;default:throw Error(te(161))}16&n.flags&&(pt(t,""),n.flags&=-17);e:t:for(n=e;;){for(;null===n.sibling;){if(null===n.return||pu(n.return)){n=null;break e}n=n.return}for(n.sibling.return=n.return,n=n.sibling;5!==n.tag&&6!==n.tag&&18!==n.tag;){if(2&n.flags)continue t;if(null===n.child||4===n.tag)continue t;n.child.return=n,n=n.child}if(!(2&n.flags)){n=n.stateNode;break e}}r?mu(e,n,t):vu(e,n,t)}function mu(e,t,n){var r=e.tag,o=5===r||6===r;if(o)e=o?e.stateNode:e.stateNode.instance,t?8===n.nodeType?n.parentNode.insertBefore(e,t):n.insertBefore(e,t):(8===n.nodeType?(t=n.parentNode).insertBefore(e,n):(t=n).appendChild(e),null!=(n=n._reactRootContainer)||null!==t.onclick||(t.onclick=Mo));else if(4!==r&&null!==(e=e.child))for(mu(e,t,n),e=e.sibling;null!==e;)mu(e,t,n),e=e.sibling}function vu(e,t,n){var r=e.tag,o=5===r||6===r;if(o)e=o?e.stateNode:e.stateNode.instance,t?n.insertBefore(e,t):n.appendChild(e);else if(4!==r&&null!==(e=e.child))for(vu(e,t,n),e=e.sibling;null!==e;)vu(e,t,n),e=e.sibling}function yu(e,t){for(var n,r,o=t,a=!1;;){if(!a){a=o.return;e:for(;;){if(null===a)throw Error(te(160));switch(n=a.stateNode,a.tag){case 5:r=!1;break e;case 3:case 4:n=n.containerInfo,r=!0;break e}a=a.return}a=!0}if(5===o.tag||6===o.tag){e:for(var i=e,l=o,u=l;;)if(fu(i,u),null!==u.child&&4!==u.tag)u.child.return=u,u=u.child;else{if(u===l)break e;for(;null===u.sibling;){if(null===u.return||u.return===l)break e;u=u.return}u.sibling.return=u.return,u=u.sibling}r?(i=n,l=o.stateNode,8===i.nodeType?i.parentNode.removeChild(l):i.removeChild(l)):n.removeChild(o.stateNode)}else if(4===o.tag){if(null!==o.child){n=o.stateNode.containerInfo,r=!0,o.child.return=o,o=o.child;continue}}else if(fu(e,o),null!==o.child){o.child.return=o,o=o.child;continue}if(o===t)break;for(;null===o.sibling;){if(null===o.return||o.return===t)return;4===(o=o.return).tag&&(a=!1)}o.sibling.return=o.return,o=o.sibling}}function gu(e,t){switch(t.tag){case 0:case 11:case 14:case 15:case 22:var n=t.updateQueue;if(null!==(n=null!==n?n.lastEffect:null)){var r=n=n.next;do{3==(3&r.tag)&&(e=r.destroy,r.destroy=void 0,void 0!==e&&e()),r=r.next}while(r!==n)}return;case 1:return;case 5:if(null!=(n=t.stateNode)){r=t.memoizedProps;var o=null!==e?e.memoizedProps:r;e=t.type;var a=t.updateQueue;if(t.updateQueue=null,null!==a){for(n[qo]=r,"input"===e&&"radio"===r.type&&null!=r.name&&Ye(n,r),wt(e,o),t=wt(e,r),o=0;oo&&(o=i),n&=~a}if(n=o,10<(n=(120>(n=za()-n)?120:480>n?480:1080>n?1080:1920>n?1920:3e3>n?3e3:4320>n?4320:1960*Su(n/1960))-n)){e.timeoutHandle=Do(Es.bind(null,e),n);break}Es(e);break;case 5:Es(e);break;default:throw Error(te(329))}}return us(e,za()),e.callbackNode===t?ss.bind(null,e):null}function cs(e,t){for(t&=~Vu,t&=~Ou,e.suspendedLanes|=t,e.pingedLanes&=~t,e=e.expirationTimes;0 component higher in the tree to provide a loading indicator or placeholder to display.")}5!==Au&&(Au=2),u=tu(u,l),d=i;do{switch(d.tag){case 3:a=u,d.flags|=4096,t&=-t,d.lanes|=t,ai(d,ou(0,a,t));break e;case 1:a=u;var S=d.type,_=d.stateNode;if(0==(64&d.flags)&&("function"==typeof S.getDerivedStateFromError||null!==_&&"function"==typeof _.componentDidCatch&&(null===Hu||!Hu.has(_)))){d.flags|=4096,t&=-t,d.lanes|=t,ai(d,au(d,a,t));break e}}d=d.return}while(null!==d)}ks(n)}catch(k){t=k,Cu===n&&null!==n&&(Cu=n=n.return);continue}break}}function gs(){var e=_u.current;return _u.current=El,null===e?El:e}function bs(e,t){var n=Eu;Eu|=16;var r=gs();for(Tu===e&&xu===t||vs(e,t);;)try{ws();break}catch(o){ys(e,o)}if(Ga(),Eu=n,_u.current=r,null!==Cu)throw Error(te(261));return Tu=null,xu=0,Au}function ws(){for(;null!==Cu;)_s(Cu)}function Ss(){for(;null!==Cu&&!Sa();)_s(Cu)}function _s(e){var t=Fu(e.alternate,e,Ru);e.memoizedProps=e.pendingProps,null===t?ks(e):Cu=t,ku.current=null}function ks(e){var t=e;do{var n=t.alternate;if(e=t.return,0==(2048&t.flags)){if(null!==(n=Jl(n,t,Ru)))return void(Cu=n);if(24!==(n=t).tag&&23!==n.tag||null===n.memoizedState||0!=(1073741824&Ru)||0==(4&n.mode)){for(var r=0,o=n.child;null!==o;)r|=o.lanes|o.childLanes,o=o.sibling;n.childLanes=r}null!==e&&0==(2048&e.flags)&&(null===e.firstEffect&&(e.firstEffect=t.firstEffect),null!==t.lastEffect&&(null!==e.lastEffect&&(e.lastEffect.nextEffect=t.firstEffect),e.lastEffect=t.lastEffect),1i&&(l=i,i=S,S=l),l=io(g,S),a=io(g,i),l&&a&&(1!==w.rangeCount||w.anchorNode!==l.node||w.anchorOffset!==l.offset||w.focusNode!==a.node||w.focusOffset!==a.offset)&&((b=b.createRange()).setStart(l.node,l.offset),w.removeAllRanges(),S>i?(w.addRange(b),w.extend(a.node,a.offset)):(b.setEnd(a.node,a.offset),w.addRange(b))))),b=[];for(w=g;w=w.parentNode;)1===w.nodeType&&b.push({element:w,left:w.scrollLeft,top:w.scrollTop});for("function"==typeof g.focus&&g.focus(),g=0;gza()-Iu?vs(e,0):Vu|=n),us(e,t)}function Os(e,t){var n=e.stateNode;null!==n&&n.delete(t),0===(t=0)&&(0==(2&(t=e.mode))?t=1:0==(4&t)?t=99===Ia()?1:2:(0===es&&(es=Pu),0===(t=In(62914560&~es))&&(t=4194304))),n=os(),null!==(e=ls(e,t))&&(Un(e,t,n),us(e,n))}function Vs(e,t,n,r){this.tag=e,this.key=n,this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null,this.index=0,this.ref=null,this.pendingProps=t,this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=r,this.flags=0,this.lastEffect=this.firstEffect=this.nextEffect=null,this.childLanes=this.lanes=0,this.alternate=null}function zs(e,t,n,r){return new Vs(e,t,n,r)}function Is(e){return!(!(e=e.prototype)||!e.isReactComponent)}function Ds(e,t){var n=e.alternate;return null===n?((n=zs(e.tag,t,e.key,e.mode)).elementType=e.elementType,n.type=e.type,n.stateNode=e.stateNode,n.alternate=e,e.alternate=n):(n.pendingProps=t,n.type=e.type,n.flags=0,n.nextEffect=null,n.firstEffect=null,n.lastEffect=null),n.childLanes=e.childLanes,n.lanes=e.lanes,n.child=e.child,n.memoizedProps=e.memoizedProps,n.memoizedState=e.memoizedState,n.updateQueue=e.updateQueue,t=e.dependencies,n.dependencies=null===t?null:{lanes:t.lanes,firstContext:t.firstContext},n.sibling=e.sibling,n.index=e.index,n.ref=e.ref,n}function Us(e,t,n,r,o,a){var i=2;if(r=e,"function"==typeof e)Is(e)&&(i=1);else if("string"==typeof e)i=5;else e:switch(e){case be:return Fs(n.children,o,a,t);case Le:i=8,o|=16;break;case we:i=8,o|=1;break;case Se:return(e=zs(12,n,t,8|o)).elementType=Se,e.type=Se,e.lanes=a,e;case Te:return(e=zs(13,n,t,o)).type=Te,e.elementType=Te,e.lanes=a,e;case Ce:return(e=zs(19,n,t,o)).elementType=Ce,e.lanes=a,e;case Pe:return Bs(n,o,a,t);case Me:return(e=zs(24,n,t,o)).elementType=Me,e.lanes=a,e;default:if("object"==typeof e&&null!==e)switch(e.$$typeof){case _e:i=10;break e;case ke:i=9;break e;case Ee:i=11;break e;case xe:i=14;break e;case Re:i=16,r=null;break e;case Ne:i=22;break e}throw Error(te(130,null==e?e:typeof e,""))}return(t=zs(i,n,t,o)).elementType=e,t.type=r,t.lanes=a,t}function Fs(e,t,n,r){return(e=zs(7,e,r,t)).lanes=n,e}function Bs(e,t,n,r){return(e=zs(23,e,r,t)).elementType=Pe,e.lanes=n,e}function js(e,t,n){return(e=zs(6,e,null,t)).lanes=n,e}function $s(e,t,n){return(t=zs(4,null!==e.children?e.children:[],e.key,t)).lanes=n,t.stateNode={containerInfo:e.containerInfo,pendingChildren:null,implementation:e.implementation},t}function Hs(e,t,n){this.tag=t,this.containerInfo=e,this.finishedWork=this.pingCache=this.current=this.pendingChildren=null,this.timeoutHandle=-1,this.pendingContext=this.context=null,this.hydrate=n,this.callbackNode=null,this.callbackPriority=0,this.eventTimes=Dn(0),this.expirationTimes=Dn(-1),this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0,this.entanglements=Dn(0),this.mutableSourceEagerHydrationData=null}function Ws(e,t,n){var r=3=0||(o[n]=e[n]);return o}var wc={BASE:"base",BODY:"body",HEAD:"head",HTML:"html",LINK:"link",META:"meta",NOSCRIPT:"noscript",SCRIPT:"script",STYLE:"style",TITLE:"title",FRAGMENT:"Symbol(react.fragment)"},Sc={rel:["amphtml","canonical","alternate"]},_c={type:["application/ld+json"]},kc={charset:"",name:["robots","description"],property:["og:type","og:title","og:url","og:image","og:image:alt","og:description","twitter:url","twitter:title","twitter:description","twitter:image","twitter:image:alt","twitter:card","twitter:site"]},Ec=Object.keys(wc).map((function(e){return wc[e]})),Tc={accesskey:"accessKey",charset:"charSet",class:"className",contenteditable:"contentEditable",contextmenu:"contextMenu","http-equiv":"httpEquiv",itemprop:"itemProp",tabindex:"tabIndex"},Cc=Object.keys(Tc).reduce((function(e,t){return e[Tc[t]]=t,e}),{}),xc=function(e,t){for(var n=e.length-1;n>=0;n-=1){var r=e[n];if(Object.prototype.hasOwnProperty.call(r,t))return r[t]}return null},Rc=function(e){var t=xc(e,wc.TITLE),n=xc(e,"titleTemplate");if(Array.isArray(t)&&(t=t.join("")),n&&t)return n.replace(/%s/g,(function(){return t}));var r=xc(e,"defaultTitle");return t||r||void 0},Nc=function(e){return xc(e,"onChangeClientState")||function(){}},Ac=function(e,t){return t.filter((function(t){return void 0!==t[e]})).map((function(t){return t[e]})).reduce((function(e,t){return vc({},e,t)}),{})},Lc=function(e,t){return t.filter((function(e){return void 0!==e[wc.BASE]})).map((function(e){return e[wc.BASE]})).reverse().reduce((function(t,n){if(!t.length)for(var r=Object.keys(n),o=0;o /g,">").replace(/"/g,""").replace(/'/g,"'")},Dc=function(e){return Object.keys(e).reduce((function(t,n){var r=void 0!==e[n]?n+'="'+e[n]+'"':""+n;return t?t+" "+r:r}),"")},Uc=function(e,t){return void 0===t&&(t={}),Object.keys(e).reduce((function(t,n){return t[Tc[n]||n]=e[n],t}),t)},Fc=function(e,t){return t.map((function(t,n){var r,o=((r={key:n})["data-rh"]=!0,r);return Object.keys(t).forEach((function(e){var n=Tc[e]||e;"innerHTML"===n||"cssText"===n?o.dangerouslySetInnerHTML={__html:t.innerHTML||t.cssText}:o[n]=t[e]})),K.createElement(e,o)}))},Bc=function(e,t,n){switch(e){case wc.TITLE:return{toComponent:function(){return n=t.titleAttributes,(r={key:e=t.title})["data-rh"]=!0,o=Uc(n,r),[K.createElement(wc.TITLE,o,e)];var e,n,r,o},toString:function(){return r=e,o=t.title,a=t.titleAttributes,i=n,l=Dc(a),u=Oc(o),l?"<"+r+' data-rh="true" '+l+">"+Ic(u,i)+""+r+">":"<"+r+' data-rh="true">'+Ic(u,i)+""+r+">";var r,o,a,i,l,u}};case"bodyAttributes":case"htmlAttributes":return{toComponent:function(){return Uc(t)},toString:function(){return Dc(t)}};default:return{toComponent:function(){return Fc(e,t)},toString:function(){return r=e,o=n,t.reduce((function(e,t){var n=Object.keys(t).filter((function(e){return!("innerHTML"===e||"cssText"===e)})).reduce((function(e,n){var r=void 0===t[n]?n:n+'="'+Ic(t[n],o)+'"';return e?e+" "+r:r}),""),a=t.innerHTML||t.cssText||"",i=-1===zc.indexOf(r);return e+"<"+r+' data-rh="true" '+n+(i?"/>":">"+a+""+r+">")}),"");var r,o}}}},jc=function(e){var t,n,r,o,a,i,l,u=e.baseTag,s=e.bodyAttributes,c=e.encode,f=e.htmlAttributes,d=e.noscriptTags,p=e.styleTags,h=e.title,m=void 0===h?"":h,v=e.titleAttributes,y=e.linkTags,g=e.metaTags,b=e.scriptTags,w={toComponent:function(){},toString:function(){return""}};if(e.prioritizeSeoTags){var S=(n=(t=e).linkTags,r=t.scriptTags,o=t.encode,a=Vc(t.metaTags,kc),i=Vc(n,Sc),l=Vc(r,_c),{priorityMethods:{toComponent:function(){return[].concat(Fc(wc.META,a.priority),Fc(wc.LINK,i.priority),Fc(wc.SCRIPT,l.priority))},toString:function(){return Bc(wc.META,a.priority,o)+" "+Bc(wc.LINK,i.priority,o)+" "+Bc(wc.SCRIPT,l.priority,o)}},metaTags:a.default,linkTags:i.default,scriptTags:l.default});w=S.priorityMethods,y=S.linkTags,g=S.metaTags,b=S.scriptTags}return{priority:w,base:Bc(wc.BASE,u,c),bodyAttributes:Bc("bodyAttributes",s,c),htmlAttributes:Bc("htmlAttributes",f,c),link:Bc(wc.LINK,y,c),meta:Bc(wc.META,g,c),noscript:Bc(wc.NOSCRIPT,d,c),script:Bc(wc.SCRIPT,b,c),style:Bc(wc.STYLE,p,c),title:Bc(wc.TITLE,{title:m,titleAttributes:v},c)}},$c=K.createContext({}),Hc=uc.shape({setHelmet:uc.func,helmetInstances:uc.shape({get:uc.func,add:uc.func,remove:uc.func})}),Wc="undefined"!=typeof document,qc=function(e){function t(n){var r;return(r=e.call(this,n)||this).instances=[],r.value={setHelmet:function(e){r.props.context.helmet=e},helmetInstances:{get:function(){return r.instances},add:function(e){r.instances.push(e)},remove:function(e){var t=r.instances.indexOf(e);r.instances.splice(t,1)}}},t.canUseDOM||(n.context.helmet=jc({baseTag:[],bodyAttributes:{},encodeSpecialCharacters:!0,htmlAttributes:{},linkTags:[],metaTags:[],noscriptTags:[],scriptTags:[],styleTags:[],title:"",titleAttributes:{}})),r}return yc(t,e),t.prototype.render=function(){return K.createElement($c.Provider,{value:this.value},this.props.children)},t}(c.exports.Component);qc.canUseDOM=Wc,qc.propTypes={context:uc.shape({helmet:uc.shape()}),children:uc.node.isRequired},qc.defaultProps={context:{}},qc.displayName="HelmetProvider";var Kc=function(e,t){var n,r=document.head||document.querySelector(wc.HEAD),o=r.querySelectorAll(e+"[data-rh]"),a=[].slice.call(o),i=[];return t&&t.length&&t.forEach((function(t){var r=document.createElement(e);for(var o in t)Object.prototype.hasOwnProperty.call(t,o)&&("innerHTML"===o?r.innerHTML=t.innerHTML:"cssText"===o?r.styleSheet?r.styleSheet.cssText=t.cssText:r.appendChild(document.createTextNode(t.cssText)):r.setAttribute(o,void 0===t[o]?"":t[o]));r.setAttribute("data-rh","true"),a.some((function(e,t){return n=t,r.isEqualNode(e)}))?a.splice(n,1):i.push(r)})),a.forEach((function(e){return e.parentNode.removeChild(e)})),i.forEach((function(e){return r.appendChild(e)})),{oldTags:a,newTags:i}},Qc=function(e,t){var n=document.getElementsByTagName(e)[0];if(n){for(var r=n.getAttribute("data-rh"),o=r?r.split(","):[],a=[].concat(o),i=Object.keys(t),l=0;l=0;f-=1)n.removeAttribute(a[f]);o.length===a.length?n.removeAttribute("data-rh"):n.getAttribute("data-rh")!==i.join(",")&&n.setAttribute("data-rh",i.join(","))}},Gc=function(e,t){var n,r,o=e.baseTag,a=e.htmlAttributes,i=e.linkTags,l=e.metaTags,u=e.noscriptTags,s=e.onChangeClientState,c=e.scriptTags,f=e.styleTags,d=e.title,p=e.titleAttributes;Qc(wc.BODY,e.bodyAttributes),Qc(wc.HTML,a),r=p,void 0!==(n=d)&&document.title!==n&&(document.title=Oc(n)),Qc(wc.TITLE,r);var h={baseTag:Kc(wc.BASE,o),linkTags:Kc(wc.LINK,i),metaTags:Kc(wc.META,l),noscriptTags:Kc(wc.NOSCRIPT,u),scriptTags:Kc(wc.SCRIPT,c),styleTags:Kc(wc.STYLE,f)},m={},v={};Object.keys(h).forEach((function(e){var t=h[e],n=t.newTags,r=t.oldTags;n.length&&(m[e]=n),r.length&&(v[e]=h[e].oldTags)})),t&&t(),s(e,m,v)},Yc=null,Zc=function(e){function t(){for(var t,n=arguments.length,r=new Array(n),o=0;o elements are self-closing and can not contain children. Refer to our API for more information.")}},n.flattenArrayTypeChildren=function(e){var t,n=e.child,r=e.arrayTypeChildren;return vc({},r,((t={})[n.type]=[].concat(r[n.type]||[],[vc({},e.newChildProps,this.mapNestedChildrenToProps(n,e.nestedChildren))]),t))},n.mapObjectTypeChildren=function(e){var t,n,r=e.child,o=e.newProps,a=e.newChildProps,i=e.nestedChildren;switch(r.type){case wc.TITLE:return vc({},o,((t={})[r.type]=i,t.titleAttributes=vc({},a),t));case wc.BODY:return vc({},o,{bodyAttributes:vc({},a)});case wc.HTML:return vc({},o,{htmlAttributes:vc({},a)});default:return vc({},o,((n={})[r.type]=vc({},a),n))}},n.mapArrayTypeChildrenToProps=function(e,t){var n=vc({},t);return Object.keys(e).forEach((function(t){var r;n=vc({},n,((r={})[t]=e[t],r))})),n},n.warnOnInvalidChildren=function(e,t){return mc(Ec.some((function(t){return e.type===t})),"function"==typeof e.type?"You may be attempting to nest components within each other, which is not allowed. Refer to our API for more information.":"Only elements types "+Ec.join(", ")+" are allowed. Helmet does not support rendering <"+e.type+"> elements. Refer to our API for more information."),mc(!t||"string"==typeof t||Array.isArray(t)&&!t.some((function(e){return"string"!=typeof e})),"Helmet expects a string as a child of <"+e.type+">. Did you forget to wrap your children in braces? ( <"+e.type+">{``}"+e.type+"> ) Refer to our API for more information."),!0},n.mapChildrenToProps=function(e,t){var n=this,r={};return K.Children.forEach(e,(function(e){if(e&&e.props){var o=e.props,a=o.children,i=bc(o,Xc),l=Object.keys(i).reduce((function(e,t){return e[Cc[t]||t]=i[t],e}),{}),u=e.type;switch("symbol"==typeof u?u=u.toString():n.warnOnInvalidChildren(e,a),u){case wc.FRAGMENT:t=n.mapChildrenToProps(a,t);break;case wc.LINK:case wc.META:case wc.NOSCRIPT:case wc.SCRIPT:case wc.STYLE:r=n.flattenArrayTypeChildren({child:e,arrayTypeChildren:r,newChildProps:l,nestedChildren:a});break;default:t=n.mapObjectTypeChildren({child:e,newProps:t,newChildProps:l,nestedChildren:a})}}})),this.mapArrayTypeChildrenToProps(r,t)},n.render=function(){var e=this.props,t=e.children,n=vc({},bc(e,Jc));return t&&(n=this.mapChildrenToProps(t,n)),K.createElement($c.Consumer,null,(function(e){return K.createElement(Zc,vc({},n,{context:e}))}))},t}(c.exports.Component);function tf(e,t){return(tf=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}function nf(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,tf(e,t)}function rf(){return(rf=Object.assign||function(e){for(var t=1;t=0;c--){var f=o[c];"."===f?af(o,c):".."===f?(af(o,c),s++):s&&(af(o,c),s--)}if(!l)for(;s--;s)o.unshift("..");!l||""===o[0]||o[0]&&of(o[0])||o.unshift("");var d=o.join("/");return n&&"/"!==d.substr(-1)&&(d+="/"),d}(o.pathname,r.pathname)):o.pathname=r.pathname:o.pathname||(o.pathname="/"),o}function hf(){var e=null;var t=[];return{setPrompt:function(t){return e=t,function(){e===t&&(e=null)}},confirmTransitionTo:function(t,n,r,o){if(null!=e){var a="function"==typeof e?e(t,n):e;"string"==typeof a?"function"==typeof r?r(a,o):o(!0):o(!1!==a)}else o(!0)},appendListener:function(e){var n=!0;function r(){n&&e.apply(void 0,arguments)}return t.push(r),function(){n=!1,t=t.filter((function(e){return e!==r}))}},notifyListeners:function(){for(var e=arguments.length,n=new Array(e),r=0;r=0||(o[n]=e[n]);return o}Uf.AsyncMode=Qf,Uf.ConcurrentMode=Gf,Uf.ContextConsumer=Kf,Uf.ContextProvider=qf,Uf.Element=Bf,Uf.ForwardRef=Yf,Uf.Fragment=$f,Uf.Lazy=ed,Uf.Memo=Jf,Uf.Portal=jf,Uf.Profiler=Wf,Uf.StrictMode=Hf,Uf.Suspense=Zf,Uf.isAsyncMode=function(e){return id(e)||ad(e)===Qf},Uf.isConcurrentMode=id,Uf.isContextConsumer=function(e){return ad(e)===Kf},Uf.isContextProvider=function(e){return ad(e)===qf},Uf.isElement=function(e){return"object"==typeof e&&null!==e&&e.$$typeof===Bf},Uf.isForwardRef=function(e){return ad(e)===Yf},Uf.isFragment=function(e){return ad(e)===$f},Uf.isLazy=function(e){return ad(e)===ed},Uf.isMemo=function(e){return ad(e)===Jf},Uf.isPortal=function(e){return ad(e)===jf},Uf.isProfiler=function(e){return ad(e)===Wf},Uf.isStrictMode=function(e){return ad(e)===Hf},Uf.isSuspense=function(e){return ad(e)===Zf},Uf.isValidElementType=function(e){return"string"==typeof e||"function"==typeof e||e===$f||e===Gf||e===Wf||e===Hf||e===Zf||e===Xf||"object"==typeof e&&null!==e&&(e.$$typeof===ed||e.$$typeof===Jf||e.$$typeof===qf||e.$$typeof===Kf||e.$$typeof===Yf||e.$$typeof===nd||e.$$typeof===rd||e.$$typeof===od||e.$$typeof===td)},Uf.typeOf=ad,Df.exports=Uf;var ud=Df.exports,sd={};sd[ud.ForwardRef]={$$typeof:!0,render:!0,defaultProps:!0,displayName:!0,propTypes:!0},sd[ud.Memo]={$$typeof:!0,compare:!0,defaultProps:!0,displayName:!0,propTypes:!0,type:!0};var cd=function(e){var t=Ef();return t.displayName=e,t},fd=cd("Router-History"),dd=cd("Router"),pd=function(e){function t(t){var n;return(n=e.call(this,t)||this).state={location:t.history.location},n._isMounted=!1,n._pendingLocation=null,t.staticContext||(n.unlisten=t.history.listen((function(e){n._isMounted?n.setState({location:e}):n._pendingLocation=e}))),n}nf(t,e),t.computeRootMatch=function(e){return{path:"/",url:"/",params:{},isExact:"/"===e}};var n=t.prototype;return n.componentDidMount=function(){this._isMounted=!0,this._pendingLocation&&this.setState({location:this._pendingLocation})},n.componentWillUnmount=function(){this.unlisten&&(this.unlisten(),this._isMounted=!1,this._pendingLocation=null)},n.render=function(){return K.createElement(dd.Provider,{value:{history:this.props.history,location:this.state.location,match:t.computeRootMatch(this.state.location.pathname),staticContext:this.props.staticContext}},K.createElement(fd.Provider,{children:this.props.children||null,value:this.props.history}))},t}(K.Component);K.Component,K.Component;var hd={},md=0;function vd(e,t){void 0===t&&(t={}),("string"==typeof t||Array.isArray(t))&&(t={path:t});var n=t,r=n.path,o=n.exact,a=void 0!==o&&o,i=n.strict,l=void 0!==i&&i,u=n.sensitive,s=void 0!==u&&u;return[].concat(r).reduce((function(t,n){if(!n&&""!==n)return null;if(t)return t;var r=function(e,t){var n=""+t.end+t.strict+t.sensitive,r=hd[n]||(hd[n]={});if(r[e])return r[e];var o=[],a={regexp:If(e,o,t),keys:o};return md<1e4&&(r[e]=a,md++),a}(n,{end:a,strict:l,sensitive:s}),o=r.regexp,i=r.keys,u=o.exec(e);if(!u)return null;var c=u[0],f=u.slice(1),d=e===c;return a&&!d?null:{path:n,url:"/"===n&&""===c?"/":c,isExact:d,params:i.reduce((function(e,t,n){return e[t.name]=f[n],e}),{})}}),null)}var yd=function(e){function t(){return e.apply(this,arguments)||this}return nf(t,e),t.prototype.render=function(){var e=this;return K.createElement(dd.Consumer,null,(function(t){t||lf(!1);var n=e.props.location||t.location,r=rf({},t,{location:n,match:e.props.computedMatch?e.props.computedMatch:e.props.path?vd(n.pathname,e.props):t.match}),o=e.props,a=o.children,i=o.component,l=o.render;return Array.isArray(a)&&function(e){return 0===K.Children.count(e)}(a)&&(a=null),K.createElement(dd.Provider,{value:r},r.match?a?"function"==typeof a?a(r):a:i?K.createElement(i,r):l?l(r):null:"function"==typeof a?a(r):null)}))},t}(K.Component);K.Component;var gd=function(e){function t(){return e.apply(this,arguments)||this}return nf(t,e),t.prototype.render=function(){var e=this;return K.createElement(dd.Consumer,null,(function(t){t||lf(!1);var n,r,o=e.props.location||t.location;return K.Children.forEach(e.props.children,(function(e){if(null==r&&K.isValidElement(e)){n=e;var a=e.props.path||e.props.from;r=a?vd(o.pathname,rf({},e.props,{path:a})):t.match}})),r?K.cloneElement(n,{location:o,computedMatch:r}):null}))},t}(K.Component),bd=K.useContext;function wd(){return bd(fd)}function Sd(){return bd(dd).location}function _d(){var e=bd(dd).match;return e?e.params:{}}K.Component;var kd=function(e){function t(){for(var t,n=arguments.length,r=new Array(n),o=0;o({__value:e})))):Id(t)}catch(t){return Pd(t)?Ud(t.next((()=>e(this.contents)))):Dd(t)}if("loading"===this.state)return Ud(this.contents.then((t=>({__value:e(t.__value)}))).catch((t=>{if(Pd(t))return t.then((()=>e(this.contents)));throw t})));throw new Error("Invalid Loadable state")}};function Id(e){return Object.freeze(u(l({state:"hasValue",contents:e},zd),{getValue(){return this.contents},toPromise(){return Promise.resolve(this.contents)},valueMaybe(){return this.contents},valueOrThrow(){return this.contents}}))}function Dd(e){return Object.freeze(u(l({state:"hasError",contents:e},zd),{getValue(){throw this.contents},toPromise(){return Promise.reject(this.contents)},errorMaybe(){return this.contents},errorOrThrow(){return this.contents}}))}function Ud(e){return Object.freeze(u(l({state:"loading",contents:e},zd),{getValue(){throw this.contents.then((({__value:e})=>e))},toPromise(){return this.contents.then((({__value:e})=>e))},promiseMaybe(){return this.contents.then((({__value:e})=>e))},promiseOrThrow(){return this.contents.then((({__value:e})=>e))}}))}var Fd,Bd={loadableWithValue:Id,loadableWithError:Dd,loadableWithPromise:Ud,loadableLoading:function(){return Ud(new Promise((()=>{})))},loadableAll:function(e){return e.every((e=>"hasValue"===e.state))?Id(e.map((e=>e.contents))):e.some((e=>"hasError"===e.state))?Dd(Md(e.find((e=>"hasError"===e.state)),"Invalid loadable passed to loadableAll").contents):Ud(Promise.all(e.map((e=>e.contents))).then((e=>({__value:e}))))},Canceled:Od,CANCELED:Vd};const jd=null!==(Fd=K.useMutableSource)&&void 0!==Fd?Fd:K.unstable_useMutableSource;var $d={mutableSourceExists:function(){return jd&&!("undefined"!=typeof window&&window.$disableRecoilValueMutableSource_TEMP_HACK_DO_NOT_USE)},useMutableSource:jd};const{mutableSourceExists:Hd}=$d,Wd=(new Map).set("recoil_hamt_2020",!0).set("recoil_memory_managament_2020",!0).set("recoil_suppress_rerender_in_callback",!0);function qd(e){var t;return!("recoil_early_rendering_2021"===e&&!Hd())&&(null!==(t=Wd.get(e))&&void 0!==t&&t)}qd.setPass=e=>{Wd.set(e,!0)},qd.setFail=e=>{Wd.set(e,!1)};var Kd=qd;var Qd=function(e,t,{error:n}={}){return null};var Gd={setByAddingToSet:function(e,t){const n=new Set(e);return n.add(t),n},setByDeletingFromSet:function(e,t){const n=new Set(e);return n.delete(t),n},mapBySettingInMap:function(e,t,n){const r=new Map(e);return r.set(t,n),r},mapByUpdatingInMap:function(e,t,n){const r=new Map(e);return r.set(t,n(r.get(t))),r},mapByDeletingFromMap:function(e,t){const n=new Map(e);return n.delete(t),n},mapByDeletingMultipleFromMap:function(e,t){const n=new Map(e);return t.forEach((e=>n.delete(e))),n}};var Yd=function*(e,t){let n=0;for(const r of e)t(r,n++)&&(yield r)};var Zd=function(e,t){return function*(){let n=0;for(const r of e)yield t(r,n++)}()};function Xd(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}class Jd{constructor(e){Xd(this,"key",void 0),this.key=e}}class ep extends Jd{}class tp extends Jd{}var np={AbstractRecoilValue:Jd,RecoilState:ep,RecoilValueReadOnly:tp,isRecoilValue:function(e){return e instanceof ep||e instanceof tp}},rp=np.AbstractRecoilValue,op=np.RecoilState,ap=np.RecoilValueReadOnly,ip=np.isRecoilValue,lp=Object.freeze({__proto__:null,AbstractRecoilValue:rp,RecoilState:op,RecoilValueReadOnly:ap,isRecoilValue:ip});class up{}const sp=new up;class cp extends Error{constructor(e){super(`Tried to set the value of Recoil selector ${e} using an updater function, but it is an async selector in a pending or error state; this is not supported.`)}}const fp=new Map,dp=new Map;class pp extends Error{}const hp=new Map;function mp(e){return hp.get(e)}var vp={nodes:fp,recoilValues:dp,registerNode:function(e){if(fp.has(e.key)){const t=`Duplicate atom key "${e.key}". This is a FATAL ERROR in\n production. But it is safe to ignore this warning if it occurred because of\n hot module replacement.`;console.warn(t)}fp.set(e.key,e);const t=null==e.set?new lp.RecoilValueReadOnly(e.key):new lp.RecoilState(e.key);return dp.set(e.key,t),t},getNode:function(e){const t=fp.get(e);if(null==t)throw new pp(`Missing definition for RecoilValue: "${e}""`);return t},getNodeMaybe:function(e){return fp.get(e)},deleteNodeConfigIfPossible:function(e){var t;if(!Kd("recoil_memory_managament_2020"))return;const n=fp.get(e);var r;(null==n||null===(t=n.shouldDeleteConfigOnRelease)||void 0===t?void 0:t.call(n))&&(fp.delete(e),null===(r=mp(e))||void 0===r||r(),hp.delete(e))},setConfigDeletionHandler:function(e,t){Kd("recoil_memory_managament_2020")&&(void 0===t?hp.delete(e):hp.set(e,t))},getConfigDeletionHandler:mp,recoilValuesForKeys:function(e){return Zd(e,(e=>Md(dp.get(e))))},NodeMissingError:pp,DefaultValue:up,DEFAULT_VALUE:sp,RecoilValueNotReady:cp};class yp{}var gp={RetentionZone:yp,retentionZone:function(){return new yp}};const{setByAddingToSet:bp}=Gd,{getNode:wp,getNodeMaybe:Sp,recoilValuesForKeys:_p}=vp,{RetentionZone:kp}=gp,Ep=Object.freeze(new Set);class Tp extends Error{}function Cp(e,t,n,r){const o=e.getState();if(o.nodeCleanupFunctions.has(n))return;const a=wp(n),i=function(e,t,n){if(!Kd("recoil_memory_managament_2020"))return()=>{};const{nodesRetainedByZone:r}=e.getState().retention;function o(e){let n=r.get(e);n||r.set(e,n=new Set),n.add(t)}if(n instanceof kp)o(n);else if(Array.isArray(n))for(const a of n)o(a);return()=>{if(!Kd("recoil_memory_managament_2020"))return;const r=e.getState().retention.nodesRetainedByZone;function o(e){const n=r.get(e);n&&n.delete(t),n&&0===n.size&&r.delete(e)}if(n instanceof kp)o(n);else if(Array.isArray(n))for(const e of n)o(e)}}(e,n,a.retainedBy),l=a.init(e,t,r);o.nodeCleanupFunctions.set(n,(()=>{l(),i()}))}function xp(e,t,n){return wp(n).peek(e,t)}function Rp(e,t,n){const r=new Set,o=Array.from(n),a=e.getGraph(t.version);for(let l=o.pop();l;l=o.pop()){var i;r.add(l);const e=null!==(i=a.nodeToNodeSubscriptions.get(l))&&void 0!==i?i:Ep;for(const t of e)r.has(t)||o.push(t)}return r}var Np={getNodeLoadable:function(e,t,n){return Cp(e,t,n,"get"),wp(n).get(e,t)},peekNodeLoadable:xp,setNodeValue:function(e,t,n,r){const o=wp(n);if(null==o.set)throw new Tp(`Attempt to set read-only RecoilValue: ${n}`);const a=o.set;return Cp(e,t,n,"set"),a(e,t,r)},cleanUpNode:function(e,t){var n;const r=e.getState();null===(n=r.nodeCleanupFunctions.get(t))||void 0===n||n(),r.nodeCleanupFunctions.delete(t)},setUnvalidatedAtomValue_DEPRECATED:function(e,t,n){var r;const o=Sp(t);return null==o||null===(r=o.invalidate)||void 0===r||r.call(o,e),u(l({},e),{atomValues:e.atomValues.clone().delete(t),nonvalidatedAtoms:e.nonvalidatedAtoms.clone().set(t,n),dirtyAtoms:bp(e.dirtyAtoms,t)})},peekNodeInfo:function(e,t,n){var r,o,a;const i=e.getState(),l=e.getGraph(t.version),u=i.knownAtoms.has(n)?"atom":i.knownSelectors.has(n)?"selector":void 0,s=Yd(Rp(e,t,new Set([n])),(e=>e!==n));return{loadable:xp(e,t,n),isActive:i.knownAtoms.has(n)||i.knownSelectors.has(n),isSet:"selector"!==u&&t.atomValues.has(n),isModified:t.dirtyAtoms.has(n),type:u,deps:_p(null!==(r=l.nodeDeps.get(n))&&void 0!==r?r:[]),subscribers:{nodes:_p(s),components:Zd(null!==(o=null===(a=i.nodeToComponentSubscriptions.get(n))||void 0===a?void 0:a.values())&&void 0!==o?o:[],(([e])=>({name:e})))}}},getDownstreamNodes:Rp,initializeNodeIfNewToStore:Cp};const{CANCELED:Ap}=Bd,{getDownstreamNodes:Lp,getNodeLoadable:Pp,setNodeValue:Mp}=Np,{getNodeMaybe:Op}=vp,{DefaultValue:Vp,RecoilValueNotReady:zp}=vp,{AbstractRecoilValue:Ip,RecoilState:Dp,RecoilValueReadOnly:Up,isRecoilValue:Fp}=lp;function Bp(e,t,n){if("set"===n.type){const{recoilValue:r,valueOrUpdater:o}=n,a=function(e,t,{key:n},r){if("function"==typeof r){const o=Pp(e,t,n);if("loading"===o.state)throw new zp(n);if("hasError"===o.state)throw o.contents;return r(o.contents)}return r}(e,t,r,o),i=Mp(e,t,r.key,a);for(const[e,n]of i.entries())jp(t,e,n)}else if("setLoadable"===n.type){const{recoilValue:{key:e},loadable:r}=n;jp(t,e,r)}else if("markModified"===n.type){const{recoilValue:{key:e}}=n;t.dirtyAtoms.add(e)}else if("setUnvalidated"===n.type){var r;const{recoilValue:{key:e},unvalidatedValue:o}=n,a=Op(e);null==a||null===(r=a.invalidate)||void 0===r||r.call(a,t),t.atomValues.delete(e),t.nonvalidatedAtoms.set(e,o),t.dirtyAtoms.add(e)}else Qd(`Unknown action ${n.type}`)}function jp(e,t,n){"hasValue"===n.state&&n.contents instanceof Vp?e.atomValues.delete(t):e.atomValues.set(t,n),e.dirtyAtoms.add(t),e.nonvalidatedAtoms.delete(t)}function $p(e,t){e.replaceState((n=>{const r=qp(n);for(const o of t)Bp(e,r,o);return Kp(e,r),r}))}function Hp(e,t){if(Wp.length){const n=Wp[Wp.length-1];let r=n.get(e);r||n.set(e,r=[]),r.push(t)}else $p(e,[t])}const Wp=[];function qp(e){return u(l({},e),{atomValues:e.atomValues.clone(),nonvalidatedAtoms:e.nonvalidatedAtoms.clone(),dirtyAtoms:new Set(e.dirtyAtoms)})}function Kp(e,t){const n=Lp(e,t,t.dirtyAtoms);for(const a of n){var r,o;null===(r=Op(a))||void 0===r||null===(o=r.invalidate)||void 0===o||o.call(r,t)}}function Qp(e,t,n){Hp(e,{type:"set",recoilValue:t,valueOrUpdater:n})}let Gp=0;var Yp={RecoilValueReadOnly:Up,AbstractRecoilValue:Ip,RecoilState:Dp,getRecoilValueAsLoadable:function(e,{key:t},n=e.getState().currentTree){var r,o;const a=e.getState();n.version!==a.currentTree.version&&n.version!==(null===(r=a.nextTree)||void 0===r?void 0:r.version)&&(n.version,null===(o=a.previousTree)||void 0===o||o.version);const i=Pp(e,n,t);return"loading"===i.state&&i.contents.catch((()=>Ap)),i},setRecoilValue:Qp,setRecoilValueLoadable:function(e,t,n){if(n instanceof Vp)return Qp(e,t,n);Hp(e,{type:"setLoadable",recoilValue:t,loadable:n})},markRecoilValueModified:function(e,t){Hp(e,{type:"markModified",recoilValue:t})},setUnvalidatedRecoilValue:function(e,t,n){Hp(e,{type:"setUnvalidated",recoilValue:t,unvalidatedValue:n})},subscribeToRecoilValue:function(e,{key:t},n,r=null){const o=Gp++,a=e.getState();if(a.nodeToComponentSubscriptions.has(t)||a.nodeToComponentSubscriptions.set(t,new Map),Md(a.nodeToComponentSubscriptions.get(t)).set(o,[null!=r?r:"",n]),Kd("recoil_early_rendering_2021")){const r=e.getState().nextTree;r&&r.dirtyAtoms.has(t)&&n(r)}return{release:()=>{const n=e.getState(),r=n.nodeToComponentSubscriptions.get(t);void 0!==r&&r.has(o)&&(r.delete(o),0===r.size&&n.nodeToComponentSubscriptions.delete(t))}}},isRecoilValue:Fp,applyAtomValueWrites:function(e,t){const n=e.clone();return t.forEach(((e,t)=>{"hasValue"===e.state&&e.contents instanceof Vp?n.delete(t):n.set(t,e)})),n},batchStart:function(){const e=new Map;return Wp.push(e),()=>{for(const[t,n]of e)$p(t,n);Wp.pop()}},writeLoadableToTreeState:jp,invalidateDownstreams:Kp,copyTreeState:qp,invalidateDownstreams_FOR_TESTING:Kp};const{unstable_batchedUpdates:Zp}=oc;var Xp={unstable_batchedUpdates:Zp};const{unstable_batchedUpdates:Jp}=Xp;var eh={unstable_batchedUpdates:Jp};const{batchStart:th}=Yp,{unstable_batchedUpdates:nh}=eh;let rh=nh;var oh={getBatcher:()=>rh,setBatcher:e=>{rh=e},batchUpdates:e=>{rh((()=>{let t=()=>{};try{t=th(),e()}finally{t()}}))}};var ah={enqueueExecution:function(e,t){t()}};var ih=function(e,...t){const n=new Set;e:for(const r of e){for(const e of t)if(e.has(r))continue e;n.add(r)}return n};var lh=function(e,t){const n=new Map;return e.forEach(((e,r)=>{n.set(r,t(e,r))})),n};function uh(e,t,n){const{nodeDeps:r,nodeToNodeSubscriptions:o}=t;e.forEach(((e,t)=>{const a=r.get(t);if(a&&n&&a!==n.nodeDeps.get(t))return;r.set(t,new Set(e));if((null==a?e:ih(e,a)).forEach((e=>{o.has(e)||o.set(e,new Set);Md(o.get(e)).add(t)})),a){ih(a,e).forEach((e=>{if(!o.has(e))return;const n=Md(o.get(e));n.delete(t),0===n.size&&o.delete(e)}))}}))}var sh={addToDependencyMap:function(e,t,n){n.has(e)||n.set(e,new Set),Md(n.get(e)).add(t)},cloneGraph:function(e){return{nodeDeps:lh(e.nodeDeps,(e=>new Set(e))),nodeToNodeSubscriptions:lh(e.nodeToNodeSubscriptions,(e=>new Set(e)))}},graph:function(){return{nodeDeps:new Map,nodeToNodeSubscriptions:new Map}},mergeDepsIntoDependencyMap:function(e,t){e.forEach(((e,n)=>{t.has(n)||t.set(n,new Set);const r=Md(t.get(n));e.forEach((e=>r.add(e)))}))},saveDependencyMapToStore:function(e,t,n){var r,o,a,i;const l=t.getState();n!==l.currentTree.version&&n!==(null===(r=l.nextTree)||void 0===r?void 0:r.version)&&(null===(o=l.previousTree)||void 0===o||o.version);const u=t.getGraph(n);if(uh(e,u),n===(null===(a=l.previousTree)||void 0===a?void 0:a.version)){uh(e,t.getGraph(l.currentTree.version),u)}if(n===(null===(i=l.previousTree)||void 0===i?void 0:i.version)||n===l.currentTree.version){var s;const n=null===(s=l.nextTree)||void 0===s?void 0:s.version;if(void 0!==n){uh(e,t.getGraph(n),u)}}}};var ch,fh=(function(e){var t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},n={},r=Math.pow(2,5),o=r-1,a=r/2,i=r/4,l={},u=function(e){return function(){return e}},s=n.hash=function(e){var n=void 0===e?"undefined":t(e);if("number"===n)return e;"string"!==n&&(e+="");for(var r=0,o=0,a=e.length;o>>e&o},f=function(e){return 1<>1&1431655765))+(n>>2&858993459))+(n>>4)&252645135,127&(n+=n>>8)+(n>>16);var n},p=function(e,t,n,r){var o=r;if(!e){var a=r.length;o=new Array(a);for(var i=0;i1?g(e,this.hash,u):u[0]}var s=r();return s===l?this:(++i.value,S(e,n,this.hash,this,o,y(e,o,a,s)))},T=function(e,t,n,r,o,i,l){var u=this.mask,s=this.children,y=c(n,o),g=f(y),S=d(u,g),k=u&g,E=k?s[S]:m,T=E._modify(e,t,n+5,r,o,i,l);if(E===T)return this;var C,x=_(e,this),R=u,N=void 0;if(k&&v(T)){if(!(R&=~g))return m;if(s.length<=2&&((C=s[1^S])===m||1===C.type||2===C.type))return s[1^S];N=h(x,S,s)}else if(k||v(T))N=p(x,S,T,s);else{if(s.length>=a)return function(e,t,n,r,o){for(var a=[],i=r,l=0,u=0;i;++u)1&i&&(a[u]=o[l++]),i>>>=1;return a[t]=n,w(e,l+1,a)}(e,y,T,u,s);R|=g,N=function(e,t,n,r){var o=r.length;if(e){for(var a=o;a>=t;)r[a--]=r[a];return r[t]=n,r}for(var i=0,l=0,u=new Array(o+1);ibh++;function Sh(){const e=wh();return{version:e,stateID:e,transactionMetadata:{},dirtyAtoms:new Set,atomValues:gh(),nonvalidatedAtoms:gh()}}var _h={makeEmptyTreeState:Sh,makeEmptyStoreState:function(){const e=Sh();return{currentTree:e,nextTree:null,previousTree:null,commitDepth:0,knownAtoms:new Set,knownSelectors:new Set,transactionSubscriptions:new Map,nodeTransactionSubscriptions:new Map,nodeToComponentSubscriptions:new Map,queuedComponentCallbacks_DEPRECATED:[],suspendedComponentResolvers:new Set,graphsByVersion:(new Map).set(e.version,yh()),versionsUsedByComponent:new Map,retention:{referenceCounts:new Map,nodesRetainedByZone:new Map,retainablesToCheckForRelease:new Set},nodeCleanupFunctions:new Map}},getNextTreeStateVersion:wh};var kh=function(...e){const t=new Set;for(const n of e)for(const e of n)t.add(e);return t};var Eh=function(e,t,n){const r=e.entries();let o=r.next();for(;!o.done;){const a=o.value;if(t.call(n,a[1],a[0],e))return!0;o=r.next()}return!1};const{cleanUpNode:Th}=Np,{deleteNodeConfigIfPossible:Ch,getNode:xh}=vp,{RetentionZone:Rh}=gp,Nh=new Set;function Ah(e,t){const n=e.getState(),r=n.currentTree;if(n.nextTree)return;const o=new Set;for(const i of t)if(i instanceof Rh)for(const e of Ph(n,i))o.add(e);else o.add(i);const a=function(e,t){const n=e.getState(),r=n.currentTree,o=e.getGraph(r.version),a=new Set,i=new Set;return l(t),a;function l(t){const u=new Set,s=function(e,t,n,r,o){const a=e.getGraph(t.version),i=[],l=new Set;for(;n.size>0;)u(Md(n.values().next().value));return i;function u(e){if(r.has(e)||o.has(e))return void n.delete(e);if(l.has(e))return;const t=a.nodeToNodeSubscriptions.get(e);if(t)for(const n of t)u(n);l.add(e),n.delete(e),i.push(e)}}(e,r,t,a,i);for(const e of s){var c;if("recoilRoot"===xh(e).retainedBy){i.add(e);continue}if((null!==(c=n.retention.referenceCounts.get(e))&&void 0!==c?c:0)>0){i.add(e);continue}if(Mh(e).some((e=>n.retention.referenceCounts.get(e)))){i.add(e);continue}const t=o.nodeToNodeSubscriptions.get(e);t&&Eh(t,(e=>i.has(e)))?i.add(e):(a.add(e),u.add(e))}const f=new Set;for(const e of u)for(const t of null!==(d=o.nodeDeps.get(e))&&void 0!==d?d:Nh){var d;a.has(t)||f.add(t)}f.size&&l(f)}}(e,o);for(const i of a)Lh(e,r,i)}function Lh(e,t,n){if(!Kd("recoil_memory_managament_2020"))return;Th(e,n);const r=e.getState();r.knownAtoms.delete(n),r.knownSelectors.delete(n),r.nodeTransactionSubscriptions.delete(n),r.retention.referenceCounts.delete(n);const o=Mh(n);for(const u of o){var a;null===(a=r.retention.nodesRetainedByZone.get(u))||void 0===a||a.delete(n)}t.atomValues.delete(n),t.dirtyAtoms.delete(n),t.nonvalidatedAtoms.delete(n);const i=r.graphsByVersion.get(t.version);if(i){const e=i.nodeDeps.get(n);if(void 0!==e){i.nodeDeps.delete(n);for(const t of e){var l;null===(l=i.nodeToNodeSubscriptions.get(t))||void 0===l||l.delete(n)}}i.nodeToNodeSubscriptions.delete(n)}Ch(n)}function Ph(e,t){var n;return null!==(n=e.retention.nodesRetainedByZone.get(t))&&void 0!==n?n:Nh}function Mh(e){const t=xh(e).retainedBy;return void 0===t||"components"===t||"recoilRoot"===t?[]:t instanceof Rh?[t]:t}function Oh(e,t){if(!Kd("recoil_memory_managament_2020"))return;e.getState().retention.referenceCounts.delete(t),function(e,t){const n=e.getState();n.nextTree?n.retention.retainablesToCheckForRelease.add(t):Ah(e,new Set([t]))}(e,t)}var Vh={updateRetainCount:function(e,t,n){var r;if(!Kd("recoil_memory_managament_2020"))return;const o=e.getState().retention.referenceCounts,a=(null!==(r=o.get(t))&&void 0!==r?r:0)+n;0===a?Oh(e,t):o.set(t,a)},updateRetainCountToZero:Oh,releaseScheduledRetainablesNow:function(e){if(!Kd("recoil_memory_managament_2020"))return;const t=e.getState();Ah(e,t.retention.retainablesToCheckForRelease),t.retention.retainablesToCheckForRelease.clear()},retainedByOptionWithDefault:function(e){return void 0===e?"recoilRoot":e}};var zh=function*(e){for(const t of e)for(const e of t)yield e};var Ih={isSSR:"undefined"==typeof window,isReactNative:"undefined"!=typeof navigator&&"ReactNative"===navigator.product};const{isSSR:Dh}=Ih,{batchUpdates:Uh}=oh,{initializeNodeIfNewToStore:Fh,peekNodeInfo:Bh}=Np,{graph:jh}=sh,{DEFAULT_VALUE:$h,recoilValues:Hh,recoilValuesForKeys:Wh}=vp,{AbstractRecoilValue:qh,getRecoilValueAsLoadable:Kh,setRecoilValue:Qh,setUnvalidatedRecoilValue:Gh}=Yp,{updateRetainCount:Yh}=Vh,{getNextTreeStateVersion:Zh,makeEmptyStoreState:Xh}=_h;class Jh{constructor(e){Xd(this,"_store",void 0),Xd(this,"_refCount",0),Xd(this,"getLoadable",(e=>(this.checkRefCount_INTERNAL(),Kh(this._store,e)))),Xd(this,"getPromise",(e=>(this.checkRefCount_INTERNAL(),this.getLoadable(e).toPromise()))),Xd(this,"getNodes_UNSTABLE",(e=>{if(this.checkRefCount_INTERNAL(),!0===(null==e?void 0:e.isModified)){if(!1===(null==e?void 0:e.isInitialized))return[];const t=this._store.getState().currentTree;return Wh(t.dirtyAtoms)}const t=this._store.getState().knownAtoms,n=this._store.getState().knownSelectors;return null==(null==e?void 0:e.isInitialized)?Hh.values():!0===e.isInitialized?Wh(zh([this._store.getState().knownAtoms,this._store.getState().knownSelectors])):Yd(Hh.values(),(({key:e})=>!t.has(e)&&!n.has(e)))})),Xd(this,"getInfo_UNSTABLE",(({key:e})=>(this.checkRefCount_INTERNAL(),Bh(this._store,this._store.getState().currentTree,e)))),Xd(this,"map",(e=>{this.checkRefCount_INTERNAL();const t=new nm(this,Uh);return e(t),tm(t.getStore_INTERNAL())})),Xd(this,"asyncMap",(async e=>{this.checkRefCount_INTERNAL();const t=new nm(this,Uh);return await e(t),tm(t.getStore_INTERNAL())})),this._store={getState:()=>e,replaceState:t=>{e.currentTree=t(e.currentTree)},getGraph:t=>{const n=e.graphsByVersion;if(n.has(t))return Md(n.get(t));const r=jh();return n.set(t,r),r},subscribeToTransactions:()=>({release:()=>{}}),addTransactionMetadata:()=>{throw new Error("Cannot subscribe to Snapshots")}};for(const t of this._store.getState().nodeCleanupFunctions.keys())Fh(this._store,e.currentTree,t,"get"),Yh(this._store,t,1);this.retain(),this.autorelease_INTERNAL()}retain(){if(!Kd("recoil_memory_managament_2020"))return()=>{};this._refCount++;let e=!1;return()=>{e||(e=!0,this.release_INTERNAL())}}autorelease_INTERNAL(){Kd("recoil_memory_managament_2020")&&(Dh||window.setTimeout((()=>this.release_INTERNAL()),0))}release_INTERNAL(){Kd("recoil_memory_managament_2020")&&(this._refCount--,this._refCount)}checkRefCount_INTERNAL(){Kd("recoil_memory_managament_2020")&&this._refCount}getStore_INTERNAL(){return this.checkRefCount_INTERNAL(),this._store}getID(){return this.checkRefCount_INTERNAL(),this.getID_INTERNAL()}getID_INTERNAL(){return this.checkRefCount_INTERNAL(),this._store.getState().currentTree.stateID}}function em(e,t,n=!1){const r=e.getState(),o=n?Zh():t.version;return{currentTree:n?{version:o,stateID:o,transactionMetadata:l({},t.transactionMetadata),dirtyAtoms:new Set(t.dirtyAtoms),atomValues:t.atomValues.clone(),nonvalidatedAtoms:t.nonvalidatedAtoms.clone()}:t,commitDepth:0,nextTree:null,previousTree:null,knownAtoms:new Set(r.knownAtoms),knownSelectors:new Set(r.knownSelectors),transactionSubscriptions:new Map,nodeTransactionSubscriptions:new Map,nodeToComponentSubscriptions:new Map,queuedComponentCallbacks_DEPRECATED:[],suspendedComponentResolvers:new Set,graphsByVersion:(new Map).set(o,e.getGraph(t.version)),versionsUsedByComponent:new Map,retention:{referenceCounts:new Map,nodesRetainedByZone:new Map,retainablesToCheckForRelease:new Set},nodeCleanupFunctions:new Map}}function tm(e,t="current"){const n=e.getState(),r="current"===t?n.currentTree:Md(n.previousTree);return new Jh(em(e,r))}class nm extends Jh{constructor(e,t){super(em(e.getStore_INTERNAL(),e.getStore_INTERNAL().getState().currentTree,!0)),Xd(this,"_batch",void 0),Xd(this,"set",((e,t)=>{this.checkRefCount_INTERNAL();const n=this.getStore_INTERNAL();this._batch((()=>{Yh(n,e.key,1),Qh(this.getStore_INTERNAL(),e,t)}))})),Xd(this,"reset",(e=>{this.checkRefCount_INTERNAL();const t=this.getStore_INTERNAL();this._batch((()=>{Yh(t,e.key,1),Qh(this.getStore_INTERNAL(),e,$h)}))})),Xd(this,"setUnvalidatedAtomValues_DEPRECATED",(e=>{this.checkRefCount_INTERNAL();const t=this.getStore_INTERNAL();Uh((()=>{for(const[n,r]of e.entries())Yh(t,n,1),Gh(t,new qh(n),r)}))})),this._batch=t}}var rm={Snapshot:Jh,MutableSnapshot:nm,freshSnapshot:function(e){const t=new Jh(Xh());return null!=e?t.map(e):t},cloneSnapshot:tm},om=rm.Snapshot,am=rm.MutableSnapshot,im=rm.freshSnapshot,lm=rm.cloneSnapshot,um=Object.freeze({__proto__:null,Snapshot:om,MutableSnapshot:am,freshSnapshot:im,cloneSnapshot:lm});const{getNextTreeStateVersion:sm,makeEmptyStoreState:cm}=_h,{cleanUpNode:fm,getDownstreamNodes:dm,setNodeValue:pm,setUnvalidatedAtomValue_DEPRECATED:hm}=Np,{graph:mm}=sh,{cloneGraph:vm}=sh,{applyAtomValueWrites:ym}=Yp,{releaseScheduledRetainablesNow:gm}=Vh,{freshSnapshot:bm}=um,{useCallback:wm,useContext:Sm,useEffect:_m,useMemo:km,useRef:Em,useState:Tm}=K;function Cm(){throw new Error("This component must be used inside a component.")}const xm=Object.freeze({getState:Cm,replaceState:Cm,getGraph:Cm,subscribeToTransactions:Cm,addTransactionMetadata:Cm});let Rm=!1;function Nm(e){if(Rm)throw new Error("An atom update was triggered within the execution of a state updater function. State updater functions provided to Recoil must be pure functions.");const t=e.getState();if(null===t.nextTree){Kd("recoil_memory_managament_2020")&&Kd("recoil_release_on_cascading_update_killswitch_2021")&&t.commitDepth>0&&gm(e);const n=t.currentTree.version,r=sm();t.nextTree=u(l({},t.currentTree),{version:r,stateID:r,dirtyAtoms:new Set,transactionMetadata:{}}),t.graphsByVersion.set(r,vm(Md(t.graphsByVersion.get(n))))}}const Am=K.createContext({current:xm}),Lm=()=>Sm(Am),Pm=K.createContext(null);function Mm(e,t,n){const r=dm(e,n,n.dirtyAtoms);for(const o of r){const e=t.nodeToComponentSubscriptions.get(o);if(e)for(const[t,[r,o]]of e)o(n)}}function Om(e){const t=e.getState(),n=t.currentTree,r=n.dirtyAtoms;if(r.size){for(const[n,o]of t.nodeTransactionSubscriptions)if(r.has(n))for(const[t,r]of o)r(e);for(const[n,r]of t.transactionSubscriptions)r(e);Kd("recoil_early_rendering_2021")&&!t.suspendedComponentResolvers.size||(Mm(e,t,n),t.suspendedComponentResolvers.forEach((e=>e())),t.suspendedComponentResolvers.clear())}t.queuedComponentCallbacks_DEPRECATED.forEach((e=>e(n))),t.queuedComponentCallbacks_DEPRECATED.splice(0,t.queuedComponentCallbacks_DEPRECATED.length)}function Vm({setNotifyBatcherOfChange:e}){const t=Lm(),[n,r]=Tm([]);return e((()=>r({}))),_m((()=>{ah.enqueueExecution("Batcher",(()=>{!function(e){const t=e.current.getState();t.commitDepth++;try{const{nextTree:n}=t;if(null===n)return;t.previousTree=t.currentTree,t.currentTree=n,t.nextTree=null,Om(e.current),null!=t.previousTree?t.graphsByVersion.delete(t.previousTree.version):Qd("Ended batch with no previous state, which is unexpected","recoil"),t.previousTree=null,Kd("recoil_memory_managament_2020")&&gm(e.current)}finally{t.commitDepth--}}(t)}))})),_m((()=>()=>{e((()=>{}))}),[e]),null}let zm=0;function Im({initializeState_DEPRECATED:e,initializeState:t,store_INTERNAL:n,children:r}){var o;let a;const i=Em(null),s=wm((e=>{i.current=e}),[i]),c=null!==(o=K.createMutableSource)&&void 0!==o?o:K.unstable_createMutableSource,f=null!=n?n:{getState:()=>a.current,replaceState:e=>{const t=d.current.getState();Nm(d.current);const n=Md(t.nextTree);let r;try{Rm=!0,r=e(n)}finally{Rm=!1}r!==n&&(t.nextTree=r,Kd("recoil_early_rendering_2021")&&Mm(f,t,r),Md(i.current)())},getGraph:e=>{const t=a.current.graphsByVersion;if(t.has(e))return Md(t.get(e));const n=mm();return t.set(e,n),n},subscribeToTransactions:(e,t)=>{if(null==t){const{transactionSubscriptions:t}=d.current.getState(),n=zm++;return t.set(n,e),{release:()=>{t.delete(n)}}}{const{nodeTransactionSubscriptions:n}=d.current.getState();n.has(t)||n.set(t,new Map);const r=zm++;return Md(n.get(t)).set(r,e),{release:()=>{const e=n.get(t);e&&(e.delete(r),0===e.size&&n.delete(t))}}}},addTransactionMetadata:e=>{Nm(d.current);for(const t of Object.keys(e))Md(d.current.getState().nextTree).transactionMetadata[t]=e[t]}},d=Em(f);a=Em(null!=e?function(e,t){const n=cm();return t({set:(t,r)=>{const o=n.currentTree,a=pm(e,o,t.key,r),i=new Set(a.keys()),s=o.nonvalidatedAtoms.clone();for(const e of i)s.delete(e);n.currentTree=u(l({},o),{dirtyAtoms:kh(o.dirtyAtoms,i),atomValues:ym(o.atomValues,a),nonvalidatedAtoms:s})},setUnvalidatedAtomValues:e=>{e.forEach(((e,t)=>{n.currentTree=hm(n.currentTree,t,e)}))}}),n}(f,e):null!=t?function(e){return bm().map(e).getStore_INTERNAL().getState()}(t):cm());const p=km((()=>c?c(a,(()=>a.current.currentTree.version)):null),[c,a]);return _m((()=>()=>{for(const e of d.current.getState().knownAtoms)fm(d.current,e)}),[]),K.createElement(Am.Provider,{value:d},K.createElement(Pm.Provider,{value:p},K.createElement(Vm,{setNotifyBatcherOfChange:s}),r))}var Dm={useStoreRef:Lm,useRecoilMutableSource:function(){return Sm(Pm)},RecoilRoot:function(e){const t=e,{override:n}=t,r=s(t,["override"]),o=Lm();return!1===n&&o.current!==xm?e.children:K.createElement(Im,r)},notifyComponents_FOR_TESTING:Mm,sendEndOfBatchNotifications_FOR_TESTING:Om};const{loadableWithValue:Um}=Bd,{DEFAULT_VALUE:Fm,getNode:Bm}=vp,{copyTreeState:jm,getRecoilValueAsLoadable:$m,invalidateDownstreams:Hm,writeLoadableToTreeState:Wm}=Yp;function qm(e){return"atom"===Bm(e.key).nodeType}class Km{constructor(e,t){Xd(this,"_store",void 0),Xd(this,"_treeState",void 0),Xd(this,"_changes",void 0),Xd(this,"get",(e=>{if(this._changes.has(e.key))return this._changes.get(e.key);if(!qm(e))throw new Error("Reading selectors within atomicUpdate is not supported");const t=$m(this._store,e,this._treeState);if("hasValue"===t.state)return t.contents;throw"hasError"===t.state?t.contents:new Error(`Expected Recoil atom ${e.key} to have a value, but it is in a loading state.`)})),Xd(this,"set",((e,t)=>{if(!qm(e))throw new Error("Setting selectors within atomicUpdate is not supported");if("function"==typeof t){const n=this.get(e);this._changes.set(e.key,t(n))}else this._changes.set(e.key,t)})),Xd(this,"reset",(e=>{this.set(e,Fm)})),this._store=e,this._treeState=t,this._changes=new Map}newTreeState_INTERNAL(){if(0===this._changes.size)return this._treeState;const e=jm(this._treeState);for(const[t,n]of this._changes)Wm(e,t,Um(n));return Hm(this._store,e),e}}var Qm=function(e){return t=>{e.replaceState((n=>{const r=new Km(e,n);return t(r),r.newTreeState_INTERNAL()}))}},Gm=Object.freeze({__proto__:null,atomicUpdater:Qm});var Ym=function(e,t){const n=new Map;for(const[r,o]of e)t(o,r)&&n.set(r,o);return n};var Zm=function(e,t){const n=new Set;for(const r of e)t(r)&&n.add(r);return n};var Xm=function(e,t){if(!e)throw new Error(t)};var Jm=function(...e){const t=new Map;for(let n=0;n"};const{atomicUpdater:rv}=Gm,{batchUpdates:ov}=oh,{DEFAULT_VALUE:av,getNode:iv,nodes:lv}=vp,{useRecoilMutableSource:uv,useStoreRef:sv}=Dm,{AbstractRecoilValue:cv,getRecoilValueAsLoadable:fv,setRecoilValue:dv,setRecoilValueLoadable:pv,setUnvalidatedRecoilValue:hv,subscribeToRecoilValue:mv}=Yp,{updateRetainCount:vv}=Vh,{RetentionZone:yv}=gp,{Snapshot:gv,cloneSnapshot:bv}=um,{setByAddingToSet:wv}=Gd,{isSSR:Sv}=Ih,{mutableSourceExists:_v,useMutableSource:kv}=$d,{useCallback:Ev,useEffect:Tv,useMemo:Cv,useRef:xv,useState:Rv}=K;function Nv(e,t,n){if("hasValue"===e.state)return e.contents;if("loading"===e.state){throw new Promise((e=>{n.current.getState().suspendedComponentResolvers.add(e)}))}if("hasError"===e.state)throw e.contents;throw new Error(`Invalid value of loadable atom "${t.key}"`)}function Av(e){return Kd("recoil_memory_managament_2020")&&Uv(e),_v()?function(e){const t=sv(),n=Ev((()=>{var n;const r=t.current,o=r.getState(),a=Kd("recoil_early_rendering_2021")&&null!==(n=o.nextTree)&&void 0!==n?n:o.currentTree;return fv(r,e,a)}),[t,e]),r=Ev((()=>n()),[n]),o=nv(),a=Ev(((r,a)=>{const i=t.current;return mv(i,e,(()=>{if(!Kd("recoil_suppress_rerender_in_callback"))return a();const e=n();u.current.is(e)||a(),u.current=e}),o).release}),[t,e,o,n]),i=uv(),l=kv(i,r,a),u=xv(l);return Tv((()=>{u.current=l})),l}(e):function(e){const t=sv(),[n,r]=Rv([]),o=nv();Tv((()=>{const n=t.current,a=n.getState(),l=mv(n,e,(t=>{var o;if(!Kd("recoil_suppress_rerender_in_callback"))return r([]);const a=fv(n,e,n.getState().currentTree);(null===(o=i.current)||void 0===o?void 0:o.is(a))||r(a),i.current=a}),o);if(a.nextTree)n.getState().queuedComponentCallbacks_DEPRECATED.push((()=>{i.current=null,r([])}));else{var u;if(!Kd("recoil_suppress_rerender_in_callback"))return r([]);const t=fv(n,e,n.getState().currentTree);(null===(u=i.current)||void 0===u?void 0:u.is(t))||r(t),i.current=t}return l.release}),[o,e,t]);const a=fv(t.current,e),i=xv(a);return Tv((()=>{i.current=a})),a}(e)}function Lv(e){const t=sv();return Nv(Av(e),e,t)}function Pv(e){const t=sv();return Ev((n=>{dv(t.current,e,n)}),[t,e])}function Mv(e){const t=sv();Tv((()=>t.current.subscribeToTransactions(e).release),[e,t])}function Ov(e){const t=e.atomValues.toMap(),n=lh(Ym(t,((e,t)=>{const n=iv(t).persistence_UNSTABLE;return null!=n&&"none"!==n.type&&"hasValue"===e.state})),(e=>e.contents));return Jm(e.nonvalidatedAtoms.toMap(),n)}function Vv(e){const t=xv();return Tv((()=>{t.current=e})),t.current}function zv(){const e=sv();return Ev((t=>{var n;const r=e.current.getState(),o=null!==(n=r.nextTree)&&void 0!==n?n:r.currentTree,a=t.getStore_INTERNAL().getState().currentTree;ov((()=>{const n=new Set;for(const e of[o.atomValues.keys(),a.atomValues.keys()])for(const t of e){var r,i;(null===(r=o.atomValues.get(t))||void 0===r?void 0:r.contents)!==(null===(i=a.atomValues.get(t))||void 0===i?void 0:i.contents)&&iv(t).shouldRestoreFromSnapshots&&n.add(t)}n.forEach((t=>{pv(e.current,new cv(t),a.atomValues.has(t)?Md(a.atomValues.get(t)):av)})),e.current.replaceState((e=>u(l({},e),{stateID:t.getID_INTERNAL()})))}))}),[e])}class Iv{}const Dv=new Iv;function Uv(e){if(Kd("recoil_memory_managament_2020"))return function(e){const t=(Array.isArray(e)?e:[e]).map((e=>e instanceof yv?e:e.key)),n=sv();Tv((()=>{if(!Kd("recoil_memory_managament_2020"))return;const e=n.current;if(r.current&&!Sv)window.clearTimeout(r.current),r.current=null;else for(const n of t)vv(e,n,1);return()=>{for(const n of t)vv(e,n,-1)}}),[n,...t]);const r=xv(),o=Vv(t);if(!(Sv||void 0!==o&&ev(o,t))){const e=n.current;for(const n of t)vv(e,n,1);if(o)for(const t of o)vv(e,t,-1);r.current&&window.clearTimeout(r.current),r.current=window.setTimeout((()=>{r.current=null;for(const n of t)vv(e,n,-1)}),12e4)}}(e)}var Fv={recoilComponentGetRecoilValueCount_FOR_TESTING:{current:0},useGotoRecoilSnapshot:zv,useRecoilCallback:function(e,t){const n=sv(),r=zv();return Ev(((...t)=>{function o(e,t){dv(n.current,e,t)}function a(e){dv(n.current,e,av)}const i=bv(n.current),l=rv(n.current);let u=Dv;return ov((()=>{const n="useRecoilCallback expects a function that returns a function: it accepts a function of the type (RecoilInterface) => T = R and returns a callback function T => R, where RecoilInterface is an object {snapshot, set, ...} and T and R are the argument and return types of the callback you want to create. Please see the docs at recoiljs.org for details.";if("function"!=typeof e)throw new Error(n);const s=e({set:o,reset:a,snapshot:i,gotoSnapshot:r,transact_UNSTABLE:l});if("function"!=typeof s)throw new Error(n);u=s(...t)})),u instanceof Iv&&Xm(!1),u}),null!=t?[...t,n]:void 0)},useRecoilInterface:function(){const e=sv(),[t,n]=Rv([]),r=xv(new Set);r.current=new Set;const o=xv(new Set),a=xv(new Map),i=Ev((e=>{const t=a.current.get(e);t&&(t.release(),a.current.delete(e))}),[a]),l=nv();return Tv((()=>{const t=e.current;function u(e,t){a.current.has(t)&&n([])}ih(r.current,o.current).forEach((e=>{if(a.current.has(e))return;const n=mv(t,new cv(e),(t=>{u(0,e)}),l);a.current.set(e,n);t.getState().nextTree?t.getState().queuedComponentCallbacks_DEPRECATED.push((()=>{u(t.getState(),e)})):u(t.getState(),e)})),ih(o.current,r.current).forEach((e=>{i(e)})),o.current=r.current})),Tv((()=>{const e=a.current;return()=>e.forEach(((e,t)=>i(t)))}),[i]),Cv((()=>{function t(t){return n=>{dv(e.current,t,n)}}function n(t){var n;r.current.has(t.key)||(r.current=wv(r.current,t.key));const o=e.current.getState();return fv(e.current,t,Kd("recoil_early_rendering_2021")&&null!==(n=o.nextTree)&&void 0!==n?n:o.currentTree)}function o(t){return Nv(n(t),t,e)}return{getRecoilValue:o,getRecoilValueLoadable:n,getRecoilState:function(e){return[o(e),t(e)]},getRecoilStateLoadable:function(e){return[n(e),t(e)]},getSetRecoilState:t,getResetRecoilState:function(t){return()=>dv(e.current,t,av)}}}),[r,e])},useRecoilSnapshot:function(){const e=sv(),[t,n]=Rv((()=>bv(e.current))),r=Vv(t),o=xv();return Tv((()=>(o.current&&!Sv&&window.clearTimeout(o.current),t.retain())),[t]),Mv(Ev((e=>n(bv(e))),[])),r===t||Sv||(o.current&&(null==r||r.release_INTERNAL(),window.clearTimeout(o.current)),t.retain(),o.current=window.setTimeout((()=>{t.release_INTERNAL(),o.current=null}),12e4)),t},useRecoilState:function(e){return[Lv(e),Pv(e)]},useRecoilStateLoadable:function(e){return[Av(e),Pv(e)]},useRecoilTransaction:function(e,t){const n=sv();return Cv((()=>(...t)=>{rv(n.current)((n=>{e(n)(...t)}))}),null!=t?[...t,n]:void 0)},useRecoilTransactionObserver:function(e){Mv(Ev((t=>{const n=bv(t,"current"),r=bv(t,"previous");e({snapshot:n,previousSnapshot:r})}),[e]))},useRecoilValue:Lv,useRecoilValueLoadable:Av,useRetain:Uv,useResetRecoilState:function(e){const t=sv();return Ev((()=>{dv(t.current,e,av)}),[t,e])},useSetRecoilState:Pv,useSetUnvalidatedAtomValues:function(){const e=sv();return(t,n={})=>{ov((()=>{e.current.addTransactionMetadata(n),t.forEach(((t,n)=>hv(e.current,new cv(n),t)))}))}},useTransactionObservation_DEPRECATED:function(e){Mv(Ev((t=>{let n=t.getState().previousTree;const r=t.getState().currentTree;n||(n=t.getState().currentTree);const o=Ov(r),a=Ov(n),i=lh(lv,(e=>{var t,n,r,o;return{persistence_UNSTABLE:{type:null!==(t=null===(n=e.persistence_UNSTABLE)||void 0===n?void 0:n.type)&&void 0!==t?t:"none",backButton:null!==(r=null===(o=e.persistence_UNSTABLE)||void 0===o?void 0:o.backButton)&&void 0!==r&&r}}})),u=Zm(r.dirtyAtoms,(e=>o.has(e)||a.has(e)));e({atomValues:o,previousAtomValues:a,atomInfo:i,modifiedAtoms:u,transactionMetadata:l({},r.transactionMetadata)})}),[e]))},useTransactionSubscription_DEPRECATED:Mv};const{peekNodeInfo:Bv}=Np,{useStoreRef:jv}=Dm;var $v=function(){const e=jv();return({key:t})=>Bv(e.current,e.current.getState().currentTree,t)};const{RecoilRoot:Hv,useStoreRef:Wv}=Dm,{useMemo:qv}=K;var Kv=function(){const e=Wv().current;return qv((()=>function({children:t}){return K.createElement(Hv,{store_INTERNAL:e},t)}),[e])};function Qv(e,t,n){if("string"==typeof e&&!e.includes('"')&&!e.includes("\\"))return`"${e}"`;switch(typeof e){case"undefined":return"";case"boolean":return e?"true":"false";case"number":case"symbol":return String(e);case"string":return JSON.stringify(e);case"function":if(!0!==(null==t?void 0:t.allowFunctions))throw new Error("Attempt to serialize function in a Recoil cache key");return`__FUNCTION(${e.name})__`}if(null===e)return"null";var r;if("object"!=typeof e)return null!==(r=JSON.stringify(e))&&void 0!==r?r:"";if(Pd(e))return"__PROMISE__";if(Array.isArray(e))return`[${e.map(((e,n)=>Qv(e,t,n.toString())))}]`;if("function"==typeof e.toJSON)return Qv(e.toJSON(n),t,n);if(e instanceof Map){const r={};for(const[n,o]of e)r["string"==typeof n?n:Qv(n,t)]=o;return Qv(r,t,n)}return e instanceof Set?Qv(Array.from(e).sort(((e,n)=>Qv(e,t).localeCompare(Qv(n,t)))),t,n):void 0!==Symbol&&null!=e[Symbol.iterator]&&"function"==typeof e[Symbol.iterator]?Qv(Array.from(e),t,n):`{${Object.keys(e).filter((t=>void 0!==e[t])).sort().map((n=>`${Qv(n,t)}:${Qv(e[n],t,n)}`)).join(",")}}`}var Gv=function(e,t={allowFunctions:!1}){return Qv(e,t)};const Yv=(e,t,n)=>{var r;if(null==e)return;if(null==n||null===(r=n.onNodeVisit)||void 0===r||r.call(n,e),"leaf"===e.type)return e;const o=t(e.nodeKey);return Yv(e.branches.get(o),t,n)},Zv=(e,t,n,r,o,a)=>{var i;let l;if(null==e)if(0===t.length)l={type:"leaf",value:r,parent:n,branchKey:o};else{const[e,...i]=t,[u,s]=e;l={type:"branch",nodeKey:u,parent:n,branches:new Map,branchKey:o},l.branches.set(s,Zv(null,i,l,r,s,a))}else if(l=e,t.length){const[n,...o]=t,[i,l]=n;("branch"!==e.type||e.nodeKey!==i)&&Xm(!1),e.branches.set(l,Zv(e.branches.get(l),o,e,r,l,a))}return null==a||null===(i=a.onNodeVisit)||void 0===i||i.call(a,l),l},Xv=(e,t,n)=>n?(n.branches.delete(t.branchKey),Jv(e,n,n.parent)):e===t,Jv=(e,t,n)=>n?(0===t.branches.size&&n.branches.delete(t.branchKey),Jv(e,n,n.parent)):e===t,ey=e=>"leaf"===e.type?1:Array.from(e.branches.values()).reduce(((e,t)=>e+ey(t)),0);var ty=class{constructor(e){var t,n,r;Xd(this,"_numLeafs",void 0),Xd(this,"_root",void 0),Xd(this,"_onHit",void 0),Xd(this,"_onSet",void 0),Xd(this,"_mapNodeValue",void 0),this._numLeafs=0,this._root=null,this._onHit=null!==(t=null==e?void 0:e.onHit)&&void 0!==t?t:()=>{},this._onSet=null!==(n=null==e?void 0:e.onSet)&&void 0!==n?n:()=>{},this._mapNodeValue=null!==(r=null==e?void 0:e.mapNodeValue)&&void 0!==r?r:e=>e}size(){return this._numLeafs}root(){return this._root}get(e,t){var n;return null===(n=this.getLeafNode(e,t))||void 0===n?void 0:n.value}getLeafNode(e,t){return Yv(this.root(),(t=>this._mapNodeValue(e(t))),{onNodeVisit:e=>{null==t||t.onNodeVisit(e),"leaf"===e.type&&this._onHit(e)}})}set(e,t,n){let r;const o=Zv(this.root(),e.map((([e,t])=>[e,this._mapNodeValue(t)])),null,t,null,{onNodeVisit:e=>{null==n||n.onNodeVisit(e),"leaf"===e.type&&(r=e)}});this.root()||(this._root=o),this._numLeafs++,this._onSet(Md(r))}delete(e){if(!this.root())return!1;const t=Md(this.root());return!!Xv(t,e,e.parent)&&(e===t||"branch"===t.type&&!t.branches.size?(this._root=null,this._numLeafs=0,!0):(this._numLeafs-=ey(e),!0))}clear(){this._numLeafs=0,this._root=null}},ny=Object.freeze({__proto__:null,TreeCache:ty});var ry=class{constructor(e){var t;Xd(this,"_maxSize",void 0),Xd(this,"_size",void 0),Xd(this,"_head",void 0),Xd(this,"_tail",void 0),Xd(this,"_map",void 0),Xd(this,"_keyMapper",void 0),this._maxSize=e.maxSize,this._size=0,this._head=null,this._tail=null,this._map=new Map,this._keyMapper=null!==(t=e.mapKey)&&void 0!==t?t:e=>e}head(){return this._head}tail(){return this._tail}size(){return this._size}maxSize(){return this._maxSize}has(e){return this._map.has(this._keyMapper(e))}get(e){const t=this._keyMapper(e),n=this._map.get(t);if(n)return this.set(e,n.value),n.value}set(e,t){const n=this._keyMapper(e);this._map.get(n)&&this.delete(e);const r=this.head(),o={key:e,right:r,left:null,value:t};r?r.left=o:this._tail=o,this._map.set(n,o),this._head=o,this._size++,this._maybeDeleteLRU()}_maybeDeleteLRU(){this.size()>this.maxSize()&&this.deleteLru()}deleteLru(){const e=this.tail();e&&this.delete(e.key)}delete(e){const t=this._keyMapper(e);if(!this._size||!this._map.has(t))return;const n=Md(this._map.get(t)),r=n.right,o=n.left;r&&(r.left=n.left),o&&(o.right=n.right),n===this.head()&&(this._head=r),n===this.tail()&&(this._tail=o),this._map.delete(t),this._size--}clear(){this._size=0,this._head=null,this._tail=null,this._map=new Map}},oy=Object.freeze({__proto__:null,LRUCache:ry});const{LRUCache:ay}=oy,{TreeCache:iy}=ny;var ly=function(e,t=(e=>e)){const n=new ay({maxSize:e}),r=new iy({mapNodeValue:t,onHit:e=>{n.set(e,!0)},onSet:t=>{const o=n.tail();n.set(t,!0),o&&r.size()>e&&r.delete(o.key)}});return r};const{TreeCache:uy}=ny,sy={equality:"reference",eviction:"keep-all",maxSize:1/0};var cy=function({equality:e=sy.equality,eviction:t=sy.eviction,maxSize:n=sy.maxSize}=sy){return function(e,t,n){switch(e){case"keep-all":return new uy({mapNodeValue:n});case"lru":return ly(Md(t),n);case"most-recent":return ly(1,n)}throw new Error(`Unrecognized eviction policy ${e}`)}(t,n,function(e){switch(e){case"reference":return e=>e;case"value":return e=>Gv(e)}throw new Error(`Unrecognized equality policy ${e}`)}(e))};var fy={startPerfBlock:function(e){return()=>null}};const{CANCELED:dy,Canceled:py,loadableWithError:hy,loadableWithPromise:my,loadableWithValue:vy}=Bd,{getNodeLoadable:yy,peekNodeLoadable:gy,setNodeValue:by}=Np,{saveDependencyMapToStore:wy}=sh,{DEFAULT_VALUE:Sy,RecoilValueNotReady:_y,getConfigDeletionHandler:ky,registerNode:Ey}=vp,{isRecoilValue:Ty}=lp,{AbstractRecoilValue:Cy}=lp,{setRecoilValueLoadable:xy}=Yp,{retainedByOptionWithDefault:Ry}=Vh,{cloneSnapshot:Ny}=um,{startPerfBlock:Ay}=fy,Ly=[],Py=new Map,My=(()=>{let e=0;return()=>e++})();var Oy=function(e){const{key:t,get:n,cachePolicy_UNSTABLE:r}=e,o=null!=e.set?e.set:void 0,a=cy(null!=r?r:{equality:"reference",eviction:"keep-all"}),i=Ry(e.retainedBy_UNSTABLE),l=new Map;let u=0;function s(){return!Kd("recoil_memory_managament_2020")||u>0}function c(e){return l.has(e)||l.set(e,{depValuesDiscoveredSoFarDuringAsyncWork:null,latestLoadable:null,latestExecutionId:null,stateVersion:null}),Md(l.get(e))}function f(e){return u++,e.getState().knownSelectors.add(t),()=>{u--,e.getState().knownSelectors.delete(t),l.delete(e)}}function d(){return void 0!==ky(t)&&!s()}function p(e,t,n){if("loading"===t.state){let t=Py.get(n);null==t&&Py.set(n,t=new Set),t.add(e)}}function h(e,t,n){const r=e.getState().knownSelectors.has(n);if(r&&t.atomValues.has(n))return Md(t.atomValues.get(n));const o=yy(e,t,n);return"loading"!==o.state&&r&&t.atomValues.set(n,o),o}function m(e,n,r,o,a){return n.then((n=>{if(!s())return C(e,a),dy;if(n instanceof py)return dy;const{__key:o,__value:i}=null!=n?n:{};let l=!0;null!=o&&(r.atomValues.set(o,vy(i)),l=!1);const u=b(e,r);if(u&&"hasValue"===u.state)return E(u,e),{__value:u.contents,__key:t};if(!x(e,a)){var c;const e=_(r);if("loading"===(null==e||null===(c=e.latestLoadable)||void 0===c?void 0:c.state))return e.latestLoadable.contents}const[f,d]=g(e,r,a,l);if(x(e,a)&&T(d,e,a),R(f),"loading"!==f.state&&(N(r,w(d),f),y(e,r,new Set(d.keys()),a),v(e,f,a)),"hasError"===f.state)throw f.contents;return"hasValue"===f.state?{__value:f.contents,__key:t}:f.contents})).catch((t=>{if(!s())return C(e,a),dy;const n=hy(t);throw N(r,w(o),hy(t)),y(e,r,new Set(o.keys()),a),v(e,n,a),t}))}function v(e,n,r){x(e,r)&&(E(n,e),function(e,n){const r=Py.get(n);if(void 0!==r){for(const n of r)xy(n,new Cy(t),e);Py.delete(n)}}(n,r))}function y(e,n,r,o){var a,i,l,u,s,c,f;(x(e,o)||n.version===(null===(a=e.getState())||void 0===a||null===(i=a.currentTree)||void 0===i?void 0:i.version)||n.version===(null===(l=e.getState())||void 0===l||null===(u=l.nextTree)||void 0===u?void 0:u.version))&&wy(new Map([[t,r]]),e,null!==(s=null===(c=e.getState())||void 0===c||null===(f=c.nextTree)||void 0===f?void 0:f.version)&&void 0!==s?s:e.getState().currentTree.version)}function g(e,r,o,a=!1){const i=Ay(t);let l,u,c=!1;const f=new Map,d=new Set;function p(t){const{key:n}=t;!function(e,t,n,r,o){n.add(r),y(e,t,n,o)}(e,r,d,n,o);const i=a?yy(e,r,n):h(e,r,n);if(R(i),f.set(n,i),"hasValue"===i.state)return i.contents;throw i.contents}y(e,r,d,o);let g=!1;const b=t=>(...n)=>{if(!g)throw new Error("getCallback() should only be called asynchronously after the selector is evalutated. It can be used for selectors to return objects with callbacks that can obtain the current Recoil state without a subscription.");const r=Ny(e),o=t({snapshot:r});if("function"!=typeof o)throw new Error("getCallback() expects a function that returns a function.");return o(...n)};try{l=n({get:p,getCallback:b}),l=Ty(l)?p(l):l,g=!0,Pd(l)?l=function(e,n,r,o,a){return n.then((n=>{if(!s())return C(e,a),dy;const i=vy(n);return N(r,w(o),i),y(e,r,new Set(o.keys()),a),v(e,i,a),{__value:n,__key:t}})).catch((t=>{if(!s())return C(e,a),dy;if(x(e,a)&&T(o,e,a),Pd(t))return m(e,t,r,o,a);const n=hy(t);throw N(r,w(o),n),y(e,r,new Set(o.keys()),a),v(e,n,a),t}))}(e,l,r,f,o).finally(i):i()}catch(S){l=S,Pd(l)?l=m(e,l,r,f,o).finally(i):(c=!0,i())}return u=c?hy(l):Pd(l)?my(l):vy(l),R(u),[u,f]}function b(e,n){const r=new Set,o=c(e),i=a.get((t=>{"string"!=typeof t&&Xm(!1);return h(e,n,t).contents}),{onNodeVisit:e=>{"branch"===e.type&&e.nodeKey!==t&&"string"==typeof e.nodeKey&&r.add(e.nodeKey)}});return i&&y(e,n,r,o.latestExecutionId),i}function w(e){return Array.from(e.entries()).map((([e,t])=>[e,t.contents]))}function S(e,t){const n=My(),[r,o]=g(e,t,n);return E(r,e,o,n,t),function(e,t,n){"loading"!==n.state&&N(e,t,n)}(t,w(o),r),p(e,r,n),r}function _(e){var t;const[,n]=null!==(t=Array.from(l.entries()).find((([t,n])=>null!=n.latestLoadable&&null!=n.latestExecutionId&&!function(e,t){var n,r;const o=c(e),a=null!==(n=o.depValuesDiscoveredSoFarDuringAsyncWork)&&void 0!==n?n:new Map,i=Array((null!==(r=k.get(t.version))&&void 0!==r?r:new Map).entries()),l=k.has(t.version)&&i.length===a.size&&i.every((([e,t])=>a.get(e)===t));if(null==a||t.version===o.stateVersion||l)return!1;return k.set(t.version,new Map(a)),Array.from(a).some((([n,r])=>h(e,t,n).contents!==r.contents))}(t,e))))&&void 0!==t?t:[];return n}const k=new Map;function E(e,t,n,r,o){const a=c(t);"loading"===e.state?(a.depValuesDiscoveredSoFarDuringAsyncWork=n,a.latestExecutionId=r,a.latestLoadable=e,a.stateVersion=null==o?void 0:o.version):(a.depValuesDiscoveredSoFarDuringAsyncWork=null,a.latestExecutionId=null,a.latestLoadable=null,a.stateVersion=null)}function T(e,t,n){const r=c(t);x(t,n)&&(r.depValuesDiscoveredSoFarDuringAsyncWork=e)}function C(e,t){x(e,t)&&l.delete(e)}function x(e,t){return t===c(e).latestExecutionId}function R(e){"loading"!==e.state&&e.contents}function N(e,n,r){e.atomValues.set(t,r),a.set(n,r)}function A(e,t){return a.get((n=>{"string"!=typeof n&&Xm(!1);const r=gy(e,t,n);return null==r?void 0:r.contents}))}function L(e,n){return function(e){if(Ly.includes(t)){const e=`Recoil selector has circular dependencies: ${Ly.slice(Ly.indexOf(t)).join(" → ")}`;return hy(new Error(e))}Ly.push(t);try{return e()}finally{Ly.pop()}}((()=>function(e,t){const n=b(e,t);if(null!=n)return E(n,e),n;const r=_(t);if(r){const t=r;return p(e,Md(t.latestLoadable),Md(t.latestExecutionId)),Md(t.latestLoadable)}return S(e,t)}(e,n)))}function P(e){e.atomValues.delete(t)}if(null!=o){return Ey({key:t,nodeType:"selector",peek:A,get:L,set:(e,t,n)=>{let r=!1;const a=new Map;function i({key:n}){if(r)throw new Error("Recoil: Async selector sets are not currently supported.");const o=h(e,t,n);if(R(o),"hasValue"===o.state)return o.contents;throw"loading"===o.state?new _y(n):o.contents}function l(n,o){if(r)throw new Error("Recoil: Async selector sets are not currently supported.");const l="function"==typeof o?o(i(n)):o;by(e,t,n.key,l).forEach(((e,t)=>a.set(t,e)))}const u=o({set:l,get:i,reset:function(e){l(e,Sy)}},n);if(void 0!==u)throw Pd(u)?new Error("Recoil: Async selector sets are not currently supported."):new Error("Recoil: selector set should be a void function.");return r=!0,a},init:f,invalidate:P,shouldDeleteConfigOnRelease:d,dangerouslyAllowMutability:e.dangerouslyAllowMutability,shouldRestoreFromSnapshots:!1,retainedBy:i})}return Ey({key:t,nodeType:"selector",peek:A,get:L,init:f,invalidate:P,shouldDeleteConfigOnRelease:d,dangerouslyAllowMutability:e.dangerouslyAllowMutability,shouldRestoreFromSnapshots:!1,retainedBy:i})};const{loadableWithError:Vy,loadableWithPromise:zy,loadableWithValue:Iy}=Bd,{DEFAULT_VALUE:Dy,DefaultValue:Uy,getConfigDeletionHandler:Fy,registerNode:By,setConfigDeletionHandler:jy}=vp,{isRecoilValue:$y}=lp,{markRecoilValueModified:Hy,setRecoilValue:Wy,setRecoilValueLoadable:qy}=Yp,{retainedByOptionWithDefault:Ky}=Vh;function Qy(e){const{key:t,persistence_UNSTABLE:n}=e,r=Ky(e.retainedBy_UNSTABLE);let o,a=0,i=Pd(e.default)?zy(e.default.then((e=>{i=Iy(e);return{__key:t,__value:e}})).catch((e=>{throw i=Vy(e),e}))):Iy(e.default);const l=new Map;const u=By({key:t,nodeType:"atom",peek:function(e,n){var r,a,l;return null!==(r=null!==(a=n.atomValues.get(t))&&void 0!==a?a:null===(l=o)||void 0===l?void 0:l[1])&&void 0!==r?r:i},get:function(e,r){if(r.atomValues.has(t))return Md(r.atomValues.get(t));if(r.nonvalidatedAtoms.has(t)){if(null!=o)return o;if(null==n)return i;const e=r.nonvalidatedAtoms.get(t),a=n.validator(e,Dy),l=a instanceof Uy?i:Iy(a);return o=l,o}return i},set:function(e,n,r){if(n.atomValues.has(t)){const e=Md(n.atomValues.get(t));if("hasValue"===e.state&&r===e.contents)return new Map}else if(!n.nonvalidatedAtoms.has(t)&&r instanceof Uy)return new Map;return o=void 0,(new Map).set(t,Iy(r))},init:function(n,r,o){a++;const s=n.getState().knownAtoms.has(t);if(n.getState().knownAtoms.add(t),"loading"===i.state){const e=()=>{var e;(null!==(e=n.getState().nextTree)&&void 0!==e?e:n.getState().currentTree).atomValues.has(t)||Hy(n,u)};i.contents.then(e).catch(e)}let c=Dy,f=null;if(null!=e.effects_UNSTABLE&&!s){let r=!0;const a=e=>t=>{if(r){const n=c instanceof Uy||Pd(c)?"hasValue"===i.state?i.contents:Dy:c;c="function"==typeof t?t(n):t,Pd(c)&&(c=c.then((t=>(f={effect:e,value:t},t))))}else{if(Pd(t))throw new Error("Setting atoms to async values is not implemented.");"function"!=typeof t&&(f={effect:e,value:t}),Wy(n,u,"function"==typeof t?n=>{const r=t(n);return f={effect:e,value:r},r}:t)}},s=e=>()=>a(e)(Dy),h=e=>r=>{n.subscribeToTransactions((n=>{var o;let{currentTree:a,previousTree:l}=n.getState();l||(l=a);const u=null!==(o=a.atomValues.get(t))&&void 0!==o?o:i;if("hasValue"===u.state){var s,c,d,p;const n=u.contents,o=null!==(s=l.atomValues.get(t))&&void 0!==s?s:i,a="hasValue"===o.state?o.contents:Dy;(null===(c=f)||void 0===c?void 0:c.effect)!==e||(null===(d=f)||void 0===d?void 0:d.value)!==n?r(n,a):(null===(p=f)||void 0===p?void 0:p.effect)===e&&(f=null)}}),t)};for(const t of null!==(d=e.effects_UNSTABLE)&&void 0!==d?d:[]){var d;const e=t({node:u,trigger:o,setSelf:a(t),resetSelf:s(t),onSet:h(t)});var p;if(null!=e)l.set(n,[...null!==(p=l.get(n))&&void 0!==p?p:[],e])}r=!1}if(!(c instanceof Uy)){var h;const e=Pd(c)?zy(function(e,n){const r=n.then((n=>{var o,a;return(null===(a=(null!==(o=e.getState().nextTree)&&void 0!==o?o:e.getState().currentTree).atomValues.get(t))||void 0===a?void 0:a.contents)===r&&Wy(e,u,n),{__key:t,__value:n}})).catch((n=>{var o,a;throw(null===(a=(null!==(o=e.getState().nextTree)&&void 0!==o?o:e.getState().currentTree).atomValues.get(t))||void 0===a?void 0:a.contents)===r&&qy(e,u,Vy(n)),n}));return r}(n,c)):Iy(c);r.atomValues.set(t,e),null===(h=n.getState().nextTree)||void 0===h||h.atomValues.set(t,e)}return()=>{var e;a--,null===(e=l.get(n))||void 0===e||e.forEach((e=>e())),l.delete(n),n.getState().knownAtoms.delete(t)}},invalidate:function(){o=void 0},shouldDeleteConfigOnRelease:function(){return void 0!==Fy(t)&&a<=0},dangerouslyAllowMutability:e.dangerouslyAllowMutability,persistence_UNSTABLE:e.persistence_UNSTABLE?{type:e.persistence_UNSTABLE.type,backButton:e.persistence_UNSTABLE.backButton}:void 0,shouldRestoreFromSnapshots:!0,retainedBy:r});return u}function Gy(e){const t=e,{default:n}=t,r=s(t,["default"]);return $y(n)?function(e){const t=Gy(u(l({},e),{default:Dy,persistence_UNSTABLE:void 0===e.persistence_UNSTABLE?void 0:u(l({},e.persistence_UNSTABLE),{validator:t=>t instanceof Uy?t:Md(e.persistence_UNSTABLE).validator(t,Dy)}),effects_UNSTABLE:e.effects_UNSTABLE})),n=Oy({key:`${e.key}__withFallback`,get:({get:n})=>{const r=n(t);return r instanceof Uy?e.default:r},set:({set:e},n)=>e(t,n),dangerouslyAllowMutability:e.dangerouslyAllowMutability});return jy(n.key,Fy(e.key)),n}(u(l({},r),{default:n})):Qy(u(l({},r),{default:n}))}var Yy=Gy;var Zy=class{constructor(e){var t;Xd(this,"_map",void 0),Xd(this,"_keyMapper",void 0),this._map=new Map,this._keyMapper=null!==(t=null==e?void 0:e.mapKey)&&void 0!==t?t:e=>e}size(){return this._map.size}has(e){return this._map.has(this._keyMapper(e))}get(e){return this._map.get(this._keyMapper(e))}set(e,t){this._map.set(this._keyMapper(e),t)}delete(e){this._map.delete(this._keyMapper(e))}clear(){this._map.clear()}},Xy=Object.freeze({__proto__:null,MapCache:Zy});const{LRUCache:Jy}=oy,{MapCache:eg}=Xy,tg={equality:"reference",eviction:"none",maxSize:1/0};var ng=function({equality:e=tg.equality,eviction:t=tg.eviction,maxSize:n=tg.maxSize}=tg){return function(e,t,n){switch(e){case"keep-all":return new eg({mapKey:n});case"lru":return new Jy({mapKey:n,maxSize:Md(t)});case"most-recent":return new Jy({mapKey:n,maxSize:1})}throw new Error(`Unrecognized eviction policy ${e}`)}(t,n,function(e){switch(e){case"reference":return e=>e;case"value":return e=>Gv(e)}throw new Error(`Unrecognized equality policy ${e}`)}(e))};const{setConfigDeletionHandler:rg}=vp;var og=function(e){var t,n;const r=ng({equality:null!==(t=null===(n=e.cachePolicyForParams_UNSTABLE)||void 0===n?void 0:n.equality)&&void 0!==t?t:"value",eviction:"keep-all"});return t=>{var n;const o=r.get(t);if(null!=o)return o;const a=e,{cachePolicyForParams_UNSTABLE:i}=a,c=s(a,["cachePolicyForParams_UNSTABLE"]),f=Yy(u(l({},c),{key:`${e.key}__${null!==(n=Gv(t))&&void 0!==n?n:"void"}`,default:"function"==typeof e.default?e.default(t):e.default,retainedBy_UNSTABLE:"function"==typeof e.retainedBy_UNSTABLE?e.retainedBy_UNSTABLE(t):e.retainedBy_UNSTABLE,effects_UNSTABLE:"function"==typeof e.effects_UNSTABLE?e.effects_UNSTABLE(t):e.effects_UNSTABLE}));return r.set(t,f),rg(f.key,(()=>{r.delete(t)})),f}};const{setConfigDeletionHandler:ag}=vp;let ig=0;var lg=function(e){var t,n;const r=ng({equality:null!==(t=null===(n=e.cachePolicyForParams_UNSTABLE)||void 0===n?void 0:n.equality)&&void 0!==t?t:"value",eviction:"keep-all"});return t=>{var n;const o=r.get(t);if(null!=o)return o;const a=`${e.key}__selectorFamily/${null!==(n=Gv(t,{allowFunctions:!0}))&&void 0!==n?n:"void"}/${ig++}`,i=n=>e.get(t)(n),l=e.cachePolicy_UNSTABLE,u="function"==typeof e.retainedBy_UNSTABLE?e.retainedBy_UNSTABLE(t):e.retainedBy_UNSTABLE;let s;if(null!=e.set){const n=e.set;s=Oy({key:a,get:i,set:(e,r)=>n(t)(e,r),cachePolicy_UNSTABLE:l,dangerouslyAllowMutability:e.dangerouslyAllowMutability,retainedBy_UNSTABLE:u})}else s=Oy({key:a,get:i,cachePolicy_UNSTABLE:l,dangerouslyAllowMutability:e.dangerouslyAllowMutability,retainedBy_UNSTABLE:u});return r.set(t,s),ag(s.key,(()=>{r.delete(t)})),s}};const ug=lg({key:"__constant",get:e=>()=>e,cachePolicyForParams_UNSTABLE:{equality:"reference"}});var sg=function(e){return ug(e)};const cg=lg({key:"__error",get:e=>()=>{throw new Error(e)},cachePolicyForParams_UNSTABLE:{equality:"reference"}});var fg=function(e){return cg(e)};var dg=function(e){return e};const{loadableWithError:pg,loadableWithPromise:hg,loadableWithValue:mg}=Bd;function vg(e,t){const n=Array(t.length).fill(void 0),r=Array(t.length).fill(void 0);for(const[a,i]of t.entries())try{n[a]=e(i)}catch(o){r[a]=o}return[n,r]}function yg(e){return null!=e&&!Pd(e)}function gg(e){return Array.isArray(e)?e:Object.getOwnPropertyNames(e).map((t=>e[t]))}function bg(e){return null!=e&&"object"==typeof e&&e.hasOwnProperty("__value")?e.__value:e}function wg(e,t){return Array.isArray(e)?t:Object.getOwnPropertyNames(e).reduce(((e,n,r)=>u(l({},e),{[n]:t[r]})),{})}function Sg(e,t,n){return wg(e,n.map(((e,n)=>null==e?mg(t[n]):Pd(e)?hg(e):pg(e))))}var _g={waitForNone:lg({key:"__waitForNone",get:e=>({get:t})=>{const n=gg(e),[r,o]=vg(t,n);return Sg(e,r,o)},dangerouslyAllowMutability:!0}),waitForAny:lg({key:"__waitForAny",get:e=>({get:t})=>{const n=gg(e),[r,o]=vg(t,n);return o.some((e=>!Pd(e)))?Sg(e,r,o):new Promise((t=>{for(const[n,a]of o.entries())Pd(a)&&a.then((a=>{r[n]=bg(a),o[n]=void 0,t(Sg(e,r,o))})).catch((a=>{o[n]=a,t(Sg(e,r,o))}))}))},dangerouslyAllowMutability:!0}),waitForAll:lg({key:"__waitForAll",get:e=>({get:t})=>{const n=gg(e),[r,o]=vg(t,n);if(o.every((e=>null==e)))return wg(e,r);const a=o.find(yg);if(null!=a)throw a;return Promise.all(o).then((t=>{return wg(e,(n=r,o=t,o.map(((e,t)=>void 0===e?n[t]:e))).map(bg));var n,o}))},dangerouslyAllowMutability:!0}),waitForAllSettled:lg({key:"__waitForAllSettled",get:e=>({get:t})=>{const n=gg(e),[r,o]=vg(t,n);return o.every((e=>!Pd(e)))?Sg(e,r,o):Promise.all(o.map(((e,t)=>Pd(e)?e.then((e=>{r[t]=bg(e),o[t]=void 0})).catch((e=>{r[t]=void 0,o[t]=e})):null))).then((()=>Sg(e,r,o)))},dangerouslyAllowMutability:!0}),noWait:lg({key:"__noWait",get:e=>({get:t})=>{try{return mg(t(e))}catch(n){return Pd(n)?hg(n):pg(n)}},dangerouslyAllowMutability:!0})};const{batchUpdates:kg,setBatcher:Eg}=oh,{DefaultValue:Tg}=vp,{RecoilRoot:Cg}=Dm,{isRecoilValue:xg}=lp,{retentionZone:Rg}=gp,{freshSnapshot:Ng}=um,{useGotoRecoilSnapshot:Ag,useRecoilCallback:Lg,useRecoilSnapshot:Pg,useRecoilState:Mg,useRecoilStateLoadable:Og,useRecoilTransaction:Vg,useRecoilTransactionObserver:zg,useRecoilValue:Ig,useRecoilValueLoadable:Dg,useResetRecoilState:Ug,useRetain:Fg,useSetRecoilState:Bg,useSetUnvalidatedAtomValues:jg,useTransactionObservation_DEPRECATED:$g}=Fv,{noWait:Hg,waitForAll:Wg,waitForAllSettled:qg,waitForAny:Kg,waitForNone:Qg}=_g;var Gg={DefaultValue:Tg,RecoilRoot:Cg,useRecoilBridgeAcrossReactRoots_UNSTABLE:Kv,atom:Yy,selector:Oy,retentionZone:Rg,atomFamily:og,selectorFamily:lg,constSelector:sg,errorSelector:fg,readOnlySelector:dg,useRecoilValue:Ig,useRecoilValueLoadable:Dg,useRecoilState:Mg,useRecoilStateLoadable:Og,useSetRecoilState:Bg,useResetRecoilState:Ug,useGetRecoilValueInfo_UNSTABLE:$v,useRetain:Fg,useRecoilCallback:Lg,useRecoilTransaction_UNSTABLE:Vg,useGotoRecoilSnapshot:Ag,useRecoilSnapshot:Pg,useRecoilTransactionObserver_UNSTABLE:zg,useTransactionObservation_UNSTABLE:$g,useSetUnvalidatedAtomValues_UNSTABLE:jg,noWait:Hg,waitForNone:Qg,waitForAny:Kg,waitForAll:Wg,waitForAllSettled:qg,isRecoilValue:xg,batchUpdates:kg,setBatcher:Eg,snapshot_UNSTABLE:Ng},Yg=Gg.RecoilRoot,Zg=Gg.atom,Xg=Gg.selector,Jg=Gg.useRecoilValue,eb=Gg.useRecoilState;export{kd as H,K as R,gd as S,Q as a,Sd as b,yd as c,Yg as d,oc as e,qc as f,Zg as g,eb as h,Xg as i,Jg as j,_d as k,ac as p,c as r,wd as u,ef as z};
diff --git a/assets/rss.2a18b2d2.svg b/assets/rss.2a18b2d2.svg
new file mode 100644
index 0000000..254f8c8
--- /dev/null
+++ b/assets/rss.2a18b2d2.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/woap.99c96107.svg b/assets/woap.99c96107.svg
new file mode 100644
index 0000000..9c9435d
--- /dev/null
+++ b/assets/woap.99c96107.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/discussions.json b/discussions.json
new file mode 100644
index 0000000..7c957ce
--- /dev/null
+++ b/discussions.json
@@ -0,0 +1 @@
+[{"cursor":"Y3Vyc29yOnYyOpK0MjAyMy0wNC0xM1QwNjozNTowOVrOADuxnw==","node":{"title":"微信杂谈 - 技术社交很重要","number":84,"updatedAt":"2023-05-23T06:38:35Z","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"category":{"name":"Notes","emojiHTML":"📝
"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwzMTgxNDE5MDUz","name":"微信杂谈","color":"13913a"}}]}}},{"cursor":"Y3Vyc29yOnYyOpK0MjAyMi0xMi0wNlQxMToxNDowMVrOAEarTw==","node":{"title":"请问如何部署?","number":90,"updatedAt":"2022-12-06T11:14:01Z","author":{"login":"Jonnyan404","avatarUrl":"https://avatars.githubusercontent.com/u/20352705?u=3806efb3d3cd512e4bd3ddfdd85b52ac53b6b797&v=4","url":"https://github.com/Jonnyan404"},"category":{"name":"QA","emojiHTML":"❓
"},"labels":{"edges":[]}}},{"cursor":"Y3Vyc29yOnYyOpK0MjAyMi0wNy0wMVQwMToyODowOVrOAD_fRg==","node":{"title":"痛苦学习的快感","number":88,"updatedAt":"2022-07-01T01:28:10Z","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"category":{"name":"Notes","emojiHTML":"📝
"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwzMDg2MDYxNzMz","name":"blog","color":"D4C5F9"}},{"node":{"id":"MDU6TGFiZWwzMTk2OTc2MDIx","name":"wechat-post","color":"d8d8d8"}}]}}},{"cursor":"Y3Vyc29yOnYyOpK0MjAyMi0wNi0xMFQxNDozMDozNFrOADQMfw==","node":{"title":"《黑客与画家》读书笔记","number":25,"updatedAt":"2022-06-10T14:30:34Z","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"category":{"name":"Notes","emojiHTML":"📝
"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwzMDg1MjU0NjQ0","name":"book","color":"A4BBBE"}},{"node":{"id":"MDU6TGFiZWwzMTk2OTc2MDIx","name":"wechat-post","color":"d8d8d8"}}]}}},{"cursor":"Y3Vyc29yOnYyOpK0MjAyMi0wNi0xMFQxMzo1MjoyM1rOADbIgg==","node":{"title":"lencx 语录","number":74,"updatedAt":"2022-06-10T13:52:23Z","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"category":{"name":"Notes","emojiHTML":"📝
"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwzMDg2MDYxNzMz","name":"blog","color":"D4C5F9"}},{"node":{"id":"MDU6TGFiZWwzMTk2OTc2MDIx","name":"wechat-post","color":"d8d8d8"}}]}}},{"cursor":"Y3Vyc29yOnYyOpK0MjAyMi0wNi0wNlQwMzozOTozM1rOADN4pg==","node":{"title":"欢迎来到《浮之静》社区","number":2,"updatedAt":"2022-06-06T03:39:33Z","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"category":{"name":"General","emojiHTML":"💬
"},"labels":{"edges":[]}}},{"cursor":"Y3Vyc29yOnYyOpK0MjAyMi0wNi0wNlQwMzozNzowOFrOAD7lbQ==","node":{"title":"微信杂谈 - 学习 Rust","number":87,"updatedAt":"2022-06-06T03:37:08Z","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"category":{"name":"Notes","emojiHTML":"📝
"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwzMTgxNDE5MDUz","name":"微信杂谈","color":"13913a"}}]}}},{"cursor":"Y3Vyc29yOnYyOpK0MjAyMi0wNC0wOFQxNjoxMToyOVrOADz7IA==","node":{"title":"微信杂谈 - 写代码","number":86,"updatedAt":"2022-09-27T07:00:40Z","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"category":{"name":"Notes","emojiHTML":"📝
"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwzMTgxNDE5MDUz","name":"微信杂谈","color":"13913a"}}]}}},{"cursor":"Y3Vyc29yOnYyOpK0MjAyMi0wMy0yOFQwOToxMDoyOVrOADw3CA==","node":{"title":"开发利器之命令行","number":85,"updatedAt":"2022-06-01T02:31:27Z","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"category":{"name":"Notes","emojiHTML":"📝
"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwzMDg2MDYxNzMz","name":"blog","color":"D4C5F9"}},{"node":{"id":"MDU6TGFiZWwzMTk2OTc2MDIx","name":"wechat-post","color":"d8d8d8"}}]}}},{"cursor":"Y3Vyc29yOnYyOpK0MjAyMi0wMi0yNVQwNzozMDozN1rOADt7Eg==","node":{"title":"微信杂谈 - 代码优化","number":83,"updatedAt":"2022-06-01T08:44:27Z","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"category":{"name":"Notes","emojiHTML":"📝
"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwzMTgxNDE5MDUz","name":"微信杂谈","color":"13913a"}}]}}},{"cursor":"Y3Vyc29yOnYyOpK0MjAyMi0wMi0yNVQwMjoxNDo0MFrOADnJhg==","node":{"title":"微信杂谈 - 解决问题方法论","number":79,"updatedAt":"2022-06-10T05:56:22Z","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"category":{"name":"Notes","emojiHTML":"📝
"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwzMTgxNDE5MDUz","name":"微信杂谈","color":"13913a"}}]}}},{"cursor":"Y3Vyc29yOnYyOpK0MjAyMi0wMi0yNFQwMTo0Njo1MlrOADt63g==","node":{"title":"微信杂谈 - 实习简历如何写","number":82,"updatedAt":"2023-03-19T10:45:01Z","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"category":{"name":"Notes","emojiHTML":"📝
"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwzMTgxNDE5MDUz","name":"微信杂谈","color":"13913a"}}]}}},{"cursor":"Y3Vyc29yOnYyOpK0MjAyMi0wMi0xN1QxNjozMDowNVrOADtEBA==","node":{"title":"如何提升写作技巧?","number":81,"updatedAt":"2022-06-06T00:43:07Z","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"category":{"name":"Notes","emojiHTML":"📝
"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwzMDg2MDYxNzMz","name":"blog","color":"D4C5F9"}},{"node":{"id":"MDU6TGFiZWwzMTk2OTc2MDIx","name":"wechat-post","color":"d8d8d8"}}]}}},{"cursor":"Y3Vyc29yOnYyOpK0MjAyMi0wMi0xMFQxMDowODo0MFrOADsELA==","node":{"title":"什么字体更适合程序员?","number":80,"updatedAt":"2022-09-01T06:21:56Z","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"category":{"name":"Notes","emojiHTML":"📝
"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwzMDg2MDYxNzMz","name":"blog","color":"D4C5F9"}},{"node":{"id":"MDU6TGFiZWwzMTk2OTc2MDIx","name":"wechat-post","color":"d8d8d8"}}]}}},{"cursor":"Y3Vyc29yOnYyOpK0MjAyMi0wMS0wOFQwMDozNDoyM1rOADmrpA==","node":{"title":"浏览器发展史","number":78,"updatedAt":"2022-09-02T10:33:44Z","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"category":{"name":"Notes","emojiHTML":"📝
"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwzMDg2MDYxNzMz","name":"blog","color":"D4C5F9"}},{"node":{"id":"MDU6TGFiZWwzMTk2OTc2MDIx","name":"wechat-post","color":"d8d8d8"}}]}}},{"cursor":"Y3Vyc29yOnYyOpK0MjAyMi0wMS0wNFQwMzozMTo1NVrOADRk0A==","node":{"title":"阅读打卡","number":44,"updatedAt":"2022-07-29T07:27:13Z","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"category":{"name":"Series","emojiHTML":"📚
"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwzMDg2MDYxNzMz","name":"blog","color":"D4C5F9"}},{"node":{"id":"MDU6TGFiZWwzMTk1NTQxODE3","name":"wechat-link","color":"C2E0C6"}}]}}},{"cursor":"Y3Vyc29yOnYyOpK0MjAyMi0wMS0wMVQwNDowMToxNFrOADmM_A==","node":{"title":"2021 年终总结","number":77,"updatedAt":"2022-10-15T16:42:23Z","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"category":{"name":"Review","emojiHTML":"🎦
"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwzMTk2OTc2MDIx","name":"wechat-post","color":"d8d8d8"}}]}}},{"cursor":"Y3Vyc29yOnYyOpK0MjAyMS0xMi0yNVQxNTo0OTo0M1rOADl1hQ==","node":{"title":"微信杂谈 - 组件开发的一些思考","number":75,"updatedAt":"2022-12-15T02:47:23Z","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"category":{"name":"Notes","emojiHTML":"📝
"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwzMTgxNDE5MDUz","name":"微信杂谈","color":"13913a"}}]}}},{"cursor":"Y3Vyc29yOnYyOpK0MjAyMS0xMi0yMlQwNjoyOToyNlrOADRmWQ==","node":{"title":"组件解耦的一些思考","number":45,"updatedAt":"2022-07-10T12:18:17Z","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"category":{"name":"Notes","emojiHTML":"📝
"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwzMDQ1ODIxNzYx","name":"react","color":"61dafb"}},{"node":{"id":"MDU6TGFiZWwzMDg2MDYxNzMz","name":"blog","color":"D4C5F9"}}]}}},{"cursor":"Y3Vyc29yOnYyOpK0MjAyMS0xMS0yOFQxNjo1OTo0NVrOADWcGw==","node":{"title":"开源 - 原创打卡","number":66,"updatedAt":"2022-09-16T07:16:28Z","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"category":{"name":"General","emojiHTML":"💬
"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwzMDg2MDYxNzMz","name":"blog","color":"D4C5F9"}},{"node":{"id":"MDU6TGFiZWwzMTk2OTc2MDIx","name":"wechat-post","color":"d8d8d8"}}]}}},{"cursor":"Y3Vyc29yOnYyOpK0MjAyMS0xMS0wNlQwNTo1NjozOFrOADQ_wA==","node":{"title":"这些年追过的动漫","number":35,"updatedAt":"2022-08-21T14:10:36Z","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"category":{"name":"Series","emojiHTML":"📚
"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwzMTk1NTQxODE3","name":"wechat-link","color":"C2E0C6"}}]}}},{"cursor":"Y3Vyc29yOnYyOpK0MjAyMS0xMC0wOVQwNzo1Njo0NlrOADOj3w==","node":{"title":"Web Development Guide","number":8,"updatedAt":"2022-06-27T09:33:01Z","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"category":{"name":"FE","emojiHTML":"🦄
"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwzMDg2MDYxNzMz","name":"blog","color":"D4C5F9"}},{"node":{"id":"MDU6TGFiZWwzMTk1NTQxODE3","name":"wechat-link","color":"C2E0C6"}}]}}},{"cursor":"Y3Vyc29yOnYyOpK0MjAyMS0wOS0yMFQwODo0NjozN1rOADaqJQ==","node":{"title":"滚动进度条","number":72,"updatedAt":"2022-07-29T07:34:15Z","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"category":{"name":"Notes","emojiHTML":"📝
"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwzMDUyMDQ4NTAz","name":"vue","color":"41b883"}},{"node":{"id":"MDU6TGFiZWwzMDg2MDYxNzMz","name":"blog","color":"D4C5F9"}},{"node":{"id":"MDU6TGFiZWwzMTk2OTc2MDIx","name":"wechat-post","color":"d8d8d8"}}]}}},{"cursor":"Y3Vyc29yOnYyOpK0MjAyMS0wOS0xNFQxMDo0Mzo0M1rOADZ9zw==","node":{"title":"开发问题汇总","number":71,"updatedAt":"2022-07-15T05:43:58Z","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"category":{"name":"FE","emojiHTML":"🦄
"},"labels":{"edges":[]}}},{"cursor":"Y3Vyc29yOnYyOpK0MjAyMS0wOS0xNFQxMDo0MDo1NlrOADZ8pw==","node":{"title":"解决问题之经验篇","number":70,"updatedAt":"2022-09-18T15:22:45Z","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"category":{"name":"Notes","emojiHTML":"📝
"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwzMDg2MDYxNzMz","name":"blog","color":"D4C5F9"}},{"node":{"id":"MDU6TGFiZWwzMTk2OTc2MDIx","name":"wechat-post","color":"d8d8d8"}}]}}},{"cursor":"Y3Vyc29yOnYyOpK0MjAyMS0wOS0xM1QwMzoxMTozMlrOADRHrA==","node":{"title":"lencx 的 vscode 配置","number":41,"updatedAt":"2022-06-09T15:28:32Z","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"category":{"name":"Tools","emojiHTML":"🛠️
"},"labels":{"edges":[]}}},{"cursor":"Y3Vyc29yOnYyOpK0MjAyMS0wOC0yNVQwOToyMDo1NFrOADV7mg==","node":{"title":"JS 手写系列","number":63,"updatedAt":"2022-06-28T06:15:29Z","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"category":{"name":"FE","emojiHTML":"🦄
"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwyMjk0NjQ2Mjcx","name":"js","color":"FBCA04"}},{"node":{"id":"MDU6TGFiZWwzMDI2NDEyNzMy","name":"interview","color":"F2D28D"}}]}}},{"cursor":"Y3Vyc29yOnYyOpK0MjAyMS0wOC0xNVQwNzowNTo1MlrOADW9PQ==","node":{"title":"基于 GitHub Discussions 的 Blog 框架","number":68,"updatedAt":"2022-07-15T00:33:45Z","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"category":{"name":"Notes","emojiHTML":"📝
"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwzMDg2MDYxNzMz","name":"blog","color":"D4C5F9"}},{"node":{"id":"MDU6TGFiZWwzMTk2OTc2MDIx","name":"wechat-post","color":"d8d8d8"}}]}}},{"cursor":"Y3Vyc29yOnYyOpK0MjAyMS0wNy0zMFQwMjo0NDo1MlrOADVAzw==","node":{"title":"微信杂谈 - 技术栈","number":61,"updatedAt":"2023-04-15T12:36:35Z","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"category":{"name":"Notes","emojiHTML":"📝
"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwzMTgxNDE5MDUz","name":"微信杂谈","color":"13913a"}}]}}},{"cursor":"Y3Vyc29yOnYyOpK0MjAyMS0wNy0yMFQxMDoyNzo1M1rOADTuLQ==","node":{"title":"自学总结・入门期","number":59,"updatedAt":"2023-04-13T12:53:24Z","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"category":{"name":"Notes","emojiHTML":"📝
"},"labels":{"edges":[]}}},{"cursor":"Y3Vyc29yOnYyOpK0MjAyMS0wNy0yMFQwMTowMzoxMlrOADTr4Q==","node":{"title":"微信杂谈 - 技术广度 & 深度","number":57,"updatedAt":"2022-11-10T00:56:41Z","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"category":{"name":"Notes","emojiHTML":"📝
"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwzMTgxNDE5MDUz","name":"微信杂谈","color":"13913a"}}]}}},{"cursor":"Y3Vyc29yOnYyOpK0MjAyMS0wNy0xOVQxMDo0MTo1NlrOADTnaA==","node":{"title":"微信杂谈 - 技术迷茫期","number":55,"updatedAt":"2022-12-23T07:26:23Z","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"category":{"name":"Notes","emojiHTML":"📝
"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwzMTgxNDE5MDUz","name":"微信杂谈","color":"13913a"}}]}}},{"cursor":"Y3Vyc29yOnYyOpK0MjAyMS0wNy0xOVQxMDoxNjoxMVrOADTnPA==","node":{"title":"微信杂谈 - 造轮子","number":54,"updatedAt":"2023-04-13T12:57:58Z","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"category":{"name":"Notes","emojiHTML":"📝
"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwzMTgxNDE5MDUz","name":"微信杂谈","color":"13913a"}}]}}},{"cursor":"Y3Vyc29yOnYyOpK0MjAyMS0wNy0xOVQwNjo1NToxNFrOADTAtw==","node":{"title":"【自荐】- 文章 & 开源","number":49,"updatedAt":"2022-06-06T04:12:18Z","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"category":{"name":"Series","emojiHTML":"📚
"},"labels":{"edges":[]}}},{"cursor":"Y3Vyc29yOnYyOpK0MjAyMS0wNy0xOVQwMzoxOTowNlrOADTlFw==","node":{"title":"Pixel Art","number":52,"updatedAt":"2023-04-13T15:27:01Z","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"category":{"name":"Series","emojiHTML":"📚
"},"labels":{"edges":[]}}},{"cursor":"Y3Vyc29yOnYyOpK0MjAyMS0wNy0xNFQxMTo1Mjo0MFrOADTKcQ==","node":{"title":"基于 Github Discussions 构建个人 Blog","number":50,"updatedAt":"2022-07-07T22:20:08Z","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"category":{"name":"Notes","emojiHTML":"📝
"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwzMDg2MDYxNzMz","name":"blog","color":"D4C5F9"}}]}}},{"cursor":"Y3Vyc29yOnYyOpK0MjAyMS0wNy0xNFQwODo1ODoxOFrOADTKfA==","node":{"title":"技术是什么?","number":51,"updatedAt":"2022-09-07T14:54:53Z","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"category":{"name":"Notes","emojiHTML":"📝
"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwzMDg2MDYxNzMz","name":"blog","color":"D4C5F9"}}]}}},{"cursor":"Y3Vyc29yOnYyOpK0MjAyMS0wNy0wN1QwNTo1NjoyM1rOADP9KQ==","node":{"title":"TODO","number":20,"updatedAt":"2023-04-15T02:21:52Z","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"category":{"name":"Notes","emojiHTML":"📝
"},"labels":{"edges":[]}}},{"cursor":"Y3Vyc29yOnYyOpK0MjAyMS0wNy0wNlQwNzoyNTozOFrOADQgIw==","node":{"title":"技术词汇表 - 中英文","number":34,"updatedAt":"2022-11-17T05:54:57Z","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"category":{"name":"Notes","emojiHTML":"📝
"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwzMDkwMTgxNDQw","name":"tech-terms","color":"315C84"}}]}}},{"cursor":"Y3Vyc29yOnYyOpK0MjAyMS0wNi0yN1QxNzoyNjoxN1rOADRh8Q==","node":{"title":"Following Series","number":43,"updatedAt":"2022-07-25T20:19:52Z","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"category":{"name":"Series","emojiHTML":"📚
"},"labels":{"edges":[]}}},{"cursor":"Y3Vyc29yOnYyOpK0MjAyMS0wNi0yM1QwNjoyNzozN1rOADRAKA==","node":{"title":"通用 - 组件 & 库","number":36,"updatedAt":"2022-08-29T14:56:36Z","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"category":{"name":"FE","emojiHTML":"🦄
"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwyMjk0NjQ2Mjcx","name":"js","color":"FBCA04"}},{"node":{"id":"MDU6TGFiZWwzMDQ1ODIxNzYx","name":"react","color":"61dafb"}},{"node":{"id":"MDU6TGFiZWwzMDUyMDQ4NTAz","name":"vue","color":"41b883"}}]}}},{"cursor":"Y3Vyc29yOnYyOpK0MjAyMS0wNi0yM1QwMzozNzoyMFrOADRGxQ==","node":{"title":"网站性能优化系列","number":39,"updatedAt":"2023-03-06T06:04:09Z","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"category":{"name":"FE","emojiHTML":"🦄
"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwyMjk0NjQ2Mjcx","name":"js","color":"FBCA04"}},{"node":{"id":"MDU6TGFiZWwzMDI2NDEyNzMy","name":"interview","color":"F2D28D"}}]}}},{"cursor":"Y3Vyc29yOnYyOpK0MjAyMS0wNi0xNVQxMjoyMDoxMFrOADOMzw==","node":{"title":"静态网站生成器","number":7,"updatedAt":"2023-05-07T16:23:47Z","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"category":{"name":"Tools","emojiHTML":"🛠️
"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwzMDI0NjA1NTk3","name":"doc","color":"B66EAD"}}]}}},{"cursor":"Y3Vyc29yOnYyOpK0MjAyMS0wNi0xNFQxNjoxMDoyNlrOADQOfA==","node":{"title":"人总是喜欢在固有思维下钻牛角尖","number":30,"updatedAt":"2022-07-29T07:36:59Z","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"category":{"name":"Notes","emojiHTML":"📝
"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwzMDg2MDYxNzMz","name":"blog","color":"D4C5F9"}}]}}},{"cursor":"Y3Vyc29yOnYyOpK0MjAyMS0wNi0xNFQxMzo0NjoyN1rOADQNCQ==","node":{"title":"在路上..🏃🏻♂️.","number":29,"updatedAt":"2022-06-24T05:39:00Z","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"category":{"name":"Notes","emojiHTML":"📝
"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwzMDg1NjU4NzMw","name":"thinking","color":"4F69DF"}}]}}},{"cursor":"Y3Vyc29yOnYyOpK0MjAyMS0wNi0xNFQxMToyNjo1MFrOADQMkw==","node":{"title":"暗淡蓝点 (Pale Blue Dot)","number":26,"updatedAt":"2023-11-27T10:07:49Z","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"category":{"name":"Notes","emojiHTML":"📝
"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwzMDg1MjU0NjQ0","name":"book","color":"A4BBBE"}}]}}},{"cursor":"Y3Vyc29yOnYyOpK0MjAyMS0wNS0xOVQxNzo1MTo1MFrOADN4rw==","node":{"title":"JavaScript 原型链","number":3,"updatedAt":"2023-03-19T09:13:26Z","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"category":{"name":"Notes","emojiHTML":"📝
"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwyMjk0NjQ2Mjcx","name":"js","color":"FBCA04"}},{"node":{"id":"MDU6TGFiZWwzMDI2NDEyNzMy","name":"interview","color":"F2D28D"}}]}}}]
\ No newline at end of file
diff --git a/favicon.ico b/favicon.ico
new file mode 100644
index 0000000..7be9aa7
Binary files /dev/null and b/favicon.ico differ
diff --git a/feed.xml b/feed.xml
new file mode 100644
index 0000000..c019871
--- /dev/null
+++ b/feed.xml
@@ -0,0 +1,2011 @@
+
+
+ 浮之静
+
+ https://lencx.tech
+ 浮之静 技术社区
+ -
+
+ https://github.com/lencx/z/discussions/84
+ https://github.com/lencx/z/discussions/84
+ 2023-05-23
+ 📅 2022.03.03
+杰拉德 (Gerrard):
+技术真好玩 可惜我不是学coding的
+lencx:
+有好的师傅领还是很重要的,我一路自学过来,走过好几年的弯路
+lencx:
+本来问人可能就是一句话的事情,但是对我来说,可能要花几周,甚至更久,还记得入行那会,一个环境配置,我断断续续自己折腾了几个月才搞好。
+lencx:
+所以我每天动态发朋友圈,也是有私心的,加的大佬多了,一定程度上,也是对自己的曝光。
+lencx:
+虽然不一定有人看,但是看到了就可能是一次机会。
+杰拉德 (Gerrard):
+社交是有用的
+lencx:
+其实我也想开了,就混混社区也挺好,不一定非要去什么大厂。
+杰拉德 (Gerrard):
+有人带肯定更好
+lencx:
+技术就是用来实践的,既然没有平台可以发挥,那么参与开源也是一种学习和实践的途径。
+lencx:
+关于有人带这个话题,在我看来或许也不是很重要了,因为这么多年,我也以为遇到问题会有人帮你,以前小公司是没条件,现在虽说这个公司不小,但是遇到问题,依旧需要自己去解决。问人也并非是什么上策。我也已经过了需要让人带(入行时很重要)的年纪了。
+杰拉德 (Gerrard):
+也是 而且兴趣是源动力 有就有 没有就自学[拳头]
+lencx:
+是的
]]>
+
+-
+
+ https://github.com/lencx/z/discussions/90
+ https://github.com/lencx/z/discussions/90
+ 2022-12-06
+ 麻烦给一篇部署文档,谢谢!]]>
+
+-
+
+ https://github.com/lencx/z/discussions/88
+ https://github.com/lencx/z/discussions/88
+ 2022-07-01
+ TODO]]>
+
+-
+
+ https://github.com/lencx/z/discussions/25
+ https://github.com/lencx/z/discussions/25
+ 2022-06-10
+
+Hackers & Painters
+作者: 保羅·格雷厄姆 (Paul Graham)
+译: 阮一峰
+
+
+
+
+出于兴趣而解决某个难题,不管它有没有用,这就是黑客。
+
+
+黑客伦理 [hacker ethic]
+
+使用计算机以及所有有助于了解这个世界本质的事物都不应该受到任何限制。任何事情都应该亲手尝试。
+Access to computers-and anything that might teach you something about the way the world works-should be unlimited and total. Always yield to the Hands-On Imperative!
+信息应该全部免费。
+All information should be free.
+不信任权威,提倡去中心化。
+Mistrust Authority-Promote Decentralization.
+判断一名黑客的水平应该看他的技术能力,而不是看他的学历、年龄或地位等其他标准。
+Hackers should be judged by their hacking, not bogus criteria such as degrees, age, race, or position.
+你可以用计算机创造美和艺术。
+You can create art and beauty on a computer.
+计算机使生活更美好。
+Computers can change your life for the better.
+
+根据这六条“黑客伦理”,黑客价值观的核心原则可以概括成这样几点:分享、开放、民主、计算机的自由使用、进步。
+
+
+计算机程序只是文本而已。你选择什么语言,决定了你能说什么话。编程语言就是程序员的思维方式。
+
+
+
+
+阿尔伯蒂 有一句名言:“任何一种艺术,不管是否重要,如果你想要在该领域出类拔萃,就必须全身心投入。”
+
+黑客与画家
+
+
+黑客搞懂“计算理论” [theory of computation] 的必要性,与画家搞懂颜料化学成分的必要性差不多大。一般来说,在理论上,你需要知道如何计算“时间复杂度”和“空间复杂度” [time and space complexity];如果你要写一个解释器,可能还需要知道状态机 [state machine] 的概念;除此以外,并不需要知道特别多的理论。这些可比画家必须记住的颜料成分少很多。
+
+
+因为如果你不爱一件事,你不可能把它做得真正优秀,要是你很热爱编程,你就不可避免地会开发你自己的项目。
+
+
+黑客就像画家,工作起来是有心理周期的。有时候,你有了一个令人兴奋的新项目,你会愿意为它一天工作 16 个小时。等过了这一阵,你又会觉得百无聊赖,对所有事情都提不起兴趣。
+
+
+对于编程,这实际上意味着你可以把 bug 留到以后解决。消灭 bug 对我来说属于轻松的工作,只有在这个时候,编程才变得直接和机械,接近社会大众想象中的编程的样子。消灭 bug 的过程就像解一道数学题,已知许许多多的约束条件,你只要根据条件对方程求解就可以了。你的程序应该能产生 x 结果,但是却产生了 y 结果。哪里出错了?你知道自己最后肯定能够解决这个问题,所以做起来很轻松,就好像刷墙一样,接近于休闲了。
+
+
+“程序写出来是为了让人看懂它的算法,附带告诉计算机如何执行。”一种好的编程语言应该比英语更容易解释软件。只有在那些不太成熟、容易出现问题的地方,你才应该加上注释,提醒读者注意那里,就好像公路上只有在急转弯处才会出现警示标志一样。
+
+
+不能说的话
+
+
+大多数成年人故意让孩子对世界有一个错误的认识。最鲜明的例子之一就是圣诞老人。我们觉得,小孩子相信圣诞老人,真是太可爱了。我本人其实也是这样想。但是,扪心自问,我们向孩子灌输圣诞老人的神话,到底是为了孩子,还是为了我们自己?
+我在这里不讨论这样做是否正确。家长想要塑造孩子的心灵,把他们装扮成可爱的小宝宝,这可能是无法避免的。我也可能这样做。但是,就本文而言,这样做会产生一个重要的结果,那就是孩子“被迫”在一个精心设计的环境中长大。他的头脑或多或少是纯洁无暇的,一点也不知道那些“不能说的话”,从来没有被真实的社会生活“污染”过。孩子眼里的世界是不真实的,是一个被灌输进他们头脑的假想世界。将来当孩子长大以后接触社会,就会发现小时候以为真实的事情,在现实世界中是荒唐可笑的。
+
+
+那些团体神经越紧张,它们所产生的禁止力量就越大。伽利略因为宣布日心说而遭到教廷的审判,这件事讽刺的地方在于,他只是在宣传哥白尼的观点,而后者却安然无恙。事实上,哥白尼不仅不反对教廷,还是一个虔诚的天主教教士,他把自己的著作献给教皇。不幸的是,伽利略正赶上教廷内部反对派上台,宗教改革制度压制,任何非正统的思想遭受到前所未有的严厉控制和禁止。
+为了在全社会制造出一个禁忌,负责实施的团体必定既不是特别强大也不是特别弱小。如果一个团体强大到无比自信,它根本不会在乎别人的抨击。美国人或者英国人对国外媒体的诋毁就毫不在意。但是一个团体太弱小,就会无力推行禁忌。有一种行为怪癖叫做“嗜粪症” [coprophila],它的患者人数以及影响势力眼下似乎就不太强大,无法把自己的观点推广给其他人。
+我猜想,道德禁忌的最大制造者是那些权利斗争中略占上风的一方。你会发现,这一方有实力推行禁忌,同时又软弱到需要用禁忌来保护自己的利益。
+大多数的斗争,不管它们实际上争的是什么,都会以思想斗争的形式表现出来。
+
+
+为什么这样做
+
+
+有人可能会问,为什么要去找出“不能说的话”?为什么要故意打探那些龌龊的,见不得人的思想观点?你明知那里有挡住去路的石头,为什么还要把它们翻过来看个究竟呢?
+首先,我这样做与小孩子翻石头是出于同样的原因:纯粹的好奇心。我对任何被禁止的东西都有特别强烈的好奇心。我要亲眼看一下,然后自己做决定。
+其次,我这样做是因为我不喜欢犯错。如果像其他时代一样,那些我们自以为正确的事情将来会被证明是荒唐可笑的,我希望自己能够知道是哪些事情,这样可以使我不会上当。
+再次,我这样做,是因为这是很好的脑力训练。想要做出优秀作品,你需要一个什么问题都能思考的大脑。尤其是那些似乎不应该思考的问题,你的大脑也要养成思考它们的习惯。
+优秀作品往往来自于其他人忽视的想法,而最被忽视的想法就是那些被禁止的思想观点。
+
+
+“守口如瓶”的真正缺点在于,你从此无法享受讨论带来的好处了,讨论一个观点会产生更多的观点,不讨论就什么观点也没有。所以,如果可能的话,你最好找一些信得过的知己,只与他们畅所欲言、无所不谈。这样不仅可以获得新观点,还可以用来选择朋友。能够一起谈论“异端邪说”并且不会因此气急败坏的人,就是你最应该认识的朋友。
+
+
+你不仅要远距离观察人群,更要远距离观察你自己。顺便提一句,这可不是激进的想法。儿童和成年人的主要差别就在这里。儿童精疲力竭时,可能会大发脾气,因为他不知道为了什么;成年人则会了解是个人的身体状况问题,与外界无关,说一句“没关系,我只是累了”。我想,通过类似的机制,一个人完全可以识别和抵制外界流行的道德观念,把它们与内心世界相分离。
+如果你想要清晰的思考,就必须远离人群。但是走的越远,你的处境就会越困难,受到的阻力也会越大,因为你没有迎合社会习俗,而是一步步地与它背道而驰。小时候,每个人都会鼓励你不断成长,变成一个心智成熟、不再耍小孩脾气的人。但是,很少有人鼓励你继续成长,变成一个怀疑和抵制社会错误潮流的人。
+如果自己就是潮水的一部分,怎么能看见潮流的方向呢?你只能永远保持质疑。问自己,什么话是我不能说的?为什么?
+
+
+另一条路
+
+
+如果软件的新版本要等一年后才能发布,我就会把大部分新构思束之高阁,至少过上一段时间再来考虑。但是,构思这种东西有一个特点,那就是它会导致更多的构思。你有没有注意过,坐下来写东西的时候,一半的构思是写作时产生的?软件也是这样。实现某个构思,会带来更多的构思。所以,将一个构思束之高阁,不仅意味着延迟它的实现,还意味着延迟所有在实现过程中激发的构思。事实上,将一个构思束之高阁,甚至会限制新构思的产生。因为你看一眼堆放在一边、还没实现的构思,就会想“我已经为下一个版本准备了很多新东西要实现了”,你就懒得再去思考更多的新功能了。
+
+
+现在,创业公司有更多的理由选择互联网软件创业,因为开发桌面软件越来越乏味了。如果你现在开发桌面软件,就不得不接受微软公司的授权条款,调用它的 API,为它那个 bug 百出的操作系统伤透脑筋。历尽千辛万苦,你最终写出了一个受大众欢迎的软件,这时你可能会发现,你所做的一切其实只是在为微软公司做市场调查。
+
+
+你能够做到这一点,意味着竞争者也能做到这一点,所以长时间工作变成了一种必须,不得不如此。因为你能做到,所以你必须做到
。这简直就是逆向的帕金森定律
+
+
+不少公司都很想知道,什么事情可以外包,什么事情不可以外包,一个可能的答案是,公司内部所有不直接感受的竞争压力的部门都应该外包出去,让它们暴露在竞争压力之下。(我这里所说的“外包”,指的是聘请另一家公司来执行,而不是指把业务部门转移到海外。)
+
+
+由于个人经历的关系,特雷弗·布莱克韦尔对这一点的认识可能比其他任何人都深刻。他写到:“我会进一步说,由于互联网软件的程序员非常辛苦,所以会使得经济优势根本性地从大公司向创业公司转移。互联网软件要求的那种工作强度和付出,只有当公司是其本人所有时,程序员才愿意提供。软件公司可以雇用到能干的人,让他们去干轻松的事情,也可以雇到不能干的人,让他们去干艰苦的事情。但是无法雇到非常能干的人,让他们去干非常艰苦的事情。因为互联网软件的创业不需要太多的资本,所以大公司可以与创业公司竞争的优势就所剩无几了。”
+
+
+如何创造财富
+
+
+交换媒介的优点是,它使得交易可以进行下去。缺点是,它往往模糊了交易的实质。人们觉得做生意就是为了挣钱,但是金钱其实只是一种中介,让大家可以更方便地获得自己想要的东西。大多数生意的目的是为了创造财富,做出人们真正需要的东西。
+
+
+金钱不是财富,而只是我们用来转移财富所有权的的东西。
+
+
+公司就是许多人聚在一起创造财富的地方,能够制造更多人们需要的东西。
+
+
+我们这个世界,你向下沉沦或者向上奋进都取决于你自己,不能把原因推给外界。
+
+
+一个大学毕业生总是想“我需要一份工作”,别人也是这么对他说的,好像变成某个组织的成员是一件多么重要的事情。更直接的表达方式应该是“你需要去做一些人们需要的东西”。即使不加入公司,你也能做到。公司不过是一群人在一起工作,共同做出某种人们需要的东西。真正重要的是做出人们需要的东西,而不是加入某个公司。
+对于大多数人来说,最好的选择可能是为某个现存的公司打工。但是,理解这种行为的真正含义对你没有什么坏处。工作就是在一个组织中,与许多人共同合作,做出某种人们需要的东西。
+
+
+要致富,你需要两样东西:可测量性
和可放大性
。你的职位产生的业绩,应该是可测量的,否则你做的再多,也不会得到更多的报酬。此外,你还必须有可放大性,也就是说你做出的决定能够产生巨大的效应。
+
+
+如果你有一个令你感到安全的工作,你是不会致富的,因为没有危险,就几乎等于没有可放大性。
+
+
+乔布斯曾经说过,创业的成败取决于最早加入公司的那十个人。我基本同意这个观点,虽然我觉得真正决定成败的其实 只是前五人。小团队的优势不在于它本身的小,而在于你可以选择成员。我们不需要小村庄的那种“小 ”,而需要全明星第一阵容的那种“小”。
+
+
+什么是技术?技术就是某种手段,就是我们做事的方式。如果你发现了一种做事的新方式,它的经济价值就取决于有多人使用这种新方式。技术就是钓鱼的鱼竿,而不是那条鱼。
+
+
+只要懂得藏富于民,国家就会变得强大。让书呆子保住他们的血汗钱,你就会无敌于天下。
+
+
+“财富”这个词有很多意思,有些并不是指物质财富。我不想做深入讨论,研究到底什么才是真正的财富。我这里指的只是一种特定的技术层面上的“财富” ——人们用金钱向你交换东西。这是一种很有趣、很值得研究的财富,因为它使得你免于饥饿,而且人们是否用金钱交换这种财富取决于他们,而不是取决于你。
+
+
+关注贫富分化
+
+设计者的品味
+
+
+对于建筑师和设计者,它意味着美依赖于一些精心选择的结构性元素,而不是依赖于表面装饰品的堆砌。(装饰品本身并不是坏事,只有它被用来掩盖结构的苍白时,才变成了一件坏事。)
+
+
+如果解决方法是丑陋的,那就肯定还有更好的解决方法,只是还没有发现而已。
+
+
+白描其实是最难画的视觉媒介,因为它们要求近乎完美的再现。用数学语言说,线条属于闭合解 [closed-form-solution],水平不够的艺术家没有办法直接解决问题,只能通过不断逼近来求解。
+
+
+人们有时会说自己有了“状态”,我的理解是,他们这时可以控制自己的脊髓。脊髓是更本能的反应,面对难题时,它能释放你的直觉。
+
+
+好设计是模仿大自然的设计。我不是说模仿大自然这种行为本身有多么好,而是说大自然在长期的演化中已经解决了很多设计问题。所以,如果你的设计与大自然很接近,那么它基本上不会很差。
+
+
+一百年后的编程语言
+
+
+在长期的职业生涯中,我发现冗余的代码会导致更多冗余的代码,不仅软件如此,而且像我这样性格懒散的人,我发现在床底下和房间的角落里这个命题也成立,一件垃圾会产生更多的垃圾。
+
+
+编程语言进化缓慢的原因在于它们并不是真正的技术。语言只是一种书写法,而程序则是一种严格符合规则的描述,以书面形式记录计算机应该如何解决你的问题。所以,编程语言的进化速度更像数学符号的进化速度,而不像真正的技术(比如交通或者通信技术)的进化速度。数学符号的进化是缓慢的渐变式变化,而不是真正技术的那种跳跃式发展。
+
+
+我已经预测到了,一旦未来硬件的性能大幅提高将会发生什么事。新增加的运算能力都会被糟蹋掉。
+在我学习编程的年代,计算机还是稀罕玩意。我记得当时使用的微机型号是 TRS-80,它的内存只有 4K,为了把 BASIC 程序装入内存,我不得不把源码中的空格全部删除。我一想到那些极其低效率的软件,不断重复某些愚蠢的运算,把硬件的计算能力全部占用,就感到无法忍受。但是,我的这种反应是错的,我就像某个出身贫寒的穷孩子,一听到要花钱就舍不得,即使把钱用在重要场合(比如去医院看病)都会觉得难以接受。
+
+
+书呆子的复仇
+
+如果你想在软件业获得成功,就使用你知道的最强大的语言,用它解决你知道的最难的问题,并且等待竞争对手的经理做出自甘平庸的选择。
+
+梦寐以求的编程语言
+
+
+编程语言不是存在于真空之中,“编程”其实是及物动词,黑客一般都是为某个系统编程。在现实中,编程语言总是与它们依附的系统联系在一起的。
+
+
+无法以一种语言本身的优缺点评判这种语言。另一个结果则是,只有当一种语言是某个系统的脚本语言时,它才能真正成为编程语言。如果你对此很吃惊,觉得不公平,那么我会跟你说不必大惊小怪。这就好比大家都认为,如果一种编程语言只有语法规则,没有一个好的实现 [implementation],那么它就不能算完整的编程语言。这些都是很正常很合理的事情,编程语言本来就该如此。
+
+
+你只需要不停地重复同一句话,最终人们将会开始倾听。人们真正注意到你的时候,不是第一眼就看到你站在那里,而是发现过了这么久你居然还在那里。
+
+
+著名散文家 E.B. 怀特说过,“最好的文字来自不停的修改”。
+
+
+为了写出优秀软件,你必须同时具备两种相互冲突的信念。一方面,你要像初生牛犊一样,对自己的能力信心万丈;另一方面,你又要像历经沧桑的老人一样,对自己的能力抱着怀疑态度。在你的大脑中,有一个声音说:“千难万险只等闲”,还有一个声音却说“早岁哪知世事艰”。
+这里的难点在于你要意识到,实际上两种信念并不矛盾。你的乐观主义和怀疑倾向分别针对两个不同的对象。你必须对解决难题的可能性保持乐观,同时对当前解法的合理性保持怀疑。
+做出优秀成果的人,在做的过程中常常觉得自己做得不够好。其他人看到他们的成果觉得棒极了,而创造者本人看到的都是自己作品的缺陷。这种视角的差异并非偶然,因为只有对现状不满,才会造就杰出的成果。
+
+
+因此现实中,尽管软件功能越来越强大,内部接口却往往一成不变,成为整个系统中拖后腿的部分。
+一种可能的解决方法是,将软件内部的接口设计成垂直接口而不是水平接口。这意味着软件内部的模块是一个个垂直堆积起来的抽象层,层与层之间的接口完全由其中的一层控制。如果较高的一层使用了较低的一层定义的语言,那么接口就由较低的一层控制;如果较低的一层从属于较高的一层,那么接口就由较高的一层控制。
+
+
+帕金森定律 [Parkinson's Law] 的一种原始表达形式是“工作总是到最后一刻才会完成”,后来引申到计算机领域就变成了“数据总是会填满所有的空间”,更一般性的总结则是:“对一种资源的需求总是会消耗光这种资源的所有供应”。
+
+
+设计与研究
+
+
+设计与研究的区别看来就在于,前者追求“好” [good],后者追求“新” [new]。优秀的设计不一定很“新”,但必须是“好”的;优秀的研究不一定很“好”,但必须是“新”的。我认为这两条道路最后会发生交叉:只有应用“新”的创新和理论,才会诞生超越前人的最佳设计;只有解决那些值得解决的难题(也就是“好”的难题),才会诞生最佳研究。所以,最终来说,设计和研究都通向同一个地方,只是前进的路线不同罢了。
+
+
+怎么理解编程语言?你不要把它看成那些已完成的程序的表达方式,而应该把它理解成促进程序从无到有的一种媒介。这里的意思是说,成品的材料和开发时用的材料其实是不一样的。搞艺术的人都知道,这两个阶段往往需要不同的媒介。比如,大理石是一种非常良好、耐用的材料,很适合用于最后的成品,但是它极其缺乏弹性和灵活性,所以不适合在构思阶段用来做模型。
+最后写出来的程序就像已经完成的数学证明一样,是一棵经过精心修剪的树木,上面杂乱滋生的树杈 都已经被剪去了。所以,评价一种语言的优劣不能简单地看最后的程序是否表达得很漂亮,而要看程序从无到有的那条完成路径是否很漂亮。
+
+
+画家之间甚至流传着一句谚语:“画作永远没有完工的一天,你只是不再画下去而已。”
+
+
+“弱即是强”指的是一种软件传播的模式,由 Common Lisp 专家里查德·加布里埃尔 [Richard P. Gabriel] 于 1991 年在 Lisp: Good News, Bad News, How to Win Big 一文中首先提出。它的含义非常广泛,涉及软件设计思想的各个方面,其中的一个重要结论就是软件功能的增加并不必然带来质量的提高。有时候,更少的功能(“弱”)反而是更好的选择(“强”),因为这会使得软件的可用性提高。相比那些体积庞大、功能全面、较难上手的软件,一种功能有限但易于使用的软件可能对用户有更大的吸引力。加布里埃尔本人经常举 Unix 和 C 语言的例子,Unix 和 C 在设计上考虑了实际环境,放弃了一些功能,但是保证了简单性,这使得它们最终在竞争中胜出,成为主流操作系统和编程语言。
+
+
+术语解释
+
+抽象 [abstract]
: 隐藏细节。编程语言越抽象,你写出程序所需的运算步骤就越少,每一步的功能就越强。
+算法 [algorithm]
: 完成任务的方法。
+Blub 困境 [Blub Paradox]
: 程序员的思想往往会受到自己正在使用的语言的束缚,不相信还存在更强大的语言。
+复杂性 [complexity]
: 算法的“时间复杂性” [time complexity] 指的是,当输入的数据量不断增加时,计算机完成过这种算法所消耗的时间
+散列表 [hash table]
: 一种类似数据库的数据结构,存储在里面的每一段数据都有一个对应的键,使用时只要按照键名就可以取出对应的数据。
+函数库 [library]
: 已经写好的代码片段,可以用来执行特定任务。
+宏 [macro]
: 一个能够生成其他程序的程序。
+元循环 [metacircular]
: 当一种语言的解释器用这种语言本身开发时,就会出现这种情况。与其说这是为了做出这种语言的一种实现,还不如说这是描述语言的一种技巧。
+方法 [method]
: 面向对象编程中充当某个类的属性的一个子程序。
+模块 [module]
: 一组子程序和变量,它们可以被视为是一个整体。通常情况下,模块外部的代码只能访问模块内部一部分专门对外公开的子程序和变量
+目标码 [object code]
: 编译器产生的机器语言。
+面向对象 [OO: object-oriented]
: 一种组织程序的方式。假定不同的类代表不同类型的数据,那么针对这些数据执行某种特定任务的代码,可以根据数据的不同被分别写进不同的类,成为这些类的方法。
+正交的 [orthogonal]
: 彼此独立、能够以多种方式组合在一起的一组东西。(乐高积木)
+解析器 [parser]
: 读取输入的数据然后生成解析树的程序。
+解析树 [parser tree]
: 解析器读取源码后生成的数据结构。它是将源码翻译成机器语言的第一步。
+管道 [pipe]
: 将操作系统的各种命令连接起来的一种方式,使得一个命令的输出变成另一个命令的输入。
+指针 [pointer]
: 一块数据,它的值是另一块数据的内存地址。
+进程 [process]
: 在同时运行多个程序的操作系统中,同时被运行的程序之一。
+质量保证 [QA: Quality Assurance]
: 软件行业中负责找出和登记 bug 的人。
+递归 [recursive]
: 一种调用自身的算法。
+ ]]>
+
+-
+
+ https://github.com/lencx/z/discussions/74
+ https://github.com/lencx/z/discussions/74
+ 2022-06-10
+
+此语录,无任何意义,仅记录生活中的所思所感...
+
+学习
+
+要学会把问题交给搜索引擎,而不是把群友当成搜索引擎。
+同样一个问题,用百度和 Bing (有能力的用 Google ) 对比一下就知道了。
+学习技术,先扫一遍文档,从最基本的开始搭建学习,功能一点点的增加进来。边看边实践,敲键盘也会加深记忆。
+优秀一天容易,难的是一直优秀。
+一篇好文章,更像是一根线,而不是一团麻。极客精神,以风趣幽默的方式解释清楚一切细节。
+学到一句话:经验这个东西,就是越多越好,可以不去做,但是不能不知道。
+有问题不可怕,可怕的是,不知道怎么和问题去相处。
+答案是最无用的东西,因为它是一个问题的处理结果,是由过程分析推理得出来的,过程推理不出,而选择去背答案是最无效的学习方式,毫无意义!
+学习就是从懵逼到膨胀的一个死循环 🔄
+以后再也不敢说自己是在自学了。没有基础作为指导,只能算是瞎学,乱学。看完《自学计算机科学》 这份书单,才发现自己对计算机一无所知。
+真正的高效工作,是首先先学会如何解放自己。
+骨头是不好啃,自己要先啃几口,才有发言权。别还没啃,就说太硬了。(软饭吃多了,牙也变软了)
+遇到问题自己不思考,不尝试,就没有资格把这个问题抛出来。(踢皮球并不能让自己成长)
+学会自我总结, 一步一个脚印,别总想着有人可以帮你。(外力终究不是自己的)
+知识就是这样的,会一点点进入你的视野。但是前提,你要保持好奇心,并且不断地尝试。
+人的思想蜕变,不是一瞬间产生的,而是不断起伏的人生带给你的。
+学习是自己的事情(信息的收发建立在共识之上),没有人可以真正帮助你。有所收获,最该感谢的人其实是自己。
+学习是一件痛苦的事情,开始享受这个过程,或许就是自己在努力汲取养分生长吧。
+
+思考
+
+学习其实就是用到什么学什么,能否快速掌握一门技术,和你学了多少门技术其实没有太大关系(要学的东西应该是技术背后的通用思想)。分析,思考,解决问题的能力,也并不是你接触的技术所能带给你的。因为知识是死的,而人却是活的,所以这些能力的培养和养成其实是一个主动行为。未知知识学习 = 拓展阅读(已有知识中的未知部分) + 信息源(领域大牛)+ 已有知识 + 经验推导
+有人问我该如何学习,其实我也不知道,当我迷茫时,就强迫自己静下心来写一个项目,不断地解决问题,然后就会变得很享受。问题不是凭空出现的,遇到的时候,你就会去搜寻各种解决方案,这就是学习。有些人最大的问题就是在遇到问题时第一时间把问题抛给别人,把群友当成搜索引擎。没有思考,没有尝试,也就不能够形成自己解决问题的方法论。
+人最大的价值就是没有价值,做任何事的意义就是毫无意义。
+
+日常
+
+知识就摆在那里,想学的会想尽办法会去寻找,没必要去投喂。
+感谢所有夸我的人,说句实话,我不 NB,在技术群里,大部分人的能力都要比我强,我只是比较张扬而已。
+任何话题都是技术交流,代码不是全部。
+不信鬼神,但对未知还是要保持敬畏之心。
+群里虽然前端居多,似乎更应该发和前端相关的内容。但一切皆知识,路应该越走越宽。专精于 xxx 或许没错,但只有 xxx,视野过于被局限,会少了很多灵感碰撞及其他可能性。(广度与深度该如何抉择)
+彩票属于不确定的意外之财,讨论这个没啥意义。运气不是每个人都有的,现实点。(学会自我催眠)
+我写的文章没啥技术含量,手撕不动,脑子也不怎么灵活,基础更是一塌糊涂。
+我想明白了一些事情:欲望就好比握在手中的沙子,不握紧,会流失。握紧了,只会流的更快。因为想要获得,各种复杂的情绪就产生了,兴奋,焦虑… 如果放弃了所有的欲,一切便会回归于无。
+当一些东西变得重复与机械的时候,也就失去了原本的兴趣。
+自省只是不想让自己太飘,因为人是社会性动物,他人的评价或多或少都会对自己产生影响。
+知识,技术可以变现,但是丢掉原则,就不再是一个技术人了。
+本以为自己只是走了两三年的弯路,谁知从未走出...
+开源其实是一件很简单的事情,你想做,就可以去做。
+人更喜欢相信自己看到的。很少有人去思考,你所看到的是不是别人故意给你看的?(眼见不一定为实)
+以前我也认为只要学会独立思考就够了,但是后来我发现,如果你所看到的一切都是假象,那么基于它做出思考将是一件可怕的事情。(价值观坍塌)
+眼界,思考,质疑,都很重要。
+当对一切失去了怀疑的态度,会让你觉得它就是权威,不会出错。这是很可怕的事情。(盲目崇拜)
+做你认为对的事情,就不存在浪费时间一说。
+有人说:“大多数的成功来源于勇气,似乎越成熟,越丧失了追求的勇气”。但是我认为不是越活越没勇气,而是人学会了算计,会去计较得失,才变得畏手畏脚。(冲动是魔鬼,太过于理智,生活也就少了一些色彩)
+一定要学会享受过程。结果很重要,但是如果真的有一天你可以直接到达这个结果的时候,未必是快乐的。(出生的结局就是死亡)
+没有学会取舍,才会让自己那么累。(放下也是一种智慧)
+我不想努力了,可是没钱。钱不是那么重要,但是没有它,可能会过的很惨。(衣食住行)
+这个世界是动态的,一切都在变化,人也如此。(保持初心)
+穷爸爸富爸爸 告诉我们,起点大于努力。(生的好也很重要)
+
+吐槽
+
+做任何事都是需要指标的,没有高标准,就不会把事情做到极致。但是国内忽视了一些东西,或者说不愿意去面对实际场景,“拍脑袋”和“我以为”就是标准。KPI 最终沦为了老板们的大屏数据,似乎数据代表一切...
+说句难听的,国人有能力的不少,但是创造的东西,真不咋样,很难有思维上的突破,到处都是“借鉴”。
+国外做开源的很多可能就是个学生,普通程序员,没啥 title,吊打国内一大批程序员;级别,title 是越封越高,能力倒是没见涨。
+国人不务实,很多都是面子工程,这莫非是大环境“造就”的?
+这两年看到比较多的消息就是 xxx 开源库作者因精力有限,放弃对其的维护工作。这都是白嫖,不返哺社区的结果。
+某度搜索并不适合程序员,查找问题效率低下,结果百分之八九十都是垃圾。(工具很重要)
+一个技术社区如果东西“杂了”,技术就变得不再纯粹。(四不像)
+Node 再卷,感觉都要卷到 V8 ,C++ 了,而我只是个前端切图仔。
+技术如果不纯粹就会变得畸形,写文章首要目标是思考沉淀,其次是分享传播帮助他人,最后才会考虑技术变现,但很多所谓的“作者”似乎本末倒置了。
+看似是要求越来越低,实则社会在教我做人。(认清现实)
+轮子哥,造轮子的速度比我用轮子的速度还快。(与大佬的差距)
+垃圾公众号看多了,人都变傻了。天天卖课,真烦...
+公众号其实就是收割流量的,既然那么多干货,为啥不写成 blog,因为写成 blog 就没多少干货了,公众号基本百分之七八十都是在转载,写成 blog 哪有那么多文章。如果你关注了 100 个前端公众号,一篇文章你起码可以在几十个公众号看到,有啥意义?还有一大堆是卖课的。一百个能有十个,可能都是比较乐观的估计,十不存一...
+我觉得很多人就喜欢混为一谈,学习的本质是为了什么?是为了吃透一门技术,掌握一门技能,还是说只是为了更好的赚钱。(多问问自己想要什么)
+最近做项目的一些体会。代码如何不腐,单从代码层面很难解决。
你可以去预留接口,提高可扩展性,但是抵不住需求从一个东西变成另一个东西,还非要表现出是一个东西的那种状态。
真要系统健壮,以及可扩展,需要的是多方配合,而不是自己搞自己的,需求自己随便提,后端按自己的想法自己定数据结构,前端天天跟着设计跑,换颜色,换交互。各种场景不做收拢,梳理。说句难听的,即使新开项目,一年项目就是一坨屎,到后面就是牵一发动全身,开发委屈说,时间不够,需要 review 的东西太多。业务觉得你不够努力,这么简单的需求你要搞那么久?这就是现状。。。
+
+非原创
+
+科技造神的祭坛下,是无数沉迷于低级娱乐与表面思考的终端消费者。但他们不得不为此付费,甚至久而久之,他们会下意识地维护这套病态逻辑。
+编程的历史就是“更少代码”的历史:寻找更好的抽象,并构建库来实现这些抽象。
+No problem can be solved from the same level of consciousness that created it. (重大问题的解决方案永远不可能在产生这个问题的维度出现。) -- Albert Einstein
+ ]]>
+
+-
+
+ https://github.com/lencx/z/discussions/2
+ https://github.com/lencx/z/discussions/2
+ 2022-06-06
+ 👋 Welcome!
+学无止境
+您可以访问网站,有更好的阅读体验: 浮之静
+仓库历史
+
+这个仓库经历过数次大改版,从换名到换技术栈...
+
+2021.07.01 - 至今
+z
-【〽️ 浮之静 - 学无止境】
+取 fzj
的中间字母,z
是一个很有意思的字母,像弹簧,蓄力愈久,反弹的力量就愈大。很符合 «浮之静» 之本意。
+2021.05.24 - 2021.07.01
+fzj
- 【🌊 浮之静 - 源于前端,但不止于前端】
+技术栈 - vite + react + github discussions api
+2021.05.23 - 2021.05.24
+sea
-【🌊 学海无涯】
+技术栈 - vitepress
+2020.08.23 - 2021.05.17
+mtc
- 【😎 My tools & config, and awesome lists】
+技术栈 - vuepress
,v2.0
基于 vitepress
+
+推荐系列
+]]>
+
+-
+
+ https://github.com/lencx/z/discussions/87
+ https://github.com/lencx/z/discussions/87
+ 2022-06-06
+
+不看文档,习惯性把已有经验带入到新语言学习中,感觉学习了很多门语言,本质上都在用同一个思维模式解决问题 ...
+
+📅 2022.06.06
+大橙子的小迪子🍊:
+let a = ‘abc’
+大橙子的小迪子🍊:
+a[0]
+大橙子的小迪子🍊:
+@lencx rust不允许这样取呀
+lencx:
+肯定不行啊
+lencx:
+单引号是 char 类型
+大橙子的小迪子🍊:
+字符串可以吗
+lencx:
+看文档
+lencx:
+写代码不是靠猜啊
+lencx:
+rust 取索引是通过 .
+lencx:
+比如 a.0
+大橙子的小迪子🍊:
+那这个是不是取的字节索引
+lencx:
+这种问题自己搜 一下不就知道了
+大橙子的小迪子🍊:
+好的
+大橙子的小迪子🍊:
+这个变化挺大的
+lencx:
+学新语言是可以通过对比去学习,但是不能硬套啊,每种语言都有自己的心智模型,而不是写 Rust 版的 JS…
+lencx:
+看文档就是学习该语言的表达方式
+不精通react不改名:
+rust版本的js在哪在哪
+lencx:
+而不是靠经验去猜,毫无意义
+大橙子的小迪子🍊:
+这个括号里面的数字代表的是字节索引吧
+lencx:
+用 js 的思维方式写 rust,不就是 rust 版的 js 吗
+不精通react不改名:
+确实
]]>
+
+-
+
+ https://github.com/lencx/z/discussions/86
+ https://github.com/lencx/z/discussions/86
+ 2022-09-27
+ 📅 2022.04.09
+lencx:
+写代码其实不难,难的是搞不清楚问题
+lencx:
+大部分写不下去都是因为自己根本不知道自己写的是个什么东西
+浦原:
+这个我深有感触
+浦原:
+写不下去就真的是单纯不知道问题出在哪里
+lencx:
+学习其实也是这样,用什么语言不重要啊,重要的是你的逻辑要清楚,剩下的事情搜索引擎帮你搞定,基本可以解决百分之八九十的问题
+lencx:
+只有少部分极难的问题,靠搜索很难搞定,这就牵扯到你的知识推导能力了
+lencx:
+经验都是虚的,没啥用
+lencx:
+因为经验会过时,会遗忘,知识的推导过程其实就是你的逻辑思维具像化
+lencx:
+我是这么认为的
]]>
+
+-
+
+ https://github.com/lencx/z/discussions/85
+ https://github.com/lencx/z/discussions/85
+ 2022-06-01
+
+高效使用命令行是程序员必备的技能
+
+以下资源均被收录在 lencx/awesome(关于各种有趣主题的精彩列表) ,包含 weekly,rust, webAssembly,js,css,tools 等不同主题。
+zsh
+Oh My Zsh - Oh My zsh 是一个开源的、社区驱动的框架,用于管理您的 zsh 配置。
+
+
+bat
+bat - 类似 cat(1),但带有 git 集成和语法高亮。
+
+fd
+fd - 是一种简单快速和用户友好的 find
替代方案。
+
+git
+gh
+gh - GitHub CLI 或 gh 是 GitHub 的命令行界面,可在您的终端或脚本中使用。
+
+gix
+gix - gix 是用于访问 git 存储库的命令行界面 ( CLI )。它是为了优化用户体验而编写的,其性能与规范实现一样好或更好。此外,它以各种小型 crate
的形式提供了一个简单且安全的 API ,用于轻松实现自己的工具。
+dura
+dura - Dura 是一个后台进程,它监视您的 Git 存储库并提交您未提交的更改,而不会影响 HEAD、当前分支或 Git 索引(暂存文件)。如果您遇到异常导致工作内容丢失,进入 dura 分支可以恢复。如果没有 dura,可以在编辑器中使用 Ctrl-Z
来恢复状态。2021 年就是这样。计算机崩溃,Ctrl-Z
只能独立处理文件。Dura 快照随时更改整个存储库,因此可以恢复到“4 小时前”而不是“按 Ctrl-Z 40 次或其他”。
+delta
+delta - 用于 git
、diff
和 grep
输出的语法高亮分页器。
+
+tig
+tig - Git 的文本模式界面。
+
+git-journal
+git-journal - Git 提交消息和变更日志生成框架。
+
+ls
+exa
+exa - 是 ls
的现代替代品。
+
+lsd
+lsd - 下一代 ls
命令。
+
+nat
+nat - 具有有用信息和色彩的 ls
替代品。
+
+just
+just - 是保存和运行项目的特定命令的简便方法,其语法受 make
启发。
+
+Asciinema
+asciinema - 是一个免费的开源的轻量级、纯文本终端录制方法。以正确的方式记录和分享您的终端会话。
+
+fff
+fff - 用 bash 编写的简单文件管理器。
+
+Watchexec
+watchexec 是一个简单的独立工具,它监视路径并在检测到修改时运行命令。
+
+Ripgrep
+ripgrep - 是一种面向行的搜索工具,它递归地在当前目录中搜索正则表达式模式。默认情况下,ripgrep 将遵守 gitignore 规则并自动跳过隐藏文件/目录和二进制文件。
+
+Hexyl
+hexyl - 是一个简单的终端十六进制查看器。它使用彩色输出来区分不同类别的字节(NULL 字节、可打印的 ASCII 字符、ASCII 空白字符、其他 ASCII 字符和非 ASCII)。
+
+Zellij
+zellij - 是一个面向开发人员、面向运维的人员和任何喜欢终端的人的工作区。它的核心是一个终端多路复用器(类似于 tmux 和 screen ),但这仅仅是它的基础设施层。
+
+Image
+cavif
+cavif - AVIF 图像的编码器/转换器,纯 Rust 实现。
+cavif --quality 60 image.png
+svgcleaner
+svgcleaner - 清理 SVG 文件中不必要的数据。
+svgcleaner --indent=2 --paths-coordinates-precision=5 --join-arcto-flags=yes in.svg out.svg
+CSV
+xsv
+xsv 是一个用于索引、切片、分析、拆分和连接 CSV 文件的命令行程序。
+$ xsv stats worldcitiespop.csv --everything | xsv table
+field type min max min_length max_length mean stddev median mode cardinality
+Country Unicode ad zw 2 2 cn 234
+City Unicode bab el ahmar Þykkvibaer 1 91 san jose 2351892
+AccentCity Unicode Bâb el Ahmar ïn Bou Chella 1 91 San Antonio 2375760
+Region Unicode 00 Z9 0 2 13 04 397
+Population Integer 7 31480498 0 8 47719.570634 302885.559204 10779 28754
+Latitude Float -54.933333 82.483333 1 12 27.188166 21.952614 32.497222 51.15 1038349
+Longitude Float -179.983333 180 1 14 37.08886 63.22301 35.28 23.8 1167162
+csview
+csview - 带有 cjk /emoji 支持的 cli 的漂亮 csv 查看器。
+
+Tokei
+tokei - 是一个显示代码统计信息的程序。 Tokei 将显示文件数、这些文件中的总行数以及按语言分组的代码、注释和空白。
+===============================================================================
+ Language Files Lines Code Comments Blanks
+===============================================================================
+ BASH 4 49 30 10 9
+ JSON 1 1332 1332 0 0
+ Shell 1 49 38 1 10
+ TOML 2 77 64 4 9
+-------------------------------------------------------------------------------
+ Markdown 5 1355 0 1074 281
+ | - JSON 1 41 41 0 0
+ | - Rust 2 53 42 6 5
+ | - Shell 1 22 18 0 4
+ (Total) 1471 101 1080 290
+-------------------------------------------------------------------------------
+ Rust 19 3416 2840 116 460
+ | - Markdown 12 351 5 295 51
+ (Total) 3767 2845 411 511
+===============================================================================
+ Total 32 6745 4410 1506 829
+===============================================================================
+procs
+procs - 是用 Rust 编写的 ps 的替代品。
+
+eva
+eva - 简单的计算器 REPL,类似于 bc(1),具有语法高亮和持久历史记录。
+
+hyperfine
+hyperfine - 命令行基准测试工具。
+
+ffsend
+ffsend - 从命令行轻松安全地共享文件。 一个功能齐全的 Firefox Send 客户端。
+
+alacritty
+alacritty - 是一个现代终端仿真器,具有合理的默认值,但允许进行广泛的配置。 通过与其他应用程序集成,而不是重新实现它们的功能,它设法提供了一组灵活的高性能特性。 目前支持的平台包括 BSD、Linux、macOS 和 Windows。
+
+Node.js
+nvm
+nvm - 允许您通过命令行快速安装和使用不同版本的 Node.js
。
+
+fnm
+fnm - 快速简单的 Node.js
版本管理器,基于 Rust 实现。
+
+volta
+Volta - 快速无缝地安装和运行任何 JS 工具! Volta 是用 Rust 构建的,以二进制文件形式发布,跨平台支持(macOS、Windows、Linux)。
+
]]>
+
+-
+
+ https://github.com/lencx/z/discussions/83
+ https://github.com/lencx/z/discussions/83
+ 2022-06-01
+ 📅 2022.02.23
+Ice:
+这种代码怎么优化一下
+
+lencx:
+策略模式
+Ice:
+什么意思
+lencx:
+额,或者 switch
+lencx:
+其实 if 也还好吧
+Ice:
+要写好长if
+lencx:
+其实这么写条件不好
+Ice:
+那我该怎么写
+lencx:
+最好是把校验规则抽象出来
+lencx:
+至于校验规则怎么抽象,需要看业务需求
+Ice:
+我就判断每一行的单元格不能为空保存的时候
+张浩:
+switch
+张浩:
+据说性能会很高
+lencx:
+其实我建议根据需求把规则做抽象,每个字段对应的校验文案其实是固定的,然后就是一个拼装问题
+lencx:
+但是过度抽象反而不如 if 这种更直白,所以需要自己权衡一下未来需求的迭代,保证一定的可扩展性
+lencx:
+其实就是做一个通用的校验器
+lencx:
+只需要接收数据源就可以返回校验文案
+lencx:
+以及是否通过的状态
+lencx:
+举个例子,看你这个截图,其实每个字段都对应一个文案,比如最高分,最低分,然后通过逗号连接,不能为空!
+这就是规则:aaa, bbb, ccc 不能为空!
+aaa, bbb, ccc 可以通过数组做收集
+Ice:
+是噢
+张浩:
+哦,然后封装一个方法,循环这个规则数组,如果有一项false,直接返回具体原因
+张浩:
+否则返回true?
+lencx:
+数组做收集,你只需要对字段做遍历就好了,不满足的就收集。
+张浩:
+哦哦
+lencx:
+这个看个人,实现方法有很多,我只是举例而已。
+张浩:
+好的学习了
+柒冉:
+学到了
+lencx:
+这样你可以针对分数写一个校验器,只接收数据源,然后返回处理结果,后期需求变更,只需要重新实现校验器即可。数据做好格式化输出。你的校验器对调用者来说就是一个黑盒。
+张浩:
+大佬,那如果是一个表单,里面有很多条件,那种校验应该如何封装比较好
+张浩:
+也要对每个字段分别封装吗
+lencx:
+一样的思路,核心思想就是做到:UI,Data, 业务逻辑之间的解耦。按照这个思路去拆。函数式编程思想。
+张浩:
+嗯嗯,我想下
+lencx:
+你抽象的东西就是一个黑盒,保证输入,输出源的一致性,内部怎么实现我并不关系。
+张浩:
+嗯嗯
+lencx:
+这个没有什么通用式,一站式解决方案,多写,多思考,自己慢慢就找到感觉了,当你觉得某个地方的代码特别繁琐,改起来很复杂,牵一发而动全身,一般就是对代码结构的思考有所欠缺了。
+张浩:
+嗯嗯
+张浩:
+感觉自己还是抽象的不够彻底,每次都是写完代码之后,发现,这地方为啥不抽个方法出来。。。。
+lencx:
+代码都是边写边优化的,过早优化,可能会导致扩展性不足。
+lencx:
+反而越改越麻烦
+张浩:
+嗯嗯
+lencx:
+写代码的一般流程:
+先实现功能 -> 找代码共性 -> 思考优化 -> 重构
+比较厉害的,可以根据自己的经验给未来的需求留出口子,方便扩展
+张浩:
+我都是写完之后就拉倒了哈哈,以后注意下,review一下[捂脸]
+lencx:
+虽然不可以一步抽象到位,但是可以边写边思考,边优化。这就是迭代。需求需要迭代,代码也需要迭代。
]]>
+
+-
+
+ https://github.com/lencx/z/discussions/79
+ https://github.com/lencx/z/discussions/79
+ 2022-06-10
+ 📅 2022.01.07
+Veda@Angie:
+Vue问题求教:在 watch 里面,我先用 splice 清空了数组,再 for 循环 push 进去,控制台打印数组是更新了、但是页面还是没有重新渲染
+Veda@Angie:
+小哥,你遇到过吗
+lencx:
+vue 我不熟
+lencx:
+你用的是 vue2 吗
+Veda@Angie:
+[可怜]对
+lencx:
+看看代码
+Veda@Angie:
+Vue3 应该没这个问题了
+Veda@Angie:
+代码在公司,只能下周一过去看了
+lencx:
+[捂脸] 有时间跑个最小 demo
+lencx:
+可能自己就发现问题了
+Veda@Angie:
+最小 demo 是啥意思
+lencx:
+就是复现问题的最小用例
+Veda@Angie:
+奥奥是这个意思啊
+Veda@Angie:
+那我回家了写一个跑一下试试
+lencx:
+https://codesandbox.io/
+lencx:
+可以用这个创建
+Veda@Angie:
+好的,感谢
+lencx:
+比较方便,写完直接分享链接,就是一个在线版的
+Veda@Angie:
+好、我去试一试,之前还没用过这种工具
+lencx:
+嗯嗯,不客气,这类工具都是比较常用的,还有 codepen 之类的
+lencx:
+学技术,只盯着公众号,很有限。要自己拓宽知识面,而不是吃别人嚼过的。如何学习,如何获取信息,如何思考,如何解决问题,我觉得才是最重要的。
+Veda@Angie:
+如何学习:
+最常用的是视频学习方式:拉勾、慕课网、B站,一般边看边敲,或看完几节再动手敲
+获取信息:
+搜索引擎、各种技术网站、公众号
+Veda@Angie:
+解决问题:
+一般是搜索引擎,谷歌或百度,如果实在解决不了就问别人
+Veda@Angie:
+如何高效、深度思考我太欠缺了,很多问题只能看到表面,看不透深层
+lencx:
+这些只属于入门级学习方式
+Veda@Angie:
+学习方式也有问题,大部分时间属于被动接受。。
+lencx:
+高效的学习方式,是知道自己想要什么
+Veda@Angie:
+我是感觉自己效率不太高,但是却不知道怎么改善[流泪]
+lencx:
+就是被这帮公众号惯坏了,丧失了捕猎的技巧,只会等着被投喂
+Veda@Angie:
+工作之余,晚上回去不晚的话会学一点,周末学一些,可利用的学习时间也不多
+lencx:
+你要学会主动获取自己想要的信息,这是第一步,然后就是根据自己的需求,拓宽知识面,然后就是读文档。
+Veda@Angie:
+最难的还有一步,就是不知道自己想要什么。。。
+Veda@Angie:
+就是有一股劲,不知道往哪个方向上使
+Veda@Angie:
+今天遇到的问题,我可能需要去看一下 vue 的源码、以及再过一下它的文档
+Veda@Angie:
+这是不是“主动获取自己想要的信息”的一种表现[可怜]
+Veda@Angie:
+还是别的其他的理解,啥都可以直说的哈,我在工作中也是直性子有啥说啥的[破涕为笑]
+lencx:
+这个不是看不看文档的问题,我现在问你,你能把自己遇到的问题,拆解成 1, 2, 3, ... 步骤吗
+lencx:
+
+我遇到了什么问题
+为什么会出现这个问题
+这个问题出现后,我应该怎么办
+我如何分析这个问题
+别人遇到同样的问题,如何定位,思考
+文档我是否都了解清楚了
+我尝试了哪些方法
+问题解决了,我学会了什么
+如果下次遇到同样的问题,我该怎么办
+
+我暂时就想到这些,你觉得你做到了哪些
+lencx:
+这是解决问题的基本流程
+lencx:
+答案毫无用处,因为它并不能让你举一反三
+lencx:
+这些东西,大部分,从公众号,视频上,是学不到的。需要自己动手折腾,思考
+Veda@Angie:
+只做到了三四条。。。
+lencx:
+形成自己解决问题的方法论,它是一个通用的解决问题的手段。
+Veda@Angie:
+折腾了,但思考的太少了
+lencx:
+很多时候,别人问我的问题,我也不会,但是有些问题,我可以解答,那是因为,我有自己的解题思路
+Veda@Angie:
+我是动手的时间比思考的时间多,这样看是搞反了
+lencx:
+是总结少了,而且少了解题的步骤,但是这个步骤恰恰是最关键的,它需要你去分析问题,拆解问题,将未知变成已知,用已经掌握的去推导陌生的
+Veda@Angie:
+说的太对了
+Veda@Angie:
+我经常会遇到那种重复性的问题,很久以前遇到过的,但就是想不起来当初是怎么解决的了,只有去翻看以前的代码或笔记才能想起来
+lencx:
+动手没有错,错的是光动手其实没啥太大意义。因为动手是机械性的动作。代码是你逻辑思维的具象化。
+Veda@Angie:
+如果没有代码或笔记参考,我就得重新把那个问题再来解决一遍
+lencx:
+你需要做的事抽象为自身可以理解的事物,而不是去记代码,记以前解决问题的答案,毫无意义(一些固定流程,可以笔记,作为参考,快速查阅)。你需要记住的是你是如何拆解问题,如何解决问题的流程,然后去强化它。这样,任何时候,碰到这个问题,或者是新问题,你都可以套用你解决问题的流程模板
+Veda@Angie:
+我之前都没往这方面想过,这似乎也适用于生活等其他方面的问题解决
+Veda@Angie:
+感谢你的提点,提醒了我,我有必要重新审视自己的学习习惯、思考方式了
+Veda@Angie:
+还有好长的路要走
+lencx:
+是的
+lencx:
+这个没有什么捷径,我自己也走了好几年的弯路
+lencx:
+所以我把我很多的经验,拿出来分享了,但是似乎群友看的并不多。
+lencx:
+每个人都有自己选择的自由,我也会重新审视自己
+Veda@Angie:
+还是看人,就像现在很多时候流量至上,写的好呢东西有深度的东西看得人就少了,被看得多的倒是那些浅显的。。
+你的分享给我了很多启发、指导,这些经验也会慢慢沉淀,到了一定时候好的东西自然会被发现也被大众接受的
+Veda@Angie:
+你的分享我觉得很受用,所以坚持做对的事啦
+lencx:
+我的分享,有一二人懂,足以。
+Veda@Angie:
+一起坚持、
+Veda@Angie:
+坚持比努力更重要、哈哈这是我喜欢的一句话
+lencx:
+嗯嗯,时间复利
+Veda@Angie:
+嗯嗯新的一年,一起加油
+lencx:
+那我再告诉你一句话:正确的坚持比坚持更重要,不然就是南辕北辙
+Veda@Angie:
+对,因为还有一句话,选择比努力更重要
+lencx:
+嗯嗯
]]>
+
+-
+
+ https://github.com/lencx/z/discussions/82
+ https://github.com/lencx/z/discussions/82
+ 2023-03-19
+ 📅 2022.02.23
+只想吃白菜:
+大佬你先看看我简历
+只想吃白菜:
+看看够资格不
+只想吃白菜:
+[苦涩]双非二本,艺术专业
+lencx:
+学历虽然很重要,但是你自身的技术也占很大部分,不用妄自菲薄
+只想吃白菜:
+我现在最大的顾虑是我之前做的项目比较水
+只想吃白菜:
+就是东西我做出来了
+只想吃白菜:
+细问的话,我感觉没什么技术点可以深入聊
+只想吃白菜:
+我差不多都能做,但要是和我聊技术点,让我从项目聊好久,聊不了,我不知道说啥
+lencx:
+项目是聊你的经历的,没做过复杂项目,单纯靠包装很难,也容易露馅
+只想吃白菜:
+这个情况怎么做会比较好呀
+只想吃白菜:
+我项目这一块的问题
+只想吃白菜:
+我有时间可以自己耗精力去弄
+只想吃白菜:
+但是不知道如何去弄
+lencx:
+项目因为你本身就是实习,没接触过大项目很正常,你可以了解一些项目相关的开发流程,还有就是让自己的基础扎实一些
+只想吃白菜:
+基础指的就是:数据结构、计网这种嘛
+只想吃白菜:
+挑几个点深入了解
+只想吃白菜:
+然后去谈?
+lencx:
+我也没实习经验,给不出太好的建议,我都是走社招的
+只想吃白菜:
+比较发愁
+lencx:
+你是19-20年实习,现在都 22 年了,你是啥时候毕业的
+只想吃白菜:
+22毕业
+只想吃白菜:
+19那次是在一个小微企业
+只想吃白菜:
+兼职一样,一周上两天
+只想吃白菜:
+那个时候我大二,原生做了两个网站,一个在我这,一个公司拿去用了
+lencx:
+哦哦,那你还是走校招吧,走社招更难,看你的简历,是不太具有优势
+只想吃白菜:
+如果要具有一定优势的话,应该怎么做?
+只想吃白菜:
+大佬明示一下
+只想吃白菜:
+我做充分准备
+只想吃白菜:
+我不想放弃做开发[苦涩]
+lencx:
+项目和基础都很重要,没有项目经验,你可以让自己基础扎实点
+lencx:
+js,算法,数据结构,还有就是计算机基础之类的
+lencx:
+项目经验很难包装,没做过的不建议瞎写,很容易被问死
+只想吃白菜:
+我可以实际去写,但是不知道该去做什么
+lencx:
+实际的项目,并没有看到你的亮点
+lencx:
+有点平了
+lencx:
+还有就是你放了 github ,但是最近一年都没怎么更新
+只想吃白菜:
+我知道,我其实可以现在再去开发,然后把那些是亮点的东西做一遍
+只想吃白菜:
+github这个确实[苦涩]在搞毕业的事,没去提交代码
+lencx:
+亮点不是靠做出来的,而是你在实际开发中解决棘手问题的解决方案
+只想吃白菜:
+那这么说来
+只想吃白菜:
+项目的事,没得解决了
+只想吃白菜:
+就只能从基础和深度上解决我的问题
+lencx:
+以你目前的经历来说,很难包装
+lencx:
+差不多是这个意思
+只想吃白菜:
+懂啦
+只想吃白菜:
+谢谢您
]]>
+
+-
+
+ https://github.com/lencx/z/discussions/81
+ https://github.com/lencx/z/discussions/81
+ 2022-06-06
+
+针对图片内容并结合自身写作经历,做了部分改编
+
+
+更多更广泛的阅读
+每天坚持写作,熟能生巧
+保持一致很重要,找到自己的写作风格
+明确目标,知道自己为何而写作
+了解你的受众,直击他们的痛点
+使用副标题来帮助略读者快速找到重点
+不滥用各种形容词凑字数,简单直接地写作
+惜字如金,保持文章结构的紧凑
+用真实经历并加入一些讲故事的技巧,使文章内容更饱满
+善用关键字和 SEO,以使文章在搜索引擎中获得更高排名
+修改之前先完成初稿,编辑未完成的作品是禁忌,它会减慢你写文章的速度并导致倦怠
+创作完成后,不要急于发布。反复斟酌,会一些发现错误、奇怪的措辞或令人困惑的句子
+从读者那里获得反馈,尽最大努力将更好的想法融入到未来的写作中
+对批评持开放态度,虚心学习,让自己变得更优秀
+
+
]]>
+
+-
+
+ https://github.com/lencx/z/discussions/80
+ https://github.com/lencx/z/discussions/80
+ 2022-09-01
+
+
+Fira Code - 带有连字的免费等宽字体
+
+
+
+Nerd Fonts - 修补了具有大量字形(图标)的开发人员目标字体。特别是从流行的“标志性字体”中添加大量额外的字形,例如 Font Awesome 、Devicons 、Octicons 等。3,600 多个图标,50 多种修补字体,如 Hack、Source Code Pro 等。
+
+
+
+
+Operator Mono - 对编码友好的字体,Operator Mono 字体本身并不支持类似于 Fira Code 的连字,但是在社区有个工具专门针对 Operator Mono 字体做连字处理。
+
+
+
+
+制作连字的 Operator Mono 字体
+第一步:下载项目
+首先要有 Operator Mono 字体(网上自行搜索),然后访问下面这个项目,下载到本地。
+
+第二步:前置环境准备
+
+如果遇到环境安装问题,可以在评论区交流
+
+
+Operator Mono 字体文件
+Python (v2.7+)
+Node.js
+从 fonttools/fonttools 安装 fonttools
+
+Windows/Linux: pip install fonttools
+注意事项: 对于 Windows,如果您的 Python 位于 C:\PythonX
下,您应该使用具有管理权限的控制台
+注意事项: 对于 WSL/WSL2 中的 Linux,请确保安装后将 fonttools
添加到 PATH。或者,考虑通过 sudo apt install fonttools
安装。
+Mac: pip3 install fonttools
+
+
+
+第三步:安装依赖及构建
+
+
+压缩包解压,然后进入到文件夹下执行
+# 使用 npm 安装可能会出现 node-gyp 之类的错误,可以尝试使用 yarn 安装
+npm install
+
+
+将 Operator Mono字体文件放到 original 目录下,然后执行脚本
+# Windows
+build
+
+# Linux/Mac
+./build.sh
+
+
+生成的 Operator Mono Lig 字体在 build 文件夹下,点击安装即可
+
+
+字体效果预览
+我的 vscode 配置
+
]]>
+
+-
+
+ https://github.com/lencx/z/discussions/78
+ https://github.com/lencx/z/discussions/78
+ 2022-09-02
+
+计算机世界是对现实世界的映射。当事物变得无法理解时,去源头找找,或许就明白了。
+
+Chrome 100
+在 2022 上半年,Chrome 将达到三位数的主版本号:100
!浏览器在很久以前第一次达到版本 10
时,因为主要版本号从一位数变为两位数,用户代理解析库发现了许多问题(Changes in Opera’s user agent string format )。现在在 Chrome 和 Firefox 中都接近版本 100
,Edge 也不甘落后。当 Chrome 达到 100
版,将会导致一些网站不工作。谷歌已经开始调查和测试解决方案。
+根据 Chromium Bug Tracker ,已知受到影响的网站主要是使用网页设计工具 Duda 开发的网站。这些网站都使用相同的代码来检查用户使用的 Chrome 版本。
+案例
+以 Chrome 为例,用户代理字符串为 Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36
+字符串最后,可以看到我们要寻找的是 Chrome/96.0.4664.110
,它为我们提供了浏览器的准确版本号。但是,大多数 Web 开发人员可能只关心主要版本号,即 96
。
+由于用户代理字符串是文本,开发人员需要自行提取信息以满足业务需求。对于 Duda,开发人员选择只读取 Chrome/
之后的前两位数字。这意味着 Chrome/99
将是 99
, Chrome/100
将被视为版本 10
。
+而 Duda(2015 年发布的版本)会自动阻止低于 Chrome 40
的版本,Chrome 99
之后的每个版本(100 - 109)的浏览器都将被视为版本 10
,因此被阻止。
+目前 Duda 已经修复了此问题(Chrome 100 Bug Was Fixed Months Before The New Version's Actual Release )
+检测与反馈
+通过访问 Is Chrome 100 yet? 可以检查浏览器是否在 User-Agent
字符串中发送主要版本 100。
+为了尽早检测三位数版本号可能导致的问题,在它成为现实前做好准备。我们可以在 Chrome 设置中开启 User-Agent
为 100
的主版本(Force Chrome major version to 100 in the User-Agent string )来对网站进行测试。
+
+访问 Is Chrome 100 yet?
,页面返回 Yes!
或 No.
;
+打开 Chrome 浏览器并在地址栏中输入 chrome://flags
;
+将打开一个包含可用实验的页面, 找到 User-Agent
中启用强制主要版本为 100
的选项(Force major version to 100 in User-Agent
)。然后重新访问步骤 1。
+
+
+成功开启后,然后测试自己的网站。如果发现问题,可以将错误报告发送至 Web Compat 以帮助 Web 浏览器准备三位数的主版本号!
+里程碑
+Web 浏览器简史 - 世界历史从不缺少史诗般的权力斗争,有征服世界的暴君,也有落败的勇士。Web 浏览器的历史也大抵如此。学术先驱们编写出引发信息革命的简易软件,并为浏览器的优势和互联网用户而战。
+在《万维网 25 岁生日快乐》 中可以了解更多网络诞生的相关信息。
+Mosaic
+Mosaic User Agents - NCSA_Mosaic/2.0 (Windows 3.1)
+NCSA Mosaic ,是一个早期普及的网页浏览器,也是互联网协议如 FTP、NNTP 和 Gopher 的客户端,浏览器因支持多种互联网协议而命名。其直观的接口、可靠性和简易安装,因此在当时大受欢迎,也是第一个可以在文字中嵌入图片,而不是在单独的窗口中显示图片的浏览器。
+Mosaic 是引发 1990 年代互联网泡沫的网页浏览器。1992 年 11 月,世界上只有仅仅 26 个网站,每一个网站都受人注目。1993 年,Mosaic 推出了一个叫做 What’s New
(What's New With NCSA Mosaic ) 的页面,几乎每天都会提供给大家一个全新网站的链接。这段期间,互联网的使用率正在由学术界和大型工业研究机构之外迅速普及。然而,这正是 Mosaic 浏览器的易用性推动了网络爆发性的成长,到了 1995 年 8 月,网站数量已经超过了一万个,1998年达到了数百万个网站数量。
+
+Mozilla
+Firefox User Agents - Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:95.0) Gecko/20100101 Firefox/95.0
+Mozilla 是一个自由软件社群,由网景通信公司的成员于 1998 年创立。在非正式的场合下,“Mozilla” 这个名字常用于不同的事物上。这些事物大都与现已歇业的网景通信公司及其旗下的应用软件相关。
+最初,“Mozilla” 被用作 网景导航者(Netscape Navigator) 的开发代号。网景通信公司希望“网景导航者”能够取代当时世界第一的 Mosaic,而这个名字由 “Mosaic Killa”(Killa 是俚语中 Killer 的拼法)变化而来,并与经典的虚拟怪物哥斯拉谐趣:“Godzilla eat the Mosaic”,即 Mosaic + Godzilla + Killa = Mozilla
,Netscape 工程师杰米·加文斯基说他是在一次 Netscape 员工会议上想到这个名字的。
+Mozilla Firefox ,通称 Firefox,中文也通称“火狐”,是一个自由及开源的网页浏览器,由 Mozilla 基金会及其子公司 Mozilla 公司开发。Firefox 于 2002 年由 Mozilla 社群成员创建,当时叫做“Phoenix”。Firefox 于 2004 年 11 月首次发布,并且 9 个月内下载量超过 6,000 万,获取了巨大的成功,Internet Explorer的主导地位首次受到了挑。其被认为是 Netscape Navigator
的精神续作。
+
+
+Internet Explorer
+Internet Explorer User Agents - Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)
+Internet Explorer (旧称 Microsoft Internet Explorer 和 Windows Internet Explorer,简称 IE 或 MSIE),是微软所开发的图形用户界面网页浏览器。自从 1995 年开始,内置在各个新版本的 Windows 操作系统,也是微软 Windows 操作系统的一个组成部分。
+Internet Explorer 曾是使用最广泛的网页浏览器,在 2002 年和 2003 年达到 95% 的使用率高峰。微软以捆绑方式赢得与 Netscape 的第一次浏览器大战,Netscape 是 1990 年代的主流浏览器。
+Internet Explorer 计划由托马斯·里尔登开始于 1994 年夏天,当时 Netscape Navigator 占据浏览器市场份额 70% 以上。竞争对手苹果公司的 Mac OS 更使用 Netscape 作为默认的浏览器,但当时的 Windows 没有一个默认的浏览器。微软需要有一个自己的浏览器,但它没有时间从零开始创造一个浏览器。因此和 Spyglass 合作,Internet Explorer 从早期一款商业性的专利网络浏览器 Spyglass Mosaic 派生出来。
+
+Opera
+Opera User Agent - Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36 OPR/82.0.4227.43
+Opera 是由 Opera 软件为个人电脑推出的网页浏览器,用于 Microsoft Windows、macOS 和 Linux 操作系统。
+1996 年首次公开发布 Opera 2.0 版本,但仅在 Microsoft Windows 上运行。1998 年开始开发第一款用于移动设备平台浏览器。
+Opera 在 2013 年以后采用 Blink 排版引擎 (layout engine) 。此前 Opera 版本曾采用 Presto 排版引擎,并在 FreeBSD 系统上运行。
+
+Safari
+Safari User Agent - Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.1 Safari/605.1.15
+Safari 浏览器 是苹果公司所开发,并内置于 macOS(前称 OS X、Mac OS X)、iOS 与 iPadOS 的网页浏览器。Safari 浏览器在 2003 年 1 月 7 日首度发行测试版,并从 Mac OS X Panther 开始成为 Mac OS X 的默认浏览器,也是 iOS 和 iPadOS 内置的默认浏览器。Windows 版本的首个测试版在 2007 年 6 月 11 日推出,支持 Windows XP、Windows Vista 和 Windows 7,并在 2008 年 3 月 18 日推出正式版,但苹果已于 2012 年 7 月 25 日停止开发 Windows 版的 Safari 浏览器。
+在 1997 年以前,Mac 预装的浏览器是 Netscape Navigator。之后苹果和微软达成协议,以在 Mac 上使用 Internet Explorer for Mac 作默认浏览器换取微软开发 Mac 版的 Microsoft Office。
+2003 年 1 月 7 日,在旧金山举行的 Macworld 大会上,史提夫·乔布斯宣布苹果正在开发自己的浏览器,称为 Safari 浏览器。它基于苹果的 KHTML 排版引擎内部分支,称为 WebKit。直至 2003 年 6 月,苹果才推出自家的 Safari 浏览器,同时微软也终止开发苹果版的 IE 浏览器。Mac OS X v10.3 仍保留 IE,但至 10.4 版苹果就仅预装 Safari 浏览器。
+
+Chrome
+Chrome User Agent - Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36
+Google Chrome 是由 Google 开发的免费网页浏览器,过去也用 Chrome 称呼浏览器的外框。Chrome 相应的开放源代码计划名为 Chromium ,而 Google Chrome 本身是非自由软件,未开放源代码。
+Chrome 代码是基于其他开放源代码软件所编写,包括 Apple WebKit (其分支 Blink 被用于基于 Chromium 的网页浏览器) 和 Mozilla Firefox,并开发出称为 V8 的高性能 JavaScript引擎 。Google Chrome 的整体发展目标是提升稳定性、速度和安全性,并创造出简单且有效率的用户界面。
+Chrome 50 结束了对 Windows XP 与 Windows Vista 系统的支持,这两个系统上的最后版本为 49.0.2623.112。
+
+User-Agent 大乱斗
+
+🙈 浏览器用户代理字符串(navigator.userAgent
)一团糟,几乎没用,每个浏览器都假装是其他浏览器,混乱不堪。
+
+具体可以查看这篇文章 《History of the browser user-agent string》 ,以风趣幽默的方式介绍了浏览器之间的“尔虞我诈”,“勾心斗角”,堪比 宫斗 。
+一般来说,如果一个网站需要知道你使用的是什么浏览器以及它的更新程度,它会检查所谓的“用户代理字符串”。这是浏览器附加到它建立的每个网络连接的一小段文本,让网站了解自己。如果分解用户代理字符串实际所说的内容,会发现很多杂乱无章的东西,其中大部分内容是为了保持与 1990 年代和 2000 年代初期的站点的兼容性。所以说有时候 使用用户代理字段进行浏览器检测 并不是一个好主意。
+用户代理字符串有各种形状和大小,唯一用户代理的数量一直在增长。List of User Agents 中收集了数以百万计的用户代理,并根据检测到的许多内容(操作系统、浏览器、硬件类型、浏览器类型等)进行分类。
+关键事件
+
+摘自《History of the browser user-agent string》
+
+
+
+一开始有 NCSA Mosaic,Mosaic 自称 NCSA_Mosaic/2.0 (Windows 3.1)
,Mosaic 在显示图片的同时也显示文字,大家都很欢欣鼓舞。
+
+
+后来出现了一个新的浏览器,叫做 “Mozilla”,是 “Mosaic Killer” 的缩写,但 Mosaic 并不高兴,所以公开名称改为 Netscape。Netscape 自称 Mozilla/1.0(Win3.1)
,人们更加欢欣鼓舞。Netscape 支持 Frames(框架) ,Frames 在人们中间流行起来,但 Mosaic 不支持 Frames,于是就出现了 "用户代理嗅探(user agent sniffing)",网络管理员向 "Mozilla "发送 Frames,但向其他浏览器发送的不是 Frames。
+
+
+网景取笑微软,把 Windows 说成是 "调试不力的设备驱动程序",微软很生气。于是,微软制造了他们自己的网络浏览器,他们称之为 IE(Internet Explorer),希望它能成为 "网景杀手"。Internet Explorer 虽然支持 Frames,但并不是 Mozilla,所以没有被赋予 Frames。微软变得不耐烦了,不希望等待网络管理员了解 IE 并开始向它发送 Frames,因此 IE 浏览器宣布它是 "Mozilla compatible(Mozilla 兼容的)",并开始冒充网景,称自己为 Mozilla/1.22 (compatible; MSIE 2.0; Windows 95)
,IE 浏览器收到了 Frames,整个微软都很高兴,但网络管理员感到困惑。
+
+
+微软将 IE 与 Windows 一起出售,并使其比网景更好,第一次浏览器战争在这片土地上肆虐。看吧,网景被干掉了,微软方面一片欢腾。但网景重生为 Mozilla,Mozilla 建立了 Gecko ,并称自己为 Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.1) Gecko/20020826
,Gecko 是渲染引擎,Gecko 很好。而 Mozilla 变成了 Firefox,并称自己为 Mozilla/5.0 (Windows; U; Windows NT 5.1; sv-SE; rv:1.7.5) Gecko/20041108 Firefox/1.0
,Firefox 非常好。而 Gecko 开始成倍增长,其他浏览器的诞生也使用了它的代码,它们自称为 Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en-US; rv:1.7.2) Gecko/20040825 Camino/0. 8.1
这一个,和 Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.8.1.8) Gecko/20071008 SeaMonkey/1.0
另一个,每一个都假装是 Mozilla,而且都是由 Gecko 驱动。
+
+
+Gecko 是好的,而 IE 不是,嗅觉重生,Gecko 被赋予了很好的 web 代码,其他浏览器则不然。而 Linux 的追随者则非常悲伤,因为他们建立了 Konqueror ,其引擎是 KHTML ,他们认为它和 Gecko 一样好,但它不是 Gecko,所以没有得到好的网页,于是 Konquerer 开始假装 "like Gecko",以获得好的网页,并称自己为 Mozilla/5.0 (compatible; Konqueror/3.2; FreeBSD)
(KHTML,like Gecko),出现了很多混乱。
+
+
+苹果建立了 Safari,使用 KHTML,增加了许多功能。分叉(Fork)了该项目,称之为 WebKit,希望为 KHTML 编写页面,因此 Safari 自称为 Mozilla/5.0 (Macintosh; U; PPC Mac OS X; de-de) AppleWebKit/85.7 (KHTML, like Gecko) Safari/85.5
,情况越来越糟。
+
+
+微软对火狐的恐惧很大,IE 浏览器又回来了,并自称 Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0)
,它能渲染好的代码,但只有在网站管理员命令它这样做的情况下。
+
+
+谷歌建立了 Chrome,Chrome 使用 Webkit,它就像 Safari 一样,想要为 Safari 制作页面,所以假装是 Safari。于是 Chrome 使用 WebKit,并假装是 Safari,WebKit 假装是 KHTML,KHTML 假装是 Gecko,所有的浏览器都假装是 Mozilla,Chrome 自称 Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.13 (KHTML, like Gecko) Chrome/0.2.149.27 Safari/525.13
,用户代理字符串完全是一团糟,几乎没有用处,每个人都假装是其他人,混乱不堪。
+
+
+结束语
+软件生态从来不是孤立的,而是在借鉴,创新中,不断发展,才有了今天这个五彩斑斓的互联网世界。
]]>
+
+-
+
+ https://github.com/lencx/z/discussions/44
+ https://github.com/lencx/z/discussions/44
+ 2022-07-29
+
+🔥 What should you say no to in the morning to have a more productive day?
+🔥 Better Incident Management Requires More than Just Data
+🔥 Recommended Reading for Developers
+🔥 提問的智慧 - 本文原文由知名 Hacker Eric S. Raymond 所撰寫,教你如何正確的提出技術問題並獲得你滿意的答案
+🔥 How To Write a Programming Book
+🔥 The Key To a Good Start in Programming
+🔥 How to break the “senior engineer” career ceiling
+🔥 Should You Be Deleting Your Own Code?
+🔥 Nobody Asked You to Code Like Kubrick
+🔥 What Is Functional Programming? | The Easy Way
+Coding Programs – 152 Coding Classes You can Take for Free Online
+
+
+Linux
+
+Git
+
+Web
+
+CSS Fingerprinting - Pure CSS device fingerprinting.
+How to Fill an Array with Initial Values in JavaScript
+The JavaScript Array Handbook – JS Array Methods Explained with Examples
+5 Things to Consider Before You Build Your App
+What if… you could use Visual Studio Code as the editor of in-browser Developer Tools?
+The Single-Page-App Morality Play
+Scroll Shadows With JavaScript
+All About Svelte, the Much-Loved, State-Driven Web Framework
+Micro Frontends With Webpack
+An in-depth perspective on webpack's bundling process
+How I Built My Blog
+Building a type-safe dictionary in TypeScript
+React, structured data, and SEO
+Rome will be written in Rust 🦀
+React Hooks for infinite scroll: An advanced tutorial
+An Intro to JavaScript Proxy
+JavaScript vs JavaScript: Round 2. Fight!
+The Future of CSS: Cascade Layers (CSS @layer)
+Designing Beautiful Shadows in CSS
+How to Build a CSS Library with Vite.js
+Best practices for using trailing commas in JavaScript
+Synchronous vs Asynchronous JavaScript – Call Stack, Promises, and More
+Exploring the CSS Paint API: Blob Animation
+What’s New With DevTools: Cross-Browser Edition
+React Video Player Component Using Hooks, TypeScript, and xState
+Bundling non-JavaScript resources
+How to create Music player with pure HTML, CSS, JS
+Create draggable components with React-Draggable
+Infinite scrolling in React with intersection observer
+Memoizing async functions in Javascript
+Event Loops in NodeJS – Beginner's Guide to Synchronous and Asynchronous Code
+JS: All You Can Weak!
+How to make realtime APIs with NodeJS and ReactJS using Socket.io
+Understanding JavaScript currying
+Deno on MDN
+Loading Third-Party JavaScript
+JavaScript vs JavaScript. Fight!
+Why WebAssembly Frameworks Are the Future of the Web
+How to Create a Video Player in React
+Algorithms and Data Structures for JavaScript Engineers
+Simple monorepos via npm workspaces and TypeScript project references
+Stay alert
+Magical Marbles in Three.js
+UI Design Tactics — Part 1
+About Web Components
+Creating a Force Graph using React, D3, and PixiJS
+How to use finite state machines in React? Explained by a frontend developer
+JavaScript Promises: then(f,f) vs then(f).catch(f)
+A Guide to Git Interactive Rebase, with Practical Examples
+10 Predictions for the Future of Computing or; the Inane Ramblings of our Chief Scientist
+How to stop re-rendering lists in React?
+Faster (and smaller) uploads in Discourse with Rust, WebAssembly and MozJPEG
+4 JavaScript Projects To Build FAST And Get Hired In 1 Month
+Is Node.js Really Single-Threaded?
+The Command Pattern in TypeScript — Encapsulating Logic to Increase Maintainability
+Use Closures for Memory Optimizations in JavaScript (a case study)
+Using WebAssembly threads from C, C++ and Rust
+🔥 The data model behind Notion's flexibility
+How to design a system to scale to your first 100 million users
+npm audit: Broken by Design
+🔥 Designing a Dataflow Editor with TypeScript and React
+Building WebRTC Video Chat Applications
+Captain Stack — Code suggestion for VSCode - This feature is somewhat similar to Github Copilot's code suggestion. But instead of using AI, it sends your search query to Google, then retrieves StackOverflow answers and autocompletes them for you.
+Temporal: getting started with JavaScript’s new date time API
+SolidJS Official Release: The long road to 1.0
+Moving Backgrounds: When, Why, and How to Use Them
+🔥 Introduction to Data Types: Static, Dynamic, Strong & Weak - static doesn’t necessarily mean strong and dynamic doesn’t necessarily mean weak
+Understanding Sorting Algorithms
+Implementing Private Fields for JavaScript
+Introducing Utopia - Design ❤️ Code
+New browser APIs to detect JavaScript performance problems in production
+Web3: A New Web for a New World
+Intro to Asynchronous JavaScript
+What is Vite and how to use it with React
+
+Rust
+
+GitHub
+
+VS Code
+]]>
+
+-
+
+ https://github.com/lencx/z/discussions/77
+ https://github.com/lencx/z/discussions/77
+ 2022-10-15
+
+{折腾 ⇌ 迷茫 ⇌ 思考]ing,在路上...
+
+
+flag 立的太多,一个也没完成
+打游戏,刷动漫,电视剧,综艺,视频
+读了一些源码,写了一些玩具项目
+吐槽太多,已整理成语录
+努力早睡,不熬夜
+认识了很多新朋友
+
+分享 & 沉淀
+建了两个微信技术群和一个免费知识星球
+
+语录
+
+lencx 语录 - 此语录,无任何意义,仅记录生活中的所思所感...
+
+🧐 学习
+
+要学会把问题交给搜索引擎,而不是把群友当成搜索引擎。
+同样一个问题,用百度和 Bing (有能力的用 Google ) 对比一下就知道了。
+学习技术,先扫一遍文档,从最基本的开始搭建学习,功能一点点的增加进来。边看边实践,敲键盘也会加深记忆。
+优秀一天容易,难的是一直优秀。
+一篇好文章,更像是一根线,而不是一团麻。极客精神,以风趣幽默的方式解释清楚一切细节。
+学到一句话:经验这个东西,就是越多越好,可以不去做,但是不能不知道。
+有问题不可怕,可怕的是,不知道怎么和问题去相处。
+答案是最无用的东西,因为它是一个问题的处理结果,是由过程分析推理得出来的,过程推理不出,而选择去背答案是最无效的学习方式,毫无意义!
+学习就是从懵逼到膨胀的一个死循环 🔄
+以后再也不敢说自己是在自学了。没有基础作为指导,只能算是瞎学,乱学。看完《自学计算机科学》 这份书单,才发现自己对计算机一无所知。
+真正的高效工作,是首先先学会如何解放自己。
+骨头是不好啃,自己要先啃几口,才有发言权。别还没啃,就说太硬了。(软饭吃多了,牙也变软了)
+遇到问题自己不思考,不尝试,就没有资格把这个问题抛出来。(踢皮球并不能让自己成长)
+学会自我总结, 一步一个脚印,别总想着有人可以帮你。(外力终究不是自己的)
+知识就是这样的,会一点点进入你的视野。但是前提,你要保持好奇心,并且不断地尝试。
+人的思想蜕变,不是一瞬间产生的,而是不断起伏的人生带给你的。
+
+😐 日常
+
+感谢所有夸我的人,说句实话,我不 NB,在技术群里,大部分人的能力都要比我强,我只是比较张扬而已。
+任何话题都是技术交流,代码不是全部。
+不信鬼神,但对未知还是要保持敬畏之心。
+群里虽然前端居多,似乎更应该发和前端相关的内容。但一切皆知识,路应该越走越宽。专精于 xxx 或许没错,但只有 xxx,视野过于被局限,会少了很多灵感碰撞及其他可能性。(广度与深度该如何抉择)
+彩票属于不确定的意外之财,讨论这个没啥意义。运气不是每个人都有的,现实点。(学会自我催眠)
+我写的文章没啥技术含量,手撕不动,脑子也不怎么灵活,基础更是一塌糊涂。
+我想明白了一些事情:欲望就好比握在手中的沙子,不握紧,会流失。握紧了,只会流的更快。因为想要获得,各种复杂的情绪就产生了,兴奋,焦虑… 如果放弃了所有的欲,一切便会回归于无。
+当一些东西变得重复与机械的时候,也就失去了原本的兴趣。
+自省只是不想让自己太飘,因为人是社会性动物,他人的评价或多或少都会对自己产生影响。
+知识,技术可以变现,但是丢掉原则,就不再是一个技术人了。
+本以为自己只是走了两三年的弯路,谁知从未走出...
+开源其实是一件很简单的事情,你想做,就可以去做。
+人更喜欢相信自己看到的。很少有人去思考,你所看到的是不是别人故意给你看的?(眼见不一定为实)
+以前我也认为只要学会独立思考就够了,但是后来我发现,如果你所看到的一切都是假象,那么基于它做出思考将是一件可怕的事情。(价值观坍塌)
+眼界,思考,质疑,都很重要。
+当对一切失去了怀疑的态度,会让你觉得它就是权威,不会出错。这是很可怕的事情。(盲目崇拜)
+做你认为对的事情,就不存在浪费时间一说。
+有人说:“大多数的成功来源于勇气,似乎越成熟,越丧失了追求的勇气”。但是我认为不是越活越没勇气,而是人学会了算计,会去计较得失,才变得畏手畏脚。(冲动是魔鬼,太过于理智,生活也就少了一些色彩)
+一定要学会享受过程。结果很重要,但是如果真的有一天你可以直接到达这个结果的时候,未必是快乐的。(出生的结局就是死亡)
+没有学会取舍,才会让自己那么累。(放下也是一种智慧)
+我不想努力了,可是没钱。钱不是那么重要,但是没有它,可能会过的很惨。(衣食住行)
+这个世界是动态的,一切都在变化,人也如此。(保持初心)
+穷爸爸富爸爸 告诉我们,起点大于努力。(生的好也很重要)
+
+🤬 吐槽
+
+做任何事都是需要指标的,没有高标准,就不会把事情做到极致。但是国内忽视了一些东西,或者说不愿意去面对实际场景,“拍脑袋”和“我以为”就是标准。KPI 最终沦为了老板们的大屏数据,似乎数据代表一切...
+说句难听的,国人有能力的不少,但是创造的东西,真不咋样,很难有思维上的突破,到处都是“借鉴”。
+国外做开源的很多可能就是个学生,普通程序员,没啥 title,吊打国内一大批程序员;级别,title 是越封越高,能力倒是没见涨。
+国人不务实,很多都是面子工程,这莫非是大环境“造就”的?
+这两年看到比较多的消息就是 xxx 开源库作者因精力有限,放弃对其的维护工作。这都是白嫖,不反哺社区的结果。
+某度搜索并不适合程序员,查找问题效率低下,结果百分之八九十都是垃圾。(工具很重要)
+一个技术社区如果东西“杂了”,技术就变得不再纯粹。(四不像)
+Node 再卷,感觉都要卷到 V8 ,C++ 了,而我只是个前端切图仔。
+技术如果不纯粹就会变得畸形,写文章首要目标是思考沉淀,其次是分享传播帮助他人,最后才会考虑技术变现,但很多所谓的“作者”似乎本末倒置了。
+看似是要求越来越低,实则社会在教我做人。(认清现实)
+轮子哥,造轮子的速度比我用轮子的速度还快。(与大佬的差距)
+垃圾公众号看多了,人都变傻了。天天卖课,真烦...
+公众号其实就是收割流量的,既然那么多干货,为啥不写成 blog,因为写成 blog 就没多少干货了,公众号基本百分之七八十都是在转载,写成 blog 哪有那么多文章。如果你关注了 100 个前端公众号,一篇文章你起码可以在几十个公众号看到,有啥意义?还有一大堆是卖课的。一百个能有十个,可能都是比较乐观的估计,十不存一...
+我觉得很多人就喜欢混为一谈,学习的本质是为了什么?是为了吃透一门技术,掌握一门技能,还是说只是为了更好的赚钱。(多问问自己想要什么)
+
+🤫 非原创
+
+科技造神的祭坛下,是无数沉迷于低级娱乐与表面思考的终端消费者。但他们不得不为此付费,甚至久而久之,他们会下意识地维护这套病态逻辑。
+编程的历史就是“更少代码”的历史:寻找更好的抽象,并构建库来实现这些抽象。
+
+开源
+2021 开源项目归档
+
+总结
+2021 年一晃而过,很多事情都没来得及去做,只能匆匆忙忙总结一番。以这篇文章(参照物),来记录自己的成长(age++)。
]]>
+
+-
+
+ https://github.com/lencx/z/discussions/75
+ https://github.com/lencx/z/discussions/75
+ 2022-12-15
+ 📅 2021.12.22
+lencx:
+人们更倾向于根据场景来探索解决方案,成也场景,败也场景。收窄要解决问题的范围,可以降低复杂度,但也降低了普适性。我以前也一直觉得,要实现的东西应该尽可能的剥离业务,但是随着做的业务越来越多,发现业务其实才是核心。当把业务抽象之后,所谓的跨平台其实就是适配的问题。
+我发现可能之前自己想错了,应该抽象的是业务而不是组件,组件只是业务的载体。
+适配层(组件)要做的就是低耦合,用抽象的业务逻辑去驱动适配层。
+其核心就是业务,怎么实现,是个技术问题。技术可以被替换,推翻。以不变(主业务逻辑)应万变(视觉及交互)。
+
+
+产生的讨论
+
+正人 (欧雷):
+场景化方案基于通用化方案,不冲突
+lencx:
+其实我是发现可能之前自己想错了,要抽象的可能是业务而不是组件
+🇨🇳 Promise (🇨🇳 Promise):
+感觉其实是不同维度
+正人 (欧雷):
+所以通用方案的扩展机制很重要
+正人 (欧雷):
+都要抽象
+正人 (欧雷):
+所以为啥要 MV*,为啥要 DDD[吃瓜]
+🇨🇳 Promise (🇨🇳 Promise):
+通用化方案抽离的开发工具本身, 例如打包工具, 组件化是ui 的抽离,例如react、vue,ant
+🇨🇳 Promise (🇨🇳 Promise):
+想到一个以前的小品,把大象放进冰箱需要几步,答案是三步。 接下来会对这三步行为不端细化和抽离。为了适配不同的场景(放进其他的东西),就对三步的行为不端抽象,部分不同的做单独适配
+lencx:
+适配层(组件)我认为要做的就是低耦合,用抽象的业务逻辑去驱动适配层
+🇨🇳 Promise (🇨🇳 Promise):
+来驱动适配层怎么来理解
+Shine.:
+除非业务组件 其他的组件都应该是低耦合吧 就只敢一件事
+Shine.:
+不应该有任何业务逻辑什么的吧?
+空:
+不是有业务组件跟通用组件之分么
+lencx:
+个人理解:组件开发一般两种模式,无状态组件和业务组件,业务组件会耦合业务逻辑
+lencx:
+但是如果按照我说的,其实就不存在业务组件了,所有的组件基本和业务都不存在太大的耦合,也就是不会在组件里处理业务相关的东西
+lencx:
+组件都退化到通用,然后只负责数据的填充。交互其实就是一个个动作,给业务数据所带来的反应。
+Shine.:
+就是说组件不去处理业务 业务都在使用的时候去处理?
+lencx:
+在抽象的业务核心逻辑里处理,你可以理解为业务核心就是一个个纯函数
+lencx:
+组件只负责接收数据
+Jack:
+按我理解
+Jack:
+理想化状态下,组件就是个书包
+Jack:
+你给我啥书 我就装啥书
+Jack:
+具体你给我的是语文书 数学书 马列主义 还是什么其他的
+Jack:
+我不管
+Jack:
+我只管把书装进去 让你带着走
+lencx:
+对,书就是业务核心,组件只负责装
+Jack:
+这也不是我该管的
+Jack:
+理想情况下就是这样
+Jack:
+我该管的只是,你如果不装书,装炸药,那我就报错
+🇨🇳 Promise (🇨🇳 Promise):
+这就是抽象与具象的互斥点了
+🇨🇳 Promise (🇨🇳 Promise):
+在业务状态下,有时候需要保证书的放入和放出顺序
+Jack:
+是的 所以理想和现实还是有些差距
+🇨🇳 Promise (🇨🇳 Promise):
+书的放置位置和摆放形势
+lencx:
+所以可能需要有类似流程控制的东西吧
+lencx:
+我其实也没完全想明白
+Jack:
+这个见仁见智了 有的倾向于在外边整理完了再塞进去
+Jack:
+有的倾向于塞进去,背在身上,让书自己动
+皓夜森林:
+ui组件的逻辑层都应该是个纯函数,ui层就是只负责渲染。业务组件感觉更偏向于,处理某个特定业务,比如唤起第三方的支付,sdk的支付组件。这种
+Shine.:
+什么叫纯函数 你给我啥我返回啥 对数据不做处理?
+皓夜森林:
+很简单,你想想你这个组件能不能在别的项目直接用
+Shine.:
+我看网上解释有点太名词了
+🇨🇳 Promise (🇨🇳 Promise):
+现在大多数抽象层的处理,都是在外面处理外,整体放进去,但是也有要求这个单独执行动作的。
+皓夜森林:
+不管啥项目。都能直接用(运行环境允许的情况下)
+Jack:
+没有副作用的函数
+Jack:
+比如 sum(1,2,3)
+lencx:
+纯函数就是个黑盒,接收参数,内部一系列处理后,返回的就是格式化后的标准数据格式
+Jack:
+我如果输入123 那输出值永远是6
+🇨🇳 Promise (🇨🇳 Promise):
+我个人推崇的还是那种微内核的形式, 提供插件机制和默认机制。 同时保留执行 过程外部可以修改的api
+皓夜森林:
+你就理解为一个函数如果在输入一样的情况下输出永远不变那就是纯函数
+皓夜森林:
+const add = (a ,b) => a + b 这就是一个纯函数
+皓夜森林:
+let effectParam = 1
+const add = (a, b) => a + b + effectParam
+皓夜森林:
+因为结果会受effectParam影响
+皓夜森林:
+这就不是一个纯函数
+皓夜森林:
+这个参数变了结果就变了 即使输入可能都是一样的输入
+Jack:
+effectParam也可能是某个api的返回值
+Shine.:
+哦 明白了
+🇨🇳 Promise (🇨🇳 Promise):
+像纯函数的编写,也是可以传入单纯的形参,或者传入一个改变执行函数作为结构的再次处理
+Shine.:
+我一直理解的是 不修改传递的参数那
+皓夜森林:
+我寄几玩我寄几的
+皓夜森林:
+你别搞我
+皓夜森林:
+这就是纯函数
+lencx:
+业务其实就是一大堆这样的纯函数,做什么功能,调什么函数,职责单一
+Jack:
+其实本质就是在做取舍
+Shine.:
+那我好像很多时候违背了这个
+🇨🇳 Promise (🇨🇳 Promise):
+能保证单一指责其实在团队中就有点难的
+皓夜森林:
+hook很多都是业务组件的逻辑层
+Shine.:
+看似代码少了
+Shine.:
+其实维护起来有点麻烦
+Jack:
+的确
+皓夜森林:
+那你的项目做大了就很难维护
+Shine.:
+一改都得变
+皓夜森林:
+这个是肯定的
+Jack:
+所以要考虑颗粒度
+Jack:
+这就又扯到很多其他方面了
+Jack:
+团队规模 业务复杂度 等等
+皓夜森林:
+我的话这种都是踩坑踩出来的
+🇨🇳 Promise (🇨🇳 Promise):
+这个本身就是一个很大的命题,把这个充满生机的世界在计算机中进行再造,本身就是厉害
+皓夜森林:
+最近改公司的支付...越发体会深刻
+lencx:
+支付的各种逻辑一旦耦合进 ui 里, ui 大改版就痛苦了
+🇨🇳 Promise (🇨🇳 Promise):
+其实理解好面向对象也是比较容易,抽象对象, 实例在进行业务适配。 提供插件机制提供实例运行
]]>
+
+-
+
+ https://github.com/lencx/z/discussions/45
+ https://github.com/lencx/z/discussions/45
+ 2022-07-10
+
+自前端三大框架 ( Vue , React , Angular ) 以及后起之秀 Svelte 出现之后,各种组件,轮子。大家都没少造过,一些大公司或者有精力的人,在研究 LowCode
或 NoCode
,也有一些落地或者具体方案。
+
+背景
+但就我自身经历及接触项目而言,项目还是停留在如何编写组件的层次上,简单的实现一些复用。一些历史项目因为需求的迭代,功能在不断增加,写代码的人员也在不断更替,交接。就会导致最后的接手项目的人痛苦不堪,重构?不现实,时间不够,之前的需求也不清楚。继续保持?就面临着怎么去在原项目之上继续迭代。 进退两难...
+在之前的需求毫不知情的情况下,如何完成需求功能的迭代,UI 改版?只能通过全局搜索一些关键词,关键字去一步步向上 debug 源码。如果代码中牵扯过多的业务逻辑,就完全懵逼了,没人知道之前的需求是什么?_?!!!
+以 React 为例,因为每个人都有自己对组件的理解,不同的人站在不同的维度去封装,就导致最后的项目结构,代码结构也是千差万别。
+
+无状态组件
: 不涉及过多状态交互,很容易实现,大家的思路都差不多。
+有状态组件
: 一旦涉及到状态,业务逻辑,交互。一个组件就变得不再可控。每个人的风格也都体现的淋漓尽致!
+
+组件内发起请求,各种请求,大量接口相互依赖。如果涉及到多个接口并行,后一个接口依赖上一个接口的返回值,写法又是各有特色。
+出现大量的业务逻辑分支,根据业务 return
出不同的组件 ╥﹏╥
+直接在组件内实现一个或多个子组件 (ノへ ̄、)
+子组件上挂载着大量的 props
,属性有时候多到令人发指,有数据,方法,状态,自定义的 xxx,各种传递。 o(╥﹏╥)o
+欢迎大家继续补充吐槽...
+
+
+
+思考
+我对数据的理解,它既贴近于业务层,也耦合着交互层,如果不能很好的分离组织这三层,很可能牵一发而动全身。所以数据是核心,既是业务的核心,也是组件的核心。
+
+数据,业务逻辑,交互都会影响最终需要渲染的UI视图。
+编写组件时,首先分析业务需求,对组件进行分层。大致分为数据 (DataSource)
,交互 (Action)
,UI视图 (View)
三层。
+
+数据处理 (Handle) : 承载着核心业务逻辑,对数据进行格式化输出,供 UI 组件进行标准化接收,一般以 function
形式存在。
+副作用 (Effect) : 以我目前接触到的场景,主要还是以事件修改组件状态,更新数据及UI视图为主。所以事件及状态变更可能会同时出现在 数据处理
和 UI 视图
中。在数据处理中,调用 (Call)
方法;在 UI 中,绑定 (Bind)
事件及状态。UI 层尽量不直接处理或少处理源数据。
+
+
+
+
+举例
+
+业务中常会有这样一种需求,用户可以动态的新增删除一个列表,因为每次需要处理的数据,和展示的 UI 形式都是不确定的。可能我们每次做需求时都实现一次代码,或者把新增和删除方法提取出来,实现部分复用。以 React Hook
为例:
+
+/* hooks/useDataOP.js */
+import { useState , useEffect } from 'react' ;
+import { v4 as uuidv4 } from 'uuid' ;
+import cloneDeep from 'lodash/cloneDeep' ;
+
+// 使用Symbol作为数据的唯一key
+const safeKey = Symbol ( 'tid' ) ;
+
+// 格式化源数据
+const opFmtData = ( data ) => {
+ return cloneDeep ( data ) . map ( ( i ) => {
+ i [ safeKey ] = uuidv4 ( ) ;
+ return i ;
+ } ) ;
+} ;
+
+/**
+ * useDataOP
+ * @author lencx
+ * @param rawData - 源数据
+ */
+export default function useDataOP ( rawData = [ ] ) {
+ const [ opData , setData ] = useState ( [ ] ) ;
+ const [ opType , setType ] = useState ( null ) ;
+ const [ isOk , setOk ] = useState ( true ) ;
+
+ // 数据初始化
+ useEffect ( ( ) => {
+ if ( Array . isArray ( rawData ) ) {
+ if ( rawData . length > 0 ) {
+ const data = opFmtData ( rawData ) ;
+ setData ( data ) ;
+ }
+ setOk ( true ) ;
+ } else {
+ setOk ( false ) ;
+ }
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ } , [ ] ) ;
+
+ if ( ! isOk ) return console . error ( 'Parameter must be an array!' ) ;
+
+ /**
+ * 新增
+ * @param data - 新增的数据对象
+ */
+ const opAdd = ( data = { } ) => {
+ const result = [ ...opData , { [ safeKey ] : uuidv4 ( ) , ...data } ] ;
+ setData ( result ) ;
+ setType ( 'add' ) ;
+ return result ;
+ } ;
+
+ /**
+ * 删除
+ * @param value - 需要删除的值,如果为字符串或数字时,需要配合key使用。
+ * 如果value为对象,则为需要删除的记录,通过safeKey查找删除。
+ * @param key - 默认为id,选填,可省略
+ */
+ const opRemove = ( value , key = 'id' ) => {
+ let result ;
+ if ( typeof value === 'string' || typeof value === 'number' ) {
+ result = opData . filter ( ( i ) => i [ key ] !== value ) ;
+ } else {
+ result = opData . filter ( ( i ) => i [ safeKey ] !== value [ safeKey ] ) ;
+ }
+ setData ( result ) ;
+ setType ( 'remove' ) ;
+ return result ;
+ } ;
+
+ /**
+ * 排序
+ * @param startIndex - 当前位置
+ * @param endIndex - 目标位置
+ */
+ const opReorder = ( startIndex , endIndex ) => {
+ const result = Array . from ( opData ) ;
+ const [ removed ] = result . splice ( startIndex , 1 ) ;
+ result . splice ( endIndex , 0 , removed ) ;
+ setData ( result ) ;
+ setType ( 'reorder' ) ;
+ return result ;
+ } ;
+
+ return {
+ opData,
+ opType,
+ opAdd,
+ opRemove,
+ opReorder,
+ opRawData : rawData ,
+ opSafeKey : safeKey ,
+ } ;
+}
+// 使用useDataOP
+import React , { useState } from 'react' ;
+import useDataOP from '@hooks/useDataOP' ;
+
+export default ( ) => {
+ const { opData, opAdd, opRemove, opReorder, opSafeKey } = useDataOP ( [ ] ) ;
+ const [ count , setCount ] = useState ( 1 ) ;
+
+ const handleAdd = ( ) => {
+ setCount ( count + 1 ) ;
+ opAdd ( { name : `test${ count } ` } ) ;
+ }
+ return (
+ < div >
+ < button onClick = { handleAdd } > Add< / button >
+ { opData . map ( ( i , idx ) => {
+ return (
+ < div key = { i [ opSafeKey ] } >
+ < span > Name: { i . name } < / span >
+ { ' ' }
+ < button onClick = { ( ) => opRemove ( i ) } > Remove< / button >
+ < button onClick = { ( ) => opReorder ( idx , idx - 1 ) } > Up+1< / button >
+ < button onClick = { ( ) => opReorder ( idx , idx + 1 ) } > Down-1< / button >
+ < / div >
+ )
+ } ) }
+ < / div >
+ ) ;
+}
+查看 DEMO 演示
+总结
+数据与 UI 的解耦,其实就意味着业务逻辑与 UI 组件视图的解耦。当组件要跨平台,或者 UI 大换肤时,我们只需要实现标准的数据接收组件就可以了。业务功能对应的其实就是一个个数据处理函数和 UI 组件的组合,通过事件去触发或者绑定一些状态。当数据处理或组件不满足需求的时候,我们只需要去扩展对应的函数或组件。
]]>
+
+-
+
+ https://github.com/lencx/z/discussions/66
+ https://github.com/lencx/z/discussions/66
+ 2022-09-16
+
+我发起了一个原创写作计划,通过开源打卡的形式来相互监督。
+
+目前计划刚刚启动,还有很多地方需要完善,如果有感兴趣的朋友,欢迎参与。
+仓库:zkuhut/monthly
+网站:臻苦舍月刊
+有两种参与方式,选择其中一种即可:
+
+关注公众号:浮之静
,回复 开源打卡
+Fork
仓库,提交 PR
,可参考 怎样贡献一篇文章?
+
+关于
+zkuhut
:臻(z)苦(ku)舍(hut)
+臻,至也;苦,始也。
- 谐音 真苦
,想要到达高的,完美的(臻),一切只是刚刚开始(苦)。
+背景
+在信息爆炸的时代,我们最缺的不是如何获取信息,有价值的信息沉淀下来才是真正的知识。我们每个人都会阅读,思考,但是要把这些思考想法输出的人似乎并没有想象中那么多。
+人都是有惰性的,会因为种种原因而放弃自己的一些计划或目标,三分钟热度。此次发起学习小组,就是想基于 GitHub 来进行协作监督,记录自己。
+很多人,包括我自己都会有这样的困惑:
+
+我很菜,不知道该写点什么。
+我会的东西那么简单,写出来会不会被别人笑话。
+我想写的东西似乎很多人都写过了,还有必要自己写吗?
+
+对此我想谈谈自己对于有价值信息的理解。输出文章是为了记录,梳理,引发一些思考及观点。其次才是分享(别太高看自己,你写的东西没几个人会看到的)。用最直白的语言讲清楚一件事或一个东西,就是有价值的信息。
+技术栈
+写作平台
+现在的写作形式就那么几种:
+
+第三方平台
+
+国内:知乎
,掘金
,公众号
,简书
,CSDN
等
+国外:dev.to
,medium
等
+
+
+自建博客
+
+自己搭建服务器
+基于 GitHub
,Gitee
的 pages
搭建网站
+
+
+云笔记:Notion
,有道云笔记
等
+
+方案确定
+最终选择 GitHub 作为代码及文章托管平台,vitepress + github actions + github pages + giscus 构建网站。原因有以下几点:
+
+多人协作
+不受平台制约
+github + git 常用操作学习
+github actions 自动执行一些脚本或发布任务
+方便进行扩展及二次开发
+
+不过缺点也十分明显,就是无法通过平台引流。不过其目标为了记录自己,所以这个缺点可以忽略不计。
+身为一名程序员,如果不会使用 GitHub,不能够在全球最大的同性交友网站畅游与学习,我认为不是一名合格的程序员。而参与项目就是最好的学习。
+写作环境
+
+Node.js
- 基于 vitepress 搭建
+GitHub
- 用于多人协作
+zkuhut
- 加入 GitHub 组织(非必需)
+
+写作要求
+
+✅ 人/月至少输出一篇原创,坚持下来的,欢迎申请加入 zkuhut
组织
+✅ 内容不限,技术,思考,新技术尝试等皆可
+✅ 严谨性,专业术语,相关资源要有出处
+🚫 打广告,卖课
+🚫 搬运,抄袭
+
+微信群
+
]]>
+
+
+
+
\ No newline at end of file
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..636f120
--- /dev/null
+++ b/index.html
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+ 浮之静
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/issues/2.json b/issues/2.json
new file mode 100644
index 0000000..55cb555
--- /dev/null
+++ b/issues/2.json
@@ -0,0 +1 @@
+{"id":"MDEwOkRpc2N1c3Npb24zMzczMjIy","title":"欢迎来到《浮之静》社区","bodyHTML":"👋 Welcome! \n学无止境
\n您可以访问网站,有更好的阅读体验: 浮之静
\n仓库历史 \n\n这个仓库经历过数次大改版,从换名到换技术栈...
\n \n2021.07.01 - 至今 \nz
-【〽️ 浮之静 - 学无止境】 \n取 fzj
的中间字母,z
是一个很有意思的字母,像弹簧,蓄力愈久,反弹的力量就愈大。很符合 «浮之静» 之本意。
\n2021.05.24 - 2021.07.01 \nfzj
- 【🌊 浮之静 - 源于前端,但不止于前端】 \n技术栈 - vite + react + github discussions api
\n2021.05.23 - 2021.05.24 \nsea
-【🌊 学海无涯】 \n技术栈 - vitepress
\n2020.08.23 - 2021.05.17 \nmtc
- 【😎 My tools & config, and awesome lists】 \n技术栈 - vuepress
,v2.0
基于 vitepress
\n
\n推荐系列 \n","category":{"name":"General"},"labels":{"edges":[]},"reactions":{"totalCount":2,"edges":[{"node":{"id":"MDE4OkRpc2N1c3Npb25SZWFjdGlvbjE3MTkzOQ==","content":"HOORAY"}},{"node":{"id":"MDE4OkRpc2N1c3Npb25SZWFjdGlvbjE3MTk0MA==","content":"HEART"}}]},"comments":{"edges":[]}}
\ No newline at end of file
diff --git a/issues/20.json b/issues/20.json
new file mode 100644
index 0000000..268a37e
--- /dev/null
+++ b/issues/20.json
@@ -0,0 +1 @@
+{"id":"MDEwOkRpc2N1c3Npb24zNDA3MTQ1","title":"TODO","bodyHTML":"\n开源 \n","category":{"name":"Notes"},"labels":{"edges":[]},"reactions":{"totalCount":0,"edges":[]},"comments":{"edges":[]}}
\ No newline at end of file
diff --git a/issues/25.json b/issues/25.json
new file mode 100644
index 0000000..846999a
--- /dev/null
+++ b/issues/25.json
@@ -0,0 +1 @@
+{"id":"MDEwOkRpc2N1c3Npb24zNDExMDcx","title":"《黑客与画家》读书笔记","bodyHTML":"\nHackers & Painters \n作者: 保羅·格雷厄姆 (Paul Graham) \n译: 阮一峰
\n \n \n\n\n出于兴趣而解决某个难题,不管它有没有用,这就是黑客。
\n \n\n黑客伦理 [hacker ethic]
\n\n使用计算机以及所有有助于了解这个世界本质的事物都不应该受到任何限制。任何事情都应该亲手尝试。 \nAccess to computers-and anything that might teach you something about the way the world works-should be unlimited and total. Always yield to the Hands-On Imperative! \n信息应该全部免费。 \nAll information should be free. \n不信任权威,提倡去中心化。 \nMistrust Authority-Promote Decentralization. \n判断一名黑客的水平应该看他的技术能力,而不是看他的学历、年龄或地位等其他标准。 \nHackers should be judged by their hacking, not bogus criteria such as degrees, age, race, or position. \n你可以用计算机创造美和艺术。 \nYou can create art and beauty on a computer. \n计算机使生活更美好。 \nComputers can change your life for the better. \n \n根据这六条“黑客伦理”,黑客价值观的核心原则可以概括成这样几点:分享、开放、民主、计算机的自由使用、进步。
\n \n\n计算机程序只是文本而已。你选择什么语言,决定了你能说什么话。编程语言就是程序员的思维方式。
\n \n \n\n\n阿尔伯蒂 有一句名言:“任何一种艺术,不管是否重要,如果你想要在该领域出类拔萃,就必须全身心投入。” \n \n黑客与画家 \n\n\n黑客搞懂“计算理论” [theory of computation] 的必要性,与画家搞懂颜料化学成分的必要性差不多大。一般来说,在理论上,你需要知道如何计算“时间复杂度”和“空间复杂度” [time and space complexity];如果你要写一个解释器,可能还需要知道状态机 [state machine] 的概念;除此以外,并不需要知道特别多的理论。这些可比画家必须记住的颜料成分少很多。
\n \n\n因为如果你不爱一件事,你不可能把它做得真正优秀,要是你很热爱编程,你就不可避免地会开发你自己的项目。
\n \n\n黑客就像画家,工作起来是有心理周期的。有时候,你有了一个令人兴奋的新项目,你会愿意为它一天工作 16 个小时。等过了这一阵,你又会觉得百无聊赖,对所有事情都提不起兴趣。
\n \n\n对于编程,这实际上意味着你可以把 bug 留到以后解决。消灭 bug 对我来说属于轻松的工作,只有在这个时候,编程才变得直接和机械,接近社会大众想象中的编程的样子。消灭 bug 的过程就像解一道数学题,已知许许多多的约束条件,你只要根据条件对方程求解就可以了。你的程序应该能产生 x 结果,但是却产生了 y 结果。哪里出错了?你知道自己最后肯定能够解决这个问题,所以做起来很轻松,就好像刷墙一样,接近于休闲了。
\n \n\n“程序写出来是为了让人看懂它的算法,附带告诉计算机如何执行。”一种好的编程语言应该比英语更容易解释软件。只有在那些不太成熟、容易出现问题的地方,你才应该加上注释,提醒读者注意那里,就好像公路上只有在急转弯处才会出现警示标志一样。
\n \n \n不能说的话 \n\n\n大多数成年人故意让孩子对世界有一个错误的认识。最鲜明的例子之一就是圣诞老人。我们觉得,小孩子相信圣诞老人,真是太可爱了。我本人其实也是这样想。但是,扪心自问,我们向孩子灌输圣诞老人的神话,到底是为了孩子,还是为了我们自己?
\n我在这里不讨论这样做是否正确。家长想要塑造孩子的心灵,把他们装扮成可爱的小宝宝,这可能是无法避免的。我也可能这样做。但是,就本文而言,这样做会产生一个重要的结果,那就是孩子“被迫”在一个精心设计的环境中长大。他的头脑或多或少是纯洁无暇的,一点也不知道那些“不能说的话”,从来没有被真实的社会生活“污染”过。孩子眼里的世界是不真实的,是一个被灌输进他们头脑的假想世界。将来当孩子长大以后接触社会,就会发现小时候以为真实的事情,在现实世界中是荒唐可笑的。
\n \n\n那些团体神经越紧张,它们所产生的禁止力量就越大。伽利略因为宣布日心说而遭到教廷的审判,这件事讽刺的地方在于,他只是在宣传哥白尼的观点,而后者却安然无恙。事实上,哥白尼不仅不反对教廷,还是一个虔诚的天主教教士,他把自己的著作献给教皇。不幸的是,伽利略正赶上教廷内部反对派上台,宗教改革制度压制,任何非正统的思想遭受到前所未有的严厉控制和禁止。
\n为了在全社会制造出一个禁忌,负责实施的团体必定既不是特别强大也不是特别弱小。如果一个团体强大到无比自信,它根本不会在乎别人的抨击。美国人或者英国人对国外媒体的诋毁就毫不在意。但是一个团体太弱小,就会无力推行禁忌。有一种行为怪癖叫做“嗜粪症” [coprophila],它的患者人数以及影响势力眼下似乎就不太强大,无法把自己的观点推广给其他人。
\n我猜想,道德禁忌的最大制造者是那些权利斗争中略占上风的一方。你会发现,这一方有实力推行禁忌,同时又软弱到需要用禁忌来保护自己的利益。
\n大多数的斗争,不管它们实际上争的是什么,都会以思想斗争的形式表现出来。
\n \n \n为什么这样做 \n\n\n有人可能会问,为什么要去找出“不能说的话”?为什么要故意打探那些龌龊的,见不得人的思想观点?你明知那里有挡住去路的石头,为什么还要把它们翻过来看个究竟呢?
\n首先,我这样做与小孩子翻石头是出于同样的原因:纯粹的好奇心。我对任何被禁止的东西都有特别强烈的好奇心。我要亲眼看一下,然后自己做决定。
\n其次,我这样做是因为我不喜欢犯错。如果像其他时代一样,那些我们自以为正确的事情将来会被证明是荒唐可笑的,我希望自己能够知道是哪些事情,这样可以使我不会上当。
\n再次,我这样做,是因为这是很好的脑力训练。想要做出优秀作品,你需要一个什么问题都能思考的大脑。尤其是那些似乎不应该思考的问题,你的大脑也要养成思考它们的习惯。
\n优秀作品往往来自于其他人忽视的想法,而最被忽视的想法就是那些被禁止的思想观点。
\n \n\n“守口如瓶”的真正缺点在于,你从此无法享受讨论带来的好处了,讨论一个观点会产生更多的观点,不讨论就什么观点也没有。所以,如果可能的话,你最好找一些信得过的知己,只与他们畅所欲言、无所不谈。这样不仅可以获得新观点,还可以用来选择朋友。能够一起谈论“异端邪说”并且不会因此气急败坏的人,就是你最应该认识的朋友。
\n \n\n你不仅要远距离观察人群,更要远距离观察你自己。顺便提一句,这可不是激进的想法。儿童和成年人的主要差别就在这里。儿童精疲力竭时,可能会大发脾气,因为他不知道为了什么;成年人则会了解是个人的身体状况问题,与外界无关,说一句“没关系,我只是累了”。我想,通过类似的机制,一个人完全可以识别和抵制外界流行的道德观念,把它们与内心世界相分离。
\n如果你想要清晰的思考,就必须远离人群。但是走的越远,你的处境就会越困难,受到的阻力也会越大,因为你没有迎合社会习俗,而是一步步地与它背道而驰。小时候,每个人都会鼓励你不断成长,变成一个心智成熟、不再耍小孩脾气的人。但是,很少有人鼓励你继续成长,变成一个怀疑和抵制社会错误潮流的人。
\n如果自己就是潮水的一部分,怎么能看见潮流的方向呢?你只能永远保持质疑。问自己,什么话是我不能说的?为什么?
\n \n \n另一条路 \n\n\n如果软件的新版本要等一年后才能发布,我就会把大部分新构思束之高阁,至少过上一段时间再来考虑。但是,构思这种东西有一个特点,那就是它会导致更多的构思。你有没有注意过,坐下来写东西的时候,一半的构思是写作时产生的?软件也是这样。实现某个构思,会带来更多的构思。所以,将一个构思束之高阁,不仅意味着延迟它的实现,还意味着延迟所有在实现过程中激发的构思。事实上,将一个构思束之高阁,甚至会限制新构思的产生。因为你看一眼堆放在一边、还没实现的构思,就会想“我已经为下一个版本准备了很多新东西要实现了”,你就懒得再去思考更多的新功能了。
\n \n\n现在,创业公司有更多的理由选择互联网软件创业,因为开发桌面软件越来越乏味了。如果你现在开发桌面软件,就不得不接受微软公司的授权条款,调用它的 API,为它那个 bug 百出的操作系统伤透脑筋。历尽千辛万苦,你最终写出了一个受大众欢迎的软件,这时你可能会发现,你所做的一切其实只是在为微软公司做市场调查。
\n \n\n你能够做到这一点,意味着竞争者也能做到这一点,所以长时间工作变成了一种必须,不得不如此。因为你能做到,所以你必须做到
。这简直就是逆向的帕金森定律
\n \n\n不少公司都很想知道,什么事情可以外包,什么事情不可以外包,一个可能的答案是,公司内部所有不直接感受的竞争压力的部门都应该外包出去,让它们暴露在竞争压力之下。(我这里所说的“外包”,指的是聘请另一家公司来执行,而不是指把业务部门转移到海外。)
\n \n\n由于个人经历的关系,特雷弗·布莱克韦尔对这一点的认识可能比其他任何人都深刻。他写到:“我会进一步说,由于互联网软件的程序员非常辛苦,所以会使得经济优势根本性地从大公司向创业公司转移。互联网软件要求的那种工作强度和付出,只有当公司是其本人所有时,程序员才愿意提供。软件公司可以雇用到能干的人,让他们去干轻松的事情,也可以雇到不能干的人,让他们去干艰苦的事情。但是无法雇到非常能干的人,让他们去干非常艰苦的事情。因为互联网软件的创业不需要太多的资本,所以大公司可以与创业公司竞争的优势就所剩无几了。”
\n \n \n如何创造财富 \n\n\n交换媒介的优点是,它使得交易可以进行下去。缺点是,它往往模糊了交易的实质。人们觉得做生意就是为了挣钱,但是金钱其实只是一种中介,让大家可以更方便地获得自己想要的东西。大多数生意的目的是为了创造财富,做出人们真正需要的东西。
\n \n\n金钱不是财富,而只是我们用来转移财富所有权的的东西。
\n \n\n公司就是许多人聚在一起创造财富的地方,能够制造更多人们需要的东西。
\n \n\n我们这个世界,你向下沉沦或者向上奋进都取决于你自己,不能把原因推给外界。
\n \n\n一个大学毕业生总是想“我需要一份工作”,别人也是这么对他说的,好像变成某个组织的成员是一件多么重要的事情。更直接的表达方式应该是“你需要去做一些人们需要的东西”。即使不加入公司,你也能做到。公司不过是一群人在一起工作,共同做出某种人们需要的东西。真正重要的是做出人们需要的东西,而不是加入某个公司。
\n对于大多数人来说,最好的选择可能是为某个现存的公司打工。但是,理解这种行为的真正含义对你没有什么坏处。工作就是在一个组织中,与许多人共同合作,做出某种人们需要的东西。
\n \n\n要致富,你需要两样东西:可测量性
和可放大性
。你的职位产生的业绩,应该是可测量的,否则你做的再多,也不会得到更多的报酬。此外,你还必须有可放大性,也就是说你做出的决定能够产生巨大的效应。
\n \n\n如果你有一个令你感到安全的工作,你是不会致富的,因为没有危险,就几乎等于没有可放大性。
\n \n\n乔布斯曾经说过,创业的成败取决于最早加入公司的那十个人。我基本同意这个观点,虽然我觉得真正决定成败的其实 只是前五人。小团队的优势不在于它本身的小,而在于你可以选择成员。我们不需要小村庄的那种“小 ”,而需要全明星第一阵容的那种“小”。
\n \n\n什么是技术?技术就是某种手段,就是我们做事的方式。如果你发现了一种做事的新方式,它的经济价值就取决于有多人使用这种新方式。技术就是钓鱼的鱼竿,而不是那条鱼。
\n \n\n只要懂得藏富于民,国家就会变得强大。让书呆子保住他们的血汗钱,你就会无敌于天下。
\n \n\n“财富”这个词有很多意思,有些并不是指物质财富。我不想做深入讨论,研究到底什么才是真正的财富。我这里指的只是一种特定的技术层面上的“财富” ——人们用金钱向你交换东西。这是一种很有趣、很值得研究的财富,因为它使得你免于饥饿,而且人们是否用金钱交换这种财富取决于他们,而不是取决于你。
\n \n \n关注贫富分化 \n\n设计者的品味 \n\n\n对于建筑师和设计者,它意味着美依赖于一些精心选择的结构性元素,而不是依赖于表面装饰品的堆砌。(装饰品本身并不是坏事,只有它被用来掩盖结构的苍白时,才变成了一件坏事。)
\n \n\n如果解决方法是丑陋的,那就肯定还有更好的解决方法,只是还没有发现而已。
\n \n\n白描其实是最难画的视觉媒介,因为它们要求近乎完美的再现。用数学语言说,线条属于闭合解 [closed-form-solution],水平不够的艺术家没有办法直接解决问题,只能通过不断逼近来求解。
\n \n\n人们有时会说自己有了“状态”,我的理解是,他们这时可以控制自己的脊髓。脊髓是更本能的反应,面对难题时,它能释放你的直觉。
\n \n\n好设计是模仿大自然的设计。我不是说模仿大自然这种行为本身有多么好,而是说大自然在长期的演化中已经解决了很多设计问题。所以,如果你的设计与大自然很接近,那么它基本上不会很差。
\n \n \n一百年后的编程语言 \n\n\n在长期的职业生涯中,我发现冗余的代码会导致更多冗余的代码,不仅软件如此,而且像我这样性格懒散的人,我发现在床底下和房间的角落里这个命题也成立,一件垃圾会产生更多的垃圾。
\n \n\n编程语言进化缓慢的原因在于它们并不是真正的技术。语言只是一种书写法,而程序则是一种严格符合规则的描述,以书面形式记录计算机应该如何解决你的问题。所以,编程语言的进化速度更像数学符号的进化速度,而不像真正的技术(比如交通或者通信技术)的进化速度。数学符号的进化是缓慢的渐变式变化,而不是真正技术的那种跳跃式发展。
\n \n\n我已经预测到了,一旦未来硬件的性能大幅提高将会发生什么事。新增加的运算能力都会被糟蹋掉。
\n在我学习编程的年代,计算机还是稀罕玩意。我记得当时使用的微机型号是 TRS-80,它的内存只有 4K,为了把 BASIC 程序装入内存,我不得不把源码中的空格全部删除。我一想到那些极其低效率的软件,不断重复某些愚蠢的运算,把硬件的计算能力全部占用,就感到无法忍受。但是,我的这种反应是错的,我就像某个出身贫寒的穷孩子,一听到要花钱就舍不得,即使把钱用在重要场合(比如去医院看病)都会觉得难以接受。
\n \n \n书呆子的复仇 \n\n如果你想在软件业获得成功,就使用你知道的最强大的语言,用它解决你知道的最难的问题,并且等待竞争对手的经理做出自甘平庸的选择。 \n \n梦寐以求的编程语言 \n\n\n编程语言不是存在于真空之中,“编程”其实是及物动词,黑客一般都是为某个系统编程。在现实中,编程语言总是与它们依附的系统联系在一起的。
\n \n\n无法以一种语言本身的优缺点评判这种语言。另一个结果则是,只有当一种语言是某个系统的脚本语言时,它才能真正成为编程语言。如果你对此很吃惊,觉得不公平,那么我会跟你说不必大惊小怪。这就好比大家都认为,如果一种编程语言只有语法规则,没有一个好的实现 [implementation],那么它就不能算完整的编程语言。这些都是很正常很合理的事情,编程语言本来就该如此。
\n \n\n你只需要不停地重复同一句话,最终人们将会开始倾听。人们真正注意到你的时候,不是第一眼就看到你站在那里,而是发现过了这么久你居然还在那里。
\n \n\n著名散文家 E.B. 怀特说过,“最好的文字来自不停的修改”。
\n \n\n为了写出优秀软件,你必须同时具备两种相互冲突的信念。一方面,你要像初生牛犊一样,对自己的能力信心万丈;另一方面,你又要像历经沧桑的老人一样,对自己的能力抱着怀疑态度。在你的大脑中,有一个声音说:“千难万险只等闲”,还有一个声音却说“早岁哪知世事艰”。
\n这里的难点在于你要意识到,实际上两种信念并不矛盾。你的乐观主义和怀疑倾向分别针对两个不同的对象。你必须对解决难题的可能性保持乐观,同时对当前解法的合理性保持怀疑。
\n做出优秀成果的人,在做的过程中常常觉得自己做得不够好。其他人看到他们的成果觉得棒极了,而创造者本人看到的都是自己作品的缺陷。这种视角的差异并非偶然,因为只有对现状不满,才会造就杰出的成果。
\n \n\n因此现实中,尽管软件功能越来越强大,内部接口却往往一成不变,成为整个系统中拖后腿的部分。
\n一种可能的解决方法是,将软件内部的接口设计成垂直接口而不是水平接口。这意味着软件内部的模块是一个个垂直堆积起来的抽象层,层与层之间的接口完全由其中的一层控制。如果较高的一层使用了较低的一层定义的语言,那么接口就由较低的一层控制;如果较低的一层从属于较高的一层,那么接口就由较高的一层控制。
\n \n\n帕金森定律 [Parkinson's Law] 的一种原始表达形式是“工作总是到最后一刻才会完成”,后来引申到计算机领域就变成了“数据总是会填满所有的空间”,更一般性的总结则是:“对一种资源的需求总是会消耗光这种资源的所有供应”。
\n \n \n设计与研究 \n\n\n设计与研究的区别看来就在于,前者追求“好” [good],后者追求“新” [new]。优秀的设计不一定很“新”,但必须是“好”的;优秀的研究不一定很“好”,但必须是“新”的。我认为这两条道路最后会发生交叉:只有应用“新”的创新和理论,才会诞生超越前人的最佳设计;只有解决那些值得解决的难题(也就是“好”的难题),才会诞生最佳研究。所以,最终来说,设计和研究都通向同一个地方,只是前进的路线不同罢了。
\n \n\n怎么理解编程语言?你不要把它看成那些已完成的程序的表达方式,而应该把它理解成促进程序从无到有的一种媒介。这里的意思是说,成品的材料和开发时用的材料其实是不一样的。搞艺术的人都知道,这两个阶段往往需要不同的媒介。比如,大理石是一种非常良好、耐用的材料,很适合用于最后的成品,但是它极其缺乏弹性和灵活性,所以不适合在构思阶段用来做模型。
\n最后写出来的程序就像已经完成的数学证明一样,是一棵经过精心修剪的树木,上面杂乱滋生的树杈 都已经被剪去了。所以,评价一种语言的优劣不能简单地看最后的程序是否表达得很漂亮,而要看程序从无到有的那条完成路径是否很漂亮。
\n \n\n画家之间甚至流传着一句谚语:“画作永远没有完工的一天,你只是不再画下去而已。”
\n \n\n“弱即是强”指的是一种软件传播的模式,由 Common Lisp 专家里查德·加布里埃尔 [Richard P. Gabriel] 于 1991 年在 Lisp: Good News, Bad News, How to Win Big 一文中首先提出。它的含义非常广泛,涉及软件设计思想的各个方面,其中的一个重要结论就是软件功能的增加并不必然带来质量的提高。有时候,更少的功能(“弱”)反而是更好的选择(“强”),因为这会使得软件的可用性提高。相比那些体积庞大、功能全面、较难上手的软件,一种功能有限但易于使用的软件可能对用户有更大的吸引力。加布里埃尔本人经常举 Unix 和 C 语言的例子,Unix 和 C 在设计上考虑了实际环境,放弃了一些功能,但是保证了简单性,这使得它们最终在竞争中胜出,成为主流操作系统和编程语言。
\n \n \n术语解释 \n\n抽象 [abstract]
: 隐藏细节。编程语言越抽象,你写出程序所需的运算步骤就越少,每一步的功能就越强。 \n算法 [algorithm]
: 完成任务的方法。 \nBlub 困境 [Blub Paradox]
: 程序员的思想往往会受到自己正在使用的语言的束缚,不相信还存在更强大的语言。 \n复杂性 [complexity]
: 算法的“时间复杂性” [time complexity] 指的是,当输入的数据量不断增加时,计算机完成过这种算法所消耗的时间 \n散列表 [hash table]
: 一种类似数据库的数据结构,存储在里面的每一段数据都有一个对应的键,使用时只要按照键名就可以取出对应的数据。 \n函数库 [library]
: 已经写好的代码片段,可以用来执行特定任务。 \n宏 [macro]
: 一个能够生成其他程序的程序。 \n元循环 [metacircular]
: 当一种语言的解释器用这种语言本身开发时,就会出现这种情况。与其说这是为了做出这种语言的一种实现,还不如说这是描述语言的一种技巧。 \n方法 [method]
: 面向对象编程中充当某个类的属性的一个子程序。 \n模块 [module]
: 一组子程序和变量,它们可以被视为是一个整体。通常情况下,模块外部的代码只能访问模块内部一部分专门对外公开的子程序和变量 \n目标码 [object code]
: 编译器产生的机器语言。 \n面向对象 [OO: object-oriented]
: 一种组织程序的方式。假定不同的类代表不同类型的数据,那么针对这些数据执行某种特定任务的代码,可以根据数据的不同被分别写进不同的类,成为这些类的方法。 \n正交的 [orthogonal]
: 彼此独立、能够以多种方式组合在一起的一组东西。(乐高积木) \n解析器 [parser]
: 读取输入的数据然后生成解析树的程序。 \n解析树 [parser tree]
: 解析器读取源码后生成的数据结构。它是将源码翻译成机器语言的第一步。 \n管道 [pipe]
: 将操作系统的各种命令连接起来的一种方式,使得一个命令的输出变成另一个命令的输入。 \n指针 [pointer]
: 一块数据,它的值是另一块数据的内存地址。 \n进程 [process]
: 在同时运行多个程序的操作系统中,同时被运行的程序之一。 \n质量保证 [QA: Quality Assurance]
: 软件行业中负责找出和登记 bug 的人。 \n递归 [recursive]
: 一种调用自身的算法。 \n ","category":{"name":"Notes"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwzMDg1MjU0NjQ0","name":"book"}},{"node":{"id":"MDU6TGFiZWwzMTk2OTc2MDIx","name":"wechat-post"}}]},"reactions":{"totalCount":0,"edges":[]},"comments":{"edges":[]}}
\ No newline at end of file
diff --git a/issues/26.json b/issues/26.json
new file mode 100644
index 0000000..911a88e
--- /dev/null
+++ b/issues/26.json
@@ -0,0 +1 @@
+{"id":"MDEwOkRpc2N1c3Npb24zNDExMDkx","title":"暗淡蓝点 (Pale Blue Dot)","bodyHTML":"「暗淡蓝点」,是一张由旅行者1号 拍摄的著名地球照片之一,显示了地球悬浮在太阳系漆黑的背景中。亦由这张照片使美国著名天文学家卡尔·萨根博士因而得到灵感,写成了《Pale Blue Dot》。
\n \n再来看一眼这个小点。就在这里。这就是家。这就是我们。在这个小点上,每一个你爱的人,每一个你认识的人,每一个你听说过的人,每一个人,无论他是谁,都曾经生活过。我们所有的快乐和挣扎,数以千万自傲的宗教信仰、思想体系观念意识,以及经济学原理教义,每一个猎人或征服者,每一位勇士或是懦夫,每一个文明的缔造者或摧毁者,每一位君王或农夫,每一对陷入爱河的年轻伴侣,每一位为人父母者,所有充满希望的小孩,发明家或探险者,每一位灵魂导师,每一个腐败的政客,每一个所谓的‘超级巨星’,每一个所谓的‘最伟大领袖’,每一位我们人类史上的圣人或是罪人……我们的一切一切,全部都存在于这样一粒悬浮在一束阳光中的尘埃上。
\n\nLook again at that dot. That's here. That's home. That's us. On it everyone you love, everyone you know, everyone you ever heard of, every human being who ever was, lived out their lives. The aggregate of our joy and suffering, thousands of confident religions, ideologies, and economic doctrines, every hunter and forager, every hero and coward, every creator and destroyer of civilization, every king and peasant, every young couple in love, every mother and father, hopeful child, inventor and explorer, every teacher of morals, every corrupt politician, every “superstar,” every “supreme leader,” every saint and sinner in the history of our species lived there--on a mote of dust suspended in a sunbeam.
\n \n地球,只是浩瀚宇宙竞技场上一个小小的舞台。想那鲜血流淌成的河流,仍由那些帝王将相挥洒。所以他们的胜利与荣耀,可以让他们成为这样一颗小小点的某一区间上,瞬间而逝的主人。想想有些永无止境的残暴,竟然就发生在这个小点上某个角落里的一群人、与几乎分不出任何区别的同样这一个小点上的另一个角落的另一群人之间。他们之间的误解能有多频繁,他们之间想灭掉对方的愿望能有多迫切,他们之间互相的仇恨能有多炙烈。
\n\nThe Earth is a very small stage in a vast cosmic arena. Think of the rivers of blood spilled by all those generals and emperors so that, in glory and triumph, they could become the momentary masters of a fraction of a dot. Think of the endless cruelties visited by the inhabitants of one corner of this pixel on the scarcely distinguishable inhabitants of some other corner, how frequent their misunderstandings, how eager they are to kill one another, how fervent their hatreds.
\n \n我们的故作深沉,我们想象出来的自我重要性,我们以为自己在宇宙里有什么特权的错觉,一直被这颗发着微弱蓝光的小点挑战着。我们的这颗星球,是一粒孤孤单单的微尘,被包裹在宇宙浩瀚的黑暗中。在我们有限的认知里,在这一片浩瀚之中,没有任何迹象表明救助会从别处而来帮助我们救赎自己。
\n\nOur posturings, our imagined self-importance, the delusion that we have some privileged position in the Universe, are challenged by this point of pale light. Our planet is a lonely speck in the great enveloping cosmic dark. In our obscurity, in all this vastness, there is no hint that help will come from elsewhere to save us from ourselves.
\n \n目前为止,地球是我们唯一所知有生命居住的世界。没有其他地方——至少是在不远的未来里,可供我们这一物种移民。造访是可以的,但尚不能常驻。不管你喜欢还是不喜欢,目前为止只有地球是我们的立足之地。
\n\nThe Earth is the only world known so far to harbor life. There is nowhere else, at least in the near future, to which our species could migrate. Visit, yes. Settle, not yet. Like it or not, for the moment the Earth is where we make our stand.
\n \n有人说,天文学是一门令人谦卑的、同时也是塑造性情的学问。也许没有什么能比从遥远太空拍摄到的我们微小世界的这张照片,更能展示人类的自负有多愚蠢。对我而言,这也是在提醒我们的责任所在:更和善的对待彼此,并维护和珍惜这颗暗蓝色的小点——这个我们目前所知唯一的家园。
\n\nIt has been said that astronomy is a humbling and character-building experience. There is perhaps no better demonstration of the folly of human conceits than this distant image of our tiny world. To me, it underscores our responsibility to deal more kindly with one another, and to preserve and cherish the pale blue dot, the only home we've ever known.
\n \n
","category":{"name":"Notes"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwzMDg1MjU0NjQ0","name":"book"}}]},"reactions":{"totalCount":0,"edges":[]},"comments":{"edges":[]}}
\ No newline at end of file
diff --git a/issues/29.json b/issues/29.json
new file mode 100644
index 0000000..504ed5c
--- /dev/null
+++ b/issues/29.json
@@ -0,0 +1 @@
+{"id":"MDEwOkRpc2N1c3Npb24zNDExMjA5","title":"在路上..🏃🏻♂️.","bodyHTML":"🤔 在迷茫,消极,思考中寻找自己的人生...
","category":{"name":"Notes"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwzMDg1NjU4NzMw","name":"thinking"}}]},"reactions":{"totalCount":1,"edges":[{"node":{"id":"MDE4OkRpc2N1c3Npb25SZWFjdGlvbjE3MzUyMQ==","content":"HEART"}}]},"comments":{"edges":[{"node":{"id":"MDE3OkRpc2N1c3Npb25Db21tZW50ODY3OTk3","bodyHTML":"2013.09.09 • from Notes
\n\n青春代表年轻,这是资本,是犯了错可以去改,跌倒了可以再爬起来的资本。虽然年轻,但她并不代表着我们可以肆无忌惮的去挥霍她。 \n也正是因为年轻,所以有很多的不确定因素,总是让人难以把握。 \n外面世界的繁华,社会的种种规则,让我这个还未步入社会的少年心生胆怯。这不是逃避,而是对于未知的一种不安罢了。我就像是一只迷途的羔羊,看不到前方的路......
\n \n这是一个安宁的村落,没有都市的繁华。但她却有着自己独特吸引着我,或许这就是家的魅力吧!
\n“家”是一个敏感的字。
\n因为外面的世界再繁华,也掩盖不住内心的孤独。在外求学,离开的日子久了,才发现原来我一直是以她为中心的。
\n她并不高大、繁华,但每当我遇到挫折、不顺时,最先想到的就是她。
\n她不能给予我什么,但是她确是精神的寄托,灵魂的归宿。这种精神上的支撑,不是金钱所能够衡量的。
\n我是一个普通的不能再普通的少年,但因为家里的一些事情,总让母亲寄予很高的期望,或许孩子在每个母亲的眼中都是那么的不平凡吧。
\n月亮依旧明亮,繁星还是满天,但是此时仰望星空却是【思绪万千】,心境与小时候大相径庭。 不知是视野的开阔让自己变得成熟起来,还是都市的繁华让自己迷失了......节奏的打乱让我有点不知所措。
\n单纯的心也在求知的道路上不断的发生着改变,不知是喜还是忧。
\n记得小时候没有电视,每天下午放学后,我每天晚上最喜欢做的事就是搬张小凳子,坐在院子里,月亮将灯光照不到的地方,映得惨白,而我则是对着破旧的土房的墙壁发呆。 墙壁上那灯泡发出的那昏暗的,发黄的光会吸引来好多的飞蛾,而墙上的壁虎估计每天晚上的这个时候都是最享受的时刻。而我看壁虎捕食,抬头仰望星空也成了我儿时的回忆。想想我当时是多么的幼稚与无知,看着满天的繁星说着我将来要当一名科学家,现在当一个人独处的时候还觉得儿时的“豪言壮语”不时的在耳旁回响。 小时候的生活虽然有点傻,但是确是那样的纯粹,没有烦恼,可以盯着那破旧的土墙看几个小时,看着明月,数着繁星。一切都是那么的自然,觉得就算是天塌下来,也是大人们的事情,跟自己没什么关系。
\n上学,学习这些词可以说是伴着自己的成长的,甚至觉得小孩就应该去上学,是很自然,很理所当然的事情。
\n在我上初三时,第一次跟父母说我不想念书了。因为刚上初中时我们班有六十多个人,中途也时不时的有几个退学,我当时并没有在意。但是当到中考前两个多月时一下子又少了好多人,人数从刚来学校时的六十多个锐减到二十多个人的时候,我的心里不是那么平静了。我在放星期时就回家跟我妈说:“妈,我不想上学了!”不知道父母当时是什么心情,只是问我“你现在不上学,你能干什么,你能干了苦力活吗,能下了苦吗,一天老晒在太阳下,你行吗!”我当时沉默了......我也忘记自己当时是怎么想通的,去了学校,参加完了中考,算是上了个高中。高中的学习虽没多好,也不算虚度。
\n但是这一切都在上完高中后发生了改变,高考虽不是很理想,但也算是我的正常发挥了,我也觉得算是对得起自己了。
\n我记得当时我是满心期待的迎来了了我所谓的“大学生活”。
\n我跟我爸坐的是晚上12点的火车,我第一次有了心痛的感觉,我跟我爸都是站票,我爸看到旁边的青年躺在那里占着两个位置就问了一下,能不能让出一个,那个青年说不让那那种语气让我永生难忘...
\n早上6点下的火车,到了所谓的“学校”,我傻了眼,觉得上天跟我开了一个天大的玩笑,“一栋上世纪八九十年代的2层楼就是所谓的教室,两个水泥地的篮球场就是所谓的操场,在操场旁边还有两个新建的活动板房就是所谓的大教室”。在这大教室里上课算是让我真正的体会到了什么叫做冬冷夏热。
\n“大一”一年还算正常,我思想的转变是发生在“大二”,因为我发现逃课成了普遍现象,而且缺课人不在少数,我就开始在想难道那张“证”真的就那么重要,有了它真的就能有工作?学习究竟是为了什么。学习真的能够改变命运?我发现自己变得多愁善感起来了,时不时的想写点东西。还记得我上高中时最讨厌的就是作文课,尤其是怕被老师叫上去读自己的作文。我一直都觉得我对写东西是有阴影的。
","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"replies":{"edges":[]}}},{"node":{"id":"MDE3OkRpc2N1c3Npb25Db21tZW50ODY4MDI3","bodyHTML":"空
\n我想寫點什麽,但是卻不知如何下筆,努力的想,又怎麼也理不出思緒,有點混亂... 我時常會有一種与世格格不入的感覺(也許是我太高估自己了),我常常會有一種感覺,感覺自己就是一切,又覺得自己很是渺小,在矛盾中往复...
\n人是怎樣的一種存在,從出生到死亡要有怎樣的經歷,才算完滿?思想賦予人的力量是偉大的(我不懂哲學,但卻總是喜歡把一些問題複雜化去究其本質,其實我也不知道哲學是不是研究這個的。可能這衹是我所認為的,不一定對),讓人能夠去深入的去思考一些事物。當你把一件事物反複的想時,可能你會有所發現【我當初就想過錢这種東西,錢本身是沒有什麼價值的(廢紙一張而已),它衹是一種驅使人力推動社會發展的工具罷了。我想當社會高度發達時,每個人的思想都是積極的,向上的能夠把建設社會,實現社會大衕當作一種本能時,我想錢這種東西應該就可以退出歷史的舞颱了吧(我沒看過有关与經濟方麵的書籍,可能我說的是十分的可笑与幼稚吧)】,也許事物都是如此,有著自己既定的軌跡,從產生到消亡。但是當我用衕樣的方法去思考人時,我迷茫了...
\n人的出現是爲了什麽,有這怎樣的軌跡,終其一生的目的又是爲了什麽?我有點混亂了... 留名千古?還是遺臭萬年?(還是爲了我所說的建設社會,實現大衕)真的衹是這些嗎?在我看來這一切都是空的,因為我覺得它們之間并沒有本質上的區別,人終將會被湮滅在浩浩蕩蕩的歷史的長河中,連一粒沙子也算不上,這也僅僅是對于我們所生活額星球而言人就這般的渺小(可能是我太過於消極了)。當你放眼太空時,地球也不過塵埃大小罷了,在這以光年為距離,億年為時間單位的茫茫太空中,人生不過是一眨眼的事情。
人是偉大的,思想是(暫時沒想到),但是在時間与空間的面前卻是那麼的渺小与脆弱。這使我感覺不到我所存在的價值(也許根本就是一毛不值)...
\n也許我會一直迷茫下去(其實我也一直在不斷的給自己定位,我也很想知道自己是怎樣的一個人,別人是不是也跟我一樣啊),或許有一天我真能悟出人活著到底是爲了什麽(雖然貌似是不可能的... 所以我更期待的是有人能夠為我解惑,一起探讨。
\n當我用言语去表達我的思想時,我總覺得少了點什么(所寫非所想),可能是我的表達能力有限吧。既然寫不出來,就讓它永遠埋在心底吧,最起碼不会覺得空蕩蕩的。
\n人?
\n人是怎樣的一種存在?
\n人生在世不過區區幾十載,忙忙碌碌,到底是為了什麽,錢嗎?還是名聲和地位?
\n我搞不懂,為什麽會有人這個物種,而人的存在又是爲了什麽???我一直在苦苦的思索,掙扎著,百思不得解,迷茫...
\n在中學时代,學習,考試就是一切,考試在我看來衹不過是一種形式,它衹會讓人變得麻木,使人成為為考試而學習的工具;大學時代,算是進入了半個社會,這才讓我體會到了什麽是現實,小時候的那些想法是多麼的荒謬,天堂就好比是那鏡中花,水中月,是那樣的望不可及。
\n人、人生 、命運對我來說都是很抽象的東西,我苦苦思索不得其解。從小老師就告訴我們“要好好學習,知識能夠改變命運”,我一直都很是質疑,我想不通知識与命運有何關係,日後要達到何種程度,取得怎樣的成就才算是改變了命運,我迷茫... 我不知道,我連什麽是人、什麽是人生都不知道,又何以去談命運。我發現我徹底迷茫了...
\n多年來的學習並沒有讓我充實,反而讓我覺路是越走越暗,心裡是越來越空... 讓我覺得与這個世界是格格不入。
\n我發現我的思緒有點混亂,一些若有若無的東西時常使我睏惑,難道是我喜歡把問題複雜化,爲什麽會這樣呢,我不知道了...
\n最近心裡老是感覺空空的,接下來的路該何去何從... 或許老天也不知道吧。
\n俗话说“人为财死,鸟为食亡”。所谓的生活,就是生下来,活下去。父母生下了你,怎样活是自己的事。但现在的社会没有钱,很显然是活不下去的,要不然国家也就不会设立低保了。所以我们想要生存,想要更好的生活,不得不变的世俗。环境可以改变人,规则可以驱使人。
\n《空》、《人?》让我是越写越迷茫,这个世界的复杂或许只有等走出去了,闯出自己的一片天,才有自己的发言权。
","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"replies":{"edges":[]}}},{"node":{"id":"MDE3OkRpc2N1c3Npb25Db21tZW50ODY4MDM3","bodyHTML":"2014.01.25 • from QQ日志
\n浑浑噩噩,日子一天天的在漫无目的中悄然溜走。大脑犹如生锈的机器,懒得或者说不敢去转动。生怕这将是一次毁灭。吃饭,睡觉玩游戏成为每天的“任务”。让人乏味,无趣。
\n没心没肺的的日子过久了,会使人麻木。什么都不去想,什么都不去做,我真很想对自己说一句:“你他妈的是废物吗?”可是我没有勇气。
\n废物或许还有被回收利用的一天,可是我呢?价值何在...
\n近似残废的身体托着一无是处的脑袋。不会思考,但却本能的知道饿,要吃...难道这就是“人”。
","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"replies":{"edges":[]}}},{"node":{"id":"MDE3OkRpc2N1c3Npb25Db21tZW50ODY4MDQy","bodyHTML":"2014.04.14 • from QQ日志
\n不知道是不是停电的缘故,无端的从脑海里闪过好多想法,突然觉得自己好幼稚(呵呵),黑色让天气降温,随之而来的是人的(降温),最近的日子过得有点得过且过了,这样的日子过久了会使人麻木,头脑也会迟钝。
\n希望还来得及,我已经浪费了不少,以后不知道还有多少是属于自己的。未知并不可怕,黎明前的黑暗,让等待成为煎熬,永远不会有人知道黑暗的背后是朝阳,还是末日。
\n活一天就要给自己一个信念。执着总会有希望(呵呵,我都觉得是自己在安慰自己)。
\n曾经的的我们是那样的懵懂无知,或许正是这份无知让我们看起来都是那样的天真。但时间不会停止,人总是会长大,当学会思考时真不知道是该喜还是忧。
\n看多了,听多了,想多了或许就活明白了。
\n其实人生就像钟摆,看似只有左右两个可能,其实确实只有左右两个可能...你可以说钟摆摆动的过程中延展了无数可能,但那不是可能,只是通往可能的路径,最终你不是摆到左,就是摆到右。一切皆有可能,但所谓一切也不过或左或右两种可能,只有居中不变万万不能,除非钟摆坏掉,而那是生命静止的模样。
\n钟摆坏掉,生命静止,并不可怕,可怕的是精神上的空虚,这是物质所不能填补的。
\n内心的空虚只能用我的胡思乱想来填充了,这样最起码不会空荡荡的,让自己知道我其实还是一个人。
","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"replies":{"edges":[]}}},{"node":{"id":"MDE3OkRpc2N1c3Npb25Db21tZW50ODY4MDQ4","bodyHTML":"2014.06.18 • from weChat朋友圈
\n口袋就剩22块5毛钱,突然觉得自己是那样的孤独与无助,希望自己能够尽快的成长起来。 ——献给年少无知的自己
","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"replies":{"edges":[]}}},{"node":{"id":"MDE3OkRpc2N1c3Npb25Db21tZW50ODY4MDYw","bodyHTML":"2014.07.31 • from Notes
\n突然觉得好无助,一个人,一个书包,跟一个傻逼似的走在熙熙攘攘的大街上。觉得好难好难,难道自己真的错了吗?
\n虽然我也想过放弃,想要退缩,但是面子告诉我不能这样,门口的人都知道我出来了,来到了上海。如果我此刻回去,别说门口的人怎么看,我都会看不起自己的。
\n泪只能自己一个人默默的流,没有人会同情你。这是一个弱肉强食的社会,虽然路人不会落井下石,但也绝不会无缘帮助你。我要变强!想要生存,想要更好的生存。只能逼自己。
\n呵呵,天不遂人愿,外面的雨下的好大,难道是老天都在打击我吗?今天的面试感觉不怎么理想,很可能已经自己已经死掉了。拖着疲惫的身体和饥肠辘辘(一天只喝了一瓶加盐的汽水)的肚子,来到这个既熟悉(昨天来过这片区,有一个认识的同学)又陌生的地方,虽然是自己一个人,但心里还是觉得一阵莫名的踏实。呵呵,我觉得自己并没有什么太大的奢求,只求能在这个陌生的城市能够有一个睡的地方和一顿能吃饱的饭。我是来学习来了,整得我像逃荒的一样。
\n我不是没钱,我是不舍得花,我是农村出来的,父母亲都是地地道道的农民,父母亲为我是操碎了心,我只是觉得自己毕业了,也该担起父亲的重担了,这两年我觉得爸爸的头发一下子白了好多,为了多挣点钱,真是用命在换钱,我爸是帮别人铺路的,打的是零工,每天几乎都是熬通夜,要是家里的农活忙了,白天还帮我妈去地里,少的时候一天只睡三四个小时,我真怕有一天父亲的身体会垮掉。而我还没来的及报答。
\n——致落魄的自己
","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"replies":{"edges":[]}}},{"node":{"id":"MDE3OkRpc2N1c3Npb25Db21tZW50ODY4MDY0","bodyHTML":"2014.10.07 • from QQ日志
\n虽说欲望是发展的动力,但我们必须要知道:欲望既能让我们向幸福的方向发展,也会让我们向痛苦的方向发展。所以它永远是一把双刃剑。 我们因为被蚊子叮而发痒的时候,用手挠痒暂时会感到舒服;我们因为欲望而心里发痒的时候,用物质去挠痒暂时会感到幸福。但是没有欲望会更加幸福。
\n有限的东西,永远无法填补无限的空间。
我们的欲望是无限的。而所有物质,给我们带来的感受却是有限的,所以物质不会真正的满足我们。
\n這是一個物慾橫流的時代,我們不得不承認。要說沒有慾望是不可能的,活下去本身就是一種慾望,所以慾望並不可怕。重要的是怎樣能讓自己無憾。這個問題我們有思考過嗎?
\n人生不過短短數十載,在這以光年為距離,億年為時間單位的茫茫宇宙中,百年的人生不過彈指一揮間。人終其一生的目的難道就是為了名或利?還是一種自我滿足的狀態?我們真的活明白了嗎?
\n夜深人靜的時候,一個人常常在想自己需要的是什麼,這是離自己最近的,也是觸手可及的。因為太虛無縹緲的東西想多了,會讓人把什麼都看得太淡了,那就不好了。失去了生活的激情,也就沒什麼意思。所以覺得做人好難,在思想与現實間來回的穿插,在人前永遠表現出一副積極樂觀的模樣。
\n有時候甚至在想,自己要是一花一草一物就好了,因為沒有思想,或許就不會有這麼多的煩惱。
\n—— 致自己
","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"replies":{"edges":[]}}},{"node":{"id":"MDE3OkRpc2N1c3Npb25Db21tZW50ODY4MDc1","bodyHTML":"2014.10.15 • from weChat朋友圈
\n认识“人”,了解“人”,你就能人所不能。
","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"replies":{"edges":[]}}},{"node":{"id":"MDE3OkRpc2N1c3Npb25Db21tZW50ODY4MDc4","bodyHTML":"2014.12.04 • from Notes
\n我其实现在也是一片迷茫,毕业了,可是真的踏上了社会,并没有给我带来多少的兴奋和喜悦。因为感觉自己什么也不会,真是比白纸还白,我开始反思了,这么多年的学业究竟让我学会了什么?或许我不是一个好学生,上学时没有很努力的争做各科第一。当时我就觉得理解就好了,分数只是一个数字而已,可是在这个以分数说话的时代,很显然,我像个傻子一样,呵呵,活在自己的世界。
\n我只是一个大专生,一个出身农村,普普通通的大专生,没有什么特别的技能,我也不是说上的大学不好,因为毕竟那也是自己的选择,即使错了,也是自己的“原因”。但是大学的几年我真的觉得是荒废了,只是照本宣科的一些理论,而不是注重一些技能和能力方面的培养(分析问题和解决问题的能力)。如果只是这样,这样的学我上着还有什么意思,机械化流水线似的教学模式难道真的是我们的国情所决定的吗?
\n今年7月份我毕业了,家里也没什么人,工作还得自己找。于是我就上网投了几分简历,写明了是机械专业,可是似乎是老天在和我开玩笑,打来电话的是一些电话销售,房地产类的。没有办法,工作总是要找的。既然销售招人,人们也都说销售锻炼人,所以我就心想,试试看吧(我本身就是一个内向的人)。
\n我在自己的家乡都没有一个人跑出去转过太多,但是这是我第一次一个人从山西仅凭一通电话跑到了上海(害怕骗人我还在网上查了好多关于公司的资料),我应聘的是一个保险电销的工作,做了差不多3个多月,每天就是一些固定的名单,话术方面短时间内也很难再有很大的突破。我觉得这样工作不是我想要的(我不想成为一个仅仅只会靠嘴吃饭的人)。 所以我辞职了。
\n我最近也看了很多东西,虽然说不上精通,但也算有所了解。网络正在悄然地改变着人们的行为和生活方式。我不能保证我能从这门课程中学到什么,但是我觉得我正在接受着改变。
","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"replies":{"edges":[]}}},{"node":{"id":"MDE3OkRpc2N1c3Npb25Db21tZW50ODY4MDgx","bodyHTML":"2015.03.31 • from weChat朋友圈
\n不知不觉中,又长了一岁,也感觉到了自己身上的责任。生活我们不能去选择,但是努力总会有所改变。
","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"replies":{"edges":[]}}},{"node":{"id":"MDE3OkRpc2N1c3Npb25Db21tZW50ODY4MDgz","bodyHTML":"2015.06.01 • from weChat朋友圈
\n夜里的光 \n绝望里的希望 \n成为夜里的光 \n再漫长 \n都会天亮
","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"replies":{"edges":[]}}},{"node":{"id":"MDE3OkRpc2N1c3Npb25Db21tZW50ODY4MTAz","bodyHTML":"2015.11.28 • from weChat朋友圈
\n“我”是一切的根源,要想改变一切,首先要改变自己!
","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"replies":{"edges":[]}}},{"node":{"id":"MDE3OkRpc2N1c3Npb25Db21tZW50ODY4MTA0","bodyHTML":"2016.04.10 • from weChat朋友圈
\n世间最好的默契,并非有人懂你的言外之意,而是懂你的欲言又止。
","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"replies":{"edges":[]}}},{"node":{"id":"MDE3OkRpc2N1c3Npb25Db21tZW50ODY4MTA3","bodyHTML":"2016.06.19 • from weChat朋友圈
\n唉,失眠了,失去并不可怕,可怕的是从来都没有得到过,竟然会有种失去的感觉。人真是越活越矫情了。
","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"replies":{"edges":[]}}},{"node":{"id":"MDE3OkRpc2N1c3Npb25Db21tZW50ODY4MTA5","bodyHTML":"2016.06.28 • from weChat朋友圈
\n给自己制定一份计划,大脑之所以会胡思乱想,就是因为闲的蛋疼,不想还能干嘛。智慧的大脑是不会将时间浪费在一些琐事中的。想想你这段时间的堕落,真为你感到心痛。当初的三年目标都抛诸脑后了吗?就你现在的这个样子,几年后靠什么支撑一个家,哪个女人会喜欢一个没有理想,没有担当的男人。(现在的你是个男人吗,堕落,真是堕落!!!)
\n骚年努力工作吧,别幻想了,当你足够优秀,强大,总会有一件衣服在合适的时间,合适的地点出现在你的面前。
","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"replies":{"edges":[]}}},{"node":{"id":"MDE3OkRpc2N1c3Npb25Db21tZW50ODY4MTEw","bodyHTML":"2016.07.10 • from weChat朋友圈 - 非原创
\n有些人的通病是,容易看清楚别人,不容易看清楚自己。在别人的问题上可以斟酌到锱铢必较,而在自己的问题上却可以粗略到走马观花。一颗自私的心,自然豢养出一双自私的眼睛,一种计较的活法以及一腔热衷于背后说人是非的态度。一辈子看不上别人,换一种说法就是,从来没看清过自己。
","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"replies":{"edges":[]}}},{"node":{"id":"MDE3OkRpc2N1c3Npb25Db21tZW50ODY4MTM0","bodyHTML":"2016.07.27 • from weChat朋友圈
\n云层之上万里晴空,任凭下面电闪雷鸣。只要飞的够高,就能摆脱环境的束缚。
\n我要找回我所失去的状态。控制好自己的心。一切才刚刚开始。
\n
","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"replies":{"edges":[]}}},{"node":{"id":"MDE3OkRpc2N1c3Npb25Db21tZW50ODY4MTM4","bodyHTML":"2016.09.26 • from weChat朋友圈
\n太满足于现状,只会坐井观天。不看看别人的NB,永远不会知道自己处在一个什么位置。
","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"replies":{"edges":[]}}},{"node":{"id":"MDE3OkRpc2N1c3Npb25Db21tZW50ODY4MTQ5","bodyHTML":"2016.10.06 • from Assembly
\n
\n含义:Hello World
这可能是所有编程语言入门的开始,用计算机的方式,向这个世界打一声招呼。256个 </>
,256
对计算机来说也是一个比较特殊的数字,</>
程序的一个符号。用这些基本元素构成一幅有鸟儿,有河流的画面...
","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"replies":{"edges":[]}}},{"node":{"id":"MDE3OkRpc2N1c3Npb25Db21tZW50ODY4MTU0","bodyHTML":"2016.10.09 • from weChat朋友圈
\n提升自我,只为遇见更好的那个她…
","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"replies":{"edges":[]}}},{"node":{"id":"MDE3OkRpc2N1c3Npb25Db21tZW50ODY4MTU4","bodyHTML":"2016.11.04 • from weChat朋友圈
\n孤独是病,脆弱的灵魂只有经历病魔的洗礼才能一步步的强大起来!
","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"replies":{"edges":[]}}},{"node":{"id":"MDE3OkRpc2N1c3Npb25Db21tZW50ODY4MTYw","bodyHTML":"2016.11.17 • from weChat朋友圈 - 非原创
\n你认真做过的事,艰辛走过的路,仔细读过的书,可能都会影响你的言行举止。不要以为做过的、走过的、读过的,都过去了,也都不复记忆,没什么作用了,其实,那些经历仍潜藏在内心和记忆深处,不由地形成你的气质、胸襟,渐渐显示出你的改变、成长或影响你终生。
","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"replies":{"edges":[]}}},{"node":{"id":"MDE3OkRpc2N1c3Npb25Db21tZW50ODY4MTYz","bodyHTML":"2016.12.09 • from Paper - 手写
\n
","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"replies":{"edges":[]}}},{"node":{"id":"MDE3OkRpc2N1c3Npb25Db21tZW50ODY4MTY4","bodyHTML":"2016.12.26 • from weChat朋友圈
\n昨天的效率很低,犯了很多习惯性的错误。就是在做一件事情的时候不能先去完成一部分,去做后续的测试。当你把整个手头上的东西都完成后,才发现后续的步骤根本行不通时,才发现自己走了好多冤枉路。 总结:当在处理新问题时,注意自己的方式方法,尽量避免习惯上认知。
\nTODO: \n纠正自己的思维惯式,提高自己遇到新问题时的分析及处理能力。
","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"replies":{"edges":[]}}},{"node":{"id":"MDE3OkRpc2N1c3Npb25Db21tZW50ODY4MTgy","bodyHTML":"2016.12.27 • from illustrator
\n画这对兄妹的灵感来源于 0
和 1
,在计算机的世界,0
和 1
对程序猿 🐒 的意义就不用我说了… 虽然计算机的世界就 0
和 1
,通与断的两种状态,却正在一步步的改变着我们的这个时代。与道德经中的 「道生一,一生二,二生三,三生万物」
不谋而合,没读过道德经,这句话只是自己的理解(注意 GG 的眼睛 👀 ,MM 是 GG 的变体。0
代表假 false
,1
代表真 true
,做人也如此,真假一念间)
\n
","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"replies":{"edges":[]}}},{"node":{"id":"MDE3OkRpc2N1c3Npb25Db21tZW50ODY4MTg0","bodyHTML":"2017.01.02 • from weChat朋友圈
\n回头看看自己说过的话,我这样说是不是太装逼了。截止到目前为止。空间,朋友圈,已经发了七八天的总结与心得。一个习惯的养成最快需要21天(也不知道是不是忽悠人的,现在就当是真的吧)。当这21天完成时,我将默默坚持自己的理想与追求。就不到处装逼炫耀了(我已经违反了一条重要的做人原则,感觉自己最近太高调了,这样不好)。哈哈。希望那些看到我那些乱七八糟总结的每天都能对你们有一点点的触动。因为人活一世,如果只爱钱,生活难免有些乏味。
","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"replies":{"edges":[]}}},{"node":{"id":"MDE3OkRpc2N1c3Npb25Db21tZW50ODY4MTg3","bodyHTML":"2017.01.14 • from weChat朋友圈
\n不知不觉中就已过去了20天。学到了很多,但是不幸的是发现不会的更多了。原来,知道与不知道是成正比的,知道的越多,才发现不知道的也愈多。(好奇害死猫,不好奇,也许猫不会死,但那还是猫吗?。。。)
","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"replies":{"edges":[]}}},{"node":{"id":"MDE3OkRpc2N1c3Npb25Db21tZW50ODY4MTk2","bodyHTML":"2017.01.16 • from Notes
\n有时候真的觉得很💔,遇到❓,🚷会给你解决方案🚦🛠🛡💵(haha ha...)。只能自己看官方📜,每天👀的🔤....,比汉字还多(终究还是没能绕🉐️开[当年想选跟💻相关的专业,因为成绩一般,英语太差<虽然差,但好在我很稳定,(💯+ 5️⃣0️⃣)分我每次都能拿4️⃣5️⃣🔟分,虽然还有3️⃣4️⃣🔟分的时候,就不说出来丢🚶🏿了。🤣>,就放弃了,但现在又绕了回来,看来有些事情是🏃🏽不了的])。 虽然现在我都不知道在忙活些啥,但我很享受现在的状态,每天⌨️代码,🎧🎶,刷刷脸书,推特啥的。才发现我的英语依旧那么烂。哈哈(不然,📝这段就不是方块字了,怎么也是个🔡啥的,这样才能装一下那个啥)。✍🏻了这么多,是因为我貌似又失眠了,睡不着总🉐️✍️点啥打发一下🕰。
\n 👣
\n 👣
\n 👣
","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"replies":{"edges":[]}}},{"node":{"id":"MDE3OkRpc2N1c3Npb25Db21tZW50ODY4MjAx","bodyHTML":"2017.02.19 • from Notes
\n观,内外 \n后,自省
\n表,如一 \n象,万千
","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"replies":{"edges":[]}}},{"node":{"id":"MDE3OkRpc2N1c3Npb25Db21tZW50ODY4MjAz","bodyHTML":"2017.02.25 • from Notes
\n夜,漫漫 \n學,無止
\n心,所思 \n靜,獨守
\n暗,無眠 \n時,不怠 \n光,如梭
\n恨,不才 \n吾,之命
\n自,始終 \n制,不堅
","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"replies":{"edges":[]}}},{"node":{"id":"MDE3OkRpc2N1c3Npb25Db21tZW50ODY4MjA1","bodyHTML":"2017.04.05 • from weChat朋友圈
\n今天清理之前使用了差不多快两年的 DELL 笔记本,本以为会有好多东西都要整理出来。没想到的是,从前视若珍宝的 code,各种 tool,破解包,现在看来也不过就是一堆垃圾。成长似乎就是回头看从前自己,就一个傻字可以概括。(现在也似乎也明白了,能力是不需要备份的,copy 的东西,总有弄丢的一天。所以要有一种方法,能让零散的知识片段形成体系。而自己真正需要的是一个索引,而不是一堆杂乱无章的片段(片段好比叶子,而体系才是真正的树,索引就好比树的节点,而我所要寻找的则是根))这导致的直接结果就是,我啥也没整理,就把系统重装了。😂(绕了一大圈,又给自己找借口了,haha...)
","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"replies":{"edges":[]}}},{"node":{"id":"MDE3OkRpc2N1c3Npb25Db21tZW50ODY4MjEx","bodyHTML":"2017.04.09 • from Notes
\n学无止境,逆水行舟!突然想谈谈我对培训的看法:培训一直讲究的是速成与方法。但在知识的道路上没有捷径可言。今天快走的十步可能需要明天的百步来填补今天所埋下的坑。方法与技巧不可否认有一定的促进作用,但是其实方法是不可复制的,不然就不会只有一个盖茨了。我之所以会坚定我的目标,是因为我相信探索其实比方法更重要,尽管这个过程是缓慢的,但我觉得是值得的。其实现在人们缺少的不是解决问题的方法,而是分析问题的能力。但这种能力没人能够教你,只能靠自己。
","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"replies":{"edges":[]}}},{"node":{"id":"MDE3OkRpc2N1c3Npb25Db21tZW50ODY4MjIy","bodyHTML":"2017.07.05 • from Notes
\n一个前端小白对刚入门的小小白的一点点微不足道的建议
\n迷茫都经历过,切记不要跟风,一切都从爬坑开始,不要怕错,不要嫌烦,按照自己的想法,把所掌握的知识去尽可能的实现出来,出来的东西可能会很丑,功能也没有,但东西都是一点点迭代出来的,代码也是需要不断的整理、合并,剔除。多处用到相同的代码,就该考虑我是不是该写个方法了。自己写的代码要反复提炼(因为自己的能力有限可能尽最大的努力写出来的也是一堆渣,提炼已经没有意义了,这时候就需要看别人的代码了,GitHub上有一大堆优秀程序员的代码都可免费供自己参考。今天模仿一个写法,用到自己的代码或项目中,明天用一个。。。长此以往会形成一个良性循环[知识面会越来越广,会思考,就会使自己慢慢地建立起逻辑]。而不是一头的的雾水,甚至是迷茫,想些没用的,到处去询问别人我该怎么去自学,我没有方向,谁能指点一下我,给我一套系统的学习方案。自己反正是没遇到这么好的人,什么都告诉我,该怎么学,该怎么做。说起来自己的前端路也是一路坎坷,本想着公司要是能遇到个大神,指点一二可能会受益良多,何曾想到从转行至今,差不多两年了,也换了几家公司,都只有我一个前端,我求谁指点呀😭,只能靠自己。作为一个被培训机构坑过的受害者,一万多元培训一个月,什么也没学到,是真的什么也没学到,不是我谦虚。就连样式需要写个CSS文件,在页面引用这种高级玩法都是当时我自己总结出来的,我这不是抱怨,甚至还想感谢这个培训机构,因为是他带我入行了)。 方向是自己给自己设定的,而不是听别人的一句话,一个建议就能对自己造成实际性的影响。
\n附上自己的 GitHub ,证明自己真的是个小白,代码现在依然写的很渣。但我会一直努力下去,我曾经迷茫过,现在也偶尔在学新东西是会迷茫,但我更坚信,自己选择的这条路,注定是条不归路。因为头发已经回不去了。。。😭
","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"replies":{"edges":[]}}},{"node":{"id":"MDE3OkRpc2N1c3Npb25Db21tZW50ODY4MjI0","bodyHTML":"2017.10.21 • from Notes
\n现在能做这行,真的可能是我与电脑的缘分。话还得从高中说起。我是一个比较努力的学习生,但并不是一个所谓的“好学生”(特指成绩好、我可不会打架,至今也不抽烟不喝酒😅,也没犯过什么大错),高考志愿现在想想真的是很重要的。
\n父母都是普普通通的农民,家里当时并没有什么人能给我提供一些比较有用的填报志愿,而我也是属于比较有主见的人。当时填写志愿我觉得比较好的就两个专业(一个是计算机,另一个是机械制造与自动化)。最后我的选择是机械制造与自动化,因为觉得可能比较好就业吧。其实当时我最想学的其实是计算机。但是以我的成绩,我的英语水平,真的是惨不忍睹。150分英语的模考,我的发挥也算是一直比较”稳定“了😂,三五十分可能就是我的极限,印象中六十多分可能也没几次。而我知道的是如果我想在计算机的这条路上走的更远,我的英语会是最大的障碍(最重要的是一直到大学毕业之前我都是一直很排斥英语的)。所以综合比较了一下,觉得还是学机械比较靠谱,起码可以当个合格的工人,有一份技能在手,挣一份安稳的工资。其实也是不错的选择。
\n我的成绩不好,只能上一个专科,但是在选择复习这件事上我从来不后悔(当时年级主任也跟我打过电话,说你来复习一年吧,还是有希望的,年纪主任是我们的化学老师)。因为我有充分的理由让自己不选择复习。一年的时间去搏一个未知数,而且只是重新去扎回题海,这样的生活不是我想要的,我一直觉得我们的教育模式是存在缺陷的,似乎只有文凭和成绩才能证明一切。
\n但是上了大专,三年后毕业出来,才发现,机械这个专业并没有我想象的那么美好。三年前是一张白纸跨入大学校门,现在也是寥寥数笔,匆匆毕业。踏入社会的我现在依旧是一张白纸。以我的成绩可能也找不到很好的公司,愿意雇我去拧螺丝。即使能够找到这样的公司,我可能也不会去了,因为我可能并不喜欢这个行业了。中国制造的路还很长... 少我一个不少。
\n我是一个很内向的人,属于跟女生说话都会脸红的那种,而且比较宅,在我们家乡上学时如此,去大学上学依旧如此,基本都是两点一线。不过这样也好,妈妈也不怕我会跑丢或迷路了😂。
\n就在这样的背景下,我要毕业了,要开始找工作了,这可把我愁坏了,我又不会说话,又不认路,还没有技能,找啥工作呢?这真的是个问题,我觉得很严重,我告诉自己这样下去不行的,我必须要出去,而且要去大城市。在6月份的时候,我一个人去了北京,不知道投了多少简历,但是很多都是销售打来的电话,各种销售(房地产,保险)。我想着我要先有份工作才好,于是就进了一家房地产,跟着主管跑过几天楼盘,后面有个考核,因为我对房产相关的东西都一窍不通,有几个不及格,可能需要重新补考,我就放弃了。从北京也就呆了十多天就灰溜溜的离开了。 在家呆了没几天就去学校把毕业证领到手了,这下我是彻底步入社会了。但是一点也没有觉得激动或者兴奋。经过北京之行,我才正真开始有些不太一样的体会。回家呆了没几天,就想着或许我可以去上海碰碰运气。来到上海后,投简历阶段基本与北京之行类似,只不过这次进的是一家保险公司。是和银行有合作的,通过电话推销保险产品,学过话术,打过电话(着实刺激了一把,我这么内向的人,找的都是什么鬼呀😅)前后差不多两个月过去了,没有业绩😶,我才发现没钱的不好忽悠,有钱人也不好忽悠,哈哈。但我真的不喜欢这种工作。脑子里只有一个想法,我要离职。在这一刻也不想多呆了。
\n就这样折腾了两次,已经到了十一月份左右。灰溜溜的回家了。又一次灰溜溜的回家了。。。当时可能是比较绝望的吧。。我都忘记了在家的那几个月是怎么度过的。但是一点也不开心☹️ ,很少出门,可能怕丢人吧。
\n在家过完年了,转眼就到了三月份(2015.3)。我还是心有不甘,再次踏上来上海绿皮火车(硬座十七八个小时吧)。说什么也不能回家了...
\n简历依旧,虽然销售依旧,但从之前的从业经验来看,这行真的不适合我,就都回掉了。但是没想到的是上海招聘玩出新花样。我是一点鉴别能力也没有(通过面试邀请,在面试中说能力与实际不符,需要参加培训,开始展开套路)。就这样还是千小心万小心的上了贼船。所谓的前端,软件什么培训,就是利用用户的知识盲点进行的各种忽悠。进行了”长达”一个月的培训,虽然什么都没学到,但是我已经要为我不负责(套路难防)的选择支付一万多的费用了。如果要问一个月到底学了什么,现在总结下来、基本就是我会写一个样式不分离的静态html,没有js(不是不想写,而是根本木有教。。。)
\n就这样,在这样的一个背景下,我在前端摸爬滚打了两年多。无基础不可怕,有人带也好呀,但是这两年多基本都是一个人过来的,没有人告诉我该学什么,遇到问题也没有人可以商量,可以讨论。现在想想心里真的很不是滋味(我觉得我可以先哭个5分钟、发泄一下,哈哈)
\n因为没有人告诉我该学什么了,所以我会尽可能的去关注大家关注的前端框架,前端知识,但是这些想法差不多在一年前有所改变了。因为我发现追框架跑,我的精力是有限的,而框架的写法是奇葩的。与其学习框架语法,倒不如抛开框架,从基础学起,所以有意无意中,自己在慢慢的向原生靠拢,只有沉淀下来的才是自己的。会用只能说明我能完成基本的任务开发,仅此而已,但这远远不够。(注:虽说想法是好的,但是我现在依然不觉得自己能力有多强,基础有多好,可能还是或多或少有点得过且过吧)
\n说了这么多,最想说的还是这可能真的是我与计算机的缘分吧,兜了一大圈似乎又回到了高中填写志愿的问题上,我因英语不好,而放弃计算机,但我现在愿意为了计算机,而重拾英语。虽然我现在也没有刻意的去学,但是我知道我在缓慢的前行着...
","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"replies":{"edges":[]}}},{"node":{"id":"MDE3OkRpc2N1c3Npb25Db21tZW50ODY4MjMw","bodyHTML":"2017.11.07 • from weChat朋友圈
\n今天总是比昨天更安全。安全不是一个决定或规则或最终状态。安全是每天的努力。
","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"replies":{"edges":[]}}},{"node":{"id":"MDE3OkRpc2N1c3Npb25Db21tZW50ODY4MjYw","bodyHTML":"2018.06.17 • from weChat朋友圈
\n今天看到朋友圈一位叔叔说话,感觉很有道理,就用自己浅薄的人生感悟评论了一下。以下是叔叔朋友圈的原话:
\n\n➡️ 一 ➡️ 起 ➡️ 学 ➡️ 习 ➡️
\n青春正是应该有梦想的年纪,没有什么可以限制你的思维,也没有什么是遥不可及的。在那些卓有成就人和事例的背后,你会发现其实所有的优秀和卓越的起初都是很普通的,只不过他们的共同点都是知道自己喜欢什么、要什么,而后就在为自己的梦想去不断地努力尝试。所以,你要大胆地去梦想自己的未来,梦想自己想从事的事业,梦想自己心仪的对象,这些都会成为你的动力!
\n学生时代是最美丽的,你所面对的是一个单纯的群体和相对纯净的社会,成绩或许是你们唯一的压力。不过成长总归是需要付出努力和代价的,孩子嘛,如果不把人生中的自我积累的年代用于拼搏和奋斗,你又哪能期许梦想呢?人生中的绝大多数时间你都在运用你后天学习的知识和技能,我们通常说的升学和就业这两大人生问题也基本上由学习决定的。所以你要努力学习并且有终身学习的习惯。多看书,知识面宽一些,你的谈吐举止和你的人生格局也会大一些!
\n我们的中学时代跟你同龄,但是见识和知识面的宽度远比不上现在的你们,当然这有一定的时代背景和客观条件上的限制。你所在的时代和能得到的支持优于我们,同样地我们的条件也优于你祖父母辈。所以我们都应该要感谢我们的时代和我们得到的支持。人在任何时候任何地方所得到的支持和帮助没有什么是理所当然的,不管是你的亲人还是今后人生里陪伴你更久的爱人,他们因为爱你所以才会为你付出,请珍惜我们所拥有的,感恩时代、感恩被爱、感恩为自己提供坚定支持的人!
\n成熟的你需要更有担当更有责任感,并成为一个完全为自己行为负责的人。对自己的行为和身边相关人的行为举止要有准则和自己的判断,法律、道德、价值观是你人生中必须要坚守的三条准则。很多人都明白法律的不可逾越性,但是往往会忽略道德和价值观,所以很多人会成为投机主义者、或见利忘义、或自私、或无情无义。孩子,一个成熟并且有修养的人绝不是不违法这么简单,请记得你人生中更多的时候是需要你有良知、有责任感、有正确的价值取向,不要盲从、不要贪图小利、尽量不要伤害别人、不能忽视自己所应该承担的责任!自我意识、责任感和正确的价值观是你今后人生中自我保护的重要手段,请记得这一点!
\n爱是人一生永恒的主题,也是人生的一个大学问。不管是爱别人还是被爱,你需要有正确的认知。虽然爱的能力大多和家庭和天性有关而不是靠学习获得的,但是希望你可以像读书那样的慎重态度去学习和总结和爱相关的一切认知和感受。爱是双向的,家人爱你和支持你的同时也需要你爱家人;爱人之间的爱同样不能总单方面索取或者被动接受,而是互动。爱包含着关爱、包容、理解、责任、付出、支持、保护等等很多积极主动的行为,所以爱是需要你经久的热情的。不要伤害爱你或者你爱的人,尤其是你人生中的女性,他们都是在最美丽的时候出现在你的生命里,请一定珍惜!同时,请记得要爱自己,懂得什么是自己需要的,什么是自己必须拒绝的,明白自己的喜好、保护好自己的身体和情感。有健康的体魄和灵魂才能享受你美丽的生活!
\n \n我的评论:
\n\n叔叔这几段话说的太对了,感觉这个社会有点浮燥(比如娱乐八卦之风盛行,很多人都想当明星,当歌手,虽然成功的那些人,背后都付出了常人难以想象的努力,但我觉得这些不是一个国家的根本。但如今各种信息,起码百分之八十以上都充斥着明星八卦。我虽然不知道这些代表着什么,但这应该是一个不太好的现象,还有很多陷阱与诱惑,也常常在干扰着我们的思维判断,生活在这样的时代,如果没有自己的一些原则底线,很容易被一些人或事带的偏离原本的方向)。做人做事,不求自己的行为能够带动或者感染到身边的朋友与家人。但是,一定要守住自己的初心,在不被那些不太美好的事物影响的前提下,尽可能地力所能及地帮助或者影响到身边的朋友。人是自私的,这句话我觉得并非都是贬义。当温饱都解决不了的时候,很多时候驱使人行为的,可能更多的则是本能,当本能与原则底线,道德问题产生矛盾与冲突时,这时候的我们该怎么办,该如何选择?... 说往往比做要来的更容易,因为根据能量守恒定律,做可能会消耗更大更多的能量,而人的本性应该是有懒惰,和精于算计的基因。往往会选择更小的代价换取更大的利益或回报。
\n学习可以弥补眼界,思维上不足。但这肯定不是一朝一夕之事,如何让自己能够从学习中获得快乐则显得尤为重要了,因为没有兴趣,或者失去兴趣,接下来的学习则会是痛苦的。
\n我认为学习与思考才是人生的两大主题。学习是攫取,获取,而思考则是将拿来的东西化为自己的东西。两者相辅相成,缺一不可
......
\n ","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"replies":{"edges":[]}}},{"node":{"id":"MDE3OkRpc2N1c3Npb25Db21tZW50ODY4MjY4","bodyHTML":"2018.06.30 • from Notes - 写给一个朋友的建议
\n我想给你提点建议,这样有助于形成自己思维方式:当遇到一个未知概念未知问题的时候,不要急于去求助别人,因为求助永远只是下下策,举个例子,以前或许你有很多问题还可以问自己的爸爸妈妈,但是程序这行,问他们,他们也只是有心无力,当你在这条路上越走越远的时候,能帮助到你的人会越来越少,不是他们不想帮助你,而是没有那个能力。
\n说一下我一般遇到问题时的一个解决思路吧:把遇到问题的点描述成一句话,刚开始会因为不懂得这方面的专业术语,而描述的比较生活化,搜到的结果其实并不准确,或者根本没搜到,但是这是必须要迈出的第一步,以后遇到问题的第一时间想到的就是搜索,这个很重要,一定要养成本能。有了第一步,接下来就要解决搜索不够准确的问题了,因为我们的技术能力薄弱,遇到的问题以我们现有能力可能不能够描述出来这很正常,我现在也时常遇到。我的做法是开阔自己的视野,多看一些技术性的文章,不要局限于某种编程语言或者某种技术,广度一定要有。看的多了就能提炼出很多技术性的关键词,这些词将来很有可能会成为搜索问题的基石。因为单词我们都知道同一个汉语意思,可能会对应多个单词,而这些单词中有生活化的也有技术专用的,当描述越来越专业的时候,结果也会越来越精确。还有需要注意的是描述一定要简短,尽量使用短语或者多个关键词叠加的方式去进行搜索。
\n你的英语很好,这是优势,要充分发挥,因为技术都是用英文写的文档。
","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"replies":{"edges":[]}}},{"node":{"id":"MDE3OkRpc2N1c3Npb25Db21tZW50ODY4Mjcw","bodyHTML":"2019.05.04
\n2014年毕业,到现在已经差不多过去了5年。 现在回过头来看以前写的东西,毒鸡汤,吐槽,反思... 真不少,挺幼稚的,这或许就是成长吧。😅
","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"replies":{"edges":[]}}},{"node":{"id":"MDE3OkRpc2N1c3Npb25Db21tZW50ODY4Mjg4","bodyHTML":"2021.05.27 • from weChat朋友圈
\n朋友:
\n为什么星星不够亮了\n为什么月亮照不出人的影子了\n为什么夏天也没那么热了\n为什么夜越来越长了\n
\n我评论:
\n星星依旧,城市灯火迷了眼\n月亮依旧,物质欲望毁了心\n夏天依旧,科技发展乱了象\n夜长依旧,物是人非没了魂\n
","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"replies":{"edges":[]}}}]}}
\ No newline at end of file
diff --git a/issues/3.json b/issues/3.json
new file mode 100644
index 0000000..24ff927
--- /dev/null
+++ b/issues/3.json
@@ -0,0 +1 @@
+{"id":"MDEwOkRpc2N1c3Npb24zMzczMjMx","title":"JavaScript 原型链","bodyHTML":"","category":{"name":"Notes"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwyMjk0NjQ2Mjcx","name":"js"}},{"node":{"id":"MDU6TGFiZWwzMDI2NDEyNzMy","name":"interview"}}]},"reactions":{"totalCount":0,"edges":[]},"comments":{"edges":[]}}
\ No newline at end of file
diff --git a/issues/30.json b/issues/30.json
new file mode 100644
index 0000000..0e95204
--- /dev/null
+++ b/issues/30.json
@@ -0,0 +1 @@
+{"id":"MDEwOkRpc2N1c3Npb24zNDExNTgw","title":"人总是喜欢在固有思维下钻牛角尖","bodyHTML":"2021.02.28
\n最近这段时间写了一个基于 vite
的 wasm-pack
(Rust -> Wasm
) 插件,遇到一个比较有意思的问题。
\n需求 \n实现一个 rsw 插件
,当 vite 服务启动后,插件会自动调用 wasm-pack
的 cli,进行 build,生成 wasm 的 npm 包,当 rust 包目录下的文件变更时,能够进行重新进行 build (热更新)。
\n问题 \n实现需求其实很简单,但是如果只是这样实现插件,虽然能用,但是体验不好。每次启动服务都会先执行 cli 的 build (耗时有点长),vite 的快速启动开发环境的体验全无。其实不分析也知道,cli 的 build 并非每次启动都需要执行。如果已经 build 过,则不需要再次执行。
\n于是,就有了第一版简单粗暴的实现方案,直接看目录中有没有 build 的文件存在,如果文件存在,则直接跳过执行,否则,执行 build。短短几行代码似乎就解决了问题。
\n// 核心代码:如果`package.json`存在则跳过执行 \n// https://github.com/lencx/vite-plugin-rsw/blob/69668e9bdb8322382e5d49d3e85b67a35354d7e0/src/compiler.ts#L82-L88 \nconst pkgPath = path . resolve ( root , getCrateName ( _crate ) , 'pkg' ) ; \n// vite startup optimization \ntry { \n fs . statSync ( `${ pkgPath } /package.json` ) . isFile ( ) ; \n console . log ( chalk . yellow ( `[rsw::optimized] wasm-pack build ${ getCrateName ( _crate ) } ` ) ) ; \n} catch ( e ) { \n compileOne ( { config : opts , crate : _crate , sync : true } ) ; \n} \n但是很快就打脸了,有一种情况是未考虑到的,就是在停止服务后修改文件,当启动服务后,因为之前 build 的文件一直都存在,所以并不会执行 build,只有在启动服务后,修改文件,才会触发热更新。
\n解决这个问题,我一直在想如何去缓存文件信息,做比较,如果两次文件内容都无变化,则文件未被修改过,但是又想到,如果文件特别多,存储读取
又会产生新的问题,感觉问题被复杂化了,但是却没什么头绪。
\n和朋友讨论这个插件,朋友的一句话点醒了我。不需要存储读取文件,因为文件内容是不需要关心的,我们其实更关心的问题是文件是否被修改,而文件是否修改,可以通过查看文件修改时间。因为 build 是后于源码修改的,所以源码的修改时间一定小于 build 目录下的文件时间。如果源码修改时间大于了 build 目录下的文件时间。则表示文件修改了,但未执行 build。
\n这也就有了下面这段代码
\n// 核心代码:比较文件变更时间 \n// https://github.com/lencx/vite-plugin-rsw/blob/8aa0d68750/src/utils.ts#L85-L127 \ntry { \n // benchmark file modified time \n const pkgMtime = fs . statSync ( benchmarkFile ) . mtimeMs ; \n const cargoMtime = fs . statSync ( cargoToml ) . mtimeMs ; \n let isOptim = true ; \n\n // run wasm-pack \n if ( cargoMtime > pkgMtime ) { \n isOptim = false ; \n return runCallback ( ) ; \n } \n\n ( function dirsMtime ( dir ) { \n for ( let f of fs . readdirSync ( dir ) ) { \n const _f = fs . statSync ( `${ dir } /${ f } ` ) ; \n\n if ( _f . isDirectory ( ) ) { \n if ( _f . mtimeMs > pkgMtime ) { \n // run wasm-pack \n isOptim = false ; \n runCallback ( ) ; \n break ; \n } else { \n dirsMtime ( `${ dir } /${ f } ` ) \n } \n } \n\n if ( _f . isFile ( ) ) { \n if ( _f . mtimeMs > pkgMtime ) { \n // run wasm-pack \n isOptim = false ; \n runCallback ( ) ; \n break ; \n } \n } \n } \n } ) ( dirs ) \n\n isOptim && optimCallback ( ) ; \n} catch ( e ) { \n // no such file or directory \n runCallback ( ) ; \n} \n总结 \n人很容易在固有思维下钻牛角尖,走到最后才发现自己虽然很努力,但似乎方向不太对。和朋友聊天,或者让自己放松一下,可能会有不一样的收获。
\n相关链接 \n","category":{"name":"Notes"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwzMDg2MDYxNzMz","name":"blog"}}]},"reactions":{"totalCount":0,"edges":[]},"comments":{"edges":[{"node":{"id":"MDE3OkRpc2N1c3Npb25Db21tZW50ODY5MjM4","bodyHTML":"协商缓存 - 当浏览器对某个资源的请求没有命中强缓存,就会发一个请求到服务器,验证协商缓存是否命中,如果协商缓存命中,请求响应返回的 http 状态为304
并且会显示一个 Not Modified
的字符串。协商缓存是利用的是【Last-Modified
,If-Modified-Since
】和【ETag
、If-None-Match
】这两对 Header
来管理的。
\n \n[MDN] HTTP 缓存
","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"replies":{"edges":[]}}}]}}
\ No newline at end of file
diff --git a/issues/34.json b/issues/34.json
new file mode 100644
index 0000000..83a457a
--- /dev/null
+++ b/issues/34.json
@@ -0,0 +1 @@
+{"id":"MDEwOkRpc2N1c3Npb24zNDE2MDk5","title":"技术词汇表 - 中英文","bodyHTML":"\n\n\n中文 \n英文 \n缩写 \n \n \n\n\n应用程序接口 \nApplication Programming Interfaces \nAPI \n \n\n用户界面 \nUser Interface \n \n \n\n解释 \ninterpret \n \n \n\n编译 \ncompile \n \n \n\n即时编译 \njust-in-time compiling \n \n \n\n服务器端 \nserver-side \n \n \n\n客户端 \nclient-side \n \n \n\n表达式 \nexpression \n \n \n\n语句 \nstatements \n \n \n\n句法 \nsyntax \n \n \n \n
","category":{"name":"Notes"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwzMDkwMTgxNDQw","name":"tech-terms"}}]},"reactions":{"totalCount":0,"edges":[]},"comments":{"edges":[]}}
\ No newline at end of file
diff --git a/issues/35.json b/issues/35.json
new file mode 100644
index 0000000..6da828f
--- /dev/null
+++ b/issues/35.json
@@ -0,0 +1 @@
+{"id":"MDEwOkRpc2N1c3Npb24zNDI0MTky","title":"这些年追过的动漫","bodyHTML":"\n以下列出的动漫,及评价,仅代表个人观点,不喜勿喷。看的动漫太多了,先列了能想起来的一部分,后面继续补充。
\n \n\n灵笼
- 世界观宏大,细节处理到极致,前几集可能看不懂,建议搭配解说一起看 \n元龙
- 枪打修真者,只能说时代变了 \n眷思量
- 画面太美,帧帧壁纸,故事情节有点一般 \n星辰变
- 时长良心,打斗效果没得说 \n白蛇传
- 好看 \n两不疑
- 有点萌 \n枕刀歌
- 打斗效果拉满 \n观海策
- 以神话,山海经,战国策等中国文化为背景 \n斗破苍穹
- 真三年之约,人物建模,打斗场面从第一部到三年之约,越来越好 \n西行纪
- 对话有点尬,每次看动漫都有种,脑子不太正常才会看这个 \n一念永恒
- 主角很怕死,但是关键时刻能够挺身而出,顺便大坑一笔 \n完美世界
- 剧情紧凑,打斗还行,就是有点翻来覆去就那几招的感觉,没啥新意 \n雪鹰领主
- 有些剧情,挺尬的,感觉一般 \n凡人修仙传
- 画风写实,剧情紧凑 \n镇魂街
\n地灵曲
\n镜·双城
\n星骸骑士
\n武动乾坤
\n山河剑心
\n魔道祖师
\n长剑风云
\n雾山五行
\n绝命响应
\n游侠战纪
\n魁拔之殊途
\n猫妖的诱惑
\n我是大神仙
\n梦塔·雪谜城
\n穿书自救指南
\n妖精种植手册
\n盗墓笔记秦岭神树
\n逆转次元:AI崛起
\n拾忆长安·明月几时有
\n \n玄机科技
\n\n武庚纪
- 主角吹牛第一,逃跑第一,有点怂。最喜欢的角色“逆天而行”和“子羽” \n斗罗大陆
- 画质,细节处理是越来越好,但是剧情越来越拖沓 \n吞噬星空
\n天行九歌
\n秦时明月
\n天宝伏妖录
\n \n若森画江湖系列
\n\n不良人
- 大帅就是大帅,以为的结局原来只是开局 \n侠岚
\n灵主
\n杯莫停
\n轨夜行
\n换世门生
\n \n若鸿、索以文化
\n\n三分片头,两分片尾,五分正片,半分内容!
\n \n\n妖神记
(若鸿) \n万界神主
(索以) \n万界春秋
(索以) \n长安幻街
(索以) \n我气哭了百万修炼者
(索以) \n \n \n灵笼解说
\n","category":{"name":"Series"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwzMTk1NTQxODE3","name":"wechat-link"}}]},"reactions":{"totalCount":0,"edges":[]},"comments":{"edges":[]}}
\ No newline at end of file
diff --git a/issues/36.json b/issues/36.json
new file mode 100644
index 0000000..8bb6e71
--- /dev/null
+++ b/issues/36.json
@@ -0,0 +1 @@
+{"id":"MDEwOkRpc2N1c3Npb24zNDI0Mjk2","title":"通用 - 组件 & 库","bodyHTML":"slider \n\n@egjs/flicking - 🎠 ♻️ Everyday 30 million people experience. It's reliable, flexible and extendable carousel. \n \nlibrary \n\nclipboard.js - ✂️ Modern copy to clipboard. No Flash. Just 3kb gzipped 📋 \n ","category":{"name":"FE"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwyMjk0NjQ2Mjcx","name":"js"}},{"node":{"id":"MDU6TGFiZWwzMDQ1ODIxNzYx","name":"react"}},{"node":{"id":"MDU6TGFiZWwzMDUyMDQ4NTAz","name":"vue"}}]},"reactions":{"totalCount":0,"edges":[]},"comments":{"edges":[]}}
\ No newline at end of file
diff --git a/issues/39.json b/issues/39.json
new file mode 100644
index 0000000..2bba0e7
--- /dev/null
+++ b/issues/39.json
@@ -0,0 +1 @@
+{"id":"MDEwOkRpc2N1c3Npb24zNDI1OTg5","title":"网站性能优化系列","bodyHTML":"","category":{"name":"FE"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwyMjk0NjQ2Mjcx","name":"js"}},{"node":{"id":"MDU6TGFiZWwzMDI2NDEyNzMy","name":"interview"}}]},"reactions":{"totalCount":0,"edges":[]},"comments":{"edges":[]}}
\ No newline at end of file
diff --git a/issues/41.json b/issues/41.json
new file mode 100644
index 0000000..1958dec
--- /dev/null
+++ b/issues/41.json
@@ -0,0 +1 @@
+{"id":"MDEwOkRpc2N1c3Npb24zNDI2MjIw","title":"lencx 的 vscode 配置","bodyHTML":"Terminal \n\nOh My Zsh - Unleash your terminal like never before. \nstarship - ☄🌌️ The minimal, blazing-fast, and infinitely customizable prompt for any shell! \n \nExtensions \n\nvsg - Explore Github repositories directly from Visual Studio Code. \nRemote Repositories - Remotely browse and edit a GitHub repository \nGitHub Copilot - Your AI pair programmer \nCodeSnap - 📷 Take beautiful screenshots of your code \nLive Share - Real-time collaborative development from the comfort of your favorite tools. \nLocal History - Save files into local history \nBracket Pair Colorizer - A customizable extension for colorizing matching brackets \nfilesize - Show the current file size in the status bar \nCode Runner - Run C, C++, Java, JS, PHP, Python, Perl, Ruby, Go, Lua, Groovy, PowerShell, CMD, BASH, F#, C#, VBScript, TypeScript, CoffeeScript, Scala, Swift, Julia, Crystal, OCaml, R, AppleScript, Elixir, VB.NET, Clojure, Haxe, Obj-C, Rust, Racket, Scheme, AutoHotkey, AutoIt, Kotlin, Dart, Pascal, Haskell, Nim... \nindent-rainbow - Makes indentation easier to read \nPrettier - Code formatter - Code formatter using prettier \nHighlight Matching Tag - Highlights matching closing and opening tags \nImport Cost - Display import/require package size in the editor \nEven Better TOML - Fully-featured TOML support \nCode Spell Checker - Spelling checker for source code \nColor Highlight - Highlight web colors in your editor \nAuto Import - Automatically finds, parses and provides code actions and code completion for all available imports. Works with Typescript and TSX \nGit Graph - View a Git Graph of your repository, and perform Git actions from the graph. \nBookmarks - Mark lines and jump to them \nQuokka.js - JavaScript and TypeScript playground in your editor. \n \nTheme \n\nShades of Purple - 🦄 A professional theme suite with hand-picked & bold shades of purple for your VS Code editor and terminal apps. One of the excellent, most downloaded, and top-rated VSCode Themes on the marketplace. Part of VSCode.pro course. \nMaterial Icon Theme - Material Design Icons for Visual Studio Code \n \nTODO \n\nTodo Tree - Show TODO, FIXME, etc. comment tags in a tree view \nBetter Comments - Improve your code commenting by annotating with alert, informational, TODOs, and more! \n \nPreview \n\nExcel Viewer - View Excel spreadsheets and CSV files within Visual Studio Code workspaces. \nImage preview - Shows image preview in the gutter and on hover \nSvg Preview - Preview for Svg files \nLaTeX Workshop - Boost LaTeX typesetting efficiency with preview, compile, autocomplete, colorize, and more. \n \nRust \n\nrust-analyzer - An alternative rust language server to the RLS \n ","category":{"name":"Tools"},"labels":{"edges":[]},"reactions":{"totalCount":3,"edges":[{"node":{"id":"MDE4OkRpc2N1c3Npb25SZWFjdGlvbjE3MDcwNA==","content":"HEART"}},{"node":{"id":"MDE4OkRpc2N1c3Npb25SZWFjdGlvbjIwMDI4Mw==","content":"HEART"}},{"node":{"id":"MDE4OkRpc2N1c3Npb25SZWFjdGlvbjIwMDI4NA==","content":"EYES"}}]},"comments":{"edges":[]}}
\ No newline at end of file
diff --git a/issues/43.json b/issues/43.json
new file mode 100644
index 0000000..7b1e6ef
--- /dev/null
+++ b/issues/43.json
@@ -0,0 +1 @@
+{"id":"MDEwOkRpc2N1c3Npb24zNDMyOTQ1","title":"Following Series","bodyHTML":"GitHub \n\n排名不分先后
\n \n\nLinus Torvalds \nBrendan Eich - Founder & CEO, Brave Software. Created JavaScript. Co-founded Mozilla and Firefox. \nSindre Sorhus - Full-Time Open-Sourcerer. Wants more empathy & kindness in open source. Focuses on Swift & JavaScript. Makes macOS apps, CLI tools, npm packages. Likes unicorns \nTJ Holowaychuk - I'm the founder and solo developer of Apex Software. I've written hundreds of open-source projects for the JavaScript and Go communities. \nLea Verou - Elected @w3ctag member, CSS WG Invited Expert, HCI researcher at MIT CSAIL. Founder of many open source projects, PrismJS probably being the most popular one. \nDan Abramov \nRyan Dahl \nLin Clark \nisaacs - Principal Engineer at GitHub npm inventor, founder npm, Inc. Former Node BDFL. All opinions are my own. Literally all of them. I own them all. He/him \nWes Bos - I create courses that make learning things like JavaScript easy and fun 🔥 \nZeke Sikelianos - Friendly open-source person localizing @github , @nodejs , and @electron . Previously @npm and @heroku \nSarah Drasner - I make tools for developers, projects, and am on the Vue.js core team. \nTobias Koppers - Author of webpack \nSean Larkin - Technical Program Manager @microsoft for @MicrosoftEdge . Javascript, webpack, Typescript. @webpack core team. @angular cli core team. \nJessica Lord - Urban designer turned open source developer. Shared knowledge champion 🎉 \nTodd Motto - 🚀 UltimateCourses.com 🐛 Google Developer Expert ⚡ \nAddy Osmani - Engineering Manager at Google working on Chrome & Web Platform \nKyle Simpson - I like to explore JS and FP techniques. Helping build a culture of engineering excellence for my employer. \nDouglas Crockford - I was born in Frostbite Falls, Minnesota. I left when I was 6 months old because it was too damn cold. My latest book is How JavaScript Works . \nJohn Resig - Chief Architect at @Khan \nJason Miller - Making the web faster at @google . Creator of @preactjs . \nFederico Zivolo - UX Engineer/Front-End Engineer. Creator of bootstrap-material-design and Popper.js. Open Source addicted. \nJohn Washam - Software Development Engineer at Amazon \nMax Stoiber - Co-Founder, @graphcdn ⚡️ Previously @gatsbyjs , before that @github after they acquired @withspectrum . ✌️ Speciality coffee geek, boulderer and skier \nEduardo San Martin Morote - Member of the @vuejs core team Speaker, trainer. From 🇪🇸, lives in 🇫🇷 \nNicholas C. Zakas \nAxel Rauschmayer \nMary Lou \n🦀 Alex Crichton \n🦀 Andrew Gallant \n🦀 Yoshua Wuyts - calm computing. he/they \n🦀 Kornel - Rust, image compression, web performance. \n \n \n\nRuan YiFeng - Stay Focused, Keep Shipping. Build Early, Build Always. Improve yourself, Write solid/simple/stupid code. \n迷渡 - Creator of vscode-deno. Currently a contributor to Deno @denoland . \nEvan You \nHao Chen - 芝兰生于空谷,不以无人而不芳。 \nafc163 - Life is a box of chaos \nchencheng (云谦) - Front-end developer at alipay, creator of @umijs , @dvajs , father, roadhog, babel-plugin-import... \n稚晖 - 野生钢铁侠本侠。 \nPhodal Huang - 待我代码编成,娶你为妻可好 \n ","category":{"name":"Series"},"labels":{"edges":[]},"reactions":{"totalCount":2,"edges":[{"node":{"id":"MDE4OkRpc2N1c3Npb25SZWFjdGlvbjE3MzY1MQ==","content":"HEART"}},{"node":{"id":"MDE4OkRpc2N1c3Npb25SZWFjdGlvbjE3MzcxMA==","content":"HEART"}}]},"comments":{"edges":[]}}
\ No newline at end of file
diff --git a/issues/44.json b/issues/44.json
new file mode 100644
index 0000000..3eed928
--- /dev/null
+++ b/issues/44.json
@@ -0,0 +1 @@
+{"id":"MDEwOkRpc2N1c3Npb24zNDMzNjgw","title":"阅读打卡","bodyHTML":"\n \nLinux \n\nGit \n\nWeb \n\nCSS Fingerprinting - Pure CSS device fingerprinting. \nHow to Fill an Array with Initial Values in JavaScript \nThe JavaScript Array Handbook – JS Array Methods Explained with Examples \n5 Things to Consider Before You Build Your App \nWhat if… you could use Visual Studio Code as the editor of in-browser Developer Tools? \nThe Single-Page-App Morality Play \nScroll Shadows With JavaScript \nAll About Svelte, the Much-Loved, State-Driven Web Framework \nMicro Frontends With Webpack \nAn in-depth perspective on webpack's bundling process \nHow I Built My Blog \nBuilding a type-safe dictionary in TypeScript \nReact, structured data, and SEO \nRome will be written in Rust 🦀 \nReact Hooks for infinite scroll: An advanced tutorial \nAn Intro to JavaScript Proxy \nJavaScript vs JavaScript: Round 2. Fight! \nThe Future of CSS: Cascade Layers (CSS @layer) \nDesigning Beautiful Shadows in CSS \nHow to Build a CSS Library with Vite.js \nBest practices for using trailing commas in JavaScript \nSynchronous vs Asynchronous JavaScript – Call Stack, Promises, and More \nExploring the CSS Paint API: Blob Animation \nWhat’s New With DevTools: Cross-Browser Edition \nReact Video Player Component Using Hooks, TypeScript, and xState \nBundling non-JavaScript resources \nHow to create Music player with pure HTML, CSS, JS \nCreate draggable components with React-Draggable \nInfinite scrolling in React with intersection observer \nMemoizing async functions in Javascript \nEvent Loops in NodeJS – Beginner's Guide to Synchronous and Asynchronous Code \nJS: All You Can Weak! \nHow to make realtime APIs with NodeJS and ReactJS using Socket.io \nUnderstanding JavaScript currying \nDeno on MDN \nLoading Third-Party JavaScript \nJavaScript vs JavaScript. Fight! \nWhy WebAssembly Frameworks Are the Future of the Web \nHow to Create a Video Player in React \nAlgorithms and Data Structures for JavaScript Engineers \nSimple monorepos via npm workspaces and TypeScript project references \nStay alert \nMagical Marbles in Three.js \nUI Design Tactics — Part 1 \nAbout Web Components \nCreating a Force Graph using React, D3, and PixiJS \nHow to use finite state machines in React? Explained by a frontend developer \nJavaScript Promises: then(f,f) vs then(f).catch(f) \nA Guide to Git Interactive Rebase, with Practical Examples \n10 Predictions for the Future of Computing or; the Inane Ramblings of our Chief Scientist \nHow to stop re-rendering lists in React? \nFaster (and smaller) uploads in Discourse with Rust, WebAssembly and MozJPEG \n4 JavaScript Projects To Build FAST And Get Hired In 1 Month \nIs Node.js Really Single-Threaded? \nThe Command Pattern in TypeScript — Encapsulating Logic to Increase Maintainability \nUse Closures for Memory Optimizations in JavaScript (a case study) \nUsing WebAssembly threads from C, C++ and Rust \n🔥 The data model behind Notion's flexibility \nHow to design a system to scale to your first 100 million users \nnpm audit: Broken by Design \n🔥 Designing a Dataflow Editor with TypeScript and React \nBuilding WebRTC Video Chat Applications \nCaptain Stack — Code suggestion for VSCode - This feature is somewhat similar to Github Copilot's code suggestion. But instead of using AI, it sends your search query to Google, then retrieves StackOverflow answers and autocompletes them for you. \nTemporal: getting started with JavaScript’s new date time API \nSolidJS Official Release: The long road to 1.0 \nMoving Backgrounds: When, Why, and How to Use Them \n🔥 Introduction to Data Types: Static, Dynamic, Strong & Weak - static doesn’t necessarily mean strong and dynamic doesn’t necessarily mean weak \nUnderstanding Sorting Algorithms \nImplementing Private Fields for JavaScript \nIntroducing Utopia - Design ❤️ Code \nNew browser APIs to detect JavaScript performance problems in production \nWeb3: A New Web for a New World \nIntro to Asynchronous JavaScript \nWhat is Vite and how to use it with React \n \nRust \n\nGitHub \n\nVS Code \n","category":{"name":"Series"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwzMDg2MDYxNzMz","name":"blog"}},{"node":{"id":"MDU6TGFiZWwzMTk1NTQxODE3","name":"wechat-link"}}]},"reactions":{"totalCount":4,"edges":[{"node":{"id":"MDE4OkRpc2N1c3Npb25SZWFjdGlvbjE3MzkxMA==","content":"HEART"}},{"node":{"id":"MDE4OkRpc2N1c3Npb25SZWFjdGlvbjE3MzkxMQ==","content":"HOORAY"}},{"node":{"id":"MDE4OkRpc2N1c3Npb25SZWFjdGlvbjE3MzkxMg==","content":"THUMBS_UP"}},{"node":{"id":"MDE4OkRpc2N1c3Npb25SZWFjdGlvbjIwMDI4NQ==","content":"ROCKET"}}]},"comments":{"edges":[]}}
\ No newline at end of file
diff --git a/issues/45.json b/issues/45.json
new file mode 100644
index 0000000..73757b5
--- /dev/null
+++ b/issues/45.json
@@ -0,0 +1 @@
+{"id":"MDEwOkRpc2N1c3Npb24zNDM0MDcz","title":"组件解耦的一些思考","bodyHTML":"\n自前端三大框架 ( Vue , React , Angular ) 以及后起之秀 Svelte 出现之后,各种组件,轮子。大家都没少造过,一些大公司或者有精力的人,在研究 LowCode
或 NoCode
,也有一些落地或者具体方案。
\n \n背景 \n但就我自身经历及接触项目而言,项目还是停留在如何编写组件的层次上,简单的实现一些复用。一些历史项目因为需求的迭代,功能在不断增加,写代码的人员也在不断更替,交接。就会导致最后的接手项目的人痛苦不堪,重构?不现实,时间不够,之前的需求也不清楚。继续保持?就面临着怎么去在原项目之上继续迭代。 进退两难...
\n在之前的需求毫不知情的情况下,如何完成需求功能的迭代,UI 改版?只能通过全局搜索一些关键词,关键字去一步步向上 debug 源码。如果代码中牵扯过多的业务逻辑,就完全懵逼了,没人知道之前的需求是什么?_?!!!
\n以 React 为例,因为每个人都有自己对组件的理解,不同的人站在不同的维度去封装,就导致最后的项目结构,代码结构也是千差万别。
\n\n无状态组件
: 不涉及过多状态交互,很容易实现,大家的思路都差不多。 \n有状态组件
: 一旦涉及到状态,业务逻辑,交互。一个组件就变得不再可控。每个人的风格也都体现的淋漓尽致!\n\n组件内发起请求,各种请求,大量接口相互依赖。如果涉及到多个接口并行,后一个接口依赖上一个接口的返回值,写法又是各有特色。 \n出现大量的业务逻辑分支,根据业务 return
出不同的组件 ╥﹏╥ \n直接在组件内实现一个或多个子组件 (ノへ ̄、) \n子组件上挂载着大量的 props
,属性有时候多到令人发指,有数据,方法,状态,自定义的 xxx,各种传递。 o(╥﹏╥)o \n欢迎大家继续补充吐槽... \n \n \n \n思考 \n我对数据的理解,它既贴近于业务层,也耦合着交互层,如果不能很好的分离组织这三层,很可能牵一发而动全身。所以数据是核心,既是业务的核心,也是组件的核心。
\n\n数据,业务逻辑,交互都会影响最终需要渲染的UI视图。 \n编写组件时,首先分析业务需求,对组件进行分层。大致分为数据 (DataSource)
,交互 (Action)
,UI视图 (View)
三层。\n\n数据处理 (Handle) : 承载着核心业务逻辑,对数据进行格式化输出,供 UI 组件进行标准化接收,一般以 function
形式存在。 \n副作用 (Effect) : 以我目前接触到的场景,主要还是以事件修改组件状态,更新数据及UI视图为主。所以事件及状态变更可能会同时出现在 数据处理
和 UI 视图
中。在数据处理中,调用 (Call)
方法;在 UI 中,绑定 (Bind)
事件及状态。UI 层尽量不直接处理或少处理源数据。 \n \n \n \n
\n举例 \n\n业务中常会有这样一种需求,用户可以动态的新增删除一个列表,因为每次需要处理的数据,和展示的 UI 形式都是不确定的。可能我们每次做需求时都实现一次代码,或者把新增和删除方法提取出来,实现部分复用。以 React Hook
为例: \n \n/* hooks/useDataOP.js */ \nimport { useState , useEffect } from 'react' ; \nimport { v4 as uuidv4 } from 'uuid' ; \nimport cloneDeep from 'lodash/cloneDeep' ; \n\n// 使用Symbol作为数据的唯一key \nconst safeKey = Symbol ( 'tid' ) ; \n\n// 格式化源数据 \nconst opFmtData = ( data ) => { \n return cloneDeep ( data ) . map ( ( i ) => { \n i [ safeKey ] = uuidv4 ( ) ; \n return i ; \n } ) ; \n} ; \n\n/** \n * useDataOP \n * @author lencx \n * @param rawData - 源数据 \n */ \nexport default function useDataOP ( rawData = [ ] ) { \n const [ opData , setData ] = useState ( [ ] ) ; \n const [ opType , setType ] = useState ( null ) ; \n const [ isOk , setOk ] = useState ( true ) ; \n\n // 数据初始化 \n useEffect ( ( ) => { \n if ( Array . isArray ( rawData ) ) { \n if ( rawData . length > 0 ) { \n const data = opFmtData ( rawData ) ; \n setData ( data ) ; \n } \n setOk ( true ) ; \n } else { \n setOk ( false ) ; \n } \n // eslint-disable-next-line react-hooks/exhaustive-deps \n } , [ ] ) ; \n\n if ( ! isOk ) return console . error ( 'Parameter must be an array!' ) ; \n\n /** \n * 新增 \n * @param data - 新增的数据对象 \n */ \n const opAdd = ( data = { } ) => { \n const result = [ ...opData , { [ safeKey ] : uuidv4 ( ) , ...data } ] ; \n setData ( result ) ; \n setType ( 'add' ) ; \n return result ; \n } ; \n\n /** \n * 删除 \n * @param value - 需要删除的值,如果为字符串或数字时,需要配合key使用。 \n * 如果value为对象,则为需要删除的记录,通过safeKey查找删除。 \n * @param key - 默认为id,选填,可省略 \n */ \n const opRemove = ( value , key = 'id' ) => { \n let result ; \n if ( typeof value === 'string' || typeof value === 'number' ) { \n result = opData . filter ( ( i ) => i [ key ] !== value ) ; \n } else { \n result = opData . filter ( ( i ) => i [ safeKey ] !== value [ safeKey ] ) ; \n } \n setData ( result ) ; \n setType ( 'remove' ) ; \n return result ; \n } ; \n\n /** \n * 排序 \n * @param startIndex - 当前位置 \n * @param endIndex - 目标位置 \n */ \n const opReorder = ( startIndex , endIndex ) => { \n const result = Array . from ( opData ) ; \n const [ removed ] = result . splice ( startIndex , 1 ) ; \n result . splice ( endIndex , 0 , removed ) ; \n setData ( result ) ; \n setType ( 'reorder' ) ; \n return result ; \n } ; \n\n return { \n opData, \n opType, \n opAdd, \n opRemove, \n opReorder, \n opRawData : rawData , \n opSafeKey : safeKey , \n } ; \n} \n// 使用useDataOP \nimport React , { useState } from 'react' ; \nimport useDataOP from '@hooks/useDataOP' ; \n\nexport default ( ) => { \n const { opData, opAdd, opRemove, opReorder, opSafeKey } = useDataOP ( [ ] ) ; \n const [ count , setCount ] = useState ( 1 ) ; \n\n const handleAdd = ( ) => { \n setCount ( count + 1 ) ; \n opAdd ( { name : `test${ count } ` } ) ; \n } \n return ( \n < div > \n < button onClick = { handleAdd } > Add< / button > \n { opData . map ( ( i , idx ) => { \n return ( \n < div key = { i [ opSafeKey ] } > \n < span > Name: { i . name } < / span > \n { ' ' } \n < button onClick = { ( ) => opRemove ( i ) } > Remove< / button > \n < button onClick = { ( ) => opReorder ( idx , idx - 1 ) } > Up+1< / button > \n < button onClick = { ( ) => opReorder ( idx , idx + 1 ) } > Down-1< / button > \n < / div > \n ) \n } ) } \n < / div > \n ) ; \n} \n查看 DEMO 演示
\n总结 \n数据与 UI 的解耦,其实就意味着业务逻辑与 UI 组件视图的解耦。当组件要跨平台,或者 UI 大换肤时,我们只需要实现标准的数据接收组件就可以了。业务功能对应的其实就是一个个数据处理函数和 UI 组件的组合,通过事件去触发或者绑定一些状态。当数据处理或组件不满足需求的时候,我们只需要去扩展对应的函数或组件。
","category":{"name":"Notes"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwzMDQ1ODIxNzYx","name":"react"}},{"node":{"id":"MDU6TGFiZWwzMDg2MDYxNzMz","name":"blog"}}]},"reactions":{"totalCount":1,"edges":[{"node":{"id":"MDE4OkRpc2N1c3Npb25SZWFjdGlvbjE3NDEzNg==","content":"THUMBS_UP"}}]},"comments":{"edges":[{"node":{"id":"MDE3OkRpc2N1c3Npb25Db21tZW50MTAyMDE4Mw==","bodyHTML":"短时间内强行多次改版。。。第一版,数据是数据,业务是业务,交互是交互;第二版,数据是数据,业务和交互混合;第三版,数据业务交互混合。。。PM&UI大声呼喊:我们的产品月越来越符合用户需求;前端coder小声嘀咕:终于又盖了一座屎山。
","author":{"login":"mJosen","avatarUrl":"https://avatars.githubusercontent.com/u/33922092?v=4","url":"https://github.com/mJosen"},"replies":{"edges":[{"node":{"id":"MDE3OkRpc2N1c3Npb25Db21tZW50MTAyMDIzNQ==","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"bodyHTML":"很难平衡,时间不够,很难把问题考虑到很全面,需求在不断迭代,问题会不断的暴露,唯一能做的就是让组件的职责单一,shi 山塌的晚一些。
"}}]}}}]}}
\ No newline at end of file
diff --git a/issues/49.json b/issues/49.json
new file mode 100644
index 0000000..e78417c
--- /dev/null
+++ b/issues/49.json
@@ -0,0 +1 @@
+{"id":"MDEwOkRpc2N1c3Npb24zNDU3MjA3","title":"【自荐】- 文章 & 开源","bodyHTML":"准则 \n自己维护了一个技术群,希望将其打造成一个高质量的技术交流群,如果放开权限,很快就会沦为推文群。完全禁止技术文章分享,似乎也并不合理。故开辟此处,为群之外的延伸阅读,此链接将更新至群公告。 好的社区需要大家共同努力来建设 🙏。 \n要推荐文章,需要提供:
\n\n✅ markdown 格式排版:学习文档 \n✅ 推荐人
+ 文章链接及标题
+ 推荐理由
\n\n推荐人:昵称
或常用社区 ID
,可以附加个人链接: [`推荐人`](个人链接)
\n推荐理由:文章截取或自身思考 \n \n \n✅ 文章列表时间排序由近及远(最新推荐放在第一条) \n✅ 号主可以自己开一个评论,添加自我介绍,然后在评论里更新推文或开源列表 \n✅ 非号主的可以放置在公共推荐区,如果长期参与,也可以单独开一个评论 \n🈲 推荐文章夹带卖课
及广告
\n🈲 敏感话题 \n \n \n示例:
\n- ` 推荐人 ` [ 文章标题] ( 文章链接 ) - 推荐理由\n- [ ` 推荐人 ` ] ( 个人链接 ) [ 文章标题] ( 文章链接 ) - 推荐理由\n- [ ` lencx ` ] ( https://github.com/lencx ) [ 技术是什么?] ( https://github.com/lencx/z/discussions/51 ) - 技术就是问题的解决方案,与... \n效果预览:
\n\nlencx
技术是什么? - 技术就是问题的解决方案,与编程语言无关,与人无关,当遇到的问题无法解决时,能够把这个问题解决掉的东西,就是技术。概括成一个流程就是:遇到问题 -> 分析问题 -> 抽象描述 -> 提供步骤 -> 解决问题
。当问题被解决后,技术本身也就产生了价值。能解决问题越多的技术,其影响力也就越大。 \n ","category":{"name":"Series"},"labels":{"edges":[]},"reactions":{"totalCount":4,"edges":[{"node":{"id":"MDE4OkRpc2N1c3Npb25SZWFjdGlvbjE5MTEwNw==","content":"THUMBS_UP"}},{"node":{"id":"MDE4OkRpc2N1c3Npb25SZWFjdGlvbjE5MTI4NA==","content":"HEART"}},{"node":{"id":"MDE4OkRpc2N1c3Npb25SZWFjdGlvbjE5NDM4Mg==","content":"THUMBS_UP"}},{"node":{"id":"MDE4OkRpc2N1c3Npb25SZWFjdGlvbjIwMTMxNg==","content":"THUMBS_UP"}}]},"comments":{"edges":[{"node":{"id":"MDE3OkRpc2N1c3Npb25Db21tZW50OTk2NTMz","bodyHTML":"公共推荐区 \n\nlencx
提問的智慧 - 本文原文由知名 Hacker Eric S. Raymond 所撰寫,教你如何正確的提出技術問題並獲得你滿意的答案 \n ","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"replies":{"edges":[]}}},{"node":{"id":"MDE3OkRpc2N1c3Npb25Db21tZW50OTk2NjE1","bodyHTML":"\n大家好,我是洛竹🎋,一只住在杭城的木系码妖🧚🏻♀️,如果你喜欢我的文章📚,可以通过点赞帮我聚集灵力⭐️。
\n文章 \n前端组件化专题 \n\n开源项目 \n","author":{"login":"youngjuning","avatarUrl":"https://avatars.githubusercontent.com/u/13204332?u=f39c14acfc5ef9f2158dca546a900c930ef208ee&v=4","url":"https://github.com/youngjuning"},"replies":{"edges":[{"node":{"id":"MDE3OkRpc2N1c3Npb25Db21tZW50MTAyMDAxMw==","author":{"login":"xushanpei","avatarUrl":"https://avatars.githubusercontent.com/u/35324963?u=dfd7948d98bef67bd395afb74753bbe4ef3fbc48&v=4","url":"https://github.com/xushanpei"},"bodyHTML":"很赞的一篇文章
"}}]}}},{"node":{"id":"MDE3OkRpc2N1c3Npb25Db21tZW50MTAwNDA3OA==","bodyHTML":"大家好,我是浦原,我会分享一下我平时看到的觉得对我自己很有助益的文章,之后也会尝试自己进行书写相关项目。其实我很喜欢在讨论中学习,如果你也喜欢这种方式,可随时找我。 \n文章列表:
\n","author":{"login":"AlanCumberbatch","avatarUrl":"https://avatars.githubusercontent.com/u/48616511?v=4","url":"https://github.com/AlanCumberbatch"},"replies":{"edges":[]}}},{"node":{"id":"MDE3OkRpc2N1c3Npb25Db21tZW50MTAwNjYzNg==","bodyHTML":"我叫欧雷 ,曾用网名「飛鳥修羅丸」,除了编程 ,我还喜欢写作 、思考 、旅行 和日语 等。另外,我曾经是个「御宅族 」,是 ACG 宅、IDOL 宅,现已退役,成为单纯的 ACG 爱好者。
\n\n\n\n\n\n","author":{"login":"ourai","avatarUrl":"https://avatars.githubusercontent.com/u/562589?u=a4e4464403fcfc05423c03772b6b6398c8b8f95d&v=4","url":"https://github.com/ourai"},"replies":{"edges":[]}}},{"node":{"id":"MDE3OkRpc2N1c3Npb25Db21tZW50MTAyMDA1Mg==","bodyHTML":"\n大家好,我是前端小菜鸡,某不知名小公司前端切图仔,如果你喜欢我的文章或者觉得我的文章对你有帮助,还请留个赞哦;也可以关注公众号:前端开发爱好者
一起学习前端技能。
\n文章列表 \n","author":{"login":"xushanpei","avatarUrl":"https://avatars.githubusercontent.com/u/35324963?u=dfd7948d98bef67bd395afb74753bbe4ef3fbc48&v=4","url":"https://github.com/xushanpei"},"replies":{"edges":[]}}},{"node":{"id":"MDE3OkRpc2N1c3Npb25Db21tZW50MTAyMDE4Mg==","bodyHTML":"\n大家好呀,我是寒草,一只快要北漂一年的草系码猿🐒。 间歇性热血🔥,持续性沙雕🌟,草系码猿期待着大家的点赞👍与关注➕。
\n文章列表 \n\n草系前端手摸手带你实现正则引擎,点燃夏日最热情的烟火🔥 - 前端讲编译原理系列全新篇章:从自动机基础知识出发,扩展至我们常用的技术栈:正则匹配,最后与大家一起共同实现简易的正则引擎, 既有干货满满的知识点, 又有实践演示。让我们一同在炎热的夏日一起点燃最热情的烟火吧! \n前端学编译原理(一):编译引论 - 前端讲编译原理系列首篇文章,从前端视角出发了解我们为什么要学习编译原理,并对编译原理的一些基础知识进行分享,最后简单的分步骤介绍了编译器的各个步骤,理论为主,为大家揭开编译原理的面纱。 \n \n开源项目 \n","author":{"login":"hancao97","avatarUrl":"https://avatars.githubusercontent.com/u/29964332?u=b3fd04c0d36c6d0ff67edfb256177df28faf6d16&v=4","url":"https://github.com/hancao97"},"replies":{"edges":[]}}}]}}
\ No newline at end of file
diff --git a/issues/50.json b/issues/50.json
new file mode 100644
index 0000000..c63de4a
--- /dev/null
+++ b/issues/50.json
@@ -0,0 +1 @@
+{"id":"MDEwOkRpc2N1c3Npb24zNDU5Njk3","title":"基于 Github Discussions 构建个人 Blog","bodyHTML":"📅 2021.07.14
\n\n待更新
\n \n背景 \n写这篇文章,我也会问自己,现在已经有了那么多成熟稳定的写作平台,为何还要自己去搭建?
\n国内有 公众号
,InfoQ
,语雀
,掘金
,知乎
,简书
;国外有 DEV Community
,Medium
等等,不下几十个平台社区。
\n即使不选择上面的平台社区,还可以选择
","category":{"name":"Notes"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwzMDg2MDYxNzMz","name":"blog"}}]},"reactions":{"totalCount":0,"edges":[]},"comments":{"edges":[]}}
\ No newline at end of file
diff --git a/issues/51.json b/issues/51.json
new file mode 100644
index 0000000..3625795
--- /dev/null
+++ b/issues/51.json
@@ -0,0 +1 @@
+{"id":"MDEwOkRpc2N1c3Npb24zNDU5NzA4","title":"技术是什么?","bodyHTML":"📅 2021.05.04
\n\n一条朋友圈评论所引发的一系列思考
\n \n背景 \n我发了朋友圈:做了个奇怪的梦,梦见被离职了,理由竟然是:你技术太菜了
\n我补充评论:我还没想明白怎么回事,就醒了。有点遗憾的是:想再努力反驳两句,结果没机会了…
\n很多人评论:梦是反的
\n我的回复:那就是到技术的瓶颈期了
\nYaoL.in评论:这衍生出一个很好的问题:「你如何证明技术不菜?」
\n我的回复:个人感觉还是影响力,即使你的技术很厉害,没人知道,或者别人也不会去使用你的技术,似乎一切为零(为零仅代表这个技术所产生的影响力,不代表技术本身的价值)
\n \n我对技术的理解 \n技术本身并没有价值,衡量一个技术的标准,应该是这门技术所产生的影响力。
\n我之前也一直认为只需要专心做好技术就可以了,是金子总会发光的,这句话没有任何问题,但是缺少了一个很重要的前提,何时才会发光? 人的生命是有限的,我认为能够更快的将自己曝光,用自己的技术或文章去影响到一些人,还是很有“必要的”(自己体会,这里可以代表着名,利,精神上,物质上等)。
\n我参与 GitHub 开源及写文章博客也很久了(惭愧,文章博客输出有点少),慢慢发现,很多好的技术,文章,项目都属于被埋没状态。一直被埋没,就不会产生价值,这就会造成一个很大的问题,技术自身有价值,但却不能用来解决问题,该如何去衡量这个技术?
\n自己封神,不如别人对你称神 \n帮别人解决问题,来体现自己的价值
\n回答别人提出的问题,也是对自身技术的 review ,review 的次数多了,这些技术点就会刻在骨子里。当一个问题讨论的深入时,往往引发的是一系列的知识点。由点成面,再成网(单纯靠回答问题,很难构建出知识网,但是可以作为一个切入点)。
\n当我学习技术累的时候,就喜欢在技术群里看别人提问题,能回答的就回答,不能回答的时候就看别人如何回答。
\n闷头搞技术,提升的只是一个人的能力,分享,提升的是一群人。有些人可能会觉得技术如果拿来分享,别人比自己强了,怎么办,那岂不是越来越卷了? 不知道别人有没有这么想,反正我以前有过这种想法,但是随着自己做开源,写文章,回答别人的问题,不但没有这种想法了,反而想把更多的技术拿来分享,进行探讨。
\n原因有以下几点:
\n\n表达能力 :能够把自己掌握的技术,抽象表达出来,这个很难。要达到这个目标,让什么都不懂的人听懂你在说什么,就需要做到知识深入浅出。 \nReview & Share :每次分享,都是对技术的一次 “review”,会产生新的理解或者引申出新的知识点。用分享的方式去学习(共赢)。 \n技术探讨 :可遇不可求,分享技术,如果遇到知己,也是莫大的幸运。 \n成就感 :这属于学习的一个正反馈,奖赏机制在学习技术方面,我觉得还是很有必要的,因为学习本身就比较枯燥,能找到一个坚持下去的理由,不容易。举个例子,我个人就拿 每天一个 github 小绿点(github commit 记录),让自己持续学习与输出
作为目标。 \n无形监督 :这个其实是为了防止自欺欺人,以为自己不分享别人就不会学习了...,有压力才会有动力,因为当自己再无可分享的东西时,则证明自己已经没有了知识的输出,需要进行自我反思。 \n \n在各大技术群里呆的久了,发现群友们提出的问题虽千奇百怪,但整理下来其实也就几大类:
\n\n想吃现成的 :遇到问题不管三七二十一,先丢群里,等待别人的回答,如果有人回答,能吃到嘴也算“不亏”;运气不好的,直接让群变得安静起来(群静音神器);还有就是群友们会围绕这个问题开始风马牛不相及的吹水。等不到问题的解决方案,则白白浪费了时间。 \n不会提问的 :这种人似乎还不占少数,比想吃现成的能稍微“好点”吧,因为不光浪费自己的时间,还浪费了看问题回答问题人的时间,有效地防止了内卷
。不会提问通常表现为问题没有上下文,只有一个报错信息,问怎么解决,在线急等。如果有人解决过类似问题还好说,没有解决过这类问题的则表示一脸懵逼,连个插话的机会都不给(抠门,惜字如金,只发问题不发产生背景及预期)。 \n会提问的 :这种人一般都是思路清晰的,也做过了大量的技术方案尝试,能够言简意赅的说明目前困境,希望能够得到什么样的帮助,目的性很强(褒义词,知道自己想要什么总比什么不知道要好)。 \n进行探讨的 :强烈推荐的方式,要讨论,就避免不了问题的梳理,在梳理问题的过程中,可能会发现自己漏掉的一些细节。小黄鸭调试法 值得拥有,有些问题解决不了,很可能也是因为自己钻了牛角尖,讨论也可以让自己快速走出思维误区。 \n \n学会提问 \n遇到问题,不要慌,常见的百分之八九十问题,网上都是有解决方案的。当搜索引擎都不能帮助你解决这个问题的时候,证明你遇到的问题“有点东西”了,这是好事情。需要去一些专业的技术提问社区去转转了,比如 Stack Overflow ,或者 GitHub Issues
(主要针对开源项目),还有就是此技术相关的社区,论坛,Slack
,Discord
等。
\n一个好的问题模板,例如 vite ISSUE_TEMPLATE/bug_report 一般包含以下几个要素:
\n\n问题描述 :简短的表述清楚问题,切记啰嗦。 \n环境信息 :问题发生的环境(系统信息,软件版本,浏览器版本等)。 \n如何复现 :提供问题复现步骤1,2,3,可以配合适当的错误截图及说明。 \n预期结果 :希望达到什么样的结果。 \n \n解决问题,根据我多年来的实践总结,一般分为以下几步:
\n\n抽象 : 用技术关键词去描述问题 \n搜索 :根据关键词去搜索问题\n\n \n延伸搜索 :围绕关键词,扩大搜索范围,查看一些相关链接 \n \n🎉 Google 高级搜索的10个技巧 : \n1)准确搜索(Exact phrase) \n2)排除关键词( Exclude terms) \n3)用 OR (或)逻辑进行搜索(Either OR) \n4)同义词搜索 ~(Synonym search) \n5)站内搜索(Search within a site) \n6)善用 * 星号(The power of the asterisk) \n7)在两个数值之间进行搜索(Searching between two values) \n8)在网页标题, 链接和主体中搜索关键词(Search for word in the body, title or URL of a page) \n9)搜索相关网站(Search for related sites) \n10)搜索技能的组合使用(Combine them)
\n总结 \n所以再次回到文章的标题,技术是什么?
,技术就是问题的解决方案,与编程语言无关,与人无关,当遇到的问题无法解决时,能够把这个问题解决掉的东西,我认为这就是技术。技术本身并不高大上,概括成一个流程就是:遇到问题 -> 分析问题 -> 抽象描述 -> 提供步骤 -> 解决问题
。当问题被解决后,技术本身也就产生了价值。能解决问题越多的技术,其影响力也就越大,提供此问题解决方案的人也就越厉害(此结论只是站在一个角度的个人观点,请勿过度解读)。所以要证明自己不菜,就要不断地去解决问题,帮助的人和解决的问题越多,你就是别人眼中的“神”,而不是自封为神。自己时刻要保持着对知识的敬畏之心
。
","category":{"name":"Notes"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwzMDg2MDYxNzMz","name":"blog"}}]},"reactions":{"totalCount":0,"edges":[]},"comments":{"edges":[]}}
\ No newline at end of file
diff --git a/issues/52.json b/issues/52.json
new file mode 100644
index 0000000..4951103
--- /dev/null
+++ b/issues/52.json
@@ -0,0 +1 @@
+{"id":"MDEwOkRpc2N1c3Npb24zNDY2NTE5","title":"Pixel Art","bodyHTML":"像素画 是一种以“像素”(Pixel)为基本单位来制作的电脑绘图表现形式。
\n在电脑绘图的两大类别——位图
与向量图
——当中,像素画以位图(bitmap)的形式,从电脑最原始的图像表现方法,演变成了一种独立的数字艺术创作风格。此风格通常被人称为“像素艺术”(pixel art),有时也被称为“点绘”(dot art)、“点图”、“点画”、“像素图”、“dot绘”等。
\n\n[wiki] 位图 -(英语:Bitmap,台湾称为点阵图),又称栅格图(Raster graphics),是使用像素阵列(Pixel-array/Dot-matrix点阵)来表示的图像。\n\n一种数据结构,代表了有限域中的稠集(dense set),每一个元素至少出现一次,没有其他的数据和元素相关联。在索引,数据压缩等方面有广泛应用。 \n位图的像素都分配有特定的位置和颜色值。每个像素的颜色信息由RGB组合或者灰度值表示。 \n根据位深度,可将位图分为1、4、8、16、24及32位图像等。每个像素使用的信息位数越多,可用的颜色就越多,颜色表现就越逼真,相应的数据量越大。例如,位深度为 1 的像素位图只有两个可能的值(黑色和白色),所以又称为二值位图。位深度为 8 的图像有 28 (即 256)个可能的值。位深度为 8 的灰度模式图像有 256 个可能的灰色值。 \n \n \n[wiki] 矢量图形 - 是计算机图形学中用点、直线或者多边形等基于数学方程的几何图元表示的图像。矢量图形与使用像素表示图像的位图不同。\n\n所有的现代计算机显示器都要将矢量图形转换成栅格图像的格式,包含屏幕上每个像素数值的栅格图像保存在内存中。 \n \n \n \n \n","category":{"name":"Series"},"labels":{"edges":[]},"reactions":{"totalCount":0,"edges":[]},"comments":{"edges":[]}}
\ No newline at end of file
diff --git a/issues/54.json b/issues/54.json
new file mode 100644
index 0000000..6612505
--- /dev/null
+++ b/issues/54.json
@@ -0,0 +1 @@
+{"id":"MDEwOkRpc2N1c3Npb24zNDY3MDY4","title":"微信杂谈 - 造轮子","bodyHTML":"📅 2021.07.19
\n少年: \n前端东西太多了
\n少年: \n学不完的呀
\n你好,浦原: \n是啊!
\n少年: \n集体转后端?
\nShine.: \n[苦涩]后端更难
\n安木~🍄: \n后端也多[捂脸]
\n少年: \n后端知识比较固定吧
\nlencx: \n后端天花板高,感觉可以比前端走的更远
\n少年: \n是呀
\n少年: \n前端这些造轮子的
\nlencx: \n前端轮子太多了
\nlencx: \n感觉没必要什么都学,了解就够了
\n安木~🍄: \n怎样才能达到造轮子的水平[捂脸]
\nlencx: \n随时都可以,轮子有大有小
\n周哈哈.: \n天呐 你居然想造轮子
\n少年: \n去一家公司面试就问React、vue 从生命周期问道源码 在问到实战 在问到html +5 css +3 再问问你懂不懂构建 再问你懂不懂优化 再问你懂不懂后端
\n安木~🍄: \n比如小到那种?
\n安木~🍄: \n对呀 只有慢慢的去接触新东西 才能成长
\nlencx: \n凡是可以用代码解决的东西都可以用程序去解决
\n周哈哈.: \n不错
\nlencx: \n然后就会发现可以做很多东西
\n安木~🍄: \n鑫哥 我没太明白这个意思
\n安木~🍄: \n代码能解决的东西 都可以用程序去解决?[捂脸][捂脸]
\nlencx: \n额、就是用程序去解放自己
\nlencx: \n实现自动化
\nlencx: \n然后往这个方向思考,去写程序
\n安木~🍄: \n你是说 只要是互联网上的软件方面的东西 都可以用代码去实现嘛
\n安木~🍄: \n哦哦 这样呀
\n安木~🍄: \n相当于是怎么用代码来给自己提供便利对吧
\nlencx: \n代码指编程,不限于语言
\nlencx: \n差不多就是这个意思
\nlencx: \n前端工具链不就是为了解放生产力吗
\n安木~🍄: \n听你这么说
\n安木~🍄: \n好像还真是
\n安木~🍄: \n[捂脸][捂脸][捂脸]
\nlencx: \n一个道理,写不了工具链,可以写小工具,小工具多了,就可以做聚合
\nlencx: \n思维的转变很重要,不是会不会的问题,而是有些人觉得,非要搞一个很牛逼的东西才算造轮子,其实并非是这样的,可以解放你部分时间的东西都是值得的
\n安木~🍄: \n嗦嘎
\nkk德米安: \n[强]
\n安木~🍄: \n你会不会就是说 知识受限 然后局限了你的思维 没发去产出小轮子呢
\nlencx: \n知识受限还不是主要因素,因为如果只是知识受限,可以通过读书查资料去弥补,更多的是去发现问题,这个不是靠读书就可以解决的
\nShine.: \n我还是感觉js
\nShine.: \n重要
\nlencx: \n要培养发现问题,提出问题的能力,能提出一个好的问题也是能力的一部分,我个人觉得
\n安木~🍄: \n要怎么去培养这种发现问题的能力呢[捂脸][捂脸]
\n安木~🍄: \n我感觉 我可能就是缺乏你说的这种思考
\n安木~🍄: \n我的开发都只限于公司业务需求
\n安木~🍄: \n貌似也没有主动精进过说 会思考怎么去提升生产力 或者 发现有什么好的方式可以提升生产力[捂脸]
\nlencx: \n说难也不难,就是不要只是站在开发的角度去思考问题,因为程序和市场是脱节的,所以开阔视野很重要
\n安木~🍄: \n说的有道理
\n安木~🍄: \n眼光不要局限对吧
\nlencx: \n举个简单例子:站在开发角度,我完成这次需求就ok了;站在产品角度,用户体验很重要;站在老板角度,节约成本很重要。
\n安木~🍄: \n不能为了业务开发而来发了[捂脸]
\nlencx: \n所以我们要做的,就是尽可能的最大化自己的价值,而不是把自己局限于某一个环节
\n安木~🍄: \n这么说 貌似明白一点了
\nlencx: \n不然的话就成了一颗螺丝钉
\n安木~🍄: \n相当于以前做的就只是完成需求
\n安木~🍄: \n对的 我现在感觉我就是颗螺丝钉
\nlencx: \n程序来源于需求,需求来源于生活之中的痛点,所以我们写代码也一样,要透过需求看本质,即代码是为了解决痛点而存在的,而不是靠想象,我想做什么就做什么,技术不能够落地的因素是多方面的,如果不能够实际去解决一些问题,即使落地了也没啥意义。
","category":{"name":"Notes"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwzMTgxNDE5MDUz","name":"微信杂谈"}}]},"reactions":{"totalCount":0,"edges":[]},"comments":{"edges":[]}}
\ No newline at end of file
diff --git a/issues/55.json b/issues/55.json
new file mode 100644
index 0000000..e095585
--- /dev/null
+++ b/issues/55.json
@@ -0,0 +1 @@
+{"id":"MDEwOkRpc2N1c3Npb24zNDY3MTEy","title":"微信杂谈 - 技术迷茫期","bodyHTML":"📅 2020.09.08
\nlencx: \n你好,我平时不会打扰您的,我有一个问题想问问您,我其实现在感觉自己挺迷茫的,我是做前端开发的,前端技术也没有做的专精,杂七杂八的东西倒是接触了不少,有种什么都想学,却又能力不够,我是不是该在前端领域让自己沉下去或者在某个细分领域钻研下去?这么问您,我也知道您不一定能给出答案,毕竟每个人都有自己选择,我想知道学新技术都会有这种焦虑吗?或者您有什么经验可以分享,谢谢
\nJason Yu 于航: \n你好 其实很多人都有这种焦虑哈 也包括我在内。从我的角度来看,可能更建议专注于某个方向去深入,做到一专多能。多能就是要认知广泛,各类技术都知道,但不用很深入,很详细,但可以把握程度,当需要用的时候可以快速去了解。而一专就是要深入到一种程度,这种程度是别人无法花几天就能够补得上的那种。当然,一专的方向可以遵循“一看兴趣、二看行业、三看收入”的顺序来选择。你说的杂七杂八可能是碎片化的知识,建议可以从完整看完几本书开始做起,当有了一个面之后,可能会更容易找到兴趣点。不知道这个回答是否可以帮到你哈
\nlencx: \n嗯嗯,谢谢
\nlencx: \n我是自学过来的,所以就导致了什么都想去了解一些,因为不知道需要什么,或者什么是好的技术,该如何去选择,就想不断的扩大自己的知识面。知识不成体系,碎片化
\nlencx: \n谢谢,其实我知道自己的不足,最近也在补一些基础知识
\nJason Yu 于航: \n嗯嗯 完全可以理解 碎片化的知识是可有的 但基础的体系一定要牢固 比如就前端而言就是从js语言本身开始到各类web api,再到web框架、工程化等等。基础的部分打牢后就可以往细分领域拓展,比如serverless,可视化,nodejs等等
\nlencx: \n嗯嗯,我的学历也是硬伤,我只有大专学历,而且非科班出身
\nJason Yu 于航: \n不用太在意学历 尤其是互联网技术这种更看重经验的工作
\nJason Yu 于航: \n非科班出班的厉害的有很多呀
\nlencx: \n最近好多猎头问找不找工作,字节,阿里之类的,我一说大专学历,都说没机会了
\nJason Yu 于航: \n是的 最近这段时间国内内卷比较严重 不过如果你有一些自己的积累 比如个人项目之类的 学历就不会成为问题了
\nlencx: \n嗯嗯,我之前是不太确定能力是否可以弥补学历的不足,听了您的话,感觉还是有希望的
\nJason Yu 于航: \n换位思考 你要是hr 一堆简历如果本身没有太多出彩的地方 就只能从学历来筛选了
\nJason Yu 于航: \n嗯嗯 放心吧 学历绝对不是问题
\nlencx: \n嗯嗯,谢谢啦
\nJason Yu 于航: \n不客气哈
","category":{"name":"Notes"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwzMTgxNDE5MDUz","name":"微信杂谈"}}]},"reactions":{"totalCount":0,"edges":[]},"comments":{"edges":[]}}
\ No newline at end of file
diff --git a/issues/57.json b/issues/57.json
new file mode 100644
index 0000000..7105966
--- /dev/null
+++ b/issues/57.json
@@ -0,0 +1 @@
+{"id":"MDEwOkRpc2N1c3Npb24zNDY4MjU3","title":"微信杂谈 - 技术广度 & 深度","bodyHTML":"📅 2021.07.01
\nShawn: \n问大家一个问题:学习广度和深度的问题,先深后广还是先广后深,阈值是多大。
\ntelescope: \n先深后广
\nShawn: \n深的阈值
\n安木~🍄: \n先深度吗
\nlencx: \n也就是吃饭的家伙要够硬
\nLeanode: \n我觉得收入 取决于做技术的高度
\n🍉: \n谈论学习深度阈值之前你要先能量化你的学习深度啊
\n🍉: \n不然还是完全主观
\nLeanode: \n一专 是理想状态
\nlencx: \n理想状态是,都要[捂脸]
\nLeanode: \n知其然知其所以然 算深度吗
\nMr.Black: \n我感觉深度重要,要在一个领域做到别人无法替代。
\nLeanode: \n目前我个人的阶段 感觉是工厂能力的好坏和解决问题的速度和解决问题的方式是否最优 可能是我认为的需要掌握的
\nLeanode: \n在一个领域无法代替有点抽象
\n南蓝: \n那么问题来了,不知道选择哪块去深究
\nLeanode: \n目前应用层技术都像一个洋葱一样被扒开来
\nlencx: \n在我看来,其实知识技术并不是割裂状态,可以在深入的同时,去发散,比如一个问题会引申一个新的问题。只需要把握好引申的范围就好,知识是网状的。
\nShawn: \n我觉得这个问题比较随缘吧、
\nShawn: \n研究的方向一是来源于自己的兴趣,二是来源于目前就职公司的业务。
\nlencx: \n准确来说是螺旋式上升,跟龙卷风🌪️一样,越卷越大
\nShawn: \n比如公司项目用的是vue,然后你要研究 react
\nShawn: \n赞 +1
\n安木~🍄: \n深入的点怎么去找呀
\n安木~🍄: \n完全就是不知道从何下手
\nlencx: \n如果以赚钱为目的,就是以企业要求去深入
\n安木~🍄: \n从那个点突破进去然后发散
\nlencx: \n以兴趣为目的,就看个人了
\n安木~🍄: \n[破涕为笑]这个感觉有点笼统
\n南蓝: \n估计我现在只能以赚钱为目的了...
\nlencx: \n比如公司用 react,就从 react 深入,发散
\n安木~🍄: \n概念很大
\nShawn: \n对。
\n安木~🍄: \n深入是只去研究高深的逻辑和底层源码实现吗
\nShawn: \n设计模式,整体架构
\nLeanode: \n如何深入react呢
\nShawn: \n我的方法就是,买课看视频,
\n宿愿Cc: \n对
\nlencx: \nreact -> 会用 -> 对生态有些一了解 -> 尝试去给生态做贡献 -> 要贡献,就需要更深层次的理解 -> 可能就会涉及到 react 的原理,源码
\n宿愿Cc: \n我自己在读源码的过程中,有很多地方都是一知半解
\nShawn: \n我最开始看源码,打 debug ,越打越多,一个点深入进去我就迷失方向了,所以买课,看看视频
\nlencx: \n对知识点的学习,肯定是有其背景的,而不是盲目去学
\nlencx: \n有痛点,才会去创造
\n安木~🍄: \n买源码讲解视频吗
\n安木~🍄: \n我感觉我现在就是盲目的学
\n安木~🍄: \n啥都是只会点皮毛
\nlencx: \n学习也是这样,遇到问题了,才会去了解问题,解决问题,解决问题就分为单纯解决问题,和问题发散了,没什么追求的,解决完问题,就算完事了,有追求的,就会打破砂锅问到底,这就是延伸
\nShawn: \n对技术充满好奇
\nlencx: \n就比如我写的 vite 插件,我的最初目的不是阅读 vite 源码,但是为了实现插件功能,迫不得已,就阅读了源码,因为你不读源码,插件机制,内部 API 都不熟悉
\nDeepKolos (DeepKolos): \n我感觉读源码,需要面对的问题是,这样的设计解决了什么问题,如果解决相同问题,你会怎么解决,目前的解法有哪些潜在缺陷
\nhello: \n我觉得。一切以实际业务为主 再去发散技术
\nDeepKolos (DeepKolos): \nlazy-gltf-loader的开发我就发现blender的gltf exporter 纹理复用有问题
\n宿愿Cc: \n然而我们业务很近,没有时间。。。
\nShawn: \n我的建议是。vue 使用过一段时间再去看,否则这个教程会让你放弃研究 vue 源码。
\nDeepKolos (DeepKolos): \ngltf-gpu-compressed-texture就发现zstd decoder是在UI线程decode,没有worker
\nlencx: \n这样看你想成为什么样的人,时间是可以挤出来的,比如坐地铁的时间,走路也可以去思考一些问题,有时候代码并不是需要写的,更多的是在大脑中的思考。大脑其实就是一台计算机
\nhello: \n我就是。一开始搞不清渲染底层。于是看了 opengl。 一直搞不清开发三维怎么写好代码。于是看了一本书。还看了u3d的开发思路 于是现在也算能模拟u3d开发自己的三维项目了
\nDeepKolos (DeepKolos): \n还是有需求读源码好
\nMr.Black: \n一些底层的东西还是要了解一下,有时候原理不知道,单纯会用,就会写出乱七八糟的代码。
\nDeepKolos (DeepKolos): \n封装本来就是为了让你不需要知道里面怎么实现就可以完成功能
\nShawn: \n会让你定位 bug 更精准
\nhello: \n以前写三维代码。只能达到demo级别。 代码量上来。 维护性和可持续行 根本扛不住。现在代码从模块和组件开发思维。 目前还没遇到扛不住的情况
","category":{"name":"Notes"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwzMTgxNDE5MDUz","name":"微信杂谈"}}]},"reactions":{"totalCount":0,"edges":[]},"comments":{"edges":[]}}
\ No newline at end of file
diff --git a/issues/59.json b/issues/59.json
new file mode 100644
index 0000000..ffc9a4f
--- /dev/null
+++ b/issues/59.json
@@ -0,0 +1 @@
+{"id":"MDEwOkRpc2N1c3Npb24zNDY4ODQ1","title":"自学总结・入门期","bodyHTML":"\n背景: \n为了学习技术,希望自己设计开发一个 blog,并尽可能多的使用到新技术。每日写总结记录开发中遇到的问题,进行思考总结
\n \n2016-12-25 \n今天的效率很低,犯了很多习惯性的错误。就是在做一件事情的时候不能先去完成一部分,去做后续的测试。当你把整个手头上的东西都完成后,才发现后续的步骤根本行不通时,才发现自己走了好多冤枉路。 \nTODO: 纠正自己的思维惯式,提高自己遇到新问题时的分析及处理能力。 \nSUM: 当在处理新问题时,注意自己的方式方法,尽量避免习惯上认知。
\n2016-12-26 \n今天装逼卖萌一波,进度有点缓慢。本来想着要把字体生成出来。没想到 AI(Adobe Illustrator) 真 TM 的太好玩了,搞起来就撒不了手。真所谓自作孽不可活。哈哈。 \nSUM: 凡事要有节制。哈哈,只能这么安慰自己了。
\n2016-12-27 \n今天 AI(Adobe Illustrator) 是玩爽了,但是生成字体因间距太大已被舍弃,也就字体图标能用用了,倒腾了几天然并卵(这真是表面光鲜亮丽,背后却还是一坨屎。到目前为止。需要的图标已差不多 OK,ai,fontforge 就先暂且放一放)。还是老老实实码代码吧。 \nSUM: 实用性永远是第一位的,不能用一切都是白搭。
\n2016-12-30 \nDONE: router, file-upload, node console -> font color \nSUM: 每天给自己十到十五分钟的时间总结一天所学,不为别的,只是觉得自己以前浪费了好多时间,总为自己的懒惰找借口,三天打鱼 两天晒网。或多或少,当哪一天没有一点可写的东西时,就该反思一下自己了。每天发朋友圈,空间不是为了获得别人的点赞和赞赏(又装逼了,因为将来能回头看看自己走过的路,知道自己进步了多少,要是我每天的装逼言论能“刺激”到一些人,也不错。哈哈)量变到质变,不是看你哪天完成了多少多少东西。一步一个脚印,踏实!
\n2017-01-01 \nDONE: 对 JavaScript base: apply , call, bind 的理解又比以前深入了。貌似今天没啥进步,就把一些要素重新梳理了一下。做这个项目,给我带来的最大感受就是能够系统的梳理自己清楚的,不清楚的的犄角旮旯里的各种知识。哈哈。总之觉得自己每天的进度都很缓慢。每前进一步都是一次学习。思考问题不能站在某一个角度了,必须🉐️从整个项目出发。从中我也发现了我的选择恐惧症。就爱对比。用 plugins 就要用最好的。在筛选这些时免不了看看介绍啥的,白花花的时间都跑了😭。后来总结出来了一个结论。用下载量最大的准没错。哈哈(这也是有科学依据的,用的人越多,对该 plugin 的测试也就越全面,出现大 bug 的可能性就越小,虽然用小众的在自己的项目中不一定会出现 bug,但我就喜欢跟风嘛,哈哈。要死大家一起挂。)
\n2017-01-02 \nDONE: 在使用 yarn 时遇到大坑,引用 jquery 库时只能从 node_modules 下引用,路径有点看着不爽,但又不知如何解决(莫不是有高级玩法我不知道?😭)。google 了一大堆也没找到合适的方案(或许我没搜索到位)。只好退而求其次,又搞过来一个 bower(能够实现自定义安装路径,我喜欢😜)来管理 jquery ...第三方库,感觉一个项目两个包管理器终究还是不爽。但目前想不到更好的方案了(谁让我就是这么矫情,就是看不惯它的安装路径,我尝试用 gulp 重新 build 一下,但没成功。回头再试试,或者还可以试试 fs 模块,重写文件),只能等到日后再想办法解决。 \nTODO: Browserify 或许是一个不错的方案 \nSUM: 有些事要么不做,要做就要做到极致。敢于追求完美,才有可能将一件事做到近乎完美。(虽然以我目前的能力,不可能把它做到做好,但我会尽我所能不将究。然后不断的优化)
\n2017-01-03 \nDONE: \nPug: mixin -> list \nSass: mixin (responsive, z-index, ...) \n... \nTODO: \n响应式网站(不借助 bootstrap 框架,实现整站布局。因为要做个性化,所以还是手写更靠谱些😪) \n如何将代码 (router, pug, sass, ...) 进行模块化(功能化)拆分,提高复用性及可维护性,以及后期整个项目的可扩展性(说着容易,做起来,也是不断的进行自我总结优化。进度没有想象中的那么快😒) \n目标:博客只是整个项目的一个板块,但是 .md or .org 的文件编译及发布虽然已在脑海形成轮廓。但感觉坑应该不会少🤔。 \n数据库... \n可以考虑的:整站的一个配置文件->常用设置
\n2017-01-04 \nDONE: Home 布局已完成一半,由于要响应多个设备,还在不断的调整中。项目结构在构建页面时又进行了一次调整,按照类型对pug 进行功能化分类。目前感觉比较合理(后期还有可能再次调整),便于路由的管理。
\n2017-01-05 \nDONE: Home 页布局已基本完成,接下来要做的就是如何将容器中的内容进行参数化,设置配置文件(这样在内容调整时就不会就不需要直接改页面,方便,也不容易出错。因为经常性的改页面,不定哪天就破坏了页面的结构。配置文件只是一个过渡,下一步可能会去实现的功能将是后台编辑的功能,但目前不考虑)。js 文件的压缩与合并的 task 已完成,下一步要做的就是一些特效,如产生滚动条时,出现返回页面顶部的 🔘。banner 处的图片轮播。 \nTODO: 目前还在构思的是用 css3 实现一些页面的动画效果,使过度更自然平滑,更酷(其实是装逼用的)。哈哈。logo 看着有点不太舒服,下一步可能还需要考虑 logo 的问题。大结构已经基本完成,会有细节上的调整(字体大小,颜色,背景等等)。
\n2017-01-06 \n今天一天没啥进度,页面的结构我现在越来越拿捏不准了。怎么看都不好看... \nsass 写了两 mixin,css3 animation 写了几个动画,但真心觉得好丑。看来不能在 UI 美化上浪费时间了(凡事都想做到极致,就容易纠结,光一个颜色都能纠结半天,我自己反正拿我是没辙了,唉)。先搞开发吧,留着以后慢慢纠结。 \n还想说的就是 atom 搞了我大半天时间,插件配置的还是不理想,只能暂时放下了。看来以后 IDE 也少折腾吧,浪费的都是白花花的时间,唉。干啥啥不顺。
\n2017-01-07 \nDONE: 了解了一些 sassdoc,jsdoc,svg。项目结构进行了一点微调(sass),浏览器终端判断 \nTODO: 突然发现自己移动端欠缺好多基础,就一个菜单的点击事件我还没想明白...😩。明天学习移动端基础。
\n2017-01-08 \nDONE: 这两天没有急于完成其他的的页面(其实好的开始就是成功的一半,当一个页面考虑的足够全面时,其实其他的页面都类似,只是一些功能的不同或增减),在写 js 时发现了一些问题(sass,pug 的结构不太合理,样式及页面的可扩展性也不好[比如我后期要扩展导航,页面结构就会发生变化,我当时的想法是后期只扩展二级菜单,一级菜单所涵盖的范围要足够广,这样我就可以将导航布局写死。但经过这两天的思考,我觉得之前的设计其实是不合理的,因为我不能保证以后会不会出现一级菜单。虽然改代码也不难,但我觉得这种设计是愚蠢的,无形中给将来埋了一颗雷],sass 比较让我头疼,可自己又不知如何去写,所以我现在在看 bootstrap源码,从中提炼出一套适合自己的样式框架,bootstrap 有很多思想是可以借鉴的,但是有很多样式其实自己是不需要的,我所需要做的就是提炼出其中的元素,重新编写自己的一套 mixin,function,%, etc.)。所以鉴于此原因,准备重写页面。合理的结构就是在不断修改中逐渐成型的,虽然目前以我的能力不足以写出一个合理的结构。但我会一步步的去改进完善它。 \nTODO: \n样式命名规则:凡是 js 操作的 class 前面都加 js-; \n凡是多次重用的样式都写成 mixin,function,or placeholder; \n对 sass 按照功能 or 类型进行分类,便于管理与扩展;(e.g., alert, error, button) \n多多考虑页面的体验与交互。(页面的一些缓冲效果,动画等)
\n2017-01-09 \nDONE: grid 已基本完成。bootstrap 作者设计的栅格系统的确很巧妙,将列宽与要响应的断点结合的很完美(至少在没看源码之前我是没想到,哈哈,看了也没看太明白,而且再一次的感受到了 mixin 的强大。原理是通了,但是代码还没全搞明白)。 \n明天继续把 grid 彻底搞通。然后进行下一步... TODO: 下一步就是把网页所有的元素分类进行管理 (font,border,button,...)。
\n2017-01-10 \nDONE: (自动化)写了那么久的代码直到今天才觉得自己是在写代码了。编程需要的思想也慢慢体会到了,以前只是为了完成任务而完成任务。计算机的优势就是计算,重复计算。在计算机中,人最不需要做的就是重复,需要的是一种思想,可以让计算机帮你去完成重复工作的逻辑与思想。 \n虽然今天没做多少东西[就写了几个页面小部件],但我觉得我进步了。因为我现在实现一个功能不是单纯的的靠代码的堆砌,为了实现一个功能而去做一个功能。每写一个功能其实都是一个方法/函数集合体,只有这样才能提高复用性及后期的可扩展性。
\n2017-01-11 \nDONE: 寻找灵感。。。顺便巩固js基础。我现在已经被canvas深深的吸引了。程序和艺术可以结合的这么完美。 \nTODO: 明天开始建站。由于自己之前太笨,结构没设计好,只能重做。这次用自己的一套 grid 和 media 相信页面结构应该会比较容易控制,而且也不存在多余的代码。垃圾代码少了,样式覆盖的问题应该能好点(虽然我水平就这样,但我尽量保证不制造垃圾,🤔)
\n2017-01-12 \nDONE: 做了一个环形进度条。。。准备学习 webpack。
\n2017-01-13 \nDONE: webpack.config.js。万事具备,似乎可以开始了。 \nSUM: 不知不觉中就已过去了 20 天。学到了很多,但是不幸的是发现不会的更多了。原来,知道与不知道是成正比的,知道的越多,才发现不知道的也愈多。(好奇害死猫,不好奇,也许猫不会死,但那还是猫吗?。。。)
","category":{"name":"Notes"},"labels":{"edges":[]},"reactions":{"totalCount":0,"edges":[]},"comments":{"edges":[]}}
\ No newline at end of file
diff --git a/issues/61.json b/issues/61.json
new file mode 100644
index 0000000..817e914
--- /dev/null
+++ b/issues/61.json
@@ -0,0 +1 @@
+{"id":"MDEwOkRpc2N1c3Npb24zNDg5OTk5","title":"微信杂谈 - 技术栈","bodyHTML":"📅 2021.07.30
\n易潇: \n大佬们可以聊聊 选前端还是后端吗 \n现在在选组 有两个 都是全栈 但一个偏前端 一个偏后端 \n可以聊聊不同方向的职业成长路线 或者 哪里可以了解到这些方向的职业成长路线吗 \n感谢~
\n小和尚: \n喜欢啥就选啥
\nlencx: \n技术方向做到后面可以自由切换的吧,我也觉得喜欢什么就选什么没错
\n小和尚: \n我都写过[苦涩]但我不喜欢后端
\n : \n全栈吧,一般大佬,前后端运维都会,样样精通。
\nlencx: \n我感觉最大的区别就是要积累的东西经验,是不一样的,这个需要花时间
\n小和尚: \n我是觉得后端做的事情,我并不是很感兴趣
\n小和尚: \n如果只是做接口写服务,其实还好
\n小和尚: \n但是如果搞docker,k8s,我就很怂
\nlencx: \n如果让我选,我可能会选全干,可惜能力不够[旺柴]
\n小和尚: \n如果不涉及这些,我早就全干过了
\n小和尚: \n但是后来明显的弱爆了,尤其是当我想搞tripworker的时候
\n小和尚: \n因为后端现在比较流行的架构就是serverless
\n小和尚: \n要么,跑wasm,要么,搞一些fass啥的
\n小和尚: \n他们在v8上跑wasm很舒服,支持多种语言的serverless
\nlencx: \n学习其实就是循序渐进,不断扩宽知识面,我刚开始只会 html,css,现在会写点 js 了,如果想继续深入,可以学其他语言技术,我觉得语言不是限制自己的条件,时间才是。
\nlencx: \n我最近也很焦虑,感觉什么都学不进去了
\nlencx: \n知识它就是不进脑子,一看东西就烦躁
\n小和尚: \n所以我从来不看知识
\n小和尚: \n我基本上不看基础的东西,上来就写代码,写不对就改
\n小和尚: \n慢慢的,很多年后,基础也就都理解了
\nlencx: \n还是解决问题吧,遇到问题就学习
\nlencx: \n从解决问题中学习
\n小和尚: \n我会积累一些东西,但仅仅只是多看一眼
\n云谦: \n@🐶 - 0 - 易潇 我理解的前端:离用户近,多终端支持和兼容,交互多,技术深度相比后端浅,普通业务话语权没后端大(富交互业务除外),竞争压力相比后端小一些?,主 JavaScript 语言,开源社区活跃。然后就看自己选了。
\n另外,长远看,前端的深度到 p8 p9 还好,再往前走会比较困难,后端则可以走地更远。
\n易潇: \n弱弱的问为什么后端技术深度高但是竞争更高?正常不应该是技术壁垒低的地方初级的竞争更激烈吗,比如说做销售
\n永远八岁: \n因为前端的概念,是这几年才有的。
\n🇨🇳 Promise: \n我的理解是基数大
\nlencx: \n是因为普通java烂大街吧
\n永远八岁: \n前10年那些人,都是去搞后端的
\nMr.Black: \n后端学校有教,前端大部分都是自己学的。
\n🇨🇳 Promise: \n现在基本本科java 考研python
\n🇨🇳 Promise: \n出来学学框架就可以了
\n永远八岁: \n这就导致大环境(包括老师、资深开发者)认为后端才是真正的敲代码的,前端都是闹着玩的
\n🇨🇳 Promise: \n我个人觉得是 谁离数据源更近,谁更具有话语权
\n永远八岁: \n我倒是觉得前端比后端更难,从现在来说
\n永远八岁: \n后端已经太久没变化了。
\n永远八岁: \n前端从 生命周期 -> hooks,这是发生了翻天覆地的变化。
\n永远八岁: \n写页面时考虑已经变了。
\n永远八岁: \n就像是当年栅格布局一样。即使Bootstrap没人用了(包括react),但是他们的思想会推动整个前端继续发展下去,影响深远。
\n永远八岁: \n能思考出 生命周期 -> hooks 这个想法的人和团队,我认为这才是真的强的人。
\n永远八岁: \n那后端已经很久没有这种大的翻天覆地的东西了。
\n易潇: \n大家对选择 大的,已经很成熟的组 vs 小的,做什么不用跟那么多组沟通,但是scope也小的组;有啥建议吗
\n🇨🇳 Promise: \n其实是不是也意味着后端思想很多的时候已经在当下环境下已经穷尽了大多数的方案和技术,更新的只是末节
\nMr. 🍊: \n从jq到react都算是翻天覆地的变化的[旺柴]
\n🇨🇳 Promise: \n而前端作为新的产物,还是在一个快速生长的时期
\n永远八岁: \n是的,大多数都是在框架以下,延伸工具链
\n小和尚: \n前端不只是web啊
\n永远八岁: \njq->react 这是一定的。因为那时候大家已经认识到jq的缺陷了
\n永远八岁: \nshow 一个组件,写一大片模版。
\n小和尚: \n前端框架这种纯web的东西其实和前端架构没什么关系的,除非你写组件库
\n永远八岁: \n只不过缺一个有担当团队做出来。
\nlencx: \nreact 肯定也不会是结局
\n阿西吧~~~: \n大多数公司都是这个状态。你有钱了,可以不工作,用你会的技术实现你自己的想法。当你出结果的时候,你就是意识形态
\n永远八岁: \nreact属于时势造英雄
\nlencx: \n我觉得技术的核心,还是产品吧,是场景孕育出技术的
\n永远八岁: \n但是 react hook 可就是纯思维啦。
\n永远八岁: \n产品是挣钱的。挣了钱满足物质,才有精力想继续发展技术。
\n永远八岁: \n场景我觉得只能孕育链路。
\n🇨🇳 Promise: \n赞同, 产品的思想是0-1的过程,是始端
\n永远八岁: \n比如 抢购场景。只能孕育这条线的流程。不会产生出伟大的思想来。
\n🇨🇳 Promise: \n我感觉多年以来思想没有变,变得只有方式
\nlencx: \n比如现在的场景是lot,如果没有相关技术来实现,就会出现一些新技术,用来解决场景中的一些需求痛点吧,我是这么理解的。但是技术的发展需要有理论作支撑,所以这又是一个演化创造的过程
\n🇨🇳 Promise: \n例如卡兰尼克创立了uber,还是打车业务,只不过方式更加的适应现代化
\n永远八岁: \n是的,你说的,正是我的想法。
\n永远八岁: \n并不是redis支撑了抢购,不是redis多厉害,而是人们需要他。
\n永远八岁: \n但是他的本质就是一个db
\n永远八岁: \ndb人们研究了几个世纪了,所以拿着这个思想来做个redis,肯定是简单许多的。
\n🇨🇳 Promise: \n今天的分享,干货满满啊,👍
","category":{"name":"Notes"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwzMTgxNDE5MDUz","name":"微信杂谈"}}]},"reactions":{"totalCount":0,"edges":[]},"comments":{"edges":[]}}
\ No newline at end of file
diff --git a/issues/63.json b/issues/63.json
new file mode 100644
index 0000000..2513ea5
--- /dev/null
+++ b/issues/63.json
@@ -0,0 +1 @@
+{"id":"MDEwOkRpc2N1c3Npb24zNTA1MDUw","title":"JS 手写系列","bodyHTML":"\nImplementation of Native JavaScript Methods
\n \n⚠️ 注意:不符合以下格式的评论将会被删除
\n\n手写新(评论中不存在)的方法,建议新开评论,排版参考 forEach \n\n👉 方法名(必须) \n💠 语法(可须) \n⚠️ 注意(可选) \n✍️ 实现(必须) \n📌 测试(必须) \n🔗 参考链接(可选) \n \n \n针对某个手写方法的讨论,建议使用回复评论的形式 \n \n \n查看源码 js-wheel
\n \nStandard \n\n\nArray \n\n \n\nFunction \n\n \n\nUtils \n\n ","category":{"name":"FE"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwyMjk0NjQ2Mjcx","name":"js"}},{"node":{"id":"MDU6TGFiZWwzMDI2NDEyNzMy","name":"interview"}}]},"reactions":{"totalCount":0,"edges":[]},"comments":{"edges":[{"node":{"id":"MDE3OkRpc2N1c3Npb25Db21tZW50MTEzNzg1MA==","bodyHTML":"👉 forEach \n\nforEach() 方法对数组的每个元素执行一次给定的函数
\n \n💠 语法 \narr . forEach ( callback ( currentValue [ , index [ , array ] ] ) [ , thisArg ] ) \n\ncallback
- 为数组中每个元素执行的函数,接收一至三个参数\n\ncurrentValue
- 数组中正在处理的当前元素 \nindex
[可选] - 数组中正在处理的当前元素的索引 \narray
[可选] - 调用 forEach() 方法的数组 \n \n \nthisArg
[可选] - 当执行回调函数 callback 时,用作 this 的值 \n返回值 - undefined
\n \n⚠️ 注意 \n除了抛出异常以外,没有办法中止或跳出 forEach() 循环
\n✍️ 实现 \nArray . prototype . myEach = function ( callback ) { \n for ( var i = 0 ; i < this . length ; i ++ ) { \n callback ( this [ i ] , i , this ) ; \t\n } \n} \n📌 测试 \nvar arr = [ 'js' , 'css' , 'html' ] ; \narr . myEach ( function ( item ) { \n console . log ( item ) ; \n} ) \n \n🔗 参考链接 \n","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"replies":{"edges":[{"node":{"id":"MDE3OkRpc2N1c3Npb25Db21tZW50MTEzODA3Mw==","author":{"login":"MarukoAnn","avatarUrl":"https://avatars.githubusercontent.com/u/34764507?u=1e7c9167471a50c22517d0a908f5034c861cced0&v=4","url":"https://github.com/MarukoAnn"},"bodyHTML":"Array . prototype . myForEach = function ( fn , args ) { \n // 边界处理 \n if ( this === null && this === undefined && ! Array . isArray ( this ) ) { \n throw new TypeError ( 'type is error' ) \n } \n if ( typeof fn !== 'function' ) { \n throw new TypeError ( fn + 'is not function' ) \n } \n for ( let i = 0 ; i < this . length ; i ++ ) { \n fn . call ( args , this [ i ] , i , this ) \n } \n} "}},{"node":{"id":"MDE3OkRpc2N1c3Npb25Db21tZW50MTEzODIxNw==","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"bodyHTML":"@moonshinean 写箭头函数,this
的指向是有问题的
\n\nArray . prototype . myForEach = ( fn , args ) => { \n // 边界处理 \n if ( this === null && this === undefined && ! Array . isArray ( this ) ) { \n throw new TypeError ( 'type is error' ) \n } \n if ( typeof fn !== 'function' ) { \n throw new TypeError ( fn + 'is not function' ) \n } \n for ( let i = 0 ; i < this . length ; i ++ ) { \n fn . call ( args , this [ i ] , i , this ) \n } \n} \n "}},{"node":{"id":"MDE3OkRpc2N1c3Npb25Db21tZW50MTEzODIyNQ==","author":{"login":"MarukoAnn","avatarUrl":"https://avatars.githubusercontent.com/u/34764507?u=1e7c9167471a50c22517d0a908f5034c861cced0&v=4","url":"https://github.com/MarukoAnn"},"bodyHTML":"@lencx 对哈 我改一下 改一下
"}}]}}},{"node":{"id":"MDE3OkRpc2N1c3Npb25Db21tZW50MTEzODYzMA==","bodyHTML":"👉 map \n\nmap() 方法创建一个新数组,其结果是该数组中的每个元素调用一次给定函数后的返回值
\n \n💠 语法 \nvar new_array = arr . map ( function callback ( currentValue [ , index [ , array ] ] ) { \n // Return element for new_array \n} [ , thisArg ] ) \n\ncallback
- 生成新数组元素的函数,接收一至三个参数\n\ncurrentValue
- 数组中正在处理的当前元素 \nindex
[可选] - 数组中正在处理的当前元素的索引 \narray
[可选] - 调用 map() 方法的数组 \n \n \nthisArg
[可选] - 当执行回调函数 callback 时,用作 this 的值 \n返回值 - 一个由原数组每个元素执行回调函数的结果组成的新数组 \n \n✍️ 实现 \nArray . prototype . myMap = function ( callback ) { \n arr = [ ] ; \n for ( var i = 0 ; i < this . length ; i ++ ) { \n arr [ i ] = callback ( this [ i ] , i , this ) ; \n } \n return arr ; \n} \n📌 测试 \nvar arr = [ 1 , 2 , 3 ] ; \nvar newVal = arr . myMap ( i => Math . pow ( i , 2 ) ) ; \nconsole . log ( newVal ) ; // [1, 9, 16] \n \n🔗 参考链接 \n","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"replies":{"edges":[]}}},{"node":{"id":"MDE3OkRpc2N1c3Npb25Db21tZW50MTE2NzYwMQ==","bodyHTML":"👉 sleep \n指定时间内函数暂停执行。 在 C 或 PHP 等编程语言中,可以调用 sleep(2)
使程序暂停 2 秒。 Java 有 Thread.sleep(2000)
,Python 有 time.sleep(2)
,Go 有 time.Sleep(2 * time.Second)
。
\nJavaScript 没有原生的休眠功能,但由于引入了 promises(以及 ES2018 中的 async/await
),我们可以用一种优雅地方式来实现此功能。
\n✍️ 实现 \nfunction sleep ( ms ) { \n return new Promise ( resolve => setTimeout ( resolve , ms ) ) ; \n} \n📌 测试 \nasync function testSleep ( ) { \n console . log ( 'Taking a break...' ) ; \n await sleep ( 2000 ) ; \n console . log ( 'Two seconds later, showing sleep in a loop...' ) ; \n\n // Sleep in loop \n for ( let i = 0 ; i < 5 ; i ++ ) { \n if ( i === 3 ) await sleep ( 2000 ) ; \n console . log ( i ) ; \n } \n} \n\ntestSleep ( ) ; \n \n🔗 参考链接 \n","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"replies":{"edges":[]}}},{"node":{"id":"MDE3OkRpc2N1c3Npb25Db21tZW50MTE4OTU1NA==","bodyHTML":"👉 filter \n💠 语法 \nvar newArray = arr . filter ( callback ( element [ , index [ , array ] ] ) [ , thisArg ] ) \n✍️ 实现 \nArray . prototype . myFilter = function ( callback , context ) { \n var arr = [ ] ; \n var idx = 0 ; \n for ( var i = 0 ; i < this . length ; i ++ ) { \n \tif ( callback . call ( context , this [ i ] , i , this ) ) { \n \t arr [ idx ++ ] = this [ i ] ; \n \t} \n } \n return arr ; \n} \n📌 测试 \nvar arr = [ 1 , 2 , 3 , 4 , 5 ] ; \nvar newVal = arr . myFilter ( i => i > 3 ) ; \nconsole . log ( newVal ) ; // [4, 5] \n \n🔗 参考链接 \n","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"replies":{"edges":[]}}},{"node":{"id":"MDE3OkRpc2N1c3Npb25Db21tZW50MTIzMTk2NA==","bodyHTML":"👉 curry \n在计算机科学中,柯里化(英语:Currying),又译为卡瑞化或加里化,是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术。这个技术由克里斯托弗·斯特雷奇以逻辑学家哈斯凯尔·加里命名的,尽管它是 Moses Schönfinkel 和戈特洛布·弗雷格发明的。
\n柯里化是将一个接受多个参数的函数分解成一系列函数,每个函数只接受一个参数。
例如:将 f(a,b,c)
变换为 f(a)(b)(c)
。
\n✍️ 实现 \nfunction curry ( func ) { \n return function curried ( ...args ) { \n // 如果参数的数量(args.length)大于或等于原函数中定义的参数数量(func.length), \n // 则直接使用 func.apply 将参数传递。 \n if ( args . length >= func . length ) { \n return func . apply ( this , args ) ; \n } \n // 否则,我们只得到一部分参数,此时还未调用 func, \n // 则返回一个新的匿名函数,重新柯里化,提供之前的参数(args)和当前匿名函数参数(args2)。 \n return function ( ...args2 ) { \n return curried . apply ( this , args . concat ( args2 ) ) ; \n } ; \n } ; \n} \n📌 测试 \nfunction sum ( a , b , c ) { \n return a + b + c ; \n} \n\nconst currySum = curry ( sum ) ; \n\ncurrySum ( 1 , 2 , 3 ) ; // 6 - 未柯里 \ncurrySum ( 1 ) ( 2 ) ( 3 ) ; // 6 - 完全柯里 \ncurrySum ( 1 ) ( 2 , 3 ) ; // 6 - 第一个参数柯里 \n \n🔗 参考链接 \n","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"replies":{"edges":[]}}}]}}
\ No newline at end of file
diff --git a/issues/66.json b/issues/66.json
new file mode 100644
index 0000000..561b9b2
--- /dev/null
+++ b/issues/66.json
@@ -0,0 +1 @@
+{"id":"MDEwOkRpc2N1c3Npb24zNTEzMzcx","title":"开源 - 原创打卡","bodyHTML":"\n我发起了一个原创写作计划,通过开源打卡的形式来相互监督。
\n \n目前计划刚刚启动,还有很多地方需要完善,如果有感兴趣的朋友,欢迎参与。
\n仓库:zkuhut/monthly \n网站:臻苦舍月刊
\n有两种参与方式,选择其中一种即可:
\n\n关注公众号:浮之静
,回复 开源打卡
\nFork
仓库,提交 PR
,可参考 怎样贡献一篇文章? \n \n关于 \nzkuhut
:臻(z)苦(ku)舍(hut) \n臻,至也;苦,始也。
- 谐音 真苦
,想要到达高的,完美的(臻),一切只是刚刚开始(苦)。
\n背景 \n在信息爆炸的时代,我们最缺的不是如何获取信息,有价值的信息沉淀下来才是真正的知识。我们每个人都会阅读,思考,但是要把这些思考想法输出的人似乎并没有想象中那么多。
\n人都是有惰性的,会因为种种原因而放弃自己的一些计划或目标,三分钟热度。此次发起学习小组,就是想基于 GitHub 来进行协作监督,记录自己。
\n很多人,包括我自己都会有这样的困惑:
\n\n我很菜,不知道该写点什么。 \n我会的东西那么简单,写出来会不会被别人笑话。 \n我想写的东西似乎很多人都写过了,还有必要自己写吗? \n \n对此我想谈谈自己对于有价值信息的理解。输出文章是为了记录,梳理,引发一些思考及观点。其次才是分享(别太高看自己,你写的东西没几个人会看到的)。用最直白的语言讲清楚一件事或一个东西,就是有价值的信息。
\n技术栈 \n写作平台 \n现在的写作形式就那么几种:
\n\n第三方平台\n\n国内:知乎
,掘金
,公众号
,简书
,CSDN
等 \n国外:dev.to
,medium
等 \n \n \n自建博客\n\n自己搭建服务器 \n基于 GitHub
,Gitee
的 pages
搭建网站 \n \n \n云笔记:Notion
,有道云笔记
等 \n \n方案确定 \n最终选择 GitHub 作为代码及文章托管平台,vitepress + github actions + github pages + giscus 构建网站。原因有以下几点:
\n\n多人协作 \n不受平台制约 \ngithub + git 常用操作学习 \ngithub actions 自动执行一些脚本或发布任务 \n方便进行扩展及二次开发 \n \n不过缺点也十分明显,就是无法通过平台引流。不过其目标为了记录自己,所以这个缺点可以忽略不计。
\n身为一名程序员,如果不会使用 GitHub,不能够在全球最大的同性交友网站畅游与学习,我认为不是一名合格的程序员。而参与项目就是最好的学习。
\n写作环境 \n\nNode.js
- 基于 vitepress 搭建 \nGitHub
- 用于多人协作 \nzkuhut
- 加入 GitHub 组织(非必需) \n \n写作要求 \n\n✅ 人/月至少输出一篇原创,坚持下来的,欢迎申请加入 zkuhut
组织 \n✅ 内容不限,技术,思考,新技术尝试等皆可 \n✅ 严谨性,专业术语,相关资源要有出处 \n🚫 打广告,卖课 \n🚫 搬运,抄袭 \n \n微信群 \n
","category":{"name":"General"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwzMDg2MDYxNzMz","name":"blog"}},{"node":{"id":"MDU6TGFiZWwzMTk2OTc2MDIx","name":"wechat-post"}}]},"reactions":{"totalCount":0,"edges":[]},"comments":{"edges":[]}}
\ No newline at end of file
diff --git a/issues/68.json b/issues/68.json
new file mode 100644
index 0000000..33771db
--- /dev/null
+++ b/issues/68.json
@@ -0,0 +1 @@
+{"id":"MDEwOkRpc2N1c3Npb24zNTIxODUz","title":"基于 GitHub Discussions 的 Blog 框架","bodyHTML":"我是一个喜欢折腾的人,虽然文章没写几篇,但是 Blog 框架没少折腾,刚入行那会用蹩脚的前端技术自己实现,就感觉越花哨,越能证明自己的实力,各种大投影,大圆角,奇怪的字体... 随着认知的提升,懂得了内容才是核心,页面开始变得不那么花哨,使用 Hexo ,Gatsby ,自己实现 nofwl 主题 。再到后来的 vuepress , vitepress 和 mdBook 。全都被我换了一遍,总是感觉不合自己胃口,于是就萌生了自己写 Blog 框架的想法。
\n需求背景 \n我想做的 Blog 框架满足以下条件:
\n\n实时性
- 可以随时随地编辑,与平台无关,同时支持手机,电脑,本地,在线编辑等 \n所有权
- 我对数据的权限越大越好,这样我就可以根据自己的需要去渲染页面模版 \n公众号
- 可以生成微信公众号文章(微信链接不支持跳转,需要生成脚注或二维码) \nRSS
- 支持 RSS 订阅 \n \n技术栈 \nBlog 框架的搭建本身也是学习的过程,技术栈一定要前沿,因为我喜欢折腾。结合上面的需求背景,经过多方面比较,最终选择了 GitHub Discussions
作为数据源。vite + react
作为 Blog 基本框架。
\n最终用到的技术包含:
\n\ngithub discussions api - 文章数据源,因为是接口请求,所以可以满足文章实时性及数据所有权需求 \ngithub actions - 执行定时任务(生成 RSS 文件,JSON 数据文件,微信文章等),及网站部署 \nscripts
- 定时任务需要执行的脚本命令,用来满足公众号文章及 RSS 需求\n\nrgd - 🍱 GitHub Discussions API - RSS & JSON \nwoap - 🌀 GitHub Discussions 生成微信文章 (支持二维码及脚注形式) \n \n \n@apollo/client - 是一个 JavaScript 状态管理库,能够使用 GraphQL 管理本地和远程数据。使用它来获取、缓存和修改应用程序数据,同时自动更新 UI。 \nvite - 下一代前端开发与构建工具 \nreact - 用于构建用户界面的 JavaScript 库 \nrecoil - React 状态管理库 \n \n常见问题 \n关于 Github Token \nBlog 需要满足任何人在不经过 GitHub 登陆,或授权就可以访问网页,所以需要提供公共 Token
来请求数据。因为 GitHub Token 存在每小时接口请求次数限制,超出请求次数会报错。官方文档建议缓存接口请求,但是整个 Blog 托管于 GitHub Pages ,并不能缓存接口请求。
\n解决方案 \n使用 rgd
将接口数据生成 JSON 文件。当网站请求 GitHub API 超过次数限制,会自动降级请求部署后项目中的 json 文件。同时支持两种模式是因为:请求接口网站是实时的(体验效果好),请求的 json 文件是非实时(每天跑一次定时任务)。
\n关于 RSS \n使用 rgd
生成 RSS 文件,每天执行一次定时任务(非实时)。
\n关于公众号 \n使用 woap
生成微信文章,每天执行一次定时任务(非实时)。Discussions
标签满足 woap
的标签规则就会将该文生成为微信文章。
\n标签规则 \n\nwechat-link
- 微信链接转为二维码,适合多链接场景 \nwechat-post
- 微信链接转为脚注,适合多文字场景 \n \n更多使用规则请查看 woap 参数 。
\n关于项目 \n","category":{"name":"Notes"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwzMDg2MDYxNzMz","name":"blog"}},{"node":{"id":"MDU6TGFiZWwzMTk2OTc2MDIx","name":"wechat-post"}}]},"reactions":{"totalCount":1,"edges":[{"node":{"id":"MDE4OkRpc2N1c3Npb25SZWFjdGlvbjIxMzU1Ng==","content":"THUMBS_UP"}}]},"comments":{"edges":[]}}
\ No newline at end of file
diff --git a/issues/7.json b/issues/7.json
new file mode 100644
index 0000000..c360150
--- /dev/null
+++ b/issues/7.json
@@ -0,0 +1 @@
+{"id":"MDEwOkRpc2N1c3Npb24zMzc4Mzgz","title":"静态网站生成器","bodyHTML":"\n文档及建站
\n \nRust \n\nmdbook - Create book from markdown files. Like Gitbook but implemented in Rust.\n\nmdbook-katex - A preprocessor for mdBook, rendering LaTex equations to HTML at build time. \nmdbook-mermaid - A preprocessor for mdbook to add mermaid support. \n \n \ncobalt - Static site generator written in Rust. \nzola - A fast static site generator in a single binary with everything built-in. \n \nNode.js \n\nVue\n\nVuePress - Vue-powered Static Site Generator. \nVitePress - VitePress is VuePress' little brother, built on top of Vite. \nSlidev - Presentation Slides for Developers. \n \n \nReact\n\nGatsby - Gatsby provides development teams an open source frontend framework for creating rich, optimized websites and a cloud platform for delivering them on a blazing fast edge network. \ndumi - A doc tool can assist you to develop libraries & write docs. \n \n \nHexo - A fast, simple & powerful blog framework. \neleventy 🕚⚡️ - A simpler static site generator. An alternative to Jekyll. Transforms a directory of templates (of varying types) into HTML. \n \nOther \n\npandoc - Universal markup converter \n ","category":{"name":"Tools"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwzMDI0NjA1NTk3","name":"doc"}}]},"reactions":{"totalCount":0,"edges":[]},"comments":{"edges":[]}}
\ No newline at end of file
diff --git a/issues/70.json b/issues/70.json
new file mode 100644
index 0000000..3854994
--- /dev/null
+++ b/issues/70.json
@@ -0,0 +1 @@
+{"id":"D_kwDOEUMBcs4ANnyn","title":"解决问题之经验篇","bodyHTML":"\n问题不可能被穷举,答案经验有时候并不足以让我们应付千奇百怪的问题。在题海中,培养自己分析,定位,解决问题的能力似乎才是我们唯一的出路(以不变应万变)。
\n \n一般问题解决步骤:
\n\n遇到问题
(不要慌)\n\n这个问题没见过,咋搞呀 \n我正好有个技术群,丢个报错截图去问问 \n... \n \n \n分析问题
(抽丝剥茧)\n\n多问自己为什么,从问题报错处,排除干扰,向上 debugger
\n小黄鸭调试法 - 小黄鸭调试法,又称橡皮鸭调试法、黄鸭除虫法(Rubber Duck Debugging)是可在软件工程中使用的一种调试代码的方法。方法就是在程序的调试或测试过程中,操作人耐心地向小黄鸭解释每一行程序的作用,以此来激发灵感与发现矛盾 \n \n \n描述问题
(提取关键词)\n\n \n关键词搜索
(中,英文)\n\n中文
- 国内太卷,抄袭严重,问题没有出处。除非是特定问题(微信小程序之类的问题),否则不建议使用中文搜索 \n英文
- 质量要高很多,推荐使用 Google 搜索,替代品 Bing 搜索 \n \n \n解决问题
(总结经验)\n\n反思总结
- 沉淀是为了让自己能够举一反三 \n分享经验
- 表达是为了进一步加深理解 \n \n \n \n如果以上步骤无法解决问题,向别人请教之前,以下几点是必须要做的:
\n\n如果以上步骤都做了,仍然无法解决问题,则可以在项目 issues
或 stack overflow
等问题社区发起提问:
\n\n问题描述
- 简洁清楚的表达问题,切记啰嗦 \n环境信息
- 问题发生的环境(系统信息,软件版本,浏览器版本等) \n如何复现
- 提供问题复现步骤 1,2,3,可以配合适当的错误截图及说明\n\n复现用例
- 用例要排除业务干扰,缩小问题范围 \n我的尝试
- 自己做过哪些尝试,也可以让别人快速排除一些干扰项 \n \n \n预期结果
- 希望得到什么样的结果 \n ","category":{"name":"Notes"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwzMDg2MDYxNzMz","name":"blog"}},{"node":{"id":"MDU6TGFiZWwzMTk2OTc2MDIx","name":"wechat-post"}}]},"reactions":{"totalCount":3,"edges":[{"node":{"id":"REA_lAXOEUMBcs4ANnynzgADiVE","content":"THUMBS_UP"}},{"node":{"id":"REA_lAXOEUMBcs4ANnynzgADmiE","content":"THUMBS_UP"}},{"node":{"id":"REA_lAXOEUMBcs4ANnynzgADm_8","content":"THUMBS_UP"}}]},"comments":{"edges":[]}}
\ No newline at end of file
diff --git a/issues/71.json b/issues/71.json
new file mode 100644
index 0000000..9d2b034
--- /dev/null
+++ b/issues/71.json
@@ -0,0 +1 @@
+{"id":"D_kwDOEUMBcs4ANn3P","title":"开发问题汇总","bodyHTML":"解决问题之经验篇
\n\n问题清单
\n \n\n什么是 disk-cache
\n浏览器缓存问题(线上代码未更新) \n... \n ","category":{"name":"FE"},"labels":{"edges":[]},"reactions":{"totalCount":0,"edges":[]},"comments":{"edges":[]}}
\ No newline at end of file
diff --git a/issues/72.json b/issues/72.json
new file mode 100644
index 0000000..de96209
--- /dev/null
+++ b/issues/72.json
@@ -0,0 +1 @@
+{"id":"D_kwDOEUMBcs4ANqol","title":"滚动进度条","bodyHTML":"\n学习框架语言,写代码是最快的入门方式。为了给基于 vitepress
构建的 Blog 新增功能,现学 Vue3
,诞生了下面的进度条组件。
\n \n体验地址 - 手写 Code Snippets 系列
\n创建一个进度条,用来指示页面滚动百分比,主要有两点注意事项及一个思考:
\n\n使用 position: fixed
将滚动进度条置于页面顶部,z-index
设置一个较大的值是为了保证元素在页面内容的最上层。 \n使用 EventTarget.addEventListener
和 Element.scrollTop
来确定文档的滚动百分比并将其设置为滚动进度条的宽度。 \n思考 - 如果页面容器高度发生变化,会发生什么? \n \n💠 核心 \n\n# scroll_progress_bar {\n position : fixed;\n top : 0 ;\n width : 0% ;\n height : 4px ;\n background : # 7983ff ;\n z-index : 10000 ;\n} \nconst scrollProgress = document . getElementById ( 'scroll_progress_bar' ) ; \n// 滚动条高度 \nconst height = document . documentElement . scrollHeight - document . documentElement . clientHeight ; \n\nwindow . addEventListener ( 'scroll' , ( ) => { \n const scrollTop = document . body . scrollTop || document . documentElement . scrollTop ; \n // 当前进度条进度 = 当前滚动条位置 / 滚动条高度 \n scrollProgress . style . width = `${ ( scrollTop / height ) * 100 } %` ; \n} ) ; \n✍️ 实现 \n🔶 Vue3 \n\n🎥 演示 \n
\n \n🔗 参考 \n","category":{"name":"Notes"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwzMDUyMDQ4NTAz","name":"vue"}},{"node":{"id":"MDU6TGFiZWwzMDg2MDYxNzMz","name":"blog"}},{"node":{"id":"MDU6TGFiZWwzMTk2OTc2MDIx","name":"wechat-post"}}]},"reactions":{"totalCount":0,"edges":[]},"comments":{"edges":[]}}
\ No newline at end of file
diff --git a/issues/74.json b/issues/74.json
new file mode 100644
index 0000000..4c7fd1f
--- /dev/null
+++ b/issues/74.json
@@ -0,0 +1 @@
+{"id":"D_kwDOEUMBcs4ANsiC","title":"lencx 语录","bodyHTML":"\n此语录,无任何意义,仅记录生活中的所思所感...
\n \n学习 \n\n要学会把问题交给搜索引擎,而不是把群友当成搜索引擎。 \n同样一个问题,用百度和 Bing (有能力的用 Google ) 对比一下就知道了。 \n学习技术,先扫一遍文档,从最基本的开始搭建学习,功能一点点的增加进来。边看边实践,敲键盘也会加深记忆。 \n优秀一天容易,难的是一直优秀。 \n一篇好文章,更像是一根线,而不是一团麻。极客精神,以风趣幽默的方式解释清楚一切细节。 \n学到一句话:经验这个东西,就是越多越好,可以不去做,但是不能不知道。 \n有问题不可怕,可怕的是,不知道怎么和问题去相处。 \n答案是最无用的东西,因为它是一个问题的处理结果,是由过程分析推理得出来的,过程推理不出,而选择去背答案是最无效的学习方式,毫无意义! \n学习就是从懵逼到膨胀的一个死循环 🔄 \n以后再也不敢说自己是在自学了。没有基础作为指导,只能算是瞎学,乱学。看完《自学计算机科学》 这份书单,才发现自己对计算机一无所知。 \n真正的高效工作,是首先先学会如何解放自己。 \n骨头是不好啃,自己要先啃几口,才有发言权。别还没啃,就说太硬了。(软饭吃多了,牙也变软了) \n遇到问题自己不思考,不尝试,就没有资格把这个问题抛出来。(踢皮球并不能让自己成长) \n学会自我总结, 一步一个脚印,别总想着有人可以帮你。(外力终究不是自己的) \n知识就是这样的,会一点点进入你的视野。但是前提,你要保持好奇心,并且不断地尝试。 \n人的思想蜕变,不是一瞬间产生的,而是不断起伏的人生带给你的。 \n学习是自己的事情(信息的收发建立在共识之上),没有人可以真正帮助你。有所收获,最该感谢的人其实是自己。 \n学习是一件痛苦的事情,开始享受这个过程,或许就是自己在努力汲取养分生长吧。 \n \n思考 \n\n学习其实就是用到什么学什么,能否快速掌握一门技术,和你学了多少门技术其实没有太大关系(要学的东西应该是技术背后的通用思想)。分析,思考,解决问题的能力,也并不是你接触的技术所能带给你的。因为知识是死的,而人却是活的,所以这些能力的培养和养成其实是一个主动行为。未知知识学习 = 拓展阅读(已有知识中的未知部分) + 信息源(领域大牛)+ 已有知识 + 经验推导
\n有人问我该如何学习,其实我也不知道,当我迷茫时,就强迫自己静下心来写一个项目,不断地解决问题,然后就会变得很享受。问题不是凭空出现的,遇到的时候,你就会去搜寻各种解决方案,这就是学习。有些人最大的问题就是在遇到问题时第一时间把问题抛给别人,把群友当成搜索引擎。没有思考,没有尝试,也就不能够形成自己解决问题的方法论。 \n人最大的价值就是没有价值,做任何事的意义就是毫无意义。 \n \n日常 \n\n知识就摆在那里,想学的会想尽办法会去寻找,没必要去投喂。 \n感谢所有夸我的人,说句实话,我不 NB,在技术群里,大部分人的能力都要比我强,我只是比较张扬而已。 \n任何话题都是技术交流,代码不是全部。 \n不信鬼神,但对未知还是要保持敬畏之心。 \n群里虽然前端居多,似乎更应该发和前端相关的内容。但一切皆知识,路应该越走越宽。专精于 xxx 或许没错,但只有 xxx,视野过于被局限,会少了很多灵感碰撞及其他可能性。(广度与深度该如何抉择) \n彩票属于不确定的意外之财,讨论这个没啥意义。运气不是每个人都有的,现实点。(学会自我催眠) \n我写的文章没啥技术含量,手撕不动,脑子也不怎么灵活,基础更是一塌糊涂。 \n我想明白了一些事情:欲望就好比握在手中的沙子,不握紧,会流失。握紧了,只会流的更快。因为想要获得,各种复杂的情绪就产生了,兴奋,焦虑… 如果放弃了所有的欲,一切便会回归于无。 \n当一些东西变得重复与机械的时候,也就失去了原本的兴趣。 \n自省只是不想让自己太飘,因为人是社会性动物,他人的评价或多或少都会对自己产生影响。 \n知识,技术可以变现,但是丢掉原则,就不再是一个技术人了。 \n本以为自己只是走了两三年的弯路,谁知从未走出... \n开源其实是一件很简单的事情,你想做,就可以去做。 \n人更喜欢相信自己看到的。很少有人去思考,你所看到的是不是别人故意给你看的?(眼见不一定为实) \n以前我也认为只要学会独立思考就够了,但是后来我发现,如果你所看到的一切都是假象,那么基于它做出思考将是一件可怕的事情。(价值观坍塌) \n眼界,思考,质疑,都很重要。 \n当对一切失去了怀疑的态度,会让你觉得它就是权威,不会出错。这是很可怕的事情。(盲目崇拜) \n做你认为对的事情,就不存在浪费时间一说。 \n有人说:“大多数的成功来源于勇气,似乎越成熟,越丧失了追求的勇气”。但是我认为不是越活越没勇气,而是人学会了算计,会去计较得失,才变得畏手畏脚。(冲动是魔鬼,太过于理智,生活也就少了一些色彩) \n一定要学会享受过程。结果很重要,但是如果真的有一天你可以直接到达这个结果的时候,未必是快乐的。(出生的结局就是死亡) \n没有学会取舍,才会让自己那么累。(放下也是一种智慧) \n我不想努力了,可是没钱。钱不是那么重要,但是没有它,可能会过的很惨。(衣食住行) \n这个世界是动态的,一切都在变化,人也如此。(保持初心) \n穷爸爸富爸爸 告诉我们,起点大于努力。(生的好也很重要) \n \n吐槽 \n\n做任何事都是需要指标的,没有高标准,就不会把事情做到极致。但是国内忽视了一些东西,或者说不愿意去面对实际场景,“拍脑袋”和“我以为”就是标准。KPI 最终沦为了老板们的大屏数据,似乎数据代表一切... \n说句难听的,国人有能力的不少,但是创造的东西,真不咋样,很难有思维上的突破,到处都是“借鉴”。 \n国外做开源的很多可能就是个学生,普通程序员,没啥 title,吊打国内一大批程序员;级别,title 是越封越高,能力倒是没见涨。 \n国人不务实,很多都是面子工程,这莫非是大环境“造就”的? \n这两年看到比较多的消息就是 xxx 开源库作者因精力有限,放弃对其的维护工作。这都是白嫖,不返哺社区的结果。 \n某度搜索并不适合程序员,查找问题效率低下,结果百分之八九十都是垃圾。(工具很重要) \n一个技术社区如果东西“杂了”,技术就变得不再纯粹。(四不像) \nNode 再卷,感觉都要卷到 V8 ,C++ 了,而我只是个前端切图仔。 \n技术如果不纯粹就会变得畸形,写文章首要目标是思考沉淀,其次是分享传播帮助他人,最后才会考虑技术变现,但很多所谓的“作者”似乎本末倒置了。 \n看似是要求越来越低,实则社会在教我做人。(认清现实) \n轮子哥,造轮子的速度比我用轮子的速度还快。(与大佬的差距) \n垃圾公众号看多了,人都变傻了。天天卖课,真烦... \n公众号其实就是收割流量的,既然那么多干货,为啥不写成 blog,因为写成 blog 就没多少干货了,公众号基本百分之七八十都是在转载,写成 blog 哪有那么多文章。如果你关注了 100 个前端公众号,一篇文章你起码可以在几十个公众号看到,有啥意义?还有一大堆是卖课的。一百个能有十个,可能都是比较乐观的估计,十不存一... \n我觉得很多人就喜欢混为一谈,学习的本质是为了什么?是为了吃透一门技术,掌握一门技能,还是说只是为了更好的赚钱。(多问问自己想要什么) \n最近做项目的一些体会。代码如何不腐,单从代码层面很难解决。
你可以去预留接口,提高可扩展性,但是抵不住需求从一个东西变成另一个东西,还非要表现出是一个东西的那种状态。
真要系统健壮,以及可扩展,需要的是多方配合,而不是自己搞自己的,需求自己随便提,后端按自己的想法自己定数据结构,前端天天跟着设计跑,换颜色,换交互。各种场景不做收拢,梳理。说句难听的,即使新开项目,一年项目就是一坨屎,到后面就是牵一发动全身,开发委屈说,时间不够,需要 review 的东西太多。业务觉得你不够努力,这么简单的需求你要搞那么久?这就是现状。。。 \n \n非原创 \n\n科技造神的祭坛下,是无数沉迷于低级娱乐与表面思考的终端消费者。但他们不得不为此付费,甚至久而久之,他们会下意识地维护这套病态逻辑。 \n编程的历史就是“更少代码”的历史:寻找更好的抽象,并构建库来实现这些抽象。 \nNo problem can be solved from the same level of consciousness that created it. (重大问题的解决方案永远不可能在产生这个问题的维度出现。) -- Albert Einstein
\n ","category":{"name":"Notes"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwzMDg2MDYxNzMz","name":"blog"}},{"node":{"id":"MDU6TGFiZWwzMTk2OTc2MDIx","name":"wechat-post"}}]},"reactions":{"totalCount":3,"edges":[{"node":{"id":"REA_lAXOEUMBcs4ANsiCzgAD4ng","content":"THUMBS_UP"}},{"node":{"id":"REA_lAXOEUMBcs4ANsiCzgAD_Fk","content":"THUMBS_UP"}},{"node":{"id":"REA_lAXOEUMBcs4ANsiCzgAEF3Y","content":"THUMBS_UP"}}]},"comments":{"edges":[{"node":{"id":"DC_kwDOEUMBcs4AGUdP","bodyHTML":"图文 \n
\n \n
","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"replies":{"edges":[]}}}]}}
\ No newline at end of file
diff --git a/issues/75.json b/issues/75.json
new file mode 100644
index 0000000..21aea8f
--- /dev/null
+++ b/issues/75.json
@@ -0,0 +1 @@
+{"id":"D_kwDOEUMBcs4AOXWF","title":"微信杂谈 - 组件开发的一些思考","bodyHTML":"📅 2021.12.22
\nlencx: \n人们更倾向于根据场景来探索解决方案,成也场景,败也场景。收窄要解决问题的范围,可以降低复杂度,但也降低了普适性。我以前也一直觉得,要实现的东西应该尽可能的剥离业务,但是随着做的业务越来越多,发现业务其实才是核心。当把业务抽象之后,所谓的跨平台其实就是适配的问题。
\n我发现可能之前自己想错了,应该抽象的是业务而不是组件,组件只是业务的载体。
\n适配层(组件)要做的就是低耦合,用抽象的业务逻辑去驱动适配层。
\n其核心就是业务,怎么实现,是个技术问题。技术可以被替换,推翻。以不变(主业务逻辑)应万变(视觉及交互)。
\n \n\n产生的讨论
\n \n正人 (欧雷): \n场景化方案基于通用化方案,不冲突
\nlencx: \n其实我是发现可能之前自己想错了,要抽象的可能是业务而不是组件
\n🇨🇳 Promise (🇨🇳 Promise): \n感觉其实是不同维度
\n正人 (欧雷): \n所以通用方案的扩展机制很重要
\n正人 (欧雷): \n都要抽象
\n正人 (欧雷): \n所以为啥要 MV*,为啥要 DDD[吃瓜]
\n🇨🇳 Promise (🇨🇳 Promise): \n通用化方案抽离的开发工具本身, 例如打包工具, 组件化是ui 的抽离,例如react、vue,ant
\n🇨🇳 Promise (🇨🇳 Promise): \n想到一个以前的小品,把大象放进冰箱需要几步,答案是三步。 接下来会对这三步行为不端细化和抽离。为了适配不同的场景(放进其他的东西),就对三步的行为不端抽象,部分不同的做单独适配
\nlencx: \n适配层(组件)我认为要做的就是低耦合,用抽象的业务逻辑去驱动适配层
\n🇨🇳 Promise (🇨🇳 Promise): \n来驱动适配层怎么来理解
\nShine.: \n除非业务组件 其他的组件都应该是低耦合吧 就只敢一件事
\nShine.: \n不应该有任何业务逻辑什么的吧?
\n空: \n不是有业务组件跟通用组件之分么
\nlencx: \n个人理解:组件开发一般两种模式,无状态组件和业务组件,业务组件会耦合业务逻辑
\nlencx: \n但是如果按照我说的,其实就不存在业务组件了,所有的组件基本和业务都不存在太大的耦合,也就是不会在组件里处理业务相关的东西
\nlencx: \n组件都退化到通用,然后只负责数据的填充。交互其实就是一个个动作,给业务数据所带来的反应。
\nShine.: \n就是说组件不去处理业务 业务都在使用的时候去处理?
\nlencx: \n在抽象的业务核心逻辑里处理,你可以理解为业务核心就是一个个纯函数
\nlencx: \n组件只负责接收数据
\nJack: \n按我理解
\nJack: \n理想化状态下,组件就是个书包
\nJack: \n你给我啥书 我就装啥书
\nJack: \n具体你给我的是语文书 数学书 马列主义 还是什么其他的
\nJack: \n我不管
\nJack: \n我只管把书装进去 让你带着走
\nlencx: \n对,书就是业务核心,组件只负责装
\nJack: \n这也不是我该管的
\nJack: \n理想情况下就是这样
\nJack: \n我该管的只是,你如果不装书,装炸药,那我就报错
\n🇨🇳 Promise (🇨🇳 Promise): \n这就是抽象与具象的互斥点了
\n🇨🇳 Promise (🇨🇳 Promise): \n在业务状态下,有时候需要保证书的放入和放出顺序
\nJack: \n是的 所以理想和现实还是有些差距
\n🇨🇳 Promise (🇨🇳 Promise): \n书的放置位置和摆放形势
\nlencx: \n所以可能需要有类似流程控制的东西吧
\nlencx: \n我其实也没完全想明白
\nJack: \n这个见仁见智了 有的倾向于在外边整理完了再塞进去
\nJack: \n有的倾向于塞进去,背在身上,让书自己动
\n皓夜森林: \nui组件的逻辑层都应该是个纯函数,ui层就是只负责渲染。业务组件感觉更偏向于,处理某个特定业务,比如唤起第三方的支付,sdk的支付组件。这种
\nShine.: \n什么叫纯函数 你给我啥我返回啥 对数据不做处理?
\n皓夜森林: \n很简单,你想想你这个组件能不能在别的项目直接用
\nShine.: \n我看网上解释有点太名词了
\n🇨🇳 Promise (🇨🇳 Promise): \n现在大多数抽象层的处理,都是在外面处理外,整体放进去,但是也有要求这个单独执行动作的。
\n皓夜森林: \n不管啥项目。都能直接用(运行环境允许的情况下)
\nJack: \n没有副作用的函数
\nJack: \n比如 sum(1,2,3)
\nlencx: \n纯函数就是个黑盒,接收参数,内部一系列处理后,返回的就是格式化后的标准数据格式
\nJack: \n我如果输入123 那输出值永远是6
\n🇨🇳 Promise (🇨🇳 Promise): \n我个人推崇的还是那种微内核的形式, 提供插件机制和默认机制。 同时保留执行 过程外部可以修改的api
\n皓夜森林: \n你就理解为一个函数如果在输入一样的情况下输出永远不变那就是纯函数
\n皓夜森林: \nconst add = (a ,b) => a + b 这就是一个纯函数
\n皓夜森林: \nlet effectParam = 1 \nconst add = (a, b) => a + b + effectParam
\n皓夜森林: \n因为结果会受effectParam影响
\n皓夜森林: \n这就不是一个纯函数
\n皓夜森林: \n这个参数变了结果就变了 即使输入可能都是一样的输入
\nJack: \neffectParam也可能是某个api的返回值
\nShine.: \n哦 明白了
\n🇨🇳 Promise (🇨🇳 Promise): \n像纯函数的编写,也是可以传入单纯的形参,或者传入一个改变执行函数作为结构的再次处理
\nShine.: \n我一直理解的是 不修改传递的参数那
\n皓夜森林: \n我寄几玩我寄几的
\n皓夜森林: \n你别搞我
\n皓夜森林: \n这就是纯函数
\nlencx: \n业务其实就是一大堆这样的纯函数,做什么功能,调什么函数,职责单一
\nJack: \n其实本质就是在做取舍
\nShine.: \n那我好像很多时候违背了这个
\n🇨🇳 Promise (🇨🇳 Promise): \n能保证单一指责其实在团队中就有点难的
\n皓夜森林: \nhook很多都是业务组件的逻辑层
\nShine.: \n看似代码少了
\nShine.: \n其实维护起来有点麻烦
\nJack: \n的确
\n皓夜森林: \n那你的项目做大了就很难维护
\nShine.: \n一改都得变
\n皓夜森林: \n这个是肯定的
\nJack: \n所以要考虑颗粒度
\nJack: \n这就又扯到很多其他方面了
\nJack: \n团队规模 业务复杂度 等等
\n皓夜森林: \n我的话这种都是踩坑踩出来的
\n🇨🇳 Promise (🇨🇳 Promise): \n这个本身就是一个很大的命题,把这个充满生机的世界在计算机中进行再造,本身就是厉害
\n皓夜森林: \n最近改公司的支付...越发体会深刻
\nlencx: \n支付的各种逻辑一旦耦合进 ui 里, ui 大改版就痛苦了
\n🇨🇳 Promise (🇨🇳 Promise): \n其实理解好面向对象也是比较容易,抽象对象, 实例在进行业务适配。 提供插件机制提供实例运行
","category":{"name":"Notes"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwzMTgxNDE5MDUz","name":"微信杂谈"}}]},"reactions":{"totalCount":0,"edges":[]},"comments":{"edges":[]}}
\ No newline at end of file
diff --git a/issues/77.json b/issues/77.json
new file mode 100644
index 0000000..037db0f
--- /dev/null
+++ b/issues/77.json
@@ -0,0 +1 @@
+{"id":"D_kwDOEUMBcs4AOYz8","title":"2021 年终总结","bodyHTML":"\n{折腾 ⇌ 迷茫 ⇌ 思考]ing,在路上...
\n \n\nflag 立的太多,一个也没完成 \n打游戏,刷动漫,电视剧,综艺,视频 \n读了一些源码,写了一些玩具项目 \n吐槽太多,已整理成语录 \n努力早睡,不熬夜 \n认识了很多新朋友 \n \n分享 & 沉淀 \n建了两个微信技术群和一个免费知识星球
\n\n语录 \n\nlencx 语录 - 此语录,无任何意义,仅记录生活中的所思所感...
\n \n🧐 学习
\n\n要学会把问题交给搜索引擎,而不是把群友当成搜索引擎。 \n同样一个问题,用百度和 Bing (有能力的用 Google ) 对比一下就知道了。 \n学习技术,先扫一遍文档,从最基本的开始搭建学习,功能一点点的增加进来。边看边实践,敲键盘也会加深记忆。 \n优秀一天容易,难的是一直优秀。 \n一篇好文章,更像是一根线,而不是一团麻。极客精神,以风趣幽默的方式解释清楚一切细节。 \n学到一句话:经验这个东西,就是越多越好,可以不去做,但是不能不知道。 \n有问题不可怕,可怕的是,不知道怎么和问题去相处。 \n答案是最无用的东西,因为它是一个问题的处理结果,是由过程分析推理得出来的,过程推理不出,而选择去背答案是最无效的学习方式,毫无意义! \n学习就是从懵逼到膨胀的一个死循环 🔄 \n以后再也不敢说自己是在自学了。没有基础作为指导,只能算是瞎学,乱学。看完《自学计算机科学》 这份书单,才发现自己对计算机一无所知。 \n真正的高效工作,是首先先学会如何解放自己。 \n骨头是不好啃,自己要先啃几口,才有发言权。别还没啃,就说太硬了。(软饭吃多了,牙也变软了) \n遇到问题自己不思考,不尝试,就没有资格把这个问题抛出来。(踢皮球并不能让自己成长) \n学会自我总结, 一步一个脚印,别总想着有人可以帮你。(外力终究不是自己的) \n知识就是这样的,会一点点进入你的视野。但是前提,你要保持好奇心,并且不断地尝试。 \n人的思想蜕变,不是一瞬间产生的,而是不断起伏的人生带给你的。 \n \n😐 日常
\n\n感谢所有夸我的人,说句实话,我不 NB,在技术群里,大部分人的能力都要比我强,我只是比较张扬而已。 \n任何话题都是技术交流,代码不是全部。 \n不信鬼神,但对未知还是要保持敬畏之心。 \n群里虽然前端居多,似乎更应该发和前端相关的内容。但一切皆知识,路应该越走越宽。专精于 xxx 或许没错,但只有 xxx,视野过于被局限,会少了很多灵感碰撞及其他可能性。(广度与深度该如何抉择) \n彩票属于不确定的意外之财,讨论这个没啥意义。运气不是每个人都有的,现实点。(学会自我催眠) \n我写的文章没啥技术含量,手撕不动,脑子也不怎么灵活,基础更是一塌糊涂。 \n我想明白了一些事情:欲望就好比握在手中的沙子,不握紧,会流失。握紧了,只会流的更快。因为想要获得,各种复杂的情绪就产生了,兴奋,焦虑… 如果放弃了所有的欲,一切便会回归于无。 \n当一些东西变得重复与机械的时候,也就失去了原本的兴趣。 \n自省只是不想让自己太飘,因为人是社会性动物,他人的评价或多或少都会对自己产生影响。 \n知识,技术可以变现,但是丢掉原则,就不再是一个技术人了。 \n本以为自己只是走了两三年的弯路,谁知从未走出... \n开源其实是一件很简单的事情,你想做,就可以去做。 \n人更喜欢相信自己看到的。很少有人去思考,你所看到的是不是别人故意给你看的?(眼见不一定为实) \n以前我也认为只要学会独立思考就够了,但是后来我发现,如果你所看到的一切都是假象,那么基于它做出思考将是一件可怕的事情。(价值观坍塌) \n眼界,思考,质疑,都很重要。 \n当对一切失去了怀疑的态度,会让你觉得它就是权威,不会出错。这是很可怕的事情。(盲目崇拜) \n做你认为对的事情,就不存在浪费时间一说。 \n有人说:“大多数的成功来源于勇气,似乎越成熟,越丧失了追求的勇气”。但是我认为不是越活越没勇气,而是人学会了算计,会去计较得失,才变得畏手畏脚。(冲动是魔鬼,太过于理智,生活也就少了一些色彩) \n一定要学会享受过程。结果很重要,但是如果真的有一天你可以直接到达这个结果的时候,未必是快乐的。(出生的结局就是死亡) \n没有学会取舍,才会让自己那么累。(放下也是一种智慧) \n我不想努力了,可是没钱。钱不是那么重要,但是没有它,可能会过的很惨。(衣食住行) \n这个世界是动态的,一切都在变化,人也如此。(保持初心) \n穷爸爸富爸爸 告诉我们,起点大于努力。(生的好也很重要) \n \n🤬 吐槽
\n\n做任何事都是需要指标的,没有高标准,就不会把事情做到极致。但是国内忽视了一些东西,或者说不愿意去面对实际场景,“拍脑袋”和“我以为”就是标准。KPI 最终沦为了老板们的大屏数据,似乎数据代表一切... \n说句难听的,国人有能力的不少,但是创造的东西,真不咋样,很难有思维上的突破,到处都是“借鉴”。 \n国外做开源的很多可能就是个学生,普通程序员,没啥 title,吊打国内一大批程序员;级别,title 是越封越高,能力倒是没见涨。 \n国人不务实,很多都是面子工程,这莫非是大环境“造就”的? \n这两年看到比较多的消息就是 xxx 开源库作者因精力有限,放弃对其的维护工作。这都是白嫖,不反哺社区的结果。 \n某度搜索并不适合程序员,查找问题效率低下,结果百分之八九十都是垃圾。(工具很重要) \n一个技术社区如果东西“杂了”,技术就变得不再纯粹。(四不像) \nNode 再卷,感觉都要卷到 V8 ,C++ 了,而我只是个前端切图仔。 \n技术如果不纯粹就会变得畸形,写文章首要目标是思考沉淀,其次是分享传播帮助他人,最后才会考虑技术变现,但很多所谓的“作者”似乎本末倒置了。 \n看似是要求越来越低,实则社会在教我做人。(认清现实) \n轮子哥,造轮子的速度比我用轮子的速度还快。(与大佬的差距) \n垃圾公众号看多了,人都变傻了。天天卖课,真烦... \n公众号其实就是收割流量的,既然那么多干货,为啥不写成 blog,因为写成 blog 就没多少干货了,公众号基本百分之七八十都是在转载,写成 blog 哪有那么多文章。如果你关注了 100 个前端公众号,一篇文章你起码可以在几十个公众号看到,有啥意义?还有一大堆是卖课的。一百个能有十个,可能都是比较乐观的估计,十不存一... \n我觉得很多人就喜欢混为一谈,学习的本质是为了什么?是为了吃透一门技术,掌握一门技能,还是说只是为了更好的赚钱。(多问问自己想要什么) \n \n🤫 非原创
\n\n科技造神的祭坛下,是无数沉迷于低级娱乐与表面思考的终端消费者。但他们不得不为此付费,甚至久而久之,他们会下意识地维护这套病态逻辑。 \n编程的历史就是“更少代码”的历史:寻找更好的抽象,并构建库来实现这些抽象。 \n \n开源 \n2021 开源项目归档
\n
\n总结 \n2021 年一晃而过,很多事情都没来得及去做,只能匆匆忙忙总结一番。以这篇文章(参照物),来记录自己的成长(age++)。
","category":{"name":"Review"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwzMTk2OTc2MDIx","name":"wechat-post"}}]},"reactions":{"totalCount":2,"edges":[{"node":{"id":"REA_lAXOEUMBcs4AOYz8zgAEsZU","content":"THUMBS_UP"}},{"node":{"id":"REA_lAXOEUMBcs4AOYz8zgAE5tg","content":"THUMBS_UP"}}]},"comments":{"edges":[]}}
\ No newline at end of file
diff --git a/issues/78.json b/issues/78.json
new file mode 100644
index 0000000..0f297e3
--- /dev/null
+++ b/issues/78.json
@@ -0,0 +1 @@
+{"id":"D_kwDOEUMBcs4AOauk","title":"浏览器发展史","bodyHTML":"\n计算机世界是对现实世界的映射。当事物变得无法理解时,去源头找找,或许就明白了。
\n \nChrome 100 \n在 2022 上半年,Chrome 将达到三位数的主版本号:100
!浏览器在很久以前第一次达到版本 10
时,因为主要版本号从一位数变为两位数,用户代理解析库发现了许多问题(Changes in Opera’s user agent string format )。现在在 Chrome 和 Firefox 中都接近版本 100
,Edge 也不甘落后。当 Chrome 达到 100
版,将会导致一些网站不工作。谷歌已经开始调查和测试解决方案。
\n根据 Chromium Bug Tracker ,已知受到影响的网站主要是使用网页设计工具 Duda 开发的网站。这些网站都使用相同的代码来检查用户使用的 Chrome 版本。
\n案例 \n以 Chrome 为例,用户代理字符串为 Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36
\n字符串最后,可以看到我们要寻找的是 Chrome/96.0.4664.110
,它为我们提供了浏览器的准确版本号。但是,大多数 Web 开发人员可能只关心主要版本号,即 96
。
\n由于用户代理字符串是文本,开发人员需要自行提取信息以满足业务需求。对于 Duda,开发人员选择只读取 Chrome/
之后的前两位数字。这意味着 Chrome/99
将是 99
, Chrome/100
将被视为版本 10
。
\n而 Duda(2015 年发布的版本)会自动阻止低于 Chrome 40
的版本,Chrome 99
之后的每个版本(100 - 109)的浏览器都将被视为版本 10
,因此被阻止。
\n目前 Duda 已经修复了此问题(Chrome 100 Bug Was Fixed Months Before The New Version's Actual Release )
\n检测与反馈 \n通过访问 Is Chrome 100 yet? 可以检查浏览器是否在 User-Agent
字符串中发送主要版本 100。
\n为了尽早检测三位数版本号可能导致的问题,在它成为现实前做好准备。我们可以在 Chrome 设置中开启 User-Agent
为 100
的主版本(Force Chrome major version to 100 in the User-Agent string )来对网站进行测试。
\n\n访问 Is Chrome 100 yet?
,页面返回 Yes!
或 No.
; \n打开 Chrome 浏览器并在地址栏中输入 chrome://flags
; \n将打开一个包含可用实验的页面, 找到 User-Agent
中启用强制主要版本为 100
的选项(Force major version to 100 in User-Agent
)。然后重新访问步骤 1。 \n \n
\n成功开启后,然后测试自己的网站。如果发现问题,可以将错误报告发送至 Web Compat 以帮助 Web 浏览器准备三位数的主版本号!
\n里程碑 \nWeb 浏览器简史 - 世界历史从不缺少史诗般的权力斗争,有征服世界的暴君,也有落败的勇士。Web 浏览器的历史也大抵如此。学术先驱们编写出引发信息革命的简易软件,并为浏览器的优势和互联网用户而战。
\n在《万维网 25 岁生日快乐》 中可以了解更多网络诞生的相关信息。
\nMosaic \nMosaic User Agents - NCSA_Mosaic/2.0 (Windows 3.1)
\nNCSA Mosaic ,是一个早期普及的网页浏览器,也是互联网协议如 FTP、NNTP 和 Gopher 的客户端,浏览器因支持多种互联网协议而命名。其直观的接口、可靠性和简易安装,因此在当时大受欢迎,也是第一个可以在文字中嵌入图片,而不是在单独的窗口中显示图片的浏览器。
\nMosaic 是引发 1990 年代互联网泡沫的网页浏览器。1992 年 11 月,世界上只有仅仅 26 个网站,每一个网站都受人注目。1993 年,Mosaic 推出了一个叫做 What’s New
(What's New With NCSA Mosaic ) 的页面,几乎每天都会提供给大家一个全新网站的链接。这段期间,互联网的使用率正在由学术界和大型工业研究机构之外迅速普及。然而,这正是 Mosaic 浏览器的易用性推动了网络爆发性的成长,到了 1995 年 8 月,网站数量已经超过了一万个,1998年达到了数百万个网站数量。
\n
\nMozilla \nFirefox User Agents - Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:95.0) Gecko/20100101 Firefox/95.0
\nMozilla 是一个自由软件社群,由网景通信公司的成员于 1998 年创立。在非正式的场合下,“Mozilla” 这个名字常用于不同的事物上。这些事物大都与现已歇业的网景通信公司及其旗下的应用软件相关。
\n最初,“Mozilla” 被用作 网景导航者(Netscape Navigator) 的开发代号。网景通信公司希望“网景导航者”能够取代当时世界第一的 Mosaic,而这个名字由 “Mosaic Killa”(Killa 是俚语中 Killer 的拼法)变化而来,并与经典的虚拟怪物哥斯拉谐趣:“Godzilla eat the Mosaic”,即 Mosaic + Godzilla + Killa = Mozilla
,Netscape 工程师杰米·加文斯基说他是在一次 Netscape 员工会议上想到这个名字的。
\nMozilla Firefox ,通称 Firefox,中文也通称“火狐”,是一个自由及开源的网页浏览器,由 Mozilla 基金会及其子公司 Mozilla 公司开发。Firefox 于 2002 年由 Mozilla 社群成员创建,当时叫做“Phoenix”。Firefox 于 2004 年 11 月首次发布,并且 9 个月内下载量超过 6,000 万,获取了巨大的成功,Internet Explorer的主导地位首次受到了挑。其被认为是 Netscape Navigator
的精神续作。
\n
\n\nInternet Explorer \nInternet Explorer User Agents - Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)
\nInternet Explorer (旧称 Microsoft Internet Explorer 和 Windows Internet Explorer,简称 IE 或 MSIE),是微软所开发的图形用户界面网页浏览器。自从 1995 年开始,内置在各个新版本的 Windows 操作系统,也是微软 Windows 操作系统的一个组成部分。
\nInternet Explorer 曾是使用最广泛的网页浏览器,在 2002 年和 2003 年达到 95% 的使用率高峰。微软以捆绑方式赢得与 Netscape 的第一次浏览器大战,Netscape 是 1990 年代的主流浏览器。
\nInternet Explorer 计划由托马斯·里尔登开始于 1994 年夏天,当时 Netscape Navigator 占据浏览器市场份额 70% 以上。竞争对手苹果公司的 Mac OS 更使用 Netscape 作为默认的浏览器,但当时的 Windows 没有一个默认的浏览器。微软需要有一个自己的浏览器,但它没有时间从零开始创造一个浏览器。因此和 Spyglass 合作,Internet Explorer 从早期一款商业性的专利网络浏览器 Spyglass Mosaic 派生出来。
\n
\nOpera \nOpera User Agent - Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36 OPR/82.0.4227.43
\nOpera 是由 Opera 软件为个人电脑推出的网页浏览器,用于 Microsoft Windows、macOS 和 Linux 操作系统。
\n1996 年首次公开发布 Opera 2.0 版本,但仅在 Microsoft Windows 上运行。1998 年开始开发第一款用于移动设备平台浏览器。
\nOpera 在 2013 年以后采用 Blink 排版引擎 (layout engine) 。此前 Opera 版本曾采用 Presto 排版引擎,并在 FreeBSD 系统上运行。
\n
\nSafari \nSafari User Agent - Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.1 Safari/605.1.15
\nSafari 浏览器 是苹果公司所开发,并内置于 macOS(前称 OS X、Mac OS X)、iOS 与 iPadOS 的网页浏览器。Safari 浏览器在 2003 年 1 月 7 日首度发行测试版,并从 Mac OS X Panther 开始成为 Mac OS X 的默认浏览器,也是 iOS 和 iPadOS 内置的默认浏览器。Windows 版本的首个测试版在 2007 年 6 月 11 日推出,支持 Windows XP、Windows Vista 和 Windows 7,并在 2008 年 3 月 18 日推出正式版,但苹果已于 2012 年 7 月 25 日停止开发 Windows 版的 Safari 浏览器。
\n在 1997 年以前,Mac 预装的浏览器是 Netscape Navigator。之后苹果和微软达成协议,以在 Mac 上使用 Internet Explorer for Mac 作默认浏览器换取微软开发 Mac 版的 Microsoft Office。
\n2003 年 1 月 7 日,在旧金山举行的 Macworld 大会上,史提夫·乔布斯宣布苹果正在开发自己的浏览器,称为 Safari 浏览器。它基于苹果的 KHTML 排版引擎内部分支,称为 WebKit。直至 2003 年 6 月,苹果才推出自家的 Safari 浏览器,同时微软也终止开发苹果版的 IE 浏览器。Mac OS X v10.3 仍保留 IE,但至 10.4 版苹果就仅预装 Safari 浏览器。
\n
\nChrome \nChrome User Agent - Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36
\nGoogle Chrome 是由 Google 开发的免费网页浏览器,过去也用 Chrome 称呼浏览器的外框。Chrome 相应的开放源代码计划名为 Chromium ,而 Google Chrome 本身是非自由软件,未开放源代码。
\nChrome 代码是基于其他开放源代码软件所编写,包括 Apple WebKit (其分支 Blink 被用于基于 Chromium 的网页浏览器) 和 Mozilla Firefox,并开发出称为 V8 的高性能 JavaScript引擎 。Google Chrome 的整体发展目标是提升稳定性、速度和安全性,并创造出简单且有效率的用户界面。
\nChrome 50 结束了对 Windows XP 与 Windows Vista 系统的支持,这两个系统上的最后版本为 49.0.2623.112。
\n
\nUser-Agent 大乱斗 \n\n🙈 浏览器用户代理字符串(navigator.userAgent
)一团糟,几乎没用,每个浏览器都假装是其他浏览器,混乱不堪。
\n \n具体可以查看这篇文章 《History of the browser user-agent string》 ,以风趣幽默的方式介绍了浏览器之间的“尔虞我诈”,“勾心斗角”,堪比 宫斗 。
\n一般来说,如果一个网站需要知道你使用的是什么浏览器以及它的更新程度,它会检查所谓的“用户代理字符串”。这是浏览器附加到它建立的每个网络连接的一小段文本,让网站了解自己。如果分解用户代理字符串实际所说的内容,会发现很多杂乱无章的东西,其中大部分内容是为了保持与 1990 年代和 2000 年代初期的站点的兼容性。所以说有时候 使用用户代理字段进行浏览器检测 并不是一个好主意。
\n用户代理字符串有各种形状和大小,唯一用户代理的数量一直在增长。List of User Agents 中收集了数以百万计的用户代理,并根据检测到的许多内容(操作系统、浏览器、硬件类型、浏览器类型等)进行分类。
\n关键事件 \n\n摘自《History of the browser user-agent string》
\n \n\n\n一开始有 NCSA Mosaic,Mosaic 自称 NCSA_Mosaic/2.0 (Windows 3.1)
,Mosaic 在显示图片的同时也显示文字,大家都很欢欣鼓舞。
\n \n\n后来出现了一个新的浏览器,叫做 “Mozilla”,是 “Mosaic Killer” 的缩写,但 Mosaic 并不高兴,所以公开名称改为 Netscape。Netscape 自称 Mozilla/1.0(Win3.1)
,人们更加欢欣鼓舞。Netscape 支持 Frames(框架) ,Frames 在人们中间流行起来,但 Mosaic 不支持 Frames,于是就出现了 \"用户代理嗅探(user agent sniffing)\",网络管理员向 \"Mozilla \"发送 Frames,但向其他浏览器发送的不是 Frames。
\n \n\n网景取笑微软,把 Windows 说成是 \"调试不力的设备驱动程序\",微软很生气。于是,微软制造了他们自己的网络浏览器,他们称之为 IE(Internet Explorer),希望它能成为 \"网景杀手\"。Internet Explorer 虽然支持 Frames,但并不是 Mozilla,所以没有被赋予 Frames。微软变得不耐烦了,不希望等待网络管理员了解 IE 并开始向它发送 Frames,因此 IE 浏览器宣布它是 \"Mozilla compatible(Mozilla 兼容的)\",并开始冒充网景,称自己为 Mozilla/1.22 (compatible; MSIE 2.0; Windows 95)
,IE 浏览器收到了 Frames,整个微软都很高兴,但网络管理员感到困惑。
\n \n\n微软将 IE 与 Windows 一起出售,并使其比网景更好,第一次浏览器战争在这片土地上肆虐。看吧,网景被干掉了,微软方面一片欢腾。但网景重生为 Mozilla,Mozilla 建立了 Gecko ,并称自己为 Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.1) Gecko/20020826
,Gecko 是渲染引擎,Gecko 很好。而 Mozilla 变成了 Firefox,并称自己为 Mozilla/5.0 (Windows; U; Windows NT 5.1; sv-SE; rv:1.7.5) Gecko/20041108 Firefox/1.0
,Firefox 非常好。而 Gecko 开始成倍增长,其他浏览器的诞生也使用了它的代码,它们自称为 Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en-US; rv:1.7.2) Gecko/20040825 Camino/0. 8.1
这一个,和 Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.8.1.8) Gecko/20071008 SeaMonkey/1.0
另一个,每一个都假装是 Mozilla,而且都是由 Gecko 驱动。
\n \n\nGecko 是好的,而 IE 不是,嗅觉重生,Gecko 被赋予了很好的 web 代码,其他浏览器则不然。而 Linux 的追随者则非常悲伤,因为他们建立了 Konqueror ,其引擎是 KHTML ,他们认为它和 Gecko 一样好,但它不是 Gecko,所以没有得到好的网页,于是 Konquerer 开始假装 \"like Gecko\",以获得好的网页,并称自己为 Mozilla/5.0 (compatible; Konqueror/3.2; FreeBSD)
(KHTML,like Gecko),出现了很多混乱。
\n \n\n苹果建立了 Safari,使用 KHTML,增加了许多功能。分叉(Fork)了该项目,称之为 WebKit,希望为 KHTML 编写页面,因此 Safari 自称为 Mozilla/5.0 (Macintosh; U; PPC Mac OS X; de-de) AppleWebKit/85.7 (KHTML, like Gecko) Safari/85.5
,情况越来越糟。
\n \n\n微软对火狐的恐惧很大,IE 浏览器又回来了,并自称 Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0)
,它能渲染好的代码,但只有在网站管理员命令它这样做的情况下。
\n \n\n谷歌建立了 Chrome,Chrome 使用 Webkit,它就像 Safari 一样,想要为 Safari 制作页面,所以假装是 Safari。于是 Chrome 使用 WebKit,并假装是 Safari,WebKit 假装是 KHTML,KHTML 假装是 Gecko,所有的浏览器都假装是 Mozilla,Chrome 自称 Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.13 (KHTML, like Gecko) Chrome/0.2.149.27 Safari/525.13
,用户代理字符串完全是一团糟,几乎没有用处,每个人都假装是其他人,混乱不堪。
\n \n \n结束语 \n软件生态从来不是孤立的,而是在借鉴,创新中,不断发展,才有了今天这个五彩斑斓的互联网世界。
","category":{"name":"Notes"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwzMDg2MDYxNzMz","name":"blog"}},{"node":{"id":"MDU6TGFiZWwzMTk2OTc2MDIx","name":"wechat-post"}}]},"reactions":{"totalCount":0,"edges":[]},"comments":{"edges":[]}}
\ No newline at end of file
diff --git a/issues/79.json b/issues/79.json
new file mode 100644
index 0000000..ce98ae0
--- /dev/null
+++ b/issues/79.json
@@ -0,0 +1 @@
+{"id":"D_kwDOEUMBcs4AOcmG","title":"微信杂谈 - 解决问题方法论","bodyHTML":"📅 2022.01.07
\nVeda@Angie: \nVue问题求教:在 watch 里面,我先用 splice 清空了数组,再 for 循环 push 进去,控制台打印数组是更新了、但是页面还是没有重新渲染
\nVeda@Angie: \n小哥,你遇到过吗
\nlencx: \nvue 我不熟
\nlencx: \n你用的是 vue2 吗
\nVeda@Angie: \n[可怜]对
\nlencx: \n看看代码
\nVeda@Angie: \nVue3 应该没这个问题了
\nVeda@Angie: \n代码在公司,只能下周一过去看了
\nlencx: \n[捂脸] 有时间跑个最小 demo
\nlencx: \n可能自己就发现问题了
\nVeda@Angie: \n最小 demo 是啥意思
\nlencx: \n就是复现问题的最小用例
\nVeda@Angie: \n奥奥是这个意思啊
\nVeda@Angie: \n那我回家了写一个跑一下试试
\nlencx: \nhttps://codesandbox.io/
\nlencx: \n可以用这个创建
\nVeda@Angie: \n好的,感谢
\nlencx: \n比较方便,写完直接分享链接,就是一个在线版的
\nVeda@Angie: \n好、我去试一试,之前还没用过这种工具
\nlencx: \n嗯嗯,不客气,这类工具都是比较常用的,还有 codepen 之类的
\nlencx: \n学技术,只盯着公众号,很有限。要自己拓宽知识面,而不是吃别人嚼过的。如何学习,如何获取信息,如何思考,如何解决问题,我觉得才是最重要的。
\nVeda@Angie: \n如何学习: \n最常用的是视频学习方式:拉勾、慕课网、B站,一般边看边敲,或看完几节再动手敲 \n获取信息: \n搜索引擎、各种技术网站、公众号
\nVeda@Angie: \n解决问题: \n一般是搜索引擎,谷歌或百度,如果实在解决不了就问别人
\nVeda@Angie: \n如何高效、深度思考我太欠缺了,很多问题只能看到表面,看不透深层
\nlencx: \n这些只属于入门级学习方式
\nVeda@Angie: \n学习方式也有问题,大部分时间属于被动接受。。
\nlencx: \n高效的学习方式,是知道自己想要什么
\nVeda@Angie: \n我是感觉自己效率不太高,但是却不知道怎么改善[流泪]
\nlencx: \n就是被这帮公众号惯坏了,丧失了捕猎的技巧,只会等着被投喂
\nVeda@Angie: \n工作之余,晚上回去不晚的话会学一点,周末学一些,可利用的学习时间也不多
\nlencx: \n你要学会主动获取自己想要的信息,这是第一步,然后就是根据自己的需求,拓宽知识面,然后就是读文档。
\nVeda@Angie: \n最难的还有一步,就是不知道自己想要什么。。。
\nVeda@Angie: \n就是有一股劲,不知道往哪个方向上使
\nVeda@Angie: \n今天遇到的问题,我可能需要去看一下 vue 的源码、以及再过一下它的文档
\nVeda@Angie: \n这是不是“主动获取自己想要的信息”的一种表现[可怜]
\nVeda@Angie: \n还是别的其他的理解,啥都可以直说的哈,我在工作中也是直性子有啥说啥的[破涕为笑]
\nlencx: \n这个不是看不看文档的问题,我现在问你,你能把自己遇到的问题,拆解成 1, 2, 3, ... 步骤吗
\nlencx:
\n\n我遇到了什么问题 \n为什么会出现这个问题 \n这个问题出现后,我应该怎么办 \n我如何分析这个问题 \n别人遇到同样的问题,如何定位,思考 \n文档我是否都了解清楚了 \n我尝试了哪些方法 \n问题解决了,我学会了什么 \n如果下次遇到同样的问题,我该怎么办 \n \n我暂时就想到这些,你觉得你做到了哪些
\nlencx: \n这是解决问题的基本流程
\nlencx: \n答案毫无用处,因为它并不能让你举一反三
\nlencx: \n这些东西,大部分,从公众号,视频上,是学不到的。需要自己动手折腾,思考
\nVeda@Angie: \n只做到了三四条。。。
\nlencx: \n形成自己解决问题的方法论,它是一个通用的解决问题的手段。
\nVeda@Angie: \n折腾了,但思考的太少了
\nlencx: \n很多时候,别人问我的问题,我也不会,但是有些问题,我可以解答,那是因为,我有自己的解题思路
\nVeda@Angie: \n我是动手的时间比思考的时间多,这样看是搞反了
\nlencx: \n是总结少了,而且少了解题的步骤,但是这个步骤恰恰是最关键的,它需要你去分析问题,拆解问题,将未知变成已知,用已经掌握的去推导陌生的
\nVeda@Angie: \n说的太对了
\nVeda@Angie: \n我经常会遇到那种重复性的问题,很久以前遇到过的,但就是想不起来当初是怎么解决的了,只有去翻看以前的代码或笔记才能想起来
\nlencx: \n动手没有错,错的是光动手其实没啥太大意义。因为动手是机械性的动作。代码是你逻辑思维的具象化。
\nVeda@Angie: \n如果没有代码或笔记参考,我就得重新把那个问题再来解决一遍
\nlencx: \n你需要做的事抽象为自身可以理解的事物,而不是去记代码,记以前解决问题的答案,毫无意义(一些固定流程,可以笔记,作为参考,快速查阅)。你需要记住的是你是如何拆解问题,如何解决问题的流程,然后去强化它。这样,任何时候,碰到这个问题,或者是新问题,你都可以套用你解决问题的流程模板
\nVeda@Angie: \n我之前都没往这方面想过,这似乎也适用于生活等其他方面的问题解决
\nVeda@Angie: \n感谢你的提点,提醒了我,我有必要重新审视自己的学习习惯、思考方式了
\nVeda@Angie: \n还有好长的路要走
\nlencx: \n是的
\nlencx: \n这个没有什么捷径,我自己也走了好几年的弯路
\nlencx: \n所以我把我很多的经验,拿出来分享了,但是似乎群友看的并不多。
\nlencx: \n每个人都有自己选择的自由,我也会重新审视自己
\nVeda@Angie: \n还是看人,就像现在很多时候流量至上,写的好呢东西有深度的东西看得人就少了,被看得多的倒是那些浅显的。。 \n你的分享给我了很多启发、指导,这些经验也会慢慢沉淀,到了一定时候好的东西自然会被发现也被大众接受的
\nVeda@Angie: \n你的分享我觉得很受用,所以坚持做对的事啦
\nlencx: \n我的分享,有一二人懂,足以。
\nVeda@Angie: \n一起坚持、
\nVeda@Angie: \n坚持比努力更重要、哈哈这是我喜欢的一句话
\nlencx: \n嗯嗯,时间复利
\nVeda@Angie: \n嗯嗯新的一年,一起加油
\nlencx: \n那我再告诉你一句话:正确的坚持比坚持更重要,不然就是南辕北辙
\nVeda@Angie: \n对,因为还有一句话,选择比努力更重要
\nlencx: \n嗯嗯
","category":{"name":"Notes"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwzMTgxNDE5MDUz","name":"微信杂谈"}}]},"reactions":{"totalCount":0,"edges":[]},"comments":{"edges":[]}}
\ No newline at end of file
diff --git a/issues/8.json b/issues/8.json
new file mode 100644
index 0000000..b94fd84
--- /dev/null
+++ b/issues/8.json
@@ -0,0 +1 @@
+{"id":"MDEwOkRpc2N1c3Npb24zMzg0Mjg3","title":"Web Development Guide","bodyHTML":"Guide \n\nLearn to Code — For Free — Coding Courses for Busy People - Learn to Code — For Free. \nMDN Web Docs - The MDN Web Docs site provides information about Open Web technologies including HTML, CSS, and APIs for both Web sites and progressive web apps. \nWeb | Google Developers - Build the next generation of web experiences. \nWeb Development for Beginners - A Curriculum - 24 Lessons, 12 Weeks, Get Started as a Web Developer \nThe Modern JavaScript Tutorial - Modern JavaScript Tutorial: simple, but detailed explanations with examples and tasks, including: closures, document and events, object oriented programming and more. \nCan I use... Support tables for HTML5, CSS3, etc - \"Can I use\" provides up-to-date browser support tables for support of front-end web technologies on desktop and mobile web browsers. \nW3Schools Online Web Tutorials - Well organized and easy to understand Web building tutorials with lots of examples of how to use HTML, CSS, JavaScript, SQL, Python, PHP, Bootstrap, Java, XML and more. \nDEV Community 👩💻👨💻 - A constructive and inclusive social network for software developers. With you every step of your journey. \nMedium - Every idea needs a Medium. \nSitepoint - Stay at the cutting edge of tech \nFireship.io - Training and Consulting for App Developers | Full Courses, Video Lessons, Chat, and More. \nMaster the JavaScript Ecosystem - ui.dev - Comprehensive learning resources for mastering the JavaScript ecosystem. \nReact Training - React Corporate Workshops, Training, and Consulting. \nawesome-lowcode - 国内低代码平台从业者交流 \nSpellbook of Modern Web Dev - A Big Picture, Thesaurus, and Taxonomy of Modern JavaScript Web Development \n30 seconds of code - Browse 1043 short code snippets for all your development needs on 30 seconds of code. \nJavaScript Series \nCSS Series \n \nFrame \n\nReact - A JavaScript library for building user interfaces\n\nPreact - ⚛️ Fast 3kB React alternative with the same modern API. Components & Virtual DOM. \n \n \nVue.js - The Progressive JavaScript Framework\n\npetite-vue - 5kb subset of Vue optimized for progressive enhancement \n \n \nAngular - The modern web developer's platform \nSvelte - Cybernetically enhanced web apps \nFre - 👻 Tiny Footprint Concurrent UI library for Fiber. \nSolid - Solid is a purely reactive library. It was designed from the ground up with a reactive core. It's influenced by reactive principles developed by previous libraries. \nLit - Simple. Fast. Web Components. \n \nAwesome \n\nCharts \n\nvisx - is a collection of reusable low-level visualization components. visx combines the power of d3 to generate your visualization with the benefits of react for updating the DOM. \nAntv - AntV is a new generation of data visualization technique from Ant Group. We provide best practices of data visualization with simplicity, convenience, profession, reliability, and infinite possibilities. \n \nSurveys \n\nRegExp \n\nRegexper - Regular expression visualizer using railroad diagrams \nRegulex - JavaScript Regular Expression Visualizer. \nRegExr: Learn, Build, & Test RegEx - RegExr is an online tool to learn, build, & test Regular Expressions (RegEx / RegExp). \nRegular-Expressions.info - Regex Tutorial, Examples and Reference - Regexp Patterns - At Regular-Expressions.info you will find a wide range of in-depth information about a powerful search pattern language called regular expressions. \nOnline Regex tester and visualizer - Python, PHP, Ruby, JavaScript, Java - Online regular expression tester for Python, PHP, Ruby, JS, Java and MySQL. Regex visualizer. Syntax highlighting. Cheatsheet. Generate string corresponding to a regex. \nDebuggex: Online visual regex tester. JavaScript, Python, and PCRE. - Test your regex by visualizing it with a live editor. JavaScript, Python, and PCRE. \nFree Online Regular Expression Tester - FreeFormatter.com - Free online regular expression tester with cheatsheet and most common solutions to common problems \n \nBlog \n\n2ality – JavaScript and more \nFront-end Web Development, Chewed Up ← Alligator.io - Learn Angular 2+, Vue.js, React, TypeScript, Ionic, JavaScript (ES6/ES2015+) & CSS with short, straightforward posts. \nOverreacted - Personal blog by Dan Abramov. I explain with words and code. \nRWieruch - Software Engineer for React.js, Node.js, GraphQL and JavaScript. Based in Berlin, German/English speaking. Consulting/Freelancing for Web Development project: Code Audits/Reviews, Workshops, Training, Implementation ... \nDave Ceddia - Articles to help you learn and master frontend development with React. \nCharlie Gerard | Senior frontend developer & Creative Technologist - Collection of side projects, conference talks and blog posts experimenting with frontend technologies and human-computer interaction. \nLea Verou – Life at the bleeding edge (of web standards) \nBlog - Chris Coyier \nFlavio Copes - JavaScript and Web Development Tutorials \n ","category":{"name":"FE"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwzMDg2MDYxNzMz","name":"blog"}},{"node":{"id":"MDU6TGFiZWwzMTk1NTQxODE3","name":"wechat-link"}}]},"reactions":{"totalCount":5,"edges":[{"node":{"id":"MDE4OkRpc2N1c3Npb25SZWFjdGlvbjE3MjUyNA==","content":"HEART"}},{"node":{"id":"MDE4OkRpc2N1c3Npb25SZWFjdGlvbjE4MjY4OA==","content":"HOORAY"}},{"node":{"id":"MDE4OkRpc2N1c3Npb25SZWFjdGlvbjIxNjQ4Ng==","content":"HEART"}},{"node":{"id":"REA_lAXOEUMBcs4AM6PfzgAEedM","content":"HOORAY"}},{"node":{"id":"REA_lAXOEUMBcs4AM6PfzgAEedQ","content":"HEART"}}]},"comments":{"edges":[]}}
\ No newline at end of file
diff --git a/issues/80.json b/issues/80.json
new file mode 100644
index 0000000..5f8f9ce
--- /dev/null
+++ b/issues/80.json
@@ -0,0 +1 @@
+{"id":"D_kwDOEUMBcs4AOwQs","title":"什么字体更适合程序员?","bodyHTML":"\n制作连字的 Operator Mono 字体 \n第一步:下载项目 \n首先要有 Operator Mono 字体(网上自行搜索),然后访问下面这个项目,下载到本地。
\n\n第二步:前置环境准备 \n\n如果遇到环境安装问题,可以在评论区交流
\n \n\nOperator Mono 字体文件 \nPython (v2.7+) \nNode.js \n从 fonttools/fonttools 安装 fonttools\n\nWindows/Linux: pip install fonttools
\n注意事项: 对于 Windows,如果您的 Python 位于 C:\\PythonX
下,您应该使用具有管理权限的控制台 \n注意事项: 对于 WSL/WSL2 中的 Linux,请确保安装后将 fonttools
添加到 PATH。或者,考虑通过 sudo apt install fonttools
安装。 \nMac: pip3 install fonttools
\n \n \n \n第三步:安装依赖及构建 \n\n\n压缩包解压,然后进入到文件夹下执行
\n# 使用 npm 安装可能会出现 node-gyp 之类的错误,可以尝试使用 yarn 安装 \nnpm install \n \n\n将 Operator Mono字体文件放到 original 目录下,然后执行脚本
\n# Windows \nbuild\n\n# Linux/Mac \n./build.sh \n \n\n生成的 Operator Mono Lig 字体在 build 文件夹下,点击安装即可
\n \n \n字体效果预览 \n我的 vscode 配置
\n
","category":{"name":"Notes"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwzMDg2MDYxNzMz","name":"blog"}},{"node":{"id":"MDU6TGFiZWwzMTk2OTc2MDIx","name":"wechat-post"}}]},"reactions":{"totalCount":0,"edges":[]},"comments":{"edges":[]}}
\ No newline at end of file
diff --git a/issues/81.json b/issues/81.json
new file mode 100644
index 0000000..c1b38f4
--- /dev/null
+++ b/issues/81.json
@@ -0,0 +1 @@
+{"id":"D_kwDOEUMBcs4AO0QE","title":"如何提升写作技巧?","bodyHTML":"\n针对图片内容并结合自身写作经历,做了部分改编
\n \n\n更多更广泛的阅读 \n每天坚持写作,熟能生巧 \n保持一致很重要,找到自己的写作风格 \n明确目标,知道自己为何而写作 \n了解你的受众,直击他们的痛点 \n使用副标题来帮助略读者快速找到重点 \n不滥用各种形容词凑字数,简单直接地写作 \n惜字如金,保持文章结构的紧凑 \n用真实经历并加入一些讲故事的技巧,使文章内容更饱满 \n善用关键字和 SEO,以使文章在搜索引擎中获得更高排名 \n修改之前先完成初稿,编辑未完成的作品是禁忌,它会减慢你写文章的速度并导致倦怠 \n创作完成后,不要急于发布。反复斟酌,会一些发现错误、奇怪的措辞或令人困惑的句子 \n从读者那里获得反馈,尽最大努力将更好的想法融入到未来的写作中 \n对批评持开放态度,虚心学习,让自己变得更优秀 \n \n
","category":{"name":"Notes"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwzMDg2MDYxNzMz","name":"blog"}},{"node":{"id":"MDU6TGFiZWwzMTk2OTc2MDIx","name":"wechat-post"}}]},"reactions":{"totalCount":1,"edges":[{"node":{"id":"REA_lAXOEUMBcs4AO0QEzgANByk","content":"THUMBS_UP"}}]},"comments":{"edges":[]}}
\ No newline at end of file
diff --git a/issues/82.json b/issues/82.json
new file mode 100644
index 0000000..937d25f
--- /dev/null
+++ b/issues/82.json
@@ -0,0 +1 @@
+{"id":"D_kwDOEUMBcs4AO3re","title":"微信杂谈 - 实习简历如何写","bodyHTML":"📅 2022.02.23
\n只想吃白菜: \n大佬你先看看我简历
\n只想吃白菜: \n看看够资格不
\n只想吃白菜: \n[苦涩]双非二本,艺术专业
\nlencx: \n学历虽然很重要,但是你自身的技术也占很大部分,不用妄自菲薄
\n只想吃白菜: \n我现在最大的顾虑是我之前做的项目比较水
\n只想吃白菜: \n就是东西我做出来了
\n只想吃白菜: \n细问的话,我感觉没什么技术点可以深入聊
\n只想吃白菜: \n我差不多都能做,但要是和我聊技术点,让我从项目聊好久,聊不了,我不知道说啥
\nlencx: \n项目是聊你的经历的,没做过复杂项目,单纯靠包装很难,也容易露馅
\n只想吃白菜: \n这个情况怎么做会比较好呀
\n只想吃白菜: \n我项目这一块的问题
\n只想吃白菜: \n我有时间可以自己耗精力去弄
\n只想吃白菜: \n但是不知道如何去弄
\nlencx: \n项目因为你本身就是实习,没接触过大项目很正常,你可以了解一些项目相关的开发流程,还有就是让自己的基础扎实一些
\n只想吃白菜: \n基础指的就是:数据结构、计网这种嘛
\n只想吃白菜: \n挑几个点深入了解
\n只想吃白菜: \n然后去谈?
\nlencx: \n我也没实习经验,给不出太好的建议,我都是走社招的
\n只想吃白菜: \n比较发愁
\nlencx: \n你是19-20年实习,现在都 22 年了,你是啥时候毕业的
\n只想吃白菜: \n22毕业
\n只想吃白菜: \n19那次是在一个小微企业
\n只想吃白菜: \n兼职一样,一周上两天
\n只想吃白菜: \n那个时候我大二,原生做了两个网站,一个在我这,一个公司拿去用了
\nlencx: \n哦哦,那你还是走校招吧,走社招更难,看你的简历,是不太具有优势
\n只想吃白菜: \n如果要具有一定优势的话,应该怎么做?
\n只想吃白菜: \n大佬明示一下
\n只想吃白菜: \n我做充分准备
\n只想吃白菜: \n我不想放弃做开发[苦涩]
\nlencx: \n项目和基础都很重要,没有项目经验,你可以让自己基础扎实点
\nlencx: \njs,算法,数据结构,还有就是计算机基础之类的
\nlencx: \n项目经验很难包装,没做过的不建议瞎写,很容易被问死
\n只想吃白菜: \n我可以实际去写,但是不知道该去做什么
\nlencx: \n实际的项目,并没有看到你的亮点
\nlencx: \n有点平了
\nlencx: \n还有就是你放了 github ,但是最近一年都没怎么更新
\n只想吃白菜: \n我知道,我其实可以现在再去开发,然后把那些是亮点的东西做一遍
\n只想吃白菜: \ngithub这个确实[苦涩]在搞毕业的事,没去提交代码
\nlencx: \n亮点不是靠做出来的,而是你在实际开发中解决棘手问题的解决方案
\n只想吃白菜: \n那这么说来
\n只想吃白菜: \n项目的事,没得解决了
\n只想吃白菜: \n就只能从基础和深度上解决我的问题
\nlencx: \n以你目前的经历来说,很难包装
\nlencx: \n差不多是这个意思
\n只想吃白菜: \n懂啦
\n只想吃白菜: \n谢谢您
","category":{"name":"Notes"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwzMTgxNDE5MDUz","name":"微信杂谈"}}]},"reactions":{"totalCount":0,"edges":[]},"comments":{"edges":[]}}
\ No newline at end of file
diff --git a/issues/83.json b/issues/83.json
new file mode 100644
index 0000000..a922018
--- /dev/null
+++ b/issues/83.json
@@ -0,0 +1 @@
+{"id":"D_kwDOEUMBcs4AO3sS","title":"微信杂谈 - 代码优化","bodyHTML":"📅 2022.02.23
\nIce: \n这种代码怎么优化一下 \n
\nlencx: \n策略模式
\nIce: \n什么意思
\nlencx: \n额,或者 switch
\nlencx: \n其实 if 也还好吧
\nIce: \n要写好长if
\nlencx: \n其实这么写条件不好
\nIce: \n那我该怎么写
\nlencx: \n最好是把校验规则抽象出来
\nlencx: \n至于校验规则怎么抽象,需要看业务需求
\nIce: \n我就判断每一行的单元格不能为空保存的时候
\n张浩: \nswitch
\n张浩: \n据说性能会很高
\nlencx: \n其实我建议根据需求把规则做抽象,每个字段对应的校验文案其实是固定的,然后就是一个拼装问题
\nlencx: \n但是过度抽象反而不如 if 这种更直白,所以需要自己权衡一下未来需求的迭代,保证一定的可扩展性
\nlencx: \n其实就是做一个通用的校验器
\nlencx: \n只需要接收数据源就可以返回校验文案
\nlencx: \n以及是否通过的状态
\nlencx: \n举个例子,看你这个截图,其实每个字段都对应一个文案,比如最高分,最低分,然后通过逗号连接,不能为空! \n这就是规则:aaa, bbb, ccc 不能为空! \naaa, bbb, ccc 可以通过数组做收集
\nIce: \n是噢
\n张浩: \n哦,然后封装一个方法,循环这个规则数组,如果有一项false,直接返回具体原因
\n张浩: \n否则返回true?
\nlencx: \n数组做收集,你只需要对字段做遍历就好了,不满足的就收集。
\n张浩: \n哦哦
\nlencx: \n这个看个人,实现方法有很多,我只是举例而已。
\n张浩: \n好的学习了
\n柒冉: \n学到了
\nlencx: \n这样你可以针对分数写一个校验器,只接收数据源,然后返回处理结果,后期需求变更,只需要重新实现校验器即可。数据做好格式化输出。你的校验器对调用者来说就是一个黑盒。
\n张浩: \n大佬,那如果是一个表单,里面有很多条件,那种校验应该如何封装比较好
\n张浩: \n也要对每个字段分别封装吗
\nlencx: \n一样的思路,核心思想就是做到:UI,Data, 业务逻辑之间的解耦。按照这个思路去拆。函数式编程思想。
\n张浩: \n嗯嗯,我想下
\nlencx: \n你抽象的东西就是一个黑盒,保证输入,输出源的一致性,内部怎么实现我并不关系。
\n张浩: \n嗯嗯
\nlencx: \n这个没有什么通用式,一站式解决方案,多写,多思考,自己慢慢就找到感觉了,当你觉得某个地方的代码特别繁琐,改起来很复杂,牵一发而动全身,一般就是对代码结构的思考有所欠缺了。
\n张浩: \n嗯嗯
\n张浩: \n感觉自己还是抽象的不够彻底,每次都是写完代码之后,发现,这地方为啥不抽个方法出来。。。。
\nlencx: \n代码都是边写边优化的,过早优化,可能会导致扩展性不足。
\nlencx: \n反而越改越麻烦
\n张浩: \n嗯嗯
\nlencx: \n写代码的一般流程: \n先实现功能 -> 找代码共性 -> 思考优化 -> 重构 \n比较厉害的,可以根据自己的经验给未来的需求留出口子,方便扩展
\n张浩: \n我都是写完之后就拉倒了哈哈,以后注意下,review一下[捂脸]
\nlencx: \n虽然不可以一步抽象到位,但是可以边写边思考,边优化。这就是迭代。需求需要迭代,代码也需要迭代。
","category":{"name":"Notes"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwzMTgxNDE5MDUz","name":"微信杂谈"}}]},"reactions":{"totalCount":0,"edges":[]},"comments":{"edges":[{"node":{"id":"DC_kwDOEUMBcs4AIlN5","bodyHTML":"代码优化我觉得更像是对于功能聚分类。以合理的数据结构对当前业务代码进行归类和分解。当数据结构的描述足够合理,那么代码自然会变得更整洁
","author":{"login":"dengshicheng1996","avatarUrl":"https://avatars.githubusercontent.com/u/41374066?v=4","url":"https://github.com/dengshicheng1996"},"replies":{"edges":[]}}}]}}
\ No newline at end of file
diff --git a/issues/84.json b/issues/84.json
new file mode 100644
index 0000000..b9fcaf4
--- /dev/null
+++ b/issues/84.json
@@ -0,0 +1 @@
+{"id":"D_kwDOEUMBcs4AO7Gf","title":"微信杂谈 - 技术社交很重要","bodyHTML":"📅 2022.03.03
\n杰拉德 (Gerrard): \n技术真好玩 可惜我不是学coding的
\nlencx: \n有好的师傅领还是很重要的,我一路自学过来,走过好几年的弯路
\nlencx: \n本来问人可能就是一句话的事情,但是对我来说,可能要花几周,甚至更久,还记得入行那会,一个环境配置,我断断续续自己折腾了几个月才搞好。
\nlencx: \n所以我每天动态发朋友圈,也是有私心的,加的大佬多了,一定程度上,也是对自己的曝光。
\nlencx: \n虽然不一定有人看,但是看到了就可能是一次机会。
\n杰拉德 (Gerrard): \n社交是有用的
\nlencx: \n其实我也想开了,就混混社区也挺好,不一定非要去什么大厂。
\n杰拉德 (Gerrard): \n有人带肯定更好
\nlencx: \n技术就是用来实践的,既然没有平台可以发挥,那么参与开源也是一种学习和实践的途径。
\nlencx: \n关于有人带这个话题,在我看来或许也不是很重要了,因为这么多年,我也以为遇到问题会有人帮你,以前小公司是没条件,现在虽说这个公司不小,但是遇到问题,依旧需要自己去解决。问人也并非是什么上策。我也已经过了需要让人带(入行时很重要)的年纪了。
\n杰拉德 (Gerrard): \n也是 而且兴趣是源动力 有就有 没有就自学[拳头]
\nlencx: \n是的
","category":{"name":"Notes"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwzMTgxNDE5MDUz","name":"微信杂谈"}}]},"reactions":{"totalCount":0,"edges":[]},"comments":{"edges":[{"node":{"id":"DC_kwDOEUMBcs4AVXSz","bodyHTML":"我关注到大佬您很久了,但是今天才发现大佬的discussion,自己想从事Java后端开发,但是技术不精,然后去年准备考研来着,后面复试被刷,现在又得和技术打交道了,在twitter上面注意到了不少程序员,感觉他们好牛,自己开发插件又开发脚本的,大学来感觉自己Java学了个皮毛,很多都是知道用,如果深入一点点应用的话,自己就懵了。失去了秋招的机会,然后接近4月份才开始准备春招,现在就是求职方面的知识还有很多东西要学,没有人带就只能自己慢慢探索,太难了这【流泪】。平台上面看到Java实在是不太好找,当前趋势也确实这样,工作就是不太好找。就像大佬说的,技术社交很重要,对于应届生,技术社交范围感觉好有限,除了就职所在公司的,好像没有其他范围的了。我也好想认识认识一些技术大佬,感觉大佬太牛了的话我和他们又有沟通断层,不知道大佬刚入职的时候怎么摸索出来的。
","author":{"login":"Johntang666","avatarUrl":"https://avatars.githubusercontent.com/u/67173358?u=74ecdd96271ff982f84610fb19ebf04ae918aa03&v=4","url":"https://github.com/Johntang666"},"replies":{"edges":[]}}}]}}
\ No newline at end of file
diff --git a/issues/85.json b/issues/85.json
new file mode 100644
index 0000000..55c6052
--- /dev/null
+++ b/issues/85.json
@@ -0,0 +1 @@
+{"id":"D_kwDOEUMBcs4APDcI","title":"开发利器之命令行","bodyHTML":"\n高效使用命令行是程序员必备的技能
\n \n以下资源均被收录在 lencx/awesome(关于各种有趣主题的精彩列表) ,包含 weekly,rust, webAssembly,js,css,tools 等不同主题。
\nzsh \nOh My Zsh - Oh My zsh 是一个开源的、社区驱动的框架,用于管理您的 zsh 配置。
\n\n
\nbat \nbat - 类似 cat(1),但带有 git 集成和语法高亮。
\n
\nfd \nfd - 是一种简单快速和用户友好的 find
替代方案。
\n
\ngit \ngh \ngh - GitHub CLI 或 gh 是 GitHub 的命令行界面,可在您的终端或脚本中使用。
\n
\ngix \ngix - gix 是用于访问 git 存储库的命令行界面 ( CLI )。它是为了优化用户体验而编写的,其性能与规范实现一样好或更好。此外,它以各种小型 crate
的形式提供了一个简单且安全的 API ,用于轻松实现自己的工具。
\ndura \ndura - Dura 是一个后台进程,它监视您的 Git 存储库并提交您未提交的更改,而不会影响 HEAD、当前分支或 Git 索引(暂存文件)。如果您遇到异常导致工作内容丢失,进入 dura 分支可以恢复。如果没有 dura,可以在编辑器中使用 Ctrl-Z
来恢复状态。2021 年就是这样。计算机崩溃,Ctrl-Z
只能独立处理文件。Dura 快照随时更改整个存储库,因此可以恢复到“4 小时前”而不是“按 Ctrl-Z 40 次或其他”。
\ndelta \ndelta - 用于 git
、diff
和 grep
输出的语法高亮分页器。
\n
\ntig \ntig - Git 的文本模式界面。
\n
\ngit-journal \ngit-journal - Git 提交消息和变更日志生成框架。 \n
\nls \nexa \nexa - 是 ls
的现代替代品。
\n
\nlsd \nlsd - 下一代 ls
命令。
\n
\nnat \nnat - 具有有用信息和色彩的 ls
替代品。
\n
\njust \njust - 是保存和运行项目的特定命令的简便方法,其语法受 make
启发。
\n
\nAsciinema \nasciinema - 是一个免费的开源的轻量级、纯文本终端录制方法。以正确的方式记录和分享您的终端会话。
\n
\nfff \nfff - 用 bash 编写的简单文件管理器。
\n
\nWatchexec \nwatchexec 是一个简单的独立工具,它监视路径并在检测到修改时运行命令。
\n
\nRipgrep \nripgrep - 是一种面向行的搜索工具,它递归地在当前目录中搜索正则表达式模式。默认情况下,ripgrep 将遵守 gitignore 规则并自动跳过隐藏文件/目录和二进制文件。
\n
\nHexyl \nhexyl - 是一个简单的终端十六进制查看器。它使用彩色输出来区分不同类别的字节(NULL 字节、可打印的 ASCII 字符、ASCII 空白字符、其他 ASCII 字符和非 ASCII)。
\n
\nZellij \nzellij - 是一个面向开发人员、面向运维的人员和任何喜欢终端的人的工作区。它的核心是一个终端多路复用器(类似于 tmux 和 screen ),但这仅仅是它的基础设施层。
\n
\nImage \ncavif \ncavif - AVIF 图像的编码器/转换器,纯 Rust 实现。
\ncavif --quality 60 image.png \nsvgcleaner \nsvgcleaner - 清理 SVG 文件中不必要的数据。
\nsvgcleaner --indent=2 --paths-coordinates-precision=5 --join-arcto-flags=yes in.svg out.svg \nCSV \nxsv \nxsv 是一个用于索引、切片、分析、拆分和连接 CSV 文件的命令行程序。
\n$ xsv stats worldcitiespop.csv --everything | xsv table\nfield type min max min_length max_length mean stddev median mode cardinality\nCountry Unicode ad zw 2 2 cn 234\nCity Unicode bab el ahmar Þykkvibaer 1 91 san jose 2351892\nAccentCity Unicode Bâb el Ahmar ïn Bou Chella 1 91 San Antonio 2375760\nRegion Unicode 00 Z9 0 2 13 04 397\nPopulation Integer 7 31480498 0 8 47719.570634 302885.559204 10779 28754\nLatitude Float -54.933333 82.483333 1 12 27.188166 21.952614 32.497222 51.15 1038349\nLongitude Float -179.983333 180 1 14 37.08886 63.22301 35.28 23.8 1167162 \ncsview \ncsview - 带有 cjk /emoji 支持的 cli 的漂亮 csv 查看器。
\n
\nTokei \ntokei - 是一个显示代码统计信息的程序。 Tokei 将显示文件数、这些文件中的总行数以及按语言分组的代码、注释和空白。
\n===============================================================================\n Language Files Lines Code Comments Blanks\n===============================================================================\n BASH 4 49 30 10 9\n JSON 1 1332 1332 0 0\n Shell 1 49 38 1 10\n TOML 2 77 64 4 9\n-------------------------------------------------------------------------------\n Markdown 5 1355 0 1074 281\n | - JSON 1 41 41 0 0\n | - Rust 2 53 42 6 5\n | - Shell 1 22 18 0 4\n (Total) 1471 101 1080 290\n-------------------------------------------------------------------------------\n Rust 19 3416 2840 116 460\n | - Markdown 12 351 5 295 51\n (Total) 3767 2845 411 511\n===============================================================================\n Total 32 6745 4410 1506 829\n=============================================================================== \nprocs \nprocs - 是用 Rust 编写的 ps 的替代品。
\n
\neva \neva - 简单的计算器 REPL,类似于 bc(1),具有语法高亮和持久历史记录。
\n
\nhyperfine \nhyperfine - 命令行基准测试工具。
\n
\nffsend \nffsend - 从命令行轻松安全地共享文件。 一个功能齐全的 Firefox Send 客户端。
\n
\nalacritty \nalacritty - 是一个现代终端仿真器,具有合理的默认值,但允许进行广泛的配置。 通过与其他应用程序集成,而不是重新实现它们的功能,它设法提供了一组灵活的高性能特性。 目前支持的平台包括 BSD、Linux、macOS 和 Windows。
\n
\nNode.js \nnvm \nnvm - 允许您通过命令行快速安装和使用不同版本的 Node.js
。
\n
\nfnm \nfnm - 快速简单的 Node.js
版本管理器,基于 Rust 实现。
\n
\nvolta \nVolta - 快速无缝地安装和运行任何 JS 工具! Volta 是用 Rust 构建的,以二进制文件形式发布,跨平台支持(macOS、Windows、Linux)。
\n
","category":{"name":"Notes"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwzMDg2MDYxNzMz","name":"blog"}},{"node":{"id":"MDU6TGFiZWwzMTk2OTc2MDIx","name":"wechat-post"}}]},"reactions":{"totalCount":1,"edges":[{"node":{"id":"REA_lAXOEUMBcs4APDcIzgAFx8o","content":"HOORAY"}}]},"comments":{"edges":[{"node":{"id":"DC_kwDOEUMBcs4AJWU8","bodyHTML":"fzf & git-fuzzy
","author":{"login":"EliazTray","avatarUrl":"https://avatars.githubusercontent.com/u/16015431?u=73c7abd9725e754791bf88453d5ab582dbb36cbf&v=4","url":"https://github.com/EliazTray"},"replies":{"edges":[]}}}]}}
\ No newline at end of file
diff --git a/issues/86.json b/issues/86.json
new file mode 100644
index 0000000..c022269
--- /dev/null
+++ b/issues/86.json
@@ -0,0 +1 @@
+{"id":"D_kwDOEUMBcs4APPsg","title":"微信杂谈 - 写代码","bodyHTML":"📅 2022.04.09
\nlencx: \n写代码其实不难,难的是搞不清楚问题
\nlencx: \n大部分写不下去都是因为自己根本不知道自己写的是个什么东西
\n浦原: \n这个我深有感触
\n浦原: \n写不下去就真的是单纯不知道问题出在哪里
\nlencx: \n学习其实也是这样,用什么语言不重要啊,重要的是你的逻辑要清楚,剩下的事情搜索引擎帮你搞定,基本可以解决百分之八九十的问题
\nlencx: \n只有少部分极难的问题,靠搜索很难搞定,这就牵扯到你的知识推导能力了
\nlencx: \n经验都是虚的,没啥用
\nlencx: \n因为经验会过时,会遗忘,知识的推导过程其实就是你的逻辑思维具像化
\nlencx: \n我是这么认为的
","category":{"name":"Notes"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwzMTgxNDE5MDUz","name":"微信杂谈"}}]},"reactions":{"totalCount":0,"edges":[]},"comments":{"edges":[]}}
\ No newline at end of file
diff --git a/issues/87.json b/issues/87.json
new file mode 100644
index 0000000..6b2d2aa
--- /dev/null
+++ b/issues/87.json
@@ -0,0 +1 @@
+{"id":"D_kwDOEUMBcs4APuVt","title":"微信杂谈 - 学习 Rust","bodyHTML":"\n不看文档,习惯性把已有经验带入到新语言学习中,感觉学习了很多门语言,本质上都在用同一个思维模式解决问题 ...
\n \n📅 2022.06.06
\n大橙子的小迪子🍊: \nlet a = ‘abc’
\n大橙子的小迪子🍊: \na[0]
\n大橙子的小迪子🍊: \n@lencx rust不允许这样取呀
\nlencx: \n肯定不行啊
\nlencx: \n单引号是 char 类型
\n大橙子的小迪子🍊: \n字符串可以吗
\nlencx: \n看文档
\nlencx: \n写代码不是靠猜啊
\nlencx: \nrust 取索引是通过 .
\nlencx: \n比如 a.0
\n大橙子的小迪子🍊: \n那这个是不是取的字节索引
\nlencx: \n这种问题自己搜 一下不就知道了
\n大橙子的小迪子🍊: \n好的
\n大橙子的小迪子🍊: \n这个变化挺大的
\nlencx: \n学新语言是可以通过对比去学习,但是不能硬套啊,每种语言都有自己的心智模型,而不是写 Rust 版的 JS…
\nlencx: \n看文档就是学习该语言的表达方式
\n不精通react不改名: \nrust版本的js在哪在哪
\nlencx: \n而不是靠经验去猜,毫无意义
\n大橙子的小迪子🍊: \n这个括号里面的数字代表的是字节索引吧
\nlencx: \n用 js 的思维方式写 rust,不就是 rust 版的 js 吗
\n不精通react不改名: \n确实
","category":{"name":"Notes"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwzMTgxNDE5MDUz","name":"微信杂谈"}}]},"reactions":{"totalCount":0,"edges":[]},"comments":{"edges":[]}}
\ No newline at end of file
diff --git a/issues/88.json b/issues/88.json
new file mode 100644
index 0000000..fb80e5e
--- /dev/null
+++ b/issues/88.json
@@ -0,0 +1 @@
+{"id":"D_kwDOEUMBcs4AP99G","title":"痛苦学习的快感","bodyHTML":"TODO
","category":{"name":"Notes"},"labels":{"edges":[{"node":{"id":"MDU6TGFiZWwzMDg2MDYxNzMz","name":"blog"}},{"node":{"id":"MDU6TGFiZWwzMTk2OTc2MDIx","name":"wechat-post"}}]},"reactions":{"totalCount":0,"edges":[]},"comments":{"edges":[]}}
\ No newline at end of file
diff --git a/issues/90.json b/issues/90.json
new file mode 100644
index 0000000..a4fbce9
--- /dev/null
+++ b/issues/90.json
@@ -0,0 +1 @@
+{"id":"D_kwDOEUMBcs4ARqtP","title":"请问如何部署?","bodyHTML":"麻烦给一篇部署文档,谢谢!
","category":{"name":"QA"},"labels":{"edges":[]},"reactions":{"totalCount":0,"edges":[]},"comments":{"edges":[{"node":{"id":"DC_kwDOEUMBcs4AQewz","bodyHTML":"我这个仓库是个人项目。如果想要部署可以看看我这个项目 https://github.com/lencx/gg
","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"replies":{"edges":[{"node":{"id":"DC_kwDOEUMBcs4AQe_7","author":{"login":"Jonnyan404","avatarUrl":"https://avatars.githubusercontent.com/u/20352705?u=3806efb3d3cd512e4bd3ddfdd85b52ac53b6b797&v=4","url":"https://github.com/Jonnyan404"},"bodyHTML":"\n我这个仓库是个人项目。如果想要部署可以看看我这个项目 https://github.com/lencx/gg
\n \n谢谢! \n然后比较喜欢你这个样式,该怎么copy你这个站点的效果?
"}}]}}},{"node":{"id":"DC_kwDOEUMBcs4AQfEA","bodyHTML":"Node.js 12 actions are deprecated. For more information see: https://github.blog/changelog/2022-09-22-github-actions-all-actions-will-begin-running-on-node16-instead-of-node12/ . Please update the following actions to use Node.js 16: actions/checkout@v2, actions/setup-node@v2
","author":{"login":"Jonnyan404","avatarUrl":"https://avatars.githubusercontent.com/u/20352705?u=3806efb3d3cd512e4bd3ddfdd85b52ac53b6b797&v=4","url":"https://github.com/Jonnyan404"},"replies":{"edges":[]}}},{"node":{"id":"DC_kwDOEUMBcs4AQfFD","bodyHTML":"还有怎么设置为/
路径访问,目前还得带个子路径
","author":{"login":"Jonnyan404","avatarUrl":"https://avatars.githubusercontent.com/u/20352705?u=3806efb3d3cd512e4bd3ddfdd85b52ac53b6b797&v=4","url":"https://github.com/Jonnyan404"},"replies":{"edges":[{"node":{"id":"DC_kwDOEUMBcs4AQfMx","author":{"login":"Jonnyan404","avatarUrl":"https://avatars.githubusercontent.com/u/20352705?u=3806efb3d3cd512e4bd3ddfdd85b52ac53b6b797&v=4","url":"https://github.com/Jonnyan404"},"bodyHTML":"\n还有怎么设置为/
路径访问,目前还得带个子路径
\n \n设置cname域名后解决.
"}},{"node":{"id":"DC_kwDOEUMBcs4AQfN-","author":{"login":"lencx","avatarUrl":"https://avatars.githubusercontent.com/u/16164244?u=77d1d01930d8e36105a49a6c474abf70eeee74b1&v=4","url":"https://github.com/lencx"},"bodyHTML":"大概说一下原理,这个和 lencx/gg
那个仓库的逻辑是类似,都是通过 github discussion api 来进行操作的,不同的是这个会发起携带 token 的请求(可以本地开发使用,token 暴露会不安全,对外不建议使用),如果请求失败会回退到 github-pages 下的 json 文件请求。json 文件的生成是通过 github action 来处理的,这里涉及到我自己实现的一个生成 json 文件的命令。
\n"}}]}}}]}}
\ No newline at end of file
diff --git a/lab.woff2 b/lab.woff2
new file mode 100644
index 0000000..e455a01
Binary files /dev/null and b/lab.woff2 differ
diff --git a/posts/issues-0008/index.html b/posts/issues-0008/index.html
new file mode 100644
index 0000000..d1ecb5e
--- /dev/null
+++ b/posts/issues-0008/index.html
@@ -0,0 +1,642 @@
+
+
+
+
+
+
+
+
+Web Development Guide
+
+
Guide
+
+Learn to Code — For Free — Coding Courses for Busy People - Learn to Code — For Free.
+
+
+
+ 长按识别二维码查看原文
+ https://www.freecodecamp.org
+
+
+
+
+
+MDN Web Docs - The MDN Web Docs site provides information about Open Web technologies including HTML, CSS, and APIs for both Web sites and progressive web apps.
+
+
+
+ 长按识别二维码查看原文
+ https://developer.mozilla.org
+
+
+
+
+
+Web | Google Developers - Build the next generation of web experiences.
+
+
+
+ 长按识别二维码查看原文
+ https://developers.google.com/web
+
+
+
+
+
+Web Development for Beginners - A Curriculum - 24 Lessons, 12 Weeks, Get Started as a Web Developer
+
+
+
+ 长按识别二维码查看原文
+ https://github.com/microsoft/Web-Dev-For-Beginners
+
+
+
+
+
+The Modern JavaScript Tutorial - Modern JavaScript Tutorial: simple, but detailed explanations with examples and tasks, including: closures, document and events, object oriented programming and more.
+
+
+
+ 长按识别二维码查看原文
+ https://javascript.info/
+
+
+
+
+
+Can I use... Support tables for HTML5, CSS3, etc - "Can I use" provides up-to-date browser support tables for support of front-end web technologies on desktop and mobile web browsers.
+
+
+
+ 长按识别二维码查看原文
+ https://caniuse.com
+
+
+
+
+
+W3Schools Online Web Tutorials - Well organized and easy to understand Web building tutorials with lots of examples of how to use HTML, CSS, JavaScript, SQL, Python, PHP, Bootstrap, Java, XML and more.
+
+
+
+ 长按识别二维码查看原文
+ https://www.w3schools.com
+
+
+
+
+
+DEV Community 👩💻👨💻 - A constructive and inclusive social network for software developers. With you every step of your journey.
+
+
+
+ 长按识别二维码查看原文
+ https://dev.to
+
+
+
+
+
+Medium - Every idea needs a Medium.
+
+
+
+ 长按识别二维码查看原文
+ https://medium.com
+
+
+
+
+
+Sitepoint - Stay at the cutting edge of tech
+
+
+
+ 长按识别二维码查看原文
+ https://www.sitepoint.com
+
+
+
+
+
+Fireship.io - Training and Consulting for App Developers | Full Courses, Video Lessons, Chat, and More.
+
+
+
+ 长按识别二维码查看原文
+ https://fireship.io
+
+
+
+
+
+Master the JavaScript Ecosystem - ui.dev - Comprehensive learning resources for mastering the JavaScript ecosystem.
+
+
+
+ 长按识别二维码查看原文
+ https://ui.dev
+
+
+
+
+
+React Training - React Corporate Workshops, Training, and Consulting.
+
+
+
+ 长按识别二维码查看原文
+ https://reacttraining.com
+
+
+
+
+
+awesome-lowcode - 国内低代码平台从业者交流
+
+
+
+ 长按识别二维码查看原文
+ https://github.com/taowen/awesome-lowcode
+
+
+
+
+
+Spellbook of Modern Web Dev - A Big Picture, Thesaurus, and Taxonomy of Modern JavaScript Web Development
+
+
+
+ 长按识别二维码查看原文
+ https://github.com/dexteryy/spellbook-of-modern-webdev
+
+
+
+
+
+30 seconds of code - Browse 1043 short code snippets for all your development needs on 30 seconds of code.
+
+
+
+ 长按识别二维码查看原文
+ https://www.30secondsofcode.org/
+
+
+
+
+
+JavaScript Series
+
+
+
+ 长按识别二维码查看原文
+ https://github.com/lencx/z/discussions/33
+
+
+
+
+
+CSS Series
+
+
+
+ 长按识别二维码查看原文
+ https://github.com/lencx/z/discussions/5
+
+
+
+
+
+
+
Frame
+
+React - A JavaScript library for building user interfaces
+
+Preact - ⚛️ Fast 3kB React alternative with the same modern API. Components & Virtual DOM.
+
+
+
+ 长按识别二维码查看原文
+ https://github.com/preactjs/preact
+
+
+
+
+
+
+
+Vue.js - The Progressive JavaScript Framework
+
+petite-vue - 5kb subset of Vue optimized for progressive enhancement
+
+
+
+ 长按识别二维码查看原文
+ https://github.com/vuejs/petite-vue
+
+
+
+
+
+
+
+Angular - The modern web developer's platform
+
+
+
+ 长按识别二维码查看原文
+ https://angular.io
+
+
+
+
+
+Svelte - Cybernetically enhanced web apps
+
+
+
+ 长按识别二维码查看原文
+ https://svelte.dev
+
+
+
+
+
+Fre - 👻 Tiny Footprint Concurrent UI library for Fiber.
+
+
+
+ 长按识别二维码查看原文
+ https://github.com/yisar/fre
+
+
+
+
+
+Solid - Solid is a purely reactive library. It was designed from the ground up with a reactive core. It's influenced by reactive principles developed by previous libraries.
+
+
+
+ 长按识别二维码查看原文
+ https://www.solidjs.com
+
+
+
+
+
+Lit - Simple. Fast. Web Components.
+
+
+
+ 长按识别二维码查看原文
+ https://lit.dev
+
+
+
+
+
+
+
Awesome
+
+Awesome React
+
+
+
+ 长按识别二维码查看原文
+ https://github.com/lencx/z/discussions/11
+
+
+
+
+
+Awesome Vue
+
+
+
+ 长按识别二维码查看原文
+ https://github.com/lencx/z/discussions/67
+
+
+
+
+
+
+
Charts
+
+visx - is a collection of reusable low-level visualization components. visx combines the power of d3 to generate your visualization with the benefits of react for updating the DOM.
+
+
+
+ 长按识别二维码查看原文
+ https://github.com/airbnb/visx
+
+
+
+
+
+Antv - AntV is a new generation of data visualization technique from Ant Group. We provide best practices of data visualization with simplicity, convenience, profession, reliability, and infinite possibilities.
+
+
+
+ 长按识别二维码查看原文
+ https://antv.vision
+
+
+
+
+
+
+
Surveys
+
+
RegExp
+
+Regexper - Regular expression visualizer using railroad diagrams
+
+
+
+ 长按识别二维码查看原文
+ https://regexper.com/
+
+
+
+
+
+Regulex - JavaScript Regular Expression Visualizer.
+
+
+
+ 长按识别二维码查看原文
+ https://jex.im/regulex
+
+
+
+
+
+RegExr: Learn, Build, & Test RegEx - RegExr is an online tool to learn, build, & test Regular Expressions (RegEx / RegExp).
+
+
+
+ 长按识别二维码查看原文
+ https://regexr.com/
+
+
+
+
+
+Regular-Expressions.info - Regex Tutorial, Examples and Reference - Regexp Patterns - At Regular-Expressions.info you will find a wide range of in-depth information about a powerful search pattern language called regular expressions.
+
+
+
+ 长按识别二维码查看原文
+ https://www.regular-expressions.info/
+
+
+
+
+
+Online Regex tester and visualizer - Python, PHP, Ruby, JavaScript, Java - Online regular expression tester for Python, PHP, Ruby, JS, Java and MySQL. Regex visualizer. Syntax highlighting. Cheatsheet. Generate string corresponding to a regex.
+
+
+
+ 长按识别二维码查看原文
+ https://extendsclass.com/regex-tester.html
+
+
+
+
+
+Debuggex: Online visual regex tester. JavaScript, Python, and PCRE. - Test your regex by visualizing it with a live editor. JavaScript, Python, and PCRE.
+
+
+
+ 长按识别二维码查看原文
+ https://www.debuggex.com/
+
+
+
+
+
+Free Online Regular Expression Tester - FreeFormatter.com - Free online regular expression tester with cheatsheet and most common solutions to common problems
+
+
+
+ 长按识别二维码查看原文
+ https://www.freeformatter.com/regex-tester.html
+
+
+
+
+
+
+
Blog
+
+2ality – JavaScript and more
+
+
+
+ 长按识别二维码查看原文
+ https://2ality.com
+
+
+
+
+
+Front-end Web Development, Chewed Up ← Alligator.io - Learn Angular 2+, Vue.js, React, TypeScript, Ionic, JavaScript (ES6/ES2015+) & CSS with short, straightforward posts.
+
+
+
+ 长按识别二维码查看原文
+ https://alligator.io
+
+
+
+
+
+Overreacted - Personal blog by Dan Abramov. I explain with words and code.
+
+
+
+ 长按识别二维码查看原文
+ https://overreacted.io
+
+
+
+
+
+RWieruch - Software Engineer for React.js, Node.js, GraphQL and JavaScript. Based in Berlin, German/English speaking. Consulting/Freelancing for Web Development project: Code Audits/Reviews, Workshops, Training, Implementation ...
+
+
+
+ 长按识别二维码查看原文
+ https://www.robinwieruch.de
+
+
+
+
+
+Dave Ceddia - Articles to help you learn and master frontend development with React.
+
+
+
+ 长按识别二维码查看原文
+ https://daveceddia.com
+
+
+
+
+
+Charlie Gerard | Senior frontend developer & Creative Technologist - Collection of side projects, conference talks and blog posts experimenting with frontend technologies and human-computer interaction.
+
+
+
+ 长按识别二维码查看原文
+ https://charliegerard.dev
+
+
+
+
+
+Lea Verou – Life at the bleeding edge (of web standards)
+
+
+
+ 长按识别二维码查看原文
+ https://lea.verou.me/
+
+
+
+
+
+Blog - Chris Coyier
+
+
+
+ 长按识别二维码查看原文
+ https://chriscoyier.net/
+
+
+
+
+
+Flavio Copes - JavaScript and Web Development Tutorials
+
+
+
+ 长按识别二维码查看原文
+ https://flaviocopes.com/
+
+
+
+
+
+
+
+
+
+
diff --git a/posts/issues-0025/index.html b/posts/issues-0025/index.html
new file mode 100644
index 0000000..713dfe9
--- /dev/null
+++ b/posts/issues-0025/index.html
@@ -0,0 +1,362 @@
+
+
+
+
+
+
+
+
+《黑客与画家》读书笔记
+
+
+Hackers & Painters
+作者: 保羅·格雷厄姆 (Paul Graham)[1]
+译: 阮一峰[2]
+
+
+
+
+出于兴趣而解决某个难题,不管它有没有用,这就是黑客。
+
+
+黑客伦理 [hacker ethic]
+
+使用计算机以及所有有助于了解这个世界本质的事物都不应该受到任何限制。任何事情都应该亲手尝试。
+Access to computers-and anything that might teach you something about the way the world works-should be unlimited and total. Always yield to the Hands-On Imperative!
+信息应该全部免费。
+All information should be free.
+不信任权威,提倡去中心化。
+Mistrust Authority-Promote Decentralization.
+判断一名黑客的水平应该看他的技术能力,而不是看他的学历、年龄或地位等其他标准。
+Hackers should be judged by their hacking, not bogus criteria such as degrees, age, race, or position.
+你可以用计算机创造美和艺术。
+You can create art and beauty on a computer.
+计算机使生活更美好。
+Computers can change your life for the better.
+
+根据这六条“黑客伦理”,黑客价值观的核心原则可以概括成这样几点:分享、开放、民主、计算机的自由使用、进步。
+
+
+计算机程序只是文本而已。你选择什么语言,决定了你能说什么话。编程语言就是程序员的思维方式。
+
+
+
+
+阿尔伯蒂[3] 有一句名言:“任何一种艺术,不管是否重要,如果你想要在该领域出类拔萃,就必须全身心投入。”
+
+
黑客与画家
+
+
+黑客搞懂“计算理论” [theory of computation] 的必要性,与画家搞懂颜料化学成分的必要性差不多大。一般来说,在理论上,你需要知道如何计算“时间复杂度”和“空间复杂度” [time and space complexity];如果你要写一个解释器,可能还需要知道状态机 [state machine] 的概念;除此以外,并不需要知道特别多的理论。这些可比画家必须记住的颜料成分少很多。
+
+
+因为如果你不爱一件事,你不可能把它做得真正优秀,要是你很热爱编程,你就不可避免地会开发你自己的项目。
+
+
+黑客就像画家,工作起来是有心理周期的。有时候,你有了一个令人兴奋的新项目,你会愿意为它一天工作 16 个小时。等过了这一阵,你又会觉得百无聊赖,对所有事情都提不起兴趣。
+
+
+对于编程,这实际上意味着你可以把 bug 留到以后解决。消灭 bug 对我来说属于轻松的工作,只有在这个时候,编程才变得直接和机械,接近社会大众想象中的编程的样子。消灭 bug 的过程就像解一道数学题,已知许许多多的约束条件,你只要根据条件对方程求解就可以了。你的程序应该能产生 x 结果,但是却产生了 y 结果。哪里出错了?你知道自己最后肯定能够解决这个问题,所以做起来很轻松,就好像刷墙一样,接近于休闲了。
+
+
+“程序写出来是为了让人看懂它的算法,附带告诉计算机如何执行。”一种好的编程语言应该比英语更容易解释软件。只有在那些不太成熟、容易出现问题的地方,你才应该加上注释,提醒读者注意那里,就好像公路上只有在急转弯处才会出现警示标志一样。
+
+
+
不能说的话
+
+
+大多数成年人故意让孩子对世界有一个错误的认识。最鲜明的例子之一就是圣诞老人。我们觉得,小孩子相信圣诞老人,真是太可爱了。我本人其实也是这样想。但是,扪心自问,我们向孩子灌输圣诞老人的神话,到底是为了孩子,还是为了我们自己?
+我在这里不讨论这样做是否正确。家长想要塑造孩子的心灵,把他们装扮成可爱的小宝宝,这可能是无法避免的。我也可能这样做。但是,就本文而言,这样做会产生一个重要的结果,那就是孩子“被迫”在一个精心设计的环境中长大。他的头脑或多或少是纯洁无暇的,一点也不知道那些“不能说的话”,从来没有被真实的社会生活“污染”过。孩子眼里的世界是不真实的,是一个被灌输进他们头脑的假想世界。将来当孩子长大以后接触社会,就会发现小时候以为真实的事情,在现实世界中是荒唐可笑的。
+
+
+那些团体神经越紧张,它们所产生的禁止力量就越大。伽利略因为宣布日心说而遭到教廷的审判,这件事讽刺的地方在于,他只是在宣传哥白尼的观点,而后者却安然无恙。事实上,哥白尼不仅不反对教廷,还是一个虔诚的天主教教士,他把自己的著作献给教皇。不幸的是,伽利略正赶上教廷内部反对派上台,宗教改革制度压制,任何非正统的思想遭受到前所未有的严厉控制和禁止。
+为了在全社会制造出一个禁忌,负责实施的团体必定既不是特别强大也不是特别弱小。如果一个团体强大到无比自信,它根本不会在乎别人的抨击。美国人或者英国人对国外媒体的诋毁就毫不在意。但是一个团体太弱小,就会无力推行禁忌。有一种行为怪癖叫做“嗜粪症” [coprophila],它的患者人数以及影响势力眼下似乎就不太强大,无法把自己的观点推广给其他人。
+我猜想,道德禁忌的最大制造者是那些权利斗争中略占上风的一方。你会发现,这一方有实力推行禁忌,同时又软弱到需要用禁忌来保护自己的利益。
+大多数的斗争,不管它们实际上争的是什么,都会以思想斗争的形式表现出来。
+
+
+
为什么这样做
+
+
+有人可能会问,为什么要去找出“不能说的话”?为什么要故意打探那些龌龊的,见不得人的思想观点?你明知那里有挡住去路的石头,为什么还要把它们翻过来看个究竟呢?
+首先,我这样做与小孩子翻石头是出于同样的原因:纯粹的好奇心。我对任何被禁止的东西都有特别强烈的好奇心。我要亲眼看一下,然后自己做决定。
+其次,我这样做是因为我不喜欢犯错。如果像其他时代一样,那些我们自以为正确的事情将来会被证明是荒唐可笑的,我希望自己能够知道是哪些事情,这样可以使我不会上当。
+再次,我这样做,是因为这是很好的脑力训练。想要做出优秀作品,你需要一个什么问题都能思考的大脑。尤其是那些似乎不应该思考的问题,你的大脑也要养成思考它们的习惯。
+优秀作品往往来自于其他人忽视的想法,而最被忽视的想法就是那些被禁止的思想观点。
+
+
+“守口如瓶”的真正缺点在于,你从此无法享受讨论带来的好处了,讨论一个观点会产生更多的观点,不讨论就什么观点也没有。所以,如果可能的话,你最好找一些信得过的知己,只与他们畅所欲言、无所不谈。这样不仅可以获得新观点,还可以用来选择朋友。能够一起谈论“异端邪说”并且不会因此气急败坏的人,就是你最应该认识的朋友。
+
+
+你不仅要远距离观察人群,更要远距离观察你自己。顺便提一句,这可不是激进的想法。儿童和成年人的主要差别就在这里。儿童精疲力竭时,可能会大发脾气,因为他不知道为了什么;成年人则会了解是个人的身体状况问题,与外界无关,说一句“没关系,我只是累了”。我想,通过类似的机制,一个人完全可以识别和抵制外界流行的道德观念,把它们与内心世界相分离。
+如果你想要清晰的思考,就必须远离人群。但是走的越远,你的处境就会越困难,受到的阻力也会越大,因为你没有迎合社会习俗,而是一步步地与它背道而驰。小时候,每个人都会鼓励你不断成长,变成一个心智成熟、不再耍小孩脾气的人。但是,很少有人鼓励你继续成长,变成一个怀疑和抵制社会错误潮流的人。
+如果自己就是潮水的一部分,怎么能看见潮流的方向呢?你只能永远保持质疑。问自己,什么话是我不能说的?为什么?
+
+
+
另一条路
+
+
+如果软件的新版本要等一年后才能发布,我就会把大部分新构思束之高阁,至少过上一段时间再来考虑。但是,构思这种东西有一个特点,那就是它会导致更多的构思。你有没有注意过,坐下来写东西的时候,一半的构思是写作时产生的?软件也是这样。实现某个构思,会带来更多的构思。所以,将一个构思束之高阁,不仅意味着延迟它的实现,还意味着延迟所有在实现过程中激发的构思。事实上,将一个构思束之高阁,甚至会限制新构思的产生。因为你看一眼堆放在一边、还没实现的构思,就会想“我已经为下一个版本准备了很多新东西要实现了”,你就懒得再去思考更多的新功能了。
+
+
+现在,创业公司有更多的理由选择互联网软件创业,因为开发桌面软件越来越乏味了。如果你现在开发桌面软件,就不得不接受微软公司的授权条款,调用它的 API,为它那个 bug 百出的操作系统伤透脑筋。历尽千辛万苦,你最终写出了一个受大众欢迎的软件,这时你可能会发现,你所做的一切其实只是在为微软公司做市场调查。
+
+
+你能够做到这一点,意味着竞争者也能做到这一点,所以长时间工作变成了一种必须,不得不如此。因为你能做到,所以你必须做到
。这简直就是逆向的帕金森定律[4]
+
+
+不少公司都很想知道,什么事情可以外包,什么事情不可以外包,一个可能的答案是,公司内部所有不直接感受的竞争压力的部门都应该外包出去,让它们暴露在竞争压力之下。(我这里所说的“外包”,指的是聘请另一家公司来执行,而不是指把业务部门转移到海外。)
+
+
+由于个人经历的关系,特雷弗·布莱克韦尔对这一点的认识可能比其他任何人都深刻。他写到:“我会进一步说,由于互联网软件的程序员非常辛苦,所以会使得经济优势根本性地从大公司向创业公司转移。互联网软件要求的那种工作强度和付出,只有当公司是其本人所有时,程序员才愿意提供。软件公司可以雇用到能干的人,让他们去干轻松的事情,也可以雇到不能干的人,让他们去干艰苦的事情。但是无法雇到非常能干的人,让他们去干非常艰苦的事情。因为互联网软件的创业不需要太多的资本,所以大公司可以与创业公司竞争的优势就所剩无几了。”
+
+
+
如何创造财富
+
+
+交换媒介的优点是,它使得交易可以进行下去。缺点是,它往往模糊了交易的实质。人们觉得做生意就是为了挣钱,但是金钱其实只是一种中介,让大家可以更方便地获得自己想要的东西。大多数生意的目的是为了创造财富,做出人们真正需要的东西。
+
+
+金钱不是财富,而只是我们用来转移财富所有权的的东西。
+
+
+公司就是许多人聚在一起创造财富的地方,能够制造更多人们需要的东西。
+
+
+我们这个世界,你向下沉沦或者向上奋进都取决于你自己,不能把原因推给外界。
+
+
+一个大学毕业生总是想“我需要一份工作”,别人也是这么对他说的,好像变成某个组织的成员是一件多么重要的事情。更直接的表达方式应该是“你需要去做一些人们需要的东西”。即使不加入公司,你也能做到。公司不过是一群人在一起工作,共同做出某种人们需要的东西。真正重要的是做出人们需要的东西,而不是加入某个公司。
+对于大多数人来说,最好的选择可能是为某个现存的公司打工。但是,理解这种行为的真正含义对你没有什么坏处。工作就是在一个组织中,与许多人共同合作,做出某种人们需要的东西。
+
+
+要致富,你需要两样东西:可测量性
和可放大性
。你的职位产生的业绩,应该是可测量的,否则你做的再多,也不会得到更多的报酬。此外,你还必须有可放大性,也就是说你做出的决定能够产生巨大的效应。
+
+
+如果你有一个令你感到安全的工作,你是不会致富的,因为没有危险,就几乎等于没有可放大性。
+
+
+乔布斯曾经说过,创业的成败取决于最早加入公司的那十个人。我基本同意这个观点,虽然我觉得真正决定成败的其实 只是前五人。小团队的优势不在于它本身的小,而在于你可以选择成员。我们不需要小村庄的那种“小 ”,而需要全明星第一阵容的那种“小”。
+
+
+什么是技术?技术就是某种手段,就是我们做事的方式。如果你发现了一种做事的新方式,它的经济价值就取决于有多人使用这种新方式。技术就是钓鱼的鱼竿,而不是那条鱼。
+
+
+只要懂得藏富于民,国家就会变得强大。让书呆子保住他们的血汗钱,你就会无敌于天下。
+
+
+“财富”这个词有很多意思,有些并不是指物质财富。我不想做深入讨论,研究到底什么才是真正的财富。我这里指的只是一种特定的技术层面上的“财富” ——人们用金钱向你交换东西。这是一种很有趣、很值得研究的财富,因为它使得你免于饥饿,而且人们是否用金钱交换这种财富取决于他们,而不是取决于你。
+
+
+
关注贫富分化
+
+
设计者的品味
+
+
+对于建筑师和设计者,它意味着美依赖于一些精心选择的结构性元素,而不是依赖于表面装饰品的堆砌。(装饰品本身并不是坏事,只有它被用来掩盖结构的苍白时,才变成了一件坏事。)
+
+
+如果解决方法是丑陋的,那就肯定还有更好的解决方法,只是还没有发现而已。
+
+
+白描其实是最难画的视觉媒介,因为它们要求近乎完美的再现。用数学语言说,线条属于闭合解 [closed-form-solution],水平不够的艺术家没有办法直接解决问题,只能通过不断逼近来求解。
+
+
+人们有时会说自己有了“状态”,我的理解是,他们这时可以控制自己的脊髓。脊髓是更本能的反应,面对难题时,它能释放你的直觉。
+
+
+好设计是模仿大自然的设计。我不是说模仿大自然这种行为本身有多么好,而是说大自然在长期的演化中已经解决了很多设计问题。所以,如果你的设计与大自然很接近,那么它基本上不会很差。
+
+
+
一百年后的编程语言
+
+
+在长期的职业生涯中,我发现冗余的代码会导致更多冗余的代码,不仅软件如此,而且像我这样性格懒散的人,我发现在床底下和房间的角落里这个命题也成立,一件垃圾会产生更多的垃圾。
+
+
+编程语言进化缓慢的原因在于它们并不是真正的技术。语言只是一种书写法,而程序则是一种严格符合规则的描述,以书面形式记录计算机应该如何解决你的问题。所以,编程语言的进化速度更像数学符号的进化速度,而不像真正的技术(比如交通或者通信技术)的进化速度。数学符号的进化是缓慢的渐变式变化,而不是真正技术的那种跳跃式发展。
+
+
+我已经预测到了,一旦未来硬件的性能大幅提高将会发生什么事。新增加的运算能力都会被糟蹋掉。
+在我学习编程的年代,计算机还是稀罕玩意。我记得当时使用的微机型号是 TRS-80,它的内存只有 4K,为了把 BASIC 程序装入内存,我不得不把源码中的空格全部删除。我一想到那些极其低效率的软件,不断重复某些愚蠢的运算,把硬件的计算能力全部占用,就感到无法忍受。但是,我的这种反应是错的,我就像某个出身贫寒的穷孩子,一听到要花钱就舍不得,即使把钱用在重要场合(比如去医院看病)都会觉得难以接受。
+
+
+
书呆子的复仇
+
+如果你想在软件业获得成功,就使用你知道的最强大的语言,用它解决你知道的最难的问题,并且等待竞争对手的经理做出自甘平庸的选择。
+
+
梦寐以求的编程语言
+
+
+编程语言不是存在于真空之中,“编程”其实是及物动词,黑客一般都是为某个系统编程。在现实中,编程语言总是与它们依附的系统联系在一起的。
+
+
+无法以一种语言本身的优缺点评判这种语言。另一个结果则是,只有当一种语言是某个系统的脚本语言时,它才能真正成为编程语言。如果你对此很吃惊,觉得不公平,那么我会跟你说不必大惊小怪。这就好比大家都认为,如果一种编程语言只有语法规则,没有一个好的实现 [implementation],那么它就不能算完整的编程语言。这些都是很正常很合理的事情,编程语言本来就该如此。
+
+
+你只需要不停地重复同一句话,最终人们将会开始倾听。人们真正注意到你的时候,不是第一眼就看到你站在那里,而是发现过了这么久你居然还在那里。
+
+
+著名散文家 E.B. 怀特说过,“最好的文字来自不停的修改”。
+
+
+为了写出优秀软件,你必须同时具备两种相互冲突的信念。一方面,你要像初生牛犊一样,对自己的能力信心万丈;另一方面,你又要像历经沧桑的老人一样,对自己的能力抱着怀疑态度。在你的大脑中,有一个声音说:“千难万险只等闲”,还有一个声音却说“早岁哪知世事艰”。
+这里的难点在于你要意识到,实际上两种信念并不矛盾。你的乐观主义和怀疑倾向分别针对两个不同的对象。你必须对解决难题的可能性保持乐观,同时对当前解法的合理性保持怀疑。
+做出优秀成果的人,在做的过程中常常觉得自己做得不够好。其他人看到他们的成果觉得棒极了,而创造者本人看到的都是自己作品的缺陷。这种视角的差异并非偶然,因为只有对现状不满,才会造就杰出的成果。
+
+
+因此现实中,尽管软件功能越来越强大,内部接口却往往一成不变,成为整个系统中拖后腿的部分。
+一种可能的解决方法是,将软件内部的接口设计成垂直接口而不是水平接口。这意味着软件内部的模块是一个个垂直堆积起来的抽象层,层与层之间的接口完全由其中的一层控制。如果较高的一层使用了较低的一层定义的语言,那么接口就由较低的一层控制;如果较低的一层从属于较高的一层,那么接口就由较高的一层控制。
+
+
+帕金森定律 [Parkinson's Law] 的一种原始表达形式是“工作总是到最后一刻才会完成”,后来引申到计算机领域就变成了“数据总是会填满所有的空间”,更一般性的总结则是:“对一种资源的需求总是会消耗光这种资源的所有供应”。
+
+
+
设计与研究
+
+
+设计与研究的区别看来就在于,前者追求“好” [good],后者追求“新” [new]。优秀的设计不一定很“新”,但必须是“好”的;优秀的研究不一定很“好”,但必须是“新”的。我认为这两条道路最后会发生交叉:只有应用“新”的创新和理论,才会诞生超越前人的最佳设计;只有解决那些值得解决的难题(也就是“好”的难题),才会诞生最佳研究。所以,最终来说,设计和研究都通向同一个地方,只是前进的路线不同罢了。
+
+
+怎么理解编程语言?你不要把它看成那些已完成的程序的表达方式,而应该把它理解成促进程序从无到有的一种媒介。这里的意思是说,成品的材料和开发时用的材料其实是不一样的。搞艺术的人都知道,这两个阶段往往需要不同的媒介。比如,大理石是一种非常良好、耐用的材料,很适合用于最后的成品,但是它极其缺乏弹性和灵活性,所以不适合在构思阶段用来做模型。
+最后写出来的程序就像已经完成的数学证明一样,是一棵经过精心修剪的树木,上面杂乱滋生的树杈 都已经被剪去了。所以,评价一种语言的优劣不能简单地看最后的程序是否表达得很漂亮,而要看程序从无到有的那条完成路径是否很漂亮。
+
+
+画家之间甚至流传着一句谚语:“画作永远没有完工的一天,你只是不再画下去而已。”
+
+
+“弱即是强”指的是一种软件传播的模式,由 Common Lisp 专家里查德·加布里埃尔 [Richard P. Gabriel] 于 1991 年在 Lisp: Good News, Bad News, How to Win Big[5] 一文中首先提出。它的含义非常广泛,涉及软件设计思想的各个方面,其中的一个重要结论就是软件功能的增加并不必然带来质量的提高。有时候,更少的功能(“弱”)反而是更好的选择(“强”),因为这会使得软件的可用性提高。相比那些体积庞大、功能全面、较难上手的软件,一种功能有限但易于使用的软件可能对用户有更大的吸引力。加布里埃尔本人经常举 Unix 和 C 语言的例子,Unix 和 C 在设计上考虑了实际环境,放弃了一些功能,但是保证了简单性,这使得它们最终在竞争中胜出,成为主流操作系统和编程语言。
+
+
+
术语解释
+
+抽象 [abstract]
: 隐藏细节。编程语言越抽象,你写出程序所需的运算步骤就越少,每一步的功能就越强。
+算法 [algorithm]
: 完成任务的方法。
+Blub 困境 [Blub Paradox]
: 程序员的思想往往会受到自己正在使用的语言的束缚,不相信还存在更强大的语言。
+复杂性 [complexity]
: 算法的“时间复杂性” [time complexity] 指的是,当输入的数据量不断增加时,计算机完成过这种算法所消耗的时间
+散列表 [hash table]
: 一种类似数据库的数据结构,存储在里面的每一段数据都有一个对应的键,使用时只要按照键名就可以取出对应的数据。
+函数库 [library]
: 已经写好的代码片段,可以用来执行特定任务。
+宏 [macro]
: 一个能够生成其他程序的程序。
+元循环 [metacircular]
: 当一种语言的解释器用这种语言本身开发时,就会出现这种情况。与其说这是为了做出这种语言的一种实现,还不如说这是描述语言的一种技巧。
+方法 [method]
: 面向对象编程中充当某个类的属性的一个子程序。
+模块 [module]
: 一组子程序和变量,它们可以被视为是一个整体。通常情况下,模块外部的代码只能访问模块内部一部分专门对外公开的子程序和变量
+目标码 [object code]
: 编译器产生的机器语言。
+面向对象 [OO: object-oriented]
: 一种组织程序的方式。假定不同的类代表不同类型的数据,那么针对这些数据执行某种特定任务的代码,可以根据数据的不同被分别写进不同的类,成为这些类的方法。
+正交的 [orthogonal]
: 彼此独立、能够以多种方式组合在一起的一组东西。(乐高积木)
+解析器 [parser]
: 读取输入的数据然后生成解析树的程序。
+解析树 [parser tree]
: 解析器读取源码后生成的数据结构。它是将源码翻译成机器语言的第一步。
+管道 [pipe]
: 将操作系统的各种命令连接起来的一种方式,使得一个命令的输出变成另一个命令的输入。
+指针 [pointer]
: 一块数据,它的值是另一块数据的内存地址。
+进程 [process]
: 在同时运行多个程序的操作系统中,同时被运行的程序之一。
+质量保证 [QA: Quality Assurance]
: 软件行业中负责找出和登记 bug 的人。
+递归 [recursive]
: 一种调用自身的算法。
+
+
参考资料 [1] 作者: 保羅·格雷厄姆 (Paul Graham): http://www.paulgraham.com
+[2] 译: 阮一峰: http://www.ruanyifeng.com
+[3] 阿尔伯蒂: https://en.wikipedia.org/wiki/Leon_Battista_Alberti
+[4] 帕金森定律: https://en.wikipedia.org/wiki/Law_of_triviality
+[5] Lisp: Good News, Bad News, How to Win Big: http://www.dreamsongs.com/WIB.html
+
+
+
+
diff --git a/posts/issues-0035/index.html b/posts/issues-0035/index.html
new file mode 100644
index 0000000..26a737b
--- /dev/null
+++ b/posts/issues-0035/index.html
@@ -0,0 +1,267 @@
+
+
+
+
+
+
+
+
+这些年追过的动漫
+
+
+以下列出的动漫,及评价,仅代表个人观点,不喜勿喷。看的动漫太多了,先列了能想起来的一部分,后面继续补充。
+
+
+灵笼
- 世界观宏大,细节处理到极致,前几集可能看不懂,建议搭配解说一起看
+元龙
- 枪打修真者,只能说时代变了
+眷思量
- 画面太美,帧帧壁纸,故事情节有点一般
+星辰变
- 时长良心,打斗效果没得说
+白蛇传
- 好看
+两不疑
- 有点萌
+枕刀歌
- 打斗效果拉满
+观海策
- 以神话,山海经,战国策等中国文化为背景
+斗破苍穹
- 真三年之约,人物建模,打斗场面从第一部到三年之约,越来越好
+西行纪
- 对话有点尬,每次看动漫都有种,脑子不太正常才会看这个
+一念永恒
- 主角很怕死,但是关键时刻能够挺身而出,顺便大坑一笔
+完美世界
- 剧情紧凑,打斗还行,就是有点翻来覆去就那几招的感觉,没啥新意
+雪鹰领主
- 有些剧情,挺尬的,感觉一般
+凡人修仙传
- 画风写实,剧情紧凑
+镇魂街
+地灵曲
+镜·双城
+星骸骑士
+武动乾坤
+山河剑心
+魔道祖师
+长剑风云
+雾山五行
+绝命响应
+游侠战纪
+魁拔之殊途
+猫妖的诱惑
+我是大神仙
+梦塔·雪谜城
+穿书自救指南
+妖精种植手册
+盗墓笔记秦岭神树
+逆转次元:AI崛起
+拾忆长安·明月几时有
+
+
玄机科技
+
+武庚纪
- 主角吹牛第一,逃跑第一,有点怂。最喜欢的角色“逆天而行”和“子羽”
+斗罗大陆
- 画质,细节处理是越来越好,但是剧情越来越拖沓
+吞噬星空
+天行九歌
+秦时明月
+天宝伏妖录
+
+
若森画江湖系列
+
+不良人
- 大帅就是大帅,以为的结局原来只是开局
+侠岚
+灵主
+杯莫停
+轨夜行
+换世门生
+
+
若鸿、索以文化
+
+三分片头,两分片尾,五分正片,半分内容!
+
+
+妖神记
(若鸿)
+万界神主
(索以)
+万界春秋
(索以)
+长安幻街
(索以)
+我气哭了百万修炼者
(索以)
+
+
+
灵笼解说
+
+
+
+
+
diff --git a/posts/issues-0044/index.html b/posts/issues-0044/index.html
new file mode 100644
index 0000000..33bb693
--- /dev/null
+++ b/posts/issues-0044/index.html
@@ -0,0 +1,1184 @@
+
+
+
+
+
+
+
+
+阅读打卡
+
+
+
+
Linux
+
+
Git
+
+
Web
+
+CSS Fingerprinting - Pure CSS device fingerprinting.
+
+
+
+ 长按识别二维码查看原文
+ https://github.com/OliverBrotchie/CSS-Fingerprint
+
+
+
+
+
+How to Fill an Array with Initial Values in JavaScript
+
+
+
+ 长按识别二维码查看原文
+ https://dmitripavlutin.com/javascript-fill-array/
+
+
+
+
+
+The JavaScript Array Handbook – JS Array Methods Explained with Examples
+
+
+
+ 长按识别二维码查看原文
+ https://www.freecodecamp.org/news/the-javascript-array-handbook/amp/
+
+
+
+
+
+5 Things to Consider Before You Build Your App
+
+
+
+ 长按识别二维码查看原文
+ https://dzone.com/articles/5-things-to-consider-before-you-build-your-app
+
+
+
+
+
+What if… you could use Visual Studio Code as the editor of in-browser Developer Tools?
+
+
+
+ 长按识别二维码查看原文
+ https://christianheilmann.com/2021/10/12/what-if-you-could-use-visual-studio-code-as-the-editor-of-in-browser-developer-tools/
+
+
+
+
+
+The Single-Page-App Morality Play
+
+
+
+ 长按识别二维码查看原文
+ https://www.baldurbjarnason.com/2021/single-page-app-morality-play/
+
+
+
+
+
+Scroll Shadows With JavaScript
+
+
+
+ 长按识别二维码查看原文
+ https://css-tricks.com/scroll-shadows-with-javascript/
+
+
+
+
+
+All About Svelte, the Much-Loved, State-Driven Web Framework
+
+
+
+ 长按识别二维码查看原文
+ https://thenewstack.io/all-about-svelte-the-much-loved-state-driven-web-framework/
+
+
+
+
+
+Micro Frontends With Webpack
+
+
+
+ 长按识别二维码查看原文
+ https://www.c-sharpcorner.com/article/micro-frontends-with-webpack/
+
+
+
+
+
+An in-depth perspective on webpack's bundling process
+
+
+
+ 长按识别二维码查看原文
+ https://indepth.dev/posts/1482/an-in-depth-perspective-on-webpacks-bundling-process
+
+
+
+
+
+How I Built My Blog
+
+
+
+ 长按识别二维码查看原文
+ https://www.joshwcomeau.com/blog/how-i-built-my-blog/
+
+
+
+
+
+Building a type-safe dictionary in TypeScript
+
+
+
+ 长按识别二维码查看原文
+ https://blog.logrocket.com/building-type-safe-dictionary-typescript/
+
+
+
+
+
+React, structured data, and SEO
+
+
+
+ 长按识别二维码查看原文
+ https://blog.logrocket.com/react-structured-data-and-seo/
+
+
+
+
+
+Rome will be written in Rust 🦀
+
+
+
+ 长按识别二维码查看原文
+ https://rome.tools/blog/2021/09/21/rome-will-be-rewritten-in-rust
+
+
+
+
+
+React Hooks for infinite scroll: An advanced tutorial
+
+
+
+ 长按识别二维码查看原文
+ https://blog.logrocket.com/react-hooks-infinite-scroll-advanced-tutorial/
+
+
+
+
+
+An Intro to JavaScript Proxy
+
+
+
+ 长按识别二维码查看原文
+ https://css-tricks.com/an-intro-to-javascript-proxy/
+
+
+
+
+
+JavaScript vs JavaScript: Round 2. Fight!
+
+
+
+ 长按识别二维码查看原文
+ https://dev.to/this-is-learning/javascript-vs-javascript-round-2-fight-2m44
+
+
+
+
+
+The Future of CSS: Cascade Layers (CSS @layer)
+
+
+
+ 长按识别二维码查看原文
+ https://www.bram.us/2021/09/15/the-future-of-css-cascade-layers-css-at-layer/
+
+
+
+
+
+Designing Beautiful Shadows in CSS
+
+
+
+ 长按识别二维码查看原文
+ https://www.joshwcomeau.com/css/designing-shadows/
+
+
+
+
+
+How to Build a CSS Library with Vite.js
+
+
+
+ 长按识别二维码查看原文
+ https://www.freecodecamp.org/news/build-a-css-library-with-vitejs/
+
+
+
+
+
+Best practices for using trailing commas in JavaScript
+
+
+
+ 长按识别二维码查看原文
+ https://blog.logrocket.com/best-practices-using-trailing-commas-javascript/
+
+
+
+
+
+Synchronous vs Asynchronous JavaScript – Call Stack, Promises, and More
+
+
+
+ 长按识别二维码查看原文
+ https://www.freecodecamp.org/news/synchronous-vs-asynchronous-in-javascript/
+
+
+
+
+
+Exploring the CSS Paint API: Blob Animation
+
+
+
+ 长按识别二维码查看原文
+ https://css-tricks.com/exploring-the-css-paint-api-blob-animation/
+
+
+
+
+
+What’s New With DevTools: Cross-Browser Edition
+
+
+
+ 长按识别二维码查看原文
+ https://www.smashingmagazine.com/2021/09/devtools-cross-browser-edition/
+
+
+
+
+
+React Video Player Component Using Hooks, TypeScript, and xState
+
+
+
+ 长按识别二维码查看原文
+ https://joelhooks.com/react-video-player
+
+
+
+
+
+Bundling non-JavaScript resources
+
+
+
+ 长按识别二维码查看原文
+ https://web.dev/bundling-non-js-resources/
+
+
+
+
+
+How to create Music player with pure HTML, CSS, JS
+
+
+
+ 长按识别二维码查看原文
+ https://dev.to/kunaal438/how-to-create-music-player-with-pure-html-css-js-c1j
+
+
+
+
+
+Create draggable components with React-Draggable
+
+
+
+ 长按识别二维码查看原文
+ https://blog.logrocket.com/create-draggable-components-react-draggable/
+
+
+
+
+
+Infinite scrolling in React with intersection observer
+
+
+
+ 长按识别二维码查看原文
+ https://dev.to/ms_yogii/infinite-scrolling-in-react-with-intersection-observer-22fh
+
+
+
+
+
+Memoizing async functions in Javascript
+
+
+
+ 长按识别二维码查看原文
+ https://dev.to/anishkumar/memoizing-fetch-api-calls-in-javascript-1d16
+
+
+
+
+
+Event Loops in NodeJS – Beginner's Guide to Synchronous and Asynchronous Code
+
+
+
+ 长按识别二维码查看原文
+ https://www.freecodecamp.org/news/nodejs-eventloop-tutorial/
+
+
+
+
+
+JS: All You Can Weak!
+
+
+
+ 长按识别二维码查看原文
+ https://webreflection.medium.com/js-all-you-can-weak-bbe45709b382
+
+
+
+
+
+How to make realtime APIs with NodeJS and ReactJS using Socket.io
+
+
+
+ 长按识别二维码查看原文
+ https://dev.to/omardiaa48/how-to-make-realtime-apis-with-nodejs-and-reactjs-using-socket-io-6ja
+
+
+
+
+
+Understanding JavaScript currying
+
+
+
+ 长按识别二维码查看原文
+ https://blog.logrocket.com/understanding-javascript-currying/
+
+
+
+
+
+Deno on MDN
+
+
+
+ 长按识别二维码查看原文
+ https://deno.com/blog/deno-on-mdn
+
+
+
+
+
+Loading Third-Party JavaScript
+
+
+
+ 长按识别二维码查看原文
+ https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/loading-third-party-javascript
+
+
+
+
+
+JavaScript vs JavaScript. Fight!
+
+
+
+ 长按识别二维码查看原文
+ https://dev.to/this-is-learning/javascript-vs-javascript-fight-53fa
+
+
+
+
+
+Why WebAssembly Frameworks Are the Future of the Web
+
+
+
+ 长按识别二维码查看原文
+ https://www.cloudsavvyit.com/13696/why-webassembly-frameworks-are-the-future-of-the-web/
+
+
+
+
+
+How to Create a Video Player in React
+
+
+
+ 长按识别二维码查看原文
+ https://dev.to/franciscomendes10866/how-to-create-a-video-player-in-react-40jj
+
+
+
+
+
+Algorithms and Data Structures for JavaScript Engineers
+
+
+
+ 长按识别二维码查看原文
+ https://javascript.plainenglish.io/what-i-wish-i-knew-about-algorithms-and-data-structures-applied-to-javascript-aba1c05edac9
+
+
+
+
+
+Simple monorepos via npm workspaces and TypeScript project references
+
+
+
+ 长按识别二维码查看原文
+ https://2ality.com/2021/07/simple-monorepos.html
+
+
+
+
+
+Stay alert
+
+
+
+ 长按识别二维码查看原文
+ https://dev.to/richharris/stay-alert-d
+
+
+
+
+
+Magical Marbles in Three.js
+
+
+
+ 长按识别二维码查看原文
+ https://tympanus.net/codrops/2021/08/02/magical-marbles-in-three-js/
+
+
+
+
+
+UI Design Tactics — Part 1
+
+
+
+ 长按识别二维码查看原文
+ https://blog.prototypr.io/ui-design-tactics-part-1-d82ae4e9d832
+
+
+
+
+
+About Web Components
+
+
+
+ 长按识别二维码查看原文
+ https://webreflection.medium.com/about-web-components-cc3e8b4035b0
+
+
+
+
+
+Creating a Force Graph using React, D3, and PixiJS
+
+
+
+ 长按识别二维码查看原文
+ https://levelup.gitconnected.com/creating-a-force-graph-using-react-d3-and-pixijs-95616051aba
+
+
+
+
+
+How to use finite state machines in React? Explained by a frontend developer
+
+
+
+ 长按识别二维码查看原文
+ https://tsh.io/blog/finite-state-machines-in-react/
+
+
+
+
+
+JavaScript Promises: then(f,f) vs then(f).catch(f)
+
+
+
+ 长按识别二维码查看原文
+ https://dmitripavlutin.com/javascript-promises-then-vs-then-catch/
+
+
+
+
+
+A Guide to Git Interactive Rebase, with Practical Examples
+
+
+
+ 长按识别二维码查看原文
+ https://www.sitepoint.com/git-interactive-rebase-guide/
+
+
+
+
+
+10 Predictions for the Future of Computing or; the Inane Ramblings of our Chief Scientist
+
+
+
+ 长按识别二维码查看原文
+ https://blog.container-solutions.com/10-predictions-for-the-future-of-computing
+
+
+
+
+
+How to stop re-rendering lists in React?
+
+
+
+ 长按识别二维码查看原文
+ https://alexsidorenko.com/blog/react-list-rerender/
+
+
+
+
+
+Faster (and smaller) uploads in Discourse with Rust, WebAssembly and MozJPEG
+
+
+
+ 长按识别二维码查看原文
+ https://blog.discourse.org/2021/07/faster-user-uploads-on-discourse-with-rust-webassembly-and-mozjpeg/
+
+
+
+
+
+4 JavaScript Projects To Build FAST And Get Hired In 1 Month
+
+
+
+ 长按识别二维码查看原文
+ https://dev.to/devpool3000/4-javascript-projects-to-build-fast-and-get-hired-in-1-month-4agf
+
+
+
+
+
+Is Node.js Really Single-Threaded?
+
+
+
+ 长按识别二维码查看原文
+ https://betterprogramming.pub/is-node-js-really-single-threaded-7ea59bcc8d64
+
+
+
+
+
+The Command Pattern in TypeScript — Encapsulating Logic to Increase Maintainability
+
+
+
+ 长按识别二维码查看原文
+ https://blog.bitsrc.io/the-command-pattern-in-typescript-encapsulating-logic-to-increase-maintainability-801cd135f2e6
+
+
+
+
+
+Use Closures for Memory Optimizations in JavaScript (a case study)
+
+
+
+ 长按识别二维码查看原文
+ https://dev.to/ahmedgmurtaza/use-closures-for-memory-optimizations-in-javascript-a-case-study-43h9
+
+
+
+
+
+Using WebAssembly threads from C, C++ and Rust
+
+
+
+ 长按识别二维码查看原文
+ https://web.dev/webassembly-threads/
+
+
+
+
+
+🔥 The data model behind Notion's flexibility
+
+
+
+ 长按识别二维码查看原文
+ https://www.notion.so/blog/data-model-behind-notion
+
+
+
+
+
+How to design a system to scale to your first 100 million users
+
+
+
+ 长按识别二维码查看原文
+ https://levelup.gitconnected.com/how-to-design-a-system-to-scale-to-your-first-100-million-users-4450a2f9703d
+
+
+
+
+
+npm audit: Broken by Design
+
+
+
+ 长按识别二维码查看原文
+ https://overreacted.io/npm-audit-broken-by-design/
+
+
+
+
+
+🔥 Designing a Dataflow Editor with TypeScript and React
+
+
+
+ 长按识别二维码查看原文
+ https://research.protocol.ai/blog/2021/designing-a-dataflow-editor-with-typescript-and-react/
+
+
+
+
+
+Building WebRTC Video Chat Applications
+
+
+
+ 长按识别二维码查看原文
+ https://www.sitepoint.com/building-webrtc-video-chat-applications/
+
+
+
+
+
+Captain Stack — Code suggestion for VSCode - This feature is somewhat similar to Github Copilot's code suggestion. But instead of using AI, it sends your search query to Google, then retrieves StackOverflow answers and autocompletes them for you.
+
+
+
+ 长按识别二维码查看原文
+ https://github.com/hieunc229/copilot-clone
+
+
+
+
+
+Temporal: getting started with JavaScript’s new date time API
+
+
+
+ 长按识别二维码查看原文
+ https://2ality.com/2021/06/temporal-api.html
+
+
+
+
+
+SolidJS Official Release: The long road to 1.0
+
+
+
+ 长按识别二维码查看原文
+ https://dev.to/ryansolid/solidjs-official-release-the-long-road-to-1-0-4ldd
+
+
+
+
+
+Moving Backgrounds: When, Why, and How to Use Them
+
+
+
+ 长按识别二维码查看原文
+ https://www.sitepoint.com/moving-backgrounds-when-why-how
+
+
+
+
+
+🔥 Introduction to Data Types: Static, Dynamic, Strong & Weak - static doesn’t necessarily mean strong and dynamic doesn’t necessarily mean weak
+
+
+
+ 长按识别二维码查看原文
+ https://www.sitepoint.com/typing-versus-dynamic-typing/
+
+
+
+
+
+Understanding Sorting Algorithms
+
+
+
+ 长按识别二维码查看原文
+ https://www.freecodecamp.org/news/understanding-sorting-algorithms/
+
+
+
+
+
+Implementing Private Fields for JavaScript
+
+
+
+ 长按识别二维码查看原文
+ https://hacks.mozilla.org/2021/06/implementing-private-fields-for-javascript/
+
+
+
+
+
+Introducing Utopia - Design ❤️ Code
+
+
+
+ 长按识别二维码查看原文
+ https://utopia.app/
+
+
+
+
+
+New browser APIs to detect JavaScript performance problems in production
+
+
+
+ 长按识别二维码查看原文
+ https://michaelscodingspot.com/javascript-performance-apis/
+
+
+
+
+
+Web3: A New Web for a New World
+
+
+
+ 长按识别二维码查看原文
+ https://www.sitepoint.com/web3-new-web-new-world/?utm_medium=email&utm_campaign=spw-28&utm_source=sitepoint-weekly
+
+
+
+
+
+Intro to Asynchronous JavaScript
+
+
+
+ 长按识别二维码查看原文
+ https://dev.to/mehmehmehlol/intro-to-asynchronous-javascript-g9e
+
+
+
+
+
+What is Vite and how to use it with React
+
+
+
+ 长按识别二维码查看原文
+ https://naruhodo.dev/what-is-vite-and-how-to-use-it-with-react/
+
+
+
+
+
+
+
Rust
+
+
GitHub
+
+
VS Code
+
+
+
+
+
diff --git a/posts/issues-0054/index.html b/posts/issues-0054/index.html
new file mode 100644
index 0000000..ae70ca2
--- /dev/null
+++ b/posts/issues-0054/index.html
@@ -0,0 +1,227 @@
+
+
+
+
+
+
+
+
+微信杂谈 - 造轮子
+
+
📅 2021.07.19
+
少年:
+前端东西太多了
+
少年:
+学不完的呀
+
你好,浦原:
+是啊!
+
少年:
+集体转后端?
+
Shine.:
+[苦涩]后端更难
+
安木~🍄:
+后端也多[捂脸]
+
少年:
+后端知识比较固定吧
+
lencx:
+后端天花板高,感觉可以比前端走的更远
+
少年:
+是呀
+
少年:
+前端这些造轮子的
+
lencx:
+前端轮子太多了
+
lencx:
+感觉没必要什么都学,了解就够了
+
安木~🍄:
+怎样才能达到造轮子的水平[捂脸]
+
lencx:
+随时都可以,轮子有大有小
+
周哈哈.:
+天呐 你居然想造轮子
+
少年:
+去一家公司面试就问React、vue 从生命周期问道源码 在问到实战 在问到html +5 css +3 再问问你懂不懂构建 再问你懂不懂优化 再问你懂不懂后端
+
安木~🍄:
+比如小到那种?
+
安木~🍄:
+对呀 只有慢慢的去接触新东西 才能成长
+
lencx:
+凡是可以用代码解决的东西都可以用程序去解决
+
周哈哈.:
+不错
+
lencx:
+然后就会发现可以做很多东西
+
安木~🍄:
+鑫哥 我没太明白这个意思
+
安木~🍄:
+代码能解决的东西 都可以用程序去解决?[捂脸][捂脸]
+
lencx:
+额、就是用程序去解放自己
+
lencx:
+实现自动化
+
lencx:
+然后往这个方向思考,去写程序
+
安木~🍄:
+你是说 只要是互联网上的软件方面的东西 都可以用代码去实现嘛
+
安木~🍄:
+哦哦 这样呀
+
安木~🍄:
+相当于是怎么用代码来给自己提供便利对吧
+
lencx:
+代码指编程,不限于语言
+
lencx:
+差不多就是这个意思
+
lencx:
+前端工具链不就是为了解放生产力吗
+
安木~🍄:
+听你这么说
+
安木~🍄:
+好像还真是
+
安木~🍄:
+[捂脸][捂脸][捂脸]
+
lencx:
+一个道理,写不了工具链,可以写小工具,小工具多了,就可以做聚合
+
lencx:
+思维的转变很重要,不是会不会的问题,而是有些人觉得,非要搞一个很牛逼的东西才算造轮子,其实并非是这样的,可以解放你部分时间的东西都是值得的
+
安木~🍄:
+嗦嘎
+
kk德米安:
+[强]
+
安木~🍄:
+你会不会就是说 知识受限 然后局限了你的思维 没发去产出小轮子呢
+
lencx:
+知识受限还不是主要因素,因为如果只是知识受限,可以通过读书查资料去弥补,更多的是去发现问题,这个不是靠读书就可以解决的
+
Shine.:
+我还是感觉js
+
Shine.:
+重要
+
lencx:
+要培养发现问题,提出问题的能力,能提出一个好的问题也是能力的一部分,我个人觉得
+
安木~🍄:
+要怎么去培养这种发现问题的能力呢[捂脸][捂脸]
+
安木~🍄:
+我感觉 我可能就是缺乏你说的这种思考
+
安木~🍄:
+我的开发都只限于公司业务需求
+
安木~🍄:
+貌似也没有主动精进过说 会思考怎么去提升生产力 或者 发现有什么好的方式可以提升生产力[捂脸]
+
lencx:
+说难也不难,就是不要只是站在开发的角度去思考问题,因为程序和市场是脱节的,所以开阔视野很重要
+
安木~🍄:
+说的有道理
+
安木~🍄:
+眼光不要局限对吧
+
lencx:
+举个简单例子:站在开发角度,我完成这次需求就ok了;站在产品角度,用户体验很重要;站在老板角度,节约成本很重要。
+
安木~🍄:
+不能为了业务开发而来发了[捂脸]
+
lencx:
+所以我们要做的,就是尽可能的最大化自己的价值,而不是把自己局限于某一个环节
+
安木~🍄:
+这么说 貌似明白一点了
+
lencx:
+不然的话就成了一颗螺丝钉
+
安木~🍄:
+相当于以前做的就只是完成需求
+
安木~🍄:
+对的 我现在感觉我就是颗螺丝钉
+
lencx:
+程序来源于需求,需求来源于生活之中的痛点,所以我们写代码也一样,要透过需求看本质,即代码是为了解决痛点而存在的,而不是靠想象,我想做什么就做什么,技术不能够落地的因素是多方面的,如果不能够实际去解决一些问题,即使落地了也没啥意义。
+
参考资料
+
+
+
+
diff --git a/posts/issues-0055/index.html b/posts/issues-0055/index.html
new file mode 100644
index 0000000..657e8c7
--- /dev/null
+++ b/posts/issues-0055/index.html
@@ -0,0 +1,141 @@
+
+
+
+
+
+
+
+
+微信杂谈 - 技术迷茫期
+
+
📅 2020.09.08
+
lencx:
+你好,我平时不会打扰您的,我有一个问题想问问您,我其实现在感觉自己挺迷茫的,我是做前端开发的,前端技术也没有做的专精,杂七杂八的东西倒是接触了不少,有种什么都想学,却又能力不够,我是不是该在前端领域让自己沉下去或者在某个细分领域钻研下去?这么问您,我也知道您不一定能给出答案,毕竟每个人都有自己选择,我想知道学新技术都会有这种焦虑吗?或者您有什么经验可以分享,谢谢
+
Jason Yu 于航:
+你好 其实很多人都有这种焦虑哈 也包括我在内。从我的角度来看,可能更建议专注于某个方向去深入,做到一专多能。多能就是要认知广泛,各类技术都知道,但不用很深入,很详细,但可以把握程度,当需要用的时候可以快速去了解。而一专就是要深入到一种程度,这种程度是别人无法花几天就能够补得上的那种。当然,一专的方向可以遵循“一看兴趣、二看行业、三看收入”的顺序来选择。你说的杂七杂八可能是碎片化的知识,建议可以从完整看完几本书开始做起,当有了一个面之后,可能会更容易找到兴趣点。不知道这个回答是否可以帮到你哈
+
lencx:
+嗯嗯,谢谢
+
lencx:
+我是自学过来的,所以就导致了什么都想去了解一些,因为不知道需要什么,或者什么是好的技术,该如何去选择,就想不断的扩大自己的知识面。知识不成体系,碎片化
+
lencx:
+谢谢,其实我知道自己的不足,最近也在补一些基础知识
+
Jason Yu 于航:
+嗯嗯 完全可以理解 碎片化的知识是可有的 但基础的体系一定要牢固 比如就前端而言就是从js语言本身开始到各类web api,再到web框架、工程化等等。基础的部分打牢后就可以往细分领域拓展,比如serverless,可视化,nodejs等等
+
lencx:
+嗯嗯,我的学历也是硬伤,我只有大专学历,而且非科班出身
+
Jason Yu 于航:
+不用太在意学历 尤其是互联网技术这种更看重经验的工作
+
Jason Yu 于航:
+非科班出班的厉害的有很多呀
+
lencx:
+最近好多猎头问找不找工作,字节,阿里之类的,我一说大专学历,都说没机会了
+
Jason Yu 于航:
+是的 最近这段时间国内内卷比较严重 不过如果你有一些自己的积累 比如个人项目之类的 学历就不会成为问题了
+
lencx:
+嗯嗯,我之前是不太确定能力是否可以弥补学历的不足,听了您的话,感觉还是有希望的
+
Jason Yu 于航:
+换位思考 你要是hr 一堆简历如果本身没有太多出彩的地方 就只能从学历来筛选了
+
Jason Yu 于航:
+嗯嗯 放心吧 学历绝对不是问题
+
lencx:
+嗯嗯,谢谢啦
+
Jason Yu 于航:
+不客气哈
+
参考资料
+
+
+
+
diff --git a/posts/issues-0057/index.html b/posts/issues-0057/index.html
new file mode 100644
index 0000000..fd062aa
--- /dev/null
+++ b/posts/issues-0057/index.html
@@ -0,0 +1,231 @@
+
+
+
+
+
+
+
+
+微信杂谈 - 技术广度 & 深度
+
+
📅 2021.07.01
+
Shawn:
+问大家一个问题:学习广度和深度的问题,先深后广还是先广后深,阈值是多大。
+
telescope:
+先深后广
+
Shawn:
+深的阈值
+
安木~🍄:
+先深度吗
+
lencx:
+也就是吃饭的家伙要够硬
+
Leanode:
+我觉得收入 取决于做技术的高度
+
🍉:
+谈论学习深度阈值之前你要先能量化你的学习深度啊
+
🍉:
+不然还是完全主观
+
Leanode:
+一专 是理想状态
+
lencx:
+理想状态是,都要[捂脸]
+
Leanode:
+知其然知其所以然 算深度吗
+
Mr.Black:
+我感觉深度重要,要在一个领域做到别人无法替代。
+
Leanode:
+目前我个人的阶段 感觉是工厂能力的好坏和解决问题的速度和解决问题的方式是否最优 可能是我认为的需要掌握的
+
Leanode:
+在一个领域无法代替有点抽象
+
南蓝:
+那么问题来了,不知道选择哪块去深究
+
Leanode:
+目前应用层技术都像一个洋葱一样被扒开来
+
lencx:
+在我看来,其实知识技术并不是割裂状态,可以在深入的同时,去发散,比如一个问题会引申一个新的问题。只需要把握好引申的范围就好,知识是网状的。
+
Shawn:
+我觉得这个问题比较随缘吧、
+
Shawn:
+研究的方向一是来源于自己的兴趣,二是来源于目前就职公司的业务。
+
lencx:
+准确来说是螺旋式上升,跟龙卷风🌪️一样,越卷越大
+
Shawn:
+比如公司项目用的是vue,然后你要研究 react
+
Shawn:
+赞 +1
+
安木~🍄:
+深入的点怎么去找呀
+
安木~🍄:
+完全就是不知道从何下手
+
lencx:
+如果以赚钱为目的,就是以企业要求去深入
+
安木~🍄:
+从那个点突破进去然后发散
+
lencx:
+以兴趣为目的,就看个人了
+
安木~🍄:
+[破涕为笑]这个感觉有点笼统
+
南蓝:
+估计我现在只能以赚钱为目的了...
+
lencx:
+比如公司用 react,就从 react 深入,发散
+
安木~🍄:
+概念很大
+
Shawn:
+对。
+
安木~🍄:
+深入是只去研究高深的逻辑和底层源码实现吗
+
Shawn:
+设计模式,整体架构
+
Leanode:
+如何深入react呢
+
Shawn:
+我的方法就是,买课看视频,
+
宿愿Cc:
+对
+
lencx:
+react -> 会用 -> 对生态有些一了解 -> 尝试去给生态做贡献 -> 要贡献,就需要更深层次的理解 -> 可能就会涉及到 react 的原理,源码
+
宿愿Cc:
+我自己在读源码的过程中,有很多地方都是一知半解
+
Shawn:
+我最开始看源码,打 debug ,越打越多,一个点深入进去我就迷失方向了,所以买课,看看视频
+
lencx:
+对知识点的学习,肯定是有其背景的,而不是盲目去学
+
lencx:
+有痛点,才会去创造
+
安木~🍄:
+买源码讲解视频吗
+
安木~🍄:
+我感觉我现在就是盲目的学
+
安木~🍄:
+啥都是只会点皮毛
+
lencx:
+学习也是这样,遇到问题了,才会去了解问题,解决问题,解决问题就分为单纯解决问题,和问题发散了,没什么追求的,解决完问题,就算完事了,有追求的,就会打破砂锅问到底,这就是延伸
+
Shawn:
+对技术充满好奇
+
lencx:
+就比如我写的 vite 插件,我的最初目的不是阅读 vite 源码,但是为了实现插件功能,迫不得已,就阅读了源码,因为你不读源码,插件机制,内部 API 都不熟悉
+
DeepKolos (DeepKolos):
+我感觉读源码,需要面对的问题是,这样的设计解决了什么问题,如果解决相同问题,你会怎么解决,目前的解法有哪些潜在缺陷
+
hello:
+我觉得。一切以实际业务为主 再去发散技术
+
DeepKolos (DeepKolos):
+lazy-gltf-loader的开发我就发现blender的gltf exporter 纹理复用有问题
+
宿愿Cc:
+然而我们业务很近,没有时间。。。
+
Shawn:
+我的建议是。vue 使用过一段时间再去看,否则这个教程会让你放弃研究 vue 源码。
+
DeepKolos (DeepKolos):
+gltf-gpu-compressed-texture就发现zstd decoder是在UI线程decode,没有worker
+
lencx:
+这样看你想成为什么样的人,时间是可以挤出来的,比如坐地铁的时间,走路也可以去思考一些问题,有时候代码并不是需要写的,更多的是在大脑中的思考。大脑其实就是一台计算机
+
hello:
+我就是。一开始搞不清渲染底层。于是看了 opengl。 一直搞不清开发三维怎么写好代码。于是看了一本书。还看了u3d的开发思路 于是现在也算能模拟u3d开发自己的三维项目了
+
DeepKolos (DeepKolos):
+还是有需求读源码好
+
Mr.Black:
+一些底层的东西还是要了解一下,有时候原理不知道,单纯会用,就会写出乱七八糟的代码。
+
DeepKolos (DeepKolos):
+封装本来就是为了让你不需要知道里面怎么实现就可以完成功能
+
Shawn:
+会让你定位 bug 更精准
+
hello:
+以前写三维代码。只能达到demo级别。 代码量上来。 维护性和可持续行 根本扛不住。现在代码从模块和组件开发思维。 目前还没遇到扛不住的情况
+
参考资料
+
+
+
+
diff --git a/posts/issues-0061/index.html b/posts/issues-0061/index.html
new file mode 100644
index 0000000..e416824
--- /dev/null
+++ b/posts/issues-0061/index.html
@@ -0,0 +1,251 @@
+
+
+
+
+
+
+
+
+微信杂谈 - 技术栈
+
+
📅 2021.07.30
+
易潇:
+大佬们可以聊聊 选前端还是后端吗
+现在在选组 有两个 都是全栈 但一个偏前端 一个偏后端
+可以聊聊不同方向的职业成长路线 或者 哪里可以了解到这些方向的职业成长路线吗
+感谢~
+
小和尚:
+喜欢啥就选啥
+
lencx:
+技术方向做到后面可以自由切换的吧,我也觉得喜欢什么就选什么没错
+
小和尚:
+我都写过[苦涩]但我不喜欢后端
+
:
+全栈吧,一般大佬,前后端运维都会,样样精通。
+
lencx:
+我感觉最大的区别就是要积累的东西经验,是不一样的,这个需要花时间
+
小和尚:
+我是觉得后端做的事情,我并不是很感兴趣
+
小和尚:
+如果只是做接口写服务,其实还好
+
小和尚:
+但是如果搞docker,k8s,我就很怂
+
lencx:
+如果让我选,我可能会选全干,可惜能力不够[旺柴]
+
小和尚:
+如果不涉及这些,我早就全干过了
+
小和尚:
+但是后来明显的弱爆了,尤其是当我想搞tripworker的时候
+
小和尚:
+因为后端现在比较流行的架构就是serverless
+
小和尚:
+要么,跑wasm,要么,搞一些fass啥的
+
小和尚:
+他们在v8上跑wasm很舒服,支持多种语言的serverless
+
lencx:
+学习其实就是循序渐进,不断扩宽知识面,我刚开始只会 html,css,现在会写点 js 了,如果想继续深入,可以学其他语言技术,我觉得语言不是限制自己的条件,时间才是。
+
lencx:
+我最近也很焦虑,感觉什么都学不进去了
+
lencx:
+知识它就是不进脑子,一看东西就烦躁
+
小和尚:
+所以我从来不看知识
+
小和尚:
+我基本上不看基础的东西,上来就写代码,写不对就改
+
小和尚:
+慢慢的,很多年后,基础也就都理解了
+
lencx:
+还是解决问题吧,遇到问题就学习
+
lencx:
+从解决问题中学习
+
小和尚:
+我会积累一些东西,但仅仅只是多看一眼
+
云谦:
+@🐶 - 0 - 易潇 我理解的前端:离用户近,多终端支持和兼容,交互多,技术深度相比后端浅,普通业务话语权没后端大(富交互业务除外),竞争压力相比后端小一些?,主 JavaScript 语言,开源社区活跃。然后就看自己选了。
+
另外,长远看,前端的深度到 p8 p9 还好,再往前走会比较困难,后端则可以走地更远。
+
易潇:
+弱弱的问为什么后端技术深度高但是竞争更高?正常不应该是技术壁垒低的地方初级的竞争更激烈吗,比如说做销售
+
永远八岁:
+因为前端的概念,是这几年才有的。
+
🇨🇳 Promise:
+我的理解是基数大
+
lencx:
+是因为普通java烂大街吧
+
永远八岁:
+前10年那些人,都是去搞后端的
+
Mr.Black:
+后端学校有教,前端大部分都是自己学的。
+
🇨🇳 Promise:
+现在基本本科java 考研python
+
🇨🇳 Promise:
+出来学学框架就可以了
+
永远八岁:
+这就导致大环境(包括老师、资深开发者)认为后端才是真正的敲代码的,前端都是闹着玩的
+
🇨🇳 Promise:
+我个人觉得是 谁离数据源更近,谁更具有话语权
+
永远八岁:
+我倒是觉得前端比后端更难,从现在来说
+
永远八岁:
+后端已经太久没变化了。
+
永远八岁:
+前端从 生命周期 -> hooks,这是发生了翻天覆地的变化。
+
永远八岁:
+写页面时考虑已经变了。
+
永远八岁:
+就像是当年栅格布局一样。即使Bootstrap没人用了(包括react),但是他们的思想会推动整个前端继续发展下去,影响深远。
+
永远八岁:
+能思考出 生命周期 -> hooks 这个想法的人和团队,我认为这才是真的强的人。
+
永远八岁:
+那后端已经很久没有这种大的翻天覆地的东西了。
+
易潇:
+大家对选择 大的,已经很成熟的组 vs 小的,做什么不用跟那么多组沟通,但是scope也小的组;有啥建议吗
+
🇨🇳 Promise:
+其实是不是也意味着后端思想很多的时候已经在当下环境下已经穷尽了大多数的方案和技术,更新的只是末节
+
Mr. 🍊:
+从jq到react都算是翻天覆地的变化的[旺柴]
+
🇨🇳 Promise:
+而前端作为新的产物,还是在一个快速生长的时期
+
永远八岁:
+是的,大多数都是在框架以下,延伸工具链
+
小和尚:
+前端不只是web啊
+
永远八岁:
+jq->react 这是一定的。因为那时候大家已经认识到jq的缺陷了
+
永远八岁:
+show 一个组件,写一大片模版。
+
小和尚:
+前端框架这种纯web的东西其实和前端架构没什么关系的,除非你写组件库
+
永远八岁:
+只不过缺一个有担当团队做出来。
+
lencx:
+react 肯定也不会是结局
+
阿西吧~~~:
+大多数公司都是这个状态。你有钱了,可以不工作,用你会的技术实现你自己的想法。当你出结果的时候,你就是意识形态
+
永远八岁:
+react属于时势造英雄
+
lencx:
+我觉得技术的核心,还是产品吧,是场景孕育出技术的
+
永远八岁:
+但是 react hook 可就是纯思维啦。
+
永远八岁:
+产品是挣钱的。挣了钱满足物质,才有精力想继续发展技术。
+
永远八岁:
+场景我觉得只能孕育链路。
+
🇨🇳 Promise:
+赞同, 产品的思想是0-1的过程,是始端
+
永远八岁:
+比如 抢购场景。只能孕育这条线的流程。不会产生出伟大的思想来。
+
🇨🇳 Promise:
+我感觉多年以来思想没有变,变得只有方式
+
lencx:
+比如现在的场景是lot,如果没有相关技术来实现,就会出现一些新技术,用来解决场景中的一些需求痛点吧,我是这么理解的。但是技术的发展需要有理论作支撑,所以这又是一个演化创造的过程
+
🇨🇳 Promise:
+例如卡兰尼克创立了uber,还是打车业务,只不过方式更加的适应现代化
+
永远八岁:
+是的,你说的,正是我的想法。
+
永远八岁:
+并不是redis支撑了抢购,不是redis多厉害,而是人们需要他。
+
永远八岁:
+但是他的本质就是一个db
+
永远八岁:
+db人们研究了几个世纪了,所以拿着这个思想来做个redis,肯定是简单许多的。
+
🇨🇳 Promise:
+今天的分享,干货满满啊,👍
+
参考资料
+
+
+
+
diff --git a/posts/issues-0066/index.html b/posts/issues-0066/index.html
new file mode 100644
index 0000000..d0cf837
--- /dev/null
+++ b/posts/issues-0066/index.html
@@ -0,0 +1,184 @@
+
+
+
+
+
+
+
+
+开源 - 原创打卡
+
+
+我发起了一个原创写作计划,通过开源打卡的形式来相互监督。
+
+
目前计划刚刚启动,还有很多地方需要完善,如果有感兴趣的朋友,欢迎参与。
+
仓库:zkuhut/monthly[1]
+网站:臻苦舍月刊[2]
+
有两种参与方式,选择其中一种即可:
+
+关注公众号:浮之静
,回复 开源打卡
+Fork
仓库,提交 PR
,可参考 怎样贡献一篇文章?[3]
+
+
关于
+
zkuhut
:臻(z)苦(ku)舍(hut)
+臻,至也;苦,始也。
- 谐音 真苦
,想要到达高的,完美的(臻),一切只是刚刚开始(苦)。
+
背景
+
在信息爆炸的时代,我们最缺的不是如何获取信息,有价值的信息沉淀下来才是真正的知识。我们每个人都会阅读,思考,但是要把这些思考想法输出的人似乎并没有想象中那么多。
+
人都是有惰性的,会因为种种原因而放弃自己的一些计划或目标,三分钟热度。此次发起学习小组,就是想基于 GitHub 来进行协作监督,记录自己。
+
很多人,包括我自己都会有这样的困惑:
+
+我很菜,不知道该写点什么。
+我会的东西那么简单,写出来会不会被别人笑话。
+我想写的东西似乎很多人都写过了,还有必要自己写吗?
+
+
对此我想谈谈自己对于有价值信息的理解。输出文章是为了记录,梳理,引发一些思考及观点。其次才是分享(别太高看自己,你写的东西没几个人会看到的)。用最直白的语言讲清楚一件事或一个东西,就是有价值的信息。
+
技术栈
+
写作平台
+
现在的写作形式就那么几种:
+
+第三方平台
+
+国内:知乎
,掘金
,公众号
,简书
,CSDN
等
+国外:dev.to
,medium
等
+
+
+自建博客
+
+自己搭建服务器
+基于 GitHub
,Gitee
的 pages
搭建网站
+
+
+云笔记:Notion
,有道云笔记
等
+
+
方案确定
+
最终选择 GitHub 作为代码及文章托管平台,vitepress[4] + github actions[5] + github pages[6] + giscus[7] 构建网站。原因有以下几点:
+
+多人协作
+不受平台制约
+github + git 常用操作学习
+github actions 自动执行一些脚本或发布任务
+方便进行扩展及二次开发
+
+
不过缺点也十分明显,就是无法通过平台引流。不过其目标为了记录自己,所以这个缺点可以忽略不计。
+
身为一名程序员,如果不会使用 GitHub,不能够在全球最大的同性交友网站畅游与学习,我认为不是一名合格的程序员。而参与项目就是最好的学习。
+
写作环境
+
+Node.js
- 基于 vitepress 搭建
+GitHub
- 用于多人协作
+zkuhut
- 加入 GitHub 组织(非必需)
+
+
写作要求
+
+✅ 人/月至少输出一篇原创,坚持下来的,欢迎申请加入 zkuhut
组织
+✅ 内容不限,技术,思考,新技术尝试等皆可
+✅ 严谨性,专业术语,相关资源要有出处
+🚫 打广告,卖课
+🚫 搬运,抄袭
+
+
微信群
+
[8]
+
参考资料 [1] zkuhut/monthly: https://github.com/zkuhut/monthly
+[2] 臻苦舍月刊: https://zkuhut.github.io/monthly/
+[3] 怎样贡献一篇文章?: https://zkuhut.github.io/monthly/lencx/general/how-to-start-monthly/
+[4] vitepress: https://vitepress.vuejs.org/
+[5] github actions: https://docs.github.com/en/actions/learn-github-actions/workflow-syntax-for-github-actions
+[6] github pages: https://pages.github.com/
+[7] giscus: https://giscus.app/
+[8] : https://user-images.githubusercontent.com/16164244/143778088-eda0b390-4846-41f5-9e7d-522f73254c88.JPG
+
+
+
+
diff --git a/posts/issues-0068/index.html b/posts/issues-0068/index.html
new file mode 100644
index 0000000..52086e8
--- /dev/null
+++ b/posts/issues-0068/index.html
@@ -0,0 +1,172 @@
+
+
+
+
+
+
+
+
+基于 GitHub Discussions 的 Blog 框架
+
+
我是一个喜欢折腾的人,虽然文章没写几篇,但是 Blog 框架没少折腾,刚入行那会用蹩脚的前端技术自己实现,就感觉越花哨,越能证明自己的实力,各种大投影,大圆角,奇怪的字体... 随着认知的提升,懂得了内容才是核心,页面开始变得不那么花哨,使用 Hexo[1] ,Gatsby[2] ,自己实现 nofwl 主题[3] 。再到后来的 vuepress[4] , vitepress[5] 和 mdBook[6] 。全都被我换了一遍,总是感觉不合自己胃口,于是就萌生了自己写 Blog 框架的想法。
+
需求背景
+
我想做的 Blog 框架满足以下条件:
+
+实时性
- 可以随时随地编辑,与平台无关,同时支持手机,电脑,本地,在线编辑等
+所有权
- 我对数据的权限越大越好,这样我就可以根据自己的需要去渲染页面模版
+公众号
- 可以生成微信公众号文章(微信链接不支持跳转,需要生成脚注或二维码)
+RSS
- 支持 RSS 订阅
+
+
技术栈
+
Blog 框架的搭建本身也是学习的过程,技术栈一定要前沿,因为我喜欢折腾。结合上面的需求背景,经过多方面比较,最终选择了 GitHub Discussions
作为数据源。vite + react
作为 Blog 基本框架。
+
最终用到的技术包含:
+
+github discussions api[7] - 文章数据源,因为是接口请求,所以可以满足文章实时性及数据所有权需求
+github actions[8] - 执行定时任务(生成 RSS 文件,JSON 数据文件,微信文章等),及网站部署
+scripts
- 定时任务需要执行的脚本命令,用来满足公众号文章及 RSS 需求
+
+rgd[9] - 🍱 GitHub Discussions API - RSS & JSON
+woap[10] - 🌀 GitHub Discussions 生成微信文章 (支持二维码及脚注形式)
+
+
+@apollo/client[11] - 是一个 JavaScript 状态管理库,能够使用 GraphQL 管理本地和远程数据。使用它来获取、缓存和修改应用程序数据,同时自动更新 UI。
+vite[12] - 下一代前端开发与构建工具
+react[13] - 用于构建用户界面的 JavaScript 库
+recoil[14] - React 状态管理库
+
+
常见问题
+
关于 Github Token
+
Blog 需要满足任何人在不经过 GitHub 登陆,或授权就可以访问网页,所以需要提供公共 Token
来请求数据。因为 GitHub Token[15] 存在每小时接口请求次数限制,超出请求次数会报错。官方文档建议缓存接口请求,但是整个 Blog 托管于 GitHub Pages[16] ,并不能缓存接口请求。
+
解决方案
+
使用 rgd
将接口数据生成 JSON 文件。当网站请求 GitHub API 超过次数限制,会自动降级请求部署后项目中的 json 文件。同时支持两种模式是因为:请求接口网站是实时的(体验效果好),请求的 json 文件是非实时(每天跑一次定时任务)。
+
关于 RSS
+
使用 rgd
生成 RSS 文件,每天执行一次定时任务(非实时)。
+
关于公众号
+
使用 woap
生成微信文章,每天执行一次定时任务(非实时)。Discussions
标签满足 woap
的标签规则就会将该文生成为微信文章。
+
标签规则
+
+wechat-link
- 微信链接转为二维码,适合多链接场景
+wechat-post
- 微信链接转为脚注,适合多文字场景
+
+
更多使用规则请查看 woap 参数[17] 。
+
关于项目
+
+查看源码 - https://github.com/lencx/z[18]
+网站体验 - https://lencx.tech[19]
+
+
参考资料 [1] Hexo: https://hexo.io/
+[2] Gatsby: https://www.gatsbyjs.com/
+[3] nofwl 主题: https://github.com/lencx/nofwl
+[4] vuepress: https://vuepress.vuejs.org/
+[5] vitepress: https://vitepress.vuejs.org/
+[6] mdBook: https://github.com/rust-lang/mdBook
+[7] github discussions api: https://docs.github.com/en/graphql/guides/using-the-graphql-api-for-discussions
+[8] github actions: https://github.com/features/actions
+[9] rgd: https://github.com/lencx/rgd
+[10] woap: https://github.com/lencx/woap
+[11] @apollo/client: https://www.apollographql.com/docs/react/
+[12] vite: https://vitejs.dev/
+[13] react: https://reactjs.org/
+[14] recoil: https://recoiljs.org/
+[15] GitHub Token: https://docs.github.com/cn/github/authenticating-to-github/keeping-your-account-and-data-secure/creating-a-personal-access-token
+[16] GitHub Pages: https://pages.github.com/
+[17] woap 参数: https://github.com/lencx/woap#%E5%8F%82%E6%95%B0
+[18] https://github.com/lencx/z: https://github.com/lencx/z
+[19] https://lencx.tech: https://lencx.tech
+
+
+
+
diff --git a/posts/issues-0070/index.html b/posts/issues-0070/index.html
new file mode 100644
index 0000000..0b6e134
--- /dev/null
+++ b/posts/issues-0070/index.html
@@ -0,0 +1,170 @@
+
+
+
+
+
+
+
+
+解决问题之经验篇
+
+
+问题不可能被穷举,答案经验有时候并不足以让我们应付千奇百怪的问题。在题海中,培养自己分析,定位,解决问题的能力似乎才是我们唯一的出路(以不变应万变)。
+
+
一般问题解决步骤:
+
+遇到问题
(不要慌)
+
+这个问题没见过,咋搞呀
+我正好有个技术群,丢个报错截图去问问
+...
+
+
+分析问题
(抽丝剥茧)
+
+多问自己为什么,从问题报错处,排除干扰,向上 debugger
+小黄鸭调试法[1] - 小黄鸭调试法,又称橡皮鸭调试法、黄鸭除虫法(Rubber Duck Debugging)是可在软件工程中使用的一种调试代码的方法。方法就是在程序的调试或测试过程中,操作人耐心地向小黄鸭解释每一行程序的作用,以此来激发灵感与发现矛盾
+
+
+描述问题
(提取关键词)
+
+清楚表达问题
- 很重要,直接影响到后面的关键词提取
+关键词转英文
- 推荐两个翻译网站 Google 翻译[2] 和 Deepl[3]
+
+
+关键词搜索
(中,英文)
+
+中文
- 国内太卷,抄袭严重,问题没有出处。除非是特定问题(微信小程序之类的问题),否则不建议使用中文搜索
+英文
- 质量要高很多,推荐使用 Google[4] 搜索,替代品 Bing[5] 搜索
+
+
+解决问题
(总结经验)
+
+反思总结
- 沉淀是为了让自己能够举一反三
+分享经验
- 表达是为了进一步加深理解
+
+
+
+
如果以上步骤无法解决问题,向别人请教之前,以下几点是必须要做的:
+
+看官方文档
(重要的事情说三遍)
+开源库或框架遇到问题,逛社区
(别偷懒) - issues[6] ,discussions[7] ,stack overflow[8] 必看
+问题仍无法解决,则需剥离业务逻辑,提供最小复现用例
(节约彼此时间)- 别人未遇到过的问题,并不能靠空想解答,即使可以,也不建议进行这样的试探
+
+
如果以上步骤都做了,仍然无法解决问题,则可以在项目 issues
或 stack overflow
等问题社区发起提问:
+
+问题描述
- 简洁清楚的表达问题,切记啰嗦
+环境信息
- 问题发生的环境(系统信息,软件版本,浏览器版本等)
+如何复现
- 提供问题复现步骤 1,2,3,可以配合适当的错误截图及说明
+
+复现用例
- 用例要排除业务干扰,缩小问题范围
+我的尝试
- 自己做过哪些尝试,也可以让别人快速排除一些干扰项
+
+
+预期结果
- 希望得到什么样的结果
+
+
参考资料 [1] 小黄鸭调试法: https://zh.wikipedia.org/wiki/%E5%B0%8F%E9%BB%84%E9%B8%AD%E8%B0%83%E8%AF%95%E6%B3%95
+[2] Google 翻译: https://translate.google.cn/
+[3] Deepl: https://www.deepl.com/
+[4] Google: https://www.google.com/
+[5] Bing: https://www.bing.com/
+[6] issues: https://guides.github.com/features/issues/
+[7] discussions: https://docs.github.com/en/discussions
+[8] stack overflow: https://stackoverflow.com/
+
+
+
+
diff --git a/posts/issues-0072/index.html b/posts/issues-0072/index.html
new file mode 100644
index 0000000..10c3850
--- /dev/null
+++ b/posts/issues-0072/index.html
@@ -0,0 +1,400 @@
+
+
+
+
+
+
+
+
+滚动进度条
+
+
+学习框架语言,写代码是最快的入门方式。为了给基于 vitepress
构建的 Blog 新增功能,现学 Vue3
,诞生了下面的进度条组件。
+
+
体验地址[1] - 手写 Code Snippets 系列
+
创建一个进度条,用来指示页面滚动百分比,主要有两点注意事项及一个思考:
+
+使用 position: fixed
将滚动进度条置于页面顶部,z-index
设置一个较大的值是为了保证元素在页面内容的最上层。
+使用 EventTarget.addEventListener
和 Element.scrollTop
来确定文档的滚动百分比并将其设置为滚动进度条的宽度。
+思考 - 如果页面容器高度发生变化,会发生什么?
+
+
💠 核心
+
< div id ="scroll_progress_bar "> </ div >
+
# scroll_progress_bar {
+ position : fixed;
+ top : 0 ;
+ width : 0% ;
+ height : 4px ;
+ background : # 7983ff ;
+ z-index : 10000 ;
+}
+
const scrollProgress = document . getElementById ( 'scroll_progress_bar' ) ;
+// 滚动条高度
+const height = document . documentElement . scrollHeight - document . documentElement . clientHeight ;
+
+window . addEventListener ( 'scroll' , ( ) => {
+ const scrollTop = document . body . scrollTop || document . documentElement . scrollTop ;
+ // 当前进度条进度 = 当前滚动条位置 / 滚动条高度
+ scrollProgress . style . width = `${ ( scrollTop / height ) * 100 } %` ;
+} ) ;
+
✍️ 实现
+
🔶 Vue3
+
<!-- ScrollProgress.vue -->
+
+<script setup lang =" ts" >
+import { ref , onMounted , onUnmounted } from ' vue'
+
+// 在 `<script setup>` 标签下要使用 `props`,则需要使用 `defineProps` 进行声明
+const props = defineProps ({
+ // 滚动容器 - 如果容器高度会发生变化,则需要对其进行监听,否则会滚动进度会出现计算误差
+ root: {
+ type: String ,
+ default: ' #app' ,
+ required: false ,
+ },
+ // 滚动条的高度
+ height: {
+ type: String ,
+ default: ' 4px' ,
+ required: false ,
+ },
+ // 滚动条颜色
+ theme: {
+ type: String ,
+ default: ' #3eaf7c' ,
+ required: false ,
+ validator : (v : string ) => {
+ document .head .style .color = v
+ const q = document .head .style .color
+ document .head .style .color = ' '
+ return !! q
+ },
+ },
+ // 滚动条放置的位置:顶部或底部
+ placement: {
+ type: String ,
+ default: ' top' ,
+ required: false ,
+ validator : (v : string ) => {
+ if (! [' top' , ' bottom' ].includes (v )) {
+ console .error (` [ScrollProgress(placement)] The value must match one of these strings: 'top' | 'bottom' ` )
+ return false
+ }
+ return true
+ },
+ },
+ // 滚动条在页面中的层级
+ zIndex: {
+ type: [Number , String ],
+ default: 10000 ,
+ required: false ,
+ validator : (v : string ) => / ^ -? [\d ] + $ / .test (v ),
+ },
+})
+
+const el = ref (null )
+const appHeight = ref (0 )
+
+// 为了避免进度条因页面容器高度变化导致计算偏差,需要对页面容器进行监听,动态获取其高度
+onMounted (() => {
+ // 需要观察变动的节点
+ const targetNode = document .querySelector (props .root )
+ if (! targetNode ) return console .error (` [ScrollProgress(root)] '${props .root }' is invalid ` )
+ // 观察器的配置(需要观察什么变动)
+ const config = { attributes: true , childList: false , subtree: true }
+ // 创建一个观察器实例并传入当观察到变动时执行的回调函数
+ const observer = new MutationObserver ((mutationsList : MutationRecord []) => {
+ // Use traditional 'for loops' for IE 11
+ for (let mutation of mutationsList ) {
+ if (mutation .type === ' attributes' ) {
+ appHeight .value = document .documentElement .scrollHeight
+ }
+ }
+ })
+ // 开始观察目标节点
+ observer .observe (targetNode , config )
+})
+
+// 滚动事件执行的回调函数
+const listener = () => {
+ const scrollProgress = el .value
+ const height = appHeight .value - document .documentElement .clientHeight
+ const scrollTop = document .body .scrollTop || document .documentElement .scrollTop
+ scrollProgress .style .width = ` ${(scrollTop / height ) * 100 }% `
+}
+
+onMounted (() => window .addEventListener (' scroll' , listener ))
+onUnmounted (() => window .removeEventListener (' scroll' , listener ))
+
+const style: any = {
+ background: props .theme ,
+ zIndex: props .zIndex ,
+ height: props .height ,
+}
+
+if (props .placement === ' top' ) style .top = 0
+if (props .placement === ' bottom' ) style .bottom = 0
+
+// 在 `<script setup>` 标签下显式公开属性,则需要使用 `defineExpose`
+defineExpose ({ style })
+</script >
+
+<template >
+ <div id =" scroll_progress" ref =" el" :style =" style" />
+</template >
+
+<style scoped >
+#scroll_progress {
+ position : fixed ;
+ width : 0% ;
+ transition : width 300ms ease-out ;
+}
+</style >
+
🎥 演示
+
+
+
🔗 参考
+
+[MDN] Document: scroll event[2] - 文档视图或者一个元素在滚动时,会触发元素的scroll事件。
+[MDN] MutationObserver[3] - 接口提供了监视对 DOM树
所做更改的能力。它被设计为旧的 Mutation Events
功能的替代品,该功能是 DOM3 Events
规范的一部分。
+Vue3 API[4]
+
+props[5]
+<script setup>[6]
+Lifecycle Hooks[7]
+defineProps and defineEmits[8]
+defineExpose[9]
+
+
+
+
参考资料 [1] 体验地址: https://code.lencx.tech/
+[2] [MDN] Document: scroll event: https://developer.mozilla.org/zh-CN/docs/Web/API/Document/scroll_event
+[3] [MDN] MutationObserver: https://developer.mozilla.org/zh-CN/docs/Web/API/MutationObserver
+[4] Vue3 API: https://v3.vuejs.org/
+[5] props: https://v3.vuejs.org/api/options-data.html#props
+[6] <script setup>: https://v3.vuejs.org/api/sfc-script-setup.html#basic-syntax
+[7] Lifecycle Hooks: https://v3.vuejs.org/api/composition-api.html#lifecycle-hooks
+[8] defineProps and defineEmits: https://v3.vuejs.org/api/sfc-script-setup.html#defineprops-and-defineemits
+[9] defineExpose: https://v3.vuejs.org/api/sfc-script-setup.html#defineexpose
+
+
+
+
diff --git a/posts/issues-0074/index.html b/posts/issues-0074/index.html
new file mode 100644
index 0000000..9bac689
--- /dev/null
+++ b/posts/issues-0074/index.html
@@ -0,0 +1,195 @@
+
+
+
+
+
+
+
+
+lencx 语录
+
+
+此语录,无任何意义,仅记录生活中的所思所感...
+
+
学习
+
+要学会把问题交给搜索引擎,而不是把群友当成搜索引擎。
+同样一个问题,用百度和 Bing[1] (有能力的用 Google[2] ) 对比一下就知道了。
+学习技术,先扫一遍文档,从最基本的开始搭建学习,功能一点点的增加进来。边看边实践,敲键盘也会加深记忆。
+优秀一天容易,难的是一直优秀。
+一篇好文章,更像是一根线,而不是一团麻。极客精神,以风趣幽默的方式解释清楚一切细节。
+学到一句话:经验这个东西,就是越多越好,可以不去做,但是不能不知道。
+有问题不可怕,可怕的是,不知道怎么和问题去相处。
+答案是最无用的东西,因为它是一个问题的处理结果,是由过程分析推理得出来的,过程推理不出,而选择去背答案是最无效的学习方式,毫无意义!
+学习就是从懵逼到膨胀的一个死循环 🔄
+以后再也不敢说自己是在自学了。没有基础作为指导,只能算是瞎学,乱学。看完《自学计算机科学》[3] 这份书单,才发现自己对计算机一无所知。
+真正的高效工作,是首先先学会如何解放自己。
+骨头是不好啃,自己要先啃几口,才有发言权。别还没啃,就说太硬了。(软饭吃多了,牙也变软了)
+遇到问题自己不思考,不尝试,就没有资格把这个问题抛出来。(踢皮球并不能让自己成长)
+学会自我总结, 一步一个脚印,别总想着有人可以帮你。(外力终究不是自己的)
+知识就是这样的,会一点点进入你的视野。但是前提,你要保持好奇心,并且不断地尝试。
+人的思想蜕变,不是一瞬间产生的,而是不断起伏的人生带给你的。
+学习是自己的事情(信息的收发建立在共识之上),没有人可以真正帮助你。有所收获,最该感谢的人其实是自己。
+学习是一件痛苦的事情,开始享受这个过程,或许就是自己在努力汲取养分生长吧。
+
+
思考
+
+学习其实就是用到什么学什么,能否快速掌握一门技术,和你学了多少门技术其实没有太大关系(要学的东西应该是技术背后的通用思想)。分析,思考,解决问题的能力,也并不是你接触的技术所能带给你的。因为知识是死的,而人却是活的,所以这些能力的培养和养成其实是一个主动行为。未知知识学习 = 拓展阅读(已有知识中的未知部分) + 信息源(领域大牛)+ 已有知识 + 经验推导
+有人问我该如何学习,其实我也不知道,当我迷茫时,就强迫自己静下心来写一个项目,不断地解决问题,然后就会变得很享受。问题不是凭空出现的,遇到的时候,你就会去搜寻各种解决方案,这就是学习。有些人最大的问题就是在遇到问题时第一时间把问题抛给别人,把群友当成搜索引擎。没有思考,没有尝试,也就不能够形成自己解决问题的方法论。
+人最大的价值就是没有价值,做任何事的意义就是毫无意义。
+
+
日常
+
+知识就摆在那里,想学的会想尽办法会去寻找,没必要去投喂。
+感谢所有夸我的人,说句实话,我不 NB,在技术群里,大部分人的能力都要比我强,我只是比较张扬而已。
+任何话题都是技术交流,代码不是全部。
+不信鬼神,但对未知还是要保持敬畏之心。
+群里虽然前端居多,似乎更应该发和前端相关的内容。但一切皆知识,路应该越走越宽。专精于 xxx 或许没错,但只有 xxx,视野过于被局限,会少了很多灵感碰撞及其他可能性。(广度与深度该如何抉择)
+彩票属于不确定的意外之财,讨论这个没啥意义。运气不是每个人都有的,现实点。(学会自我催眠)
+我写的文章没啥技术含量,手撕不动,脑子也不怎么灵活,基础更是一塌糊涂。
+我想明白了一些事情:欲望就好比握在手中的沙子,不握紧,会流失。握紧了,只会流的更快。因为想要获得,各种复杂的情绪就产生了,兴奋,焦虑… 如果放弃了所有的欲,一切便会回归于无。
+当一些东西变得重复与机械的时候,也就失去了原本的兴趣。
+自省只是不想让自己太飘,因为人是社会性动物,他人的评价或多或少都会对自己产生影响。
+知识,技术可以变现,但是丢掉原则,就不再是一个技术人了。
+本以为自己只是走了两三年的弯路,谁知从未走出...
+开源其实是一件很简单的事情,你想做,就可以去做。
+人更喜欢相信自己看到的。很少有人去思考,你所看到的是不是别人故意给你看的?(眼见不一定为实)
+以前我也认为只要学会独立思考就够了,但是后来我发现,如果你所看到的一切都是假象,那么基于它做出思考将是一件可怕的事情。(价值观坍塌)
+眼界,思考,质疑,都很重要。
+当对一切失去了怀疑的态度,会让你觉得它就是权威,不会出错。这是很可怕的事情。(盲目崇拜)
+做你认为对的事情,就不存在浪费时间一说。
+有人说:“大多数的成功来源于勇气,似乎越成熟,越丧失了追求的勇气”。但是我认为不是越活越没勇气,而是人学会了算计,会去计较得失,才变得畏手畏脚。(冲动是魔鬼,太过于理智,生活也就少了一些色彩)
+一定要学会享受过程。结果很重要,但是如果真的有一天你可以直接到达这个结果的时候,未必是快乐的。(出生的结局就是死亡)
+没有学会取舍,才会让自己那么累。(放下也是一种智慧)
+我不想努力了,可是没钱。钱不是那么重要,但是没有它,可能会过的很惨。(衣食住行)
+这个世界是动态的,一切都在变化,人也如此。(保持初心)
+穷爸爸富爸爸[4] 告诉我们,起点大于努力。(生的好也很重要)
+
+
吐槽
+
+做任何事都是需要指标的,没有高标准,就不会把事情做到极致。但是国内忽视了一些东西,或者说不愿意去面对实际场景,“拍脑袋”和“我以为”就是标准。KPI 最终沦为了老板们的大屏数据,似乎数据代表一切...
+说句难听的,国人有能力的不少,但是创造的东西,真不咋样,很难有思维上的突破,到处都是“借鉴”。
+国外做开源的很多可能就是个学生,普通程序员,没啥 title,吊打国内一大批程序员;级别,title 是越封越高,能力倒是没见涨。
+国人不务实,很多都是面子工程,这莫非是大环境“造就”的?
+这两年看到比较多的消息就是 xxx 开源库作者因精力有限,放弃对其的维护工作。这都是白嫖,不返哺社区的结果。
+某度搜索并不适合程序员,查找问题效率低下,结果百分之八九十都是垃圾。(工具很重要)
+一个技术社区如果东西“杂了”,技术就变得不再纯粹。(四不像)
+Node[5] 再卷,感觉都要卷到 V8[6] ,C++[7] 了,而我只是个前端切图仔。
+技术如果不纯粹就会变得畸形,写文章首要目标是思考沉淀,其次是分享传播帮助他人,最后才会考虑技术变现,但很多所谓的“作者”似乎本末倒置了。
+看似是要求越来越低,实则社会在教我做人。(认清现实)
+轮子哥,造轮子的速度比我用轮子的速度还快。(与大佬的差距)
+垃圾公众号看多了,人都变傻了。天天卖课,真烦...
+公众号其实就是收割流量的,既然那么多干货,为啥不写成 blog,因为写成 blog 就没多少干货了,公众号基本百分之七八十都是在转载,写成 blog 哪有那么多文章。如果你关注了 100 个前端公众号,一篇文章你起码可以在几十个公众号看到,有啥意义?还有一大堆是卖课的。一百个能有十个,可能都是比较乐观的估计,十不存一...
+我觉得很多人就喜欢混为一谈,学习的本质是为了什么?是为了吃透一门技术,掌握一门技能,还是说只是为了更好的赚钱。(多问问自己想要什么)
+最近做项目的一些体会。代码如何不腐,单从代码层面很难解决。
你可以去预留接口,提高可扩展性,但是抵不住需求从一个东西变成另一个东西,还非要表现出是一个东西的那种状态。
真要系统健壮,以及可扩展,需要的是多方配合,而不是自己搞自己的,需求自己随便提,后端按自己的想法自己定数据结构,前端天天跟着设计跑,换颜色,换交互。各种场景不做收拢,梳理。说句难听的,即使新开项目,一年项目就是一坨屎,到后面就是牵一发动全身,开发委屈说,时间不够,需要 review 的东西太多。业务觉得你不够努力,这么简单的需求你要搞那么久?这就是现状。。。
+
+
非原创
+
+科技造神的祭坛下,是无数沉迷于低级娱乐与表面思考的终端消费者。但他们不得不为此付费,甚至久而久之,他们会下意识地维护这套病态逻辑。
+编程的历史就是“更少代码”的历史:寻找更好的抽象,并构建库来实现这些抽象。
+No problem can be solved from the same level of consciousness that created it. (重大问题的解决方案永远不可能在产生这个问题的维度出现。) -- Albert Einstein
+
+
参考资料 [1] Bing: https://bing.com/
+[2] Google: https://www.google.com/
+[3] 《自学计算机科学》: https://github.com/izackwu/TeachYourselfCS-CN/blob/master/TeachYourselfCS-CN.md
+[4] 穷爸爸富爸爸: https://zh.wikipedia.org/wiki/%E5%AF%8C%E7%88%B8%E7%88%B8%C2%B7%E7%AA%AE%E7%88%B8%E7%88%B8
+[5] Node: https://nodejs.org/en/
+[6] V8: https://v8.dev/
+[7] C++: https://isocpp.org/
+
+
+
+
diff --git a/posts/issues-0075/index.html b/posts/issues-0075/index.html
new file mode 100644
index 0000000..b241dc0
--- /dev/null
+++ b/posts/issues-0075/index.html
@@ -0,0 +1,279 @@
+
+
+
+
+
+
+
+
+微信杂谈 - 组件开发的一些思考
+
+
📅 2021.12.22
+
lencx:
+人们更倾向于根据场景来探索解决方案,成也场景,败也场景。收窄要解决问题的范围,可以降低复杂度,但也降低了普适性。我以前也一直觉得,要实现的东西应该尽可能的剥离业务,但是随着做的业务越来越多,发现业务其实才是核心。当把业务抽象之后,所谓的跨平台其实就是适配的问题。
+
我发现可能之前自己想错了,应该抽象的是业务而不是组件,组件只是业务的载体。
+
适配层(组件)要做的就是低耦合,用抽象的业务逻辑去驱动适配层。
+
其核心就是业务,怎么实现,是个技术问题。技术可以被替换,推翻。以不变(主业务逻辑)应万变(视觉及交互)。
+
+
+产生的讨论
+
+
正人 (欧雷):
+场景化方案基于通用化方案,不冲突
+
lencx:
+其实我是发现可能之前自己想错了,要抽象的可能是业务而不是组件
+
🇨🇳 Promise (🇨🇳 Promise):
+感觉其实是不同维度
+
正人 (欧雷):
+所以通用方案的扩展机制很重要
+
正人 (欧雷):
+都要抽象
+
正人 (欧雷):
+所以为啥要 MV*,为啥要 DDD[吃瓜]
+
🇨🇳 Promise (🇨🇳 Promise):
+通用化方案抽离的开发工具本身, 例如打包工具, 组件化是ui 的抽离,例如react、vue,ant
+
🇨🇳 Promise (🇨🇳 Promise):
+想到一个以前的小品,把大象放进冰箱需要几步,答案是三步。 接下来会对这三步行为不端细化和抽离。为了适配不同的场景(放进其他的东西),就对三步的行为不端抽象,部分不同的做单独适配
+
lencx:
+适配层(组件)我认为要做的就是低耦合,用抽象的业务逻辑去驱动适配层
+
🇨🇳 Promise (🇨🇳 Promise):
+来驱动适配层怎么来理解
+
Shine.:
+除非业务组件 其他的组件都应该是低耦合吧 就只敢一件事
+
Shine.:
+不应该有任何业务逻辑什么的吧?
+
空:
+不是有业务组件跟通用组件之分么
+
lencx:
+个人理解:组件开发一般两种模式,无状态组件和业务组件,业务组件会耦合业务逻辑
+
lencx:
+但是如果按照我说的,其实就不存在业务组件了,所有的组件基本和业务都不存在太大的耦合,也就是不会在组件里处理业务相关的东西
+
lencx:
+组件都退化到通用,然后只负责数据的填充。交互其实就是一个个动作,给业务数据所带来的反应。
+
Shine.:
+就是说组件不去处理业务 业务都在使用的时候去处理?
+
lencx:
+在抽象的业务核心逻辑里处理,你可以理解为业务核心就是一个个纯函数
+
lencx:
+组件只负责接收数据
+
Jack:
+按我理解
+
Jack:
+理想化状态下,组件就是个书包
+
Jack:
+你给我啥书 我就装啥书
+
Jack:
+具体你给我的是语文书 数学书 马列主义 还是什么其他的
+
Jack:
+我不管
+
Jack:
+我只管把书装进去 让你带着走
+
lencx:
+对,书就是业务核心,组件只负责装
+
Jack:
+这也不是我该管的
+
Jack:
+理想情况下就是这样
+
Jack:
+我该管的只是,你如果不装书,装炸药,那我就报错
+
🇨🇳 Promise (🇨🇳 Promise):
+这就是抽象与具象的互斥点了
+
🇨🇳 Promise (🇨🇳 Promise):
+在业务状态下,有时候需要保证书的放入和放出顺序
+
Jack:
+是的 所以理想和现实还是有些差距
+
🇨🇳 Promise (🇨🇳 Promise):
+书的放置位置和摆放形势
+
lencx:
+所以可能需要有类似流程控制的东西吧
+
lencx:
+我其实也没完全想明白
+
Jack:
+这个见仁见智了 有的倾向于在外边整理完了再塞进去
+
Jack:
+有的倾向于塞进去,背在身上,让书自己动
+
皓夜森林:
+ui组件的逻辑层都应该是个纯函数,ui层就是只负责渲染。业务组件感觉更偏向于,处理某个特定业务,比如唤起第三方的支付,sdk的支付组件。这种
+
Shine.:
+什么叫纯函数 你给我啥我返回啥 对数据不做处理?
+
皓夜森林:
+很简单,你想想你这个组件能不能在别的项目直接用
+
Shine.:
+我看网上解释有点太名词了
+
🇨🇳 Promise (🇨🇳 Promise):
+现在大多数抽象层的处理,都是在外面处理外,整体放进去,但是也有要求这个单独执行动作的。
+
皓夜森林:
+不管啥项目。都能直接用(运行环境允许的情况下)
+
Jack:
+没有副作用的函数
+
Jack:
+比如 sum(1,2,3)
+
lencx:
+纯函数就是个黑盒,接收参数,内部一系列处理后,返回的就是格式化后的标准数据格式
+
Jack:
+我如果输入123 那输出值永远是6
+
🇨🇳 Promise (🇨🇳 Promise):
+我个人推崇的还是那种微内核的形式, 提供插件机制和默认机制。 同时保留执行 过程外部可以修改的api
+
皓夜森林:
+你就理解为一个函数如果在输入一样的情况下输出永远不变那就是纯函数
+
皓夜森林:
+const add = (a ,b) => a + b 这就是一个纯函数
+
皓夜森林:
+let effectParam = 1
+const add = (a, b) => a + b + effectParam
+
皓夜森林:
+因为结果会受effectParam影响
+
皓夜森林:
+这就不是一个纯函数
+
皓夜森林:
+这个参数变了结果就变了 即使输入可能都是一样的输入
+
Jack:
+effectParam也可能是某个api的返回值
+
Shine.:
+哦 明白了
+
🇨🇳 Promise (🇨🇳 Promise):
+像纯函数的编写,也是可以传入单纯的形参,或者传入一个改变执行函数作为结构的再次处理
+
Shine.:
+我一直理解的是 不修改传递的参数那
+
皓夜森林:
+我寄几玩我寄几的
+
皓夜森林:
+你别搞我
+
皓夜森林:
+这就是纯函数
+
lencx:
+业务其实就是一大堆这样的纯函数,做什么功能,调什么函数,职责单一
+
Jack:
+其实本质就是在做取舍
+
Shine.:
+那我好像很多时候违背了这个
+
🇨🇳 Promise (🇨🇳 Promise):
+能保证单一指责其实在团队中就有点难的
+
皓夜森林:
+hook很多都是业务组件的逻辑层
+
Shine.:
+看似代码少了
+
Shine.:
+其实维护起来有点麻烦
+
Jack:
+的确
+
皓夜森林:
+那你的项目做大了就很难维护
+
Shine.:
+一改都得变
+
皓夜森林:
+这个是肯定的
+
Jack:
+所以要考虑颗粒度
+
Jack:
+这就又扯到很多其他方面了
+
Jack:
+团队规模 业务复杂度 等等
+
皓夜森林:
+我的话这种都是踩坑踩出来的
+
🇨🇳 Promise (🇨🇳 Promise):
+这个本身就是一个很大的命题,把这个充满生机的世界在计算机中进行再造,本身就是厉害
+
皓夜森林:
+最近改公司的支付...越发体会深刻
+
lencx:
+支付的各种逻辑一旦耦合进 ui 里, ui 大改版就痛苦了
+
🇨🇳 Promise (🇨🇳 Promise):
+其实理解好面向对象也是比较容易,抽象对象, 实例在进行业务适配。 提供插件机制提供实例运行
+
参考资料
+
+
+
+
diff --git a/posts/issues-0077/index.html b/posts/issues-0077/index.html
new file mode 100644
index 0000000..6644db2
--- /dev/null
+++ b/posts/issues-0077/index.html
@@ -0,0 +1,224 @@
+
+
+
+
+
+
+
+
+2021 年终总结
+
+
+{折腾 ⇌ 迷茫 ⇌ 思考]ing,在路上...
+
+
+flag 立的太多,一个也没完成
+打游戏,刷动漫,电视剧,综艺,视频
+读了一些源码,写了一些玩具项目
+吐槽太多,已整理成语录
+努力早睡,不熬夜
+认识了很多新朋友
+
+
分享 & 沉淀
+
建了两个微信技术群和一个免费知识星球
+
+浮之静 - 知识星球[1] - 这里分享技术,无用的小知识(常识之外)。
+微信杂谈[2] - 技术相关的群聊记录
+
+组件开发的一些思考[3]
+技术栈[4]
+技术广度 & 深度[5]
+技术迷茫期[6]
+造轮子[7]
+
+
+
+
语录
+
+lencx 语录[8] - 此语录,无任何意义,仅记录生活中的所思所感...
+
+
🧐 学习
+
+要学会把问题交给搜索引擎,而不是把群友当成搜索引擎。
+同样一个问题,用百度和 Bing[9] (有能力的用 Google[10] ) 对比一下就知道了。
+学习技术,先扫一遍文档,从最基本的开始搭建学习,功能一点点的增加进来。边看边实践,敲键盘也会加深记忆。
+优秀一天容易,难的是一直优秀。
+一篇好文章,更像是一根线,而不是一团麻。极客精神,以风趣幽默的方式解释清楚一切细节。
+学到一句话:经验这个东西,就是越多越好,可以不去做,但是不能不知道。
+有问题不可怕,可怕的是,不知道怎么和问题去相处。
+答案是最无用的东西,因为它是一个问题的处理结果,是由过程分析推理得出来的,过程推理不出,而选择去背答案是最无效的学习方式,毫无意义!
+学习就是从懵逼到膨胀的一个死循环 🔄
+以后再也不敢说自己是在自学了。没有基础作为指导,只能算是瞎学,乱学。看完《自学计算机科学》[11] 这份书单,才发现自己对计算机一无所知。
+真正的高效工作,是首先先学会如何解放自己。
+骨头是不好啃,自己要先啃几口,才有发言权。别还没啃,就说太硬了。(软饭吃多了,牙也变软了)
+遇到问题自己不思考,不尝试,就没有资格把这个问题抛出来。(踢皮球并不能让自己成长)
+学会自我总结, 一步一个脚印,别总想着有人可以帮你。(外力终究不是自己的)
+知识就是这样的,会一点点进入你的视野。但是前提,你要保持好奇心,并且不断地尝试。
+人的思想蜕变,不是一瞬间产生的,而是不断起伏的人生带给你的。
+
+
😐 日常
+
+感谢所有夸我的人,说句实话,我不 NB,在技术群里,大部分人的能力都要比我强,我只是比较张扬而已。
+任何话题都是技术交流,代码不是全部。
+不信鬼神,但对未知还是要保持敬畏之心。
+群里虽然前端居多,似乎更应该发和前端相关的内容。但一切皆知识,路应该越走越宽。专精于 xxx 或许没错,但只有 xxx,视野过于被局限,会少了很多灵感碰撞及其他可能性。(广度与深度该如何抉择)
+彩票属于不确定的意外之财,讨论这个没啥意义。运气不是每个人都有的,现实点。(学会自我催眠)
+我写的文章没啥技术含量,手撕不动,脑子也不怎么灵活,基础更是一塌糊涂。
+我想明白了一些事情:欲望就好比握在手中的沙子,不握紧,会流失。握紧了,只会流的更快。因为想要获得,各种复杂的情绪就产生了,兴奋,焦虑… 如果放弃了所有的欲,一切便会回归于无。
+当一些东西变得重复与机械的时候,也就失去了原本的兴趣。
+自省只是不想让自己太飘,因为人是社会性动物,他人的评价或多或少都会对自己产生影响。
+知识,技术可以变现,但是丢掉原则,就不再是一个技术人了。
+本以为自己只是走了两三年的弯路,谁知从未走出...
+开源其实是一件很简单的事情,你想做,就可以去做。
+人更喜欢相信自己看到的。很少有人去思考,你所看到的是不是别人故意给你看的?(眼见不一定为实)
+以前我也认为只要学会独立思考就够了,但是后来我发现,如果你所看到的一切都是假象,那么基于它做出思考将是一件可怕的事情。(价值观坍塌)
+眼界,思考,质疑,都很重要。
+当对一切失去了怀疑的态度,会让你觉得它就是权威,不会出错。这是很可怕的事情。(盲目崇拜)
+做你认为对的事情,就不存在浪费时间一说。
+有人说:“大多数的成功来源于勇气,似乎越成熟,越丧失了追求的勇气”。但是我认为不是越活越没勇气,而是人学会了算计,会去计较得失,才变得畏手畏脚。(冲动是魔鬼,太过于理智,生活也就少了一些色彩)
+一定要学会享受过程。结果很重要,但是如果真的有一天你可以直接到达这个结果的时候,未必是快乐的。(出生的结局就是死亡)
+没有学会取舍,才会让自己那么累。(放下也是一种智慧)
+我不想努力了,可是没钱。钱不是那么重要,但是没有它,可能会过的很惨。(衣食住行)
+这个世界是动态的,一切都在变化,人也如此。(保持初心)
+穷爸爸富爸爸[12] 告诉我们,起点大于努力。(生的好也很重要)
+
+
🤬 吐槽
+
+做任何事都是需要指标的,没有高标准,就不会把事情做到极致。但是国内忽视了一些东西,或者说不愿意去面对实际场景,“拍脑袋”和“我以为”就是标准。KPI 最终沦为了老板们的大屏数据,似乎数据代表一切...
+说句难听的,国人有能力的不少,但是创造的东西,真不咋样,很难有思维上的突破,到处都是“借鉴”。
+国外做开源的很多可能就是个学生,普通程序员,没啥 title,吊打国内一大批程序员;级别,title 是越封越高,能力倒是没见涨。
+国人不务实,很多都是面子工程,这莫非是大环境“造就”的?
+这两年看到比较多的消息就是 xxx 开源库作者因精力有限,放弃对其的维护工作。这都是白嫖,不反哺社区的结果。
+某度搜索并不适合程序员,查找问题效率低下,结果百分之八九十都是垃圾。(工具很重要)
+一个技术社区如果东西“杂了”,技术就变得不再纯粹。(四不像)
+Node[13] 再卷,感觉都要卷到 V8[14] ,C++[15] 了,而我只是个前端切图仔。
+技术如果不纯粹就会变得畸形,写文章首要目标是思考沉淀,其次是分享传播帮助他人,最后才会考虑技术变现,但很多所谓的“作者”似乎本末倒置了。
+看似是要求越来越低,实则社会在教我做人。(认清现实)
+轮子哥,造轮子的速度比我用轮子的速度还快。(与大佬的差距)
+垃圾公众号看多了,人都变傻了。天天卖课,真烦...
+公众号其实就是收割流量的,既然那么多干货,为啥不写成 blog,因为写成 blog 就没多少干货了,公众号基本百分之七八十都是在转载,写成 blog 哪有那么多文章。如果你关注了 100 个前端公众号,一篇文章你起码可以在几十个公众号看到,有啥意义?还有一大堆是卖课的。一百个能有十个,可能都是比较乐观的估计,十不存一...
+我觉得很多人就喜欢混为一谈,学习的本质是为了什么?是为了吃透一门技术,掌握一门技能,还是说只是为了更好的赚钱。(多问问自己想要什么)
+
+
🤫 非原创
+
+科技造神的祭坛下,是无数沉迷于低级娱乐与表面思考的终端消费者。但他们不得不为此付费,甚至久而久之,他们会下意识地维护这套病态逻辑。
+编程的历史就是“更少代码”的历史:寻找更好的抽象,并构建库来实现这些抽象。
+
+
开源
+
2021 开源项目归档[16]
+
+
总结
+
2021 年一晃而过,很多事情都没来得及去做,只能匆匆忙忙总结一番。以这篇文章(参照物),来记录自己的成长(age++)。
+
参考资料 [1] 浮之静 - 知识星球: https://t.zsxq.com/fMRRNvz
+[2] 微信杂谈: https://github.com/lencx/z/discussions?discussions_q=label%3A%E5%BE%AE%E4%BF%A1%E6%9D%82%E8%B0%88
+[3] 组件开发的一些思考: https://github.com/lencx/z/discussions/75
+[4] 技术栈: https://github.com/lencx/z/discussions/61
+[5] 技术广度 & 深度: https://github.com/lencx/z/discussions/57
+[6] 技术迷茫期: https://github.com/lencx/z/discussions/55
+[7] 造轮子: https://github.com/lencx/z/discussions/54
+[8] lencx 语录: https://github.com/lencx/z/discussions/74
+[9] Bing: https://bing.com/
+[10] Google: https://www.google.com/
+[11] 《自学计算机科学》: https://github.com/izackwu/TeachYourselfCS-CN/blob/master/TeachYourselfCS-CN.md
+[12] 穷爸爸富爸爸: https://zh.wikipedia.org/wiki/%E5%AF%8C%E7%88%B8%E7%88%B8%C2%B7%E7%AA%AE%E7%88%B8%E7%88%B8
+[13] Node: https://nodejs.org/en/
+[14] V8: https://v8.dev/
+[15] C++: https://isocpp.org/
+[16] 2021 开源项目归档: https://github.com/stars/lencx/lists/2021
+
+
+
+
diff --git a/posts/issues-0078/index.html b/posts/issues-0078/index.html
new file mode 100644
index 0000000..4794645
--- /dev/null
+++ b/posts/issues-0078/index.html
@@ -0,0 +1,247 @@
+
+
+
+
+
+
+
+
+浏览器发展史
+
+
+计算机世界是对现实世界的映射。当事物变得无法理解时,去源头找找,或许就明白了。
+
+
Chrome 100
+
在 2022 上半年,Chrome[1] 将达到三位数的主版本号:100
!浏览器在很久以前第一次达到版本 10
时,因为主要版本号从一位数变为两位数,用户代理解析库发现了许多问题(Changes in Opera’s user agent string format[2] )。现在在 Chrome 和 Firefox[3] 中都接近版本 100
,Edge[4] 也不甘落后。当 Chrome 达到 100
版,将会导致一些网站不工作。谷歌已经开始调查和测试解决方案。
+
根据 Chromium Bug Tracker[5] ,已知受到影响的网站主要是使用网页设计工具 Duda[6] 开发的网站。这些网站都使用相同的代码来检查用户使用的 Chrome 版本。
+
案例
+
以 Chrome 为例,用户代理字符串为 Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36
+
字符串最后,可以看到我们要寻找的是 Chrome/96.0.4664.110
,它为我们提供了浏览器的准确版本号。但是,大多数 Web 开发人员可能只关心主要版本号,即 96
。
+
由于用户代理字符串是文本,开发人员需要自行提取信息以满足业务需求。对于 Duda,开发人员选择只读取 Chrome/
之后的前两位数字。这意味着 Chrome/99
将是 99
, Chrome/100
将被视为版本 10
。
+
而 Duda(2015 年发布的版本)会自动阻止低于 Chrome 40
的版本,Chrome 99
之后的每个版本(100 - 109)的浏览器都将被视为版本 10
,因此被阻止。
+
目前 Duda 已经修复了此问题(Chrome 100 Bug Was Fixed Months Before The New Version's Actual Release[7] )
+
检测与反馈
+
通过访问 Is Chrome 100 yet?[8] 可以检查浏览器是否在 User-Agent
字符串中发送主要版本 100。
+
为了尽早检测三位数版本号可能导致的问题,在它成为现实前做好准备。我们可以在 Chrome 设置中开启 User-Agent
为 100
的主版本(Force Chrome major version to 100 in the User-Agent string[9] )来对网站进行测试。
+
+访问 Is Chrome 100 yet?
,页面返回 Yes!
或 No.
;
+打开 Chrome 浏览器并在地址栏中输入 chrome://flags
;
+将打开一个包含可用实验的页面, 找到 User-Agent
中启用强制主要版本为 100
的选项(Force major version to 100 in User-Agent
)。然后重新访问步骤 1。
+
+
+
成功开启后,然后测试自己的网站。如果发现问题,可以将错误报告发送至 Web Compat[10] 以帮助 Web 浏览器准备三位数的主版本号!
+
里程碑
+
Web 浏览器简史[11] - 世界历史从不缺少史诗般的权力斗争,有征服世界的暴君,也有落败的勇士。Web 浏览器的历史也大抵如此。学术先驱们编写出引发信息革命的简易软件,并为浏览器的优势和互联网用户而战。
+
在《万维网 25 岁生日快乐》[12] 中可以了解更多网络诞生的相关信息。
+
Mosaic
+
Mosaic User Agents[13] - NCSA_Mosaic/2.0 (Windows 3.1)
+
NCSA Mosaic[14] ,是一个早期普及的网页浏览器,也是互联网协议如 FTP、NNTP 和 Gopher 的客户端,浏览器因支持多种互联网协议而命名。其直观的接口、可靠性和简易安装,因此在当时大受欢迎,也是第一个可以在文字中嵌入图片,而不是在单独的窗口中显示图片的浏览器。
+
Mosaic 是引发 1990 年代互联网泡沫的网页浏览器。1992 年 11 月,世界上只有仅仅 26 个网站,每一个网站都受人注目。1993 年,Mosaic 推出了一个叫做 What’s New
(What's New With NCSA Mosaic[15] ) 的页面,几乎每天都会提供给大家一个全新网站的链接。这段期间,互联网的使用率正在由学术界和大型工业研究机构之外迅速普及。然而,这正是 Mosaic 浏览器的易用性推动了网络爆发性的成长,到了 1995 年 8 月,网站数量已经超过了一万个,1998年达到了数百万个网站数量。
+
+
Mozilla
+
Firefox User Agents[16] - Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:95.0) Gecko/20100101 Firefox/95.0
+
Mozilla[17] 是一个自由软件社群,由网景通信公司的成员于 1998 年创立。在非正式的场合下,“Mozilla” 这个名字常用于不同的事物上。这些事物大都与现已歇业的网景通信公司及其旗下的应用软件相关。
+
最初,“Mozilla” 被用作 网景导航者(Netscape Navigator)[18] 的开发代号。网景通信公司希望“网景导航者”能够取代当时世界第一的 Mosaic,而这个名字由 “Mosaic Killa”(Killa 是俚语中 Killer 的拼法)变化而来,并与经典的虚拟怪物哥斯拉谐趣:“Godzilla eat the Mosaic”,即 Mosaic + Godzilla + Killa = Mozilla
,Netscape 工程师杰米·加文斯基说他是在一次 Netscape 员工会议上想到这个名字的。
+
Mozilla Firefox[19] ,通称 Firefox,中文也通称“火狐”,是一个自由及开源的网页浏览器,由 Mozilla 基金会及其子公司 Mozilla 公司开发。Firefox 于 2002 年由 Mozilla 社群成员创建,当时叫做“Phoenix”。Firefox 于 2004 年 11 月首次发布,并且 9 个月内下载量超过 6,000 万,获取了巨大的成功,Internet Explorer的主导地位首次受到了挑。其被认为是 Netscape Navigator
的精神续作。
+
+
+
Internet Explorer
+
Internet Explorer User Agents[20] - Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)
+
Internet Explorer[21] (旧称 Microsoft Internet Explorer 和 Windows Internet Explorer,简称 IE 或 MSIE),是微软所开发的图形用户界面网页浏览器。自从 1995 年开始,内置在各个新版本的 Windows 操作系统,也是微软 Windows 操作系统的一个组成部分。
+
Internet Explorer 曾是使用最广泛的网页浏览器,在 2002 年和 2003 年达到 95% 的使用率高峰。微软以捆绑方式赢得与 Netscape 的第一次浏览器大战,Netscape 是 1990 年代的主流浏览器。
+
Internet Explorer 计划由托马斯·里尔登开始于 1994 年夏天,当时 Netscape Navigator 占据浏览器市场份额 70% 以上。竞争对手苹果公司的 Mac OS 更使用 Netscape 作为默认的浏览器,但当时的 Windows 没有一个默认的浏览器。微软需要有一个自己的浏览器,但它没有时间从零开始创造一个浏览器。因此和 Spyglass 合作,Internet Explorer 从早期一款商业性的专利网络浏览器 Spyglass Mosaic 派生出来。
+
+
Opera
+
Opera User Agent[22] - Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36 OPR/82.0.4227.43
+
Opera 是由 Opera 软件为个人电脑推出的网页浏览器,用于 Microsoft Windows、macOS 和 Linux 操作系统。
+
1996 年首次公开发布 Opera 2.0 版本,但仅在 Microsoft Windows 上运行。1998 年开始开发第一款用于移动设备平台浏览器。
+
Opera 在 2013 年以后采用 Blink[23] 排版引擎 (layout engine)[24] 。此前 Opera 版本曾采用 Presto[25] 排版引擎,并在 FreeBSD 系统上运行。
+
+
Safari
+
Safari User Agent[26] - Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.1 Safari/605.1.15
+
Safari 浏览器[27] 是苹果公司所开发,并内置于 macOS(前称 OS X、Mac OS X)、iOS 与 iPadOS 的网页浏览器。Safari 浏览器在 2003 年 1 月 7 日首度发行测试版,并从 Mac OS X Panther 开始成为 Mac OS X 的默认浏览器,也是 iOS 和 iPadOS 内置的默认浏览器。Windows 版本的首个测试版在 2007 年 6 月 11 日推出,支持 Windows XP、Windows Vista 和 Windows 7,并在 2008 年 3 月 18 日推出正式版,但苹果已于 2012 年 7 月 25 日停止开发 Windows 版的 Safari 浏览器。
+
在 1997 年以前,Mac 预装的浏览器是 Netscape Navigator。之后苹果和微软达成协议,以在 Mac 上使用 Internet Explorer for Mac 作默认浏览器换取微软开发 Mac 版的 Microsoft Office。
+
2003 年 1 月 7 日,在旧金山举行的 Macworld 大会上,史提夫·乔布斯宣布苹果正在开发自己的浏览器,称为 Safari 浏览器。它基于苹果的 KHTML 排版引擎内部分支,称为 WebKit。直至 2003 年 6 月,苹果才推出自家的 Safari 浏览器,同时微软也终止开发苹果版的 IE 浏览器。Mac OS X v10.3 仍保留 IE,但至 10.4 版苹果就仅预装 Safari 浏览器。
+
+
Chrome
+
Chrome User Agent[28] - Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36
+
Google Chrome 是由 Google 开发的免费网页浏览器,过去也用 Chrome 称呼浏览器的外框。Chrome 相应的开放源代码计划名为 Chromium[29] ,而 Google Chrome 本身是非自由软件,未开放源代码。
+
Chrome 代码是基于其他开放源代码软件所编写,包括 Apple WebKit[30] (其分支 Blink 被用于基于 Chromium 的网页浏览器) 和 Mozilla Firefox,并开发出称为 V8[31] 的高性能 JavaScript引擎[32] 。Google Chrome 的整体发展目标是提升稳定性、速度和安全性,并创造出简单且有效率的用户界面。
+
Chrome 50 结束了对 Windows XP 与 Windows Vista 系统的支持,这两个系统上的最后版本为 49.0.2623.112。
+
+
User-Agent 大乱斗
+
+🙈 浏览器用户代理字符串(navigator.userAgent
)一团糟,几乎没用,每个浏览器都假装是其他浏览器,混乱不堪。
+
+
具体可以查看这篇文章 《History of the browser user-agent string》[33] ,以风趣幽默的方式介绍了浏览器之间的“尔虞我诈”,“勾心斗角”,堪比 宫斗[34] 。
+
一般来说,如果一个网站需要知道你使用的是什么浏览器以及它的更新程度,它会检查所谓的“用户代理字符串”。这是浏览器附加到它建立的每个网络连接的一小段文本,让网站了解自己。如果分解用户代理字符串实际所说的内容,会发现很多杂乱无章的东西,其中大部分内容是为了保持与 1990 年代和 2000 年代初期的站点的兼容性。所以说有时候 使用用户代理字段进行浏览器检测[35] 并不是一个好主意。
+
用户代理字符串有各种形状和大小,唯一用户代理的数量一直在增长。List of User Agents[36] 中收集了数以百万计的用户代理,并根据检测到的许多内容(操作系统、浏览器、硬件类型、浏览器类型等)进行分类。
+
关键事件
+
+摘自《History of the browser user-agent string》
+
+
+
+一开始有 NCSA Mosaic,Mosaic 自称 NCSA_Mosaic/2.0 (Windows 3.1)
,Mosaic 在显示图片的同时也显示文字,大家都很欢欣鼓舞。
+
+
+后来出现了一个新的浏览器,叫做 “Mozilla”,是 “Mosaic Killer” 的缩写,但 Mosaic 并不高兴,所以公开名称改为 Netscape。Netscape 自称 Mozilla/1.0(Win3.1)
,人们更加欢欣鼓舞。Netscape 支持 Frames(框架)[37] ,Frames 在人们中间流行起来,但 Mosaic 不支持 Frames,于是就出现了 "用户代理嗅探(user agent sniffing)",网络管理员向 "Mozilla "发送 Frames,但向其他浏览器发送的不是 Frames。
+
+
+网景取笑微软,把 Windows 说成是 "调试不力的设备驱动程序",微软很生气。于是,微软制造了他们自己的网络浏览器,他们称之为 IE(Internet Explorer),希望它能成为 "网景杀手"。Internet Explorer 虽然支持 Frames,但并不是 Mozilla,所以没有被赋予 Frames。微软变得不耐烦了,不希望等待网络管理员了解 IE 并开始向它发送 Frames,因此 IE 浏览器宣布它是 "Mozilla compatible(Mozilla 兼容的)",并开始冒充网景,称自己为 Mozilla/1.22 (compatible; MSIE 2.0; Windows 95)
,IE 浏览器收到了 Frames,整个微软都很高兴,但网络管理员感到困惑。
+
+
+微软将 IE 与 Windows 一起出售,并使其比网景更好,第一次浏览器战争在这片土地上肆虐。看吧,网景被干掉了,微软方面一片欢腾。但网景重生为 Mozilla,Mozilla 建立了 Gecko[38] ,并称自己为 Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.1) Gecko/20020826
,Gecko 是渲染引擎,Gecko 很好。而 Mozilla 变成了 Firefox,并称自己为 Mozilla/5.0 (Windows; U; Windows NT 5.1; sv-SE; rv:1.7.5) Gecko/20041108 Firefox/1.0
,Firefox 非常好。而 Gecko 开始成倍增长,其他浏览器的诞生也使用了它的代码,它们自称为 Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en-US; rv:1.7.2) Gecko/20040825 Camino/0. 8.1
这一个,和 Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.8.1.8) Gecko/20071008 SeaMonkey/1.0
另一个,每一个都假装是 Mozilla,而且都是由 Gecko 驱动。
+
+
+Gecko 是好的,而 IE 不是,嗅觉重生,Gecko 被赋予了很好的 web 代码,其他浏览器则不然。而 Linux 的追随者则非常悲伤,因为他们建立了 Konqueror[39] ,其引擎是 KHTML[40] ,他们认为它和 Gecko 一样好,但它不是 Gecko,所以没有得到好的网页,于是 Konquerer 开始假装 "like Gecko",以获得好的网页,并称自己为 Mozilla/5.0 (compatible; Konqueror/3.2; FreeBSD)
(KHTML,like Gecko),出现了很多混乱。
+
+
+苹果建立了 Safari,使用 KHTML,增加了许多功能。分叉(Fork)了该项目,称之为 WebKit,希望为 KHTML 编写页面,因此 Safari 自称为 Mozilla/5.0 (Macintosh; U; PPC Mac OS X; de-de) AppleWebKit/85.7 (KHTML, like Gecko) Safari/85.5
,情况越来越糟。
+
+
+微软对火狐的恐惧很大,IE 浏览器又回来了,并自称 Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0)
,它能渲染好的代码,但只有在网站管理员命令它这样做的情况下。
+
+
+谷歌建立了 Chrome,Chrome 使用 Webkit,它就像 Safari 一样,想要为 Safari 制作页面,所以假装是 Safari。于是 Chrome 使用 WebKit,并假装是 Safari,WebKit 假装是 KHTML,KHTML 假装是 Gecko,所有的浏览器都假装是 Mozilla,Chrome 自称 Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.13 (KHTML, like Gecko) Chrome/0.2.149.27 Safari/525.13
,用户代理字符串完全是一团糟,几乎没有用处,每个人都假装是其他人,混乱不堪。
+
+
+
结束语
+
软件生态从来不是孤立的,而是在借鉴,创新中,不断发展,才有了今天这个五彩斑斓的互联网世界。
+
参考资料 [1] Chrome: https://www.google.com/intl/en_us/chrome/
+[2] Changes in Opera’s user agent string format: https://maqentaer.com/devopera-static-backup/http/dev.opera.com/articles/view/opera-ua-string-changes/index.html
+[3] Firefox: https://www.mozilla.org/en-US/firefox/new/
+[4] Edge: https://www.microsoft.com/en-us/edge
+[5] Chromium Bug Tracker: https://bugs.chromium.org/p/chromium/issues/detail?id=1273958
+[6] Duda: https://www.duda.co/
+[7] Chrome 100 Bug Was Fixed Months Before The New Version's Actual Release: https://blog.duda.co/chrome-100-bug-was-fixed-months-before-the-new-version-s-actual-release
+[8] Is Chrome 100 yet?: https://is-chrome-100-yet.glitch.me/
+[9] Force Chrome major version to 100 in the User-Agent string: https://developer.chrome.com/blog/force-major-version-to-100/
+[10] Web Compat: https://webcompat.com/issues/new?label=version100
+[11] Web 浏览器简史: https://www.mozilla.org/zh-CN/firefox/browsers/browser-history/
+[12] 《万维网 25 岁生日快乐》: https://computerhistory.org/blog/happy-25th-birthday-to-the-world-wide-web/
+[13] Mosaic User Agents: https://developers.whatismybrowser.com/useragents/explore/software_name/mosaic/
+[14] NCSA Mosaic: https://zh.wikipedia.org/wiki/Mosaic
+[15] What's New With NCSA Mosaic: https://www.w3.org/MarkUp/html-test/ncsa/whats-new.html
+[16] Firefox User Agents: https://www.whatismybrowser.com/guides/the-latest-user-agent/firefox
+[17] Mozilla: https://zh.wikipedia.org/wiki/Mozilla
+[18] 网景导航者(Netscape Navigator): https://zh.wikipedia.org/wiki/%E7%BD%91%E6%99%AF%E5%AF%BC%E8%88%AA%E8%80%85
+[19] Mozilla Firefox: https://zh.wikipedia.org/wiki/Firefox%E7%80%8F%E8%A6%BD%E5%99%A8
+[20] Internet Explorer User Agents: https://developers.whatismybrowser.com/useragents/explore/software_name/internet-explorer/
+[21] Internet Explorer: https://zh.wikipedia.org/wiki/Internet_Explorer
+[22] Opera User Agent: https://www.whatismybrowser.com/guides/the-latest-user-agent/opera
+[23] Blink: https://zh.wikipedia.org/wiki/Blink
+[24] 排版引擎 (layout engine): https://zh.wikipedia.org/wiki/%E6%B5%8F%E8%A7%88%E5%99%A8%E5%BC%95%E6%93%8E
+[25] Presto: https://zh.wikipedia.org/wiki/Presto
+[26] Safari User Agent: https://www.whatismybrowser.com/guides/the-latest-user-agent/safari
+[27] Safari 浏览器: https://zh.wikipedia.org/wiki/Safari
+[28] Chrome User Agent: https://www.whatismybrowser.com/guides/the-latest-user-agent/chrome
+[29] Chromium: https://zh.wikipedia.org/wiki/Chromium
+[30] Apple WebKit: https://zh.wikipedia.org/wiki/Apple_WebKit
+[31] V8: https://zh.wikipedia.org/wiki/V8_(JavaScript%E5%BC%95%E6%93%8E)
+[32] JavaScript引擎: https://zh.wikipedia.org/wiki/JavaScript%E5%BC%95%E6%93%8E
+[33] 《History of the browser user-agent string》: https://webaim.org/blog/user-agent-string-history/comment-page-1/
+[34] 宫斗: https://baike.baidu.com/item/%E5%AE%AB%E6%96%97/130784
+[35] 使用用户代理字段进行浏览器检测: https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Browser_detection_using_the_user_agent
+[36] List of User Agents: https://developers.whatismybrowser.com/useragents/explore/
+[37] Frames(框架): https://en.wikipedia.org/wiki/Frame_(World_Wide_Web)
+[38] Gecko: https://zh.wikipedia.org/wiki/Gecko
+[39] Konqueror: https://zh.wikipedia.org/zh-tw/Konqueror
+[40] KHTML: https://zh.wikipedia.org/wiki/KHTML
+
+
+
+
diff --git a/posts/issues-0079/index.html b/posts/issues-0079/index.html
new file mode 100644
index 0000000..080a84c
--- /dev/null
+++ b/posts/issues-0079/index.html
@@ -0,0 +1,263 @@
+
+
+
+
+
+
+
+
+微信杂谈 - 解决问题方法论
+
+
📅 2022.01.07
+
Veda@Angie:
+Vue问题求教:在 watch 里面,我先用 splice 清空了数组,再 for 循环 push 进去,控制台打印数组是更新了、但是页面还是没有重新渲染
+
Veda@Angie:
+小哥,你遇到过吗
+
lencx:
+vue 我不熟
+
lencx:
+你用的是 vue2 吗
+
Veda@Angie:
+[可怜]对
+
lencx:
+看看代码
+
Veda@Angie:
+Vue3 应该没这个问题了
+
Veda@Angie:
+代码在公司,只能下周一过去看了
+
lencx:
+[捂脸] 有时间跑个最小 demo
+
lencx:
+可能自己就发现问题了
+
Veda@Angie:
+最小 demo 是啥意思
+
lencx:
+就是复现问题的最小用例
+
Veda@Angie:
+奥奥是这个意思啊
+
Veda@Angie:
+那我回家了写一个跑一下试试
+
lencx:
+https://codesandbox.io/[1]
+
lencx:
+可以用这个创建
+
Veda@Angie:
+好的,感谢
+
lencx:
+比较方便,写完直接分享链接,就是一个在线版的
+
Veda@Angie:
+好、我去试一试,之前还没用过这种工具
+
lencx:
+嗯嗯,不客气,这类工具都是比较常用的,还有 codepen 之类的
+
lencx:
+学技术,只盯着公众号,很有限。要自己拓宽知识面,而不是吃别人嚼过的。如何学习,如何获取信息,如何思考,如何解决问题,我觉得才是最重要的。
+
Veda@Angie:
+如何学习:
+最常用的是视频学习方式:拉勾、慕课网、B站,一般边看边敲,或看完几节再动手敲
+获取信息:
+搜索引擎、各种技术网站、公众号
+
Veda@Angie:
+解决问题:
+一般是搜索引擎,谷歌或百度,如果实在解决不了就问别人
+
Veda@Angie:
+如何高效、深度思考我太欠缺了,很多问题只能看到表面,看不透深层
+
lencx:
+这些只属于入门级学习方式
+
Veda@Angie:
+学习方式也有问题,大部分时间属于被动接受。。
+
lencx:
+高效的学习方式,是知道自己想要什么
+
Veda@Angie:
+我是感觉自己效率不太高,但是却不知道怎么改善[流泪]
+
lencx:
+就是被这帮公众号惯坏了,丧失了捕猎的技巧,只会等着被投喂
+
Veda@Angie:
+工作之余,晚上回去不晚的话会学一点,周末学一些,可利用的学习时间也不多
+
lencx:
+你要学会主动获取自己想要的信息,这是第一步,然后就是根据自己的需求,拓宽知识面,然后就是读文档。
+
Veda@Angie:
+最难的还有一步,就是不知道自己想要什么。。。
+
Veda@Angie:
+就是有一股劲,不知道往哪个方向上使
+
Veda@Angie:
+今天遇到的问题,我可能需要去看一下 vue 的源码、以及再过一下它的文档
+
Veda@Angie:
+这是不是“主动获取自己想要的信息”的一种表现[可怜]
+
Veda@Angie:
+还是别的其他的理解,啥都可以直说的哈,我在工作中也是直性子有啥说啥的[破涕为笑]
+
lencx:
+这个不是看不看文档的问题,我现在问你,你能把自己遇到的问题,拆解成 1, 2, 3, ... 步骤吗
+
lencx:
+
+我遇到了什么问题
+为什么会出现这个问题
+这个问题出现后,我应该怎么办
+我如何分析这个问题
+别人遇到同样的问题,如何定位,思考
+文档我是否都了解清楚了
+我尝试了哪些方法
+问题解决了,我学会了什么
+如果下次遇到同样的问题,我该怎么办
+
+
我暂时就想到这些,你觉得你做到了哪些
+
lencx:
+这是解决问题的基本流程
+
lencx:
+答案毫无用处,因为它并不能让你举一反三
+
lencx:
+这些东西,大部分,从公众号,视频上,是学不到的。需要自己动手折腾,思考
+
Veda@Angie:
+只做到了三四条。。。
+
lencx:
+形成自己解决问题的方法论,它是一个通用的解决问题的手段。
+
Veda@Angie:
+折腾了,但思考的太少了
+
lencx:
+很多时候,别人问我的问题,我也不会,但是有些问题,我可以解答,那是因为,我有自己的解题思路
+
Veda@Angie:
+我是动手的时间比思考的时间多,这样看是搞反了
+
lencx:
+是总结少了,而且少了解题的步骤,但是这个步骤恰恰是最关键的,它需要你去分析问题,拆解问题,将未知变成已知,用已经掌握的去推导陌生的
+
Veda@Angie:
+说的太对了
+
Veda@Angie:
+我经常会遇到那种重复性的问题,很久以前遇到过的,但就是想不起来当初是怎么解决的了,只有去翻看以前的代码或笔记才能想起来
+
lencx:
+动手没有错,错的是光动手其实没啥太大意义。因为动手是机械性的动作。代码是你逻辑思维的具象化。
+
Veda@Angie:
+如果没有代码或笔记参考,我就得重新把那个问题再来解决一遍
+
lencx:
+你需要做的事抽象为自身可以理解的事物,而不是去记代码,记以前解决问题的答案,毫无意义(一些固定流程,可以笔记,作为参考,快速查阅)。你需要记住的是你是如何拆解问题,如何解决问题的流程,然后去强化它。这样,任何时候,碰到这个问题,或者是新问题,你都可以套用你解决问题的流程模板
+
Veda@Angie:
+我之前都没往这方面想过,这似乎也适用于生活等其他方面的问题解决
+
Veda@Angie:
+感谢你的提点,提醒了我,我有必要重新审视自己的学习习惯、思考方式了
+
Veda@Angie:
+还有好长的路要走
+
lencx:
+是的
+
lencx:
+这个没有什么捷径,我自己也走了好几年的弯路
+
lencx:
+所以我把我很多的经验,拿出来分享了,但是似乎群友看的并不多。
+
lencx:
+每个人都有自己选择的自由,我也会重新审视自己
+
Veda@Angie:
+还是看人,就像现在很多时候流量至上,写的好呢东西有深度的东西看得人就少了,被看得多的倒是那些浅显的。。
+你的分享给我了很多启发、指导,这些经验也会慢慢沉淀,到了一定时候好的东西自然会被发现也被大众接受的
+
Veda@Angie:
+你的分享我觉得很受用,所以坚持做对的事啦
+
lencx:
+我的分享,有一二人懂,足以。
+
Veda@Angie:
+一起坚持、
+
Veda@Angie:
+坚持比努力更重要、哈哈这是我喜欢的一句话
+
lencx:
+嗯嗯,时间复利
+
Veda@Angie:
+嗯嗯新的一年,一起加油
+
lencx:
+那我再告诉你一句话:正确的坚持比坚持更重要,不然就是南辕北辙
+
Veda@Angie:
+对,因为还有一句话,选择比努力更重要
+
lencx:
+嗯嗯
+
参考资料 [1] https://codesandbox.io/: https://codesandbox.io/
+
+
+
+
diff --git a/posts/issues-0080/index.html b/posts/issues-0080/index.html
new file mode 100644
index 0000000..f6a528b
--- /dev/null
+++ b/posts/issues-0080/index.html
@@ -0,0 +1,184 @@
+
+
+
+
+
+
+
+
+什么字体更适合程序员?
+
+
+
+Fira Code[1] - 带有连字的免费等宽字体
+
+
+
+Nerd Fonts[2] - 修补了具有大量字形(图标)的开发人员目标字体。特别是从流行的“标志性字体”中添加大量额外的字形,例如 Font Awesome[3] 、Devicons[4] 、Octicons[5] 等。3,600 多个图标,50 多种修补字体,如 Hack、Source Code Pro 等。
+
+
+
+
+Operator Mono[6] - 对编码友好的字体,Operator Mono 字体本身并不支持类似于 Fira Code 的连字,但是在社区有个工具专门针对 Operator Mono 字体做连字处理。
+
+
+
+
+
制作连字的 Operator Mono 字体
+
第一步:下载项目
+
首先要有 Operator Mono 字体(网上自行搜索),然后访问下面这个项目,下载到本地。
+
+项目: https://github.com/kiliman/operator-mono-lig[7] - 向 Operator Mono 添加连字,类似于 Fira Code。
+压缩包下载链接:点击下载[8]
+
+
第二步:前置环境准备
+
+如果遇到环境安装问题,可以在评论区交流
+
+
+Operator Mono 字体文件
+Python (v2.7+)
+Node.js
+从 fonttools/fonttools[9] 安装 fonttools
+
+Windows/Linux: pip install fonttools
+注意事项: 对于 Windows,如果您的 Python 位于 C:\PythonX
下,您应该使用具有管理权限的控制台
+注意事项: 对于 WSL/WSL2 中的 Linux,请确保安装后将 fonttools
添加到 PATH。或者,考虑通过 sudo apt install fonttools
安装。
+Mac: pip3 install fonttools
+
+
+
+
第三步:安装依赖及构建
+
+
+压缩包解压,然后进入到文件夹下执行
+# 使用 npm 安装可能会出现 node-gyp 之类的错误,可以尝试使用 yarn 安装
+npm install
+
+
+将 Operator Mono字体文件放到 original 目录下,然后执行脚本
+# Windows
+build
+
+# Linux/Mac
+./build.sh
+
+
+生成的 Operator Mono Lig 字体在 build 文件夹下,点击安装即可
+
+
+
字体效果预览
+
我的 vscode 配置[10]
+
+
参考资料 [1] Fira Code: https://github.com/tonsky/FiraCode
+[2] Nerd Fonts: https://github.com/ryanoasis/nerd-fonts
+[3] Font Awesome: https://github.com/FortAwesome/Font-Awesome
+[4] Devicons: http://vorillaz.github.io/devicons/
+[5] Octicons: https://github.com/github/octicons
+[6] Operator Mono: https://www.typography.com/fonts/operator/styles
+[7] https://github.com/kiliman/operator-mono-lig: https://github.com/kiliman/operator-mono-lig
+[8] 点击下载: https://github.com/kiliman/operator-mono-lig/archive/refs/tags/v2.4.1.zip
+[9] fonttools/fonttools: https://github.com/fonttools/fonttools
+[10] 我的 vscode 配置: https://github.com/lencx/z/discussions/41
+
+
+
+
diff --git a/posts/issues-0081/index.html b/posts/issues-0081/index.html
new file mode 100644
index 0000000..00ccf26
--- /dev/null
+++ b/posts/issues-0081/index.html
@@ -0,0 +1,128 @@
+
+
+
+
+
+
+
+
+如何提升写作技巧?
+
+
+针对图片内容并结合自身写作经历,做了部分改编
+
+
+更多更广泛的阅读
+每天坚持写作,熟能生巧
+保持一致很重要,找到自己的写作风格
+明确目标,知道自己为何而写作
+了解你的受众,直击他们的痛点
+使用副标题来帮助略读者快速找到重点
+不滥用各种形容词凑字数,简单直接地写作
+惜字如金,保持文章结构的紧凑
+用真实经历并加入一些讲故事的技巧,使文章内容更饱满
+善用关键字和 SEO,以使文章在搜索引擎中获得更高排名
+修改之前先完成初稿,编辑未完成的作品是禁忌,它会减慢你写文章的速度并导致倦怠
+创作完成后,不要急于发布。反复斟酌,会一些发现错误、奇怪的措辞或令人困惑的句子
+从读者那里获得反馈,尽最大努力将更好的想法融入到未来的写作中
+对批评持开放态度,虚心学习,让自己变得更优秀
+
+
+
参考资料
+
+
+
+
diff --git a/posts/issues-0082/index.html b/posts/issues-0082/index.html
new file mode 100644
index 0000000..ca27446
--- /dev/null
+++ b/posts/issues-0082/index.html
@@ -0,0 +1,201 @@
+
+
+
+
+
+
+
+
+微信杂谈 - 实习简历如何写
+
+
📅 2022.02.23
+
只想吃白菜:
+大佬你先看看我简历
+
只想吃白菜:
+看看够资格不
+
只想吃白菜:
+[苦涩]双非二本,艺术专业
+
lencx:
+学历虽然很重要,但是你自身的技术也占很大部分,不用妄自菲薄
+
只想吃白菜:
+我现在最大的顾虑是我之前做的项目比较水
+
只想吃白菜:
+就是东西我做出来了
+
只想吃白菜:
+细问的话,我感觉没什么技术点可以深入聊
+
只想吃白菜:
+我差不多都能做,但要是和我聊技术点,让我从项目聊好久,聊不了,我不知道说啥
+
lencx:
+项目是聊你的经历的,没做过复杂项目,单纯靠包装很难,也容易露馅
+
只想吃白菜:
+这个情况怎么做会比较好呀
+
只想吃白菜:
+我项目这一块的问题
+
只想吃白菜:
+我有时间可以自己耗精力去弄
+
只想吃白菜:
+但是不知道如何去弄
+
lencx:
+项目因为你本身就是实习,没接触过大项目很正常,你可以了解一些项目相关的开发流程,还有就是让自己的基础扎实一些
+
只想吃白菜:
+基础指的就是:数据结构、计网这种嘛
+
只想吃白菜:
+挑几个点深入了解
+
只想吃白菜:
+然后去谈?
+
lencx:
+我也没实习经验,给不出太好的建议,我都是走社招的
+
只想吃白菜:
+比较发愁
+
lencx:
+你是19-20年实习,现在都 22 年了,你是啥时候毕业的
+
只想吃白菜:
+22毕业
+
只想吃白菜:
+19那次是在一个小微企业
+
只想吃白菜:
+兼职一样,一周上两天
+
只想吃白菜:
+那个时候我大二,原生做了两个网站,一个在我这,一个公司拿去用了
+
lencx:
+哦哦,那你还是走校招吧,走社招更难,看你的简历,是不太具有优势
+
只想吃白菜:
+如果要具有一定优势的话,应该怎么做?
+
只想吃白菜:
+大佬明示一下
+
只想吃白菜:
+我做充分准备
+
只想吃白菜:
+我不想放弃做开发[苦涩]
+
lencx:
+项目和基础都很重要,没有项目经验,你可以让自己基础扎实点
+
lencx:
+js,算法,数据结构,还有就是计算机基础之类的
+
lencx:
+项目经验很难包装,没做过的不建议瞎写,很容易被问死
+
只想吃白菜:
+我可以实际去写,但是不知道该去做什么
+
lencx:
+实际的项目,并没有看到你的亮点
+
lencx:
+有点平了
+
lencx:
+还有就是你放了 github ,但是最近一年都没怎么更新
+
只想吃白菜:
+我知道,我其实可以现在再去开发,然后把那些是亮点的东西做一遍
+
只想吃白菜:
+github这个确实[苦涩]在搞毕业的事,没去提交代码
+
lencx:
+亮点不是靠做出来的,而是你在实际开发中解决棘手问题的解决方案
+
只想吃白菜:
+那这么说来
+
只想吃白菜:
+项目的事,没得解决了
+
只想吃白菜:
+就只能从基础和深度上解决我的问题
+
lencx:
+以你目前的经历来说,很难包装
+
lencx:
+差不多是这个意思
+
只想吃白菜:
+懂啦
+
只想吃白菜:
+谢谢您
+
参考资料
+
+
+
+
diff --git a/posts/issues-0083/index.html b/posts/issues-0083/index.html
new file mode 100644
index 0000000..d7a00e2
--- /dev/null
+++ b/posts/issues-0083/index.html
@@ -0,0 +1,200 @@
+
+
+
+
+
+
+
+
+微信杂谈 - 代码优化
+
+
📅 2022.02.23
+
Ice:
+这种代码怎么优化一下
+
+
lencx:
+策略模式
+
Ice:
+什么意思
+
lencx:
+额,或者 switch
+
lencx:
+其实 if 也还好吧
+
Ice:
+要写好长if
+
lencx:
+其实这么写条件不好
+
Ice:
+那我该怎么写
+
lencx:
+最好是把校验规则抽象出来
+
lencx:
+至于校验规则怎么抽象,需要看业务需求
+
Ice:
+我就判断每一行的单元格不能为空保存的时候
+
张浩:
+switch
+
张浩:
+据说性能会很高
+
lencx:
+其实我建议根据需求把规则做抽象,每个字段对应的校验文案其实是固定的,然后就是一个拼装问题
+
lencx:
+但是过度抽象反而不如 if 这种更直白,所以需要自己权衡一下未来需求的迭代,保证一定的可扩展性
+
lencx:
+其实就是做一个通用的校验器
+
lencx:
+只需要接收数据源就可以返回校验文案
+
lencx:
+以及是否通过的状态
+
lencx:
+举个例子,看你这个截图,其实每个字段都对应一个文案,比如最高分,最低分,然后通过逗号连接,不能为空!
+这就是规则:aaa, bbb, ccc 不能为空!
+aaa, bbb, ccc 可以通过数组做收集
+
Ice:
+是噢
+
张浩:
+哦,然后封装一个方法,循环这个规则数组,如果有一项false,直接返回具体原因
+
张浩:
+否则返回true?
+
lencx:
+数组做收集,你只需要对字段做遍历就好了,不满足的就收集。
+
张浩:
+哦哦
+
lencx:
+这个看个人,实现方法有很多,我只是举例而已。
+
张浩:
+好的学习了
+
柒冉:
+学到了
+
lencx:
+这样你可以针对分数写一个校验器,只接收数据源,然后返回处理结果,后期需求变更,只需要重新实现校验器即可。数据做好格式化输出。你的校验器对调用者来说就是一个黑盒。
+
张浩:
+大佬,那如果是一个表单,里面有很多条件,那种校验应该如何封装比较好
+
张浩:
+也要对每个字段分别封装吗
+
lencx:
+一样的思路,核心思想就是做到:UI,Data, 业务逻辑之间的解耦。按照这个思路去拆。函数式编程思想。
+
张浩:
+嗯嗯,我想下
+
lencx:
+你抽象的东西就是一个黑盒,保证输入,输出源的一致性,内部怎么实现我并不关系。
+
张浩:
+嗯嗯
+
lencx:
+这个没有什么通用式,一站式解决方案,多写,多思考,自己慢慢就找到感觉了,当你觉得某个地方的代码特别繁琐,改起来很复杂,牵一发而动全身,一般就是对代码结构的思考有所欠缺了。
+
张浩:
+嗯嗯
+
张浩:
+感觉自己还是抽象的不够彻底,每次都是写完代码之后,发现,这地方为啥不抽个方法出来。。。。
+
lencx:
+代码都是边写边优化的,过早优化,可能会导致扩展性不足。
+
lencx:
+反而越改越麻烦
+
张浩:
+嗯嗯
+
lencx:
+写代码的一般流程:
+先实现功能 -> 找代码共性 -> 思考优化 -> 重构
+比较厉害的,可以根据自己的经验给未来的需求留出口子,方便扩展
+
张浩:
+我都是写完之后就拉倒了哈哈,以后注意下,review一下[捂脸]
+
lencx:
+虽然不可以一步抽象到位,但是可以边写边思考,边优化。这就是迭代。需求需要迭代,代码也需要迭代。
+
参考资料
+
+
+
+
diff --git a/posts/issues-0084/index.html b/posts/issues-0084/index.html
new file mode 100644
index 0000000..6d051e7
--- /dev/null
+++ b/posts/issues-0084/index.html
@@ -0,0 +1,133 @@
+
+
+
+
+
+
+
+
+微信杂谈 - 技术社交很重要
+
+
📅 2022.03.03
+
杰拉德 (Gerrard):
+技术真好玩 可惜我不是学coding的
+
lencx:
+有好的师傅领还是很重要的,我一路自学过来,走过好几年的弯路
+
lencx:
+本来问人可能就是一句话的事情,但是对我来说,可能要花几周,甚至更久,还记得入行那会,一个环境配置,我断断续续自己折腾了几个月才搞好。
+
lencx:
+所以我每天动态发朋友圈,也是有私心的,加的大佬多了,一定程度上,也是对自己的曝光。
+
lencx:
+虽然不一定有人看,但是看到了就可能是一次机会。
+
杰拉德 (Gerrard):
+社交是有用的
+
lencx:
+其实我也想开了,就混混社区也挺好,不一定非要去什么大厂。
+
杰拉德 (Gerrard):
+有人带肯定更好
+
lencx:
+技术就是用来实践的,既然没有平台可以发挥,那么参与开源也是一种学习和实践的途径。
+
lencx:
+关于有人带这个话题,在我看来或许也不是很重要了,因为这么多年,我也以为遇到问题会有人帮你,以前小公司是没条件,现在虽说这个公司不小,但是遇到问题,依旧需要自己去解决。问人也并非是什么上策。我也已经过了需要让人带(入行时很重要)的年纪了。
+
杰拉德 (Gerrard):
+也是 而且兴趣是源动力 有就有 没有就自学[拳头]
+
lencx:
+是的
+
参考资料
+
+
+
+
diff --git a/posts/issues-0085/index.html b/posts/issues-0085/index.html
new file mode 100644
index 0000000..28b3f6f
--- /dev/null
+++ b/posts/issues-0085/index.html
@@ -0,0 +1,317 @@
+
+
+
+
+
+
+
+
+开发利器之命令行
+
+
+高效使用命令行是程序员必备的技能
+
+
以下资源均被收录在 lencx/awesome(关于各种有趣主题的精彩列表)[1] ,包含 weekly,rust, webAssembly,js,css,tools 等不同主题。
+
zsh
+
Oh My Zsh[2] - Oh My zsh 是一个开源的、社区驱动的框架,用于管理您的 zsh 配置。
+
+antigen[3] - 是一小组功能,可帮助您轻松管理 shell (zsh) 插件,称为捆绑包。这个概念与典型的 vim + pathogen 设置中的包几乎相同。 Antigen 之于 zsh,Vundle 之于 vim。
+zsh-autosuggestions[4] - zsh 的类似 Fish[5] 的快速/不显眼的自动建议。它根据历史记录和完成建议您键入的命令。
+zsh-syntax-highlighting[6] - 类似 Fish shell[7] 的语法高亮显示。
+history-substring-search[8] - 历史搜索功能,您可以在其中键入历史中任何命令的任何部分,然后按选择的键,例如向上和向下箭头,以循环匹配。
+spaceship[9] - 是一个简约、强大且高度可定制的 Zsh 提示符。它结合了方便工作所需的一切,没有不必要的复杂性,就像真正的宇宙飞船一样。
+starship[10] - 适用于任何 shell 的最小、极快且可无限定制的提示!是 spaceship 的替代品。
+
+
+
bat
+
bat[11] - 类似 cat(1),但带有 git 集成和语法高亮。
+
+
fd
+
fd[12] - 是一种简单快速和用户友好的 find
替代方案。
+
+
git
+
gh
+
gh[13] - GitHub CLI 或 gh 是 GitHub 的命令行界面,可在您的终端或脚本中使用。
+
+
gix
+
gix[14] - gix 是用于访问 git 存储库的命令行界面 ( CLI )。它是为了优化用户体验而编写的,其性能与规范实现一样好或更好。此外,它以各种小型 crate
的形式提供了一个简单且安全的 API ,用于轻松实现自己的工具。
+
dura
+
dura[15] - Dura 是一个后台进程,它监视您的 Git 存储库并提交您未提交的更改,而不会影响 HEAD、当前分支或 Git 索引(暂存文件)。如果您遇到异常导致工作内容丢失,进入 dura 分支可以恢复。如果没有 dura,可以在编辑器中使用 Ctrl-Z
来恢复状态。2021 年就是这样。计算机崩溃,Ctrl-Z
只能独立处理文件。Dura 快照随时更改整个存储库,因此可以恢复到“4 小时前”而不是“按 Ctrl-Z 40 次或其他”。
+
delta
+
delta[16] - 用于 git
、diff
和 grep
输出的语法高亮分页器。
+
+
tig
+
tig[17] - Git 的文本模式界面。
+
+
git-journal
+
git-journal[18] - Git 提交消息和变更日志生成框架。
+
+
ls
+
exa
+
exa[19] - 是 ls
的现代替代品。
+
+
lsd
+
lsd[20] - 下一代 ls
命令。
+
+
nat
+
nat[21] - 具有有用信息和色彩的 ls
替代品。
+
+
just
+
just[22] - 是保存和运行项目的特定命令的简便方法,其语法受 make
启发。
+
+
Asciinema
+
asciinema[23] - 是一个免费的开源的轻量级、纯文本终端录制方法。以正确的方式记录和分享您的终端会话。
+
+
fff
+
fff[24] - 用 bash 编写的简单文件管理器。
+
+
Watchexec
+
watchexec[25] 是一个简单的独立工具,它监视路径并在检测到修改时运行命令。
+
+
Ripgrep
+
ripgrep[26] - 是一种面向行的搜索工具,它递归地在当前目录中搜索正则表达式模式。默认情况下,ripgrep 将遵守 gitignore 规则并自动跳过隐藏文件/目录和二进制文件。
+
+
Hexyl
+
hexyl[27] - 是一个简单的终端十六进制查看器。它使用彩色输出来区分不同类别的字节(NULL 字节、可打印的 ASCII 字符、ASCII 空白字符、其他 ASCII 字符和非 ASCII)。
+
+
Zellij
+
zellij[28] - 是一个面向开发人员、面向运维的人员和任何喜欢终端的人的工作区。它的核心是一个终端多路复用器(类似于 tmux[29] 和 screen[30] ),但这仅仅是它的基础设施层。
+
+
Image
+
cavif
+
cavif[31] - AVIF 图像的编码器/转换器,纯 Rust 实现。
+
cavif --quality 60 image.png
+
svgcleaner
+
svgcleaner[32] - 清理 SVG 文件中不必要的数据。
+
svgcleaner --indent=2 --paths-coordinates-precision=5 --join-arcto-flags=yes in.svg out.svg
+
CSV
+
xsv
+
xsv[33] 是一个用于索引、切片、分析、拆分和连接 CSV 文件的命令行程序。
+
$ xsv stats worldcitiespop.csv --everything | xsv table
+field type min max min_length max_length mean stddev median mode cardinality
+Country Unicode ad zw 2 2 cn 234
+City Unicode bab el ahmar Þykkvibaer 1 91 san jose 2351892
+AccentCity Unicode Bâb el Ahmar ïn Bou Chella 1 91 San Antonio 2375760
+Region Unicode 00 Z9 0 2 13 04 397
+Population Integer 7 31480498 0 8 47719.570634 302885.559204 10779 28754
+Latitude Float -54.933333 82.483333 1 12 27.188166 21.952614 32.497222 51.15 1038349
+Longitude Float -179.983333 180 1 14 37.08886 63.22301 35.28 23.8 1167162
+
csview
+
csview[34] - 带有 cjk[35] /emoji 支持的 cli 的漂亮 csv 查看器。
+
+
Tokei
+
tokei[36] - 是一个显示代码统计信息的程序。 Tokei 将显示文件数、这些文件中的总行数以及按语言分组的代码、注释和空白。
+
===============================================================================
+ Language Files Lines Code Comments Blanks
+===============================================================================
+ BASH 4 49 30 10 9
+ JSON 1 1332 1332 0 0
+ Shell 1 49 38 1 10
+ TOML 2 77 64 4 9
+-------------------------------------------------------------------------------
+ Markdown 5 1355 0 1074 281
+ | - JSON 1 41 41 0 0
+ | - Rust 2 53 42 6 5
+ | - Shell 1 22 18 0 4
+ (Total) 1471 101 1080 290
+-------------------------------------------------------------------------------
+ Rust 19 3416 2840 116 460
+ | - Markdown 12 351 5 295 51
+ (Total) 3767 2845 411 511
+===============================================================================
+ Total 32 6745 4410 1506 829
+===============================================================================
+
procs
+
procs[37] - 是用 Rust 编写的 ps[38] 的替代品。
+
+
eva
+
eva[39] - 简单的计算器 REPL,类似于 bc(1),具有语法高亮和持久历史记录。
+
+
hyperfine
+
hyperfine[40] - 命令行基准测试工具。
+
+
ffsend
+
ffsend[41] - 从命令行轻松安全地共享文件。 一个功能齐全的 Firefox Send 客户端。
+
+
alacritty
+
alacritty[42] - 是一个现代终端仿真器,具有合理的默认值,但允许进行广泛的配置。 通过与其他应用程序集成,而不是重新实现它们的功能,它设法提供了一组灵活的高性能特性。 目前支持的平台包括 BSD、Linux、macOS 和 Windows。
+
+
Node.js
+
nvm
+
nvm[43] - 允许您通过命令行快速安装和使用不同版本的 Node.js
。
+
+
fnm
+
fnm[44] - 快速简单的 Node.js
版本管理器,基于 Rust 实现。
+
+
volta
+
Volta[45] - 快速无缝地安装和运行任何 JS 工具! Volta 是用 Rust 构建的,以二进制文件形式发布,跨平台支持(macOS、Windows、Linux)。
+
+
参考资料 [1] lencx/awesome(关于各种有趣主题的精彩列表): https://github.com/lencx/awesome
+[2] Oh My Zsh: https://github.com/ohmyzsh/ohmyzsh
+[3] antigen: https:/github.com/zsh-users/antigen
+[4] zsh-autosuggestions: https://github.com/zsh-users/zsh-autosuggestions
+[5] Fish: http://fishshell.com
+[6] zsh-syntax-highlighting: https://github.com/zsh-users/zsh-syntax-highlighting
+[7] Fish shell: https://fishshell.com
+[8] history-substring-search: https://github.com/zsh-users/zsh-history-substring-search
+[9] spaceship: https://github.com/spaceship-prompt/spaceship-prompt
+[10] starship: https://github.com/starship/starship
+[11] bat: https://github.com/sharkdp/bat
+[12] fd: https://github.com/sharkdp/fd
+[13] gh: https://cli.github.com
+[14] gix: https://github.com/Byron/gitoxide
+[15] dura: https://github.com/tkellogg/dura
+[16] delta: https://github.com/dandavison/delta
+[17] tig: https://github.com/jonas/tig
+[18] git-journal: https://github.com/saschagrunert/git-journal
+[19] exa: https://github.com/ogham/exa
+[20] lsd: https://github.com/Peltoche/lsd
+[21] nat: https://github.com/willdoescode/nat
+[22] just: https://github.com/casey/just
+[23] asciinema: https://asciinema.org/
+[24] fff: https://github.com/dylanaraps/fff
+[25] watchexec: https://github.com/watchexec/watchexec
+[26] ripgrep: https://github.com/BurntSushi/ripgrep
+[27] hexyl: https://github.com/sharkdp/hexyl
+[28] zellij: https://github.com/zellij-org/zellij
+[29] tmux: https://github.com/tmux/tmux
+[30] screen: https://www.gnu.org/software/screen/
+[31] cavif: https://github.com/kornelski/cavif-rs
+[32] svgcleaner: https://github.com/RazrFalcon/svgcleaner
+[33] xsv: https://github.com/BurntSushi/xsv
+[34] csview: https://github.com/wfxr/csview
+[35] cjk: https://en.wikipedia.org/wiki/CJK_characters
+[36] tokei: https://github.com/XAMPPRocky/tokei
+[37] procs: https://github.com/dalance/procs
+[38] ps: https://man7.org/linux/man-pages/man1/ps.1.html
+[39] eva: https://github.com/nerdypepper/eva
+[40] hyperfine: https://github.com/sharkdp/hyperfine
+[41] ffsend: https://gitlab.com/timvisee/ffsend
+[42] alacritty: https://github.com/alacritty/alacritty
+[43] nvm: https://github.com/nvm-sh/nvm
+[44] fnm: https://github.com/Schniz/fnm
+[45] Volta: https://github.com/volta-cli/volta
+
+
+
+
diff --git a/posts/issues-0086/index.html b/posts/issues-0086/index.html
new file mode 100644
index 0000000..0824262
--- /dev/null
+++ b/posts/issues-0086/index.html
@@ -0,0 +1,127 @@
+
+
+
+
+
+
+
+
+微信杂谈 - 写代码
+
+
📅 2022.04.09
+
lencx:
+写代码其实不难,难的是搞不清楚问题
+
lencx:
+大部分写不下去都是因为自己根本不知道自己写的是个什么东西
+
浦原:
+这个我深有感触
+
浦原:
+写不下去就真的是单纯不知道问题出在哪里
+
lencx:
+学习其实也是这样,用什么语言不重要啊,重要的是你的逻辑要清楚,剩下的事情搜索引擎帮你搞定,基本可以解决百分之八九十的问题
+
lencx:
+只有少部分极难的问题,靠搜索很难搞定,这就牵扯到你的知识推导能力了
+
lencx:
+经验都是虚的,没啥用
+
lencx:
+因为经验会过时,会遗忘,知识的推导过程其实就是你的逻辑思维具像化
+
lencx:
+我是这么认为的
+
参考资料
+
+
+
+
diff --git a/posts/issues-0087/index.html b/posts/issues-0087/index.html
new file mode 100644
index 0000000..b991185
--- /dev/null
+++ b/posts/issues-0087/index.html
@@ -0,0 +1,154 @@
+
+
+
+
+
+
+
+
+微信杂谈 - 学习 Rust
+
+
+不看文档,习惯性把已有经验带入到新语言学习中,感觉学习了很多门语言,本质上都在用同一个思维模式解决问题 ...
+
+
📅 2022.06.06
+
大橙子的小迪子🍊:
+let a = ‘abc’
+
大橙子的小迪子🍊:
+a[0]
+
大橙子的小迪子🍊:
+@lencx[1] rust不允许这样取呀
+
lencx:
+肯定不行啊
+
lencx:
+单引号是 char 类型
+
大橙子的小迪子🍊:
+字符串可以吗
+
lencx:
+看文档
+
lencx:
+写代码不是靠猜啊
+
lencx:
+rust 取索引是通过 .
+
lencx:
+比如 a.0
+
大橙子的小迪子🍊:
+那这个是不是取的字节索引
+
lencx:
+这种问题自己搜 一下不就知道了
+
大橙子的小迪子🍊:
+好的
+
大橙子的小迪子🍊:
+这个变化挺大的
+
lencx:
+学新语言是可以通过对比去学习,但是不能硬套啊,每种语言都有自己的心智模型,而不是写 Rust 版的 JS…
+
lencx:
+看文档就是学习该语言的表达方式
+
不精通react不改名:
+rust版本的js在哪在哪
+
lencx:
+而不是靠经验去猜,毫无意义
+
大橙子的小迪子🍊:
+这个括号里面的数字代表的是字节索引吧
+
lencx:
+用 js 的思维方式写 rust,不就是 rust 版的 js 吗
+
不精通react不改名:
+确实
+
参考资料 [1] @lencx: https://github.com/lencx
+
+
+
+
diff --git a/posts/issues-0088/index.html b/posts/issues-0088/index.html
new file mode 100644
index 0000000..8252d26
--- /dev/null
+++ b/posts/issues-0088/index.html
@@ -0,0 +1,109 @@
+
+
+
+
+
+
+
+
+痛苦学习的快感
+
+
+
+