diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 0000000..e69de29 diff --git a/404.html b/404.html new file mode 100644 index 0000000..ac5b5af --- /dev/null +++ b/404.html @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + +

404

Looks like we've got some broken links.
Take me home
+ + + diff --git a/assets/143302995899560-QLa9npRq.png b/assets/143302995899560-QLa9npRq.png new file mode 100644 index 0000000..2883e44 Binary files /dev/null and b/assets/143302995899560-QLa9npRq.png differ diff --git a/assets/147946907626091-Gwqindbp.png b/assets/147946907626091-Gwqindbp.png new file mode 100644 index 0000000..c1f5c82 Binary files /dev/null and b/assets/147946907626091-Gwqindbp.png differ diff --git a/assets/161005792836721-bV5MJt_O.png b/assets/161005792836721-bV5MJt_O.png new file mode 100644 index 0000000..88a6153 Binary files /dev/null and b/assets/161005792836721-bV5MJt_O.png differ diff --git a/assets/194035815278790-0CpyiHN8.png b/assets/194035815278790-0CpyiHN8.png new file mode 100644 index 0000000..0de7eab Binary files /dev/null and b/assets/194035815278790-0CpyiHN8.png differ diff --git a/assets/19550911278872-YgjUDoc8.png b/assets/19550911278872-YgjUDoc8.png new file mode 100644 index 0000000..8850f5b Binary files /dev/null and b/assets/19550911278872-YgjUDoc8.png differ diff --git "a/assets/2019\345\271\264\345\271\264\345\272\246\346\261\207\346\212\245.html-5zIqPlhA.js" "b/assets/2019\345\271\264\345\271\264\345\272\246\346\261\207\346\212\245.html-5zIqPlhA.js" new file mode 100644 index 0000000..691953c --- /dev/null +++ "b/assets/2019\345\271\264\345\271\264\345\272\246\346\261\207\346\212\245.html-5zIqPlhA.js" @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-070018d8","path":"/notebook/2019%E5%B9%B4%E5%B9%B4%E5%BA%A6%E6%B1%87%E6%8A%A5.html","title":"","lang":"en-US","frontmatter":{},"headers":[{"level":3,"title":"2018.10.1 开封","slug":"_2018-10-1-开封","link":"#_2018-10-1-开封","children":[]},{"level":3,"title":"1月 ~ 2月","slug":"_1月-2月","link":"#_1月-2月","children":[]},{"level":3,"title":"3月","slug":"_3月","link":"#_3月","children":[]},{"level":3,"title":"5月","slug":"_5月","link":"#_5月","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/2019年年度汇报.md"}');export{e as data}; diff --git "a/assets/2019\345\271\264\345\271\264\345\272\246\346\261\207\346\212\245.html-8RXNfl9v.js" "b/assets/2019\345\271\264\345\271\264\345\272\246\346\261\207\346\212\245.html-8RXNfl9v.js" new file mode 100644 index 0000000..140dde8 --- /dev/null +++ "b/assets/2019\345\271\264\345\271\264\345\272\246\346\261\207\346\212\245.html-8RXNfl9v.js" @@ -0,0 +1 @@ +import{_ as e,o as a,c as r,a as _}from"./app-x8p6wK6B.js";const h={},t=_('

2018.10.1 开封

1月 ~ 2月

在家中无限期的游玩

3月

5月

25日 , 海淀区 参加蓝桥杯国赛, 拿到B组二等奖

',6),d=[t];function c(n,i){return a(),r("div",null,d)}const o=e(h,[["render",c],["__file","2019年年度汇报.html.vue"]]);export{o as default}; diff --git a/assets/20200216001653735_883-IQNkpcp5.png b/assets/20200216001653735_883-IQNkpcp5.png new file mode 100644 index 0000000..8f17ae8 Binary files /dev/null and b/assets/20200216001653735_883-IQNkpcp5.png differ diff --git a/assets/20200216003909531_3860-Kd-pzYyS.png b/assets/20200216003909531_3860-Kd-pzYyS.png new file mode 100644 index 0000000..4078592 Binary files /dev/null and b/assets/20200216003909531_3860-Kd-pzYyS.png differ diff --git a/assets/20200216003958555_8778-v9lJg-BZ.png b/assets/20200216003958555_8778-v9lJg-BZ.png new file mode 100644 index 0000000..f6a5c24 Binary files /dev/null and b/assets/20200216003958555_8778-v9lJg-BZ.png differ diff --git a/assets/20200216004851429_31590-ycX-VYgZ.js b/assets/20200216004851429_31590-ycX-VYgZ.js new file mode 100644 index 0000000..68683b3 --- /dev/null +++ b/assets/20200216004851429_31590-ycX-VYgZ.js @@ -0,0 +1 @@ +const A="/assets/20200216005249746_24248-IkKG5FEb.png",K="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAWIAAABTCAIAAAAqb5qRAAAACXBIWXMAABJ0AAASdAHeZh94AAAN3UlEQVR4nO2dP2zcyBXGv/dIyil0hySAsAYMaIF0wQlWYSSAtlWgQqnsJsCpUichqt3KV6QRglQ27E5I4VZOEwUQoOIaOcWpkCLg0q4SA9psdaXN5bwUJLXcXXKGy+VKK+n9KmnJmfk4O3wczp9vaX5+HoqiKMXwbQtQFGXW0TChKIoDDROKojjQMKEoigMNE4qiONAwoSiKAw0TiqI40DChKIoDDROKojjQMKEoigMNE4qiONAwoSiKAw0TiqI40DChKIoDDROKojjQMKEoigMNE4qiONAwoSiKAw0TiqI48Ksl4xfsQcIDqVdNjcy4QmoSPaNZVqgo13hzc3PUJP9bDjbJ/z3xb8n7NeEUjsb7b/AfCN8Pn8bbPBfn8zOYH0FEwRsO0n9vlAKFMwJ/w14L6NRWLdSk4FsyP9STm6Jk8R49euT/iehf0vsLen8XfCH/dzCHJe6uXxP/D+anwQ9Pgd8Q/tl/SMo/gEfo3cozM1fhbCD/EfySGPVFz58gXQ6+BU6pWl3zNlPB48FySHkIMG0RX0h4IEYEgDkx4QV40Z1SDkHrU9c3CbOvsF6kbXqH5G2BiW5bi3KvYG8J5mzgIzkU8yRzxgt+9Ib95kjLuxRp0Ey3yNlXWDdppHhYV61MG5+B8OPAR9IWabtTiog5J28F5mSM8rjF3kYyv2IuIGfSO0k6s9RkfxO8AADmOHltoSb760AD3JEv70BbFCwBXYTfJd0fS4ajConI2yUPCM8RrMJcSHRG3ga4KMP3Ep6kMl6CkRSN5xSsjpwwIt5yXaMVYi4QvUs0OGqjI70r8vNSIY0U/hbhHbKf8wv2VpNLMB1gCUjFK4od90yHOTCfD/IPyQfBLvHHgeZogZrsrSHak7AtRETPyXvcP+RvItpPDnm7FADhgQASnQHLxABtEZ/Jl0P4m4RFoG3LMFehiET7RC/hXcmXHfivyetIbwfeLvEiTBvU4mAD0Z58bgs1yX9JARCeiLRNb4e8XTJxNDmQsME4FNMWq/gkvuC9fD4RapK/ScEV+jfnU/Ig0Q56gLfbj2iW2hAQNcjPS9W/6rb03iEbKajFwVOEexK2JQ5M0Z6YtvTDX8xrAgiAOZbeKRUd0tmZh0bFCdEYEYk6yQ02BpdJWjkQk35G68BRcteJSHREc2vEH2DaIm0QCGvE+9JrC4DwlTgztCnsIko7UNGHVMAT0CV5azDvk1KkLb33NLeWRJls34SIuJOcZhMvQuvAcfrQvkTUAT5llJz3bzlzngmaxbVhOgPTqNlUFugxzHma4UeRNWLAANI24R+Tc3ibMdAxkeJDysNiojABQM5A68Dbcie3TXTO3mvyLmjgdYOIG+ANerRR/EaduS2dGVZUuEi0AMnexp9gFnAdZeSDYAs4AVaIrtzi40NIh35ERN6677RStWHPoUn+OmVfRuQKvEZ8CtMWWiFaQHRZLW/lIeIbYOhhS0S0CDNyT+YTP5qo7HuHOTDmANxiXqZHa3Q9IoDMe/5YWDKsqDB7/1xK3NOOEZEI7DdhlhG9G0yVJ56IaGGsq3FkWIZ4/GJowAIfJVwm7yUFIHQR7WnXQBkDli7o2cBH9JxQ+lEjIuYc3krm387gGYs5Y+7mxPTemi9HCLYyqQY7zzw6t1LMUIYWhTYuRbqDZ64QdwcCh5yB1snrZB7UVvHSHTnUckxDTFIb1GR/XYZjBEDPyYNEexLuyOdXZrRfpigWODoCr1LQSlphvMZ5aIQ8f0I0RT4I1jJNvwNepbhZU5O8TchpP6vgRf9MeozrmCKHwKAMzkzKFqovztCmsOhCRKIj8EZfvL8BczT8WJZG/4rs4pMMV8lvEeK3iRfswd2vqVYbaYzIyV8+iIC8dfJ2KXjDj17lfKHmrSkSZjmkPARofn6eW+ytFc/YveBgFdFeztBA/5xt5sPkhGTGIZ17i/YzQ30t9peBRlpWiSnAuPQ+mZlLZ4ajCqNLeLvkLcAcS9RI51bPERcR7ogRyZ0Q7dcXkbeF3sgQg2XWM7d6r68r/mToX2dtjKbqncJfR5g39hHPlZhsvRH5uxSNvqApSh40Pz9fQy4t9pclt43OCLUoZCJZIR93bLkBEfmvKbtKglscrCFnHEdR8ph0piNhzGHCW2BihbzNwRLMxUxHw1xEpLcHf7M/dWIuEO5rjFDKUk9vQlGUe4za0iiK4kDDhKIoDmoam7hTEBGtAI/Jewod7VeyaNvIZbbCxNBkargvZReDjsUieJkI4AVE9ef+gKAW+xszvdPU0qLyxWvbyKPUSwdvc9HaJMuhCtBzChoS7ciXHYkA75k7CeIlBq0xNEhbem9N793wPjFlbD6KXPT30U2Vcb/lJJWlReWJ17aRywz1JoiInyLaT+Yse6/KPqDoGehqmsqUAkRkdKXZlKjwLdtb1E2Kv+tMawjTucS7LqhJ3qr7tHvGjVWvW0nzJpyypvQt34z4e4CPGfA1ipcJJhHrJXkgoL88nIi8LfKWkpP7y5ljK6p4C2a67TpecG1JNZHOMf21ZJHGsN7KGmFZU1WRbfW8sq9PL8wzNa0JdwatugrK4hZ7y0BHIiSDBeYi2YESrzrvr0mPV7K9l/BE7N9yoTx7iyoQX+qqLUvyC1zU7gH01drXc2vJ0I7N1yglx9coc2iSWzFuENgf3jzC2+whaU+xo5RkNpjEqehouHHbUyFtSZGrwfXPTx2lTOooRecSHgg1iZ4AyxRAQhCfSfQJ/iZF+yJA0SHTFmrx3EbSdmOFcXS2ZFhtQJea5K0TAehI9AECZGusSEapnEfq0FJWcqgBHGXu/458fptsV8na7fA2e2d9GUXfslNebosqEm8/VNQARg/F+3Hvk8eXP/u+RnIo0fWuyktId4qpLFTz1yo6RFTslFXGsGscpNjzyiaj0ndqKSs51Elu9dRwcLbX+GeweJQlZxS7qN11/Nn3NZK2UIuDTcJC0oUpM1NVLVURlf21Cg+5nLIcGdZFGRnT41KA8U0SbwN7Ayjjonan8Wff14i3OWgkr0VJN3JqqexUdpQqzLDYKesmuTUZi3ds+NDSANwuancZP/U1QnQ5i30/arK35B6yuoabFA+sjJXKiYiYzrA5bVxWxRwvRbqDptgrxF2EN9yVu10ZT8CoUtZENV+Jkg3AnBhzgqjFc1v4XM4g9k7AU/I1qnfGLjaeI6L4tQiA/yJ1kctYwlGTs+tnLKkqUM1RqjC3Mk5ZxdRVvRPKqAA/Tb284rKOk7LkCvw0mZ7kFnsNYJn6XoHF3/KNYWkAJV3U7i708z9/PQ1fozKeVwPnb3Ow1P83O2nSn2rqItoX84yC1YHu3/U0VXaez5IqHtvPMsYs4Dj+WnbrLRTMRDpTYczqdTplTTghGhOLsZcVT2ckvmGD33J2Atu8l2iZPOT/2pPFo2zgqotbVJF4pPM+WXJb2nCGpV3U7ij0i79+rb5Gys0wNOup3BXoq2++8jeJU594c4HocDobrpSHTb+XNMFSMeVWUPcqRVEcqC2NoigONEwoiuJgVjaSq2vQ3YVbhMf3bReDkuUWehPU4uANB0MWI4vgZfLSKaXplnX3mZ3rIiI8foh7+R8U3tzc3A0XSf8FLZL5GwYePT/B/CByClonOcRYTyVqsv8NzH9KlzUdLDLqL6vu65pEvPwo+BkxYH6sSY0yY9xCb0JEerX+JiU9K9yEUHtZ1WTUzk3WoaLczhBmja5BTl+jO22vZOEm61B54ND8/HxZT56smxCSX+g1FxKdkbcB7iL8TrBCRQ5FGHENKmsHUsa9KqXvXmUty2YbVezylF+DVhkY3/OKi6vXiBRdl118tTosEj9ch12E59AhzHuMHzc7vJfPJ0JN8jcpuMK1r1GwgWhPPqe+RgEQnsRuIvCu5MsO/NfkdaS3A2+XeBHRJ5FloqfkHUn4xySmBFsS75aLrW6SX74tDW0RQcKdvg+Vf4peW0Sk90qiAl8jS1lF1wWIgKhBPiTaQQ/wdgd3T+Zhl3HtaxSm+9kDIDwQQKIzYJkYoC3iM/lyCH+TsIhoH0XVa9qW67KJr1aHxeIH6jD+yXWcl/9KlTsG0zpwnLaPS0QdRJ+AfF8j8Fra0e32ncujD8kf9CR2KALOsw5FMEsTdY/lUKLD2nyoLNeViO9IeCBGRETMebIrsXpxw5ZHyT5IaYs5ETkDGsSH0jsRaUv4yiTL5Auq14JdfLU6LBIPgJZhjpM6NCcm0hhxr/G5AZwl/4iIXFuSF/sajWcDNbFDUb0+VDfp1zSp51V9VKhDi3gi8pb6zUa59/hkXadQg6/RxA5FU/GhukG/pto9rypQuQ5zxZOa1j8wWLrD/WpuERPhUqSbOLskrBB3B2+wMjwBY/xUKYkP1XdlN62y06mlrusqISNrpjKGwrqpVod28cOvLY06hCqzCkdH4NXUUIiIX7AHxC+3lX2NihyKKlPNvSqXKfk1Fcmo1/NqEirUYZH4oTqMzaa4kf67PSs/NaTUBc3Pz8cj1eNNiC7AHKc2RN1k9g7xj6PE5pq5DkWVXIOquVdZysq9LpRweXJUZYG90lieV87qlcXhH0kpZRtVqQ6LxCd1mP4KlDmWCOQ1ErOp2DaqvHGZMvvU7zehDkWKcs+oeU9H/BCjX5H/W5Lvb2InhaIo00bdqxRFcaC2NIqiONAwoSiKAw0TiqI40DChKIoDDROKojjQMKEoigMNE4qiONAwoSiKAw0TiqI40DChKIoDDROKojj4P5COVzLwBHT+AAAAAElFTkSuQmCC";export{A as _,K as a}; diff --git a/assets/20200216005034283_6861-hoVHTvC9.png b/assets/20200216005034283_6861-hoVHTvC9.png new file mode 100644 index 0000000..730ce3a Binary files /dev/null and b/assets/20200216005034283_6861-hoVHTvC9.png differ diff --git a/assets/20200216005249746_24248-IkKG5FEb.png b/assets/20200216005249746_24248-IkKG5FEb.png new file mode 100644 index 0000000..4bb8720 Binary files /dev/null and b/assets/20200216005249746_24248-IkKG5FEb.png differ diff --git a/assets/20200216005527217_28042-hRMqyCAE.png b/assets/20200216005527217_28042-hRMqyCAE.png new file mode 100644 index 0000000..405be6e Binary files /dev/null and b/assets/20200216005527217_28042-hRMqyCAE.png differ diff --git a/assets/20200216010203757_32340-VomJlKL_.png b/assets/20200216010203757_32340-VomJlKL_.png new file mode 100644 index 0000000..3eb7cb6 Binary files /dev/null and b/assets/20200216010203757_32340-VomJlKL_.png differ diff --git a/assets/20200216010453980_27238-hTvJHllu.png b/assets/20200216010453980_27238-hTvJHllu.png new file mode 100644 index 0000000..b4f8e85 Binary files /dev/null and b/assets/20200216010453980_27238-hTvJHllu.png differ diff --git a/assets/20200216010658929_2127--mQBQPAm.png b/assets/20200216010658929_2127--mQBQPAm.png new file mode 100644 index 0000000..0cf8279 Binary files /dev/null and b/assets/20200216010658929_2127--mQBQPAm.png differ diff --git a/assets/20200216011139813_4073-CFm4jt_m.png b/assets/20200216011139813_4073-CFm4jt_m.png new file mode 100644 index 0000000..783db13 Binary files /dev/null and b/assets/20200216011139813_4073-CFm4jt_m.png differ diff --git a/assets/20200216011249181_32265-KdC56aiJ.png b/assets/20200216011249181_32265-KdC56aiJ.png new file mode 100644 index 0000000..77a08ee Binary files /dev/null and b/assets/20200216011249181_32265-KdC56aiJ.png differ diff --git a/assets/20200216012809191_27147-cjku2_ER.png b/assets/20200216012809191_27147-cjku2_ER.png new file mode 100644 index 0000000..a04a3b4 Binary files /dev/null and b/assets/20200216012809191_27147-cjku2_ER.png differ diff --git a/assets/20200216015749119_31992-XAlIPdu_.png b/assets/20200216015749119_31992-XAlIPdu_.png new file mode 100644 index 0000000..4e3801f Binary files /dev/null and b/assets/20200216015749119_31992-XAlIPdu_.png differ diff --git a/assets/20200216020006936_26223-6nqb2gLR.png b/assets/20200216020006936_26223-6nqb2gLR.png new file mode 100644 index 0000000..1245f2a Binary files /dev/null and b/assets/20200216020006936_26223-6nqb2gLR.png differ diff --git a/assets/20200216020115513_27857-2qK9dJpn.png b/assets/20200216020115513_27857-2qK9dJpn.png new file mode 100644 index 0000000..aeb2bd8 Binary files /dev/null and b/assets/20200216020115513_27857-2qK9dJpn.png differ diff --git a/assets/20200216020714652_5899-vsZEi9Fr.png b/assets/20200216020714652_5899-vsZEi9Fr.png new file mode 100644 index 0000000..77c2d45 Binary files /dev/null and b/assets/20200216020714652_5899-vsZEi9Fr.png differ diff --git a/assets/20200216020814094_3886-Y1sov4DF.png b/assets/20200216020814094_3886-Y1sov4DF.png new file mode 100644 index 0000000..14ff281 Binary files /dev/null and b/assets/20200216020814094_3886-Y1sov4DF.png differ diff --git a/assets/20200216153319843_23184-3ZlR-OOz.png b/assets/20200216153319843_23184-3ZlR-OOz.png new file mode 100644 index 0000000..66a7b18 Binary files /dev/null and b/assets/20200216153319843_23184-3ZlR-OOz.png differ diff --git a/assets/20200216153545000_7574-O4HmZ0GH.png b/assets/20200216153545000_7574-O4HmZ0GH.png new file mode 100644 index 0000000..ab03c88 Binary files /dev/null and b/assets/20200216153545000_7574-O4HmZ0GH.png differ diff --git a/assets/20200216153609444_2629-ixahf16v.png b/assets/20200216153609444_2629-ixahf16v.png new file mode 100644 index 0000000..6349d48 Binary files /dev/null and b/assets/20200216153609444_2629-ixahf16v.png differ diff --git a/assets/20200216154035988_9536-02LS7Lye.png b/assets/20200216154035988_9536-02LS7Lye.png new file mode 100644 index 0000000..286b757 Binary files /dev/null and b/assets/20200216154035988_9536-02LS7Lye.png differ diff --git a/assets/20200216154144431_6911-SPeYXN50.png b/assets/20200216154144431_6911-SPeYXN50.png new file mode 100644 index 0000000..54e36c2 Binary files /dev/null and b/assets/20200216154144431_6911-SPeYXN50.png differ diff --git a/assets/20200216154222027_24290-6_tTy4lT.png b/assets/20200216154222027_24290-6_tTy4lT.png new file mode 100644 index 0000000..e1d4e90 Binary files /dev/null and b/assets/20200216154222027_24290-6_tTy4lT.png differ diff --git a/assets/20200216154335434_2501-StwAyUTR.png b/assets/20200216154335434_2501-StwAyUTR.png new file mode 100644 index 0000000..0b41f6c Binary files /dev/null and b/assets/20200216154335434_2501-StwAyUTR.png differ diff --git a/assets/20200216154747896_13220-aBXmIC1D.png b/assets/20200216154747896_13220-aBXmIC1D.png new file mode 100644 index 0000000..a8d7621 Binary files /dev/null and b/assets/20200216154747896_13220-aBXmIC1D.png differ diff --git a/assets/20200216154959017_19426-XDkjvjMW.png b/assets/20200216154959017_19426-XDkjvjMW.png new file mode 100644 index 0000000..21e78b4 Binary files /dev/null and b/assets/20200216154959017_19426-XDkjvjMW.png differ diff --git a/assets/20200216161057865_16709-Qp-cWsyF.png b/assets/20200216161057865_16709-Qp-cWsyF.png new file mode 100644 index 0000000..2bdcc89 Binary files /dev/null and b/assets/20200216161057865_16709-Qp-cWsyF.png differ diff --git a/assets/20200216161132880_26553-09cgfzSI.png b/assets/20200216161132880_26553-09cgfzSI.png new file mode 100644 index 0000000..767a49c Binary files /dev/null and b/assets/20200216161132880_26553-09cgfzSI.png differ diff --git a/assets/20200216161321957_23988-DgbbbMPg.png b/assets/20200216161321957_23988-DgbbbMPg.png new file mode 100644 index 0000000..4adab96 Binary files /dev/null and b/assets/20200216161321957_23988-DgbbbMPg.png differ diff --git a/assets/20200216162855158_2094-r5FBiv_f.png b/assets/20200216162855158_2094-r5FBiv_f.png new file mode 100644 index 0000000..5dad0ca Binary files /dev/null and b/assets/20200216162855158_2094-r5FBiv_f.png differ diff --git a/assets/20200216164012830_18992-4J4_TkRN.png b/assets/20200216164012830_18992-4J4_TkRN.png new file mode 100644 index 0000000..b3f9f88 Binary files /dev/null and b/assets/20200216164012830_18992-4J4_TkRN.png differ diff --git a/assets/20200313180023826_26780-wWVBxmWt.png b/assets/20200313180023826_26780-wWVBxmWt.png new file mode 100644 index 0000000..2cf775d Binary files /dev/null and b/assets/20200313180023826_26780-wWVBxmWt.png differ diff --git a/assets/20200414193656801_9782-A3TGyBfn.png b/assets/20200414193656801_9782-A3TGyBfn.png new file mode 100644 index 0000000..a00ec34 Binary files /dev/null and b/assets/20200414193656801_9782-A3TGyBfn.png differ diff --git a/assets/20200901183418861_6495-bTW84ikP.png b/assets/20200901183418861_6495-bTW84ikP.png new file mode 100644 index 0000000..4893c64 Binary files /dev/null and b/assets/20200901183418861_6495-bTW84ikP.png differ diff --git a/assets/20200901183528812_6549-HohvyDgv.png b/assets/20200901183528812_6549-HohvyDgv.png new file mode 100644 index 0000000..d394f2f Binary files /dev/null and b/assets/20200901183528812_6549-HohvyDgv.png differ diff --git a/assets/20200901183708535_18118-C3ZqngYK.png b/assets/20200901183708535_18118-C3ZqngYK.png new file mode 100644 index 0000000..fae6e92 Binary files /dev/null and b/assets/20200901183708535_18118-C3ZqngYK.png differ diff --git a/assets/20200901183832304_18855-ATV1U73Z.png b/assets/20200901183832304_18855-ATV1U73Z.png new file mode 100644 index 0000000..6bff48c Binary files /dev/null and b/assets/20200901183832304_18855-ATV1U73Z.png differ diff --git a/assets/20200901193852676_25722-MuH2SkjC.png b/assets/20200901193852676_25722-MuH2SkjC.png new file mode 100644 index 0000000..bf95b4f Binary files /dev/null and b/assets/20200901193852676_25722-MuH2SkjC.png differ diff --git a/assets/20200904175700699_9216-cL-SE0zR.png b/assets/20200904175700699_9216-cL-SE0zR.png new file mode 100644 index 0000000..63b1ffd Binary files /dev/null and b/assets/20200904175700699_9216-cL-SE0zR.png differ diff --git a/assets/20200907113712971_21558-UR7FKPl7.png b/assets/20200907113712971_21558-UR7FKPl7.png new file mode 100644 index 0000000..0bb4174 Binary files /dev/null and b/assets/20200907113712971_21558-UR7FKPl7.png differ diff --git a/assets/20200911144429087_21780-UgjUW2WM.png b/assets/20200911144429087_21780-UgjUW2WM.png new file mode 100644 index 0000000..4f57e43 Binary files /dev/null and b/assets/20200911144429087_21780-UgjUW2WM.png differ diff --git a/assets/20200911144457950_30869-783m7FV3.js b/assets/20200911144457950_30869-783m7FV3.js new file mode 100644 index 0000000..2b61918 --- /dev/null +++ b/assets/20200911144457950_30869-783m7FV3.js @@ -0,0 +1 @@ +const s="/assets/20200911144429087_21780-UgjUW2WM.png",t="/assets/20200911144457950_30869-rGGuu0yj.png";export{s as _,t as a}; diff --git a/assets/20200911144457950_30869-rGGuu0yj.png b/assets/20200911144457950_30869-rGGuu0yj.png new file mode 100644 index 0000000..211be69 Binary files /dev/null and b/assets/20200911144457950_30869-rGGuu0yj.png differ diff --git a/assets/20201028111849591_17629-qHhsPnSN.png b/assets/20201028111849591_17629-qHhsPnSN.png new file mode 100644 index 0000000..4b556f7 Binary files /dev/null and b/assets/20201028111849591_17629-qHhsPnSN.png differ diff --git a/assets/20201028112620077_29096-nP_fmyqj.png b/assets/20201028112620077_29096-nP_fmyqj.png new file mode 100644 index 0000000..592c1c0 Binary files /dev/null and b/assets/20201028112620077_29096-nP_fmyqj.png differ diff --git a/assets/20201028112637988_17637-ZPWbOD8Z.png b/assets/20201028112637988_17637-ZPWbOD8Z.png new file mode 100644 index 0000000..3c88d8b Binary files /dev/null and b/assets/20201028112637988_17637-ZPWbOD8Z.png differ diff --git a/assets/20201028112704364_31298-EEcfg45a.png b/assets/20201028112704364_31298-EEcfg45a.png new file mode 100644 index 0000000..306b651 Binary files /dev/null and b/assets/20201028112704364_31298-EEcfg45a.png differ diff --git a/assets/20201028112723365_22810-ZPTRYmvU.png b/assets/20201028112723365_22810-ZPTRYmvU.png new file mode 100644 index 0000000..0ae546d Binary files /dev/null and b/assets/20201028112723365_22810-ZPTRYmvU.png differ diff --git a/assets/20201028112741659_23346-9v_O1g-B.png b/assets/20201028112741659_23346-9v_O1g-B.png new file mode 100644 index 0000000..25c14bb Binary files /dev/null and b/assets/20201028112741659_23346-9v_O1g-B.png differ diff --git a/assets/20201028113043407_26300-eYJszmty.png b/assets/20201028113043407_26300-eYJszmty.png new file mode 100644 index 0000000..4109b2c Binary files /dev/null and b/assets/20201028113043407_26300-eYJszmty.png differ diff --git a/assets/20201028143720450_16306-kIRzpCo2.png b/assets/20201028143720450_16306-kIRzpCo2.png new file mode 100644 index 0000000..e916e72 Binary files /dev/null and b/assets/20201028143720450_16306-kIRzpCo2.png differ diff --git a/assets/20201028143741429_31672-49mnKWTl.png b/assets/20201028143741429_31672-49mnKWTl.png new file mode 100644 index 0000000..b5185fc Binary files /dev/null and b/assets/20201028143741429_31672-49mnKWTl.png differ diff --git a/assets/20201028143855586_15749-J-YRX282.png b/assets/20201028143855586_15749-J-YRX282.png new file mode 100644 index 0000000..0a8a8e8 Binary files /dev/null and b/assets/20201028143855586_15749-J-YRX282.png differ diff --git a/assets/20201028143917116_14446-Hif_DF24.png b/assets/20201028143917116_14446-Hif_DF24.png new file mode 100644 index 0000000..a960cc1 Binary files /dev/null and b/assets/20201028143917116_14446-Hif_DF24.png differ diff --git a/assets/20201028145335586_24818-wb6LNbXY.png b/assets/20201028145335586_24818-wb6LNbXY.png new file mode 100644 index 0000000..7588a68 Binary files /dev/null and b/assets/20201028145335586_24818-wb6LNbXY.png differ diff --git a/assets/20201028145447224_19742-kmDrGdfN.png b/assets/20201028145447224_19742-kmDrGdfN.png new file mode 100644 index 0000000..0894ef9 Binary files /dev/null and b/assets/20201028145447224_19742-kmDrGdfN.png differ diff --git a/assets/20201028153839771_805-cmkxF9kR.png b/assets/20201028153839771_805-cmkxF9kR.png new file mode 100644 index 0000000..15ad902 Binary files /dev/null and b/assets/20201028153839771_805-cmkxF9kR.png differ diff --git a/assets/20201028154016449_11872-hdGUXOME.png b/assets/20201028154016449_11872-hdGUXOME.png new file mode 100644 index 0000000..3ffd43d Binary files /dev/null and b/assets/20201028154016449_11872-hdGUXOME.png differ diff --git a/assets/20210706000854738_8657-_CyPZxwc.png b/assets/20210706000854738_8657-_CyPZxwc.png new file mode 100644 index 0000000..559dfa6 Binary files /dev/null and b/assets/20210706000854738_8657-_CyPZxwc.png differ diff --git a/assets/20210710111354832_28033-d6IVyjbP.png b/assets/20210710111354832_28033-d6IVyjbP.png new file mode 100644 index 0000000..6e05695 Binary files /dev/null and b/assets/20210710111354832_28033-d6IVyjbP.png differ diff --git a/assets/20210710111622380_22277-rkxmw4x3.png b/assets/20210710111622380_22277-rkxmw4x3.png new file mode 100644 index 0000000..e848a15 Binary files /dev/null and b/assets/20210710111622380_22277-rkxmw4x3.png differ diff --git a/assets/20210710111717516_31301-jnrMYRo7.png b/assets/20210710111717516_31301-jnrMYRo7.png new file mode 100644 index 0000000..e248fdf Binary files /dev/null and b/assets/20210710111717516_31301-jnrMYRo7.png differ diff --git a/assets/20210710111828345_24528-wV1biks8.png b/assets/20210710111828345_24528-wV1biks8.png new file mode 100644 index 0000000..97f56e6 Binary files /dev/null and b/assets/20210710111828345_24528-wV1biks8.png differ diff --git a/assets/20210712122339853_29496-WHb4SxrT.png b/assets/20210712122339853_29496-WHb4SxrT.png new file mode 100644 index 0000000..331b870 Binary files /dev/null and b/assets/20210712122339853_29496-WHb4SxrT.png differ diff --git a/assets/20210712122439699_5581-wNjEpKjZ.png b/assets/20210712122439699_5581-wNjEpKjZ.png new file mode 100644 index 0000000..f4aec84 Binary files /dev/null and b/assets/20210712122439699_5581-wNjEpKjZ.png differ diff --git a/assets/20210712122457899_22964--zHa_imy.png b/assets/20210712122457899_22964--zHa_imy.png new file mode 100644 index 0000000..5ca9d32 Binary files /dev/null and b/assets/20210712122457899_22964--zHa_imy.png differ diff --git a/assets/20210818031909887_21744-zbqdqOVa.png b/assets/20210818031909887_21744-zbqdqOVa.png new file mode 100644 index 0000000..e6aee15 Binary files /dev/null and b/assets/20210818031909887_21744-zbqdqOVa.png differ diff --git "a/assets/2022-8\346\234\272\346\242\260\351\224\256\347\233\230\351\234\200\346\261\202.html-UPAJYpuk.js" "b/assets/2022-8\346\234\272\346\242\260\351\224\256\347\233\230\351\234\200\346\261\202.html-UPAJYpuk.js" new file mode 100644 index 0000000..79e717a --- /dev/null +++ "b/assets/2022-8\346\234\272\346\242\260\351\224\256\347\233\230\351\234\200\346\261\202.html-UPAJYpuk.js" @@ -0,0 +1 @@ +const l=JSON.parse('{"key":"v-1d07bef0","path":"/notebook/2022-8%E6%9C%BA%E6%A2%B0%E9%94%AE%E7%9B%98%E9%9C%80%E6%B1%82.html","title":"2022-8机械键盘需求","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"用过的","slug":"用过的","link":"#用过的","children":[{"level":3,"title":"雷柏 V805","slug":"雷柏-v805","link":"#雷柏-v805","children":[]},{"level":3,"title":"宁芝 82","slug":"宁芝-82","link":"#宁芝-82","children":[]}]},{"level":2,"title":"1公司用","slug":"_1公司用","link":"#_1公司用","children":[{"level":3,"title":"罗技MX keys","slug":"罗技mx-keys","link":"#罗技mx-keys","children":[]},{"level":3,"title":"Keychen K3","slug":"keychen-k3","link":"#keychen-k3","children":[]},{"level":3,"title":"TTC金粉,茶静","slug":"ttc金粉-茶静","link":"#ttc金粉-茶静","children":[]}]},{"level":2,"title":"2家里用","slug":"_2家里用","link":"#_2家里用","children":[{"level":3,"title":"rk 87","slug":"rk-87","link":"#rk-87","children":[]},{"level":3,"title":"黑峡谷","slug":"黑峡谷","link":"#黑峡谷","children":[]},{"level":3,"title":"rk 98","slug":"rk-98","link":"#rk-98","children":[]},{"level":3,"title":"达尔优","slug":"达尔优","link":"#达尔优","children":[]},{"level":3,"title":"fl cmk 98","slug":"fl-cmk-98","link":"#fl-cmk-98","children":[]},{"level":3,"title":"akko","slug":"akko","link":"#akko","children":[]},{"level":3,"title":"珂芝","slug":"珂芝","link":"#珂芝","children":[]}]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/2022-8机械键盘需求.md"}');export{l as data}; diff --git "a/assets/2022-8\346\234\272\346\242\260\351\224\256\347\233\230\351\234\200\346\261\202.html-aZY-ZaE9.js" "b/assets/2022-8\346\234\272\346\242\260\351\224\256\347\233\230\351\234\200\346\261\202.html-aZY-ZaE9.js" new file mode 100644 index 0000000..472e0b7 --- /dev/null +++ "b/assets/2022-8\346\234\272\346\242\260\351\224\256\347\233\230\351\234\200\346\261\202.html-aZY-ZaE9.js" @@ -0,0 +1 @@ +import{_ as a,o as s,c as e,a as r}from"./app-x8p6wK6B.js";const t="/assets/20220802173939155_6597-6CHxBUTj.png",i="/assets/20220802173903823_21890-rdVdbSQy.png",h="/assets/20220802174217434_8203-b7mhjjOk.png",n="/assets/20220802170125044_2240-saycqpps.png",c="/assets/20220802173323861_22313-e3oQHXwO.png",d="/assets/20220802173421936_17841-ZoMXgp70.png",_="/assets/20220731200548028_21925-1KbHrxHX.png",p="/assets/20220731201044629_4162-XhCkaSEq.png",o="/assets/20220731200136604_337-msppGkIG.png",m="/assets/20220731201214493_26640-09KLe87h.png",l="/assets/20220731200115907_6521-aRB7RXRV.png",g="/assets/20220731202148112_32356-Uad1VhED.png",k="/assets/20220731195820978_26214-5JUUyO_y.png",f="/assets/20220731202427851_1049-GhavgIqK.png",x="/assets/20220731195842725_13203-Q152G8IA.png",u="/assets/20220731202736174_29464-i9gqiiZg.png",b="/assets/20220731200011685_26497-jZk7Q90Z.png",y="/assets/20220731200036072_1414-FBC2yiUK.png",K="/assets/20220731202934975_22322-Z_KijlGG.png",j={},G=r('

2022-8机械键盘需求

用过的

雷柏 V805

https://item.jd.com/4619025.html#product-detail

宁芝 82

1公司用

好看就行,104, 87, 84

罗技MX keys

mx keys 399 430.2mm×131.6mm×20.5mm 2.4g+蓝牙+有线

Keychen K3

有线+蓝牙 无背光

TTC金粉,茶静

2家里用

< 30cm

无线

rk 87

黑峡谷

rk 98

40 mm高

达尔优

fl cmk 98

akko

珂芝

',34),X=[G];function v(B,U){return s(),e("div",null,X)}const Z=a(j,[["render",v],["__file","2022-8机械键盘需求.html.vue"]]);export{Z as default}; diff --git a/assets/20220207015340394_10855-WkKd7zDr.png b/assets/20220207015340394_10855-WkKd7zDr.png new file mode 100644 index 0000000..139910f Binary files /dev/null and b/assets/20220207015340394_10855-WkKd7zDr.png differ diff --git a/assets/20220207020455741_14423-0hzHeQzp.png b/assets/20220207020455741_14423-0hzHeQzp.png new file mode 100644 index 0000000..e8a3d35 Binary files /dev/null and b/assets/20220207020455741_14423-0hzHeQzp.png differ diff --git a/assets/20220207232816641_27744-ixb5EC4z.png b/assets/20220207232816641_27744-ixb5EC4z.png new file mode 100644 index 0000000..fc06ba1 Binary files /dev/null and b/assets/20220207232816641_27744-ixb5EC4z.png differ diff --git a/assets/20220207233147081_24080-V7_vSr-g.png b/assets/20220207233147081_24080-V7_vSr-g.png new file mode 100644 index 0000000..7ec0e9c Binary files /dev/null and b/assets/20220207233147081_24080-V7_vSr-g.png differ diff --git a/assets/20220207233945612_13266-lT_z19WY.png b/assets/20220207233945612_13266-lT_z19WY.png new file mode 100644 index 0000000..0d83b36 Binary files /dev/null and b/assets/20220207233945612_13266-lT_z19WY.png differ diff --git a/assets/20220207234131065_31240-himi3PAW.png b/assets/20220207234131065_31240-himi3PAW.png new file mode 100644 index 0000000..dd46a84 Binary files /dev/null and b/assets/20220207234131065_31240-himi3PAW.png differ diff --git a/assets/20220207234824158_14626-SIvcFdMC.png b/assets/20220207234824158_14626-SIvcFdMC.png new file mode 100644 index 0000000..6092a2e Binary files /dev/null and b/assets/20220207234824158_14626-SIvcFdMC.png differ diff --git a/assets/20220208000905799_19986-bR9eGTbv.png b/assets/20220208000905799_19986-bR9eGTbv.png new file mode 100644 index 0000000..760b5f6 Binary files /dev/null and b/assets/20220208000905799_19986-bR9eGTbv.png differ diff --git a/assets/20220208001114853_16951-jxhFg3uB.png b/assets/20220208001114853_16951-jxhFg3uB.png new file mode 100644 index 0000000..602aeba Binary files /dev/null and b/assets/20220208001114853_16951-jxhFg3uB.png differ diff --git a/assets/20220208001221680_4061-QG9ozPf4.png b/assets/20220208001221680_4061-QG9ozPf4.png new file mode 100644 index 0000000..61d7518 Binary files /dev/null and b/assets/20220208001221680_4061-QG9ozPf4.png differ diff --git a/assets/20220209135741145_23408-ROZYQ1JU.png b/assets/20220209135741145_23408-ROZYQ1JU.png new file mode 100644 index 0000000..86697a3 Binary files /dev/null and b/assets/20220209135741145_23408-ROZYQ1JU.png differ diff --git a/assets/20220209140047704_18587-Fej0ZjCm.png b/assets/20220209140047704_18587-Fej0ZjCm.png new file mode 100644 index 0000000..36ca2e5 Binary files /dev/null and b/assets/20220209140047704_18587-Fej0ZjCm.png differ diff --git a/assets/20220209140104734_21646-qwn7a-6c.png b/assets/20220209140104734_21646-qwn7a-6c.png new file mode 100644 index 0000000..5b31d00 Binary files /dev/null and b/assets/20220209140104734_21646-qwn7a-6c.png differ diff --git a/assets/20220209140136127_9585-FLB24hie.png b/assets/20220209140136127_9585-FLB24hie.png new file mode 100644 index 0000000..2dfc0e1 Binary files /dev/null and b/assets/20220209140136127_9585-FLB24hie.png differ diff --git a/assets/20220219222138020_909483616-DU3bFCqD.png b/assets/20220219222138020_909483616-DU3bFCqD.png new file mode 100644 index 0000000..8237e2e Binary files /dev/null and b/assets/20220219222138020_909483616-DU3bFCqD.png differ diff --git a/assets/20220219222408266_2050018413-nSRpEmm5.png b/assets/20220219222408266_2050018413-nSRpEmm5.png new file mode 100644 index 0000000..d68b65e Binary files /dev/null and b/assets/20220219222408266_2050018413-nSRpEmm5.png differ diff --git a/assets/20220219222636498_431834823-VNfMIq1D.png b/assets/20220219222636498_431834823-VNfMIq1D.png new file mode 100644 index 0000000..81b77d2 Binary files /dev/null and b/assets/20220219222636498_431834823-VNfMIq1D.png differ diff --git a/assets/20220219223839876_1500626948-s2_6NsQS.png b/assets/20220219223839876_1500626948-s2_6NsQS.png new file mode 100644 index 0000000..b185659 Binary files /dev/null and b/assets/20220219223839876_1500626948-s2_6NsQS.png differ diff --git a/assets/20220219223947700_989164668-_tlZGLdw.png b/assets/20220219223947700_989164668-_tlZGLdw.png new file mode 100644 index 0000000..33a2046 Binary files /dev/null and b/assets/20220219223947700_989164668-_tlZGLdw.png differ diff --git a/assets/20220219224108809_1219663649-55uQuf5E.png b/assets/20220219224108809_1219663649-55uQuf5E.png new file mode 100644 index 0000000..783d10d Binary files /dev/null and b/assets/20220219224108809_1219663649-55uQuf5E.png differ diff --git a/assets/20220220001302388_1155538128-6X_Vxzk2.png b/assets/20220220001302388_1155538128-6X_Vxzk2.png new file mode 100644 index 0000000..9273f44 Binary files /dev/null and b/assets/20220220001302388_1155538128-6X_Vxzk2.png differ diff --git a/assets/20220220001455371_1434697475-YC2uc6mo.png b/assets/20220220001455371_1434697475-YC2uc6mo.png new file mode 100644 index 0000000..6ef1ec5 Binary files /dev/null and b/assets/20220220001455371_1434697475-YC2uc6mo.png differ diff --git a/assets/20220220001811914_1014073809-MAyRD0ce.png b/assets/20220220001811914_1014073809-MAyRD0ce.png new file mode 100644 index 0000000..20f6c3b Binary files /dev/null and b/assets/20220220001811914_1014073809-MAyRD0ce.png differ diff --git a/assets/20220220001907411_1108285271-UpI37-ty.png b/assets/20220220001907411_1108285271-UpI37-ty.png new file mode 100644 index 0000000..a085def Binary files /dev/null and b/assets/20220220001907411_1108285271-UpI37-ty.png differ diff --git a/assets/20220220002310307_1824879266-Uqw-Hsmf.png b/assets/20220220002310307_1824879266-Uqw-Hsmf.png new file mode 100644 index 0000000..38205aa Binary files /dev/null and b/assets/20220220002310307_1824879266-Uqw-Hsmf.png differ diff --git a/assets/20220220002509061_384377208-Vd2BzHf4.png b/assets/20220220002509061_384377208-Vd2BzHf4.png new file mode 100644 index 0000000..4a552c9 Binary files /dev/null and b/assets/20220220002509061_384377208-Vd2BzHf4.png differ diff --git a/assets/20220220003025856_596924680-kf1XdrQ2.png b/assets/20220220003025856_596924680-kf1XdrQ2.png new file mode 100644 index 0000000..07a6ba7 Binary files /dev/null and b/assets/20220220003025856_596924680-kf1XdrQ2.png differ diff --git a/assets/20220220013115494_1616981623-MFQ5NXol.png b/assets/20220220013115494_1616981623-MFQ5NXol.png new file mode 100644 index 0000000..3958e40 Binary files /dev/null and b/assets/20220220013115494_1616981623-MFQ5NXol.png differ diff --git a/assets/20220221181054219_1470266552-JVSSjxaF.png b/assets/20220221181054219_1470266552-JVSSjxaF.png new file mode 100644 index 0000000..fe6cf32 Binary files /dev/null and b/assets/20220221181054219_1470266552-JVSSjxaF.png differ diff --git a/assets/20220221181100943_1823097082-9a4ulm3V.png b/assets/20220221181100943_1823097082-9a4ulm3V.png new file mode 100644 index 0000000..1b3ac86 Binary files /dev/null and b/assets/20220221181100943_1823097082-9a4ulm3V.png differ diff --git a/assets/20220221181107838_495981778-XBC-v5cr.png b/assets/20220221181107838_495981778-XBC-v5cr.png new file mode 100644 index 0000000..2e12815 Binary files /dev/null and b/assets/20220221181107838_495981778-XBC-v5cr.png differ diff --git a/assets/20220224210923170_2109960537-GwFjhZ3Z.jpg b/assets/20220224210923170_2109960537-GwFjhZ3Z.jpg new file mode 100644 index 0000000..92852a8 Binary files /dev/null and b/assets/20220224210923170_2109960537-GwFjhZ3Z.jpg differ diff --git a/assets/20220224210928822_228379039-jj5_jq4n.png b/assets/20220224210928822_228379039-jj5_jq4n.png new file mode 100644 index 0000000..196a6b8 Binary files /dev/null and b/assets/20220224210928822_228379039-jj5_jq4n.png differ diff --git a/assets/20220224210940314_813231284-I9WT5wLd.png b/assets/20220224210940314_813231284-I9WT5wLd.png new file mode 100644 index 0000000..e8b6872 Binary files /dev/null and b/assets/20220224210940314_813231284-I9WT5wLd.png differ diff --git a/assets/20220224221723556_1392260680-_0RFBjlq.png b/assets/20220224221723556_1392260680-_0RFBjlq.png new file mode 100644 index 0000000..df76278 Binary files /dev/null and b/assets/20220224221723556_1392260680-_0RFBjlq.png differ diff --git a/assets/20220224230946729_743431048-3ursmqfX.png b/assets/20220224230946729_743431048-3ursmqfX.png new file mode 100644 index 0000000..bea04fa Binary files /dev/null and b/assets/20220224230946729_743431048-3ursmqfX.png differ diff --git a/assets/20220226143036597_1542929079-MxXugexT.png b/assets/20220226143036597_1542929079-MxXugexT.png new file mode 100644 index 0000000..d1bb79c Binary files /dev/null and b/assets/20220226143036597_1542929079-MxXugexT.png differ diff --git a/assets/20220314140628431_1059217444-CI6eIG4g.png b/assets/20220314140628431_1059217444-CI6eIG4g.png new file mode 100644 index 0000000..1eb870e Binary files /dev/null and b/assets/20220314140628431_1059217444-CI6eIG4g.png differ diff --git a/assets/20220401140429373_9677-JkF4tT3w.png b/assets/20220401140429373_9677-JkF4tT3w.png new file mode 100644 index 0000000..0336dba Binary files /dev/null and b/assets/20220401140429373_9677-JkF4tT3w.png differ diff --git a/assets/20220601113611092_2486-dyOpFLRl.png b/assets/20220601113611092_2486-dyOpFLRl.png new file mode 100644 index 0000000..02f9ab2 Binary files /dev/null and b/assets/20220601113611092_2486-dyOpFLRl.png differ diff --git a/assets/20220601115731928_9728-YPmom_hm.png b/assets/20220601115731928_9728-YPmom_hm.png new file mode 100644 index 0000000..ba634a3 Binary files /dev/null and b/assets/20220601115731928_9728-YPmom_hm.png differ diff --git a/assets/20220601135116316_3391-aO04G6Ii.png b/assets/20220601135116316_3391-aO04G6Ii.png new file mode 100644 index 0000000..6f65514 Binary files /dev/null and b/assets/20220601135116316_3391-aO04G6Ii.png differ diff --git a/assets/20220728154343100_23767-GfAGAFuL.png b/assets/20220728154343100_23767-GfAGAFuL.png new file mode 100644 index 0000000..606ce97 Binary files /dev/null and b/assets/20220728154343100_23767-GfAGAFuL.png differ diff --git a/assets/20220731195820978_26214-5JUUyO_y.png b/assets/20220731195820978_26214-5JUUyO_y.png new file mode 100644 index 0000000..abf6456 Binary files /dev/null and b/assets/20220731195820978_26214-5JUUyO_y.png differ diff --git a/assets/20220731195842725_13203-Q152G8IA.png b/assets/20220731195842725_13203-Q152G8IA.png new file mode 100644 index 0000000..8dbdad1 Binary files /dev/null and b/assets/20220731195842725_13203-Q152G8IA.png differ diff --git a/assets/20220731200011685_26497-jZk7Q90Z.png b/assets/20220731200011685_26497-jZk7Q90Z.png new file mode 100644 index 0000000..b95cb17 Binary files /dev/null and b/assets/20220731200011685_26497-jZk7Q90Z.png differ diff --git a/assets/20220731200036072_1414-FBC2yiUK.png b/assets/20220731200036072_1414-FBC2yiUK.png new file mode 100644 index 0000000..aa8fcf3 Binary files /dev/null and b/assets/20220731200036072_1414-FBC2yiUK.png differ diff --git a/assets/20220731200115907_6521-aRB7RXRV.png b/assets/20220731200115907_6521-aRB7RXRV.png new file mode 100644 index 0000000..d62182b Binary files /dev/null and b/assets/20220731200115907_6521-aRB7RXRV.png differ diff --git a/assets/20220731200136604_337-msppGkIG.png b/assets/20220731200136604_337-msppGkIG.png new file mode 100644 index 0000000..35eb063 Binary files /dev/null and b/assets/20220731200136604_337-msppGkIG.png differ diff --git a/assets/20220731200548028_21925-1KbHrxHX.png b/assets/20220731200548028_21925-1KbHrxHX.png new file mode 100644 index 0000000..2a6f67a Binary files /dev/null and b/assets/20220731200548028_21925-1KbHrxHX.png differ diff --git a/assets/20220731201044629_4162-XhCkaSEq.png b/assets/20220731201044629_4162-XhCkaSEq.png new file mode 100644 index 0000000..d02adff Binary files /dev/null and b/assets/20220731201044629_4162-XhCkaSEq.png differ diff --git a/assets/20220731201214493_26640-09KLe87h.png b/assets/20220731201214493_26640-09KLe87h.png new file mode 100644 index 0000000..00237b3 Binary files /dev/null and b/assets/20220731201214493_26640-09KLe87h.png differ diff --git a/assets/20220731202148112_32356-Uad1VhED.png b/assets/20220731202148112_32356-Uad1VhED.png new file mode 100644 index 0000000..f2762f2 Binary files /dev/null and b/assets/20220731202148112_32356-Uad1VhED.png differ diff --git a/assets/20220731202427851_1049-GhavgIqK.png b/assets/20220731202427851_1049-GhavgIqK.png new file mode 100644 index 0000000..9af0a94 Binary files /dev/null and b/assets/20220731202427851_1049-GhavgIqK.png differ diff --git a/assets/20220731202736174_29464-i9gqiiZg.png b/assets/20220731202736174_29464-i9gqiiZg.png new file mode 100644 index 0000000..37fe0c8 Binary files /dev/null and b/assets/20220731202736174_29464-i9gqiiZg.png differ diff --git a/assets/20220731202934975_22322-Z_KijlGG.png b/assets/20220731202934975_22322-Z_KijlGG.png new file mode 100644 index 0000000..8a4578d Binary files /dev/null and b/assets/20220731202934975_22322-Z_KijlGG.png differ diff --git a/assets/20220802170125044_2240-saycqpps.png b/assets/20220802170125044_2240-saycqpps.png new file mode 100644 index 0000000..8fd60f1 Binary files /dev/null and b/assets/20220802170125044_2240-saycqpps.png differ diff --git a/assets/20220802173323861_22313-e3oQHXwO.png b/assets/20220802173323861_22313-e3oQHXwO.png new file mode 100644 index 0000000..0bb7cf4 Binary files /dev/null and b/assets/20220802173323861_22313-e3oQHXwO.png differ diff --git a/assets/20220802173421936_17841-ZoMXgp70.png b/assets/20220802173421936_17841-ZoMXgp70.png new file mode 100644 index 0000000..c5b559f Binary files /dev/null and b/assets/20220802173421936_17841-ZoMXgp70.png differ diff --git a/assets/20220802173903823_21890-rdVdbSQy.png b/assets/20220802173903823_21890-rdVdbSQy.png new file mode 100644 index 0000000..76b1b33 Binary files /dev/null and b/assets/20220802173903823_21890-rdVdbSQy.png differ diff --git a/assets/20220802173939155_6597-6CHxBUTj.png b/assets/20220802173939155_6597-6CHxBUTj.png new file mode 100644 index 0000000..56ffd7e Binary files /dev/null and b/assets/20220802173939155_6597-6CHxBUTj.png differ diff --git a/assets/20220802174217434_8203-b7mhjjOk.png b/assets/20220802174217434_8203-b7mhjjOk.png new file mode 100644 index 0000000..9109b56 Binary files /dev/null and b/assets/20220802174217434_8203-b7mhjjOk.png differ diff --git a/assets/20220906182537987_26393-RRpH7fSK.png b/assets/20220906182537987_26393-RRpH7fSK.png new file mode 100644 index 0000000..04752ac Binary files /dev/null and b/assets/20220906182537987_26393-RRpH7fSK.png differ diff --git a/assets/20220906182619519_25504-S5OXFblH.png b/assets/20220906182619519_25504-S5OXFblH.png new file mode 100644 index 0000000..5590090 Binary files /dev/null and b/assets/20220906182619519_25504-S5OXFblH.png differ diff --git a/assets/20220906183511031_14728-0w-7xDcr.png b/assets/20220906183511031_14728-0w-7xDcr.png new file mode 100644 index 0000000..5077282 Binary files /dev/null and b/assets/20220906183511031_14728-0w-7xDcr.png differ diff --git a/assets/20220906193542887_24307-KvnRTBLz.png b/assets/20220906193542887_24307-KvnRTBLz.png new file mode 100644 index 0000000..2b1aa92 Binary files /dev/null and b/assets/20220906193542887_24307-KvnRTBLz.png differ diff --git a/assets/20220906193606268_13713-foGFoJlc.png b/assets/20220906193606268_13713-foGFoJlc.png new file mode 100644 index 0000000..a9f8205 Binary files /dev/null and b/assets/20220906193606268_13713-foGFoJlc.png differ diff --git a/assets/20220906201131109_32680-zvh61D5d.png b/assets/20220906201131109_32680-zvh61D5d.png new file mode 100644 index 0000000..e777d35 Binary files /dev/null and b/assets/20220906201131109_32680-zvh61D5d.png differ diff --git a/assets/20220906201150745_32638-kwaoj9AS.png b/assets/20220906201150745_32638-kwaoj9AS.png new file mode 100644 index 0000000..dde8c1f Binary files /dev/null and b/assets/20220906201150745_32638-kwaoj9AS.png differ diff --git a/assets/20220913113645278_23384-f-keS_J0.png b/assets/20220913113645278_23384-f-keS_J0.png new file mode 100644 index 0000000..122a8c5 Binary files /dev/null and b/assets/20220913113645278_23384-f-keS_J0.png differ diff --git a/assets/20220913145345755_22381-WQ_61mxD.png b/assets/20220913145345755_22381-WQ_61mxD.png new file mode 100644 index 0000000..93464b5 Binary files /dev/null and b/assets/20220913145345755_22381-WQ_61mxD.png differ diff --git a/assets/20220914154132929_32258-sJ3-Cxv6.png b/assets/20220914154132929_32258-sJ3-Cxv6.png new file mode 100644 index 0000000..7f53ab9 Binary files /dev/null and b/assets/20220914154132929_32258-sJ3-Cxv6.png differ diff --git a/assets/20221017105043746_29382-EW-14mL8.png b/assets/20221017105043746_29382-EW-14mL8.png new file mode 100644 index 0000000..ab3463d Binary files /dev/null and b/assets/20221017105043746_29382-EW-14mL8.png differ diff --git a/assets/20221017105049326_26966-WlMfoEfL.png b/assets/20221017105049326_26966-WlMfoEfL.png new file mode 100644 index 0000000..c1547e6 Binary files /dev/null and b/assets/20221017105049326_26966-WlMfoEfL.png differ diff --git a/assets/20221121134210181_20921-NCRj5vsy.png b/assets/20221121134210181_20921-NCRj5vsy.png new file mode 100644 index 0000000..81d6949 Binary files /dev/null and b/assets/20221121134210181_20921-NCRj5vsy.png differ diff --git a/assets/20221121134247040_13313-01QZcw1E.png b/assets/20221121134247040_13313-01QZcw1E.png new file mode 100644 index 0000000..9c0a08e Binary files /dev/null and b/assets/20221121134247040_13313-01QZcw1E.png differ diff --git a/assets/20221121134803539_27462-FSYqWKCt.png b/assets/20221121134803539_27462-FSYqWKCt.png new file mode 100644 index 0000000..eec9541 Binary files /dev/null and b/assets/20221121134803539_27462-FSYqWKCt.png differ diff --git a/assets/20221206100854428_16773-Jc0xcMb9.png b/assets/20221206100854428_16773-Jc0xcMb9.png new file mode 100644 index 0000000..8cf5b6c Binary files /dev/null and b/assets/20221206100854428_16773-Jc0xcMb9.png differ diff --git a/assets/20221209180120985_22521-BGo8JcQo.png b/assets/20221209180120985_22521-BGo8JcQo.png new file mode 100644 index 0000000..025dcff Binary files /dev/null and b/assets/20221209180120985_22521-BGo8JcQo.png differ diff --git a/assets/20221213105953021_4596-gbj6KSr4.png b/assets/20221213105953021_4596-gbj6KSr4.png new file mode 100644 index 0000000..ad2687e Binary files /dev/null and b/assets/20221213105953021_4596-gbj6KSr4.png differ diff --git a/assets/20221222170242535_17309-awGBiN82.png b/assets/20221222170242535_17309-awGBiN82.png new file mode 100644 index 0000000..0f266df Binary files /dev/null and b/assets/20221222170242535_17309-awGBiN82.png differ diff --git a/assets/20221222170248974_17861-n-cpp9fj.png b/assets/20221222170248974_17861-n-cpp9fj.png new file mode 100644 index 0000000..21f0e2e Binary files /dev/null and b/assets/20221222170248974_17861-n-cpp9fj.png differ diff --git a/assets/20221222170415632_6307-cQMYUYI0.png b/assets/20221222170415632_6307-cQMYUYI0.png new file mode 100644 index 0000000..26030bd Binary files /dev/null and b/assets/20221222170415632_6307-cQMYUYI0.png differ diff --git a/assets/20221222170648272_2876-kQFMy3_2.png b/assets/20221222170648272_2876-kQFMy3_2.png new file mode 100644 index 0000000..f6d083d Binary files /dev/null and b/assets/20221222170648272_2876-kQFMy3_2.png differ diff --git a/assets/20221222171347277_19524-9pq0v9TU.png b/assets/20221222171347277_19524-9pq0v9TU.png new file mode 100644 index 0000000..228893c Binary files /dev/null and b/assets/20221222171347277_19524-9pq0v9TU.png differ diff --git a/assets/20221222175006341_28511-qud_ErsR.png b/assets/20221222175006341_28511-qud_ErsR.png new file mode 100644 index 0000000..842c18a Binary files /dev/null and b/assets/20221222175006341_28511-qud_ErsR.png differ diff --git a/assets/20230117102418974_24620-A5goY1hE.png b/assets/20230117102418974_24620-A5goY1hE.png new file mode 100644 index 0000000..3c98dcd Binary files /dev/null and b/assets/20230117102418974_24620-A5goY1hE.png differ diff --git a/assets/21323416278796-xygIMZaK.png b/assets/21323416278796-xygIMZaK.png new file mode 100644 index 0000000..4172d35 Binary files /dev/null and b/assets/21323416278796-xygIMZaK.png differ diff --git "a/assets/23-5-22pg\346\225\260\346\215\256\345\272\223\347\232\204\344\270\255\346\226\207\346\216\222\345\272\217.html-C_4RKu4R.js" "b/assets/23-5-22pg\346\225\260\346\215\256\345\272\223\347\232\204\344\270\255\346\226\207\346\216\222\345\272\217.html-C_4RKu4R.js" new file mode 100644 index 0000000..7200b86 --- /dev/null +++ "b/assets/23-5-22pg\346\225\260\346\215\256\345\272\223\347\232\204\344\270\255\346\226\207\346\216\222\345\272\217.html-C_4RKu4R.js" @@ -0,0 +1 @@ +import{_ as e,o as a,c as r,a as o}from"./app-x8p6wK6B.js";const t={},c=o('

23-5-22pg数据库的中文排序

背景

pg数据库存储的utf8字段,需要按拼音进行排序

方案1

方案1:在了解到gbk编码按照拼音顺序编码后,使用convert函数将utf8字段转为gbk,然后ordr by即可 ORDER BY CONVERT(ColumnName USING gbk) 小问题:存储的emjoy等不能转换为utf8的,则会查询失败, 需要禁止输入非gbk编码

方案2

方案2:select * from process order by name collate "zh_CN" 前提db有这个collate,可以通过select * from pg_collation;查询

group_member_ids: list[StringIDInput] = Field(alias="group_members")

',8),d=[c];function _(n,h){return a(),r("div",null,d)}const s=e(t,[["render",_],["__file","23-5-22pg数据库的中文排序.html.vue"]]);export{s as default}; diff --git "a/assets/23-5-22pg\346\225\260\346\215\256\345\272\223\347\232\204\344\270\255\346\226\207\346\216\222\345\272\217.html-k0DhmuBI.js" "b/assets/23-5-22pg\346\225\260\346\215\256\345\272\223\347\232\204\344\270\255\346\226\207\346\216\222\345\272\217.html-k0DhmuBI.js" new file mode 100644 index 0000000..b470d43 --- /dev/null +++ "b/assets/23-5-22pg\346\225\260\346\215\256\345\272\223\347\232\204\344\270\255\346\226\207\346\216\222\345\272\217.html-k0DhmuBI.js" @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-54f0d1d0","path":"/web/23-5-22pg%E6%95%B0%E6%8D%AE%E5%BA%93%E7%9A%84%E4%B8%AD%E6%96%87%E6%8E%92%E5%BA%8F.html","title":"23-5-22pg数据库的中文排序","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"背景","slug":"背景","link":"#背景","children":[]},{"level":2,"title":"方案1","slug":"方案1","link":"#方案1","children":[]},{"level":2,"title":"方案2","slug":"方案2","link":"#方案2","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"web/23-5-22pg数据库的中文排序.md"}');export{e as data}; diff --git a/assets/231835696836803-2nk4Z3C-.png b/assets/231835696836803-2nk4Z3C-.png new file mode 100644 index 0000000..718d7b1 Binary files /dev/null and b/assets/231835696836803-2nk4Z3C-.png differ diff --git a/assets/239891913912036-u-9AFBdU.png b/assets/239891913912036-u-9AFBdU.png new file mode 100644 index 0000000..466bfef Binary files /dev/null and b/assets/239891913912036-u-9AFBdU.png differ diff --git a/assets/262282302625813-_qHSbY-g.png b/assets/262282302625813-_qHSbY-g.png new file mode 100644 index 0000000..3b254d4 Binary files /dev/null and b/assets/262282302625813-_qHSbY-g.png differ diff --git a/assets/26585610279198-qDPAQFRs.png b/assets/26585610279198-qDPAQFRs.png new file mode 100644 index 0000000..7926b57 Binary files /dev/null and b/assets/26585610279198-qDPAQFRs.png differ diff --git a/assets/267571311278872-aiy3JK4f.png b/assets/267571311278872-aiy3JK4f.png new file mode 100644 index 0000000..85f9fd2 Binary files /dev/null and b/assets/267571311278872-aiy3JK4f.png differ diff --git a/assets/267835701625494-p4jK1vfP.png b/assets/267835701625494-p4jK1vfP.png new file mode 100644 index 0000000..132f72b Binary files /dev/null and b/assets/267835701625494-p4jK1vfP.png differ diff --git a/assets/270522409533576-XXXpJ4s5.png b/assets/270522409533576-XXXpJ4s5.png new file mode 100644 index 0000000..3284ff7 Binary files /dev/null and b/assets/270522409533576-XXXpJ4s5.png differ diff --git a/assets/270663025951564-grm2JTEW.png b/assets/270663025951564-grm2JTEW.png new file mode 100644 index 0000000..ba59da4 Binary files /dev/null and b/assets/270663025951564-grm2JTEW.png differ diff --git a/assets/27510892836406-L9knP75y.png b/assets/27510892836406-L9knP75y.png new file mode 100644 index 0000000..c075bf0 Binary files /dev/null and b/assets/27510892836406-L9knP75y.png differ diff --git a/assets/280304492836402-eUylmFoN.png b/assets/280304492836402-eUylmFoN.png new file mode 100644 index 0000000..deae38b Binary files /dev/null and b/assets/280304492836402-eUylmFoN.png differ diff --git a/assets/284455698836999-JYle4GdA.png b/assets/284455698836999-JYle4GdA.png new file mode 100644 index 0000000..d3c7a82 Binary files /dev/null and b/assets/284455698836999-JYle4GdA.png differ diff --git a/assets/287800781817896-Vpyzzqtw.png b/assets/287800781817896-Vpyzzqtw.png new file mode 100644 index 0000000..ec71915 Binary files /dev/null and b/assets/287800781817896-Vpyzzqtw.png differ diff --git a/assets/298007630951842-DxmUwS8I.png b/assets/298007630951842-DxmUwS8I.png new file mode 100644 index 0000000..d05dbc0 Binary files /dev/null and b/assets/298007630951842-DxmUwS8I.png differ diff --git a/assets/325013368947114-V-SvYCjT.png b/assets/325013368947114-V-SvYCjT.png new file mode 100644 index 0000000..9094faa Binary files /dev/null and b/assets/325013368947114-V-SvYCjT.png differ diff --git a/assets/339666605625810-SRbakhNE.png b/assets/339666605625810-SRbakhNE.png new file mode 100644 index 0000000..fbd3f99 Binary files /dev/null and b/assets/339666605625810-SRbakhNE.png differ diff --git a/assets/370660893836505-jwyokzhR.png b/assets/370660893836505-jwyokzhR.png new file mode 100644 index 0000000..9341d49 Binary files /dev/null and b/assets/370660893836505-jwyokzhR.png differ diff --git a/assets/378723495836805-Akg88FZH.png b/assets/378723495836805-Akg88FZH.png new file mode 100644 index 0000000..e4ce3a4 Binary files /dev/null and b/assets/378723495836805-Akg88FZH.png differ diff --git a/assets/379880510279073-CwzzhgUw.png b/assets/379880510279073-CwzzhgUw.png new file mode 100644 index 0000000..d3c84ee Binary files /dev/null and b/assets/379880510279073-CwzzhgUw.png differ diff --git a/assets/382107205625895-2OGByWCv.png b/assets/382107205625895-2OGByWCv.png new file mode 100644 index 0000000..4e94e94 Binary files /dev/null and b/assets/382107205625895-2OGByWCv.png differ diff --git a/assets/388303814279280-O_8WYwxq.png b/assets/388303814279280-O_8WYwxq.png new file mode 100644 index 0000000..aa6810f Binary files /dev/null and b/assets/388303814279280-O_8WYwxq.png differ diff --git a/assets/399381599836319-B5jf8FFP.png b/assets/399381599836319-B5jf8FFP.png new file mode 100644 index 0000000..2eac932 Binary files /dev/null and b/assets/399381599836319-B5jf8FFP.png differ diff --git a/assets/401180871947710-4AqukcNL.png b/assets/401180871947710-4AqukcNL.png new file mode 100644 index 0000000..efec2f0 Binary files /dev/null and b/assets/401180871947710-4AqukcNL.png differ diff --git a/assets/404.html-6Yl8cQE3.js b/assets/404.html-6Yl8cQE3.js new file mode 100644 index 0000000..7a25b17 --- /dev/null +++ b/assets/404.html-6Yl8cQE3.js @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-3706649a","path":"/404.html","title":"","lang":"en-US","frontmatter":{"layout":"NotFound"},"headers":[],"git":{},"filePathRelative":null}');export{t as data}; diff --git a/assets/404.html-jx0VGdGa.js b/assets/404.html-jx0VGdGa.js new file mode 100644 index 0000000..c7adc36 --- /dev/null +++ b/assets/404.html-jx0VGdGa.js @@ -0,0 +1 @@ +import{_ as e,o as c,c as t}from"./app-x8p6wK6B.js";const _={};function o(r,n){return c(),t("div")}const a=e(_,[["render",o],["__file","404.html.vue"]]);export{a as default}; diff --git a/assets/424924709279287-YfJWF5ev.png b/assets/424924709279287-YfJWF5ev.png new file mode 100644 index 0000000..993b118 Binary files /dev/null and b/assets/424924709279287-YfJWF5ev.png differ diff --git a/assets/43397323951244-njmpsXEy.png b/assets/43397323951244-njmpsXEy.png new file mode 100644 index 0000000..3b63855 Binary files /dev/null and b/assets/43397323951244-njmpsXEy.png differ diff --git a/assets/44541929951561-LUCbnwYK.png b/assets/44541929951561-LUCbnwYK.png new file mode 100644 index 0000000..7bbb55b Binary files /dev/null and b/assets/44541929951561-LUCbnwYK.png differ diff --git a/assets/486322292836512-Zfrvlyu0.png b/assets/486322292836512-Zfrvlyu0.png new file mode 100644 index 0000000..2eb8556 Binary files /dev/null and b/assets/486322292836512-Zfrvlyu0.png differ diff --git a/assets/493477101625617-8YwdJfeb.png b/assets/493477101625617-8YwdJfeb.png new file mode 100644 index 0000000..826594f Binary files /dev/null and b/assets/493477101625617-8YwdJfeb.png differ diff --git a/assets/500087022133366-w73em1gi.png b/assets/500087022133366-w73em1gi.png new file mode 100644 index 0000000..1db8b6b Binary files /dev/null and b/assets/500087022133366-w73em1gi.png differ diff --git a/assets/501727794900246-II9R_YS8.png b/assets/501727794900246-II9R_YS8.png new file mode 100644 index 0000000..727aaf2 Binary files /dev/null and b/assets/501727794900246-II9R_YS8.png differ diff --git a/assets/514935909278883-YU9p5snK.png b/assets/514935909278883-YU9p5snK.png new file mode 100644 index 0000000..8e7b64a Binary files /dev/null and b/assets/514935909278883-YU9p5snK.png differ diff --git a/assets/515895892836525-h9GyQ7S-.png b/assets/515895892836525-h9GyQ7S-.png new file mode 100644 index 0000000..b3aae97 Binary files /dev/null and b/assets/515895892836525-h9GyQ7S-.png differ diff --git a/assets/548223420659412-6QJypmJi.png b/assets/548223420659412-6QJypmJi.png new file mode 100644 index 0000000..5974940 Binary files /dev/null and b/assets/548223420659412-6QJypmJi.png differ diff --git a/assets/Mysql.html-SjpbbPal.js b/assets/Mysql.html-SjpbbPal.js new file mode 100644 index 0000000..2ff3351 --- /dev/null +++ b/assets/Mysql.html-SjpbbPal.js @@ -0,0 +1 @@ +const l=JSON.parse('{"key":"v-47da6a9c","path":"/notebook/Mysql.html","title":"Mysql","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"2020/9/28","slug":"_2020-9-28","link":"#_2020-9-28","children":[{"level":3,"title":"重置mysql密码","slug":"重置mysql密码","link":"#重置mysql密码","children":[]}]},{"level":2,"title":"2020/4/5","slug":"_2020-4-5","link":"#_2020-4-5","children":[{"level":3,"title":"select insert","slug":"select-insert","link":"#select-insert","children":[]}]},{"level":2,"title":"2020/3/29","slug":"_2020-3-29","link":"#_2020-3-29","children":[{"level":3,"title":"mysql 语句分析:","slug":"mysql-语句分析","link":"#mysql-语句分析","children":[]},{"level":3,"title":"数据类型为text 的时间字段, 对比","slug":"数据类型为text-的时间字段-对比","link":"#数据类型为text-的时间字段-对比","children":[]},{"level":3,"title":"输出表的字段名 2020/03/26","slug":"输出表的字段名-2020-03-26","link":"#输出表的字段名-2020-03-26","children":[]},{"level":3,"title":"查询所有符合要求的行数, 同时取limit数据","slug":"查询所有符合要求的行数-同时取limit数据","link":"#查询所有符合要求的行数-同时取limit数据","children":[]}]},{"level":2,"title":"3/29:","slug":"_3-29","link":"#_3-29","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/Mysql.md"}');export{l as data}; diff --git a/assets/Mysql.html-lejLX8Of.js b/assets/Mysql.html-lejLX8Of.js new file mode 100644 index 0000000..34830ed --- /dev/null +++ b/assets/Mysql.html-lejLX8Of.js @@ -0,0 +1,51 @@ +import{_ as t,r as i,o as l,c as o,b as s,d as a,e as d,a as n}from"./app-x8p6wK6B.js";const c={},p=n(`

Mysql

2020/9/28

重置mysql密码

服务器版本: ubuntu

第一步:停止mysql服务 sudo /etc/init.d/mysqld stop or sudo service mysql stop

第二步, 以跳过密码验证模式启动mysql , 这一步窗口会阻塞, 需要再开启一个终端 sudo mysqld_safe --skip-grant-tables

可能有人这个时候报了一个错误, mysqld_safe Directory '/var/run/mysqld' for UNIX socket file don't exists

google 得到解决方案

https://stackoverflow.com/questions/42153059/mysqld-safe-directory-var-run-mysqld-for-unix-socket-file-dont-exists

sudo mkdir -p /var/run/mysqld
+sudo chown mysql:mysql /var/run/mysqld
+

问题解决

第三步: 进入mysql

mysql

第四步, 更新密码,这里我将密码改为your_password


+use mysql;
+
+update user set authentication_string = password("your_password") where user = "root";
+flush privileges;
+
+

然后重启mysql 即可

先杀掉我们
+

2020/4/5

select insert


+INSERT INTO table2
+(column_name(s))
+SELECT column_name(s)
+FROM table1;
+

2020/3/29

mysql 语句分析:

explain + sql语句

数据类型为text 的时间字段, 对比

  1. 最简形式 96s
SELECT * FROM \`tousu_heimao_table\` WHERE complaint_time > '2020-03-27'
+
+
+加入limit 50
+SELECT id FROM \`tousu_heimao_table\` WHERE complaint_time > '2020-03-27' ORDER BY complaint_time limit 50;  5s
+
+
  1. 使用时间戳,以及替换*为字段名 45s
SELECT id,identity_code,crawl_time,title,complain_man,website,object_of_complaint,question_type,appeal_type,details_of_complaint,process_flow,comment_data,complaint_time FROM \`tousu_heimao_table\` WHERE unix_timestamp(complaint_time) > 1585281379\`
+
+
+
+
  1. 只查询id,没有设置limit
SELECT id FROM \`tousu_heimao_table\` WHERE unix_timestamp(complaint_time) > 1585281379 limit 50
+
  1. 前50个 6.5s, 第1000-1050个, 65s
SELECT id FROM \`tousu_heimao_table\` WHERE unix_timestamp(complaint_time) > 1585281379 ORDER BY complaint_time DESC limit 50
+
  1. 第100000-100050条 40s
SELECT id FROM \`tousu_heimao_table\` WHERE 1=1 ORDER BY complaint_time DESC limit 100000,50
+
  1. 稍微优化, 27s
SELECT id FROM \`tousu_heimao_table\` WHERE id > (select id from \`tousu_heimao_table\` ORDER BY complaint_time DESC limit 100000,1) limit 50
+

7.究极优化 3s

SELECT * FROM \`tousu_heimao_table\` WHERE id > (select id from \`tousu_heimao_table\` ORDER BY id  limit 100000,1) limit 50
+

8 .加入时间 2s

SELECT * FROM \`tousu_heimao_table\` WHERE id > (select id from \`tousu_heimao_table\` where complaint_time>'2019-3-27'    ORDER BY id  limit 100000,1) limit 50
+
  1. 字段数据类型设置为datetime
SELECT * FROM tousu_table WHERE complaint_time > '2020-3-27' limit 100;   7s
+
SELECT * FROM tousu_table WHERE complaint_time > '2020-03-27' limit 100;  10s
+

输出表的字段名 2020/03/26

select COLUMN_NAME from information_schema.COLUMNS where table_name = 'your_table_name' and table_schema = 'your_db_name';
+

查询所有符合要求的行数, 同时取limit数据

一般思路: 查一下count(1) , 然后把count(1) 换成 * , 后面加上limit 0, 50, 再次查询得到数据

`,47),r={href:"https://blog.csdn.net/qq_31122833/article/details/83894509",target:"_blank",rel:"noopener noreferrer"},u=n(`
select SQL_CALC_FOUND_ROWS 
+    col_name1 as colName1,
+    col_name2 as colName2
+from table_name limit 0,10;
+select FOUND_ROWS() as count;
+ 
+在SELECT语句中加上修饰SQL_CALC_FOUND_ROWS 之后,SELECT FOUND_ROWS() 会返回满足条件记录的总数。
+

这样,你执行完 select SQL_CALC_FOUND_ROWS 之后,再取一下记录总数就行了。

3/29:

 SELECT SQL_CALC_FOUND_ROWS
+	*
+FROM
+	tousu_table 
+WHERE
+	(complaint_time <= '2020-03-30' AND complaint_time >= '2020-03-22' )
+ORDER BY
+	complaint_time 
+	LIMIT 0,
+	50
+

建立索引后,加与不加时间差异很大,加上后6.6s 不加1s

使用这个东西会导致全表扫描

`,5);function m(v,k){const e=i("ExternalLinkIcon");return l(),o("div",null,[p,s("p",null,[a("优化: "),s("a",r,[a("博客"),d(e)])]),u])}const _=t(c,[["render",m],["__file","Mysql.html.vue"]]);export{_ as default}; diff --git a/assets/adb.html-PCZulOnl.js b/assets/adb.html-PCZulOnl.js new file mode 100644 index 0000000..9f306e4 --- /dev/null +++ b/assets/adb.html-PCZulOnl.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-1bb63775","path":"/notebook/adb.html","title":"adb","lang":"en-US","frontmatter":{},"headers":[{"level":3,"title":"adb 更换壁纸 2020/4/29","slug":"adb-更换壁纸-2020-4-29","link":"#adb-更换壁纸-2020-4-29","children":[]},{"level":3,"title":"adb 授予/撤销 应用权限 2020/4/27","slug":"adb-授予-撤销-应用权限-2020-4-27","link":"#adb-授予-撤销-应用权限-2020-4-27","children":[]},{"level":3,"title":"adb推送后,图片在相册中不显示 2020/4/26","slug":"adb推送后-图片在相册中不显示-2020-4-26","link":"#adb推送后-图片在相册中不显示-2020-4-26","children":[]},{"level":3,"title":"清空应用缓存 2020/4/19","slug":"清空应用缓存-2020-4-19","link":"#清空应用缓存-2020-4-19","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/adb.md"}');export{e as data}; diff --git a/assets/adb.html-aasCYosc.js b/assets/adb.html-aasCYosc.js new file mode 100644 index 0000000..1f7f93a --- /dev/null +++ b/assets/adb.html-aasCYosc.js @@ -0,0 +1,8 @@ +import{_ as t,r as i,o as l,c as r,b as e,d as a,e as d,a as s}from"./app-x8p6wK6B.js";const c={},o=s(`

adb

adb 更换壁纸 2020/4/29

am start -d file:////data/local/tmp/black_white.png -a android.service.wallpaper.CROP_AND_SET_WALLPAPER -f 0x1 com.android.launcher3/.WallpaperCropActivity

adb 授予/撤销 应用权限 2020/4/27

# 给微信授予高精度定位权限
+adb shell pm grant com.tencent.mm android.permission.ACCESS_FINE_LOCATION
+
+# 撤销
+adb shell pm revoke com.tencent.mm android.permission.ACCESS_FINE_LOCATION
+
+
+

有用的链接

  1. https://www.cnblogs.com/jianxu/p/5380882.html
  2. https://ligboy.org/?p=429 AppOps ,设置权限(在一加5, 7.1.1上简单测试未生效)

adb推送后,图片在相册中不显示 2020/4/26

`,8),h={href:"https://www.zhipanyou.com/help/a.php?t=5a6J5Y2TYWRi5ZG95Luk5Yi35paw5Zu+5bqTIC0gamltaWMwODMx55qE5Y2a5a6iX0NTRE7ljZrlrqI=&u=aHR0cDovL3d3dy5iYWlkdS5jb20vbGluaz91cmw9cG5jVkdXWTdBSWxaajVPblBHNnRaaWlXTEdmLTRkSHVJcUpZMnVHQUtvMXZ4N3JtY2V2WTR6cGxrNmM2YkU1RWpwUFp0cjBoQ2xSU3pDTkVqMEdIU1dWMVlfZnl6MGxxb1lrMUk2eVBEckc=",target:"_blank",rel:"noopener noreferrer"},_={href:"https://blog.csdn.net/lincyang/article/details/45766479",target:"_blank",rel:"noopener noreferrer"},p=e("p",null,"命令1刷新图片:adb shell am broadcast -a android.intent.action.MEDIA_SCANNER_SCAN_FILE -d file:///sdcard/Pictures/xx.png",-1),b=e("p",null,"命令2刷新目录:adb shell am broadcast -a android.intent.action.MEDIA_MOUNTED -d file:///sdcard/Pictures ▲ android < 4.4",-1),m=e("p",null,"EXTERNAL_CONTENT_URI",-1),u=e("p",null,"Intent.ACTION_MEDIA_MOUNTED",-1),v=e("p",null,"一般命令2比较有用。但是命令2,需要权限,因此使用命令1",-1),x=e("p",null,"———————————————— 版权声明:本文为CSDN博主「jimic0831」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/jimic0831/article/details/78274265",-1),E=e("h3",{id:"清空应用缓存-2020-4-19",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#清空应用缓存-2020-4-19","aria-hidden":"true"},"#"),a(" 清空应用缓存 2020/4/19")],-1),N=e("p",null,[e("code",null,"adb shell pm clear ")],-1);function f(A,C){const n=i("ExternalLinkIcon");return l(),r("div",null,[o,e("p",null,[e("a",h,[a("解决方案"),d(n)])]),e("p",null,[e("a",_,[a("博客1"),d(n)])]),p,b,m,u,v,x,E,N])}const g=t(c,[["render",f],["__file","adb.html.vue"]]);export{g as default}; diff --git a/assets/app-x8p6wK6B.js b/assets/app-x8p6wK6B.js new file mode 100644 index 0000000..b112122 --- /dev/null +++ b/assets/app-x8p6wK6B.js @@ -0,0 +1,16 @@ +function vl(e,t){const n=Object.create(null),o=e.split(",");for(let l=0;l!!n[l.toLowerCase()]:l=>!!n[l]}const Be={},ln=[],ut=()=>{},Zs=()=>!1,$n=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&(e.charCodeAt(2)>122||e.charCodeAt(2)<97),_l=e=>e.startsWith("onUpdate:"),Pe=Object.assign,gl=(e,t)=>{const n=e.indexOf(t);n>-1&&e.splice(n,1)},Gs=Object.prototype.hasOwnProperty,he=(e,t)=>Gs.call(e,t),ee=Array.isArray,rn=e=>Lo(e)==="[object Map]",pi=e=>Lo(e)==="[object Set]",ie=e=>typeof e=="function",Ee=e=>typeof e=="string",xo=e=>typeof e=="symbol",ke=e=>e!==null&&typeof e=="object",mi=e=>(ke(e)||ie(e))&&ie(e.then)&&ie(e.catch),Ei=Object.prototype.toString,Lo=e=>Ei.call(e),Js=e=>Lo(e).slice(8,-1),vi=e=>Lo(e)==="[object Object]",bl=e=>Ee(e)&&e!=="NaN"&&e[0]!=="-"&&""+parseInt(e,10)===e,xn=vl(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),Do=e=>{const t=Object.create(null);return n=>t[n]||(t[n]=e(n))},Qs=/-(\w)/g,dt=Do(e=>e.replace(Qs,(t,n)=>n?n.toUpperCase():"")),Xs=/\B([A-Z])/g,Gt=Do(e=>e.replace(Xs,"-$1").toLowerCase()),Co=Do(e=>e.charAt(0).toUpperCase()+e.slice(1)),No=Do(e=>e?`on${Co(e)}`:""),Zt=(e,t)=>!Object.is(e,t),Ho=(e,t)=>{for(let n=0;n{Object.defineProperty(e,t,{configurable:!0,enumerable:!1,value:n})},ea=e=>{const t=parseFloat(e);return isNaN(t)?e:t},ta=e=>{const t=Ee(e)?Number(e):NaN;return isNaN(t)?e:t};let Xl;const tl=()=>Xl||(Xl=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{});function Nn(e){if(ee(e)){const t={};for(let n=0;n{if(n){const o=n.split(oa);o.length>1&&(t[o[0].trim()]=o[1].trim())}}),t}function Ke(e){let t="";if(Ee(e))t=e;else if(ee(e))for(let n=0;nEe(e)?e:e==null?"":ee(e)||ke(e)&&(e.toString===Ei||!ie(e.toString))?JSON.stringify(e,gi,2):String(e),gi=(e,t)=>t&&t.__v_isRef?gi(e,t.value):rn(t)?{[`Map(${t.size})`]:[...t.entries()].reduce((n,[o,l])=>(n[`${o} =>`]=l,n),{})}:pi(t)?{[`Set(${t.size})`]:[...t.values()]}:ke(t)&&!ee(t)&&!vi(t)?String(t):t;let Ze;class aa{constructor(t=!1){this.detached=t,this._active=!0,this.effects=[],this.cleanups=[],this.parent=Ze,!t&&Ze&&(this.index=(Ze.scopes||(Ze.scopes=[])).push(this)-1)}get active(){return this._active}run(t){if(this._active){const n=Ze;try{return Ze=this,t()}finally{Ze=n}}}on(){Ze=this}off(){Ze=this.parent}stop(t){if(this._active){let n,o;for(n=0,o=this.effects.length;n{const t=new Set(e);return t.w=0,t.n=0,t},Ai=e=>(e.w&Pt)>0,yi=e=>(e.n&Pt)>0,da=({deps:e})=>{if(e.length)for(let t=0;t{const{deps:t}=e;if(t.length){let n=0;for(let o=0;o{(u==="length"||!xo(u)&&u>=s)&&a.push(c)})}else switch(n!==void 0&&a.push(i.get(n)),t){case"add":ee(e)?bl(n)&&a.push(i.get("length")):(a.push(i.get(Ut)),rn(e)&&a.push(i.get(ol)));break;case"delete":ee(e)||(a.push(i.get(Ut)),rn(e)&&a.push(i.get(ol)));break;case"set":rn(e)&&a.push(i.get(Ut));break}if(a.length===1)a[0]&&ll(a[0]);else{const s=[];for(const c of a)c&&s.push(...c);ll(Al(s))}}function ll(e,t){const n=ee(e)?e:[...e];for(const o of n)o.computed&&tr(o);for(const o of n)o.computed||tr(o)}function tr(e,t){(e!==ot||e.allowRecurse)&&(e.scheduler?e.scheduler():e.run())}function ha(e,t){var n;return(n=po.get(e))==null?void 0:n.get(t)}const pa=vl("__proto__,__v_isRef,__isVue"),wi=new Set(Object.getOwnPropertyNames(Symbol).filter(e=>e!=="arguments"&&e!=="caller").map(e=>Symbol[e]).filter(xo)),nr=ma();function ma(){const e={};return["includes","indexOf","lastIndexOf"].forEach(t=>{e[t]=function(...n){const o=me(this);for(let r=0,i=this.length;r{e[t]=function(...n){vn();const o=me(this)[t].apply(this,n);return _n(),o}}),e}function Ea(e){const t=me(this);return We(t,"has",e),t.hasOwnProperty(e)}class xi{constructor(t=!1,n=!1){this._isReadonly=t,this._shallow=n}get(t,n,o){const l=this._isReadonly,r=this._shallow;if(n==="__v_isReactive")return!l;if(n==="__v_isReadonly")return l;if(n==="__v_isShallow")return r;if(n==="__v_raw"&&o===(l?r?Ca:Ti:r?Ci:Di).get(t))return t;const i=ee(t);if(!l){if(i&&he(nr,n))return Reflect.get(nr,n,o);if(n==="hasOwnProperty")return Ea}const a=Reflect.get(t,n,o);return(xo(n)?wi.has(n):pa(n))||(l||We(t,"get",n),r)?a:Ie(a)?i&&bl(n)?a:a.value:ke(a)?l?qn(a):Hn(a):a}}class Li extends xi{constructor(t=!1){super(!1,t)}set(t,n,o,l){let r=t[n];if(un(r)&&Ie(r)&&!Ie(o))return!1;if(!this._shallow&&(!mo(o)&&!un(o)&&(r=me(r),o=me(o)),!ee(t)&&Ie(r)&&!Ie(o)))return r.value=o,!0;const i=ee(t)&&bl(n)?Number(n)e,To=e=>Reflect.getPrototypeOf(e);function Gn(e,t,n=!1,o=!1){e=e.__v_raw;const l=me(e),r=me(t);n||(Zt(t,r)&&We(l,"get",t),We(l,"get",r));const{has:i}=To(l),a=o?Bl:n?xl:Pn;if(i.call(l,t))return a(e.get(t));if(i.call(l,r))return a(e.get(r));e!==l&&e.get(t)}function Jn(e,t=!1){const n=this.__v_raw,o=me(n),l=me(e);return t||(Zt(e,l)&&We(o,"has",e),We(o,"has",l)),e===l?n.has(e):n.has(e)||n.has(l)}function Qn(e,t=!1){return e=e.__v_raw,!t&&We(me(e),"iterate",Ut),Reflect.get(e,"size",e)}function or(e){e=me(e);const t=me(this);return To(t).has.call(t,e)||(t.add(e),Et(t,"add",e,e)),this}function lr(e,t){t=me(t);const n=me(this),{has:o,get:l}=To(n);let r=o.call(n,e);r||(e=me(e),r=o.call(n,e));const i=l.call(n,e);return n.set(e,t),r?Zt(t,i)&&Et(n,"set",e,t):Et(n,"add",e,t),this}function rr(e){const t=me(this),{has:n,get:o}=To(t);let l=n.call(t,e);l||(e=me(e),l=n.call(t,e)),o&&o.call(t,e);const r=t.delete(e);return l&&Et(t,"delete",e,void 0),r}function ir(){const e=me(this),t=e.size!==0,n=e.clear();return t&&Et(e,"clear",void 0,void 0),n}function Xn(e,t){return function(o,l){const r=this,i=r.__v_raw,a=me(i),s=t?Bl:e?xl:Pn;return!e&&We(a,"iterate",Ut),i.forEach((c,u)=>o.call(l,s(c),s(u),r))}}function eo(e,t,n){return function(...o){const l=this.__v_raw,r=me(l),i=rn(r),a=e==="entries"||e===Symbol.iterator&&i,s=e==="keys"&&i,c=l[e](...o),u=n?Bl:t?xl:Pn;return!t&&We(r,"iterate",s?ol:Ut),{next(){const{value:d,done:f}=c.next();return f?{value:d,done:f}:{value:a?[u(d[0]),u(d[1])]:u(d),done:f}},[Symbol.iterator](){return this}}}}function Bt(e){return function(...t){return e==="delete"?!1:e==="clear"?void 0:this}}function Aa(){const e={get(r){return Gn(this,r)},get size(){return Qn(this)},has:Jn,add:or,set:lr,delete:rr,clear:ir,forEach:Xn(!1,!1)},t={get(r){return Gn(this,r,!1,!0)},get size(){return Qn(this)},has:Jn,add:or,set:lr,delete:rr,clear:ir,forEach:Xn(!1,!0)},n={get(r){return Gn(this,r,!0)},get size(){return Qn(this,!0)},has(r){return Jn.call(this,r,!0)},add:Bt("add"),set:Bt("set"),delete:Bt("delete"),clear:Bt("clear"),forEach:Xn(!0,!1)},o={get(r){return Gn(this,r,!0,!0)},get size(){return Qn(this,!0)},has(r){return Jn.call(this,r,!0)},add:Bt("add"),set:Bt("set"),delete:Bt("delete"),clear:Bt("clear"),forEach:Xn(!0,!0)};return["keys","values","entries",Symbol.iterator].forEach(r=>{e[r]=eo(r,!1,!1),n[r]=eo(r,!0,!1),t[r]=eo(r,!1,!0),o[r]=eo(r,!0,!0)}),[e,n,t,o]}const[ya,Ba,ka,wa]=Aa();function kl(e,t){const n=t?e?wa:ka:e?Ba:ya;return(o,l,r)=>l==="__v_isReactive"?!e:l==="__v_isReadonly"?e:l==="__v_raw"?o:Reflect.get(he(n,l)&&l in o?n:o,l,r)}const xa={get:kl(!1,!1)},La={get:kl(!1,!0)},Da={get:kl(!0,!1)},Di=new WeakMap,Ci=new WeakMap,Ti=new WeakMap,Ca=new WeakMap;function Ta(e){switch(e){case"Object":case"Array":return 1;case"Map":case"Set":case"WeakMap":case"WeakSet":return 2;default:return 0}}function Ra(e){return e.__v_skip||!Object.isExtensible(e)?0:Ta(Js(e))}function Hn(e){return un(e)?e:wl(e,!1,_a,xa,Di)}function Ri(e){return wl(e,!1,ba,La,Ci)}function qn(e){return wl(e,!0,ga,Da,Ti)}function wl(e,t,n,o,l){if(!ke(e)||e.__v_raw&&!(t&&e.__v_isReactive))return e;const r=l.get(e);if(r)return r;const i=Ra(e);if(i===0)return e;const a=new Proxy(e,i===2?o:n);return l.set(e,a),a}function sn(e){return un(e)?sn(e.__v_raw):!!(e&&e.__v_isReactive)}function un(e){return!!(e&&e.__v_isReadonly)}function mo(e){return!!(e&&e.__v_isShallow)}function Pi(e){return sn(e)||un(e)}function me(e){const t=e&&e.__v_raw;return t?me(t):e}function Oi(e){return ho(e,"__v_skip",!0),e}const Pn=e=>ke(e)?Hn(e):e,xl=e=>ke(e)?qn(e):e;function Ll(e){Tt&&ot&&(e=me(e),ki(e.dep||(e.dep=Al())))}function Dl(e,t){e=me(e);const n=e.dep;n&&ll(n)}function Ie(e){return!!(e&&e.__v_isRef===!0)}function _e(e){return Fi(e,!1)}function Cl(e){return Fi(e,!0)}function Fi(e,t){return Ie(e)?e:new Pa(e,t)}class Pa{constructor(t,n){this.__v_isShallow=n,this.dep=void 0,this.__v_isRef=!0,this._rawValue=n?t:me(t),this._value=n?t:Pn(t)}get value(){return Ll(this),this._value}set value(t){const n=this.__v_isShallow||mo(t)||un(t);t=n?t:me(t),Zt(t,this._rawValue)&&(this._rawValue=t,this._value=n?t:Pn(t),Dl(this))}}function ne(e){return Ie(e)?e.value:e}const Oa={get:(e,t,n)=>ne(Reflect.get(e,t,n)),set:(e,t,n,o)=>{const l=e[t];return Ie(l)&&!Ie(n)?(l.value=n,!0):Reflect.set(e,t,n,o)}};function Ii(e){return sn(e)?e:new Proxy(e,Oa)}class Fa{constructor(t){this.dep=void 0,this.__v_isRef=!0;const{get:n,set:o}=t(()=>Ll(this),()=>Dl(this));this._get=n,this._set=o}get value(){return this._get()}set value(t){this._set(t)}}function Ia(e){return new Fa(e)}function Ro(e){const t=ee(e)?new Array(e.length):{};for(const n in e)t[n]=Va(e,n);return t}class Sa{constructor(t,n,o){this._object=t,this._key=n,this._defaultValue=o,this.__v_isRef=!0}get value(){const t=this._object[this._key];return t===void 0?this._defaultValue:t}set value(t){this._object[this._key]=t}get dep(){return ha(me(this._object),this._key)}}function Va(e,t,n){const o=e[t];return Ie(o)?o:new Sa(e,t,n)}class Ma{constructor(t,n,o,l){this._setter=n,this.dep=void 0,this.__v_isRef=!0,this.__v_isReadonly=!1,this._dirty=!0,this.effect=new yl(t,()=>{this._dirty||(this._dirty=!0,Dl(this))}),this.effect.computed=this,this.effect.active=this._cacheable=!l,this.__v_isReadonly=o}get value(){const t=me(this);return Ll(t),(t._dirty||!t._cacheable)&&(t._dirty=!1,t._value=t.effect.run()),t._value}set value(t){this._setter(t)}}function $a(e,t,n=!1){let o,l;const r=ie(e);return r?(o=e,l=ut):(o=e.get,l=e.set),new Ma(o,l,r||!l,n)}function Rt(e,t,n,o){let l;try{l=o?e(...o):e()}catch(r){jn(r,t,n)}return l}function et(e,t,n,o){if(ie(e)){const r=Rt(e,t,n,o);return r&&mi(r)&&r.catch(i=>{jn(i,t,n)}),r}const l=[];for(let r=0;r>>1,l=Ne[o],r=Fn(l);rct&&Ne.splice(t,1)}function ja(e){ee(e)?an.push(...e):(!mt||!mt.includes(e,e.allowRecurse?Ht+1:Ht))&&an.push(e),Vi()}function sr(e,t=On?ct+1:0){for(;tFn(n)-Fn(o)),Ht=0;Hte.id==null?1/0:e.id,za=(e,t)=>{const n=Fn(e)-Fn(t);if(n===0){if(e.pre&&!t.pre)return-1;if(t.pre&&!e.pre)return 1}return n};function Mi(e){rl=!1,On=!0,Ne.sort(za);try{for(ct=0;ctEe(E)?E.trim():E)),d&&(l=n.map(ea))}let a,s=o[a=No(t)]||o[a=No(dt(t))];!s&&r&&(s=o[a=No(Gt(t))]),s&&et(s,e,6,l);const c=o[a+"Once"];if(c){if(!e.emitted)e.emitted={};else if(e.emitted[a])return;e.emitted[a]=!0,et(c,e,6,l)}}function $i(e,t,n=!1){const o=t.emitsCache,l=o.get(e);if(l!==void 0)return l;const r=e.emits;let i={},a=!1;if(!ie(e)){const s=c=>{const u=$i(c,t,!0);u&&(a=!0,Pe(i,u))};!n&&t.mixins.length&&t.mixins.forEach(s),e.extends&&s(e.extends),e.mixins&&e.mixins.forEach(s)}return!r&&!a?(ke(e)&&o.set(e,null),null):(ee(r)?r.forEach(s=>i[s]=null):Pe(i,r),ke(e)&&o.set(e,i),i)}function Oo(e,t){return!e||!$n(t)?!1:(t=t.slice(2).replace(/Once$/,""),he(e,t[0].toLowerCase()+t.slice(1))||he(e,Gt(t))||he(e,t))}let Me=null,Ni=null;function vo(e){const t=Me;return Me=e,Ni=e&&e.type.__scopeId||null,t}function Ve(e,t=Me,n){if(!t||e._n)return e;const o=(...l)=>{o._d&&gr(-1);const r=vo(t);let i;try{i=e(...l)}finally{vo(r),o._d&&gr(1)}return i};return o._n=!0,o._c=!0,o._d=!0,o}function qo(e){const{type:t,vnode:n,proxy:o,withProxy:l,props:r,propsOptions:[i],slots:a,attrs:s,emit:c,render:u,renderCache:d,data:f,setupState:E,ctx:A,inheritAttrs:B}=e;let x,T;const C=vo(e);try{if(n.shapeFlag&4){const b=l||o,H=b;x=nt(u.call(H,b,d,r,E,f,A)),T=s}else{const b=t;x=nt(b.length>1?b(r,{attrs:s,slots:a,emit:c}):b(r,null)),T=t.props?s:Ka(s)}}catch(b){Cn.length=0,jn(b,e,1),x=le(Je)}let _=x;if(T&&B!==!1){const b=Object.keys(T),{shapeFlag:H}=_;b.length&&H&7&&(i&&b.some(_l)&&(T=Wa(T,i)),_=Ft(_,T))}return n.dirs&&(_=Ft(_),_.dirs=_.dirs?_.dirs.concat(n.dirs):n.dirs),n.transition&&(_.transition=n.transition),x=_,vo(C),x}const Ka=e=>{let t;for(const n in e)(n==="class"||n==="style"||$n(n))&&((t||(t={}))[n]=e[n]);return t},Wa=(e,t)=>{const n={};for(const o in e)(!_l(o)||!(o.slice(9)in t))&&(n[o]=e[o]);return n};function Ya(e,t,n){const{props:o,children:l,component:r}=e,{props:i,children:a,patchFlag:s}=t,c=r.emitsOptions;if(t.dirs||t.transition)return!0;if(n&&s>=0){if(s&1024)return!0;if(s&16)return o?ar(o,i,c):!!i;if(s&8){const u=t.dynamicProps;for(let d=0;de.__isSuspense;function qi(e,t){t&&t.pendingBranch?ee(e)?t.effects.push(...e):t.effects.push(e):ja(e)}function ji(e,t){return Rl(e,null,t)}const to={};function Ge(e,t,n){return Rl(e,t,n)}function Rl(e,t,{immediate:n,deep:o,flush:l,onTrack:r,onTrigger:i}=Be){var a;const s=bi()===((a=Te)==null?void 0:a.scope)?Te:null;let c,u=!1,d=!1;if(Ie(e)?(c=()=>e.value,u=mo(e)):sn(e)?(c=()=>e,o=!0):ee(e)?(d=!0,u=e.some(b=>sn(b)||mo(b)),c=()=>e.map(b=>{if(Ie(b))return b.value;if(sn(b))return zt(b);if(ie(b))return Rt(b,s,2)})):ie(e)?t?c=()=>Rt(e,s,2):c=()=>{if(!(s&&s.isUnmounted))return f&&f(),et(e,s,3,[E])}:c=ut,t&&o){const b=c;c=()=>zt(b())}let f,E=b=>{f=C.onStop=()=>{Rt(b,s,4),f=C.onStop=void 0}},A;if(hn)if(E=ut,t?n&&et(t,s,3,[c(),d?[]:void 0,E]):c(),l==="sync"){const b=Uc();A=b.__watcherHandles||(b.__watcherHandles=[])}else return ut;let B=d?new Array(e.length).fill(to):to;const x=()=>{if(C.active)if(t){const b=C.run();(o||u||(d?b.some((H,Y)=>Zt(H,B[Y])):Zt(b,B)))&&(f&&f(),et(t,s,3,[b,B===to?void 0:d&&B[0]===to?[]:B,E]),B=b)}else C.run()};x.allowRecurse=!!t;let T;l==="sync"?T=x:l==="post"?T=()=>Ue(x,s&&s.suspense):(x.pre=!0,s&&(x.id=s.uid),T=()=>Po(x));const C=new yl(c,T);t?n?x():B=C.run():l==="post"?Ue(C.run.bind(C),s&&s.suspense):C.run();const _=()=>{C.stop(),s&&s.scope&&gl(s.scope.effects,C)};return A&&A.push(_),_}function Xa(e,t,n){const o=this.proxy,l=Ee(e)?e.includes(".")?zi(o,e):()=>o[e]:e.bind(o,o);let r;ie(t)?r=t:(r=t.handler,n=t);const i=Te;fn(this);const a=Rl(l,r.bind(o),n);return i?fn(i):Wt(),a}function zi(e,t){const n=t.split(".");return()=>{let o=e;for(let l=0;l{zt(n,t)});else if(vi(e))for(const n in e)zt(e[n],t);return e}function _o(e,t){const n=Me;if(n===null)return e;const o=Vo(n)||n.proxy,l=e.dirs||(e.dirs=[]);for(let r=0;r{e.isMounted=!0}),Kn(()=>{e.isUnmounting=!0}),e}const Qe=[Function,Array],Ui={mode:String,appear:Boolean,persisted:Boolean,onBeforeEnter:Qe,onEnter:Qe,onAfterEnter:Qe,onEnterCancelled:Qe,onBeforeLeave:Qe,onLeave:Qe,onAfterLeave:Qe,onLeaveCancelled:Qe,onBeforeAppear:Qe,onAppear:Qe,onAfterAppear:Qe,onAppearCancelled:Qe},tc={name:"BaseTransition",props:Ui,setup(e,{slots:t}){const n=Il(),o=ec();let l;return()=>{const r=t.default&&Wi(t.default(),!0);if(!r||!r.length)return;let i=r[0];if(r.length>1){for(const B of r)if(B.type!==Je){i=B;break}}const a=me(e),{mode:s}=a;if(o.isLeaving)return jo(i);const c=ur(i);if(!c)return jo(i);const u=il(c,a,o,n);sl(c,u);const d=n.subTree,f=d&&ur(d);let E=!1;const{getTransitionKey:A}=c.type;if(A){const B=A();l===void 0?l=B:B!==l&&(l=B,E=!0)}if(f&&f.type!==Je&&(!qt(c,f)||E)){const B=il(f,a,o,n);if(sl(f,B),s==="out-in")return o.isLeaving=!0,B.afterLeave=()=>{o.isLeaving=!1,n.update.active!==!1&&n.update()},jo(i);s==="in-out"&&c.type!==Je&&(B.delayLeave=(x,T,C)=>{const _=Ki(o,f);_[String(f.key)]=f,x[Lt]=()=>{T(),x[Lt]=void 0,delete u.delayedLeave},u.delayedLeave=C})}return i}}},nc=tc;function Ki(e,t){const{leavingVNodes:n}=e;let o=n.get(t.type);return o||(o=Object.create(null),n.set(t.type,o)),o}function il(e,t,n,o){const{appear:l,mode:r,persisted:i=!1,onBeforeEnter:a,onEnter:s,onAfterEnter:c,onEnterCancelled:u,onBeforeLeave:d,onLeave:f,onAfterLeave:E,onLeaveCancelled:A,onBeforeAppear:B,onAppear:x,onAfterAppear:T,onAppearCancelled:C}=t,_=String(e.key),b=Ki(n,e),H=(g,I)=>{g&&et(g,o,9,I)},Y=(g,I)=>{const P=I[1];H(g,I),ee(g)?g.every(W=>W.length<=1)&&P():g.length<=1&&P()},M={mode:r,persisted:i,beforeEnter(g){let I=a;if(!n.isMounted)if(l)I=B||a;else return;g[Lt]&&g[Lt](!0);const P=b[_];P&&qt(e,P)&&P.el[Lt]&&P.el[Lt](),H(I,[g])},enter(g){let I=s,P=c,W=u;if(!n.isMounted)if(l)I=x||s,P=T||c,W=C||u;else return;let k=!1;const V=g[no]=oe=>{k||(k=!0,oe?H(W,[g]):H(P,[g]),M.delayedLeave&&M.delayedLeave(),g[no]=void 0)};I?Y(I,[g,V]):V()},leave(g,I){const P=String(e.key);if(g[no]&&g[no](!0),n.isUnmounting)return I();H(d,[g]);let W=!1;const k=g[Lt]=V=>{W||(W=!0,I(),V?H(A,[g]):H(E,[g]),g[Lt]=void 0,b[P]===e&&delete b[P])};b[P]=e,f?Y(f,[g,k]):k()},clone(g){return il(g,t,n,o)}};return M}function jo(e){if(Un(e))return e=Ft(e),e.children=null,e}function ur(e){return Un(e)?e.children?e.children[0]:void 0:e}function sl(e,t){e.shapeFlag&6&&e.component?sl(e.component.subTree,t):e.shapeFlag&128?(e.ssContent.transition=t.clone(e.ssContent),e.ssFallback.transition=t.clone(e.ssFallback)):e.transition=t}function Wi(e,t=!1,n){let o=[],l=0;for(let r=0;r1)for(let r=0;r!!e.type.__asyncLoader;/*! #__NO_SIDE_EFFECTS__ */function D(e){ie(e)&&(e={loader:e});const{loader:t,loadingComponent:n,errorComponent:o,delay:l=200,timeout:r,suspensible:i=!0,onError:a}=e;let s=null,c,u=0;const d=()=>(u++,s=null,f()),f=()=>{let E;return s||(E=s=t().catch(A=>{if(A=A instanceof Error?A:new Error(String(A)),a)return new Promise((B,x)=>{a(A,()=>B(d()),()=>x(A),u+1)});throw A}).then(A=>E!==s&&s?s:(A&&(A.__esModule||A[Symbol.toStringTag]==="Module")&&(A=A.default),c=A,A)))};return de({name:"AsyncComponentWrapper",__asyncLoader:f,get __asyncResolved(){return c},setup(){const E=Te;if(c)return()=>zo(c,E);const A=C=>{s=null,jn(C,E,13,!o)};if(i&&E.suspense||hn)return f().then(C=>()=>zo(C,E)).catch(C=>(A(C),()=>o?le(o,{error:C}):null));const B=_e(!1),x=_e(),T=_e(!!l);return l&&setTimeout(()=>{T.value=!1},l),r!=null&&setTimeout(()=>{if(!B.value&&!x.value){const C=new Error(`Async component timed out after ${r}ms.`);A(C),x.value=C}},r),f().then(()=>{B.value=!0,E.parent&&Un(E.parent.vnode)&&Po(E.parent.update)}).catch(C=>{A(C),x.value=C}),()=>{if(B.value&&c)return zo(c,E);if(x.value&&o)return le(o,{error:x.value});if(n&&!T.value)return le(n)}}})}function zo(e,t){const{ref:n,props:o,children:l,ce:r}=t.vnode,i=le(e,o,l);return i.ref=n,i.ce=r,delete t.vnode.ce,i}const Un=e=>e.type.__isKeepAlive;function oc(e,t){Yi(e,"a",t)}function lc(e,t){Yi(e,"da",t)}function Yi(e,t,n=Te){const o=e.__wdc||(e.__wdc=()=>{let l=n;for(;l;){if(l.isDeactivated)return;l=l.parent}return e()});if(Fo(t,o,n),n){let l=n.parent;for(;l&&l.parent;)Un(l.parent.vnode)&&rc(o,t,n,l),l=l.parent}}function rc(e,t,n,o){const l=Fo(t,e,o,!0);Io(()=>{gl(o[t],l)},n)}function Fo(e,t,n=Te,o=!1){if(n){const l=n[e]||(n[e]=[]),r=t.__weh||(t.__weh=(...i)=>{if(n.isUnmounted)return;vn(),fn(n);const a=et(t,n,e,i);return Wt(),_n(),a});return o?l.unshift(r):l.push(r),r}}const bt=e=>(t,n=Te)=>(!hn||e==="sp")&&Fo(e,(...o)=>t(...o),n),ic=bt("bm"),je=bt("m"),sc=bt("bu"),ac=bt("u"),Kn=bt("bum"),Io=bt("um"),cc=bt("sp"),uc=bt("rtg"),dc=bt("rtc");function fc(e,t=Te){Fo("ec",e,t)}function Ot(e,t,n,o){let l;const r=n&&n[o];if(ee(e)||Ee(e)){l=new Array(e.length);for(let i=0,a=e.length;it(i,a,void 0,r&&r[a]));else{const i=Object.keys(e);l=new Array(i.length);for(let a=0,s=i.length;ayo(t)?!(t.type===Je||t.type===ye&&!Zi(t.children)):!0)?e:null}const al=e=>e?ss(e)?Vo(e)||e.proxy:al(e.parent):null,Ln=Pe(Object.create(null),{$:e=>e,$el:e=>e.vnode.el,$data:e=>e.data,$props:e=>e.props,$attrs:e=>e.attrs,$slots:e=>e.slots,$refs:e=>e.refs,$parent:e=>al(e.parent),$root:e=>al(e.root),$emit:e=>e.emit,$options:e=>Pl(e),$forceUpdate:e=>e.f||(e.f=()=>Po(e.update)),$nextTick:e=>e.n||(e.n=zn.bind(e.proxy)),$watch:e=>Xa.bind(e)}),Uo=(e,t)=>e!==Be&&!e.__isScriptSetup&&he(e,t),hc={get({_:e},t){const{ctx:n,setupState:o,data:l,props:r,accessCache:i,type:a,appContext:s}=e;let c;if(t[0]!=="$"){const E=i[t];if(E!==void 0)switch(E){case 1:return o[t];case 2:return l[t];case 4:return n[t];case 3:return r[t]}else{if(Uo(o,t))return i[t]=1,o[t];if(l!==Be&&he(l,t))return i[t]=2,l[t];if((c=e.propsOptions[0])&&he(c,t))return i[t]=3,r[t];if(n!==Be&&he(n,t))return i[t]=4,n[t];cl&&(i[t]=0)}}const u=Ln[t];let d,f;if(u)return t==="$attrs"&&We(e,"get",t),u(e);if((d=a.__cssModules)&&(d=d[t]))return d;if(n!==Be&&he(n,t))return i[t]=4,n[t];if(f=s.config.globalProperties,he(f,t))return f[t]},set({_:e},t,n){const{data:o,setupState:l,ctx:r}=e;return Uo(l,t)?(l[t]=n,!0):o!==Be&&he(o,t)?(o[t]=n,!0):he(e.props,t)||t[0]==="$"&&t.slice(1)in e?!1:(r[t]=n,!0)},has({_:{data:e,setupState:t,accessCache:n,ctx:o,appContext:l,propsOptions:r}},i){let a;return!!n[i]||e!==Be&&he(e,i)||Uo(t,i)||(a=r[0])&&he(a,i)||he(o,i)||he(Ln,i)||he(l.config.globalProperties,i)},defineProperty(e,t,n){return n.get!=null?e._.accessCache[t]=0:he(n,"value")&&this.set(e,t,n.value,null),Reflect.defineProperty(e,t,n)}};function dr(e){return ee(e)?e.reduce((t,n)=>(t[n]=null,t),{}):e}let cl=!0;function pc(e){const t=Pl(e),n=e.proxy,o=e.ctx;cl=!1,t.beforeCreate&&fr(t.beforeCreate,e,"bc");const{data:l,computed:r,methods:i,watch:a,provide:s,inject:c,created:u,beforeMount:d,mounted:f,beforeUpdate:E,updated:A,activated:B,deactivated:x,beforeDestroy:T,beforeUnmount:C,destroyed:_,unmounted:b,render:H,renderTracked:Y,renderTriggered:M,errorCaptured:g,serverPrefetch:I,expose:P,inheritAttrs:W,components:k,directives:V,filters:oe}=t;if(c&&mc(c,o,null),i)for(const J in i){const K=i[J];ie(K)&&(o[J]=K.bind(n))}if(l){const J=l.call(n,n);ke(J)&&(e.data=Hn(J))}if(cl=!0,r)for(const J in r){const K=r[J],Oe=ie(K)?K.bind(n,n):ie(K.get)?K.get.bind(n,n):ut,Se=!ie(K)&&ie(K.set)?K.set.bind(n):ut,ze=j({get:Oe,set:Se});Object.defineProperty(o,J,{enumerable:!0,configurable:!0,get:()=>ze.value,set:$e=>ze.value=$e})}if(a)for(const J in a)Gi(a[J],o,n,J);if(s){const J=ie(s)?s.call(n):s;Reflect.ownKeys(J).forEach(K=>{Kt(K,J[K])})}u&&fr(u,e,"c");function F(J,K){ee(K)?K.forEach(Oe=>J(Oe.bind(n))):K&&J(K.bind(n))}if(F(ic,d),F(je,f),F(sc,E),F(ac,A),F(oc,B),F(lc,x),F(fc,g),F(dc,Y),F(uc,M),F(Kn,C),F(Io,b),F(cc,I),ee(P))if(P.length){const J=e.exposed||(e.exposed={});P.forEach(K=>{Object.defineProperty(J,K,{get:()=>n[K],set:Oe=>n[K]=Oe})})}else e.exposed||(e.exposed={});H&&e.render===ut&&(e.render=H),W!=null&&(e.inheritAttrs=W),k&&(e.components=k),V&&(e.directives=V)}function mc(e,t,n=ut){ee(e)&&(e=ul(e));for(const o in e){const l=e[o];let r;ke(l)?"default"in l?r=Le(l.from||o,l.default,!0):r=Le(l.from||o):r=Le(l),Ie(r)?Object.defineProperty(t,o,{enumerable:!0,configurable:!0,get:()=>r.value,set:i=>r.value=i}):t[o]=r}}function fr(e,t,n){et(ee(e)?e.map(o=>o.bind(t.proxy)):e.bind(t.proxy),t,n)}function Gi(e,t,n,o){const l=o.includes(".")?zi(n,o):()=>n[o];if(Ee(e)){const r=t[e];ie(r)&&Ge(l,r)}else if(ie(e))Ge(l,e.bind(n));else if(ke(e))if(ee(e))e.forEach(r=>Gi(r,t,n,o));else{const r=ie(e.handler)?e.handler.bind(n):t[e.handler];ie(r)&&Ge(l,r,e)}}function Pl(e){const t=e.type,{mixins:n,extends:o}=t,{mixins:l,optionsCache:r,config:{optionMergeStrategies:i}}=e.appContext,a=r.get(t);let s;return a?s=a:!l.length&&!n&&!o?s=t:(s={},l.length&&l.forEach(c=>go(s,c,i,!0)),go(s,t,i)),ke(t)&&r.set(t,s),s}function go(e,t,n,o=!1){const{mixins:l,extends:r}=t;r&&go(e,r,n,!0),l&&l.forEach(i=>go(e,i,n,!0));for(const i in t)if(!(o&&i==="expose")){const a=Ec[i]||n&&n[i];e[i]=a?a(e[i],t[i]):t[i]}return e}const Ec={data:hr,props:pr,emits:pr,methods:wn,computed:wn,beforeCreate:He,created:He,beforeMount:He,mounted:He,beforeUpdate:He,updated:He,beforeDestroy:He,beforeUnmount:He,destroyed:He,unmounted:He,activated:He,deactivated:He,errorCaptured:He,serverPrefetch:He,components:wn,directives:wn,watch:_c,provide:hr,inject:vc};function hr(e,t){return t?e?function(){return Pe(ie(e)?e.call(this,this):e,ie(t)?t.call(this,this):t)}:t:e}function vc(e,t){return wn(ul(e),ul(t))}function ul(e){if(ee(e)){const t={};for(let n=0;n1)return n&&ie(t)?t.call(o&&o.proxy):t}}function Ac(e,t,n,o=!1){const l={},r={};ho(r,So,1),e.propsDefaults=Object.create(null),Qi(e,t,l,r);for(const i in e.propsOptions[0])i in l||(l[i]=void 0);n?e.props=o?l:Ri(l):e.type.props?e.props=l:e.props=r,e.attrs=r}function yc(e,t,n,o){const{props:l,attrs:r,vnode:{patchFlag:i}}=e,a=me(l),[s]=e.propsOptions;let c=!1;if((o||i>0)&&!(i&16)){if(i&8){const u=e.vnode.dynamicProps;for(let d=0;d{s=!0;const[f,E]=Xi(d,t,!0);Pe(i,f),E&&a.push(...E)};!n&&t.mixins.length&&t.mixins.forEach(u),e.extends&&u(e.extends),e.mixins&&e.mixins.forEach(u)}if(!r&&!s)return ke(e)&&o.set(e,ln),ln;if(ee(r))for(let u=0;u-1,E[1]=B<0||A-1||he(E,"default"))&&a.push(d)}}}const c=[i,a];return ke(e)&&o.set(e,c),c}function mr(e){return e[0]!=="$"}function Er(e){const t=e&&e.toString().match(/^\s*(function|class) (\w+)/);return t?t[2]:e===null?"null":""}function vr(e,t){return Er(e)===Er(t)}function _r(e,t){return ee(t)?t.findIndex(n=>vr(n,e)):ie(t)&&vr(t,e)?0:-1}const es=e=>e[0]==="_"||e==="$stable",Ol=e=>ee(e)?e.map(nt):[nt(e)],Bc=(e,t,n)=>{if(t._n)return t;const o=Ve((...l)=>Ol(t(...l)),n);return o._c=!1,o},ts=(e,t,n)=>{const o=e._ctx;for(const l in e){if(es(l))continue;const r=e[l];if(ie(r))t[l]=Bc(l,r,o);else if(r!=null){const i=Ol(r);t[l]=()=>i}}},ns=(e,t)=>{const n=Ol(t);e.slots.default=()=>n},kc=(e,t)=>{if(e.vnode.shapeFlag&32){const n=t._;n?(e.slots=me(t),ho(t,"_",n)):ts(t,e.slots={})}else e.slots={},t&&ns(e,t);ho(e.slots,So,1)},wc=(e,t,n)=>{const{vnode:o,slots:l}=e;let r=!0,i=Be;if(o.shapeFlag&32){const a=t._;a?n&&a===1?r=!1:(Pe(l,t),!n&&a===1&&delete l._):(r=!t.$stable,ts(t,l)),i=t}else t&&(ns(e,t),i={default:1});if(r)for(const a in l)!es(a)&&i[a]==null&&delete l[a]};function Ao(e,t,n,o,l=!1){if(ee(e)){e.forEach((f,E)=>Ao(f,t&&(ee(t)?t[E]:t),n,o,l));return}if(cn(o)&&!l)return;const r=o.shapeFlag&4?Vo(o.component)||o.component.proxy:o.el,i=l?null:r,{i:a,r:s}=e,c=t&&t.r,u=a.refs===Be?a.refs={}:a.refs,d=a.setupState;if(c!=null&&c!==s&&(Ee(c)?(u[c]=null,he(d,c)&&(d[c]=null)):Ie(c)&&(c.value=null)),ie(s))Rt(s,a,12,[i,u]);else{const f=Ee(s),E=Ie(s);if(f||E){const A=()=>{if(e.f){const B=f?he(d,s)?d[s]:u[s]:s.value;l?ee(B)&&gl(B,r):ee(B)?B.includes(r)||B.push(r):f?(u[s]=[r],he(d,s)&&(d[s]=u[s])):(s.value=[r],e.k&&(u[e.k]=s.value))}else f?(u[s]=i,he(d,s)&&(d[s]=i)):E&&(s.value=i,e.k&&(u[e.k]=i))};i?(A.id=-1,Ue(A,n)):A()}}}let kt=!1;const oo=e=>/svg/.test(e.namespaceURI)&&e.tagName!=="foreignObject",lo=e=>e.nodeType===8;function xc(e){const{mt:t,p:n,o:{patchProp:o,createText:l,nextSibling:r,parentNode:i,remove:a,insert:s,createComment:c}}=e,u=(_,b)=>{if(!b.hasChildNodes()){n(null,_,b),Eo(),b._vnode=_;return}kt=!1,d(b.firstChild,_,null,null,null),Eo(),b._vnode=_,kt&&console.error("Hydration completed but contains mismatches.")},d=(_,b,H,Y,M,g=!1)=>{const I=lo(_)&&_.data==="[",P=()=>B(_,b,H,Y,M,I),{type:W,ref:k,shapeFlag:V,patchFlag:oe}=b;let se=_.nodeType;b.el=_,oe===-2&&(g=!1,b.dynamicChildren=null);let F=null;switch(W){case dn:se!==3?b.children===""?(s(b.el=l(""),i(_),_),F=_):F=P():(_.data!==b.children&&(kt=!0,_.data=b.children),F=r(_));break;case Je:C(_)?(F=r(_),T(b.el=_.content.firstChild,_,H)):se!==8||I?F=P():F=r(_);break;case Dn:if(I&&(_=r(_),se=_.nodeType),se===1||se===3){F=_;const J=!b.children.length;for(let K=0;K{g=g||!!b.dynamicChildren;const{type:I,props:P,patchFlag:W,shapeFlag:k,dirs:V,transition:oe}=b,se=I==="input"||I==="option";if(se||W!==-1){if(V&&at(b,null,H,"created"),P)if(se||!g||W&48)for(const K in P)(se&&(K.endsWith("value")||K==="indeterminate")||$n(K)&&!xn(K)||K[0]===".")&&o(_,K,null,P[K],!1,void 0,H);else P.onClick&&o(_,"onClick",null,P.onClick,!1,void 0,H);let F;(F=P&&P.onVnodeBeforeMount)&&Xe(F,H,b);let J=!1;if(C(_)){J=os(Y,oe)&&H&&H.vnode.props&&H.vnode.props.appear;const K=_.content.firstChild;J&&oe.beforeEnter(K),T(K,_,H),b.el=_=K}if(V&&at(b,null,H,"beforeMount"),((F=P&&P.onVnodeMounted)||V||J)&&qi(()=>{F&&Xe(F,H,b),J&&oe.enter(_),V&&at(b,null,H,"mounted")},Y),k&16&&!(P&&(P.innerHTML||P.textContent))){let K=E(_.firstChild,b,_,H,Y,M,g);for(;K;){kt=!0;const Oe=K;K=K.nextSibling,a(Oe)}}else k&8&&_.textContent!==b.children&&(kt=!0,_.textContent=b.children)}return _.nextSibling},E=(_,b,H,Y,M,g,I)=>{I=I||!!b.dynamicChildren;const P=b.children,W=P.length;for(let k=0;k{const{slotScopeIds:I}=b;I&&(M=M?M.concat(I):I);const P=i(_),W=E(r(_),b,P,H,Y,M,g);return W&&lo(W)&&W.data==="]"?r(b.anchor=W):(kt=!0,s(b.anchor=c("]"),P,W),W)},B=(_,b,H,Y,M,g)=>{if(kt=!0,b.el=null,g){const W=x(_);for(;;){const k=r(_);if(k&&k!==W)a(k);else break}}const I=r(_),P=i(_);return a(_),n(null,b,P,I,H,Y,oo(P),M),I},x=(_,b="[",H="]")=>{let Y=0;for(;_;)if(_=r(_),_&&lo(_)&&(_.data===b&&Y++,_.data===H)){if(Y===0)return r(_);Y--}return _},T=(_,b,H)=>{const Y=b.parentNode;Y&&Y.replaceChild(_,b);let M=H;for(;M;)M.vnode.el===b&&(M.vnode.el=M.subTree.el=_),M=M.parent},C=_=>_.nodeType===1&&_.tagName.toLowerCase()==="template";return[u,d]}const Ue=qi;function Lc(e){return Dc(e,xc)}function Dc(e,t){const n=tl();n.__VUE__=!0;const{insert:o,remove:l,patchProp:r,createElement:i,createText:a,createComment:s,setText:c,setElementText:u,parentNode:d,nextSibling:f,setScopeId:E=ut,insertStaticContent:A}=e,B=(h,p,v,y=null,L=null,R=null,q=!1,S=null,N=!!p.dynamicChildren)=>{if(h===p)return;h&&!qt(h,p)&&(y=w(h),$e(h,L,R,!0),h=null),p.patchFlag===-2&&(N=!1,p.dynamicChildren=null);const{type:O,ref:Q,shapeFlag:Z}=p;switch(O){case dn:x(h,p,v,y);break;case Je:T(h,p,v,y);break;case Dn:h==null&&C(p,v,y,q);break;case ye:k(h,p,v,y,L,R,q,S,N);break;default:Z&1?H(h,p,v,y,L,R,q,S,N):Z&6?V(h,p,v,y,L,R,q,S,N):(Z&64||Z&128)&&O.process(h,p,v,y,L,R,q,S,N,$)}Q!=null&&L&&Ao(Q,h&&h.ref,R,p||h,!p)},x=(h,p,v,y)=>{if(h==null)o(p.el=a(p.children),v,y);else{const L=p.el=h.el;p.children!==h.children&&c(L,p.children)}},T=(h,p,v,y)=>{h==null?o(p.el=s(p.children||""),v,y):p.el=h.el},C=(h,p,v,y)=>{[h.el,h.anchor]=A(h.children,p,v,y,h.el,h.anchor)},_=({el:h,anchor:p},v,y)=>{let L;for(;h&&h!==p;)L=f(h),o(h,v,y),h=L;o(p,v,y)},b=({el:h,anchor:p})=>{let v;for(;h&&h!==p;)v=f(h),l(h),h=v;l(p)},H=(h,p,v,y,L,R,q,S,N)=>{q=q||p.type==="svg",h==null?Y(p,v,y,L,R,q,S,N):I(h,p,L,R,q,S,N)},Y=(h,p,v,y,L,R,q,S)=>{let N,O;const{type:Q,props:Z,shapeFlag:X,transition:re,dirs:ae}=h;if(N=h.el=i(h.type,R,Z&&Z.is,Z),X&8?u(N,h.children):X&16&&g(h.children,N,null,y,L,R&&Q!=="foreignObject",q,S),ae&&at(h,null,y,"created"),M(N,h,h.scopeId,q,y),Z){for(const ge in Z)ge!=="value"&&!xn(ge)&&r(N,ge,null,Z[ge],R,h.children,y,L,Fe);"value"in Z&&r(N,"value",null,Z.value),(O=Z.onVnodeBeforeMount)&&Xe(O,y,h)}ae&&at(h,null,y,"beforeMount");const be=os(L,re);be&&re.beforeEnter(N),o(N,p,v),((O=Z&&Z.onVnodeMounted)||be||ae)&&Ue(()=>{O&&Xe(O,y,h),be&&re.enter(N),ae&&at(h,null,y,"mounted")},L)},M=(h,p,v,y,L)=>{if(v&&E(h,v),y)for(let R=0;R{for(let O=N;O{const S=p.el=h.el;let{patchFlag:N,dynamicChildren:O,dirs:Q}=p;N|=h.patchFlag&16;const Z=h.props||Be,X=p.props||Be;let re;v&&Vt(v,!1),(re=X.onVnodeBeforeUpdate)&&Xe(re,v,p,h),Q&&at(p,h,v,"beforeUpdate"),v&&Vt(v,!0);const ae=L&&p.type!=="foreignObject";if(O?P(h.dynamicChildren,O,S,v,y,ae,R):q||K(h,p,S,null,v,y,ae,R,!1),N>0){if(N&16)W(S,p,Z,X,v,y,L);else if(N&2&&Z.class!==X.class&&r(S,"class",null,X.class,L),N&4&&r(S,"style",Z.style,X.style,L),N&8){const be=p.dynamicProps;for(let ge=0;ge{re&&Xe(re,v,p,h),Q&&at(p,h,v,"updated")},y)},P=(h,p,v,y,L,R,q)=>{for(let S=0;S{if(v!==y){if(v!==Be)for(const S in v)!xn(S)&&!(S in y)&&r(h,S,v[S],null,q,p.children,L,R,Fe);for(const S in y){if(xn(S))continue;const N=y[S],O=v[S];N!==O&&S!=="value"&&r(h,S,O,N,q,p.children,L,R,Fe)}"value"in y&&r(h,"value",v.value,y.value)}},k=(h,p,v,y,L,R,q,S,N)=>{const O=p.el=h?h.el:a(""),Q=p.anchor=h?h.anchor:a("");let{patchFlag:Z,dynamicChildren:X,slotScopeIds:re}=p;re&&(S=S?S.concat(re):re),h==null?(o(O,v,y),o(Q,v,y),g(p.children,v,Q,L,R,q,S,N)):Z>0&&Z&64&&X&&h.dynamicChildren?(P(h.dynamicChildren,X,v,L,R,q,S),(p.key!=null||L&&p===L.subTree)&&ls(h,p,!0)):K(h,p,v,Q,L,R,q,S,N)},V=(h,p,v,y,L,R,q,S,N)=>{p.slotScopeIds=S,h==null?p.shapeFlag&512?L.ctx.activate(p,v,y,q,N):oe(p,v,y,L,R,q,N):se(h,p,N)},oe=(h,p,v,y,L,R,q)=>{const S=h.component=Vc(h,y,L);if(Un(h)&&(S.ctx.renderer=$),Mc(S),S.asyncDep){if(L&&L.registerDep(S,F),!h.el){const N=S.subTree=le(Je);T(null,N,p,v)}return}F(S,h,p,v,L,R,q)},se=(h,p,v)=>{const y=p.component=h.component;if(Ya(h,p,v))if(y.asyncDep&&!y.asyncResolved){J(y,p,v);return}else y.next=p,qa(y.update),y.update();else p.el=h.el,y.vnode=p},F=(h,p,v,y,L,R,q)=>{const S=()=>{if(h.isMounted){let{next:Q,bu:Z,u:X,parent:re,vnode:ae}=h,be=Q,ge;Vt(h,!1),Q?(Q.el=ae.el,J(h,Q,q)):Q=ae,Z&&Ho(Z),(ge=Q.props&&Q.props.onVnodeBeforeUpdate)&&Xe(ge,re,Q,ae),Vt(h,!0);const De=qo(h),tt=h.subTree;h.subTree=De,B(tt,De,d(tt.el),w(tt),h,L,R),Q.el=De.el,be===null&&Za(h,De.el),X&&Ue(X,L),(ge=Q.props&&Q.props.onVnodeUpdated)&&Ue(()=>Xe(ge,re,Q,ae),L)}else{let Q;const{el:Z,props:X}=p,{bm:re,m:ae,parent:be}=h,ge=cn(p);if(Vt(h,!1),re&&Ho(re),!ge&&(Q=X&&X.onVnodeBeforeMount)&&Xe(Q,be,p),Vt(h,!0),Z&&ue){const De=()=>{h.subTree=qo(h),ue(Z,h.subTree,h,L,null)};ge?p.type.__asyncLoader().then(()=>!h.isUnmounted&&De()):De()}else{const De=h.subTree=qo(h);B(null,De,v,y,h,L,R),p.el=De.el}if(ae&&Ue(ae,L),!ge&&(Q=X&&X.onVnodeMounted)){const De=p;Ue(()=>Xe(Q,be,De),L)}(p.shapeFlag&256||be&&cn(be.vnode)&&be.vnode.shapeFlag&256)&&h.a&&Ue(h.a,L),h.isMounted=!0,p=v=y=null}},N=h.effect=new yl(S,()=>Po(O),h.scope),O=h.update=()=>N.run();O.id=h.uid,Vt(h,!0),O()},J=(h,p,v)=>{p.component=h;const y=h.vnode.props;h.vnode=p,h.next=null,yc(h,p.props,y,v),wc(h,p.children,v),vn(),sr(),_n()},K=(h,p,v,y,L,R,q,S,N=!1)=>{const O=h&&h.children,Q=h?h.shapeFlag:0,Z=p.children,{patchFlag:X,shapeFlag:re}=p;if(X>0){if(X&128){Se(O,Z,v,y,L,R,q,S,N);return}else if(X&256){Oe(O,Z,v,y,L,R,q,S,N);return}}re&8?(Q&16&&Fe(O,L,R),Z!==O&&u(v,Z)):Q&16?re&16?Se(O,Z,v,y,L,R,q,S,N):Fe(O,L,R,!0):(Q&8&&u(v,""),re&16&&g(Z,v,y,L,R,q,S,N))},Oe=(h,p,v,y,L,R,q,S,N)=>{h=h||ln,p=p||ln;const O=h.length,Q=p.length,Z=Math.min(O,Q);let X;for(X=0;XQ?Fe(h,L,R,!0,!1,Z):g(p,v,y,L,R,q,S,N,Z)},Se=(h,p,v,y,L,R,q,S,N)=>{let O=0;const Q=p.length;let Z=h.length-1,X=Q-1;for(;O<=Z&&O<=X;){const re=h[O],ae=p[O]=N?Dt(p[O]):nt(p[O]);if(qt(re,ae))B(re,ae,v,null,L,R,q,S,N);else break;O++}for(;O<=Z&&O<=X;){const re=h[Z],ae=p[X]=N?Dt(p[X]):nt(p[X]);if(qt(re,ae))B(re,ae,v,null,L,R,q,S,N);else break;Z--,X--}if(O>Z){if(O<=X){const re=X+1,ae=reX)for(;O<=Z;)$e(h[O],L,R,!0),O++;else{const re=O,ae=O,be=new Map;for(O=ae;O<=X;O++){const Ye=p[O]=N?Dt(p[O]):nt(p[O]);Ye.key!=null&&be.set(Ye.key,O)}let ge,De=0;const tt=X-ae+1;let Xt=!1,Gl=0;const gn=new Array(tt);for(O=0;O=tt){$e(Ye,L,R,!0);continue}let st;if(Ye.key!=null)st=be.get(Ye.key);else for(ge=ae;ge<=X;ge++)if(gn[ge-ae]===0&&qt(Ye,p[ge])){st=ge;break}st===void 0?$e(Ye,L,R,!0):(gn[st-ae]=O+1,st>=Gl?Gl=st:Xt=!0,B(Ye,p[st],v,null,L,R,q,S,N),De++)}const Jl=Xt?Cc(gn):ln;for(ge=Jl.length-1,O=tt-1;O>=0;O--){const Ye=ae+O,st=p[Ye],Ql=Ye+1{const{el:R,type:q,transition:S,children:N,shapeFlag:O}=h;if(O&6){ze(h.component.subTree,p,v,y);return}if(O&128){h.suspense.move(p,v,y);return}if(O&64){q.move(h,p,v,$);return}if(q===ye){o(R,p,v);for(let Z=0;ZS.enter(R),L);else{const{leave:Z,delayLeave:X,afterLeave:re}=S,ae=()=>o(R,p,v),be=()=>{Z(R,()=>{ae(),re&&re()})};X?X(R,ae,be):be()}else o(R,p,v)},$e=(h,p,v,y=!1,L=!1)=>{const{type:R,props:q,ref:S,children:N,dynamicChildren:O,shapeFlag:Q,patchFlag:Z,dirs:X}=h;if(S!=null&&Ao(S,null,v,h,!0),Q&256){p.ctx.deactivate(h);return}const re=Q&1&&X,ae=!cn(h);let be;if(ae&&(be=q&&q.onVnodeBeforeUnmount)&&Xe(be,p,h),Q&6)it(h.component,v,y);else{if(Q&128){h.suspense.unmount(v,y);return}re&&at(h,null,p,"beforeUnmount"),Q&64?h.type.remove(h,p,v,L,$,y):O&&(R!==ye||Z>0&&Z&64)?Fe(O,p,v,!1,!0):(R===ye&&Z&384||!L&&Q&16)&&Fe(N,p,v),y&&At(h)}(ae&&(be=q&&q.onVnodeUnmounted)||re)&&Ue(()=>{be&&Xe(be,p,h),re&&at(h,null,p,"unmounted")},v)},At=h=>{const{type:p,el:v,anchor:y,transition:L}=h;if(p===ye){yt(v,y);return}if(p===Dn){b(h);return}const R=()=>{l(v),L&&!L.persisted&&L.afterLeave&&L.afterLeave()};if(h.shapeFlag&1&&L&&!L.persisted){const{leave:q,delayLeave:S}=L,N=()=>q(v,R);S?S(h.el,R,N):N()}else R()},yt=(h,p)=>{let v;for(;h!==p;)v=f(h),l(h),h=v;l(p)},it=(h,p,v)=>{const{bum:y,scope:L,update:R,subTree:q,um:S}=h;y&&Ho(y),L.stop(),R&&(R.active=!1,$e(q,h,p,v)),S&&Ue(S,p),Ue(()=>{h.isUnmounted=!0},p),p&&p.pendingBranch&&!p.isUnmounted&&h.asyncDep&&!h.asyncResolved&&h.suspenseId===p.pendingId&&(p.deps--,p.deps===0&&p.resolve())},Fe=(h,p,v,y=!1,L=!1,R=0)=>{for(let q=R;qh.shapeFlag&6?w(h.component.subTree):h.shapeFlag&128?h.suspense.next():f(h.anchor||h.el),U=(h,p,v)=>{h==null?p._vnode&&$e(p._vnode,null,null,!0):B(p._vnode||null,h,p,null,null,null,v),sr(),Eo(),p._vnode=h},$={p:B,um:$e,m:ze,r:At,mt:oe,mc:g,pc:K,pbc:P,n:w,o:e};let G,ue;return t&&([G,ue]=t($)),{render:U,hydrate:G,createApp:bc(U,G)}}function Vt({effect:e,update:t},n){e.allowRecurse=t.allowRecurse=n}function os(e,t){return(!e||e&&!e.pendingBranch)&&t&&!t.persisted}function ls(e,t,n=!1){const o=e.children,l=t.children;if(ee(o)&&ee(l))for(let r=0;r>1,e[n[a]]0&&(t[o]=n[r-1]),n[r]=o)}}for(r=n.length,i=n[r-1];r-- >0;)n[r]=i,i=t[i];return n}const Tc=e=>e.__isTeleport,ye=Symbol.for("v-fgt"),dn=Symbol.for("v-txt"),Je=Symbol.for("v-cmt"),Dn=Symbol.for("v-stc"),Cn=[];let lt=null;function z(e=!1){Cn.push(lt=e?null:[])}function Rc(){Cn.pop(),lt=Cn[Cn.length-1]||null}let In=1;function gr(e){In+=e}function rs(e){return e.dynamicChildren=In>0?lt||ln:null,Rc(),In>0&<&<.push(e),e}function te(e,t,n,o,l,r){return rs(pe(e,t,n,o,l,r,!0))}function Ce(e,t,n,o,l){return rs(le(e,t,n,o,l,!0))}function yo(e){return e?e.__v_isVNode===!0:!1}function qt(e,t){return e.type===t.type&&e.key===t.key}const So="__vInternal",is=({key:e})=>e??null,uo=({ref:e,ref_key:t,ref_for:n})=>(typeof e=="number"&&(e=""+e),e!=null?Ee(e)||Ie(e)||ie(e)?{i:Me,r:e,k:t,f:!!n}:e:null);function pe(e,t=null,n=null,o=0,l=null,r=e===ye?0:1,i=!1,a=!1){const s={__v_isVNode:!0,__v_skip:!0,type:e,props:t,key:t&&is(t),ref:t&&uo(t),scopeId:Ni,slotScopeIds:null,children:n,component:null,suspense:null,ssContent:null,ssFallback:null,dirs:null,transition:null,el:null,anchor:null,target:null,targetAnchor:null,staticCount:0,shapeFlag:r,patchFlag:o,dynamicProps:l,dynamicChildren:null,appContext:null,ctx:Me};return a?(Fl(s,n),r&128&&e.normalize(s)):n&&(s.shapeFlag|=Ee(n)?8:16),In>0&&!i&<&&(s.patchFlag>0||r&6)&&s.patchFlag!==32&<.push(s),s}const le=Pc;function Pc(e,t=null,n=null,o=0,l=null,r=!1){if((!e||e===Ga)&&(e=Je),yo(e)){const a=Ft(e,t,!0);return n&&Fl(a,n),In>0&&!r&<&&(a.shapeFlag&6?lt[lt.indexOf(e)]=a:lt.push(a)),a.patchFlag|=-2,a}if(jc(e)&&(e=e.__vccOpts),t){t=Oc(t);let{class:a,style:s}=t;a&&!Ee(a)&&(t.class=Ke(a)),ke(s)&&(Pi(s)&&!ee(s)&&(s=Pe({},s)),t.style=Nn(s))}const i=Ee(e)?1:Qa(e)?128:Tc(e)?64:ke(e)?4:ie(e)?2:0;return pe(e,t,n,o,l,i,r,!0)}function Oc(e){return e?Pi(e)||So in e?Pe({},e):e:null}function Ft(e,t,n=!1){const{props:o,ref:l,patchFlag:r,children:i}=e,a=t?fl(o||{},t):o;return{__v_isVNode:!0,__v_skip:!0,type:e.type,props:a,key:a&&is(a),ref:t&&t.ref?n&&l?ee(l)?l.concat(uo(t)):[l,uo(t)]:uo(t):l,scopeId:e.scopeId,slotScopeIds:e.slotScopeIds,children:i,target:e.target,targetAnchor:e.targetAnchor,staticCount:e.staticCount,shapeFlag:e.shapeFlag,patchFlag:t&&e.type!==ye?r===-1?16:r|16:r,dynamicProps:e.dynamicProps,dynamicChildren:e.dynamicChildren,appContext:e.appContext,dirs:e.dirs,transition:e.transition,component:e.component,suspense:e.suspense,ssContent:e.ssContent&&Ft(e.ssContent),ssFallback:e.ssFallback&&Ft(e.ssFallback),el:e.el,anchor:e.anchor,ctx:e.ctx,ce:e.ce}}function It(e=" ",t=0){return le(dn,null,e,t)}function Fc(e,t){const n=le(Dn,null,e);return n.staticCount=t,n}function xe(e="",t=!1){return t?(z(),Ce(Je,null,e)):le(Je,null,e)}function nt(e){return e==null||typeof e=="boolean"?le(Je):ee(e)?le(ye,null,e.slice()):typeof e=="object"?Dt(e):le(dn,null,String(e))}function Dt(e){return e.el===null&&e.patchFlag!==-1||e.memo?e:Ft(e)}function Fl(e,t){let n=0;const{shapeFlag:o}=e;if(t==null)t=null;else if(ee(t))n=16;else if(typeof t=="object")if(o&65){const l=t.default;l&&(l._c&&(l._d=!1),Fl(e,l()),l._c&&(l._d=!0));return}else{n=32;const l=t._;!l&&!(So in t)?t._ctx=Me:l===3&&Me&&(Me.slots._===1?t._=1:(t._=2,e.patchFlag|=1024))}else ie(t)?(t={default:t,_ctx:Me},n=32):(t=String(t),o&64?(n=16,t=[It(t)]):n=8);e.children=t,e.shapeFlag|=n}function fl(...e){const t={};for(let n=0;nTe||Me;let Sl,en,br="__VUE_INSTANCE_SETTERS__";(en=tl()[br])||(en=tl()[br]=[]),en.push(e=>Te=e),Sl=e=>{en.length>1?en.forEach(t=>t(e)):en[0](e)};const fn=e=>{Sl(e),e.scope.on()},Wt=()=>{Te&&Te.scope.off(),Sl(null)};function ss(e){return e.vnode.shapeFlag&4}let hn=!1;function Mc(e,t=!1){hn=t;const{props:n,children:o}=e.vnode,l=ss(e);Ac(e,n,l,t),kc(e,o);const r=l?$c(e,t):void 0;return hn=!1,r}function $c(e,t){const n=e.type;e.accessCache=Object.create(null),e.proxy=Oi(new Proxy(e.ctx,hc));const{setup:o}=n;if(o){const l=e.setupContext=o.length>1?Hc(e):null;fn(e),vn();const r=Rt(o,e,0,[e.props,l]);if(_n(),Wt(),mi(r)){if(r.then(Wt,Wt),t)return r.then(i=>{Ar(e,i,t)}).catch(i=>{jn(i,e,0)});e.asyncDep=r}else Ar(e,r,t)}else as(e,t)}function Ar(e,t,n){ie(t)?e.type.__ssrInlineRender?e.ssrRender=t:e.render=t:ke(t)&&(e.setupState=Ii(t)),as(e,n)}let yr;function as(e,t,n){const o=e.type;if(!e.render){if(!t&&yr&&!o.render){const l=o.template||Pl(e).template;if(l){const{isCustomElement:r,compilerOptions:i}=e.appContext.config,{delimiters:a,compilerOptions:s}=o,c=Pe(Pe({isCustomElement:r,delimiters:a},i),s);o.render=yr(l,c)}}e.render=o.render||ut}{fn(e),vn();try{pc(e)}finally{_n(),Wt()}}}function Nc(e){return e.attrsProxy||(e.attrsProxy=new Proxy(e.attrs,{get(t,n){return We(e,"get","$attrs"),t[n]}}))}function Hc(e){const t=n=>{e.exposed=n||{}};return{get attrs(){return Nc(e)},slots:e.slots,emit:e.emit,expose:t}}function Vo(e){if(e.exposed)return e.exposeProxy||(e.exposeProxy=new Proxy(Ii(Oi(e.exposed)),{get(t,n){if(n in t)return t[n];if(n in Ln)return Ln[n](e)},has(t,n){return n in t||n in Ln}}))}function qc(e,t=!0){return ie(e)?e.displayName||e.name:e.name||t&&e.__name}function jc(e){return ie(e)&&"__vccOpts"in e}const j=(e,t)=>$a(e,t,hn);function ce(e,t,n){const o=arguments.length;return o===2?ke(t)&&!ee(t)?yo(t)?le(e,null,[t]):le(e,t):le(e,null,t):(o>3?n=Array.prototype.slice.call(arguments,2):o===3&&yo(n)&&(n=[n]),le(e,t,n))}const zc=Symbol.for("v-scx"),Uc=()=>Le(zc),Kc="3.3.10",Wc="http://www.w3.org/2000/svg",jt=typeof document<"u"?document:null,Br=jt&&jt.createElement("template"),Yc={insert:(e,t,n)=>{t.insertBefore(e,n||null)},remove:e=>{const t=e.parentNode;t&&t.removeChild(e)},createElement:(e,t,n,o)=>{const l=t?jt.createElementNS(Wc,e):jt.createElement(e,n?{is:n}:void 0);return e==="select"&&o&&o.multiple!=null&&l.setAttribute("multiple",o.multiple),l},createText:e=>jt.createTextNode(e),createComment:e=>jt.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>jt.querySelector(e),setScopeId(e,t){e.setAttribute(t,"")},insertStaticContent(e,t,n,o,l,r){const i=n?n.previousSibling:t.lastChild;if(l&&(l===r||l.nextSibling))for(;t.insertBefore(l.cloneNode(!0),n),!(l===r||!(l=l.nextSibling)););else{Br.innerHTML=o?`${e}`:e;const a=Br.content;if(o){const s=a.firstChild;for(;s.firstChild;)a.appendChild(s.firstChild);a.removeChild(s)}t.insertBefore(a,n)}return[i?i.nextSibling:t.firstChild,n?n.previousSibling:t.lastChild]}},wt="transition",bn="animation",Sn=Symbol("_vtc"),Wn=(e,{slots:t})=>ce(nc,Zc(e),t);Wn.displayName="Transition";const cs={name:String,type:String,css:{type:Boolean,default:!0},duration:[String,Number,Object],enterFromClass:String,enterActiveClass:String,enterToClass:String,appearFromClass:String,appearActiveClass:String,appearToClass:String,leaveFromClass:String,leaveActiveClass:String,leaveToClass:String};Wn.props=Pe({},Ui,cs);const Mt=(e,t=[])=>{ee(e)?e.forEach(n=>n(...t)):e&&e(...t)},kr=e=>e?ee(e)?e.some(t=>t.length>1):e.length>1:!1;function Zc(e){const t={};for(const k in e)k in cs||(t[k]=e[k]);if(e.css===!1)return t;const{name:n="v",type:o,duration:l,enterFromClass:r=`${n}-enter-from`,enterActiveClass:i=`${n}-enter-active`,enterToClass:a=`${n}-enter-to`,appearFromClass:s=r,appearActiveClass:c=i,appearToClass:u=a,leaveFromClass:d=`${n}-leave-from`,leaveActiveClass:f=`${n}-leave-active`,leaveToClass:E=`${n}-leave-to`}=e,A=Gc(l),B=A&&A[0],x=A&&A[1],{onBeforeEnter:T,onEnter:C,onEnterCancelled:_,onLeave:b,onLeaveCancelled:H,onBeforeAppear:Y=T,onAppear:M=C,onAppearCancelled:g=_}=t,I=(k,V,oe)=>{$t(k,V?u:a),$t(k,V?c:i),oe&&oe()},P=(k,V)=>{k._isLeaving=!1,$t(k,d),$t(k,E),$t(k,f),V&&V()},W=k=>(V,oe)=>{const se=k?M:C,F=()=>I(V,k,oe);Mt(se,[V,F]),wr(()=>{$t(V,k?s:r),xt(V,k?u:a),kr(se)||xr(V,o,B,F)})};return Pe(t,{onBeforeEnter(k){Mt(T,[k]),xt(k,r),xt(k,i)},onBeforeAppear(k){Mt(Y,[k]),xt(k,s),xt(k,c)},onEnter:W(!1),onAppear:W(!0),onLeave(k,V){k._isLeaving=!0;const oe=()=>P(k,V);xt(k,d),Xc(),xt(k,f),wr(()=>{k._isLeaving&&($t(k,d),xt(k,E),kr(b)||xr(k,o,x,oe))}),Mt(b,[k,oe])},onEnterCancelled(k){I(k,!1),Mt(_,[k])},onAppearCancelled(k){I(k,!0),Mt(g,[k])},onLeaveCancelled(k){P(k),Mt(H,[k])}})}function Gc(e){if(e==null)return null;if(ke(e))return[Ko(e.enter),Ko(e.leave)];{const t=Ko(e);return[t,t]}}function Ko(e){return ta(e)}function xt(e,t){t.split(/\s+/).forEach(n=>n&&e.classList.add(n)),(e[Sn]||(e[Sn]=new Set)).add(t)}function $t(e,t){t.split(/\s+/).forEach(o=>o&&e.classList.remove(o));const n=e[Sn];n&&(n.delete(t),n.size||(e[Sn]=void 0))}function wr(e){requestAnimationFrame(()=>{requestAnimationFrame(e)})}let Jc=0;function xr(e,t,n,o){const l=e._endId=++Jc,r=()=>{l===e._endId&&o()};if(n)return setTimeout(r,n);const{type:i,timeout:a,propCount:s}=Qc(e,t);if(!i)return o();const c=i+"end";let u=0;const d=()=>{e.removeEventListener(c,f),r()},f=E=>{E.target===e&&++u>=s&&d()};setTimeout(()=>{u(n[A]||"").split(", "),l=o(`${wt}Delay`),r=o(`${wt}Duration`),i=Lr(l,r),a=o(`${bn}Delay`),s=o(`${bn}Duration`),c=Lr(a,s);let u=null,d=0,f=0;t===wt?i>0&&(u=wt,d=i,f=r.length):t===bn?c>0&&(u=bn,d=c,f=s.length):(d=Math.max(i,c),u=d>0?i>c?wt:bn:null,f=u?u===wt?r.length:s.length:0);const E=u===wt&&/\b(transform|all)(,|$)/.test(o(`${wt}Property`).toString());return{type:u,timeout:d,propCount:f,hasTransform:E}}function Lr(e,t){for(;e.lengthDr(n)+Dr(e[o])))}function Dr(e){return e==="auto"?0:Number(e.slice(0,-1).replace(",","."))*1e3}function Xc(){return document.body.offsetHeight}function eu(e,t,n){const o=e[Sn];o&&(t=(t?[t,...o]:[...o]).join(" ")),t==null?e.removeAttribute("class"):n?e.setAttribute("class",t):e.className=t}const Vl=Symbol("_vod"),Bo={beforeMount(e,{value:t},{transition:n}){e[Vl]=e.style.display==="none"?"":e.style.display,n&&t?n.beforeEnter(e):An(e,t)},mounted(e,{value:t},{transition:n}){n&&t&&n.enter(e)},updated(e,{value:t,oldValue:n},{transition:o}){!t!=!n&&(o?t?(o.beforeEnter(e),An(e,!0),o.enter(e)):o.leave(e,()=>{An(e,!1)}):An(e,t))},beforeUnmount(e,{value:t}){An(e,t)}};function An(e,t){e.style.display=t?e[Vl]:"none"}function tu(e,t,n){const o=e.style,l=Ee(n);if(n&&!l){if(t&&!Ee(t))for(const r in t)n[r]==null&&hl(o,r,"");for(const r in n)hl(o,r,n[r])}else{const r=o.display;l?t!==n&&(o.cssText=n):t&&e.removeAttribute("style"),Vl in e&&(o.display=r)}}const Cr=/\s*!important$/;function hl(e,t,n){if(ee(n))n.forEach(o=>hl(e,t,o));else if(n==null&&(n=""),t.startsWith("--"))e.setProperty(t,n);else{const o=nu(e,t);Cr.test(n)?e.setProperty(Gt(o),n.replace(Cr,""),"important"):e[o]=n}}const Tr=["Webkit","Moz","ms"],Wo={};function nu(e,t){const n=Wo[t];if(n)return n;let o=dt(t);if(o!=="filter"&&o in e)return Wo[t]=o;o=Co(o);for(let l=0;lYo||(cu.then(()=>Yo=0),Yo=Date.now());function du(e,t){const n=o=>{if(!o._vts)o._vts=Date.now();else if(o._vts<=n.attached)return;et(fu(o,n.value),t,5,[o])};return n.value=e,n.attached=uu(),n}function fu(e,t){if(ee(t)){const n=e.stopImmediatePropagation;return e.stopImmediatePropagation=()=>{n.call(e),e._stopped=!0},t.map(o=>l=>!l._stopped&&o&&o(l))}else return t}const Fr=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&e.charCodeAt(2)>96&&e.charCodeAt(2)<123,hu=(e,t,n,o,l=!1,r,i,a,s)=>{t==="class"?eu(e,o,l):t==="style"?tu(e,n,o):$n(t)?_l(t)||su(e,t,n,o,i):(t[0]==="."?(t=t.slice(1),!0):t[0]==="^"?(t=t.slice(1),!1):pu(e,t,o,l))?lu(e,t,o,r,i,a,s):(t==="true-value"?e._trueValue=o:t==="false-value"&&(e._falseValue=o),ou(e,t,o,l))};function pu(e,t,n,o){if(o)return!!(t==="innerHTML"||t==="textContent"||t in e&&Fr(t)&&ie(n));if(t==="spellcheck"||t==="draggable"||t==="translate"||t==="form"||t==="list"&&e.tagName==="INPUT"||t==="type"&&e.tagName==="TEXTAREA")return!1;if(t==="width"||t==="height"){const l=e.tagName;return!(l==="IMG"||l==="VIDEO"||l==="CANVAS"||l==="SOURCE")}return Fr(t)&&Ee(n)?!1:t in e}const mu={esc:"escape",space:" ",up:"arrow-up",left:"arrow-left",right:"arrow-right",down:"arrow-down",delete:"backspace"},Eu=(e,t)=>e._withKeys||(e._withKeys=n=>{if(!("key"in n))return;const o=Gt(n.key);if(t.some(l=>l===o||mu[l]===o))return e(n)}),vu=Pe({patchProp:hu},Yc);let Zo,Ir=!1;function _u(){return Zo=Ir?Zo:Lc(vu),Ir=!0,Zo}const gu=(...e)=>{const t=_u().createApp(...e),{mount:n}=t;return t.mount=o=>{const l=bu(o);if(l)return n(l,!0,l instanceof SVGElement)},t};function bu(e){return Ee(e)?document.querySelector(e):e}const Au="modulepreload",yu=function(e){return"/"+e},Sr={},m=function(t,n,o){let l=Promise.resolve();if(n&&n.length>0){const r=document.getElementsByTagName("link");l=Promise.all(n.map(i=>{if(i=yu(i),i in Sr)return;Sr[i]=!0;const a=i.endsWith(".css"),s=a?'[rel="stylesheet"]':"";if(!!o)for(let d=r.length-1;d>=0;d--){const f=r[d];if(f.href===i&&(!a||f.rel==="stylesheet"))return}else if(document.querySelector(`link[href="${i}"]${s}`))return;const u=document.createElement("link");if(u.rel=a?"stylesheet":Au,a||(u.as="script",u.crossOrigin=""),u.href=i,document.head.appendChild(u),a)return new Promise((d,f)=>{u.addEventListener("load",d),u.addEventListener("error",()=>f(new Error(`Unable to preload CSS for ${i}`)))})}))}return l.then(()=>t()).catch(r=>{const i=new Event("vite:preloadError",{cancelable:!0});if(i.payload=r,window.dispatchEvent(i),!i.defaultPrevented)throw r})},Bu={"v-070018d8":()=>m(()=>import("./2019年年度汇报.html-5zIqPlhA.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-1d07bef0":()=>m(()=>import("./2022-8机械键盘需求.html-UPAJYpuk.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-47da6a9c":()=>m(()=>import("./Mysql.html-SjpbbPal.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-68c3eedb":()=>m(()=>import("./index.html-WtnzvEI5.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-50f44d9a":()=>m(()=>import("./k2p_更新官改固件v1.9中的ssr-server.html-myu_DXA5.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-5107f338":()=>m(()=>import("./n1盒子_使用n1盒子以及罗技摄像头进行直播.html-1DGe_3H6.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-1bb63775":()=>m(()=>import("./adb.html-PCZulOnl.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-2d9e888d":()=>m(()=>import("./cf-tools.html-xEbAAg4N.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-4ac7a662":()=>m(()=>import("./django缓存.html-THwhYwkg.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-72251e04":()=>m(()=>import("./docker.html-oMuRRHsC.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-0e6ec2eb":()=>m(()=>import("./k2p-luci.html-WodZTAGg.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-67adb115":()=>m(()=>import("./kodi.html-o4IVGQ1p.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-c65efaa2":()=>m(()=>import("./linux关闭访问日志及mysql.html-24tVYX00.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-9fbc4e4a":()=>m(()=>import("./linux学习.html--GCM8Al2.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-5be7464d":()=>m(()=>import("./mac_win10双系统下的时间问题.html-1VeVPUm0.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-2f05202c":()=>m(()=>import("./markdown学习.html-z0qqMoTi.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-53b6469a":()=>m(()=>import("./nginx.html-xodFXP41.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-46b5f098":()=>m(()=>import("./oceanus.html-xIXz_Fll.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-7d01c4b5":()=>m(()=>import("./teg争霸赛.html-O4OxJDqO.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-171fb32c":()=>m(()=>import("./url重定向.html-57srkQ1H.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-688e63da":()=>m(()=>import("./vscode替代codeblock.html-i0KV3h8u.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-0ba06cdc":()=>m(()=>import("./vue修改数组内的对象.html-Zshm8zZm.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-3b4cc106":()=>m(()=>import("./webpack-source_map.html-vldnKXpI.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-43c0d09a":()=>m(()=>import("./使用onedrive在win10和linux之间同步.html-wF-F4Tgw.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-94b8d7f0":()=>m(()=>import("./使用罗技摄像头_斐讯n1盒子直播.html-8Vw1sWwQ.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-185ae8c4":()=>m(()=>import("./分辨率.html-A5Aya7jM.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-e63c018a":()=>m(()=>import("./博客搭建.html-mnoPtCHz.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-42bda90c":()=>m(()=>import("./变量命名相关.html-VlLPxf9A.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-68b2c946":()=>m(()=>import("./图形抗锯齿.html-QnGxD5ZW.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-03b64b50":()=>m(()=>import("./密码管理.html-zMIlL1m8.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-07bbb0aa":()=>m(()=>import("./数据传输.html-b78wwm4X.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-6bb06026":()=>m(()=>import("./数据整理.html-XAg1_BbR.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-579922c2":()=>m(()=>import("./文件描述符与缓冲区.html-ihVAix4D.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-0ad25c3f":()=>m(()=>import("./显卡.html-uOqhkSyc.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-2305be92":()=>m(()=>import("./显卡需求分析.html-s8yVhWzc.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-526a70af":()=>m(()=>import("./购买记录.html-jJ5CWRUF.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-44a727a6":()=>m(()=>import("./运动手表.html-FcWbk867.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-2466882a":()=>m(()=>import("./重置CMD设置.html-Nvd1Q05q.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-63cd5dba":()=>m(()=>import("./index.html-yNSHZEOF.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-02431a08":()=>m(()=>import("./celery异步任务.html-SxBcjfXw.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-736bb064":()=>m(()=>import("./django.html-Ety7BvIO.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-71f31afa":()=>m(()=>import("./pydantic特殊验证.html-HkEdQiyu.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-6b835d08":()=>m(()=>import("./pythongui-父子进程与孤儿进程.html-NY-oSU1C.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-7bcdc38f":()=>m(()=>import("./python任务队列.html-QsoxeOWC.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-26816455":()=>m(()=>import("./python使用正则过滤表情符号.html-enwOLL_3.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-39784c24":()=>m(()=>import("./python对比两个时间字符串.html-6-UMo1AV.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-2a51215c":()=>m(()=>import("./python打印行号.html-A1gPX7eV.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-38e7669c":()=>m(()=>import("./以图搜图.html-HBoOJ3G3.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-4e710776":()=>m(()=>import("./机器学习-nsfw.html-WfHOs-eL.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-6e1b0644":()=>m(()=>import("./爬虫-pdd调研.html-iLBF0K6T.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-d4a5a1a8":()=>m(()=>import("./爬虫-使用接口过tx滑块验证.html-I3bwLb3R.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-323d42ea":()=>m(()=>import("./爬虫-记一次过反爬虫的经历.html-MTH-4UYK.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-75f9e5c3":()=>m(()=>import("./爬虫-过简单js加密.html-naBOMf9p.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-4d543397":()=>m(()=>import("./进程管理.html-JMs5DErA.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-27f8a722":()=>m(()=>import("./面试.html-mdJ2GoUw.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-744af636":()=>m(()=>import("./index.html-oabfFboZ.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-1306d2e8":()=>m(()=>import("./mysql_主从复制.html-hhiDhYAg.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-33996b77":()=>m(()=>import("./drone.html-9R06-RAX.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-57d5a7e9":()=>m(()=>import("./k8s.html-LyXLVnMP.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-12fb3630":()=>m(()=>import("./oj.html-79YbMTzR.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-57e15916":()=>m(()=>import("./sudo.html-Qy0hDxEt.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-1160d8a3":()=>m(()=>import("./ubuntu_x11.html-Qjrg3K8h.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-087e08e6":()=>m(()=>import("./vmware虚拟机硬盘调整.html-LlXHLqrq.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-37242cf2":()=>m(()=>import("./【运维】expect.html-Xo_NTm5r.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-bca00f24":()=>m(()=>import("./代理使用.html-LkBfvjFZ.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-564889a0":()=>m(()=>import("./硬盘速度测试.html-6gnct4wC.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-690fb1f4":()=>m(()=>import("./网盘与同步.html-z5dwokBU.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-168cd3a7":()=>m(()=>import("./购买参考.html-j4bizFuP.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-86c67626":()=>m(()=>import("./index.html-qTwyPiP-.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-357da27c":()=>m(()=>import("./zerotier.html-w6bwfzot.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-70e270ee":()=>m(()=>import("./zerotier、二级路由、DMZ.html-dYsPzP-4.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-beb5c272":()=>m(()=>import("./异地组网.html-K2IP39Zi.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-118904ce":()=>m(()=>import("./监控某个服务正常运行.html-wDcK9f4R.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-307698ed":()=>m(()=>import("./简易监控.html-QE5yoi6q.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-cd2572f4":()=>m(()=>import("./记一次破解天翼网关.html-yPGyP_KQ.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-ce20e166":()=>m(()=>import("./index.html-1OhrB_6n.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-24dac847":()=>m(()=>import("./ffmpeg.html-8fiVg3eC.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-4a06d9af":()=>m(()=>import("./shinobi-开源NVR.html-mGkOVpVm.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-54f0d1d0":()=>m(()=>import("./23-5-22pg数据库的中文排序.html-k0DhmuBI.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-744e6dd4":()=>m(()=>import("./index.html-j6pj97yD.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-18f94f3e":()=>m(()=>import("./mysql_全表查询的优化.html-2oZQleTZ.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-70851bec":()=>m(()=>import("./project_项目配置文件.html-MQ8gDqA5.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-3c9f71df":()=>m(()=>import("./python_以图搜图系统.html-o2hDWyzD.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-5a4912c0":()=>m(()=>import("./web_web模型.html-XmBvhhvk.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-1ce7b414":()=>m(()=>import("./web_服务端渲染与客户端渲染.html-CUPLhHz3.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-6099f3b2":()=>m(()=>import("./web_装饰器模式在canvas里的应用.html-8KA7vgn8.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-29eb5e8d":()=>m(()=>import("./异步任务与事务_.html-lnVlJxsu.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-e50f7ea8":()=>m(()=>import("./计算机网络_iptables.html-0T1RzTzE.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-75d78820":()=>m(()=>import("./计算机网络_ip协议.html-cIjAa45A.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-8353569e":()=>m(()=>import("./计算机网络_路由器.html-2wDxlDEC.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-8100aa12":()=>m(()=>import("./乐观锁、悲观锁、分布式锁.html-P9kFGdGG.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-d0dc2cca":()=>m(()=>import("./基于ddd的架构.html-5cALh4sc.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-553c7882":()=>m(()=>import("./运维相关.html-6v7-SYPQ.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-211fff28":()=>m(()=>import("./index.html-wkt_QydO.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-7dfc8bcb":()=>m(()=>import("./webodm配置安装.html-_7-Ppzp6.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-7181ad41":()=>m(()=>import("./index.html-vBYbJktd.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-046aced0":()=>m(()=>import("./ddd_graphql数据流.html-kRRHB29s.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-b1bba884":()=>m(()=>import("./graphql和python.html-LZqXIs1X.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-67e92c6d":()=>m(()=>import("./graphql遇到过的问题.html-HT1ruz5l.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-17af9222":()=>m(()=>import("./index.html-JFy8A48P.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-7443725c":()=>m(()=>import("./conda.html-uf0UMaKT.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-d7f6c430":()=>m(()=>import("./cuda.html-yP6QwKyU.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-d6e05f70":()=>m(()=>import("./pytorch.html-BGmtra1R.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-3e81f7f2":()=>m(()=>import("./基于yolov5的cf自瞄.html-uSvowgMd.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-689f17cc":()=>m(()=>import("./部署paddle框架之ocr.html-vwkMyYHg.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-3706649a":()=>m(()=>import("./404.html-6Yl8cQE3.js"),__vite__mapDeps([])).then(({data:e})=>e)},ku=JSON.parse('{"base":"/","lang":"en-US","title":"","description":"","head":[],"locales":{}}');var wu=([e,t,n])=>e==="meta"&&t.name?`${e}.${t.name}`:["title","base"].includes(e)?e:e==="template"&&t.id?`${e}.${t.id}`:JSON.stringify([e,t,n]),xu=e=>{const t=new Set,n=[];return e.forEach(o=>{const l=wu(o);t.has(l)||(t.add(l),n.push(o))}),n},Yn=e=>/^(https?:)?\/\//.test(e),Lu=e=>/^[a-z][a-z0-9+.-]*:/.test(e),Ml=e=>Object.prototype.toString.call(e)==="[object Object]",us=e=>e[e.length-1]==="/"?e.slice(0,-1):e,ds=e=>e[0]==="/"?e.slice(1):e,fs=(e,t)=>{const n=Object.keys(e).sort((o,l)=>{const r=l.split("/").length-o.split("/").length;return r!==0?r:l.length-o.length});for(const o of n)if(t.startsWith(o))return o;return"/"};const hs={"v-070018d8":D(()=>m(()=>import("./2019年年度汇报.html-8RXNfl9v.js"),__vite__mapDeps([]))),"v-1d07bef0":D(()=>m(()=>import("./2022-8机械键盘需求.html-aZY-ZaE9.js"),__vite__mapDeps([]))),"v-47da6a9c":D(()=>m(()=>import("./Mysql.html-lejLX8Of.js"),__vite__mapDeps([]))),"v-68c3eedb":D(()=>m(()=>import("./index.html-D-QLn7gm.js"),__vite__mapDeps([]))),"v-50f44d9a":D(()=>m(()=>import("./k2p_更新官改固件v1.9中的ssr-server.html-b_u5zeQ6.js"),__vite__mapDeps([]))),"v-5107f338":D(()=>m(()=>import("./n1盒子_使用n1盒子以及罗技摄像头进行直播.html-Awm7UpR8.js"),__vite__mapDeps([]))),"v-1bb63775":D(()=>m(()=>import("./adb.html-aasCYosc.js"),__vite__mapDeps([]))),"v-2d9e888d":D(()=>m(()=>import("./cf-tools.html-6fH2SBD0.js"),__vite__mapDeps([0,1]))),"v-4ac7a662":D(()=>m(()=>import("./django缓存.html-NX5g_H28.js"),__vite__mapDeps([]))),"v-72251e04":D(()=>m(()=>import("./docker.html-4FlAdIF3.js"),__vite__mapDeps([]))),"v-0e6ec2eb":D(()=>m(()=>import("./k2p-luci.html-t_XdYGXg.js"),__vite__mapDeps([]))),"v-67adb115":D(()=>m(()=>import("./kodi.html-9pUgXDHi.js"),__vite__mapDeps([]))),"v-c65efaa2":D(()=>m(()=>import("./linux关闭访问日志及mysql.html-amzU4nG6.js"),__vite__mapDeps([]))),"v-9fbc4e4a":D(()=>m(()=>import("./linux学习.html-FUsT3kNP.js"),__vite__mapDeps([]))),"v-5be7464d":D(()=>m(()=>import("./mac_win10双系统下的时间问题.html-Uil1Iztz.js"),__vite__mapDeps([]))),"v-2f05202c":D(()=>m(()=>import("./markdown学习.html-reKNUoVC.js"),__vite__mapDeps([]))),"v-53b6469a":D(()=>m(()=>import("./nginx.html-5oTIskkv.js"),__vite__mapDeps([]))),"v-46b5f098":D(()=>m(()=>import("./oceanus.html-wyQKBsB6.js"),__vite__mapDeps([]))),"v-7d01c4b5":D(()=>m(()=>import("./teg争霸赛.html-KE1DSMKT.js"),__vite__mapDeps([]))),"v-171fb32c":D(()=>m(()=>import("./url重定向.html-0RgneqCm.js"),__vite__mapDeps([]))),"v-688e63da":D(()=>m(()=>import("./vscode替代codeblock.html-QvZWRnPv.js"),__vite__mapDeps([2,1]))),"v-0ba06cdc":D(()=>m(()=>import("./vue修改数组内的对象.html-1tLRHQAN.js"),__vite__mapDeps([]))),"v-3b4cc106":D(()=>m(()=>import("./webpack-source_map.html-8aoWF3hJ.js"),__vite__mapDeps([]))),"v-43c0d09a":D(()=>m(()=>import("./使用onedrive在win10和linux之间同步.html-DH2Z4RxM.js"),__vite__mapDeps([]))),"v-94b8d7f0":D(()=>m(()=>import("./使用罗技摄像头_斐讯n1盒子直播.html-Sz6mkK-i.js"),__vite__mapDeps([]))),"v-185ae8c4":D(()=>m(()=>import("./分辨率.html-RUfi1z9A.js"),__vite__mapDeps([]))),"v-e63c018a":D(()=>m(()=>import("./博客搭建.html-z_tV2tys.js"),__vite__mapDeps([3,4]))),"v-42bda90c":D(()=>m(()=>import("./变量命名相关.html-jVwTA9Zg.js"),__vite__mapDeps([]))),"v-68b2c946":D(()=>m(()=>import("./图形抗锯齿.html-swuZ5enR.js"),__vite__mapDeps([]))),"v-03b64b50":D(()=>m(()=>import("./密码管理.html-n96BGOcg.js"),__vite__mapDeps([]))),"v-07bbb0aa":D(()=>m(()=>import("./数据传输.html-ZbCJKGuL.js"),__vite__mapDeps([]))),"v-6bb06026":D(()=>m(()=>import("./数据整理.html-nkuQTRl9.js"),__vite__mapDeps([5,4]))),"v-579922c2":D(()=>m(()=>import("./文件描述符与缓冲区.html-Ih5dLzYg.js"),__vite__mapDeps([]))),"v-0ad25c3f":D(()=>m(()=>import("./显卡.html-XE63hcjH.js"),__vite__mapDeps([]))),"v-2305be92":D(()=>m(()=>import("./显卡需求分析.html-mEHcJKxM.js"),__vite__mapDeps([]))),"v-526a70af":D(()=>m(()=>import("./购买记录.html-QfUG13El.js"),__vite__mapDeps([]))),"v-44a727a6":D(()=>m(()=>import("./运动手表.html-g1Ph5wO2.js"),__vite__mapDeps([]))),"v-2466882a":D(()=>m(()=>import("./重置CMD设置.html-WYxGHLc5.js"),__vite__mapDeps([]))),"v-63cd5dba":D(()=>m(()=>import("./index.html-biE9myrq.js"),__vite__mapDeps([]))),"v-02431a08":D(()=>m(()=>import("./celery异步任务.html-0BnblJpL.js"),__vite__mapDeps([]))),"v-736bb064":D(()=>m(()=>import("./django.html-LrCE0hnu.js"),__vite__mapDeps([]))),"v-71f31afa":D(()=>m(()=>import("./pydantic特殊验证.html-kxDwQ-i1.js"),__vite__mapDeps([]))),"v-6b835d08":D(()=>m(()=>import("./pythongui-父子进程与孤儿进程.html-gjByGcrm.js"),__vite__mapDeps([]))),"v-7bcdc38f":D(()=>m(()=>import("./python任务队列.html-MW7lRocT.js"),__vite__mapDeps([]))),"v-26816455":D(()=>m(()=>import("./python使用正则过滤表情符号.html-0YAfmiVZ.js"),__vite__mapDeps([]))),"v-39784c24":D(()=>m(()=>import("./python对比两个时间字符串.html--3T0cbqc.js"),__vite__mapDeps([]))),"v-2a51215c":D(()=>m(()=>import("./python打印行号.html-o7fc7YJ0.js"),__vite__mapDeps([]))),"v-38e7669c":D(()=>m(()=>import("./以图搜图.html-rQJpjPS7.js"),__vite__mapDeps([]))),"v-4e710776":D(()=>m(()=>import("./机器学习-nsfw.html-LUhq-R2z.js"),__vite__mapDeps([]))),"v-6e1b0644":D(()=>m(()=>import("./爬虫-pdd调研.html-ylPxeOwC.js"),__vite__mapDeps([]))),"v-d4a5a1a8":D(()=>m(()=>import("./爬虫-使用接口过tx滑块验证.html-TeytDI-l.js"),__vite__mapDeps([]))),"v-323d42ea":D(()=>m(()=>import("./爬虫-记一次过反爬虫的经历.html-vh6R4q31.js"),__vite__mapDeps([]))),"v-75f9e5c3":D(()=>m(()=>import("./爬虫-过简单js加密.html-KN-jMbBx.js"),__vite__mapDeps([]))),"v-4d543397":D(()=>m(()=>import("./进程管理.html-OXlKZbzZ.js"),__vite__mapDeps([]))),"v-27f8a722":D(()=>m(()=>import("./面试.html-o0gloVSU.js"),__vite__mapDeps([]))),"v-744af636":D(()=>m(()=>import("./index.html-AndxTJYq.js"),__vite__mapDeps([]))),"v-1306d2e8":D(()=>m(()=>import("./mysql_主从复制.html-MzwNrIxL.js"),__vite__mapDeps([]))),"v-33996b77":D(()=>m(()=>import("./drone.html-zUPidYWq.js"),__vite__mapDeps([]))),"v-57d5a7e9":D(()=>m(()=>import("./k8s.html-buAOIcob.js"),__vite__mapDeps([]))),"v-12fb3630":D(()=>m(()=>import("./oj.html-DrprtZF7.js"),__vite__mapDeps([]))),"v-57e15916":D(()=>m(()=>import("./sudo.html-4XyrR9mM.js"),__vite__mapDeps([]))),"v-1160d8a3":D(()=>m(()=>import("./ubuntu_x11.html-vAk25k69.js"),__vite__mapDeps([]))),"v-087e08e6":D(()=>m(()=>import("./vmware虚拟机硬盘调整.html-BDfp_wEd.js"),__vite__mapDeps([]))),"v-37242cf2":D(()=>m(()=>import("./【运维】expect.html-r2NWxrez.js"),__vite__mapDeps([]))),"v-bca00f24":D(()=>m(()=>import("./代理使用.html-5t2ZHJgP.js"),__vite__mapDeps([]))),"v-564889a0":D(()=>m(()=>import("./硬盘速度测试.html-Wn0S-23-.js"),__vite__mapDeps([]))),"v-690fb1f4":D(()=>m(()=>import("./网盘与同步.html-467twRhv.js"),__vite__mapDeps([]))),"v-168cd3a7":D(()=>m(()=>import("./购买参考.html-hrg296u9.js"),__vite__mapDeps([]))),"v-86c67626":D(()=>m(()=>import("./index.html-TX7mQu1p.js"),__vite__mapDeps([]))),"v-357da27c":D(()=>m(()=>import("./zerotier.html--ebF61CG.js"),__vite__mapDeps([]))),"v-70e270ee":D(()=>m(()=>import("./zerotier、二级路由、DMZ.html-1tr5uUKd.js"),__vite__mapDeps([]))),"v-beb5c272":D(()=>m(()=>import("./异地组网.html-Tj0VW0Xz.js"),__vite__mapDeps([]))),"v-118904ce":D(()=>m(()=>import("./监控某个服务正常运行.html-L-VpgyeW.js"),__vite__mapDeps([]))),"v-307698ed":D(()=>m(()=>import("./简易监控.html-C4Pk3813.js"),__vite__mapDeps([]))),"v-cd2572f4":D(()=>m(()=>import("./记一次破解天翼网关.html-2ZogijjF.js"),__vite__mapDeps([]))),"v-ce20e166":D(()=>m(()=>import("./index.html-okFbtMfA.js"),__vite__mapDeps([]))),"v-24dac847":D(()=>m(()=>import("./ffmpeg.html--o2PJUEg.js"),__vite__mapDeps([]))),"v-4a06d9af":D(()=>m(()=>import("./shinobi-开源NVR.html-JZKGSKui.js"),__vite__mapDeps([]))),"v-54f0d1d0":D(()=>m(()=>import("./23-5-22pg数据库的中文排序.html-C_4RKu4R.js"),__vite__mapDeps([]))),"v-744e6dd4":D(()=>m(()=>import("./index.html-GZKm3Qsm.js"),__vite__mapDeps([]))),"v-18f94f3e":D(()=>m(()=>import("./mysql_全表查询的优化.html-HycpRTEg.js"),__vite__mapDeps([]))),"v-70851bec":D(()=>m(()=>import("./project_项目配置文件.html-Yb36aCmH.js"),__vite__mapDeps([]))),"v-3c9f71df":D(()=>m(()=>import("./python_以图搜图系统.html-TZtQBxRT.js"),__vite__mapDeps([]))),"v-5a4912c0":D(()=>m(()=>import("./web_web模型.html-gCwItGiF.js"),__vite__mapDeps([]))),"v-1ce7b414":D(()=>m(()=>import("./web_服务端渲染与客户端渲染.html-d2iT7On5.js"),__vite__mapDeps([]))),"v-6099f3b2":D(()=>m(()=>import("./web_装饰器模式在canvas里的应用.html-tqEN9jbM.js"),__vite__mapDeps([]))),"v-29eb5e8d":D(()=>m(()=>import("./异步任务与事务_.html-Au8WpE6u.js"),__vite__mapDeps([]))),"v-e50f7ea8":D(()=>m(()=>import("./计算机网络_iptables.html-oVpB3JjA.js"),__vite__mapDeps([]))),"v-75d78820":D(()=>m(()=>import("./计算机网络_ip协议.html-Sv4FYo54.js"),__vite__mapDeps([]))),"v-8353569e":D(()=>m(()=>import("./计算机网络_路由器.html--hNUIKTf.js"),__vite__mapDeps([]))),"v-8100aa12":D(()=>m(()=>import("./乐观锁、悲观锁、分布式锁.html-jTPLzWIf.js"),__vite__mapDeps([]))),"v-d0dc2cca":D(()=>m(()=>import("./基于ddd的架构.html-lnxupp3Q.js"),__vite__mapDeps([]))),"v-553c7882":D(()=>m(()=>import("./运维相关.html-2LDRmBaI.js"),__vite__mapDeps([]))),"v-211fff28":D(()=>m(()=>import("./index.html-rVR--s9I.js"),__vite__mapDeps([]))),"v-7dfc8bcb":D(()=>m(()=>import("./webodm配置安装.html-efDH4Tm-.js"),__vite__mapDeps([]))),"v-7181ad41":D(()=>m(()=>import("./index.html-TThl94CJ.js"),__vite__mapDeps([]))),"v-046aced0":D(()=>m(()=>import("./ddd_graphql数据流.html-P651VC0Z.js"),__vite__mapDeps([]))),"v-b1bba884":D(()=>m(()=>import("./graphql和python.html-k8cAeIZm.js"),__vite__mapDeps([]))),"v-67e92c6d":D(()=>m(()=>import("./graphql遇到过的问题.html-jjLgDvV-.js"),__vite__mapDeps([]))),"v-17af9222":D(()=>m(()=>import("./index.html-BjbYssGN.js"),__vite__mapDeps([]))),"v-7443725c":D(()=>m(()=>import("./conda.html-8vWzKDUw.js"),__vite__mapDeps([]))),"v-d7f6c430":D(()=>m(()=>import("./cuda.html-Vr_7SkES.js"),__vite__mapDeps([]))),"v-d6e05f70":D(()=>m(()=>import("./pytorch.html-T61jQByQ.js"),__vite__mapDeps([]))),"v-3e81f7f2":D(()=>m(()=>import("./基于yolov5的cf自瞄.html-ftAqeGea.js"),__vite__mapDeps([]))),"v-689f17cc":D(()=>m(()=>import("./部署paddle框架之ocr.html-5ZV3ZJJm.js"),__vite__mapDeps([]))),"v-3706649a":D(()=>m(()=>import("./404.html-jx0VGdGa.js"),__vite__mapDeps([])))};var Du=Symbol(""),ps=Symbol(""),Cu=qn({key:"",path:"",title:"",lang:"",frontmatter:{},headers:[]}),Yt=()=>{const e=Le(ps);if(!e)throw new Error("pageData() is called without provider.");return e},ms=Symbol(""),vt=()=>{const e=Le(ms);if(!e)throw new Error("usePageFrontmatter() is called without provider.");return e},Es=Symbol(""),Tu=()=>{const e=Le(Es);if(!e)throw new Error("usePageHead() is called without provider.");return e},Ru=Symbol(""),vs=Symbol(""),Pu=()=>{const e=Le(vs);if(!e)throw new Error("usePageLang() is called without provider.");return e},_s=Symbol(""),Ou=()=>{const e=Le(_s);if(!e)throw new Error("usePageLayout() is called without provider.");return e},Fu=_e(Bu),$l=Symbol(""),Zn=()=>{const e=Le($l);if(!e)throw new Error("useRouteLocale() is called without provider.");return e},on=_e(ku),gs=()=>on,bs=Symbol(""),Nl=()=>{const e=Le(bs);if(!e)throw new Error("useSiteLocaleData() is called without provider.");return e},Iu=Symbol(""),Su="Layout",Vu="NotFound",ht=Hn({resolveLayouts:e=>e.reduce((t,n)=>({...t,...n.layouts}),{}),resolvePageData:async e=>{const t=Fu.value[e];return await(t==null?void 0:t())??Cu},resolvePageFrontmatter:e=>e.frontmatter,resolvePageHead:(e,t,n)=>{const o=Ee(t.description)?t.description:n.description,l=[...ee(t.head)?t.head:[],...n.head,["title",{},e],["meta",{name:"description",content:o}]];return xu(l)},resolvePageHeadTitle:(e,t)=>[e.title,t.title].filter(n=>!!n).join(" | "),resolvePageLang:(e,t)=>e.lang||t.lang||"en-US",resolvePageLayout:(e,t)=>{let n;if(e.path){const o=e.frontmatter.layout;Ee(o)?n=o:n=Su}else n=Vu;return t[n]},resolveRouteLocale:(e,t)=>fs(e,t),resolveSiteLocaleData:(e,t)=>({...e,...e.locales[t]})}),Hl=de({name:"ClientOnly",setup(e,t){const n=_e(!1);return je(()=>{n.value=!0}),()=>{var o,l;return n.value?(l=(o=t.slots).default)==null?void 0:l.call(o):null}}}),Mu=de({name:"Content",props:{pageKey:{type:String,required:!1,default:""}},setup(e){const t=Yt(),n=j(()=>hs[e.pageKey||t.value.key]);return()=>n.value?ce(n.value):ce("div","404 Not Found")}}),St=(e={})=>e,ql=e=>Yn(e)?e:`/${ds(e)}`;function As(e,t,n){var o,l,r;t===void 0&&(t=50),n===void 0&&(n={});var i=(o=n.isImmediate)!=null&&o,a=(l=n.callback)!=null&&l,s=n.maxWait,c=Date.now(),u=[];function d(){if(s!==void 0){var E=Date.now()-c;if(E+t>=s)return s-E}return t}var f=function(){var E=[].slice.call(arguments),A=this;return new Promise(function(B,x){var T=i&&r===void 0;if(r!==void 0&&clearTimeout(r),r=setTimeout(function(){if(r=void 0,c=Date.now(),!i){var _=e.apply(A,E);a&&a(_),u.forEach(function(b){return(0,b.resolve)(_)}),u=[]}},d()),T){var C=e.apply(A,E);return a&&a(C),B(C)}u.push({resolve:B,reject:x})})};return f.cancel=function(E){r!==void 0&&clearTimeout(r),u.forEach(function(A){return(0,A.reject)(E)}),u=[]},f}/*! + * vue-router v4.2.5 + * (c) 2023 Eduardo San Martin Morote + * @license MIT + */const nn=typeof window<"u";function $u(e){return e.__esModule||e[Symbol.toStringTag]==="Module"}const ve=Object.assign;function Go(e,t){const n={};for(const o in t){const l=t[o];n[o]=rt(l)?l.map(e):e(l)}return n}const Tn=()=>{},rt=Array.isArray,Nu=/\/$/,Hu=e=>e.replace(Nu,"");function Jo(e,t,n="/"){let o,l={},r="",i="";const a=t.indexOf("#");let s=t.indexOf("?");return a=0&&(s=-1),s>-1&&(o=t.slice(0,s),r=t.slice(s+1,a>-1?a:t.length),l=e(r)),a>-1&&(o=o||t.slice(0,a),i=t.slice(a,t.length)),o=Uu(o??t,n),{fullPath:o+(r&&"?")+r+i,path:o,query:l,hash:i}}function qu(e,t){const n=t.query?e(t.query):"";return t.path+(n&&"?")+n+(t.hash||"")}function Vr(e,t){return!t||!e.toLowerCase().startsWith(t.toLowerCase())?e:e.slice(t.length)||"/"}function ju(e,t,n){const o=t.matched.length-1,l=n.matched.length-1;return o>-1&&o===l&&pn(t.matched[o],n.matched[l])&&ys(t.params,n.params)&&e(t.query)===e(n.query)&&t.hash===n.hash}function pn(e,t){return(e.aliasOf||e)===(t.aliasOf||t)}function ys(e,t){if(Object.keys(e).length!==Object.keys(t).length)return!1;for(const n in e)if(!zu(e[n],t[n]))return!1;return!0}function zu(e,t){return rt(e)?Mr(e,t):rt(t)?Mr(t,e):e===t}function Mr(e,t){return rt(t)?e.length===t.length&&e.every((n,o)=>n===t[o]):e.length===1&&e[0]===t}function Uu(e,t){if(e.startsWith("/"))return e;if(!e)return t;const n=t.split("/"),o=e.split("/"),l=o[o.length-1];(l===".."||l===".")&&o.push("");let r=n.length-1,i,a;for(i=0;i1&&r--;else break;return n.slice(0,r).join("/")+"/"+o.slice(i-(i===o.length?1:0)).join("/")}var Vn;(function(e){e.pop="pop",e.push="push"})(Vn||(Vn={}));var Rn;(function(e){e.back="back",e.forward="forward",e.unknown=""})(Rn||(Rn={}));function Ku(e){if(!e)if(nn){const t=document.querySelector("base");e=t&&t.getAttribute("href")||"/",e=e.replace(/^\w+:\/\/[^\/]+/,"")}else e="/";return e[0]!=="/"&&e[0]!=="#"&&(e="/"+e),Hu(e)}const Wu=/^[^#]+#/;function Yu(e,t){return e.replace(Wu,"#")+t}function Zu(e,t){const n=document.documentElement.getBoundingClientRect(),o=e.getBoundingClientRect();return{behavior:t.behavior,left:o.left-n.left-(t.left||0),top:o.top-n.top-(t.top||0)}}const Mo=()=>({left:window.pageXOffset,top:window.pageYOffset});function Gu(e){let t;if("el"in e){const n=e.el,o=typeof n=="string"&&n.startsWith("#"),l=typeof n=="string"?o?document.getElementById(n.slice(1)):document.querySelector(n):n;if(!l)return;t=Zu(l,e)}else t=e;"scrollBehavior"in document.documentElement.style?window.scrollTo(t):window.scrollTo(t.left!=null?t.left:window.pageXOffset,t.top!=null?t.top:window.pageYOffset)}function $r(e,t){return(history.state?history.state.position-t:-1)+e}const pl=new Map;function Ju(e,t){pl.set(e,t)}function Qu(e){const t=pl.get(e);return pl.delete(e),t}let Xu=()=>location.protocol+"//"+location.host;function Bs(e,t){const{pathname:n,search:o,hash:l}=t,r=e.indexOf("#");if(r>-1){let a=l.includes(e.slice(r))?e.slice(r).length:1,s=l.slice(a);return s[0]!=="/"&&(s="/"+s),Vr(s,"")}return Vr(n,e)+o+l}function ed(e,t,n,o){let l=[],r=[],i=null;const a=({state:f})=>{const E=Bs(e,location),A=n.value,B=t.value;let x=0;if(f){if(n.value=E,t.value=f,i&&i===A){i=null;return}x=B?f.position-B.position:0}else o(E);l.forEach(T=>{T(n.value,A,{delta:x,type:Vn.pop,direction:x?x>0?Rn.forward:Rn.back:Rn.unknown})})};function s(){i=n.value}function c(f){l.push(f);const E=()=>{const A=l.indexOf(f);A>-1&&l.splice(A,1)};return r.push(E),E}function u(){const{history:f}=window;f.state&&f.replaceState(ve({},f.state,{scroll:Mo()}),"")}function d(){for(const f of r)f();r=[],window.removeEventListener("popstate",a),window.removeEventListener("beforeunload",u)}return window.addEventListener("popstate",a),window.addEventListener("beforeunload",u,{passive:!0}),{pauseListeners:s,listen:c,destroy:d}}function Nr(e,t,n,o=!1,l=!1){return{back:e,current:t,forward:n,replaced:o,position:window.history.length,scroll:l?Mo():null}}function td(e){const{history:t,location:n}=window,o={value:Bs(e,n)},l={value:t.state};l.value||r(o.value,{back:null,current:o.value,forward:null,position:t.length-1,replaced:!0,scroll:null},!0);function r(s,c,u){const d=e.indexOf("#"),f=d>-1?(n.host&&document.querySelector("base")?e:e.slice(d))+s:Xu()+e+s;try{t[u?"replaceState":"pushState"](c,"",f),l.value=c}catch(E){console.error(E),n[u?"replace":"assign"](f)}}function i(s,c){const u=ve({},t.state,Nr(l.value.back,s,l.value.forward,!0),c,{position:l.value.position});r(s,u,!0),o.value=s}function a(s,c){const u=ve({},l.value,t.state,{forward:s,scroll:Mo()});r(u.current,u,!0);const d=ve({},Nr(o.value,s,null),{position:u.position+1},c);r(s,d,!1),o.value=s}return{location:o,state:l,push:a,replace:i}}function nd(e){e=Ku(e);const t=td(e),n=ed(e,t.state,t.location,t.replace);function o(r,i=!0){i||n.pauseListeners(),history.go(r)}const l=ve({location:"",base:e,go:o,createHref:Yu.bind(null,e)},t,n);return Object.defineProperty(l,"location",{enumerable:!0,get:()=>t.location.value}),Object.defineProperty(l,"state",{enumerable:!0,get:()=>t.state.value}),l}function od(e){return typeof e=="string"||e&&typeof e=="object"}function ks(e){return typeof e=="string"||typeof e=="symbol"}const pt={path:"/",name:void 0,params:{},query:{},hash:"",fullPath:"/",matched:[],meta:{},redirectedFrom:void 0},ws=Symbol("");var Hr;(function(e){e[e.aborted=4]="aborted",e[e.cancelled=8]="cancelled",e[e.duplicated=16]="duplicated"})(Hr||(Hr={}));function mn(e,t){return ve(new Error,{type:e,[ws]:!0},t)}function ft(e,t){return e instanceof Error&&ws in e&&(t==null||!!(e.type&t))}const qr="[^/]+?",ld={sensitive:!1,strict:!1,start:!0,end:!0},rd=/[.+*?^${}()[\]/\\]/g;function id(e,t){const n=ve({},ld,t),o=[];let l=n.start?"^":"";const r=[];for(const c of e){const u=c.length?[]:[90];n.strict&&!c.length&&(l+="/");for(let d=0;dt.length?t.length===1&&t[0]===80?1:-1:0}function ad(e,t){let n=0;const o=e.score,l=t.score;for(;n0&&t[t.length-1]<0}const cd={type:0,value:""},ud=/[a-zA-Z0-9_]/;function dd(e){if(!e)return[[]];if(e==="/")return[[cd]];if(!e.startsWith("/"))throw new Error(`Invalid path "${e}"`);function t(E){throw new Error(`ERR (${n})/"${c}": ${E}`)}let n=0,o=n;const l=[];let r;function i(){r&&l.push(r),r=[]}let a=0,s,c="",u="";function d(){c&&(n===0?r.push({type:0,value:c}):n===1||n===2||n===3?(r.length>1&&(s==="*"||s==="+")&&t(`A repeatable param (${c}) must be alone in its segment. eg: '/:ids+.`),r.push({type:1,value:c,regexp:u,repeatable:s==="*"||s==="+",optional:s==="*"||s==="?"})):t("Invalid state to consume buffer"),c="")}function f(){c+=s}for(;a{i(C)}:Tn}function i(u){if(ks(u)){const d=o.get(u);d&&(o.delete(u),n.splice(n.indexOf(d),1),d.children.forEach(i),d.alias.forEach(i))}else{const d=n.indexOf(u);d>-1&&(n.splice(d,1),u.record.name&&o.delete(u.record.name),u.children.forEach(i),u.alias.forEach(i))}}function a(){return n}function s(u){let d=0;for(;d=0&&(u.record.path!==n[d].record.path||!xs(u,n[d]));)d++;n.splice(d,0,u),u.record.name&&!Ur(u)&&o.set(u.record.name,u)}function c(u,d){let f,E={},A,B;if("name"in u&&u.name){if(f=o.get(u.name),!f)throw mn(1,{location:u});B=f.record.name,E=ve(zr(d.params,f.keys.filter(C=>!C.optional).map(C=>C.name)),u.params&&zr(u.params,f.keys.map(C=>C.name))),A=f.stringify(E)}else if("path"in u)A=u.path,f=n.find(C=>C.re.test(A)),f&&(E=f.parse(A),B=f.record.name);else{if(f=d.name?o.get(d.name):n.find(C=>C.re.test(d.path)),!f)throw mn(1,{location:u,currentLocation:d});B=f.record.name,E=ve({},d.params,u.params),A=f.stringify(E)}const x=[];let T=f;for(;T;)x.unshift(T.record),T=T.parent;return{name:B,path:A,params:E,matched:x,meta:Ed(x)}}return e.forEach(u=>r(u)),{addRoute:r,resolve:c,removeRoute:i,getRoutes:a,getRecordMatcher:l}}function zr(e,t){const n={};for(const o of t)o in e&&(n[o]=e[o]);return n}function pd(e){return{path:e.path,redirect:e.redirect,name:e.name,meta:e.meta||{},aliasOf:void 0,beforeEnter:e.beforeEnter,props:md(e),children:e.children||[],instances:{},leaveGuards:new Set,updateGuards:new Set,enterCallbacks:{},components:"components"in e?e.components||null:e.component&&{default:e.component}}}function md(e){const t={},n=e.props||!1;if("component"in e)t.default=n;else for(const o in e.components)t[o]=typeof n=="object"?n[o]:n;return t}function Ur(e){for(;e;){if(e.record.aliasOf)return!0;e=e.parent}return!1}function Ed(e){return e.reduce((t,n)=>ve(t,n.meta),{})}function Kr(e,t){const n={};for(const o in e)n[o]=o in t?t[o]:e[o];return n}function xs(e,t){return t.children.some(n=>n===e||xs(e,n))}const Ls=/#/g,vd=/&/g,_d=/\//g,gd=/=/g,bd=/\?/g,Ds=/\+/g,Ad=/%5B/g,yd=/%5D/g,Cs=/%5E/g,Bd=/%60/g,Ts=/%7B/g,kd=/%7C/g,Rs=/%7D/g,wd=/%20/g;function jl(e){return encodeURI(""+e).replace(kd,"|").replace(Ad,"[").replace(yd,"]")}function xd(e){return jl(e).replace(Ts,"{").replace(Rs,"}").replace(Cs,"^")}function ml(e){return jl(e).replace(Ds,"%2B").replace(wd,"+").replace(Ls,"%23").replace(vd,"%26").replace(Bd,"`").replace(Ts,"{").replace(Rs,"}").replace(Cs,"^")}function Ld(e){return ml(e).replace(gd,"%3D")}function Dd(e){return jl(e).replace(Ls,"%23").replace(bd,"%3F")}function Cd(e){return e==null?"":Dd(e).replace(_d,"%2F")}function ko(e){try{return decodeURIComponent(""+e)}catch{}return""+e}function Td(e){const t={};if(e===""||e==="?")return t;const o=(e[0]==="?"?e.slice(1):e).split("&");for(let l=0;lr&&ml(r)):[o&&ml(o)]).forEach(r=>{r!==void 0&&(t+=(t.length?"&":"")+n,r!=null&&(t+="="+r))})}return t}function Rd(e){const t={};for(const n in e){const o=e[n];o!==void 0&&(t[n]=rt(o)?o.map(l=>l==null?null:""+l):o==null?o:""+o)}return t}const Pd=Symbol(""),Yr=Symbol(""),$o=Symbol(""),zl=Symbol(""),El=Symbol("");function yn(){let e=[];function t(o){return e.push(o),()=>{const l=e.indexOf(o);l>-1&&e.splice(l,1)}}function n(){e=[]}return{add:t,list:()=>e.slice(),reset:n}}function Ct(e,t,n,o,l){const r=o&&(o.enterCallbacks[l]=o.enterCallbacks[l]||[]);return()=>new Promise((i,a)=>{const s=d=>{d===!1?a(mn(4,{from:n,to:t})):d instanceof Error?a(d):od(d)?a(mn(2,{from:t,to:d})):(r&&o.enterCallbacks[l]===r&&typeof d=="function"&&r.push(d),i())},c=e.call(o&&o.instances[l],t,n,s);let u=Promise.resolve(c);e.length<3&&(u=u.then(s)),u.catch(d=>a(d))})}function Qo(e,t,n,o){const l=[];for(const r of e)for(const i in r.components){let a=r.components[i];if(!(t!=="beforeRouteEnter"&&!r.instances[i]))if(Od(a)){const c=(a.__vccOpts||a)[t];c&&l.push(Ct(c,n,o,r,i))}else{let s=a();l.push(()=>s.then(c=>{if(!c)return Promise.reject(new Error(`Couldn't resolve component "${i}" at "${r.path}"`));const u=$u(c)?c.default:c;r.components[i]=u;const f=(u.__vccOpts||u)[t];return f&&Ct(f,n,o,r,i)()}))}}return l}function Od(e){return typeof e=="object"||"displayName"in e||"props"in e||"__vccOpts"in e}function Zr(e){const t=Le($o),n=Le(zl),o=j(()=>t.resolve(ne(e.to))),l=j(()=>{const{matched:s}=o.value,{length:c}=s,u=s[c-1],d=n.matched;if(!u||!d.length)return-1;const f=d.findIndex(pn.bind(null,u));if(f>-1)return f;const E=Gr(s[c-2]);return c>1&&Gr(u)===E&&d[d.length-1].path!==E?d.findIndex(pn.bind(null,s[c-2])):f}),r=j(()=>l.value>-1&&Vd(n.params,o.value.params)),i=j(()=>l.value>-1&&l.value===n.matched.length-1&&ys(n.params,o.value.params));function a(s={}){return Sd(s)?t[ne(e.replace)?"replace":"push"](ne(e.to)).catch(Tn):Promise.resolve()}return{route:o,href:j(()=>o.value.href),isActive:r,isExactActive:i,navigate:a}}const Fd=de({name:"RouterLink",compatConfig:{MODE:3},props:{to:{type:[String,Object],required:!0},replace:Boolean,activeClass:String,exactActiveClass:String,custom:Boolean,ariaCurrentValue:{type:String,default:"page"}},useLink:Zr,setup(e,{slots:t}){const n=Hn(Zr(e)),{options:o}=Le($o),l=j(()=>({[Jr(e.activeClass,o.linkActiveClass,"router-link-active")]:n.isActive,[Jr(e.exactActiveClass,o.linkExactActiveClass,"router-link-exact-active")]:n.isExactActive}));return()=>{const r=t.default&&t.default(n);return e.custom?r:ce("a",{"aria-current":n.isExactActive?e.ariaCurrentValue:null,href:n.href,onClick:n.navigate,class:l.value},r)}}}),Id=Fd;function Sd(e){if(!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)&&!e.defaultPrevented&&!(e.button!==void 0&&e.button!==0)){if(e.currentTarget&&e.currentTarget.getAttribute){const t=e.currentTarget.getAttribute("target");if(/\b_blank\b/i.test(t))return}return e.preventDefault&&e.preventDefault(),!0}}function Vd(e,t){for(const n in t){const o=t[n],l=e[n];if(typeof o=="string"){if(o!==l)return!1}else if(!rt(l)||l.length!==o.length||o.some((r,i)=>r!==l[i]))return!1}return!0}function Gr(e){return e?e.aliasOf?e.aliasOf.path:e.path:""}const Jr=(e,t,n)=>e??t??n,Md=de({name:"RouterView",inheritAttrs:!1,props:{name:{type:String,default:"default"},route:Object},compatConfig:{MODE:3},setup(e,{attrs:t,slots:n}){const o=Le(El),l=j(()=>e.route||o.value),r=Le(Yr,0),i=j(()=>{let c=ne(r);const{matched:u}=l.value;let d;for(;(d=u[c])&&!d.components;)c++;return c}),a=j(()=>l.value.matched[i.value]);Kt(Yr,j(()=>i.value+1)),Kt(Pd,a),Kt(El,l);const s=_e();return Ge(()=>[s.value,a.value,e.name],([c,u,d],[f,E,A])=>{u&&(u.instances[d]=c,E&&E!==u&&c&&c===f&&(u.leaveGuards.size||(u.leaveGuards=E.leaveGuards),u.updateGuards.size||(u.updateGuards=E.updateGuards))),c&&u&&(!E||!pn(u,E)||!f)&&(u.enterCallbacks[d]||[]).forEach(B=>B(c))},{flush:"post"}),()=>{const c=l.value,u=e.name,d=a.value,f=d&&d.components[u];if(!f)return Qr(n.default,{Component:f,route:c});const E=d.props[u],A=E?E===!0?c.params:typeof E=="function"?E(c):E:null,x=ce(f,ve({},A,t,{onVnodeUnmounted:T=>{T.component.isUnmounted&&(d.instances[u]=null)},ref:s}));return Qr(n.default,{Component:x,route:c})||x}}});function Qr(e,t){if(!e)return null;const n=e(t);return n.length===1?n[0]:n}const Ps=Md;function $d(e){const t=hd(e.routes,e),n=e.parseQuery||Td,o=e.stringifyQuery||Wr,l=e.history,r=yn(),i=yn(),a=yn(),s=Cl(pt);let c=pt;nn&&e.scrollBehavior&&"scrollRestoration"in history&&(history.scrollRestoration="manual");const u=Go.bind(null,w=>""+w),d=Go.bind(null,Cd),f=Go.bind(null,ko);function E(w,U){let $,G;return ks(w)?($=t.getRecordMatcher(w),G=U):G=w,t.addRoute(G,$)}function A(w){const U=t.getRecordMatcher(w);U&&t.removeRoute(U)}function B(){return t.getRoutes().map(w=>w.record)}function x(w){return!!t.getRecordMatcher(w)}function T(w,U){if(U=ve({},U||s.value),typeof w=="string"){const v=Jo(n,w,U.path),y=t.resolve({path:v.path},U),L=l.createHref(v.fullPath);return ve(v,y,{params:f(y.params),hash:ko(v.hash),redirectedFrom:void 0,href:L})}let $;if("path"in w)$=ve({},w,{path:Jo(n,w.path,U.path).path});else{const v=ve({},w.params);for(const y in v)v[y]==null&&delete v[y];$=ve({},w,{params:d(v)}),U.params=d(U.params)}const G=t.resolve($,U),ue=w.hash||"";G.params=u(f(G.params));const h=qu(o,ve({},w,{hash:xd(ue),path:G.path})),p=l.createHref(h);return ve({fullPath:h,hash:ue,query:o===Wr?Rd(w.query):w.query||{}},G,{redirectedFrom:void 0,href:p})}function C(w){return typeof w=="string"?Jo(n,w,s.value.path):ve({},w)}function _(w,U){if(c!==w)return mn(8,{from:U,to:w})}function b(w){return M(w)}function H(w){return b(ve(C(w),{replace:!0}))}function Y(w){const U=w.matched[w.matched.length-1];if(U&&U.redirect){const{redirect:$}=U;let G=typeof $=="function"?$(w):$;return typeof G=="string"&&(G=G.includes("?")||G.includes("#")?G=C(G):{path:G},G.params={}),ve({query:w.query,hash:w.hash,params:"path"in G?{}:w.params},G)}}function M(w,U){const $=c=T(w),G=s.value,ue=w.state,h=w.force,p=w.replace===!0,v=Y($);if(v)return M(ve(C(v),{state:typeof v=="object"?ve({},ue,v.state):ue,force:h,replace:p}),U||$);const y=$;y.redirectedFrom=U;let L;return!h&&ju(o,G,$)&&(L=mn(16,{to:y,from:G}),ze(G,G,!0,!1)),(L?Promise.resolve(L):P(y,G)).catch(R=>ft(R)?ft(R,2)?R:Se(R):K(R,y,G)).then(R=>{if(R){if(ft(R,2))return M(ve({replace:p},C(R.to),{state:typeof R.to=="object"?ve({},ue,R.to.state):ue,force:h}),U||y)}else R=k(y,G,!0,p,ue);return W(y,G,R),R})}function g(w,U){const $=_(w,U);return $?Promise.reject($):Promise.resolve()}function I(w){const U=yt.values().next().value;return U&&typeof U.runWithContext=="function"?U.runWithContext(w):w()}function P(w,U){let $;const[G,ue,h]=Nd(w,U);$=Qo(G.reverse(),"beforeRouteLeave",w,U);for(const v of G)v.leaveGuards.forEach(y=>{$.push(Ct(y,w,U))});const p=g.bind(null,w,U);return $.push(p),Fe($).then(()=>{$=[];for(const v of r.list())$.push(Ct(v,w,U));return $.push(p),Fe($)}).then(()=>{$=Qo(ue,"beforeRouteUpdate",w,U);for(const v of ue)v.updateGuards.forEach(y=>{$.push(Ct(y,w,U))});return $.push(p),Fe($)}).then(()=>{$=[];for(const v of h)if(v.beforeEnter)if(rt(v.beforeEnter))for(const y of v.beforeEnter)$.push(Ct(y,w,U));else $.push(Ct(v.beforeEnter,w,U));return $.push(p),Fe($)}).then(()=>(w.matched.forEach(v=>v.enterCallbacks={}),$=Qo(h,"beforeRouteEnter",w,U),$.push(p),Fe($))).then(()=>{$=[];for(const v of i.list())$.push(Ct(v,w,U));return $.push(p),Fe($)}).catch(v=>ft(v,8)?v:Promise.reject(v))}function W(w,U,$){a.list().forEach(G=>I(()=>G(w,U,$)))}function k(w,U,$,G,ue){const h=_(w,U);if(h)return h;const p=U===pt,v=nn?history.state:{};$&&(G||p?l.replace(w.fullPath,ve({scroll:p&&v&&v.scroll},ue)):l.push(w.fullPath,ue)),s.value=w,ze(w,U,$,p),Se()}let V;function oe(){V||(V=l.listen((w,U,$)=>{if(!it.listening)return;const G=T(w),ue=Y(G);if(ue){M(ve(ue,{replace:!0}),G).catch(Tn);return}c=G;const h=s.value;nn&&Ju($r(h.fullPath,$.delta),Mo()),P(G,h).catch(p=>ft(p,12)?p:ft(p,2)?(M(p.to,G).then(v=>{ft(v,20)&&!$.delta&&$.type===Vn.pop&&l.go(-1,!1)}).catch(Tn),Promise.reject()):($.delta&&l.go(-$.delta,!1),K(p,G,h))).then(p=>{p=p||k(G,h,!1),p&&($.delta&&!ft(p,8)?l.go(-$.delta,!1):$.type===Vn.pop&&ft(p,20)&&l.go(-1,!1)),W(G,h,p)}).catch(Tn)}))}let se=yn(),F=yn(),J;function K(w,U,$){Se(w);const G=F.list();return G.length?G.forEach(ue=>ue(w,U,$)):console.error(w),Promise.reject(w)}function Oe(){return J&&s.value!==pt?Promise.resolve():new Promise((w,U)=>{se.add([w,U])})}function Se(w){return J||(J=!w,oe(),se.list().forEach(([U,$])=>w?$(w):U()),se.reset()),w}function ze(w,U,$,G){const{scrollBehavior:ue}=e;if(!nn||!ue)return Promise.resolve();const h=!$&&Qu($r(w.fullPath,0))||(G||!$)&&history.state&&history.state.scroll||null;return zn().then(()=>ue(w,U,h)).then(p=>p&&Gu(p)).catch(p=>K(p,w,U))}const $e=w=>l.go(w);let At;const yt=new Set,it={currentRoute:s,listening:!0,addRoute:E,removeRoute:A,hasRoute:x,getRoutes:B,resolve:T,options:e,push:b,replace:H,go:$e,back:()=>$e(-1),forward:()=>$e(1),beforeEach:r.add,beforeResolve:i.add,afterEach:a.add,onError:F.add,isReady:Oe,install(w){const U=this;w.component("RouterLink",Id),w.component("RouterView",Ps),w.config.globalProperties.$router=U,Object.defineProperty(w.config.globalProperties,"$route",{enumerable:!0,get:()=>ne(s)}),nn&&!At&&s.value===pt&&(At=!0,b(l.location).catch(ue=>{}));const $={};for(const ue in pt)Object.defineProperty($,ue,{get:()=>s.value[ue],enumerable:!0});w.provide($o,U),w.provide(zl,Ri($)),w.provide(El,s);const G=w.unmount;yt.add(w),w.unmount=function(){yt.delete(w),yt.size<1&&(c=pt,V&&V(),V=null,s.value=pt,At=!1,J=!1),G()}}};function Fe(w){return w.reduce((U,$)=>U.then(()=>I($)),Promise.resolve())}return it}function Nd(e,t){const n=[],o=[],l=[],r=Math.max(t.matched.length,e.matched.length);for(let i=0;ipn(c,a))?o.push(a):n.push(a));const s=e.matched[i];s&&(t.matched.find(c=>pn(c,s))||l.push(s))}return[n,o,l]}function Jt(){return Le($o)}function Qt(){return Le(zl)}const Hd=({headerLinkSelector:e,headerAnchorSelector:t,delay:n,offset:o=5})=>{const l=Jt(),i=As(()=>{var B,x;const a=Math.max(window.scrollY,document.documentElement.scrollTop,document.body.scrollTop);if(Math.abs(a-0)f.some(C=>C.hash===T.hash));for(let T=0;T=(((B=C.parentElement)==null?void 0:B.offsetTop)??0)-o,H=!_||a<(((x=_.parentElement)==null?void 0:x.offsetTop)??0)-o;if(!(b&&H))continue;const M=decodeURIComponent(l.currentRoute.value.hash),g=decodeURIComponent(C.hash);if(M===g)return;if(d){for(let I=T+1;I{window.addEventListener("scroll",i)}),Kn(()=>{window.removeEventListener("scroll",i)})},Xr=async(e,t)=>{const{scrollBehavior:n}=e.options;e.options.scrollBehavior=void 0,await e.replace({query:e.currentRoute.value.query,hash:t}).finally(()=>e.options.scrollBehavior=n)},qd="a.sidebar-item",jd=".header-anchor",zd=300,Ud=5,Kd=St({setup(){Hd({headerLinkSelector:qd,headerAnchorSelector:jd,delay:zd,offset:Ud})}}),ei=()=>window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0,Wd=()=>window.scrollTo({top:0,behavior:"smooth"}),Yd=de({name:"BackToTop",setup(){const e=_e(0),t=j(()=>e.value>300),n=As(()=>{e.value=ei()},100);je(()=>{e.value=ei(),window.addEventListener("scroll",()=>n())});const o=ce("div",{class:"back-to-top",onClick:Wd});return()=>ce(Wn,{name:"back-to-top"},()=>t.value?o:null)}}),Zd=St({rootComponents:[Yd]}),Gd=ce("svg",{class:"external-link-icon",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",focusable:"false",x:"0px",y:"0px",viewBox:"0 0 100 100",width:"15",height:"15"},[ce("path",{fill:"currentColor",d:"M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"}),ce("polygon",{fill:"currentColor",points:"45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"})]),Jd=de({name:"ExternalLinkIcon",props:{locales:{type:Object,required:!1,default:()=>({})}},setup(e){const t=Zn(),n=j(()=>e.locales[t.value]??{openInNewWindow:"open in new window"});return()=>ce("span",[Gd,ce("span",{class:"external-link-icon-sr-only"},n.value.openInNewWindow)])}});var Qd={"/":{openInNewWindow:"open in new window"}};const Xd=Qd,ef=St({enhance({app:e}){e.component("ExternalLinkIcon",ce(Jd,{locales:Xd}))}});/** + * NProgress, (c) 2013, 2014 Rico Sta. Cruz - http://ricostacruz.com/nprogress + * @license MIT + */const fe={settings:{minimum:.08,easing:"ease",speed:200,trickle:!0,trickleRate:.02,trickleSpeed:800,barSelector:'[role="bar"]',parent:"body",template:'
'},status:null,set:e=>{const t=fe.isStarted();e=Xo(e,fe.settings.minimum,1),fe.status=e===1?null:e;const n=fe.render(!t),o=n.querySelector(fe.settings.barSelector),l=fe.settings.speed,r=fe.settings.easing;return n.offsetWidth,tf(i=>{ro(o,{transform:"translate3d("+ti(e)+"%,0,0)",transition:"all "+l+"ms "+r}),e===1?(ro(n,{transition:"none",opacity:"1"}),n.offsetWidth,setTimeout(function(){ro(n,{transition:"all "+l+"ms linear",opacity:"0"}),setTimeout(function(){fe.remove(),i()},l)},l)):setTimeout(()=>i(),l)}),fe},isStarted:()=>typeof fe.status=="number",start:()=>{fe.status||fe.set(0);const e=()=>{setTimeout(()=>{fe.status&&(fe.trickle(),e())},fe.settings.trickleSpeed)};return fe.settings.trickle&&e(),fe},done:e=>!e&&!fe.status?fe:fe.inc(.3+.5*Math.random()).set(1),inc:e=>{let t=fe.status;return t?(typeof e!="number"&&(e=(1-t)*Xo(Math.random()*t,.1,.95)),t=Xo(t+e,0,.994),fe.set(t)):fe.start()},trickle:()=>fe.inc(Math.random()*fe.settings.trickleRate),render:e=>{if(fe.isRendered())return document.getElementById("nprogress");ni(document.documentElement,"nprogress-busy");const t=document.createElement("div");t.id="nprogress",t.innerHTML=fe.settings.template;const n=t.querySelector(fe.settings.barSelector),o=e?"-100":ti(fe.status||0),l=document.querySelector(fe.settings.parent);return ro(n,{transition:"all 0 linear",transform:"translate3d("+o+"%,0,0)"}),l!==document.body&&ni(l,"nprogress-custom-parent"),l==null||l.appendChild(t),t},remove:()=>{oi(document.documentElement,"nprogress-busy"),oi(document.querySelector(fe.settings.parent),"nprogress-custom-parent");const e=document.getElementById("nprogress");e&&nf(e)},isRendered:()=>!!document.getElementById("nprogress")},Xo=(e,t,n)=>en?n:e,ti=e=>(-1+e)*100,tf=function(){const e=[];function t(){const n=e.shift();n&&n(t)}return function(n){e.push(n),e.length===1&&t()}}(),ro=function(){const e=["Webkit","O","Moz","ms"],t={};function n(i){return i.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,function(a,s){return s.toUpperCase()})}function o(i){const a=document.body.style;if(i in a)return i;let s=e.length;const c=i.charAt(0).toUpperCase()+i.slice(1);let u;for(;s--;)if(u=e[s]+c,u in a)return u;return i}function l(i){return i=n(i),t[i]??(t[i]=o(i))}function r(i,a,s){a=l(a),i.style[a]=s}return function(i,a){for(const s in a){const c=a[s];c!==void 0&&Object.prototype.hasOwnProperty.call(a,s)&&r(i,s,c)}}}(),Os=(e,t)=>(typeof e=="string"?e:Ul(e)).indexOf(" "+t+" ")>=0,ni=(e,t)=>{const n=Ul(e),o=n+t;Os(n,t)||(e.className=o.substring(1))},oi=(e,t)=>{const n=Ul(e);if(!Os(e,t))return;const o=n.replace(" "+t+" "," ");e.className=o.substring(1,o.length-1)},Ul=e=>(" "+(e.className||"")+" ").replace(/\s+/gi," "),nf=e=>{e&&e.parentNode&&e.parentNode.removeChild(e)},of=()=>{je(()=>{const e=Jt(),t=new Set;t.add(e.currentRoute.value.path),e.beforeEach(n=>{t.has(n.path)||fe.start()}),e.afterEach(n=>{t.add(n.path),fe.done()})})},lf=St({setup(){of()}}),rf=JSON.parse(`{"sidebar":{"/notebook/":[{"text":"graphql","link":"/notebook/graphql/","collapsible":true,"children":[{"text":"graphql和python","link":"/notebook/graphql/graphql和python.md"},{"text":"graphql遇到过的问题","link":"/notebook/graphql/graphql遇到过的问题.md"},{"text":"ddd+graphql数据流","link":"/notebook/graphql/ddd+graphql数据流.md"}]},{"text":"3D建模","link":"/notebook/3D建模/","collapsible":true,"children":[{"text":"webodm配置安装","link":"/notebook/3D建模/webodm配置安装.md"}]},{"text":"markdown学习","link":"/notebook/markdown学习.md"},{"text":"docker","link":"/notebook/docker.md"},{"text":"linux关闭访问日志及mysql","link":"/notebook/linux关闭访问日志及mysql.md"},{"text":"Mysql","link":"/notebook/Mysql.md"},{"text":"adb","link":"/notebook/adb.md"},{"text":"linux学习","link":"/notebook/linux学习.md"},{"text":"2019年年度汇报","link":"/notebook/2019年年度汇报.md"},{"text":"webpack-source_map","link":"/notebook/webpack-source_map.md"},{"text":"vue修改数组内的对象","link":"/notebook/vue修改数组内的对象.md"},{"text":"teg争霸赛","link":"/notebook/teg争霸赛.md"},{"text":"oceanus","link":"/notebook/oceanus.md"},{"text":"django缓存","link":"/notebook/django缓存.md"},{"text":"nginx","link":"/notebook/nginx.md"},{"text":"kodi","link":"/notebook/kodi.md"},{"text":"使用onedrive在win10和linux之间同步","link":"/notebook/使用onedrive在win10和linux之间同步.md"},{"text":"vscode替代codeblock","link":"/notebook/vscode替代codeblock.md"},{"text":"博客搭建","link":"/notebook/博客搭建.md"},{"text":"cf-tools","link":"/notebook/cf-tools.md"},{"text":"重置CMD设置","link":"/notebook/重置CMD设置.md"},{"text":"url重定向","link":"/notebook/url重定向.md"},{"text":"数据传输","link":"/notebook/数据传输.md"},{"text":"数据整理","link":"/notebook/数据整理.md"},{"text":"k2p-luci","link":"/notebook/k2p-luci.md"},{"text":"mac+win10双系统下的时间问题","link":"/notebook/mac+win10双系统下的时间问题.md"},{"text":"使用罗技摄像头+斐讯n1盒子直播","link":"/notebook/使用罗技摄像头+斐讯n1盒子直播.md"},{"text":"[n1盒子]使用n1盒子以及罗技摄像头进行直播","link":"/notebook/[n1盒子]使用n1盒子以及罗技摄像头进行直播.md"},{"text":"[k2p]更新官改固件v1.9中的ssr-server","link":"/notebook/[k2p]更新官改固件v1.9中的ssr-server.md"},{"text":"2022-8机械键盘需求","link":"/notebook/2022-8机械键盘需求.md"},{"text":"购买记录","link":"/notebook/购买记录.md"},{"text":"显卡","link":"/notebook/显卡.md"},{"text":"分辨率","link":"/notebook/分辨率.md"},{"text":"显卡需求分析","link":"/notebook/显卡需求分析.md"},{"text":"文件描述符与缓冲区","link":"/notebook/文件描述符与缓冲区.md"},{"text":"图形抗锯齿","link":"/notebook/图形抗锯齿.md"},{"text":"密码管理","link":"/notebook/密码管理.md"},{"text":"变量命名相关","link":"/notebook/变量命名相关.md"},{"text":"运动手表","link":"/notebook/运动手表.md"}],"/ops/":[{"text":"vmware虚拟机硬盘调整","link":"/ops/vmware虚拟机硬盘调整.md"},{"text":"硬盘速度测试","link":"/ops/硬盘速度测试.md"},{"text":"购买参考","link":"/ops/购买参考.md"},{"text":"【运维】expect","link":"/ops/【运维】expect.md"},{"text":"sudo","link":"/ops/sudo.md"},{"text":"k8s","link":"/ops/k8s.md"},{"text":"ubuntu_x11","link":"/ops/ubuntu_x11.md"},{"text":"oj","link":"/ops/oj.md"},{"text":"代理使用","link":"/ops/代理使用.md"},{"text":"drone","link":"/ops/drone.md"},{"text":"网盘与同步","link":"/ops/网盘与同步.md"},{"text":"[mysql]主从复制","link":"/ops/[mysql]主从复制.md"}],"/python/":[{"text":"cv","link":"/python/cv/","collapsible":true,"children":[{"text":"基于yolov5的cf自瞄","link":"/python/cv/基于yolov5的cf自瞄.md"},{"text":"部署paddle框架之ocr","link":"/python/cv/部署paddle框架之ocr.md"},{"text":"conda","link":"/python/cv/conda.md"},{"text":"cuda","link":"/python/cv/cuda.md"},{"text":"pytorch","link":"/python/cv/pytorch.md"}]},{"text":"python对比两个时间字符串","link":"/python/python对比两个时间字符串.md"},{"text":"python使用正则过滤表情符号","link":"/python/python使用正则过滤表情符号.md"},{"text":"python打印行号","link":"/python/python打印行号.md"},{"text":"爬虫-使用接口过tx滑块验证","link":"/python/爬虫-使用接口过tx滑块验证.md"},{"text":"进程管理","link":"/python/进程管理.md"},{"text":"爬虫-过简单js加密","link":"/python/爬虫-过简单js加密.md"},{"text":"python任务队列","link":"/python/python任务队列.md"},{"text":"爬虫-pdd调研","link":"/python/爬虫-pdd调研.md"},{"text":"爬虫-记一次过反爬虫的经历","link":"/python/爬虫-记一次过反爬虫的经历.md"},{"text":"机器学习-nsfw","link":"/python/机器学习-nsfw.md"},{"text":"pythongui-父子进程与孤儿进程","link":"/python/pythongui-父子进程与孤儿进程.md"},{"text":"面试","link":"/python/面试.md"},{"text":"以图搜图","link":"/python/以图搜图.md"},{"text":"celery异步任务","link":"/python/celery异步任务.md"},{"text":"django","link":"/python/django.md"},{"text":"pydantic特殊验证","link":"/python/pydantic特殊验证.md"}],"/router/":[{"text":"记一次破解天翼网关","link":"/router/记一次破解天翼网关.md"},{"text":"zerotier、二级路由、DMZ","link":"/router/zerotier、二级路由、DMZ.md"},{"text":"zerotier","link":"/router/zerotier.md"},{"text":"异地组网","link":"/router/异地组网.md"},{"text":"监控某个服务正常运行","link":"/router/监控某个服务正常运行.md"},{"text":"简易监控","link":"/router/简易监控.md"}],"/video/":[{"text":"ffmpeg","link":"/video/ffmpeg.md"},{"text":"shinobi-开源NVR","link":"/video/shinobi-开源NVR.md"}],"/web/":[{"text":"[web]装饰器模式在canvas里的应用","link":"/web/[web]装饰器模式在canvas里的应用.md"},{"text":"[mysql]全表查询的优化","link":"/web/[mysql]全表查询的优化.md"},{"text":"[web]服务端渲染与客户端渲染","link":"/web/[web]服务端渲染与客户端渲染.md"},{"text":"[计算机网络]ip协议","link":"/web/[计算机网络]ip协议.md"},{"text":"运维相关","link":"/web/运维相关.md"},{"text":"[python]以图搜图系统","link":"/web/[python]以图搜图系统.md"},{"text":"[web]web模型","link":"/web/[web]web模型.md"},{"text":"[计算机网络]路由器","link":"/web/[计算机网络]路由器.md"},{"text":"[计算机网络]iptables","link":"/web/[计算机网络]iptables.md"},{"text":"23-5-22pg数据库的中文排序","link":"/web/23-5-22pg数据库的中文排序.md"},{"text":"基于ddd的架构","link":"/web/基于ddd的架构.md"},{"text":"[project]项目配置文件","link":"/web/[project]项目配置文件.md"},{"text":"[异步任务与事务]","link":"/web/[异步任务与事务].md"},{"text":"乐观锁、悲观锁、分布式锁","link":"/web/乐观锁、悲观锁、分布式锁.md"}]},"navbar":[{"text":"python","link":"/python/"},{"text":"web","link":"/web/"},{"text":"notebook","link":"/notebook/"},{"text":"ops","link":"/ops/"},{"text":"router","link":"/router/"},{"text":"video","link":"/video/"}],"locales":{"/":{"selectLanguageName":"English"}},"colorMode":"auto","colorModeSwitch":true,"logo":null,"repo":null,"selectLanguageText":"Languages","selectLanguageAriaLabel":"Select language","sidebarDepth":2,"editLink":true,"editLinkText":"Edit this page","lastUpdated":true,"lastUpdatedText":"Last Updated","contributors":true,"contributorsText":"Contributors","notFound":["There's nothing here.","How did we get here?","That's a Four-Oh-Four.","Looks like we've got some broken links."],"backToHome":"Take me home","openInNewWindow":"open in new window","toggleColorMode":"toggle color mode","toggleSidebar":"toggle sidebar"}`),sf=_e(rf),Fs=()=>sf,Is=Symbol(""),af=()=>{const e=Le(Is);if(!e)throw new Error("useThemeLocaleData() is called without provider.");return e},cf=(e,t)=>{const{locales:n,...o}=e;return{...o,...n==null?void 0:n[t]}},uf=St({enhance({app:e}){const t=Fs(),n=e._context.provides[$l],o=j(()=>cf(t.value,n.value));e.provide(Is,o),Object.defineProperties(e.config.globalProperties,{$theme:{get(){return t.value}},$themeLocale:{get(){return o.value}}})}}),df=de({__name:"Badge",props:{type:{type:String,required:!1,default:"tip"},text:{type:String,required:!1,default:""},vertical:{type:String,required:!1,default:void 0}},setup(e){return(t,n)=>(z(),te("span",{class:Ke(["badge",e.type]),style:Nn({verticalAlign:e.vertical})},[Ae(t.$slots,"default",{},()=>[It(Re(e.text),1)])],6))}}),we=(e,t)=>{const n=e.__vccOpts||e;for(const[o,l]of t)n[o]=l;return n},ff=we(df,[["__file","Badge.vue"]]);function li(e,t){var n;const o=Cl();return ji(()=>{o.value=e()},{...t,flush:(n=t==null?void 0:t.flush)!=null?n:"sync"}),qn(o)}function hf(e,t){let n,o,l;const r=_e(!0),i=()=>{r.value=!0,l()};Ge(e,i,{flush:"sync"});const a=typeof t=="function"?t:t.get,s=typeof t=="function"?void 0:t.set,c=Ia((u,d)=>(o=u,l=d,{get(){return r.value&&(n=a(),r.value=!1),o(),n},set(f){s==null||s(f)}}));return Object.isExtensible(c)&&(c.trigger=i),c}function Ss(e){return bi()?(ua(e),!0):!1}function En(e){return typeof e=="function"?e():ne(e)}const pf=typeof window<"u"&&typeof document<"u";typeof WorkerGlobalScope<"u"&&globalThis instanceof WorkerGlobalScope;const mf=Object.prototype.toString,Ef=e=>mf.call(e)==="[object Object]",vf=()=>{};function _f(e,t){function n(...o){return new Promise((l,r)=>{Promise.resolve(e(()=>t.apply(this,o),{fn:t,thisArg:this,args:o})).then(l).catch(r)})}return n}const Vs=e=>e();function gf(e=Vs){const t=_e(!0);function n(){t.value=!1}function o(){t.value=!0}const l=(...r)=>{t.value&&e(...r)};return{isActive:qn(t),pause:n,resume:o,eventFilter:l}}function bf(e){return e||Il()}function Af(e,t,n={}){const{eventFilter:o=Vs,...l}=n;return Ge(e,_f(o,t),l)}function yf(e,t,n={}){const{eventFilter:o,...l}=n,{eventFilter:r,pause:i,resume:a,isActive:s}=gf(o);return{stop:Af(e,t,{...l,eventFilter:r}),pause:i,resume:a,isActive:s}}function Bf(e,t=!0,n){const o=bf(n);o?je(e,o):t?e():zn(e)}function kf(e=!1,t={}){const{truthyValue:n=!0,falsyValue:o=!1}=t,l=Ie(e),r=_e(e);function i(a){if(arguments.length)return r.value=a,r.value;{const s=En(n);return r.value=r.value===s?En(o):s,r.value}}return l?i:[r,i]}function wf(e){var t;const n=En(e);return(t=n==null?void 0:n.$el)!=null?t:n}const wo=pf?window:void 0;function ri(...e){let t,n,o,l;if(typeof e[0]=="string"||Array.isArray(e[0])?([n,o,l]=e,t=wo):[t,n,o,l]=e,!t)return vf;Array.isArray(n)||(n=[n]),Array.isArray(o)||(o=[o]);const r=[],i=()=>{r.forEach(u=>u()),r.length=0},a=(u,d,f,E)=>(u.addEventListener(d,f,E),()=>u.removeEventListener(d,f,E)),s=Ge(()=>[wf(t),En(l)],([u,d])=>{if(i(),!u)return;const f=Ef(d)?{...d}:d;r.push(...n.flatMap(E=>o.map(A=>a(u,E,A,f))))},{immediate:!0,flush:"post"}),c=()=>{s(),i()};return Ss(c),c}function xf(){const e=_e(!1);return Il()&&je(()=>{e.value=!0}),e}function Lf(e){const t=xf();return j(()=>(t.value,!!e()))}function Df(e,t={}){const{window:n=wo}=t,o=Lf(()=>n&&"matchMedia"in n&&typeof n.matchMedia=="function");let l;const r=_e(!1),i=c=>{r.value=c.matches},a=()=>{l&&("removeEventListener"in l?l.removeEventListener("change",i):l.removeListener(i))},s=ji(()=>{o.value&&(a(),l=n.matchMedia(En(e)),"addEventListener"in l?l.addEventListener("change",i):l.addListener(i),r.value=l.matches)});return Ss(()=>{s(),a(),l=void 0}),r}const io=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{},so="__vueuse_ssr_handlers__",Cf=Tf();function Tf(){return so in io||(io[so]=io[so]||{}),io[so]}function Rf(e,t){return Cf[e]||t}function Pf(e){return e==null?"any":e instanceof Set?"set":e instanceof Map?"map":e instanceof Date?"date":typeof e=="boolean"?"boolean":typeof e=="string"?"string":typeof e=="object"?"object":Number.isNaN(e)?"any":"number"}const Of={boolean:{read:e=>e==="true",write:e=>String(e)},object:{read:e=>JSON.parse(e),write:e=>JSON.stringify(e)},number:{read:e=>Number.parseFloat(e),write:e=>String(e)},any:{read:e=>e,write:e=>String(e)},string:{read:e=>e,write:e=>String(e)},map:{read:e=>new Map(JSON.parse(e)),write:e=>JSON.stringify(Array.from(e.entries()))},set:{read:e=>new Set(JSON.parse(e)),write:e=>JSON.stringify(Array.from(e))},date:{read:e=>new Date(e),write:e=>e.toISOString()}},ii="vueuse-storage";function Ms(e,t,n,o={}){var l;const{flush:r="pre",deep:i=!0,listenToStorageChanges:a=!0,writeDefaults:s=!0,mergeDefaults:c=!1,shallow:u,window:d=wo,eventFilter:f,onError:E=I=>{console.error(I)},initOnMounted:A}=o,B=(u?Cl:_e)(typeof t=="function"?t():t);if(!n)try{n=Rf("getDefaultStorage",()=>{var I;return(I=wo)==null?void 0:I.localStorage})()}catch(I){E(I)}if(!n)return B;const x=En(t),T=Pf(x),C=(l=o.serializer)!=null?l:Of[T],{pause:_,resume:b}=yf(B,()=>H(B.value),{flush:r,deep:i,eventFilter:f});return d&&a&&Bf(()=>{ri(d,"storage",g),ri(d,ii,M),A&&g()}),A||g(),B;function H(I){try{if(I==null)n.removeItem(e);else{const P=C.write(I),W=n.getItem(e);W!==P&&(n.setItem(e,P),d&&d.dispatchEvent(new CustomEvent(ii,{detail:{key:e,oldValue:W,newValue:P,storageArea:n}})))}}catch(P){E(P)}}function Y(I){const P=I?I.newValue:n.getItem(e);if(P==null)return s&&x!=null&&n.setItem(e,C.write(x)),x;if(!I&&c){const W=C.read(P);return typeof c=="function"?c(W,x):T==="object"&&!Array.isArray(W)?{...x,...W}:W}else return typeof P!="string"?P:C.read(P)}function M(I){g(I.detail)}function g(I){if(!(I&&I.storageArea!==n)){if(I&&I.key==null){B.value=x;return}if(!(I&&I.key!==e)){_();try{(I==null?void 0:I.newValue)!==C.write(B.value)&&(B.value=Y(I))}catch(P){E(P)}finally{I?zn(b):b()}}}}}function Ff(e){return Df("(prefers-color-scheme: dark)",e)}const If=de({name:"CodeGroup",slots:Object,setup(e,{slots:t}){const n=_e([]),o=_e(-1),l=Ms("vuepress-code-group",{}),r=j(()=>n.value.map(c=>c.innerText).join(","));je(()=>{Ge(()=>l.value[r.value],(c=-1)=>{o.value!==c&&(o.value=c)},{immediate:!0}),Ge(o,c=>{l.value[r.value]!==c&&(l.value[r.value]=c)})});const i=(c=o.value)=>{c{c>0?o.value=c-1:o.value=n.value.length-1,n.value[o.value].focus()},s=(c,u)=>{c.key===" "||c.key==="Enter"?(c.preventDefault(),o.value=u):c.key==="ArrowRight"?(c.preventDefault(),i(u)):c.key==="ArrowLeft"&&(c.preventDefault(),a(u))};return()=>{var u;const c=(((u=t.default)==null?void 0:u.call(t))||[]).filter(d=>d.type.name==="CodeGroupItem").map(d=>(d.props===null&&(d.props={}),d));return c.length===0?null:(o.value<0||o.value>c.length-1?(o.value=c.findIndex(d=>d.props.active===""||d.props.active===!0),o.value===-1&&(o.value=0)):c.forEach((d,f)=>{d.props.active=f===o.value}),ce("div",{class:"code-group"},[ce("div",{class:"code-group__nav"},ce("ul",{class:"code-group__ul"},c.map((d,f)=>{const E=f===o.value;return ce("li",{class:"code-group__li"},ce("button",{ref:A=>{A&&(n.value[f]=A)},class:{"code-group__nav-tab":!0,"code-group__nav-tab-active":E},ariaPressed:E,ariaExpanded:E,onClick:()=>o.value=f,onKeydown:A=>s(A,f)},d.props.title))}))),c]))}}}),Sf=["aria-selected"],Vf=de({name:"CodeGroupItem"}),Mf=de({...Vf,props:{title:{type:String,required:!0},active:{type:Boolean,required:!1,default:!1}},setup(e){return(t,n)=>(z(),te("div",{class:Ke(["code-group-item",{"code-group-item__active":e.active}]),"aria-selected":e.active},[Ae(t.$slots,"default")],10,Sf))}}),$f=we(Mf,[["__file","CodeGroupItem.vue"]]),Nf=()=>Fs(),qe=()=>af(),$s=Symbol(""),Kl=()=>{const e=Le($s);if(!e)throw new Error("useDarkMode() is called without provider.");return e},Hf=()=>{const e=qe(),t=Ff(),n=Ms("vuepress-color-scheme",e.value.colorMode),o=j({get(){return e.value.colorModeSwitch?n.value==="auto"?t.value:n.value==="dark":e.value.colorMode==="dark"},set(l){l===t.value?n.value="auto":n.value=l?"dark":"light"}});Kt($s,o),qf(o)},qf=e=>{const t=(n=e.value)=>{const o=window==null?void 0:window.document.querySelector("html");o==null||o.classList.toggle("dark",n)};je(()=>{Ge(e,t,{immediate:!0})}),Io(()=>t())},Ns=(...e)=>{const n=Jt().resolve(...e),o=n.matched[n.matched.length-1];if(!(o!=null&&o.redirect))return n;const{redirect:l}=o,r=ie(l)?l(n):l,i=Ee(r)?{path:r}:r;return Ns({hash:n.hash,query:n.query,params:n.params,...i})},Wl=e=>{const t=Ns(encodeURI(e));return{text:t.meta.title||e,link:t.name==="404"?e:t.fullPath}};let el=null,Bn=null;const jf={wait:()=>el,pending:()=>{el=new Promise(e=>Bn=e)},resolve:()=>{Bn==null||Bn(),el=null,Bn=null}},Hs=()=>jf,qs=Symbol("sidebarItems"),Yl=()=>{const e=Le(qs);if(!e)throw new Error("useSidebarItems() is called without provider.");return e},zf=()=>{const e=qe(),t=vt(),n=j(()=>Uf(t.value,e.value));Kt(qs,n)},Uf=(e,t)=>{const n=e.sidebar??t.sidebar??"auto",o=e.sidebarDepth??t.sidebarDepth??2;return e.home||n===!1?[]:n==="auto"?Wf(o):ee(n)?js(n,o):Ml(n)?Yf(n,o):[]},Kf=(e,t)=>({text:e.title,link:e.link,children:Zl(e.children,t)}),Zl=(e,t)=>t>0?e.map(n=>Kf(n,t-1)):[],Wf=e=>{const t=Yt();return[{text:t.value.title,children:Zl(t.value.headers,e)}]},js=(e,t)=>{const n=Qt(),o=Yt(),l=r=>{var a;let i;if(Ee(r)?i=Wl(r):i=r,i.children)return{...i,children:i.children.map(s=>l(s))};if(i.link===n.path){const s=((a=o.value.headers[0])==null?void 0:a.level)===1?o.value.headers[0].children:o.value.headers;return{...i,children:Zl(s,t)}}return i};return e.map(r=>l(r))},Yf=(e,t)=>{const n=Qt(),o=fs(e,n.path),l=e[o]??[];return js(l,t)},Zf="719px",Gf={mobile:Zf};var Mn;(function(e){e.MOBILE="mobile"})(Mn||(Mn={}));var hi;const Jf={[Mn.MOBILE]:Number.parseInt((hi=Gf.mobile)==null?void 0:hi.replace("px",""),10)},zs=(e,t)=>{const n=Jf[e];Number.isInteger(n)&&je(()=>{t(n),window.addEventListener("resize",()=>t(n),!1),window.addEventListener("orientationchange",()=>t(n),!1)})},Qf={},Xf={class:"theme-default-content"};function eh(e,t){const n=gt("Content");return z(),te("div",Xf,[le(n)])}const th=we(Qf,[["render",eh],["__file","HomeContent.vue"]]),nh={key:0,class:"features"},oh=de({__name:"HomeFeatures",setup(e){const t=vt(),n=j(()=>ee(t.value.features)?t.value.features:[]);return(o,l)=>n.value.length?(z(),te("div",nh,[(z(!0),te(ye,null,Ot(n.value,r=>(z(),te("div",{key:r.title,class:"feature"},[pe("h2",null,Re(r.title),1),pe("p",null,Re(r.details),1)]))),128))])):xe("v-if",!0)}}),lh=we(oh,[["__file","HomeFeatures.vue"]]),rh=["innerHTML"],ih=["textContent"],sh=de({__name:"HomeFooter",setup(e){const t=vt(),n=j(()=>t.value.footer),o=j(()=>t.value.footerHtml);return(l,r)=>n.value?(z(),te(ye,{key:0},[xe(" eslint-disable-next-line vue/no-v-html "),o.value?(z(),te("div",{key:0,class:"footer",innerHTML:n.value},null,8,rh)):(z(),te("div",{key:1,class:"footer",textContent:Re(n.value)},null,8,ih))],64)):xe("v-if",!0)}}),ah=we(sh,[["__file","HomeFooter.vue"]]),ch=["href","rel","target","aria-label"],uh=de({inheritAttrs:!1}),dh=de({...uh,__name:"AutoLink",props:{item:{type:Object,required:!0}},setup(e){const t=e,n=Qt(),o=gs(),{item:l}=Ro(t),r=j(()=>Yn(l.value.link)),i=j(()=>!r.value&&Lu(l.value.link)),a=j(()=>{if(!i.value){if(l.value.target)return l.value.target;if(r.value)return"_blank"}}),s=j(()=>a.value==="_blank"),c=j(()=>!r.value&&!i.value&&!s.value),u=j(()=>{if(!i.value){if(l.value.rel)return l.value.rel;if(s.value)return"noopener noreferrer"}}),d=j(()=>l.value.ariaLabel||l.value.text),f=j(()=>{const B=Object.keys(o.value.locales);return B.length?!B.some(x=>x===l.value.link):l.value.link!=="/"}),E=j(()=>f.value?n.path.startsWith(l.value.link):!1),A=j(()=>c.value?l.value.activeMatch?new RegExp(l.value.activeMatch).test(n.path):E.value:!1);return(B,x)=>{const T=gt("RouterLink"),C=gt("AutoLinkExternalIcon");return c.value?(z(),Ce(T,fl({key:0,class:{"router-link-active":A.value},to:ne(l).link,"aria-label":d.value},B.$attrs),{default:Ve(()=>[Ae(B.$slots,"before"),It(" "+Re(ne(l).text)+" ",1),Ae(B.$slots,"after")]),_:3},16,["class","to","aria-label"])):(z(),te("a",fl({key:1,class:"external-link",href:ne(l).link,rel:u.value,target:a.value,"aria-label":d.value},B.$attrs),[Ae(B.$slots,"before"),It(" "+Re(ne(l).text)+" ",1),s.value?(z(),Ce(C,{key:0})):xe("v-if",!0),Ae(B.$slots,"after")],16,ch))}}}),_t=we(dh,[["__file","AutoLink.vue"]]),fh={class:"hero"},hh={key:0,id:"main-title"},ph={key:1,class:"description"},mh={key:2,class:"actions"},Eh=de({__name:"HomeHero",setup(e){const t=vt(),n=Nl(),o=Kl(),l=j(()=>o.value&&t.value.heroImageDark!==void 0?t.value.heroImageDark:t.value.heroImage),r=j(()=>t.value.heroAlt||a.value||"hero"),i=j(()=>t.value.heroHeight||280),a=j(()=>t.value.heroText===null?null:t.value.heroText||n.value.title||"Hello"),s=j(()=>t.value.tagline===null?null:t.value.tagline||n.value.description||"Welcome to your VuePress site"),c=j(()=>ee(t.value.actions)?t.value.actions.map(({text:d,link:f,type:E="primary"})=>({text:d,link:f,type:E})):[]),u=()=>{if(!l.value)return null;const d=ce("img",{src:ql(l.value),alt:r.value,height:i.value});return t.value.heroImageDark===void 0?d:ce(Hl,()=>d)};return(d,f)=>(z(),te("header",fh,[le(u),a.value?(z(),te("h1",hh,Re(a.value),1)):xe("v-if",!0),s.value?(z(),te("p",ph,Re(s.value),1)):xe("v-if",!0),c.value.length?(z(),te("p",mh,[(z(!0),te(ye,null,Ot(c.value,E=>(z(),Ce(_t,{key:E.text,class:Ke(["action-button",[E.type]]),item:E},null,8,["class","item"]))),128))])):xe("v-if",!0)]))}}),vh=we(Eh,[["__file","HomeHero.vue"]]),_h={class:"home"},gh=de({__name:"Home",setup(e){return(t,n)=>(z(),te("main",_h,[le(vh),le(lh),le(th),le(ah)]))}}),bh=we(gh,[["__file","Home.vue"]]),Ah=de({__name:"NavbarBrand",setup(e){const t=Zn(),n=Nl(),o=qe(),l=Kl(),r=j(()=>o.value.home||t.value),i=j(()=>n.value.title),a=j(()=>l.value&&o.value.logoDark!==void 0?o.value.logoDark:o.value.logo),s=()=>{if(!a.value)return null;const c=ce("img",{class:"logo",src:ql(a.value),alt:i.value});return o.value.logoDark===void 0?c:ce(Hl,()=>c)};return(c,u)=>{const d=gt("RouterLink");return z(),Ce(d,{to:r.value},{default:Ve(()=>[le(s),i.value?(z(),te("span",{key:0,class:Ke(["site-name",{"can-hide":a.value}])},Re(i.value),3)):xe("v-if",!0)]),_:1},8,["to"])}}}),yh=we(Ah,[["__file","NavbarBrand.vue"]]),Bh=de({__name:"DropdownTransition",setup(e){const t=o=>{o.style.height=o.scrollHeight+"px"},n=o=>{o.style.height=""};return(o,l)=>(z(),Ce(Wn,{name:"dropdown",onEnter:t,onAfterEnter:n,onBeforeLeave:t},{default:Ve(()=>[Ae(o.$slots,"default")]),_:3}))}}),Us=we(Bh,[["__file","DropdownTransition.vue"]]),kh=["aria-label"],wh={class:"title"},xh=pe("span",{class:"arrow down"},null,-1),Lh=["aria-label"],Dh={class:"title"},Ch={class:"navbar-dropdown"},Th={class:"navbar-dropdown-subtitle"},Rh={key:1},Ph={class:"navbar-dropdown-subitem-wrapper"},Oh=de({__name:"NavbarDropdown",props:{item:{type:Object,required:!0}},setup(e){const t=e,{item:n}=Ro(t),o=j(()=>n.value.ariaLabel||n.value.text),l=_e(!1),r=Qt();Ge(()=>r.path,()=>{l.value=!1});const i=s=>{s.detail===0?l.value=!l.value:l.value=!1},a=(s,c)=>c[c.length-1]===s;return(s,c)=>(z(),te("div",{class:Ke(["navbar-dropdown-wrapper",{open:l.value}])},[pe("button",{class:"navbar-dropdown-title",type:"button","aria-label":o.value,onClick:i},[pe("span",wh,Re(ne(n).text),1),xh],8,kh),pe("button",{class:"navbar-dropdown-title-mobile",type:"button","aria-label":o.value,onClick:c[0]||(c[0]=u=>l.value=!l.value)},[pe("span",Dh,Re(ne(n).text),1),pe("span",{class:Ke(["arrow",l.value?"down":"right"])},null,2)],8,Lh),le(Us,null,{default:Ve(()=>[_o(pe("ul",Ch,[(z(!0),te(ye,null,Ot(ne(n).children,u=>(z(),te("li",{key:u.text,class:"navbar-dropdown-item"},[u.children?(z(),te(ye,{key:0},[pe("h4",Th,[u.link?(z(),Ce(_t,{key:0,item:u,onFocusout:d=>a(u,ne(n).children)&&u.children.length===0&&(l.value=!1)},null,8,["item","onFocusout"])):(z(),te("span",Rh,Re(u.text),1))]),pe("ul",Ph,[(z(!0),te(ye,null,Ot(u.children,d=>(z(),te("li",{key:d.link,class:"navbar-dropdown-subitem"},[le(_t,{item:d,onFocusout:f=>a(d,u.children)&&a(u,ne(n).children)&&(l.value=!1)},null,8,["item","onFocusout"])]))),128))])],64)):(z(),Ce(_t,{key:1,item:u,onFocusout:d=>a(u,ne(n).children)&&(l.value=!1)},null,8,["item","onFocusout"]))]))),128))],512),[[Bo,l.value]])]),_:1})],2))}}),Fh=we(Oh,[["__file","NavbarDropdown.vue"]]),si=e=>decodeURI(e).replace(/#.*$/,"").replace(/(index)?\.(md|html)$/,""),Ih=(e,t)=>{if(t.hash===e)return!0;const n=si(t.path),o=si(e);return n===o},Ks=(e,t)=>e.link&&Ih(e.link,t)?!0:e.children?e.children.some(n=>Ks(n,t)):!1,Ws=e=>!Yn(e)||/github\.com/.test(e)?"GitHub":/bitbucket\.org/.test(e)?"Bitbucket":/gitlab\.com/.test(e)?"GitLab":/gitee\.com/.test(e)?"Gitee":null,Sh={GitHub:":repo/edit/:branch/:path",GitLab:":repo/-/edit/:branch/:path",Gitee:":repo/edit/:branch/:path",Bitbucket:":repo/src/:branch/:path?mode=edit&spa=0&at=:branch&fileviewer=file-view-default"},Vh=({docsRepo:e,editLinkPattern:t})=>{if(t)return t;const n=Ws(e);return n!==null?Sh[n]:null},Mh=({docsRepo:e,docsBranch:t,docsDir:n,filePathRelative:o,editLinkPattern:l})=>{if(!o)return null;const r=Vh({docsRepo:e,editLinkPattern:l});return r?r.replace(/:repo/,Yn(e)?e:`https://github.com/${e}`).replace(/:branch/,t).replace(/:path/,ds(`${us(n)}/${o}`)):null},$h={key:0,class:"navbar-items"},Nh=de({__name:"NavbarItems",setup(e){const t=()=>{const u=Jt(),d=Zn(),f=gs(),E=Nl(),A=Nf(),B=qe();return j(()=>{const x=Object.keys(f.value.locales);if(x.length<2)return[];const T=u.currentRoute.value.path,C=u.currentRoute.value.fullPath;return[{text:`${B.value.selectLanguageText}`,ariaLabel:`${B.value.selectLanguageAriaLabel??B.value.selectLanguageText}`,children:x.map(b=>{var P,W;const H=((P=f.value.locales)==null?void 0:P[b])??{},Y=((W=A.value.locales)==null?void 0:W[b])??{},M=`${H.lang}`,g=Y.selectLanguageName??M;let I;if(M===E.value.lang)I=C;else{const k=T.replace(d.value,b);u.getRoutes().some(V=>V.path===k)?I=C.replace(T,k):I=Y.home??b}return{text:g,link:I}})}]})},n=()=>{const u=qe(),d=j(()=>u.value.repo),f=j(()=>d.value?Ws(d.value):null),E=j(()=>d.value&&!Yn(d.value)?`https://github.com/${d.value}`:d.value),A=j(()=>E.value?u.value.repoLabel?u.value.repoLabel:f.value===null?"Source":f.value:null);return j(()=>!E.value||!A.value?[]:[{text:A.value,link:E.value}])},o=u=>Ee(u)?Wl(u):u.children?{...u,children:u.children.map(o)}:u,l=()=>{const u=qe();return j(()=>(u.value.navbar||[]).map(o))},r=_e(!1),i=l(),a=t(),s=n(),c=j(()=>[...i.value,...a.value,...s.value]);return zs(Mn.MOBILE,u=>{window.innerWidthc.value.length?(z(),te("nav",$h,[(z(!0),te(ye,null,Ot(c.value,f=>(z(),te("div",{key:f.text,class:"navbar-item"},[f.children?(z(),Ce(Fh,{key:0,item:f,class:Ke(r.value?"mobile":"")},null,8,["item","class"])):(z(),Ce(_t,{key:1,item:f},null,8,["item"]))]))),128))])):xe("v-if",!0)}}),Ys=we(Nh,[["__file","NavbarItems.vue"]]),Hh=["title"],qh={class:"icon",focusable:"false",viewBox:"0 0 32 32"},jh=Fc('',9),zh=[jh],Uh={class:"icon",focusable:"false",viewBox:"0 0 32 32"},Kh=pe("path",{d:"M13.502 5.414a15.075 15.075 0 0 0 11.594 18.194a11.113 11.113 0 0 1-7.975 3.39c-.138 0-.278.005-.418 0a11.094 11.094 0 0 1-3.2-21.584M14.98 3a1.002 1.002 0 0 0-.175.016a13.096 13.096 0 0 0 1.825 25.981c.164.006.328 0 .49 0a13.072 13.072 0 0 0 10.703-5.555a1.01 1.01 0 0 0-.783-1.565A13.08 13.08 0 0 1 15.89 4.38A1.015 1.015 0 0 0 14.98 3z",fill:"currentColor"},null,-1),Wh=[Kh],Yh=de({__name:"ToggleColorModeButton",setup(e){const t=qe(),n=Kl(),o=()=>{n.value=!n.value};return(l,r)=>(z(),te("button",{class:"toggle-color-mode-button",title:ne(t).toggleColorMode,onClick:o},[_o((z(),te("svg",qh,zh,512)),[[Bo,!ne(n)]]),_o((z(),te("svg",Uh,Wh,512)),[[Bo,ne(n)]])],8,Hh))}}),Zh=we(Yh,[["__file","ToggleColorModeButton.vue"]]),Gh=["title"],Jh=pe("div",{class:"icon","aria-hidden":"true"},[pe("span"),pe("span"),pe("span")],-1),Qh=[Jh],Xh=de({__name:"ToggleSidebarButton",emits:["toggle"],setup(e){const t=qe();return(n,o)=>(z(),te("div",{class:"toggle-sidebar-button",title:ne(t).toggleSidebar,"aria-expanded":"false",role:"button",tabindex:"0",onClick:o[0]||(o[0]=l=>n.$emit("toggle"))},Qh,8,Gh))}}),ep=we(Xh,[["__file","ToggleSidebarButton.vue"]]),tp=de({__name:"Navbar",emits:["toggle-sidebar"],setup(e){const t=qe(),n=_e(null),o=_e(null),l=_e(0),r=j(()=>l.value?{maxWidth:l.value+"px"}:{});zs(Mn.MOBILE,a=>{var c;const s=i(n.value,"paddingLeft")+i(n.value,"paddingRight");window.innerWidth{const c=gt("NavbarSearch");return z(),te("header",{ref_key:"navbar",ref:n,class:"navbar"},[le(ep,{onToggle:s[0]||(s[0]=u=>a.$emit("toggle-sidebar"))}),pe("span",{ref_key:"navbarBrand",ref:o},[le(yh)],512),pe("div",{class:"navbar-items-wrapper",style:Nn(r.value)},[Ae(a.$slots,"before"),le(Ys,{class:"can-hide"}),Ae(a.$slots,"after"),ne(t).colorModeSwitch?(z(),Ce(Zh,{key:0})):xe("v-if",!0),le(c)],4)],512)}}}),np=we(tp,[["__file","Navbar.vue"]]),op={class:"page-meta"},lp={key:0,class:"meta-item edit-link"},rp={key:1,class:"meta-item last-updated"},ip={class:"meta-item-label"},sp={class:"meta-item-info"},ap={key:2,class:"meta-item contributors"},cp={class:"meta-item-label"},up={class:"meta-item-info"},dp=["title"],fp=de({__name:"PageMeta",setup(e){const t=()=>{const s=qe(),c=Yt(),u=vt();return j(()=>{if(!(u.value.editLink??s.value.editLink??!0))return null;const{repo:f,docsRepo:E=f,docsBranch:A="main",docsDir:B="",editLinkText:x}=s.value;if(!E)return null;const T=Mh({docsRepo:E,docsBranch:A,docsDir:B,filePathRelative:c.value.filePathRelative,editLinkPattern:u.value.editLinkPattern??s.value.editLinkPattern});return T?{text:x??"Edit this page",link:T}:null})},n=()=>{const s=qe(),c=Yt(),u=vt();return j(()=>{var E,A;return!(u.value.lastUpdated??s.value.lastUpdated??!0)||!((E=c.value.git)!=null&&E.updatedTime)?null:new Date((A=c.value.git)==null?void 0:A.updatedTime).toLocaleString()})},o=()=>{const s=qe(),c=Yt(),u=vt();return j(()=>{var f;return u.value.contributors??s.value.contributors??!0?((f=c.value.git)==null?void 0:f.contributors)??null:null})},l=qe(),r=t(),i=n(),a=o();return(s,c)=>{const u=gt("ClientOnly");return z(),te("footer",op,[ne(r)?(z(),te("div",lp,[le(_t,{class:"meta-item-label",item:ne(r)},null,8,["item"])])):xe("v-if",!0),ne(i)?(z(),te("div",rp,[pe("span",ip,Re(ne(l).lastUpdatedText)+": ",1),le(u,null,{default:Ve(()=>[pe("span",sp,Re(ne(i)),1)]),_:1})])):xe("v-if",!0),ne(a)&&ne(a).length?(z(),te("div",ap,[pe("span",cp,Re(ne(l).contributorsText)+": ",1),pe("span",up,[(z(!0),te(ye,null,Ot(ne(a),(d,f)=>(z(),te(ye,{key:f},[pe("span",{class:"contributor",title:`email: ${d.email}`},Re(d.name),9,dp),f!==ne(a).length-1?(z(),te(ye,{key:0},[It(", ")],64)):xe("v-if",!0)],64))),128))])])):xe("v-if",!0)])}}}),hp=we(fp,[["__file","PageMeta.vue"]]),pp={key:0,class:"page-nav"},mp={class:"inner"},Ep={key:0,class:"prev"},vp={key:1,class:"next"},_p=de({__name:"PageNav",setup(e){const t=s=>s===!1?null:Ee(s)?Wl(s):Ml(s)?s:!1,n=(s,c,u)=>{const d=s.findIndex(f=>f.link===c);if(d!==-1){const f=s[d+u];return f!=null&&f.link?f:null}for(const f of s)if(f.children){const E=n(f.children,c,u);if(E)return E}return null},o=vt(),l=Yl(),r=Qt(),i=j(()=>{const s=t(o.value.prev);return s!==!1?s:n(l.value,r.path,-1)}),a=j(()=>{const s=t(o.value.next);return s!==!1?s:n(l.value,r.path,1)});return(s,c)=>i.value||a.value?(z(),te("nav",pp,[pe("p",mp,[i.value?(z(),te("span",Ep,[le(_t,{item:i.value},null,8,["item"])])):xe("v-if",!0),a.value?(z(),te("span",vp,[le(_t,{item:a.value},null,8,["item"])])):xe("v-if",!0)])])):xe("v-if",!0)}}),gp=we(_p,[["__file","PageNav.vue"]]),bp={class:"page"},Ap={class:"theme-default-content"},yp=de({__name:"Page",setup(e){return(t,n)=>{const o=gt("Content");return z(),te("main",bp,[Ae(t.$slots,"top"),pe("div",Ap,[Ae(t.$slots,"content-top"),le(o),Ae(t.$slots,"content-bottom")]),le(hp),le(gp),Ae(t.$slots,"bottom")])}}}),Bp=we(yp,[["__file","Page.vue"]]),kp={class:"sidebar-item-children"},wp=de({__name:"SidebarItem",props:{item:{type:Object,required:!0},depth:{type:Number,required:!1,default:0}},setup(e){const t=e,{item:n,depth:o}=Ro(t),l=Qt(),r=Jt(),i=j(()=>Ks(n.value,l)),a=j(()=>({"sidebar-item":!0,"sidebar-heading":o.value===0,active:i.value,collapsible:n.value.collapsible})),s=j(()=>n.value.collapsible?i.value:!0),[c,u]=kf(s.value),d=E=>{n.value.collapsible&&(E.preventDefault(),u())},f=r.afterEach(E=>{zn(()=>{c.value=s.value})});return Kn(()=>{f()}),(E,A)=>{var x;const B=gt("SidebarItem",!0);return z(),te("li",null,[ne(n).link?(z(),Ce(_t,{key:0,class:Ke(a.value),item:ne(n)},null,8,["class","item"])):(z(),te("p",{key:1,tabindex:"0",class:Ke(a.value),onClick:d,onKeydown:Eu(d,["enter"])},[It(Re(ne(n).text)+" ",1),ne(n).collapsible?(z(),te("span",{key:0,class:Ke(["arrow",ne(c)?"down":"right"])},null,2)):xe("v-if",!0)],34)),(x=ne(n).children)!=null&&x.length?(z(),Ce(Us,{key:2},{default:Ve(()=>[_o(pe("ul",kp,[(z(!0),te(ye,null,Ot(ne(n).children,T=>(z(),Ce(B,{key:`${ne(o)}${T.text}${T.link}`,item:T,depth:ne(o)+1},null,8,["item","depth"]))),128))],512),[[Bo,ne(c)]])]),_:1})):xe("v-if",!0)])}}}),xp=we(wp,[["__file","SidebarItem.vue"]]),Lp={key:0,class:"sidebar-items"},Dp=de({__name:"SidebarItems",setup(e){const t=Qt(),n=Yl();return je(()=>{Ge(()=>t.hash,o=>{const l=document.querySelector(".sidebar");if(!l)return;const r=document.querySelector(`.sidebar a.sidebar-item[href="${t.path}${o}"]`);if(!r)return;const{top:i,height:a}=l.getBoundingClientRect(),{top:s,height:c}=r.getBoundingClientRect();si+a&&r.scrollIntoView(!1)})}),(o,l)=>ne(n).length?(z(),te("ul",Lp,[(z(!0),te(ye,null,Ot(ne(n),r=>(z(),Ce(xp,{key:`${r.text}${r.link}`,item:r},null,8,["item"]))),128))])):xe("v-if",!0)}}),Cp=we(Dp,[["__file","SidebarItems.vue"]]),Tp={class:"sidebar"},Rp=de({__name:"Sidebar",setup(e){return(t,n)=>(z(),te("aside",Tp,[le(Ys),Ae(t.$slots,"top"),le(Cp),Ae(t.$slots,"bottom")]))}}),Pp=we(Rp,[["__file","Sidebar.vue"]]),Op=de({__name:"Layout",setup(e){const t=Yt(),n=vt(),o=qe(),l=j(()=>n.value.navbar!==!1&&o.value.navbar!==!1),r=Yl(),i=_e(!1),a=x=>{i.value=typeof x=="boolean"?x:!i.value},s={x:0,y:0},c=x=>{s.x=x.changedTouches[0].clientX,s.y=x.changedTouches[0].clientY},u=x=>{const T=x.changedTouches[0].clientX-s.x,C=x.changedTouches[0].clientY-s.y;Math.abs(T)>Math.abs(C)&&Math.abs(T)>40&&(T>0&&s.x<=80?a(!0):a(!1))},d=j(()=>[{"no-navbar":!l.value,"no-sidebar":!r.value.length,"sidebar-open":i.value},n.value.pageClass]);let f;je(()=>{f=Jt().afterEach(()=>{a(!1)})}),Io(()=>{f()});const E=Hs(),A=E.resolve,B=E.pending;return(x,T)=>(z(),te("div",{class:Ke(["theme-container",d.value]),onTouchstart:c,onTouchend:u},[Ae(x.$slots,"navbar",{},()=>[l.value?(z(),Ce(np,{key:0,onToggleSidebar:a},{before:Ve(()=>[Ae(x.$slots,"navbar-before")]),after:Ve(()=>[Ae(x.$slots,"navbar-after")]),_:3})):xe("v-if",!0)]),pe("div",{class:"sidebar-mask",onClick:T[0]||(T[0]=C=>a(!1))}),Ae(x.$slots,"sidebar",{},()=>[le(Pp,null,{top:Ve(()=>[Ae(x.$slots,"sidebar-top")]),bottom:Ve(()=>[Ae(x.$slots,"sidebar-bottom")]),_:3})]),Ae(x.$slots,"page",{},()=>[ne(n).home?(z(),Ce(bh,{key:0})):(z(),Ce(Wn,{key:1,name:"fade-slide-y",mode:"out-in",onBeforeEnter:ne(A),onBeforeLeave:ne(B)},{default:Ve(()=>[(z(),Ce(Bp,{key:ne(t).path},{top:Ve(()=>[Ae(x.$slots,"page-top")]),"content-top":Ve(()=>[Ae(x.$slots,"page-content-top")]),"content-bottom":Ve(()=>[Ae(x.$slots,"page-content-bottom")]),bottom:Ve(()=>[Ae(x.$slots,"page-bottom")]),_:3}))]),_:3},8,["onBeforeEnter","onBeforeLeave"]))])],34))}}),Fp=we(Op,[["__file","Layout.vue"]]),Ip={class:"theme-container"},Sp={class:"page"},Vp={class:"theme-default-content"},Mp=pe("h1",null,"404",-1),$p=de({__name:"NotFound",setup(e){const t=Zn(),n=qe(),o=n.value.notFound??["Not Found"],l=()=>o[Math.floor(Math.random()*o.length)],r=n.value.home??t.value,i=n.value.backToHome??"Back to home";return(a,s)=>{const c=gt("RouterLink");return z(),te("div",Ip,[pe("main",Sp,[pe("div",Vp,[Mp,pe("blockquote",null,Re(l()),1),le(c,{to:ne(r)},{default:Ve(()=>[It(Re(ne(i)),1)]),_:1},8,["to"])])])])}}}),Np=we($p,[["__file","NotFound.vue"]]),Hp=St({enhance({app:e,router:t}){e.component("Badge",ff),e.component("CodeGroup",If),e.component("CodeGroupItem",$f),e.component("AutoLinkExternalIcon",()=>{const o=e.component("ExternalLinkIcon");return o?ce(o):null}),e.component("NavbarSearch",()=>{const o=e.component("Docsearch")||e.component("SearchBox");return o?ce(o):null});const n=t.options.scrollBehavior;t.options.scrollBehavior=async(...o)=>(await Hs().wait(),n(...o))},setup(){Hf(),zf()},layouts:{Layout:Fp,NotFound:Np}}),qp=e=>e instanceof Element?document.activeElement===e&&(["TEXTAREA","SELECT","INPUT"].includes(e.tagName)||e.hasAttribute("contenteditable")):!1,jp=(e,t)=>t.some(n=>{if(Ee(n))return n===e.key;const{key:o,ctrl:l=!1,shift:r=!1,alt:i=!1}=n;return o===e.key&&l===e.ctrlKey&&r===e.shiftKey&&i===e.altKey}),zp=/[^\x00-\x7F]/,Up=e=>e.split(/\s+/g).map(t=>t.trim()).filter(t=>!!t),ai=e=>e.replace(/[-/\\^$*+?.()|[\]{}]/g,"\\$&"),ci=(e,t)=>{const n=t.join(" "),o=Up(e);if(zp.test(e))return o.some(i=>n.toLowerCase().indexOf(i)>-1);const l=e.endsWith(" ");return new RegExp(o.map((i,a)=>o.length===a+1&&!l?`(?=.*\\b${ai(i)})`:`(?=.*\\b${ai(i)}\\b)`).join("")+".+","gi").test(n)},Kp=({input:e,hotKeys:t})=>{if(t.value.length===0)return;const n=o=>{e.value&&jp(o,t.value)&&!qp(o.target)&&(o.preventDefault(),e.value.focus())};je(()=>{document.addEventListener("keydown",n)}),Kn(()=>{document.removeEventListener("keydown",n)})},Wp=[{title:"",headers:[{level:3,title:"2018.10.1 开封",slug:"_2018-10-1-开封",link:"#_2018-10-1-开封",children:[]},{level:3,title:"1月 ~ 2月",slug:"_1月-2月",link:"#_1月-2月",children:[]},{level:3,title:"3月",slug:"_3月",link:"#_3月",children:[]},{level:3,title:"5月",slug:"_5月",link:"#_5月",children:[]}],path:"/notebook/2019%E5%B9%B4%E5%B9%B4%E5%BA%A6%E6%B1%87%E6%8A%A5.html",pathLocale:"/",extraFields:[]},{title:"2022-8机械键盘需求",headers:[{level:2,title:"用过的",slug:"用过的",link:"#用过的",children:[{level:3,title:"雷柏 V805",slug:"雷柏-v805",link:"#雷柏-v805",children:[]},{level:3,title:"宁芝 82",slug:"宁芝-82",link:"#宁芝-82",children:[]}]},{level:2,title:"1公司用",slug:"_1公司用",link:"#_1公司用",children:[{level:3,title:"罗技MX keys",slug:"罗技mx-keys",link:"#罗技mx-keys",children:[]},{level:3,title:"Keychen K3",slug:"keychen-k3",link:"#keychen-k3",children:[]},{level:3,title:"TTC金粉,茶静",slug:"ttc金粉-茶静",link:"#ttc金粉-茶静",children:[]}]},{level:2,title:"2家里用",slug:"_2家里用",link:"#_2家里用",children:[{level:3,title:"rk 87",slug:"rk-87",link:"#rk-87",children:[]},{level:3,title:"黑峡谷",slug:"黑峡谷",link:"#黑峡谷",children:[]},{level:3,title:"rk 98",slug:"rk-98",link:"#rk-98",children:[]},{level:3,title:"达尔优",slug:"达尔优",link:"#达尔优",children:[]},{level:3,title:"fl cmk 98",slug:"fl-cmk-98",link:"#fl-cmk-98",children:[]},{level:3,title:"akko",slug:"akko",link:"#akko",children:[]},{level:3,title:"珂芝",slug:"珂芝",link:"#珂芝",children:[]}]}],path:"/notebook/2022-8%E6%9C%BA%E6%A2%B0%E9%94%AE%E7%9B%98%E9%9C%80%E6%B1%82.html",pathLocale:"/",extraFields:[]},{title:"Mysql",headers:[{level:2,title:"2020/9/28",slug:"_2020-9-28",link:"#_2020-9-28",children:[{level:3,title:"重置mysql密码",slug:"重置mysql密码",link:"#重置mysql密码",children:[]}]},{level:2,title:"2020/4/5",slug:"_2020-4-5",link:"#_2020-4-5",children:[{level:3,title:"select insert",slug:"select-insert",link:"#select-insert",children:[]}]},{level:2,title:"2020/3/29",slug:"_2020-3-29",link:"#_2020-3-29",children:[{level:3,title:"mysql 语句分析:",slug:"mysql-语句分析",link:"#mysql-语句分析",children:[]},{level:3,title:"数据类型为text 的时间字段, 对比",slug:"数据类型为text-的时间字段-对比",link:"#数据类型为text-的时间字段-对比",children:[]},{level:3,title:"输出表的字段名 2020/03/26",slug:"输出表的字段名-2020-03-26",link:"#输出表的字段名-2020-03-26",children:[]},{level:3,title:"查询所有符合要求的行数, 同时取limit数据",slug:"查询所有符合要求的行数-同时取limit数据",link:"#查询所有符合要求的行数-同时取limit数据",children:[]}]},{level:2,title:"3/29:",slug:"_3-29",link:"#_3-29",children:[]}],path:"/notebook/Mysql.html",pathLocale:"/",extraFields:[]},{title:"这里是notebook",headers:[],path:"/notebook/",pathLocale:"/",extraFields:[]},{title:"[k2p]更新官改固件v1.9中的ssr-server",headers:[],path:"/notebook/k2p_%E6%9B%B4%E6%96%B0%E5%AE%98%E6%94%B9%E5%9B%BA%E4%BB%B6v1.9%E4%B8%AD%E7%9A%84ssr-server.html",pathLocale:"/",extraFields:[]},{title:"[n1盒子]使用n1盒子以及罗技摄像头进行直播",headers:[],path:"/notebook/n1%E7%9B%92%E5%AD%90_%E4%BD%BF%E7%94%A8n1%E7%9B%92%E5%AD%90%E4%BB%A5%E5%8F%8A%E7%BD%97%E6%8A%80%E6%91%84%E5%83%8F%E5%A4%B4%E8%BF%9B%E8%A1%8C%E7%9B%B4%E6%92%AD.html",pathLocale:"/",extraFields:[]},{title:"adb",headers:[{level:3,title:"adb 更换壁纸 2020/4/29",slug:"adb-更换壁纸-2020-4-29",link:"#adb-更换壁纸-2020-4-29",children:[]},{level:3,title:"adb 授予/撤销 应用权限 2020/4/27",slug:"adb-授予-撤销-应用权限-2020-4-27",link:"#adb-授予-撤销-应用权限-2020-4-27",children:[]},{level:3,title:"adb推送后,图片在相册中不显示 2020/4/26",slug:"adb推送后-图片在相册中不显示-2020-4-26",link:"#adb推送后-图片在相册中不显示-2020-4-26",children:[]},{level:3,title:"清空应用缓存 2020/4/19",slug:"清空应用缓存-2020-4-19",link:"#清空应用缓存-2020-4-19",children:[]}],path:"/notebook/adb.html",pathLocale:"/",extraFields:[]},{title:"cf-tools",headers:[{level:3,title:"cf-tool下载",slug:"cf-tool下载",link:"#cf-tool下载",children:[]},{level:3,title:"windows准备工作",slug:"windows准备工作",link:"#windows准备工作",children:[]},{level:3,title:"LINUX 准备工作",slug:"linux-准备工作",link:"#linux-准备工作",children:[]},{level:2,title:"配置cf",slug:"配置cf",link:"#配置cf",children:[]},{level:2,title:"简单的流程",slug:"简单的流程",link:"#简单的流程",children:[]}],path:"/notebook/cf-tools.html",pathLocale:"/",extraFields:[]},{title:"django缓存",headers:[],path:"/notebook/django%E7%BC%93%E5%AD%98.html",pathLocale:"/",extraFields:[]},{title:"2020/5/9 docKer 时区设置",headers:[{level:2,title:"Ubuntu 16.04 阿里源",slug:"ubuntu-16-04-阿里源",link:"#ubuntu-16-04-阿里源",children:[]},{level:2,title:"pip 国内源",slug:"pip-国内源",link:"#pip-国内源",children:[]}],path:"/notebook/docker.html",pathLocale:"/",extraFields:[]},{title:"k2p-luci",headers:[{level:3,title:"2022/6/1",slug:"_2022-6-1",link:"#_2022-6-1",children:[]}],path:"/notebook/k2p-luci.html",pathLocale:"/",extraFields:[]},{title:"kodi",headers:[{level:2,title:"家庭网络",slug:"家庭网络",link:"#家庭网络",children:[]},{level:2,title:"场景需求",slug:"场景需求",link:"#场景需求",children:[]},{level:2,title:"我不在家",slug:"我不在家",link:"#我不在家",children:[]},{level:2,title:"我在家",slug:"我在家",link:"#我在家",children:[]},{level:2,title:"插线板",slug:"插线板",link:"#插线板",children:[]}],path:"/notebook/kodi.html",pathLocale:"/",extraFields:[]},{title:"日志",headers:[{level:2,title:"关闭.bash_history",slug:"关闭-bash-history",link:"#关闭-bash-history",children:[]},{level:2,title:"关闭mysql连接日志",slug:"关闭mysql连接日志",link:"#关闭mysql连接日志",children:[]},{level:2,title:"关闭SSH日志",slug:"关闭ssh日志",link:"#关闭ssh日志",children:[]}],path:"/notebook/linux%E5%85%B3%E9%97%AD%E8%AE%BF%E9%97%AE%E6%97%A5%E5%BF%97%E5%8F%8Amysql.html",pathLocale:"/",extraFields:[]},{title:"linux学习",headers:[{level:3,title:"删除含有行的文件",slug:"删除含有行的文件",link:"#删除含有行的文件",children:[]},{level:2,title:"软连接 2020/4/20",slug:"软连接-2020-4-20",link:"#软连接-2020-4-20",children:[{level:3,title:"删除所有以.log结尾的文件 20200806",slug:"删除所有以-log结尾的文件-20200806",link:"#删除所有以-log结尾的文件-20200806",children:[]}]}],path:"/notebook/linux%E5%AD%A6%E4%B9%A0.html",pathLocale:"/",extraFields:[]},{title:"mac+win10双系统下的时间问题",headers:[{level:2,title:"解决问题",slug:"解决问题",link:"#解决问题",children:[]},{level:2,title:"遇到的问题",slug:"遇到的问题",link:"#遇到的问题",children:[]},{level:2,title:"20220207 时间不同步的真正原因",slug:"_20220207-时间不同步的真正原因",link:"#_20220207-时间不同步的真正原因",children:[]},{level:2,title:"2022020 使用intel连接设置",slug:"_2022020-使用intel连接设置",link:"#_2022020-使用intel连接设置",children:[]}],path:"/notebook/mac_win10%E5%8F%8C%E7%B3%BB%E7%BB%9F%E4%B8%8B%E7%9A%84%E6%97%B6%E9%97%B4%E9%97%AE%E9%A2%98.html",pathLocale:"/",extraFields:[]},{title:"markdown学习",headers:[],path:"/notebook/markdown%E5%AD%A6%E4%B9%A0.html",pathLocale:"/",extraFields:[]},{title:"nginx简洁",headers:[{level:2,title:"带PHP的页面",slug:"带php的页面",link:"#带php的页面",children:[]},{level:2,title:"nginx日志审计",slug:"nginx日志审计",link:"#nginx日志审计",children:[{level:3,title:"统计访问IP前十",slug:"统计访问ip前十",link:"#统计访问ip前十",children:[]},{level:3,title:"统计状态码",slug:"统计状态码",link:"#统计状态码",children:[]}]},{level:2,title:"nginx 安全",slug:"nginx-安全",link:"#nginx-安全",children:[{level:3,title:"账户验证",slug:"账户验证",link:"#账户验证",children:[]}]}],path:"/notebook/nginx.html",pathLocale:"/",extraFields:[]},{title:"oceanus",headers:[{level:2,title:"操作步骤",slug:"操作步骤",link:"#操作步骤",children:[]},{level:2,title:"问题1",slug:"问题1",link:"#问题1",children:[]},{level:2,title:"问题2",slug:"问题2",link:"#问题2",children:[]},{level:2,title:"问题3:",slug:"问题3",link:"#问题3",children:[]},{level:2,title:"问题4 数据消费问题",slug:"问题4-数据消费问题",link:"#问题4-数据消费问题",children:[]},{level:2,title:"问题5 导出至clickhouse数据库",slug:"问题5-导出至clickhouse数据库",link:"#问题5-导出至clickhouse数据库",children:[]}],path:"/notebook/oceanus.html",pathLocale:"/",extraFields:[]},{title:"teg争霸赛",headers:[{level:3,title:"第一关 刷到10000",slug:"第一关-刷到10000",link:"#第一关-刷到10000",children:[]},{level:3,title:"第二关",slug:"第二关",link:"#第二关",children:[]},{level:3,title:"第三关 20201021",slug:"第三关-20201021",link:"#第三关-20201021",children:[]},{level:3,title:"第四关 20201022",slug:"第四关-20201022",link:"#第四关-20201022",children:[]},{level:3,title:"第五关 20201023",slug:"第五关-20201023",link:"#第五关-20201023",children:[]}],path:"/notebook/teg%E4%BA%89%E9%9C%B8%E8%B5%9B.html",pathLocale:"/",extraFields:[]},{title:"url",headers:[],path:"/notebook/url%E9%87%8D%E5%AE%9A%E5%90%91.html",pathLocale:"/",extraFields:[]},{title:"vscode替代codeblocks",headers:[{level:2,title:"准备工作",slug:"准备工作",link:"#准备工作",children:[{level:3,title:"测试编译器是否可用",slug:"测试编译器是否可用",link:"#测试编译器是否可用",children:[]}]},{level:2,title:"vscode配置",slug:"vscode配置",link:"#vscode配置",children:[{level:3,title:"插件安装",slug:"插件安装",link:"#插件安装",children:[]},{level:3,title:"vscode 初体验",slug:"vscode-初体验",link:"#vscode-初体验",children:[]},{level:3,title:"解决输出区域无法输入的问题",slug:"解决输出区域无法输入的问题",link:"#解决输出区域无法输入的问题",children:[]},{level:3,title:"生成文件放在固定目录,减少硬盘占用",slug:"生成文件放在固定目录-减少硬盘占用",link:"#生成文件放在固定目录-减少硬盘占用",children:[]}]}],path:"/notebook/vscode%E6%9B%BF%E4%BB%A3codeblock.html",pathLocale:"/",extraFields:[]},{title:"vue修改数组内的对象",headers:[],path:"/notebook/vue%E4%BF%AE%E6%94%B9%E6%95%B0%E7%BB%84%E5%86%85%E7%9A%84%E5%AF%B9%E8%B1%A1.html",pathLocale:"/",extraFields:[]},{title:"webpack-source_map",headers:[],path:"/notebook/webpack-source_map.html",pathLocale:"/",extraFields:[]},{title:"使用onedrive在win10和linux之间同步",headers:[{level:2,title:"上手:",slug:"上手",link:"#上手",children:[{level:3,title:"事前准备: Fedora/CentOS",slug:"事前准备-fedora-centos",link:"#事前准备-fedora-centos",children:[]},{level:3,title:"安装",slug:"安装",link:"#安装",children:[]},{level:3,title:"卸载",slug:"卸载",link:"#卸载",children:[]},{level:3,title:"进行配置",slug:"进行配置",link:"#进行配置",children:[]},{level:3,title:"选择性同步",slug:"选择性同步",link:"#选择性同步",children:[]}]},{level:2,title:"本人的使用方法",slug:"本人的使用方法",link:"#本人的使用方法",children:[]}],path:"/notebook/%E4%BD%BF%E7%94%A8onedrive%E5%9C%A8win10%E5%92%8Clinux%E4%B9%8B%E9%97%B4%E5%90%8C%E6%AD%A5.html",pathLocale:"/",extraFields:[]},{title:"使用罗技摄像头+斐讯n1盒子直播",headers:[],path:"/notebook/%E4%BD%BF%E7%94%A8%E7%BD%97%E6%8A%80%E6%91%84%E5%83%8F%E5%A4%B4_%E6%96%90%E8%AE%AFn1%E7%9B%92%E5%AD%90%E7%9B%B4%E6%92%AD.html",pathLocale:"/",extraFields:[]},{title:"分辨率",headers:[{level:2,title:"物理分辨率",slug:"物理分辨率",link:"#物理分辨率",children:[]},{level:2,title:"设置分辨率",slug:"设置分辨率",link:"#设置分辨率",children:[]},{level:2,title:"PPI",slug:"ppi",link:"#ppi",children:[]},{level:2,title:"ui分辨率",slug:"ui分辨率",link:"#ui分辨率",children:[]},{level:2,title:"游戏分辨率",slug:"游戏分辨率",link:"#游戏分辨率",children:[]},{level:2,title:"nvidia dsr",slug:"nvidia-dsr",link:"#nvidia-dsr",children:[]},{level:2,title:"推断",slug:"推断",link:"#推断",children:[]},{level:2,title:"4k显示器尺寸的选择",slug:"_4k显示器尺寸的选择",link:"#_4k显示器尺寸的选择",children:[]}],path:"/notebook/%E5%88%86%E8%BE%A8%E7%8E%87.html",pathLocale:"/",extraFields:[]},{title:"甲骨文服务器凉凉",headers:[{level:2,title:"20200911甲骨文复活辣",slug:"_20200911甲骨文复活辣",link:"#_20200911甲骨文复活辣",children:[]},{level:2,title:"2020/2/24",slug:"_2020-2-24",link:"#_2020-2-24",children:[]},{level:2,title:"20200215 甲骨文凉凉",slug:"_20200215-甲骨文凉凉",link:"#_20200215-甲骨文凉凉",children:[]},{level:2,title:"处理笔记的分类方式",slug:"处理笔记的分类方式",link:"#处理笔记的分类方式",children:[{level:3,title:"笔记的种类:",slug:"笔记的种类",link:"#笔记的种类",children:[]},{level:3,title:"可用的笔记,提醒,便签软件",slug:"可用的笔记-提醒-便签软件",link:"#可用的笔记-提醒-便签软件",children:[]},{level:3,title:"场景",slug:"场景",link:"#场景",children:[]}]},{level:2,title:"找到合适的写日记软件",slug:"找到合适的写日记软件",link:"#找到合适的写日记软件",children:[]}],path:"/notebook/%E5%8D%9A%E5%AE%A2%E6%90%AD%E5%BB%BA.html",pathLocale:"/",extraFields:[]},{title:"变量命名相关",headers:[],path:"/notebook/%E5%8F%98%E9%87%8F%E5%91%BD%E5%90%8D%E7%9B%B8%E5%85%B3.html",pathLocale:"/",extraFields:[]},{title:"图形抗锯齿",headers:[{level:2,title:"",slug:"",link:"#",children:[]}],path:"/notebook/%E5%9B%BE%E5%BD%A2%E6%8A%97%E9%94%AF%E9%BD%BF.html",pathLocale:"/",extraFields:[]},{title:"密码管理",headers:[],path:"/notebook/%E5%AF%86%E7%A0%81%E7%AE%A1%E7%90%86.html",pathLocale:"/",extraFields:[]},{title:"数据传输",headers:[{level:3,title:"mysql dump",slug:"mysql-dump",link:"#mysql-dump",children:[]}],path:"/notebook/%E6%95%B0%E6%8D%AE%E4%BC%A0%E8%BE%93.html",pathLocale:"/",extraFields:[]},{title:"数据整理",headers:[{level:2,title:"处理笔记的分类方式",slug:"处理笔记的分类方式",link:"#处理笔记的分类方式",children:[{level:3,title:"笔记的种类:",slug:"笔记的种类",link:"#笔记的种类",children:[]},{level:3,title:"可用的笔记,提醒,便签软件",slug:"可用的笔记-提醒-便签软件",link:"#可用的笔记-提醒-便签软件",children:[]},{level:3,title:"场景",slug:"场景",link:"#场景",children:[]},{level:3,title:"找到合适的写日记软件",slug:"找到合适的写日记软件",link:"#找到合适的写日记软件",children:[]}]},{level:2,title:"照片相片的备份, 归纳",slug:"照片相片的备份-归纳",link:"#照片相片的备份-归纳",children:[{level:3,title:"调研",slug:"调研",link:"#调研",children:[]},{level:3,title:"ondrive",slug:"ondrive",link:"#ondrive",children:[]},{level:3,title:"google photo",slug:"google-photo",link:"#google-photo",children:[]}]}],path:"/notebook/%E6%95%B0%E6%8D%AE%E6%95%B4%E7%90%86.html",pathLocale:"/",extraFields:[]},{title:"文件描述符与缓冲区",headers:[{level:3,title:"文件描述符",slug:"文件描述符",link:"#文件描述符",children:[]},{level:3,title:"java FileReader",slug:"java-filereader",link:"#java-filereader",children:[]},{level:3,title:"python demo",slug:"python-demo",link:"#python-demo",children:[]}],path:"/notebook/%E6%96%87%E4%BB%B6%E6%8F%8F%E8%BF%B0%E7%AC%A6%E4%B8%8E%E7%BC%93%E5%86%B2%E5%8C%BA.html",pathLocale:"/",extraFields:[]},{title:"显卡",headers:[{level:2,title:"game fps",slug:"game-fps",link:"#game-fps",children:[]}],path:"/notebook/%E6%98%BE%E5%8D%A1.html",pathLocale:"/",extraFields:[]},{title:"显卡需求分析",headers:[{level:2,title:"显卡fps表",slug:"显卡fps表",link:"#显卡fps表",children:[]},{level:2,title:"2k高刷&4k办公",slug:"_2k高刷-4k办公",link:"#_2k高刷-4k办公",children:[]}],path:"/notebook/%E6%98%BE%E5%8D%A1%E9%9C%80%E6%B1%82%E5%88%86%E6%9E%90.html",pathLocale:"/",extraFields:[]},{title:"电子产品购买记录",headers:[{level:2,title:"大物件",slug:"大物件",link:"#大物件",children:[]},{level:2,title:"手机",slug:"手机",link:"#手机",children:[]},{level:2,title:"小物件 price<200",slug:"小物件-price-200",link:"#小物件-price-200",children:[]},{level:2,title:"家里",slug:"家里",link:"#家里",children:[]},{level:2,title:"电脑装机 2022.11",slug:"电脑装机-2022-11",link:"#电脑装机-2022-11",children:[]},{level:2,title:"眼镜",slug:"眼镜",link:"#眼镜",children:[]},{level:2,title:"猫粮",slug:"猫粮",link:"#猫粮",children:[]}],path:"/notebook/%E8%B4%AD%E4%B9%B0%E8%AE%B0%E5%BD%95.html",pathLocale:"/",extraFields:[]},{title:"运动手表",headers:[],path:"/notebook/%E8%BF%90%E5%8A%A8%E6%89%8B%E8%A1%A8.html",pathLocale:"/",extraFields:[]},{title:"重置CMD设置",headers:[],path:"/notebook/%E9%87%8D%E7%BD%AECMD%E8%AE%BE%E7%BD%AE.html",pathLocale:"/",extraFields:[]},{title:"这里是python",headers:[],path:"/python/",pathLocale:"/",extraFields:[]},{title:"celery异步任务",headers:[{level:3,title:"异步任务prefork gevent的选择",slug:"异步任务prefork-gevent的选择",link:"#异步任务prefork-gevent的选择",children:[]}],path:"/python/celery%E5%BC%82%E6%AD%A5%E4%BB%BB%E5%8A%A1.html",pathLocale:"/",extraFields:[]},{title:"django",headers:[],path:"/python/django.html",pathLocale:"/",extraFields:[]},{title:"pydantic特殊验证",headers:[],path:"/python/pydantic%E7%89%B9%E6%AE%8A%E9%AA%8C%E8%AF%81.html",pathLocale:"/",extraFields:[]},{title:"pythongui-父子进程与孤儿进程",headers:[],path:"/python/pythongui-%E7%88%B6%E5%AD%90%E8%BF%9B%E7%A8%8B%E4%B8%8E%E5%AD%A4%E5%84%BF%E8%BF%9B%E7%A8%8B.html",pathLocale:"/",extraFields:[]},{title:"任务队列",headers:[{level:2,title:"最初版本",slug:"最初版本",link:"#最初版本",children:[]},{level:2,title:"aps版本",slug:"aps版本",link:"#aps版本",children:[{level:3,title:"四个进程",slug:"四个进程",link:"#四个进程",children:[]},{level:3,title:"两个队列",slug:"两个队列",link:"#两个队列",children:[]}]},{level:2,title:"redis 版本",slug:"redis-版本",link:"#redis-版本",children:[]},{level:2,title:"crontab 版本",slug:"crontab-版本",link:"#crontab-版本",children:[]}],path:"/python/python%E4%BB%BB%E5%8A%A1%E9%98%9F%E5%88%97.html",pathLocale:"/",extraFields:[]},{title:"python使用正则过滤表情符号",headers:[],path:"/python/python%E4%BD%BF%E7%94%A8%E6%AD%A3%E5%88%99%E8%BF%87%E6%BB%A4%E8%A1%A8%E6%83%85%E7%AC%A6%E5%8F%B7.html",pathLocale:"/",extraFields:[]},{title:"python对比两个时间字符串",headers:[],path:"/python/python%E5%AF%B9%E6%AF%94%E4%B8%A4%E4%B8%AA%E6%97%B6%E9%97%B4%E5%AD%97%E7%AC%A6%E4%B8%B2.html",pathLocale:"/",extraFields:[]},{title:"skill",headers:[{level:3,title:"python 打印行号",slug:"python-打印行号",link:"#python-打印行号",children:[]},{level:3,title:"python 获取当前脚本或其他模块的所有类",slug:"python-获取当前脚本或其他模块的所有类",link:"#python-获取当前脚本或其他模块的所有类",children:[]}],path:"/python/python%E6%89%93%E5%8D%B0%E8%A1%8C%E5%8F%B7.html",pathLocale:"/",extraFields:[]},{title:"以图搜图",headers:[{level:3,title:"部署",slug:"部署",link:"#部署",children:[]}],path:"/python/%E4%BB%A5%E5%9B%BE%E6%90%9C%E5%9B%BE.html",pathLocale:"/",extraFields:[]},{title:"nsfw",headers:[{level:2,title:"0. https://github.com/yahoo/open_nsfw",slug:"_0-https-github-com-yahoo-open-nsfw",link:"#_0-https-github-com-yahoo-open-nsfw",children:[]},{level:2,title:"1. https://github.com/devzwy/open_nsfw_android",slug:"_1-https-github-com-devzwy-open-nsfw-android",link:"#_1-https-github-com-devzwy-open-nsfw-android",children:[]},{level:2,title:"2. https://github.com/mdietrichstein/tensorflow-open_nsfw",slug:"_2-https-github-com-mdietrichstein-tensorflow-open-nsfw",link:"#_2-https-github-com-mdietrichstein-tensorflow-open-nsfw",children:[]},{level:2,title:"3. https://github.com/yangbisheng2009/nsfw-resnet",slug:"_3-https-github-com-yangbisheng2009-nsfw-resnet",link:"#_3-https-github-com-yangbisheng2009-nsfw-resnet",children:[]},{level:2,title:"4. https://github.com/EugenCepoi/nsfw_api",slug:"_4-https-github-com-eugencepoi-nsfw-api",link:"#_4-https-github-com-eugencepoi-nsfw-api",children:[]}],path:"/python/%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0-nsfw.html",pathLocale:"/",extraFields:[]},{title:"pdd调研",headers:[{level:2,title:"h5端",slug:"h5端",link:"#h5端",children:[{level:3,title:"渠道一:首页",slug:"渠道一-首页",link:"#渠道一-首页",children:[]},{level:3,title:"渠道二:分类",slug:"渠道二-分类",link:"#渠道二-分类",children:[]},{level:3,title:"渠道三: 搜索",slug:"渠道三-搜索",link:"#渠道三-搜索",children:[]}]}],path:"/python/%E7%88%AC%E8%99%AB-pdd%E8%B0%83%E7%A0%94.html",pathLocale:"/",extraFields:[]},{title:"使用接口过tx滑块验证",headers:[{level:3,title:"0x00 抓包分析",slug:"_0x00-抓包分析",link:"#_0x00-抓包分析",children:[]},{level:3,title:"0x01 获取ticket和randstr",slug:"_0x01-获取ticket和randstr",link:"#_0x01-获取ticket和randstr",children:[]}],path:"/python/%E7%88%AC%E8%99%AB-%E4%BD%BF%E7%94%A8%E6%8E%A5%E5%8F%A3%E8%BF%87tx%E6%BB%91%E5%9D%97%E9%AA%8C%E8%AF%81.html",pathLocale:"/",extraFields:[]},{title:"记一次过反爬虫的经历",headers:[],path:"/python/%E7%88%AC%E8%99%AB-%E8%AE%B0%E4%B8%80%E6%AC%A1%E8%BF%87%E5%8F%8D%E7%88%AC%E8%99%AB%E7%9A%84%E7%BB%8F%E5%8E%86.html",pathLocale:"/",extraFields:[]},{title:"过简单js加密",headers:[{level:2,title:"0x00 chrome debug",slug:"_0x00-chrome-debug",link:"#_0x00-chrome-debug",children:[]}],path:"/python/%E7%88%AC%E8%99%AB-%E8%BF%87%E7%AE%80%E5%8D%95js%E5%8A%A0%E5%AF%86.html",pathLocale:"/",extraFields:[]},{title:"进程管理",headers:[{level:3,title:"APScheduler",slug:"apscheduler",link:"#apscheduler",children:[]},{level:3,title:"20201026",slug:"_20201026",link:"#_20201026",children:[]}],path:"/python/%E8%BF%9B%E7%A8%8B%E7%AE%A1%E7%90%86.html",pathLocale:"/",extraFields:[]},{title:"面试",headers:[],path:"/python/%E9%9D%A2%E8%AF%95.html",pathLocale:"/",extraFields:[]},{title:"这里是ops",headers:[],path:"/ops/",pathLocale:"/",extraFields:[]},{title:"[mysql]主从复制",headers:[{level:2,title:"步骤",slug:"步骤",link:"#步骤",children:[{level:3,title:"1,主开启binlog",slug:"_1-主开启binlog",link:"#_1-主开启binlog",children:[]},{level:3,title:"2. 副修改server_id",slug:"_2-副修改server-id",link:"#_2-副修改server-id",children:[]},{level:3,title:"3.副开启主从",slug:"_3-副开启主从",link:"#_3-副开启主从",children:[]}]}],path:"/ops/mysql_%E4%B8%BB%E4%BB%8E%E5%A4%8D%E5%88%B6.html",pathLocale:"/",extraFields:[]},{title:"drone",headers:[{level:2,title:"docker缓存(优先使用)",slug:"docker缓存-优先使用",link:"#docker缓存-优先使用",children:[]},{level:2,title:"本地缓存",slug:"本地缓存",link:"#本地缓存",children:[{level:3,title:"npm cache",slug:"npm-cache",link:"#npm-cache",children:[]},{level:3,title:"yarn cache",slug:"yarn-cache",link:"#yarn-cache",children:[]}]}],path:"/ops/drone.html",pathLocale:"/",extraFields:[]},{title:"k8s",headers:[{level:2,title:"alias k8s",slug:"alias-k8s",link:"#alias-k8s",children:[{level:3,title:"问题定位",slug:"问题定位",link:"#问题定位",children:[]},{level:3,title:"解决方案1",slug:"解决方案1",link:"#解决方案1",children:[]},{level:3,title:"解决方案2",slug:"解决方案2",link:"#解决方案2",children:[]}]}],path:"/ops/k8s.html",pathLocale:"/",extraFields:[]},{title:"oj",headers:[{level:2,title:"php7.2",slug:"php7-2",link:"#php7-2",children:[{level:3,title:"代码路径信息",slug:"代码路径信息",link:"#代码路径信息",children:[]}]},{level:2,title:"代码结构",slug:"代码结构",link:"#代码结构",children:[]},{level:2,title:"nginx",slug:"nginx",link:"#nginx",children:[]}],path:"/ops/oj.html",pathLocale:"/",extraFields:[]},{title:"sudo",headers:[],path:"/ops/sudo.html",pathLocale:"/",extraFields:[]},{title:"ubuntu_x11",headers:[{level:2,title:"启动方式",slug:"启动方式",link:"#启动方式",children:[]},{level:2,title:"遇到的问题",slug:"遇到的问题",link:"#遇到的问题",children:[{level:3,title:"无法显示中文",slug:"无法显示中文",link:"#无法显示中文",children:[]},{level:3,title:"无法输入中文",slug:"无法输入中文",link:"#无法输入中文",children:[]}]}],path:"/ops/ubuntu_x11.html",pathLocale:"/",extraFields:[]},{title:"vmware虚拟机硬盘调整",headers:[],path:"/ops/vmware%E8%99%9A%E6%8B%9F%E6%9C%BA%E7%A1%AC%E7%9B%98%E8%B0%83%E6%95%B4.html",pathLocale:"/",extraFields:[]},{title:"【运维】expect",headers:[],path:"/ops/%E3%80%90%E8%BF%90%E7%BB%B4%E3%80%91expect.html",pathLocale:"/",extraFields:[]},{title:"代理使用",headers:[{level:2,title:"环境变量",slug:"环境变量",link:"#环境变量",children:[{level:3,title:"Linux",slug:"linux",link:"#linux",children:[]},{level:3,title:"Windows",slug:"windows",link:"#windows",children:[]}]},{level:2,title:"Ubuntu apt",slug:"ubuntu-apt",link:"#ubuntu-apt",children:[]},{level:2,title:"Git",slug:"git",link:"#git",children:[]},{level:2,title:"Docker",slug:"docker",link:"#docker",children:[]},{level:2,title:"Python代码",slug:"python代码",link:"#python代码",children:[]},{level:2,title:"浏览器插件",slug:"浏览器插件",link:"#浏览器插件",children:[]},{level:2,title:"其他",slug:"其他",link:"#其他",children:[]}],path:"/ops/%E4%BB%A3%E7%90%86%E4%BD%BF%E7%94%A8.html",pathLocale:"/",extraFields:[]},{title:"硬盘速度测试",headers:[{level:3,title:"linux 测试磁盘性能",slug:"linux-测试磁盘性能",link:"#linux-测试磁盘性能",children:[]},{level:3,title:"as ssd",slug:"as-ssd",link:"#as-ssd",children:[]}],path:"/ops/%E7%A1%AC%E7%9B%98%E9%80%9F%E5%BA%A6%E6%B5%8B%E8%AF%95.html",pathLocale:"/",extraFields:[]},{title:"网盘与同步",headers:[{level:2,title:"目前的选择:OneDrive",slug:"目前的选择-onedrive",link:"#目前的选择-onedrive",children:[]},{level:2,title:"他人智慧",slug:"他人智慧",link:"#他人智慧",children:[]},{level:2,title:"按照分类",slug:"按照分类",link:"#按照分类",children:[]},{level:2,title:"知乎",slug:"知乎",link:"#知乎",children:[]}],path:"/ops/%E7%BD%91%E7%9B%98%E4%B8%8E%E5%90%8C%E6%AD%A5.html",pathLocale:"/",extraFields:[]},{title:"购买参考",headers:[{level:3,title:"电池",slug:"电池",link:"#电池",children:[]}],path:"/ops/%E8%B4%AD%E4%B9%B0%E5%8F%82%E8%80%83.html",pathLocale:"/",extraFields:[]},{title:"这里是router",headers:[],path:"/router/",pathLocale:"/",extraFields:[]},{title:"zerotier",headers:[{level:2,title:"实战配置",slug:"实战配置",link:"#实战配置",children:[{level:3,title:"1 zerotier 配置",slug:"_1-zerotier-配置",link:"#_1-zerotier-配置",children:[]},{level:3,title:"1.2 设置这两个设备允许 Allow Ethernet Bridging",slug:"_1-2-设置这两个设备允许-allow-ethernet-bridging",link:"#_1-2-设置这两个设备允许-allow-ethernet-bridging",children:[]},{level:3,title:"2 客户端设置",slug:"_2-客户端设置",link:"#_2-客户端设置",children:[]}]}],path:"/router/zerotier.html",pathLocale:"/",extraFields:[]},{title:"zerotier、二级路由、DMZ",headers:[],path:"/router/zerotier%E3%80%81%E4%BA%8C%E7%BA%A7%E8%B7%AF%E7%94%B1%E3%80%81DMZ.html",pathLocale:"/",extraFields:[]},{title:"异地组网",headers:[{level:2,title:"设备:k2p",slug:"设备-k2p",link:"#设备-k2p",children:[]},{level:2,title:"斐讯n1盒子",slug:"斐讯n1盒子",link:"#斐讯n1盒子",children:[]},{level:2,title:"wr1200js",slug:"wr1200js",link:"#wr1200js",children:[]},{level:2,title:"cloud server hk",slug:"cloud-server-hk",link:"#cloud-server-hk",children:[]}],path:"/router/%E5%BC%82%E5%9C%B0%E7%BB%84%E7%BD%91.html",pathLocale:"/",extraFields:[]},{title:"监控某个服务正常运行",headers:[],path:"/router/%E7%9B%91%E6%8E%A7%E6%9F%90%E4%B8%AA%E6%9C%8D%E5%8A%A1%E6%AD%A3%E5%B8%B8%E8%BF%90%E8%A1%8C.html",pathLocale:"/",extraFields:[]},{title:"简易监控",headers:[{level:2,title:"23.9.20 开始写方案",slug:"_23-9-20-开始写方案",link:"#_23-9-20-开始写方案",children:[{level:3,title:"方案1:POE录像机",slug:"方案1-poe录像机",link:"#方案1-poe录像机",children:[]},{level:3,title:"方案2:单摄像头(纯娱乐)",slug:"方案2-单摄像头-纯娱乐",link:"#方案2-单摄像头-纯娱乐",children:[]}]},{level:2,title:"9.22记录",slug:"_9-22记录",link:"#_9-22记录",children:[{level:3,title:"最终方案",slug:"最终方案",link:"#最终方案",children:[]}]},{level:2,title:"9.25",slug:"_9-25",link:"#_9-25",children:[]},{level:2,title:"10.8",slug:"_10-8",link:"#_10-8",children:[]}],path:"/router/%E7%AE%80%E6%98%93%E7%9B%91%E6%8E%A7.html",pathLocale:"/",extraFields:[]},{title:"记一次破解天翼网关",headers:[],path:"/router/%E8%AE%B0%E4%B8%80%E6%AC%A1%E7%A0%B4%E8%A7%A3%E5%A4%A9%E7%BF%BC%E7%BD%91%E5%85%B3.html",pathLocale:"/",extraFields:[]},{title:"这里是video",headers:[],path:"/video/",pathLocale:"/",extraFields:[]},{title:"ffmpeg",headers:[{level:2,title:"第一个应用 制作延时摄像",slug:"第一个应用-制作延时摄像",link:"#第一个应用-制作延时摄像",children:[]}],path:"/video/ffmpeg.html",pathLocale:"/",extraFields:[]},{title:"shinobi-开源NVR",headers:[],path:"/video/shinobi-%E5%BC%80%E6%BA%90NVR.html",pathLocale:"/",extraFields:[]},{title:"23-5-22pg数据库的中文排序",headers:[{level:2,title:"背景",slug:"背景",link:"#背景",children:[]},{level:2,title:"方案1",slug:"方案1",link:"#方案1",children:[]},{level:2,title:"方案2",slug:"方案2",link:"#方案2",children:[]}],path:"/web/23-5-22pg%E6%95%B0%E6%8D%AE%E5%BA%93%E7%9A%84%E4%B8%AD%E6%96%87%E6%8E%92%E5%BA%8F.html",pathLocale:"/",extraFields:[]},{title:"这里是web",headers:[],path:"/web/",pathLocale:"/",extraFields:[]},{title:"[mysql]全表查询的优化",headers:[],path:"/web/mysql_%E5%85%A8%E8%A1%A8%E6%9F%A5%E8%AF%A2%E7%9A%84%E4%BC%98%E5%8C%96.html",pathLocale:"/",extraFields:[]},{title:"[project]项目配置文件",headers:[],path:"/web/project_%E9%A1%B9%E7%9B%AE%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6.html",pathLocale:"/",extraFields:[]},{title:"[python]以图搜图系统",headers:[],path:"/web/python_%E4%BB%A5%E5%9B%BE%E6%90%9C%E5%9B%BE%E7%B3%BB%E7%BB%9F.html",pathLocale:"/",extraFields:[]},{title:"[web]web模型",headers:[],path:"/web/web_web%E6%A8%A1%E5%9E%8B.html",pathLocale:"/",extraFields:[]},{title:"[web]服务端渲染与客户端渲染",headers:[],path:"/web/web_%E6%9C%8D%E5%8A%A1%E7%AB%AF%E6%B8%B2%E6%9F%93%E4%B8%8E%E5%AE%A2%E6%88%B7%E7%AB%AF%E6%B8%B2%E6%9F%93.html",pathLocale:"/",extraFields:[]},{title:"[web]装饰器模式在canvas里的应用",headers:[],path:"/web/web_%E8%A3%85%E9%A5%B0%E5%99%A8%E6%A8%A1%E5%BC%8F%E5%9C%A8canvas%E9%87%8C%E7%9A%84%E5%BA%94%E7%94%A8.html",pathLocale:"/",extraFields:[]},{title:"[异步任务与事务]",headers:[],path:"/web/%E5%BC%82%E6%AD%A5%E4%BB%BB%E5%8A%A1%E4%B8%8E%E4%BA%8B%E5%8A%A1_.html",pathLocale:"/",extraFields:[]},{title:"[计算机网络]iptables",headers:[],path:"/web/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C_iptables.html",pathLocale:"/",extraFields:[]},{title:"[计算机网络]ip协议",headers:[],path:"/web/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C_ip%E5%8D%8F%E8%AE%AE.html",pathLocale:"/",extraFields:[]},{title:"[计算机网络]路由器",headers:[],path:"/web/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C_%E8%B7%AF%E7%94%B1%E5%99%A8.html",pathLocale:"/",extraFields:[]},{title:"乐观锁、悲观锁、分布式锁",headers:[{level:3,title:"100并发",slug:"_100并发",link:"#_100并发",children:[]},{level:3,title:"并发100, 总共1000个",slug:"并发100-总共1000个",link:"#并发100-总共1000个",children:[]},{level:3,title:"并发200,总共1000",slug:"并发200-总共1000",link:"#并发200-总共1000",children:[]}],path:"/web/%E4%B9%90%E8%A7%82%E9%94%81%E3%80%81%E6%82%B2%E8%A7%82%E9%94%81%E3%80%81%E5%88%86%E5%B8%83%E5%BC%8F%E9%94%81.html",pathLocale:"/",extraFields:[]},{title:"基于ddd的架构",headers:[],path:"/web/%E5%9F%BA%E4%BA%8Eddd%E7%9A%84%E6%9E%B6%E6%9E%84.html",pathLocale:"/",extraFields:[]},{title:"运维相关",headers:[],path:"/web/%E8%BF%90%E7%BB%B4%E7%9B%B8%E5%85%B3.html",pathLocale:"/",extraFields:[]},{title:"这里是notebook/3D建模",headers:[],path:"/notebook/3D%E5%BB%BA%E6%A8%A1/",pathLocale:"/",extraFields:[]},{title:"webodm配置安装",headers:[{level:2,title:"moyechen 23.9.24",slug:"moyechen-23-9-24",link:"#moyechen-23-9-24",children:[{level:3,title:"步骤1 wsl2配置",slug:"步骤1-wsl2配置",link:"#步骤1-wsl2配置",children:[]},{level:3,title:"步骤1 安装docker desktop",slug:"步骤1-安装docker-desktop",link:"#步骤1-安装docker-desktop",children:[]},{level:3,title:"ubuntu nvidia驱动配置",slug:"ubuntu-nvidia驱动配置",link:"#ubuntu-nvidia驱动配置",children:[]},{level:3,title:"步骤3 拉取项目文件",slug:"步骤3-拉取项目文件",link:"#步骤3-拉取项目文件",children:[]},{level:3,title:"步骤4 启动",slug:"步骤4-启动",link:"#步骤4-启动",children:[]},{level:3,title:"mipc杂项",slug:"mipc杂项",link:"#mipc杂项",children:[]}]}],path:"/notebook/3D%E5%BB%BA%E6%A8%A1/webodm%E9%85%8D%E7%BD%AE%E5%AE%89%E8%A3%85.html",pathLocale:"/",extraFields:[]},{title:"这里是notebook/graphql",headers:[],path:"/notebook/graphql/",pathLocale:"/",extraFields:[]},{title:"ddd+graphql数据流",headers:[],path:"/notebook/graphql/ddd_graphql%E6%95%B0%E6%8D%AE%E6%B5%81.html",pathLocale:"/",extraFields:[]},{title:"graphql和python",headers:[],path:"/notebook/graphql/graphql%E5%92%8Cpython.html",pathLocale:"/",extraFields:[]},{title:"graphql遇到过的问题",headers:[{level:2,title:"1.schema编写问题",slug:"_1-schema编写问题",link:"#_1-schema编写问题",children:[]},{level:2,title:"2.dataload 问题",slug:"_2-dataload-问题",link:"#_2-dataload-问题",children:[]}],path:"/notebook/graphql/graphql%E9%81%87%E5%88%B0%E8%BF%87%E7%9A%84%E9%97%AE%E9%A2%98.html",pathLocale:"/",extraFields:[]},{title:"这里是python/cv",headers:[],path:"/python/cv/",pathLocale:"/",extraFields:[]},{title:"环境部署",headers:[{level:2,title:"cuda",slug:"cuda",link:"#cuda",children:[]},{level:2,title:"cudaa",slug:"cudaa",link:"#cudaa",children:[]},{level:2,title:"conda",slug:"conda",link:"#conda",children:[{level:3,title:"conda vs anconda",slug:"conda-vs-anconda",link:"#conda-vs-anconda",children:[]},{level:3,title:"安装",slug:"安装",link:"#安装",children:[]},{level:3,title:"使用",slug:"使用",link:"#使用",children:[]}]}],path:"/python/cv/conda.html",pathLocale:"/",extraFields:[]},{title:"cuda",headers:[],path:"/python/cv/cuda.html",pathLocale:"/",extraFields:[]},{title:"pytorch",headers:[],path:"/python/cv/pytorch.html",pathLocale:"/",extraFields:[]},{title:"基于yolov5的cf自瞄",headers:[{level:2,title:"环境配置",slug:"环境配置",link:"#环境配置",children:[]}],path:"/python/cv/%E5%9F%BA%E4%BA%8Eyolov5%E7%9A%84cf%E8%87%AA%E7%9E%84.html",pathLocale:"/",extraFields:[]},{title:"部署paddle框架之ocr",headers:[{level:2,title:"步骤",slug:"步骤",link:"#步骤",children:[]}],path:"/python/cv/%E9%83%A8%E7%BD%B2paddle%E6%A1%86%E6%9E%B6%E4%B9%8Bocr.html",pathLocale:"/",extraFields:[]},{title:"",headers:[],path:"/404.html",pathLocale:"/",extraFields:[]}],Yp=_e(Wp),Zp=()=>Yp,Gp=({searchIndex:e,routeLocale:t,query:n,maxSuggestions:o})=>{const l=j(()=>e.value.filter(r=>r.pathLocale===t.value));return j(()=>{const r=n.value.trim().toLowerCase();if(!r)return[];const i=[],a=(s,c)=>{ci(r,[c.title])&&i.push({link:`${s.path}#${c.slug}`,title:s.title,header:c.title});for(const u of c.children){if(i.length>=o.value)return;a(s,u)}};for(const s of l.value){if(i.length>=o.value)break;if(ci(r,[s.title,...s.extraFields])){i.push({link:s.path,title:s.title});continue}for(const c of s.headers){if(i.length>=o.value)break;a(s,c)}}return i})},Jp=e=>{const t=_e(0);return{focusIndex:t,focusNext:()=>{t.value{t.value>0?t.value-=1:t.value=e.value.length-1}}},Qp=de({name:"SearchBox",props:{locales:{type:Object,required:!1,default:()=>({})},hotKeys:{type:Array,required:!1,default:()=>[]},maxSuggestions:{type:Number,required:!1,default:5}},setup(e){const{locales:t,hotKeys:n,maxSuggestions:o}=Ro(e),l=Jt(),r=Zn(),i=Zp(),a=_e(null),s=_e(!1),c=_e(""),u=j(()=>t.value[r.value]??{}),d=Gp({searchIndex:i,routeLocale:r,query:c,maxSuggestions:o}),{focusIndex:f,focusNext:E,focusPrev:A}=Jp(d);Kp({input:a,hotKeys:n});const B=j(()=>s.value&&!!d.value.length),x=()=>{B.value&&A()},T=()=>{B.value&&E()},C=_=>{if(!B.value)return;const b=d.value[_];b&&l.push(b.link).then(()=>{c.value="",f.value=0})};return()=>ce("form",{class:"search-box",role:"search"},[ce("input",{ref:a,type:"search",placeholder:u.value.placeholder,autocomplete:"off",spellcheck:!1,value:c.value,onFocus:()=>s.value=!0,onBlur:()=>s.value=!1,onInput:_=>c.value=_.target.value,onKeydown:_=>{switch(_.key){case"ArrowUp":{x();break}case"ArrowDown":{T();break}case"Enter":{_.preventDefault(),C(f.value);break}}}}),B.value&&ce("ul",{class:"suggestions",onMouseleave:()=>f.value=-1},d.value.map(({link:_,title:b,header:H},Y)=>ce("li",{class:["suggestion",{focus:f.value===Y}],onMouseenter:()=>f.value=Y,onMousedown:()=>C(Y)},ce("a",{href:_,onClick:M=>M.preventDefault()},[ce("span",{class:"page-title"},b),H&&ce("span",{class:"page-header"},`> ${H}`)]))))])}});var Xp=["s","/"],em={};const tm=em,nm=Xp,om=5,lm=St({enhance({app:e}){e.component("SearchBox",t=>ce(Qp,{locales:tm,hotKeys:nm,maxSuggestions:om,...t}))}});/*! medium-zoom 1.1.0 | MIT License | https://github.com/francoischalifour/medium-zoom */var Nt=Object.assign||function(e){for(var t=1;t1&&arguments[1]!==void 0?arguments[1]:{},o=window.Promise||function(k){function V(){}k(V,V)},l=function(k){var V=k.target;if(V===I){A();return}_.indexOf(V)!==-1&&B({target:V})},r=function(){if(!(H||!g.original)){var k=window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0;Math.abs(Y-k)>M.scrollOffset&&setTimeout(A,150)}},i=function(k){var V=k.key||k.keyCode;(V==="Escape"||V==="Esc"||V===27)&&A()},a=function(){var k=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},V=k;if(k.background&&(I.style.background=k.background),k.container&&k.container instanceof Object&&(V.container=Nt({},M.container,k.container)),k.template){var oe=fo(k.template)?k.template:document.querySelector(k.template);V.template=oe}return M=Nt({},M,V),_.forEach(function(se){se.dispatchEvent(tn("medium-zoom:update",{detail:{zoom:P}}))}),P},s=function(){var k=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{};return e(Nt({},M,k))},c=function(){for(var k=arguments.length,V=Array(k),oe=0;oe0?V.reduce(function(F,J){return[].concat(F,di(J))},[]):_;return se.forEach(function(F){F.classList.remove("medium-zoom-image"),F.dispatchEvent(tn("medium-zoom:detach",{detail:{zoom:P}}))}),_=_.filter(function(F){return se.indexOf(F)===-1}),P},d=function(k,V){var oe=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{};return _.forEach(function(se){se.addEventListener("medium-zoom:"+k,V,oe)}),b.push({type:"medium-zoom:"+k,listener:V,options:oe}),P},f=function(k,V){var oe=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{};return _.forEach(function(se){se.removeEventListener("medium-zoom:"+k,V,oe)}),b=b.filter(function(se){return!(se.type==="medium-zoom:"+k&&se.listener.toString()===V.toString())}),P},E=function(){var k=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},V=k.target,oe=function(){var F={width:document.documentElement.clientWidth,height:document.documentElement.clientHeight,left:0,top:0,right:0,bottom:0},J=void 0,K=void 0;if(M.container)if(M.container instanceof Object)F=Nt({},F,M.container),J=F.width-F.left-F.right-M.margin*2,K=F.height-F.top-F.bottom-M.margin*2;else{var Oe=fo(M.container)?M.container:document.querySelector(M.container),Se=Oe.getBoundingClientRect(),ze=Se.width,$e=Se.height,At=Se.left,yt=Se.top;F=Nt({},F,{width:ze,height:$e,left:At,top:yt})}J=J||F.width-M.margin*2,K=K||F.height-M.margin*2;var it=g.zoomedHd||g.original,Fe=ui(it)?J:it.naturalWidth||J,w=ui(it)?K:it.naturalHeight||K,U=it.getBoundingClientRect(),$=U.top,G=U.left,ue=U.width,h=U.height,p=Math.min(Math.max(ue,Fe),J)/ue,v=Math.min(Math.max(h,w),K)/h,y=Math.min(p,v),L=(-G+(J-ue)/2+M.margin+F.left)/y,R=(-$+(K-h)/2+M.margin+F.top)/y,q="scale("+y+") translate3d("+L+"px, "+R+"px, 0)";g.zoomed.style.transform=q,g.zoomedHd&&(g.zoomedHd.style.transform=q)};return new o(function(se){if(V&&_.indexOf(V)===-1){se(P);return}var F=function ze(){H=!1,g.zoomed.removeEventListener("transitionend",ze),g.original.dispatchEvent(tn("medium-zoom:opened",{detail:{zoom:P}})),se(P)};if(g.zoomed){se(P);return}if(V)g.original=V;else if(_.length>0){var J=_;g.original=J[0]}else{se(P);return}if(g.original.dispatchEvent(tn("medium-zoom:open",{detail:{zoom:P}})),Y=window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0,H=!0,g.zoomed=sm(g.original),document.body.appendChild(I),M.template){var K=fo(M.template)?M.template:document.querySelector(M.template);g.template=document.createElement("div"),g.template.appendChild(K.content.cloneNode(!0)),document.body.appendChild(g.template)}if(g.original.parentElement&&g.original.parentElement.tagName==="PICTURE"&&g.original.currentSrc&&(g.zoomed.src=g.original.currentSrc),document.body.appendChild(g.zoomed),window.requestAnimationFrame(function(){document.body.classList.add("medium-zoom--opened")}),g.original.classList.add("medium-zoom-image--hidden"),g.zoomed.classList.add("medium-zoom-image--opened"),g.zoomed.addEventListener("click",A),g.zoomed.addEventListener("transitionend",F),g.original.getAttribute("data-zoom-src")){g.zoomedHd=g.zoomed.cloneNode(),g.zoomedHd.removeAttribute("srcset"),g.zoomedHd.removeAttribute("sizes"),g.zoomedHd.removeAttribute("loading"),g.zoomedHd.src=g.zoomed.getAttribute("data-zoom-src"),g.zoomedHd.onerror=function(){clearInterval(Oe),console.warn("Unable to reach the zoom image target "+g.zoomedHd.src),g.zoomedHd=null,oe()};var Oe=setInterval(function(){g.zoomedHd.complete&&(clearInterval(Oe),g.zoomedHd.classList.add("medium-zoom-image--opened"),g.zoomedHd.addEventListener("click",A),document.body.appendChild(g.zoomedHd),oe())},10)}else if(g.original.hasAttribute("srcset")){g.zoomedHd=g.zoomed.cloneNode(),g.zoomedHd.removeAttribute("sizes"),g.zoomedHd.removeAttribute("loading");var Se=g.zoomedHd.addEventListener("load",function(){g.zoomedHd.removeEventListener("load",Se),g.zoomedHd.classList.add("medium-zoom-image--opened"),g.zoomedHd.addEventListener("click",A),document.body.appendChild(g.zoomedHd),oe()})}else oe()})},A=function(){return new o(function(k){if(H||!g.original){k(P);return}var V=function oe(){g.original.classList.remove("medium-zoom-image--hidden"),document.body.removeChild(g.zoomed),g.zoomedHd&&document.body.removeChild(g.zoomedHd),document.body.removeChild(I),g.zoomed.classList.remove("medium-zoom-image--opened"),g.template&&document.body.removeChild(g.template),H=!1,g.zoomed.removeEventListener("transitionend",oe),g.original.dispatchEvent(tn("medium-zoom:closed",{detail:{zoom:P}})),g.original=null,g.zoomed=null,g.zoomedHd=null,g.template=null,k(P)};H=!0,document.body.classList.remove("medium-zoom--opened"),g.zoomed.style.transform="",g.zoomedHd&&(g.zoomedHd.style.transform=""),g.template&&(g.template.style.transition="opacity 150ms",g.template.style.opacity=0),g.original.dispatchEvent(tn("medium-zoom:close",{detail:{zoom:P}})),g.zoomed.addEventListener("transitionend",V)})},B=function(){var k=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},V=k.target;return g.original?A():E({target:V})},x=function(){return M},T=function(){return _},C=function(){return g.original},_=[],b=[],H=!1,Y=0,M=n,g={original:null,zoomed:null,zoomedHd:null,template:null};Object.prototype.toString.call(t)==="[object Object]"?M=t:(t||typeof t=="string")&&c(t),M=Nt({margin:0,background:"#fff",scrollOffset:40,container:null,template:null},M);var I=im(M.background);document.addEventListener("click",l),document.addEventListener("keyup",i),document.addEventListener("scroll",r),window.addEventListener("resize",A);var P={open:E,close:A,toggle:B,update:a,clone:s,attach:c,detach:u,on:d,off:f,getOptions:x,getImages:T,getZoomedImage:C};return P};function cm(e,t){t===void 0&&(t={});var n=t.insertAt;if(!(!e||typeof document>"u")){var o=document.head||document.getElementsByTagName("head")[0],l=document.createElement("style");l.type="text/css",n==="top"&&o.firstChild?o.insertBefore(l,o.firstChild):o.appendChild(l),l.styleSheet?l.styleSheet.cssText=e:l.appendChild(document.createTextNode(e))}}var um=".medium-zoom-overlay{position:fixed;top:0;right:0;bottom:0;left:0;opacity:0;transition:opacity .3s;will-change:opacity}.medium-zoom--opened .medium-zoom-overlay{cursor:pointer;cursor:zoom-out;opacity:1}.medium-zoom-image{cursor:pointer;cursor:zoom-in;transition:transform .3s cubic-bezier(.2,0,.2,1)!important}.medium-zoom-image--hidden{visibility:hidden}.medium-zoom-image--opened{position:relative;cursor:pointer;cursor:zoom-out;will-change:transform}";cm(um);const dm=am,fm=Symbol("mediumZoom");var hm={};const pm=":not(a) > img",mm=hm,Em=500,vm=St({enhance({app:e,router:t}){const n=dm(mm);n.refresh=(o=pm)=>{n.detach(),n.attach(o)},e.provide(fm,n),t.afterEach(()=>{setTimeout(()=>n.refresh(),Em)})}}),co=[Kd,Zd,ef,lf,uf,Hp,lm,vm],_m=[["v-070018d8","/notebook/2019%E5%B9%B4%E5%B9%B4%E5%BA%A6%E6%B1%87%E6%8A%A5.html",{title:""},["/notebook/2019年年度汇报.html","/notebook/2019年年度汇报.md",":md"]],["v-1d07bef0","/notebook/2022-8%E6%9C%BA%E6%A2%B0%E9%94%AE%E7%9B%98%E9%9C%80%E6%B1%82.html",{title:"2022-8机械键盘需求"},["/notebook/2022-8机械键盘需求.html","/notebook/2022-8机械键盘需求.md",":md"]],["v-47da6a9c","/notebook/Mysql.html",{title:"Mysql"},[":md"]],["v-68c3eedb","/notebook/",{title:"这里是notebook"},["/notebook/README.md"]],["v-50f44d9a","/notebook/k2p_%E6%9B%B4%E6%96%B0%E5%AE%98%E6%94%B9%E5%9B%BA%E4%BB%B6v1.9%E4%B8%AD%E7%9A%84ssr-server.html",{title:"[k2p]更新官改固件v1.9中的ssr-server"},["/notebook/k2p_更新官改固件v1.9中的ssr-server.html","/notebook/[k2p]更新官改固件v1.9中的ssr-server.html","/notebook/%5Bk2p%5D%E6%9B%B4%E6%96%B0%E5%AE%98%E6%94%B9%E5%9B%BA%E4%BB%B6v1.9%E4%B8%AD%E7%9A%84ssr-server.html","/notebook/[k2p]更新官改固件v1.9中的ssr-server.md","/notebook/%5Bk2p%5D%E6%9B%B4%E6%96%B0%E5%AE%98%E6%94%B9%E5%9B%BA%E4%BB%B6v1.9%E4%B8%AD%E7%9A%84ssr-server.md"]],["v-5107f338","/notebook/n1%E7%9B%92%E5%AD%90_%E4%BD%BF%E7%94%A8n1%E7%9B%92%E5%AD%90%E4%BB%A5%E5%8F%8A%E7%BD%97%E6%8A%80%E6%91%84%E5%83%8F%E5%A4%B4%E8%BF%9B%E8%A1%8C%E7%9B%B4%E6%92%AD.html",{title:"[n1盒子]使用n1盒子以及罗技摄像头进行直播"},["/notebook/n1盒子_使用n1盒子以及罗技摄像头进行直播.html","/notebook/[n1盒子]使用n1盒子以及罗技摄像头进行直播.html","/notebook/%5Bn1%E7%9B%92%E5%AD%90%5D%E4%BD%BF%E7%94%A8n1%E7%9B%92%E5%AD%90%E4%BB%A5%E5%8F%8A%E7%BD%97%E6%8A%80%E6%91%84%E5%83%8F%E5%A4%B4%E8%BF%9B%E8%A1%8C%E7%9B%B4%E6%92%AD.html","/notebook/[n1盒子]使用n1盒子以及罗技摄像头进行直播.md","/notebook/%5Bn1%E7%9B%92%E5%AD%90%5D%E4%BD%BF%E7%94%A8n1%E7%9B%92%E5%AD%90%E4%BB%A5%E5%8F%8A%E7%BD%97%E6%8A%80%E6%91%84%E5%83%8F%E5%A4%B4%E8%BF%9B%E8%A1%8C%E7%9B%B4%E6%92%AD.md"]],["v-1bb63775","/notebook/adb.html",{title:"adb"},[":md"]],["v-2d9e888d","/notebook/cf-tools.html",{title:"cf-tools"},[":md"]],["v-4ac7a662","/notebook/django%E7%BC%93%E5%AD%98.html",{title:"django缓存"},["/notebook/django缓存.html","/notebook/django缓存.md",":md"]],["v-72251e04","/notebook/docker.html",{title:"2020/5/9 docKer 时区设置"},[":md"]],["v-0e6ec2eb","/notebook/k2p-luci.html",{title:"k2p-luci"},[":md"]],["v-67adb115","/notebook/kodi.html",{title:"kodi"},[":md"]],["v-c65efaa2","/notebook/linux%E5%85%B3%E9%97%AD%E8%AE%BF%E9%97%AE%E6%97%A5%E5%BF%97%E5%8F%8Amysql.html",{title:"日志"},["/notebook/linux关闭访问日志及mysql.html","/notebook/linux关闭访问日志及mysql.md",":md"]],["v-9fbc4e4a","/notebook/linux%E5%AD%A6%E4%B9%A0.html",{title:"linux学习"},["/notebook/linux学习.html","/notebook/linux学习.md",":md"]],["v-5be7464d","/notebook/mac_win10%E5%8F%8C%E7%B3%BB%E7%BB%9F%E4%B8%8B%E7%9A%84%E6%97%B6%E9%97%B4%E9%97%AE%E9%A2%98.html",{title:"mac+win10双系统下的时间问题"},["/notebook/mac_win10双系统下的时间问题.html","/notebook/mac+win10双系统下的时间问题.html","/notebook/mac+win10%E5%8F%8C%E7%B3%BB%E7%BB%9F%E4%B8%8B%E7%9A%84%E6%97%B6%E9%97%B4%E9%97%AE%E9%A2%98.html","/notebook/mac+win10双系统下的时间问题.md","/notebook/mac+win10%E5%8F%8C%E7%B3%BB%E7%BB%9F%E4%B8%8B%E7%9A%84%E6%97%B6%E9%97%B4%E9%97%AE%E9%A2%98.md"]],["v-2f05202c","/notebook/markdown%E5%AD%A6%E4%B9%A0.html",{title:"markdown学习"},["/notebook/markdown学习.html","/notebook/markdown学习.md",":md"]],["v-53b6469a","/notebook/nginx.html",{title:"nginx简洁"},[":md"]],["v-46b5f098","/notebook/oceanus.html",{title:"oceanus"},[":md"]],["v-7d01c4b5","/notebook/teg%E4%BA%89%E9%9C%B8%E8%B5%9B.html",{title:"teg争霸赛"},["/notebook/teg争霸赛.html","/notebook/teg争霸赛.md",":md"]],["v-171fb32c","/notebook/url%E9%87%8D%E5%AE%9A%E5%90%91.html",{title:"url"},["/notebook/url重定向.html","/notebook/url重定向.md",":md"]],["v-688e63da","/notebook/vscode%E6%9B%BF%E4%BB%A3codeblock.html",{title:"vscode替代codeblocks"},["/notebook/vscode替代codeblock.html","/notebook/vscode替代codeblock.md",":md"]],["v-0ba06cdc","/notebook/vue%E4%BF%AE%E6%94%B9%E6%95%B0%E7%BB%84%E5%86%85%E7%9A%84%E5%AF%B9%E8%B1%A1.html",{title:"vue修改数组内的对象"},["/notebook/vue修改数组内的对象.html","/notebook/vue修改数组内的对象.md",":md"]],["v-3b4cc106","/notebook/webpack-source_map.html",{title:"webpack-source_map"},[":md"]],["v-43c0d09a","/notebook/%E4%BD%BF%E7%94%A8onedrive%E5%9C%A8win10%E5%92%8Clinux%E4%B9%8B%E9%97%B4%E5%90%8C%E6%AD%A5.html",{title:"使用onedrive在win10和linux之间同步"},["/notebook/使用onedrive在win10和linux之间同步.html","/notebook/使用onedrive在win10和linux之间同步.md",":md"]],["v-94b8d7f0","/notebook/%E4%BD%BF%E7%94%A8%E7%BD%97%E6%8A%80%E6%91%84%E5%83%8F%E5%A4%B4_%E6%96%90%E8%AE%AFn1%E7%9B%92%E5%AD%90%E7%9B%B4%E6%92%AD.html",{title:"使用罗技摄像头+斐讯n1盒子直播"},["/notebook/使用罗技摄像头_斐讯n1盒子直播.html","/notebook/使用罗技摄像头+斐讯n1盒子直播.html","/notebook/%E4%BD%BF%E7%94%A8%E7%BD%97%E6%8A%80%E6%91%84%E5%83%8F%E5%A4%B4+%E6%96%90%E8%AE%AFn1%E7%9B%92%E5%AD%90%E7%9B%B4%E6%92%AD.html","/notebook/使用罗技摄像头+斐讯n1盒子直播.md","/notebook/%E4%BD%BF%E7%94%A8%E7%BD%97%E6%8A%80%E6%91%84%E5%83%8F%E5%A4%B4+%E6%96%90%E8%AE%AFn1%E7%9B%92%E5%AD%90%E7%9B%B4%E6%92%AD.md"]],["v-185ae8c4","/notebook/%E5%88%86%E8%BE%A8%E7%8E%87.html",{title:"分辨率"},["/notebook/分辨率.html","/notebook/分辨率.md",":md"]],["v-e63c018a","/notebook/%E5%8D%9A%E5%AE%A2%E6%90%AD%E5%BB%BA.html",{title:"甲骨文服务器凉凉"},["/notebook/博客搭建.html","/notebook/博客搭建.md",":md"]],["v-42bda90c","/notebook/%E5%8F%98%E9%87%8F%E5%91%BD%E5%90%8D%E7%9B%B8%E5%85%B3.html",{title:"变量命名相关"},["/notebook/变量命名相关.html","/notebook/变量命名相关.md",":md"]],["v-68b2c946","/notebook/%E5%9B%BE%E5%BD%A2%E6%8A%97%E9%94%AF%E9%BD%BF.html",{title:"图形抗锯齿"},["/notebook/图形抗锯齿.html","/notebook/图形抗锯齿.md",":md"]],["v-03b64b50","/notebook/%E5%AF%86%E7%A0%81%E7%AE%A1%E7%90%86.html",{title:"密码管理"},["/notebook/密码管理.html","/notebook/密码管理.md",":md"]],["v-07bbb0aa","/notebook/%E6%95%B0%E6%8D%AE%E4%BC%A0%E8%BE%93.html",{title:"数据传输"},["/notebook/数据传输.html","/notebook/数据传输.md",":md"]],["v-6bb06026","/notebook/%E6%95%B0%E6%8D%AE%E6%95%B4%E7%90%86.html",{title:"数据整理"},["/notebook/数据整理.html","/notebook/数据整理.md",":md"]],["v-579922c2","/notebook/%E6%96%87%E4%BB%B6%E6%8F%8F%E8%BF%B0%E7%AC%A6%E4%B8%8E%E7%BC%93%E5%86%B2%E5%8C%BA.html",{title:"文件描述符与缓冲区"},["/notebook/文件描述符与缓冲区.html","/notebook/文件描述符与缓冲区.md",":md"]],["v-0ad25c3f","/notebook/%E6%98%BE%E5%8D%A1.html",{title:"显卡"},["/notebook/显卡.html","/notebook/显卡.md",":md"]],["v-2305be92","/notebook/%E6%98%BE%E5%8D%A1%E9%9C%80%E6%B1%82%E5%88%86%E6%9E%90.html",{title:"显卡需求分析"},["/notebook/显卡需求分析.html","/notebook/显卡需求分析.md",":md"]],["v-526a70af","/notebook/%E8%B4%AD%E4%B9%B0%E8%AE%B0%E5%BD%95.html",{title:"电子产品购买记录"},["/notebook/购买记录.html","/notebook/购买记录.md",":md"]],["v-44a727a6","/notebook/%E8%BF%90%E5%8A%A8%E6%89%8B%E8%A1%A8.html",{title:"运动手表"},["/notebook/运动手表.html","/notebook/运动手表.md",":md"]],["v-2466882a","/notebook/%E9%87%8D%E7%BD%AECMD%E8%AE%BE%E7%BD%AE.html",{title:"重置CMD设置"},["/notebook/重置CMD设置.html","/notebook/重置CMD设置.md",":md"]],["v-63cd5dba","/python/",{title:"这里是python"},["/python/README.md"]],["v-02431a08","/python/celery%E5%BC%82%E6%AD%A5%E4%BB%BB%E5%8A%A1.html",{title:"celery异步任务"},["/python/celery异步任务.html","/python/celery异步任务.md",":md"]],["v-736bb064","/python/django.html",{title:"django"},[":md"]],["v-71f31afa","/python/pydantic%E7%89%B9%E6%AE%8A%E9%AA%8C%E8%AF%81.html",{title:"pydantic特殊验证"},["/python/pydantic特殊验证.html","/python/pydantic特殊验证.md",":md"]],["v-6b835d08","/python/pythongui-%E7%88%B6%E5%AD%90%E8%BF%9B%E7%A8%8B%E4%B8%8E%E5%AD%A4%E5%84%BF%E8%BF%9B%E7%A8%8B.html",{title:"pythongui-父子进程与孤儿进程"},["/python/pythongui-父子进程与孤儿进程.html","/python/pythongui-父子进程与孤儿进程.md",":md"]],["v-7bcdc38f","/python/python%E4%BB%BB%E5%8A%A1%E9%98%9F%E5%88%97.html",{title:"任务队列"},["/python/python任务队列.html","/python/python任务队列.md",":md"]],["v-26816455","/python/python%E4%BD%BF%E7%94%A8%E6%AD%A3%E5%88%99%E8%BF%87%E6%BB%A4%E8%A1%A8%E6%83%85%E7%AC%A6%E5%8F%B7.html",{title:"python使用正则过滤表情符号"},["/python/python使用正则过滤表情符号.html","/python/python使用正则过滤表情符号.md",":md"]],["v-39784c24","/python/python%E5%AF%B9%E6%AF%94%E4%B8%A4%E4%B8%AA%E6%97%B6%E9%97%B4%E5%AD%97%E7%AC%A6%E4%B8%B2.html",{title:"python对比两个时间字符串"},["/python/python对比两个时间字符串.html","/python/python对比两个时间字符串.md",":md"]],["v-2a51215c","/python/python%E6%89%93%E5%8D%B0%E8%A1%8C%E5%8F%B7.html",{title:"skill"},["/python/python打印行号.html","/python/python打印行号.md",":md"]],["v-38e7669c","/python/%E4%BB%A5%E5%9B%BE%E6%90%9C%E5%9B%BE.html",{title:"以图搜图"},["/python/以图搜图.html","/python/以图搜图.md",":md"]],["v-4e710776","/python/%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0-nsfw.html",{title:"nsfw"},["/python/机器学习-nsfw.html","/python/机器学习-nsfw.md",":md"]],["v-6e1b0644","/python/%E7%88%AC%E8%99%AB-pdd%E8%B0%83%E7%A0%94.html",{title:"pdd调研"},["/python/爬虫-pdd调研.html","/python/爬虫-pdd调研.md",":md"]],["v-d4a5a1a8","/python/%E7%88%AC%E8%99%AB-%E4%BD%BF%E7%94%A8%E6%8E%A5%E5%8F%A3%E8%BF%87tx%E6%BB%91%E5%9D%97%E9%AA%8C%E8%AF%81.html",{title:"使用接口过tx滑块验证"},["/python/爬虫-使用接口过tx滑块验证.html","/python/爬虫-使用接口过tx滑块验证.md",":md"]],["v-323d42ea","/python/%E7%88%AC%E8%99%AB-%E8%AE%B0%E4%B8%80%E6%AC%A1%E8%BF%87%E5%8F%8D%E7%88%AC%E8%99%AB%E7%9A%84%E7%BB%8F%E5%8E%86.html",{title:"记一次过反爬虫的经历"},["/python/爬虫-记一次过反爬虫的经历.html","/python/爬虫-记一次过反爬虫的经历.md",":md"]],["v-75f9e5c3","/python/%E7%88%AC%E8%99%AB-%E8%BF%87%E7%AE%80%E5%8D%95js%E5%8A%A0%E5%AF%86.html",{title:"过简单js加密"},["/python/爬虫-过简单js加密.html","/python/爬虫-过简单js加密.md",":md"]],["v-4d543397","/python/%E8%BF%9B%E7%A8%8B%E7%AE%A1%E7%90%86.html",{title:"进程管理"},["/python/进程管理.html","/python/进程管理.md",":md"]],["v-27f8a722","/python/%E9%9D%A2%E8%AF%95.html",{title:"面试"},["/python/面试.html","/python/面试.md",":md"]],["v-744af636","/ops/",{title:"这里是ops"},["/ops/README.md"]],["v-1306d2e8","/ops/mysql_%E4%B8%BB%E4%BB%8E%E5%A4%8D%E5%88%B6.html",{title:"[mysql]主从复制"},["/ops/mysql_主从复制.html","/ops/[mysql]主从复制.html","/ops/%5Bmysql%5D%E4%B8%BB%E4%BB%8E%E5%A4%8D%E5%88%B6.html","/ops/[mysql]主从复制.md","/ops/%5Bmysql%5D%E4%B8%BB%E4%BB%8E%E5%A4%8D%E5%88%B6.md"]],["v-33996b77","/ops/drone.html",{title:"drone"},[":md"]],["v-57d5a7e9","/ops/k8s.html",{title:"k8s"},[":md"]],["v-12fb3630","/ops/oj.html",{title:"oj"},[":md"]],["v-57e15916","/ops/sudo.html",{title:"sudo"},[":md"]],["v-1160d8a3","/ops/ubuntu_x11.html",{title:"ubuntu_x11"},[":md"]],["v-087e08e6","/ops/vmware%E8%99%9A%E6%8B%9F%E6%9C%BA%E7%A1%AC%E7%9B%98%E8%B0%83%E6%95%B4.html",{title:"vmware虚拟机硬盘调整"},["/ops/vmware虚拟机硬盘调整.html","/ops/vmware虚拟机硬盘调整.md",":md"]],["v-37242cf2","/ops/%E3%80%90%E8%BF%90%E7%BB%B4%E3%80%91expect.html",{title:"【运维】expect"},["/ops/【运维】expect.html","/ops/【运维】expect.md",":md"]],["v-bca00f24","/ops/%E4%BB%A3%E7%90%86%E4%BD%BF%E7%94%A8.html",{title:"代理使用"},["/ops/代理使用.html","/ops/代理使用.md",":md"]],["v-564889a0","/ops/%E7%A1%AC%E7%9B%98%E9%80%9F%E5%BA%A6%E6%B5%8B%E8%AF%95.html",{title:"硬盘速度测试"},["/ops/硬盘速度测试.html","/ops/硬盘速度测试.md",":md"]],["v-690fb1f4","/ops/%E7%BD%91%E7%9B%98%E4%B8%8E%E5%90%8C%E6%AD%A5.html",{title:"网盘与同步"},["/ops/网盘与同步.html","/ops/网盘与同步.md",":md"]],["v-168cd3a7","/ops/%E8%B4%AD%E4%B9%B0%E5%8F%82%E8%80%83.html",{title:"购买参考"},["/ops/购买参考.html","/ops/购买参考.md",":md"]],["v-86c67626","/router/",{title:"这里是router"},["/router/README.md"]],["v-357da27c","/router/zerotier.html",{title:"zerotier"},[":md"]],["v-70e270ee","/router/zerotier%E3%80%81%E4%BA%8C%E7%BA%A7%E8%B7%AF%E7%94%B1%E3%80%81DMZ.html",{title:"zerotier、二级路由、DMZ"},["/router/zerotier、二级路由、DMZ.html","/router/zerotier、二级路由、DMZ.md",":md"]],["v-beb5c272","/router/%E5%BC%82%E5%9C%B0%E7%BB%84%E7%BD%91.html",{title:"异地组网"},["/router/异地组网.html","/router/异地组网.md",":md"]],["v-118904ce","/router/%E7%9B%91%E6%8E%A7%E6%9F%90%E4%B8%AA%E6%9C%8D%E5%8A%A1%E6%AD%A3%E5%B8%B8%E8%BF%90%E8%A1%8C.html",{title:"监控某个服务正常运行"},["/router/监控某个服务正常运行.html","/router/监控某个服务正常运行.md",":md"]],["v-307698ed","/router/%E7%AE%80%E6%98%93%E7%9B%91%E6%8E%A7.html",{title:"简易监控"},["/router/简易监控.html","/router/简易监控.md",":md"]],["v-cd2572f4","/router/%E8%AE%B0%E4%B8%80%E6%AC%A1%E7%A0%B4%E8%A7%A3%E5%A4%A9%E7%BF%BC%E7%BD%91%E5%85%B3.html",{title:"记一次破解天翼网关"},["/router/记一次破解天翼网关.html","/router/记一次破解天翼网关.md",":md"]],["v-ce20e166","/video/",{title:"这里是video"},["/video/README.md"]],["v-24dac847","/video/ffmpeg.html",{title:"ffmpeg"},[":md"]],["v-4a06d9af","/video/shinobi-%E5%BC%80%E6%BA%90NVR.html",{title:"shinobi-开源NVR"},["/video/shinobi-开源NVR.html","/video/shinobi-开源NVR.md",":md"]],["v-54f0d1d0","/web/23-5-22pg%E6%95%B0%E6%8D%AE%E5%BA%93%E7%9A%84%E4%B8%AD%E6%96%87%E6%8E%92%E5%BA%8F.html",{title:"23-5-22pg数据库的中文排序"},["/web/23-5-22pg数据库的中文排序.html","/web/23-5-22pg数据库的中文排序.md",":md"]],["v-744e6dd4","/web/",{title:"这里是web"},["/web/README.md"]],["v-18f94f3e","/web/mysql_%E5%85%A8%E8%A1%A8%E6%9F%A5%E8%AF%A2%E7%9A%84%E4%BC%98%E5%8C%96.html",{title:"[mysql]全表查询的优化"},["/web/mysql_全表查询的优化.html","/web/[mysql]全表查询的优化.html","/web/%5Bmysql%5D%E5%85%A8%E8%A1%A8%E6%9F%A5%E8%AF%A2%E7%9A%84%E4%BC%98%E5%8C%96.html","/web/[mysql]全表查询的优化.md","/web/%5Bmysql%5D%E5%85%A8%E8%A1%A8%E6%9F%A5%E8%AF%A2%E7%9A%84%E4%BC%98%E5%8C%96.md"]],["v-70851bec","/web/project_%E9%A1%B9%E7%9B%AE%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6.html",{title:"[project]项目配置文件"},["/web/project_项目配置文件.html","/web/[project]项目配置文件.html","/web/%5Bproject%5D%E9%A1%B9%E7%9B%AE%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6.html","/web/[project]项目配置文件.md","/web/%5Bproject%5D%E9%A1%B9%E7%9B%AE%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6.md"]],["v-3c9f71df","/web/python_%E4%BB%A5%E5%9B%BE%E6%90%9C%E5%9B%BE%E7%B3%BB%E7%BB%9F.html",{title:"[python]以图搜图系统"},["/web/python_以图搜图系统.html","/web/[python]以图搜图系统.html","/web/%5Bpython%5D%E4%BB%A5%E5%9B%BE%E6%90%9C%E5%9B%BE%E7%B3%BB%E7%BB%9F.html","/web/[python]以图搜图系统.md","/web/%5Bpython%5D%E4%BB%A5%E5%9B%BE%E6%90%9C%E5%9B%BE%E7%B3%BB%E7%BB%9F.md"]],["v-5a4912c0","/web/web_web%E6%A8%A1%E5%9E%8B.html",{title:"[web]web模型"},["/web/web_web模型.html","/web/[web]web模型.html","/web/%5Bweb%5Dweb%E6%A8%A1%E5%9E%8B.html","/web/[web]web模型.md","/web/%5Bweb%5Dweb%E6%A8%A1%E5%9E%8B.md"]],["v-1ce7b414","/web/web_%E6%9C%8D%E5%8A%A1%E7%AB%AF%E6%B8%B2%E6%9F%93%E4%B8%8E%E5%AE%A2%E6%88%B7%E7%AB%AF%E6%B8%B2%E6%9F%93.html",{title:"[web]服务端渲染与客户端渲染"},["/web/web_服务端渲染与客户端渲染.html","/web/[web]服务端渲染与客户端渲染.html","/web/%5Bweb%5D%E6%9C%8D%E5%8A%A1%E7%AB%AF%E6%B8%B2%E6%9F%93%E4%B8%8E%E5%AE%A2%E6%88%B7%E7%AB%AF%E6%B8%B2%E6%9F%93.html","/web/[web]服务端渲染与客户端渲染.md","/web/%5Bweb%5D%E6%9C%8D%E5%8A%A1%E7%AB%AF%E6%B8%B2%E6%9F%93%E4%B8%8E%E5%AE%A2%E6%88%B7%E7%AB%AF%E6%B8%B2%E6%9F%93.md"]],["v-6099f3b2","/web/web_%E8%A3%85%E9%A5%B0%E5%99%A8%E6%A8%A1%E5%BC%8F%E5%9C%A8canvas%E9%87%8C%E7%9A%84%E5%BA%94%E7%94%A8.html",{title:"[web]装饰器模式在canvas里的应用"},["/web/web_装饰器模式在canvas里的应用.html","/web/[web]装饰器模式在canvas里的应用.html","/web/%5Bweb%5D%E8%A3%85%E9%A5%B0%E5%99%A8%E6%A8%A1%E5%BC%8F%E5%9C%A8canvas%E9%87%8C%E7%9A%84%E5%BA%94%E7%94%A8.html","/web/[web]装饰器模式在canvas里的应用.md","/web/%5Bweb%5D%E8%A3%85%E9%A5%B0%E5%99%A8%E6%A8%A1%E5%BC%8F%E5%9C%A8canvas%E9%87%8C%E7%9A%84%E5%BA%94%E7%94%A8.md"]],["v-29eb5e8d","/web/%E5%BC%82%E6%AD%A5%E4%BB%BB%E5%8A%A1%E4%B8%8E%E4%BA%8B%E5%8A%A1_.html",{title:"[异步任务与事务]"},["/web/异步任务与事务_.html","/web/[异步任务与事务].html","/web/%5B%E5%BC%82%E6%AD%A5%E4%BB%BB%E5%8A%A1%E4%B8%8E%E4%BA%8B%E5%8A%A1%5D.html","/web/[异步任务与事务].md","/web/%5B%E5%BC%82%E6%AD%A5%E4%BB%BB%E5%8A%A1%E4%B8%8E%E4%BA%8B%E5%8A%A1%5D.md"]],["v-e50f7ea8","/web/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C_iptables.html",{title:"[计算机网络]iptables"},["/web/计算机网络_iptables.html","/web/[计算机网络]iptables.html","/web/%5B%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C%5Diptables.html","/web/[计算机网络]iptables.md","/web/%5B%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C%5Diptables.md"]],["v-75d78820","/web/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C_ip%E5%8D%8F%E8%AE%AE.html",{title:"[计算机网络]ip协议"},["/web/计算机网络_ip协议.html","/web/[计算机网络]ip协议.html","/web/%5B%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C%5Dip%E5%8D%8F%E8%AE%AE.html","/web/[计算机网络]ip协议.md","/web/%5B%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C%5Dip%E5%8D%8F%E8%AE%AE.md"]],["v-8353569e","/web/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C_%E8%B7%AF%E7%94%B1%E5%99%A8.html",{title:"[计算机网络]路由器"},["/web/计算机网络_路由器.html","/web/[计算机网络]路由器.html","/web/%5B%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C%5D%E8%B7%AF%E7%94%B1%E5%99%A8.html","/web/[计算机网络]路由器.md","/web/%5B%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C%5D%E8%B7%AF%E7%94%B1%E5%99%A8.md"]],["v-8100aa12","/web/%E4%B9%90%E8%A7%82%E9%94%81%E3%80%81%E6%82%B2%E8%A7%82%E9%94%81%E3%80%81%E5%88%86%E5%B8%83%E5%BC%8F%E9%94%81.html",{title:"乐观锁、悲观锁、分布式锁"},["/web/乐观锁、悲观锁、分布式锁.html","/web/乐观锁、悲观锁、分布式锁.md",":md"]],["v-d0dc2cca","/web/%E5%9F%BA%E4%BA%8Eddd%E7%9A%84%E6%9E%B6%E6%9E%84.html",{title:"基于ddd的架构"},["/web/基于ddd的架构.html","/web/基于ddd的架构.md",":md"]],["v-553c7882","/web/%E8%BF%90%E7%BB%B4%E7%9B%B8%E5%85%B3.html",{title:"运维相关"},["/web/运维相关.html","/web/运维相关.md",":md"]],["v-211fff28","/notebook/3D%E5%BB%BA%E6%A8%A1/",{title:"这里是notebook/3D建模"},["/notebook/3D建模/","/notebook/3D建模/README.md","/notebook/3D%E5%BB%BA%E6%A8%A1/README.md"]],["v-7dfc8bcb","/notebook/3D%E5%BB%BA%E6%A8%A1/webodm%E9%85%8D%E7%BD%AE%E5%AE%89%E8%A3%85.html",{title:"webodm配置安装"},["/notebook/3D建模/webodm配置安装.html","/notebook/3D建模/webodm配置安装.md",":md"]],["v-7181ad41","/notebook/graphql/",{title:"这里是notebook/graphql"},["/notebook/graphql/README.md"]],["v-046aced0","/notebook/graphql/ddd_graphql%E6%95%B0%E6%8D%AE%E6%B5%81.html",{title:"ddd+graphql数据流"},["/notebook/graphql/ddd_graphql数据流.html","/notebook/graphql/ddd+graphql数据流.html","/notebook/graphql/ddd+graphql%E6%95%B0%E6%8D%AE%E6%B5%81.html","/notebook/graphql/ddd+graphql数据流.md","/notebook/graphql/ddd+graphql%E6%95%B0%E6%8D%AE%E6%B5%81.md"]],["v-b1bba884","/notebook/graphql/graphql%E5%92%8Cpython.html",{title:"graphql和python"},["/notebook/graphql/graphql和python.html","/notebook/graphql/graphql和python.md",":md"]],["v-67e92c6d","/notebook/graphql/graphql%E9%81%87%E5%88%B0%E8%BF%87%E7%9A%84%E9%97%AE%E9%A2%98.html",{title:"graphql遇到过的问题"},["/notebook/graphql/graphql遇到过的问题.html","/notebook/graphql/graphql遇到过的问题.md",":md"]],["v-17af9222","/python/cv/",{title:"这里是python/cv"},["/python/cv/README.md"]],["v-7443725c","/python/cv/conda.html",{title:"环境部署"},[":md"]],["v-d7f6c430","/python/cv/cuda.html",{title:"cuda"},[":md"]],["v-d6e05f70","/python/cv/pytorch.html",{title:"pytorch"},[":md"]],["v-3e81f7f2","/python/cv/%E5%9F%BA%E4%BA%8Eyolov5%E7%9A%84cf%E8%87%AA%E7%9E%84.html",{title:"基于yolov5的cf自瞄"},["/python/cv/基于yolov5的cf自瞄.html","/python/cv/基于yolov5的cf自瞄.md",":md"]],["v-689f17cc","/python/cv/%E9%83%A8%E7%BD%B2paddle%E6%A1%86%E6%9E%B6%E4%B9%8Bocr.html",{title:"部署paddle框架之ocr"},["/python/cv/部署paddle框架之ocr.html","/python/cv/部署paddle框架之ocr.md",":md"]],["v-3706649a","/404.html",{title:""},[]]];var fi=de({name:"Vuepress",setup(){const e=Ou();return()=>ce(e.value)}}),gm=()=>_m.reduce((e,[t,n,o,l])=>(e.push({name:t,path:n,component:fi,meta:o},{path:n.endsWith("/")?n+"index.html":n.substring(0,n.length-5),redirect:n},...l.map(r=>({path:r===":md"?n.substring(0,n.length-5)+".md":r,redirect:n}))),e),[{name:"404",path:"/:catchAll(.*)",component:fi}]),bm=nd,Am=()=>{const e=$d({history:bm(us("/")),routes:gm(),scrollBehavior:(t,n,o)=>o||(t.hash?{el:t.hash}:{top:0})});return e.beforeResolve(async(t,n)=>{var o;(t.path!==n.path||n===pt)&&([t.meta._data]=await Promise.all([ht.resolvePageData(t.name),(o=hs[t.name])==null?void 0:o.__asyncLoader()]))}),e},ym=e=>{e.component("ClientOnly",Hl),e.component("Content",Mu)},Bm=(e,t,n)=>{const o=li(()=>t.currentRoute.value.path),l=li(()=>ht.resolveRouteLocale(on.value.locales,o.value)),r=hf(o,()=>t.currentRoute.value.meta._data),i=j(()=>ht.resolveLayouts(n)),a=j(()=>ht.resolveSiteLocaleData(on.value,l.value)),s=j(()=>ht.resolvePageFrontmatter(r.value)),c=j(()=>ht.resolvePageHeadTitle(r.value,a.value)),u=j(()=>ht.resolvePageHead(c.value,s.value,a.value)),d=j(()=>ht.resolvePageLang(r.value,a.value)),f=j(()=>ht.resolvePageLayout(r.value,i.value));return e.provide(Du,i),e.provide(ps,r),e.provide(ms,s),e.provide(Ru,c),e.provide(Es,u),e.provide(vs,d),e.provide(_s,f),e.provide($l,l),e.provide(bs,a),Object.defineProperties(e.config.globalProperties,{$frontmatter:{get:()=>s.value},$head:{get:()=>u.value},$headTitle:{get:()=>c.value},$lang:{get:()=>d.value},$page:{get:()=>r.value},$routeLocale:{get:()=>l.value},$site:{get:()=>on.value},$siteLocale:{get:()=>a.value},$withBase:{get:()=>ql}}),{layouts:i,pageData:r,pageFrontmatter:s,pageHead:u,pageHeadTitle:c,pageLang:d,pageLayout:f,routeLocale:l,siteData:on,siteLocaleData:a}},km=()=>{const e=Tu(),t=Pu(),n=_e([]),o=()=>{e.value.forEach(r=>{const i=wm(r);i&&n.value.push(i)})},l=()=>{document.documentElement.lang=t.value,n.value.forEach(r=>{r.parentNode===document.head&&document.head.removeChild(r)}),n.value.splice(0,n.value.length),e.value.forEach(r=>{const i=xm(r);i!==null&&(document.head.appendChild(i),n.value.push(i))})};Kt(Iu,l),je(()=>{o(),l(),Ge(()=>e.value,l)})},wm=([e,t,n=""])=>{const o=Object.entries(t).map(([a,s])=>Ee(s)?`[${a}=${JSON.stringify(s)}]`:s===!0?`[${a}]`:"").join(""),l=`head > ${e}${o}`;return Array.from(document.querySelectorAll(l)).find(a=>a.innerText===n)||null},xm=([e,t,n])=>{if(!Ee(e))return null;const o=document.createElement(e);return Ml(t)&&Object.entries(t).forEach(([l,r])=>{Ee(r)?o.setAttribute(l,r):r===!0&&o.setAttribute(l,"")}),Ee(n)&&o.appendChild(document.createTextNode(n)),o},Lm=gu,Dm=async()=>{var n;const e=Lm({name:"VuepressApp",setup(){var o;km();for(const l of co)(o=l.setup)==null||o.call(l);return()=>[ce(Ps),...co.flatMap(({rootComponents:l=[]})=>l.map(r=>ce(r)))]}}),t=Am();ym(e),Bm(e,t,co);for(const o of co)await((n=o.enhance)==null?void 0:n.call(o,{app:e,router:t,siteData:on}));return e.use(t),{app:e,router:t}};Dm().then(({app:e,router:t})=>{t.isReady().then(()=>{e.mount("#app")})});export{we as _,Fc as a,pe as b,te as c,Dm as createVueApp,It as d,le as e,z as o,gt as r,Ve as w}; +function __vite__mapDeps(indexes) { + if (!__vite__mapDeps.viteFileDeps) { + __vite__mapDeps.viteFileDeps = ["assets/cf-tools.html-6fH2SBD0.js","assets/20200216004851429_31590-ycX-VYgZ.js","assets/vscode替代codeblock.html-QvZWRnPv.js","assets/博客搭建.html-z_tV2tys.js","assets/20200911144457950_30869-783m7FV3.js","assets/数据整理.html-nkuQTRl9.js"] + } + return indexes.map((i) => __vite__mapDeps.viteFileDeps[i]) +} \ No newline at end of file diff --git "a/assets/celery\345\274\202\346\255\245\344\273\273\345\212\241.html-0BnblJpL.js" "b/assets/celery\345\274\202\346\255\245\344\273\273\345\212\241.html-0BnblJpL.js" new file mode 100644 index 0000000..edb6301 --- /dev/null +++ "b/assets/celery\345\274\202\346\255\245\344\273\273\345\212\241.html-0BnblJpL.js" @@ -0,0 +1,45 @@ +import{_ as n,o as s,c as e,a}from"./app-x8p6wK6B.js";const t={},i=a(`

celery异步任务

在使用celery时,需要控制异步任务

任务终止有多种情况

  • 任务内部错误
  • celery被杀死
  • 手动结束任务(通过celery控制)

这些需要我们特殊注意

@shared_task(ignore_result=True, time_limit=3600*24)
+def scan(task_id, report_id):
+
+    def handle_stop(*args, **kwargs):
+        pass 
+        # 这里如果需要修改任务状态,则一定需要判断任务是否已结束,
+        # 停止任务之后保留任务记录,
+        # 杀死celery会走这里(SIGQUIT), 然后celery给该进程发送指令
+        # bug:任务已完成,但是celery进程还在,那么退出celery仍旧会执行handle_stop,因此需要在stop中增加对任务状态的判断。
+        # 如果机器断电,肯定走不到这里,所以需要在启动django的时候,将所有运行中的任务修改为失败
+
+    signal.signal(signal.SIGTERM, handle_stop) # 这里注册是对整个celery worker生效,因此
+    try:
+        openvas_scan(task_id, report_id)
+    except Exception as e:
+        with open("/home/bolean/logs/vulscan.los", 'a', encoding='utf8') as f:
+            f.write("漏洞扫描任务_{}_{}异常结束:handle_stop but in try except\\n".format(task_id, report_id))
+        logger.warning("handle_stop, but in try except")
+        handle_stop()
+
+

异步任务prefork gevent的选择

使用gevent时,遇到问题


+Traceback (most recent call last):
+  File "/mnt/bolean/venv/lib/python3.10/site-packages/celery/app/trace.py", line 451, in trace_task
+    R = retval = fun(*args, **kwargs)
+  File "/mnt/bolean/venv/lib/python3.10/site-packages/celery/app/trace.py", line 734, in __protected_call__
+    return self.run(*args, **kwargs)
+  File "/mnt/bolean/sdp-backend/fuzz_testing/tasks.py", line 496, in task_test_case_result
+    test_case_obj = FuzzTestingTestCase.objects.get(id=test_case_id)
+  File "/mnt/bolean/venv/lib/python3.10/site-packages/django/db/models/manager.py", line 85, in manager_method
+    return getattr(self.get_queryset(), name)(*args, **kwargs)
+  File "/mnt/bolean/venv/lib/python3.10/site-packages/django/db/models/query.py", line 492, in get
+    num = len(clone)
+  File "/mnt/bolean/venv/lib/python3.10/site-packages/django/db/models/query.py", line 302, in __len__
+    self._fetch_all()
+  File "/mnt/bolean/venv/lib/python3.10/site-packages/django/db/models/query.py", line 1507, in _fetch_all
+    self._result_cache = list(self._iterable_class(self))
+  File "/mnt/bolean/venv/lib/python3.10/site-packages/django/db/models/query.py", line 57, in __iter__
+    results = compiler.execute_sql(
+  File "/mnt/bolean/venv/lib/python3.10/site-packages/django/db/models/sql/compiler.py", line 1359, in execute_sql
+    cursor = self.connection.cursor()
+  File "/mnt/bolean/venv/lib/python3.10/site-packages/django/utils/asyncio.py", line 24, in inner
+    raise SynchronousOnlyOperation(message)
+django.core.exceptions.SynchronousOnlyOperation: You cannot call this from an async context - use a thread or sync_to_async.
+
+

也就是说FuzzTestingTestCase.objects.get(id=test_case_id) 这个不能在gevent下执行

但是 这样的命令时可以执行的 models.Host.objects.filter(id=host_id, status=VulHostStatus.RUNNING.value).exists()

`,11),l=[i];function o(c,p){return s(),e("div",null,l)}const r=n(t,[["render",o],["__file","celery异步任务.html.vue"]]);export{r as default}; diff --git "a/assets/celery\345\274\202\346\255\245\344\273\273\345\212\241.html-SxBcjfXw.js" "b/assets/celery\345\274\202\346\255\245\344\273\273\345\212\241.html-SxBcjfXw.js" new file mode 100644 index 0000000..f7be262 --- /dev/null +++ "b/assets/celery\345\274\202\346\255\245\344\273\273\345\212\241.html-SxBcjfXw.js" @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-02431a08","path":"/python/celery%E5%BC%82%E6%AD%A5%E4%BB%BB%E5%8A%A1.html","title":"celery异步任务","lang":"en-US","frontmatter":{},"headers":[{"level":3,"title":"异步任务prefork gevent的选择","slug":"异步任务prefork-gevent的选择","link":"#异步任务prefork-gevent的选择","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"python/celery异步任务.md"}');export{e as data}; diff --git a/assets/cf-tools.html-6fH2SBD0.js b/assets/cf-tools.html-6fH2SBD0.js new file mode 100644 index 0000000..304c83c --- /dev/null +++ b/assets/cf-tools.html-6fH2SBD0.js @@ -0,0 +1,27 @@ +import{_ as t,a as o}from"./20200216004851429_31590-ycX-VYgZ.js";import{_ as n,r as l,o as a,c as p,d as c,b as e,e as i,a as d}from"./app-x8p6wK6B.js";const r="/assets/20200216005034283_6861-hoVHTvC9.png",u="/assets/20200216003909531_3860-Kd-pzYyS.png",m="/assets/20200216003958555_8778-v9lJg-BZ.png",h="/assets/20200216001653735_883-IQNkpcp5.png",f="/assets/20200216005527217_28042-hRMqyCAE.png",_="/assets/20200216010453980_27238-hTvJHllu.png",g="/assets/20200216010203757_32340-VomJlKL_.png",v="/assets/20200216010658929_2127--mQBQPAm.png",b="/assets/20200216011139813_4073-CFm4jt_m.png",x="/assets/20200216011249181_32265-KdC56aiJ.png",w="/assets/20200216012809191_27147-cjku2_ER.png",q="/assets/20200216015749119_31992-XAlIPdu_.png",$="/assets/20200216020006936_26223-6nqb2gLR.png",y="/assets/20200216020115513_27857-2qK9dJpn.png",k="/assets/20200216020714652_5899-vsZEi9Fr.png",E="/assets/20200216020814094_3886-Y1sov4DF.png",I={},N=e("h1",{id:"cf-tools",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#cf-tools","aria-hidden":"true"},"#"),c(" cf-tools")],-1),D=e("div",{style:{float:"right"}},[e("table",null,[e("thead",null,[e("tr",null,[e("th",null,"时间"),e("th",null,"作者")])]),e("tbody",null,[e("tr",null,[e("td",null,"2020/2/16 0:43"),e("td",null,"moyechen")])])])],-1),T={href:"https://github.com/xalanq/cf-tool/",target:"_blank",rel:"noopener noreferrer"},C=e("p",null,"cf-tool 是 Codeforces 的命令行界面的跨平台(支持 Windows、Linux、OS X)工具,其支持很多常用操作。",-1),L=e("h3",{id:"cf-tool下载",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#cf-tool下载","aria-hidden":"true"},"#"),c(" cf-tool下载")],-1),V={href:"https://github.com/xalanq/cf-tool/releases",target:"_blank",rel:"noopener noreferrer"},Y=d('

之后的更新可以直接使用 upgrade 命令获取。

windows准备工作

你的电脑需要编译器才能调试你编写的代码

对于c/cpp, 我们需要g++这款编译器 如果你拥有自带mingw的code:block这款IDE, 可以从如下位置找到 2

▲将第三张图片红框中的路径复制下来, 记做compiler_path

将这个路径添加到环境变量中,什么,你还不会添加路径到环境变量? 点击以获得讲解

否则,可以访问 https://www.jianshu.com/p/ff24a81f3637 ,参考教程下载g++编译器

测试编译器是否可用

按住win键,然后输入r,在弹出的框中输入cmd

此时会打开一个黑框框

输入g++

如果出现下图,这说明编译器准备完毕

添加cf.exe到环境变量

首先先将下载到的cf.exe文件放到一个合适的目录

右击 我的电脑,在弹出的下来框中选择 属性 这个选项 然后按下图操作

至此, 打开cmd,输入cf,如果显示以下内容,即为cf 环境变量配置成功

LINUX 准备工作

准备cf

将下载到cf 文件放在合适的目录,进入这个目录

执行以下命令,给予执行权限并创建软连接


+chmod 775 ./cf
+ln ./cf /usr/bin/cf
+
+

输入cf 出现下图则成功

linux测试g++编译器是否可用

输入g++,出现下图,则为正常

如果没有, 请自行安装g++编译器

配置cf

终于将准备工作做完了

我们可以开始配置了

windows用户请打开cmd linxu 用户请进入shell

下图是我在linux的终端上操作的,windows和linux通用

输入以下命令 cf config

  1. username and password > 这个是用来配置用户名以及密码
  2. add a template > 添加一个代码模板,可以指定语言
  3. delete a template > 删除一个模板
  4. 设置默认模板
  5. 在解析题目结束后,自动生成模板代码
  6. 设置网站主体, 比如在中国我们可以设置为镜像站 https://codeforces.ml 以获得更好的体验

我们选择1

然后选择你要使用的编译器, 这里我们使用42号编译器 GNU G++11 5.1.0

紧接着

可以看到, cf-tool 提供了一些变量,比如 年月日, 以及你的用户名

这里我提供一个模板

#include<bits/stdc++.h>
+using namespace std;
+typedef long long ll;
+
+/*
+$%U%$
+$%Y%$-$%M%$-$%D%$  $%h%$:$%m%$
+*/
+
+const int maxn = 5e5 + 5;
+const int inf  = 0x3f3f3f3f;
+
+
+int main() {
+    std::ios::sync_with_stdio(false);
+    cin.tie(0);
+
+    return 0;
+}
+

你只需要复制到一个地方,然后记住他的绝对路径,并输入即可 例如:

  • ~/template.cpp (适用于linux)
  • D:/template.cpp (适用于windows,需要带上盘符)

在输入后, 配置程序给了几个询问,我来分别做以下解释

  1. The suffix of template above will be added by default. Other suffix? (e.g. "cxx cc"), empty is ok:

    默认情况下,将添加上面模板的后缀。 需要添加其他后缀吗?(例如,“cxx cc”),空的也是可以:

    这里我们不需要了,所以直接回车

  2. Template's alias (e.g. "cpp" "py"):

    模板别名,因为我们用的是cpp, 因此我输入了cpp, 别名在使用 cf gen 生成模板代码时可以用到, 比如输入cf gen cpp, 就会生成我们刚刚添加的模板

  3. Script in template: Template will run 3 scripts in sequence when you run "cf test":

    - before_script   (execute once)
    + - script          (execute the number of samples times)
    + - after_script    (execute once)
    +

    You could set "before_script" or "after_script" to empty string, meaning not executing. You have to run your program in "script" with standard input/output (no need to redirect).

    You can insert some placeholders in your scripts. When execute a script, cf will replace all placeholders by following rules:

    $%path%$ Path to source file (Excluding $%full%$, e.g. "/home/xalanq/") $%full%$ Full name of source file (e.g. "a.cpp") $%file%$ Name of source file (Excluding suffix, e.g. "a") $%rand%$ Random string with 8 character (including "a-z" "0-9")

    这一段讲的是工具的运作原理

    在你输入cf test之后

    • 首先工具执行你输入的 before_script 脚本, 例如 g++ $%full%$ -o /tmp/a.out -std=c++11, 来编译代码,并生成到/tmp/a.out
    • 然后执行 你输入的script脚本, 例如/tmp/a.out ,这代表执行这个刚刚编译好的程序, (ps, 这一步 是用来执行程序的)
    • 接下来执行你输入的after_script脚本,例如执行 rm $%file%$.exe 以将刚刚编译好的程序删除, 防止占用硬盘空间(ps. 一般来说,acm的代码不超过5kb, 但是编译好的控制台应用程序一般在1mb左右, 但是这个程序我们只用一次,比较浪费空间,因此可以在执行后删除)

    下面我讲解一下我的输入

    • 对于第一个问题before_script .我的回答是 g++ $%full%$ -o /tmp/a.out -std=c++11, 我每次都生成到同一个地方, 这次生成的会覆盖掉上次生成的, 也不需要删除了,其中 /tmp/a.out 是一个生成的路径, -std=c++11 是执行的c++标准, 我们可以改为-std=c++14 或者 -std=c++17以享用新特性
      • 在windows上,路径可以更改为 D:/tmp.exe 等等等等,需要加上盘符
    • 对于第二个问题script . 我的回答是 /tmp/a.out, 无论是linux 还是windows ,都需要写的是生成的文件的绝对路径
    • 第三个问题 after_script .我们不需要任何处理,因此,直接回车

最后,它询问我是否作为默认设置, 输入 y 确认

至此, 配置结束

简单的流程

准备比赛了, 首先拿到比赛编号,

▲可以在url中看到比赛编号

控制台输入 cf race 比赛编号

▼它就会为你解析比赛测试样例,并打开题面网站

▼如果比赛未开始,他会自动等待,然后在开始的一瞬间为你解析数据

然后使用cd命令切换到比赛目录,并进入a题文件夹

cd 比赛编号\\a

使用cf gen命令生成一个模板

你可以使用别名,这样根据你对应的模板生成代码 cf gen cpp

然后开始编写你的代码:

  • 在linux 上 : vim a.cpp
  • 在windows上: 如果装有vscode ,则可以使用code -r a.cpp,否则, 可以使用notepad a.cpp使用记事本,当然,你也可以在你的IDE中添加这个文件夹,以使用IDE编写代码

编写结束 使用cf test测试样例数据

很好, 样例过了

使用cf submit提交你所在目录的题目

过题,

然后使用cd命令切换到其他题目的目录, 继续重复操作

',72);function B(J,F){const s=l("ExternalLinkIcon");return a(),p("div",null,[N,D,c(" ## 下载&准备工作 "),e("p",null,[c("GitHub 地址: "),e("a",T,[c("xalanq/cf-tool"),i(s)])]),C,L,e("p",null,[c("前往 "),e("a",V,[c("cf-tool/releases"),i(s)]),c(" 下载最新版。")]),Y])}const S=n(I,[["render",B],["__file","cf-tools.html.vue"]]);export{S as default}; diff --git a/assets/cf-tools.html-xEbAAg4N.js b/assets/cf-tools.html-xEbAAg4N.js new file mode 100644 index 0000000..ee6ac71 --- /dev/null +++ b/assets/cf-tools.html-xEbAAg4N.js @@ -0,0 +1 @@ +const l=JSON.parse('{"key":"v-2d9e888d","path":"/notebook/cf-tools.html","title":"cf-tools","lang":"en-US","frontmatter":{},"headers":[{"level":3,"title":"cf-tool下载","slug":"cf-tool下载","link":"#cf-tool下载","children":[]},{"level":3,"title":"windows准备工作","slug":"windows准备工作","link":"#windows准备工作","children":[]},{"level":3,"title":"LINUX 准备工作","slug":"linux-准备工作","link":"#linux-准备工作","children":[]},{"level":2,"title":"配置cf","slug":"配置cf","link":"#配置cf","children":[]},{"level":2,"title":"简单的流程","slug":"简单的流程","link":"#简单的流程","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/cf-tools.md"}');export{l as data}; diff --git a/assets/conda.html-8vWzKDUw.js b/assets/conda.html-8vWzKDUw.js new file mode 100644 index 0000000..afceb65 --- /dev/null +++ b/assets/conda.html-8vWzKDUw.js @@ -0,0 +1 @@ +import{_ as a,o as e,c as n,a as d}from"./app-x8p6wK6B.js";const c="/assets/325013368947114-V-SvYCjT.png",o={},i=d('

环境部署

cuda

nvidia-smi 可以查看

cudaa

conda

科学计算时,使用conda可以方便的部署所需的python环境

conda vs anconda

https://zhuanlan.zhihu.com/p/379321816

安装

使用

  1. 查看版本信息 conda -V

  2. 创建虚拟环境 conda create -n your_env_name python=x.x

  3. 激活 conda active your_env_name

  4. 查看已经创建的虚拟环境 conda env list
    conda info -e

  5. 设置国内镜像

conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/

conda config --set show_channel_urls yes

  1. 恢复使用国内

conda config --remove-key channels

',16),r=[i];function h(t,s){return e(),n("div",null,r)}const p=a(o,[["render",h],["__file","conda.html.vue"]]);export{p as default}; diff --git a/assets/conda.html-uf0UMaKT.js b/assets/conda.html-uf0UMaKT.js new file mode 100644 index 0000000..a267f59 --- /dev/null +++ b/assets/conda.html-uf0UMaKT.js @@ -0,0 +1 @@ +const l=JSON.parse('{"key":"v-7443725c","path":"/python/cv/conda.html","title":"环境部署","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"cuda","slug":"cuda","link":"#cuda","children":[]},{"level":2,"title":"cudaa","slug":"cudaa","link":"#cudaa","children":[]},{"level":2,"title":"conda","slug":"conda","link":"#conda","children":[{"level":3,"title":"conda vs anconda","slug":"conda-vs-anconda","link":"#conda-vs-anconda","children":[]},{"level":3,"title":"安装","slug":"安装","link":"#安装","children":[]},{"level":3,"title":"使用","slug":"使用","link":"#使用","children":[]}]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"python/cv/conda.md"}');export{l as data}; diff --git a/assets/cuda.html-Vr_7SkES.js b/assets/cuda.html-Vr_7SkES.js new file mode 100644 index 0000000..6775209 --- /dev/null +++ b/assets/cuda.html-Vr_7SkES.js @@ -0,0 +1 @@ +import{_ as e,o as d,c as a,b as c,d as n}from"./app-x8p6wK6B.js";const t={},o=c("h1",{id:"cuda",tabindex:"-1"},[c("a",{class:"header-anchor",href:"#cuda","aria-hidden":"true"},"#"),n(" cuda")],-1),s=c("p",null,"cuda的下载和管理,可以从nvidia官方网站下载,需配合cudnn版本使用",-1),_=c("p",null,"如果要pytorch,要下指定版本的cuda、cudnn,并配置环境变量 如果要paddle,也是要下指定版本的cuda、cudnn,并配置环境变量",-1),u=c("p",null,"多种库、多种版本,对应的cuda版本,也不相同",-1),l=c("p",null,"可以使用conda管理",-1),r=[o,s,_,u,l];function i(h,p){return d(),a("div",null,r)}const m=e(t,[["render",i],["__file","cuda.html.vue"]]);export{m as default}; diff --git a/assets/cuda.html-yP6QwKyU.js b/assets/cuda.html-yP6QwKyU.js new file mode 100644 index 0000000..189c8d9 --- /dev/null +++ b/assets/cuda.html-yP6QwKyU.js @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-d7f6c430","path":"/python/cv/cuda.html","title":"cuda","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"python/cv/cuda.md"}');export{t as data}; diff --git "a/assets/ddd_graphql\346\225\260\346\215\256\346\265\201.html-P651VC0Z.js" "b/assets/ddd_graphql\346\225\260\346\215\256\346\265\201.html-P651VC0Z.js" new file mode 100644 index 0000000..37f99ae --- /dev/null +++ "b/assets/ddd_graphql\346\225\260\346\215\256\346\265\201.html-P651VC0Z.js" @@ -0,0 +1,4 @@ +import{_ as e,o as t,c as p,a as r}from"./app-x8p6wK6B.js";const a={},d=r(`

ddd+graphql数据流

数据流 kong就是openresty的一个应用,nginx

前端 -> kong (解析token,装上user信息)->后端

-> controller层 ->resolve-> types -> graphql input -> 封装为command

-> 应用层-> mutation_service -> 调用各种domain、repo方法, -> domain 层, 领域方法 -> 调用domain层repo的方法(实现在infrastructure中),持久化到db

返回数据,在应用层中定义了各种Representation,可以序列化数据

与Django的映射: types = view之前的数据解析 apps = view

问题1:数据校验,唯一性校验应该db实现 问题2:数据默认值,应该在orm层实现,还是在app层实现 问题3:选择输入,如何判断输入数据有效性?

基础的,应该在domain的validate中定义,抛出ValueError即可
+复杂的,比如增加工段需要工序id,就需判断工序id是否存在,是否同一个租户下的,
+	这种应该在app层实现
+

问题4:关联关系时,db-orm只存储关联的id,那聚合根的model如何写? graphql的types怎么写?中间如何转换

`,10),o=[d];function n(i,s){return t(),p("div",null,o)}const g=e(a,[["render",n],["__file","ddd_graphql数据流.html.vue"]]);export{g as default}; diff --git "a/assets/ddd_graphql\346\225\260\346\215\256\346\265\201.html-kRRHB29s.js" "b/assets/ddd_graphql\346\225\260\346\215\256\346\265\201.html-kRRHB29s.js" new file mode 100644 index 0000000..a29fe32 --- /dev/null +++ "b/assets/ddd_graphql\346\225\260\346\215\256\346\265\201.html-kRRHB29s.js" @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-046aced0","path":"/notebook/graphql/ddd_graphql%E6%95%B0%E6%8D%AE%E6%B5%81.html","title":"ddd+graphql数据流","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/graphql/ddd+graphql数据流.md"}');export{t as data}; diff --git a/assets/django.html-Ety7BvIO.js b/assets/django.html-Ety7BvIO.js new file mode 100644 index 0000000..d701ffa --- /dev/null +++ b/assets/django.html-Ety7BvIO.js @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-736bb064","path":"/python/django.html","title":"django","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"python/django.md"}');export{t as data}; diff --git a/assets/django.html-LrCE0hnu.js b/assets/django.html-LrCE0hnu.js new file mode 100644 index 0000000..13eecc0 --- /dev/null +++ b/assets/django.html-LrCE0hnu.js @@ -0,0 +1,209 @@ +import{_ as n,o as s,c as a,a as e}from"./app-x8p6wK6B.js";const t={},p=e(`

django

作者:PegasusWang 链接:https://www.zhihu.com/question/56472691/answer/292510026 来源:知乎 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

简单的说就是服务端监听 每次 accept 一个新的请求后,开一个处理 这个 socket 客户连接。如果你对底层实现原理感兴趣,可以继续看下去,从 socket 编程的角度来解释多线程 server。最后附上一个异步框架工作过程的视频讲解。这里我们自己撸一个简单的多线程 wsgi server 来看下原理,还是需要深入源码和 socket 编程你才能真正理解。 我们从 python 自带的一个 wsgi server 看下如何实现多线程处理请求。首先你需要熟悉下 wsgi。 看一个最简单的 wsgi app:

#!/usr/bin/env python
+# -*- coding:utf-8 -*-
+
+
+def application(environ, start_response):
+    status = '200 OK'
+    headers = [('Content-Type', 'text/html; charset=utf8')]
+
+    start_response(status, headers)
+    return [b"<h1>Hello</h1>"]
+
+
+if __name__ == '__main__':
+    from wsgiref.simple_server import make_server
+    httpd = make_server('127.0.0.1', 8000, application)
+    httpd.serve_forever()
+

然后用你的开发工具跟进去 make_server 这个函数,看下它的定义:

# lib/python2.7/wsgiref/simple_server.py
+
+def make_server(
+    host, port, app, server_class=WSGIServer, handler_class=WSGIRequestHandler
+):
+    """Create a new WSGI server listening on \`host\` and \`port\` for \`app\`"""
+    server = server_class((host, port), handler_class)
+    server.set_app(app)
+    return server
+
+class WSGIServer(HTTPServer):
+
+    """BaseHTTPServer that implements the Python WSGI protocol"""
+
+    application = None
+
+    def server_bind(self):
+        """Override server_bind to store the server name."""
+        HTTPServer.server_bind(self)
+        self.setup_environ()
+
+    def setup_environ(self):
+        # Set up base environment
+        env = self.base_environ = {}
+        env['SERVER_NAME'] = self.server_name
+        env['GATEWAY_INTERFACE'] = 'CGI/1.1'
+        env['SERVER_PORT'] = str(self.server_port)
+        env['REMOTE_HOST']=''
+        env['CONTENT_LENGTH']=''
+        env['SCRIPT_NAME'] = ''
+
+    def get_app(self):
+        return self.application
+
+    def set_app(self,application):
+        self.application = application
+

看到这个 WSGIServer 定义了吗,继承了一个 HttpServer。我们再继续追一下其定义:

# lib/python2.7/BaseHTTPServer.py
+
+class HTTPServer(SocketServer.TCPServer):
+
+    allow_reuse_address = 1    # Seems to make sense in testing environment
+
+    def server_bind(self):
+        """Override server_bind to store the server name."""
+        SocketServer.TCPServer.server_bind(self)
+        host, port = self.socket.getsockname()[:2]
+        self.server_name = socket.getfqdn(host)
+        self.server_port = port
+

到这里,我们继续追,看到 TcpServer 定义:

# lib/python2.7/SocketServer.py
+
+class TCPServer(BaseServer):
+    """这里我省略了定义"""
+

你还可以发现一个 ThreadingTCPServer 类:我们看下它的定义

class ThreadingTCPServer(ThreadingMixIn, TCPServer): 
+    pass
+

好了,怎么多线程处理请求呢?看下这个 ThreadingMixIn 类是如何实现的:

class ThreadingMixIn:
+    """Mix-in class to handle each request in a new thread."""
+
+    # Decides how threads will act upon termination of the
+    # main process
+    daemon_threads = False
+
+    def process_request_thread(self, request, client_address):
+        """Same as in BaseServer but as a thread.
+
+        In addition, exception handling is done here.
+
+        """
+        try:
+            self.finish_request(request, client_address)
+            self.shutdown_request(request)
+        except:
+            self.handle_error(request, client_address)
+            self.shutdown_request(request)
+
+    def process_request(self, request, client_address):
+        """Start a new thread to process the request."""
+        t = threading.Thread(target = self.process_request_thread,
+                             args = (request, client_address))
+        t.daemon = self.daemon_threads
+        t.start()
+

看到吗,其实就是对于每个新请求,会启动一个新的线程来处理 socket 请求。假如让我们自己实现一个多线程 socket server 应该怎么实现呢?先来写一个简单的单线程 socker echo server:

from socket import *  # 偷懒这么写
+s = socket(AF_INET, SOCK_STREAM)
+s.bind(("", 9000))
+s.listen(5)
+while True:
+    c, a = s.accept()
+    print "Received connection from", a
+    c.send("Hello %s\\\\n" % a[0])
+    c.close()
+

你可以用telnet之类的工具连上该端口看效果。 这样一次只能处理一个请求,如果想每次来一个请求用一个线程处理呢?我们可以这样做:

import threading
+from socket import *
+
+def handle_client(c):
+    # 处理 client 请求
+    c.send("Hello\\n")
+    c.close()
+    return
+
+s = socket(AF_INET, SOCK_STREAM)
+s.bind(("", 9000))
+s.listen(5)
+while True:
+    c, a = s.accept()
+    t = threading.Thread(target=handle_client,
+                         args=(c,))
+

是不是很简单,这其实就是多线程工作的原理,每次 accept 得到一个新的客户端请求以后开一个线程去处理。当然 socket 编程还是偏底层,我们刚才看到了 python 提供了 SocketServer 模块来简化 socket 编程。我们使用 SocketServer 模块来发送数据:

import SocketServer
+import time
+
+class TimeHandler(SocketServer.BaseRequestHandler):
+    def handle(self):
+        # self.request 是一个 client socket 对象
+        self.request.sendall(.ctime() + "\\n")
+
+serv = SocketServer.TCPServer(("", 8889), TimeHandler)
+serv.serve_forever()
+

它的执行原理是这样的:server 等待请求到来对每个 socket 连接,server 创建一个新的 handler 类handle() 方法调用处理 client socket 对象,比如发送数据handle() 方法返回后,连接关闭,同时 handler 实例对象销毁但是这个 server 的处理能力很差,一次只能处理一个请求,我们看下这个模块提供了几个类:TCPServer: 同步的 tcp serverForkingTCPServer: 多进程 tcp serverThreadingTCPServer: 多线程 tcp server怎么实现一个多线程 tcp server 呢?很简单:

# 改成 ThreadingTCPServer 就行了,代码其他部分不动
+serv = SocketServer.ThreadingTCPServer(("",8000),TimeHandler)
+serv.serve_forever()
+
+

这样一来,新的请求就能被新的线程去处理了。我们就通过线程来增强了并发能力,当然线程开销比较大,不如用协程(抽空会写个用协程实现异步的socker server)。 如果你浏览该模块,还能看到两个 Mixin:ForkingMixinThreadingMixIn我们只要继承它们就很容易实现一个多进程或者多线程的 server,比如实现一个多线程的 HTTPServerfrom BaseHTTPServer

import HTTPServer
+from SimpleHTTPServer import SimpleHTTPRequestHandler
+from SocketServer import ThreadingMixIn
+
+class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
+    pass
+
+serv = ThreadedHTTPServer(("", 8080), SimpleHTTPRequestHandler)
+

好了,看了这么多让我们改造下 Python 自带的 wsgi server 为多线程的:

import time
+import SocketServer
+import socket
+from SimpleHTTPServer import SimpleHTTPRequestHandler
+from SocketServer import ThreadingMixIn
+
+
+class HTTPServer(SocketServer.TCPServer):
+
+    allow_reuse_address = 1    # Seems to make sense in testing environment
+
+    def server_bind(self):
+        """Override server_bind to store the server name."""
+        SocketServer.TCPServer.server_bind(self)
+        host, port = self.socket.getsockname()[:2]
+        self.server_name = socket.getfqdn(host)
+        self.server_port = port
+
+
+class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
+    pass
+
+
+class ThreadWSGIServer(ThreadedHTTPServer):
+
+    """BaseHTTPServer that implements the Python WSGI protocol"""
+
+    application = None
+
+    def server_bind(self):
+        """Override server_bind to store the server name."""
+        HTTPServer.server_bind(self)
+        self.setup_environ()
+
+    def setup_environ(self):
+        # Set up base environment
+        env = self.base_environ = {}
+        env['SERVER_NAME'] = self.server_name
+        env['GATEWAY_INTERFACE'] = 'CGI/1.1'
+        env['SERVER_PORT'] = str(self.server_port)
+        env['REMOTE_HOST'] = ''
+        env['CONTENT_LENGTH'] = ''
+        env['SCRIPT_NAME'] = ''
+
+    def get_app(self):
+        return self.application
+
+    def set_app(self, application):
+        self.application = application
+
+
+def application(environ, start_response):
+    time.sleep(10)    # 注意这里的 sleep
+    status = '200 OK'
+    headers = [('Content-Type', 'text/html; charset=utf8')]
+
+    start_response(status, headers)
+    return [b"<h1>Hello</h1>"]
+
+
+if __name__ == '__main__':
+    from wsgiref.simple_server import make_server
+    httpd = make_server('127.0.0.1', 8000, application, server_class=ThreadWSGIServer)
+    httpd.serve_forever()
+
+

对了,我们怎么证明这个真是多线程的 wsgi server 了呢,很简单。你看我加了个 sleep(10)。 如果你在之前的单线程 wsgi server 跑,你可以开俩个终端去 curl,curl 完一个赶紧切到另一个 curl 。 单线程你会发现几乎是 10 + 10 秒,但是下边这个多线程 wsgi server 你会发现大概只用10秒,两个请求是并发的(当然我这种测试很 low,你可以随便用一个网络测试工具)。虽然我没看过 django wsgi server 的实现,但是它自己实现的开发服务器原理应该是类似的。如果你能坚持看到这里,是更明白了呢还是更懵了呢?你可以看下PegasusWang/notebooks 这个是手撸 web 框架的教程,看完你就对 wsgi,如何自己写 框架以及 gunicorn 部署有点概念了。最近在学习异步框架的工作原理,感兴趣可以看看,之后还会出个协程版本的。

https://zhuanlan.zhihu.com/p/42044997

`,28),o=[p];function c(i,l){return s(),a("div",null,o)}const r=n(t,[["render",c],["__file","django.html.vue"]]);export{r as default}; diff --git "a/assets/django\347\274\223\345\255\230.html-NX5g_H28.js" "b/assets/django\347\274\223\345\255\230.html-NX5g_H28.js" new file mode 100644 index 0000000..bc879fb --- /dev/null +++ "b/assets/django\347\274\223\345\255\230.html-NX5g_H28.js" @@ -0,0 +1 @@ +import{_ as s,o as t,c as a,b as e,d as o}from"./app-x8p6wK6B.js";const n="/assets/20210818031909887_21744-zbqdqOVa.png",c={},_=e("h1",{id:"django缓存",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#django缓存","aria-hidden":"true"},"#"),o(" django缓存")],-1),d=e("p",null,"接口: 自动补全接口 程序中有预定义的词,但是需要进行去重和按拼音排序, 每次占用大量时间",-1),r=e("p",null,"优化: 使用django 缓存 https://docs.djangoproject.com/zh-hans/3.2/topics/cache/",-1),h=e("p",null,[o("由于该缓存是线程安全的, 每个线程独立拥有一个缓存,可以看到重启后前几次访问需要时间约1250ms, 之后收敛到250ms,提升400%的速度 "),e("img",{src:n,alt:""})],-1),i=[_,d,r,h];function l(p,m){return t(),a("div",null,i)}const u=s(c,[["render",l],["__file","django缓存.html.vue"]]);export{u as default}; diff --git "a/assets/django\347\274\223\345\255\230.html-THwhYwkg.js" "b/assets/django\347\274\223\345\255\230.html-THwhYwkg.js" new file mode 100644 index 0000000..3435618 --- /dev/null +++ "b/assets/django\347\274\223\345\255\230.html-THwhYwkg.js" @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-4ac7a662","path":"/notebook/django%E7%BC%93%E5%AD%98.html","title":"django缓存","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/django缓存.md"}');export{t as data}; diff --git a/assets/docker.html-4FlAdIF3.js b/assets/docker.html-4FlAdIF3.js new file mode 100644 index 0000000..600aa1e --- /dev/null +++ b/assets/docker.html-4FlAdIF3.js @@ -0,0 +1,27 @@ +import{_ as e,o as i,c as n,a as r}from"./app-x8p6wK6B.js";const a={},s=r(`

2020/5/9 docKer 时区设置

echo "Asia/Shanghai" > /etc/timezone
+dpkg-reconfigure -f noninteractive tzdata
+

如果没有tzdata,需要手动安装 apt-get install -y tzdata

docker

给容器换一个名字, 比如说 docker run -it --name=mycentos2 centos:7 /bin/bash, 可以解决问题. 将原来的容器删除

查询当前容器: docker container ls -all

删除当前容器: docker container rm mycentos(提示: 这一步要确定删除容器没问题的情况下, 才可以做)

Ubuntu 16.04 阿里源


+deb-src http://archive.ubuntu.com/ubuntu xenial main restricted #Added by software-properties
+deb http://mirrors.aliyun.com/ubuntu/ xenial main restricted
+deb-src http://mirrors.aliyun.com/ubuntu/ xenial main restricted multiverse universe #Added by software-properties
+deb http://mirrors.aliyun.com/ubuntu/ xenial-updates main restricted
+deb-src http://mirrors.aliyun.com/ubuntu/ xenial-updates main restricted multiverse universe #Added by software-properties
+deb http://mirrors.aliyun.com/ubuntu/ xenial universe
+deb http://mirrors.aliyun.com/ubuntu/ xenial-updates universe
+deb http://mirrors.aliyun.com/ubuntu/ xenial multiverse
+deb http://mirrors.aliyun.com/ubuntu/ xenial-updates multiverse
+deb http://mirrors.aliyun.com/ubuntu/ xenial-backports main restricted universe multiverse
+deb-src http://mirrors.aliyun.com/ubuntu/ xenial-backports main restricted universe multiverse #Added by software-properties
+deb http://archive.canonical.com/ubuntu xenial partner
+deb-src http://archive.canonical.com/ubuntu xenial partner
+deb http://mirrors.aliyun.com/ubuntu/ xenial-security main restricted
+deb-src http://mirrors.aliyun.com/ubuntu/ xenial-security main restricted multiverse universe #Added by software-properties
+deb http://mirrors.aliyun.com/ubuntu/ xenial-security universe
+deb http://mirrors.aliyun.com/ubuntu/ xenial-security multiverse
+
+

pip 国内源

pip3 install django==2.1 -i https://pypi.tuna.tsinghua.edu.cn/simple

cd ; mkdir .config ; cd .config ; mkdir pip ; cd pip ; vim pip.conf

[global]
+timeout = 6000
+index-url = http://mirrors.aliyun.com/pypi/simple/
+trusted-host = mirrors.aliyun.com
+
+
`,13),t=[s];function d(u,c){return i(),n("div",null,t)}const o=e(a,[["render",d],["__file","docker.html.vue"]]);export{o as default}; diff --git a/assets/docker.html-oMuRRHsC.js b/assets/docker.html-oMuRRHsC.js new file mode 100644 index 0000000..5be92d0 --- /dev/null +++ b/assets/docker.html-oMuRRHsC.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-72251e04","path":"/notebook/docker.html","title":"2020/5/9 docKer 时区设置","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Ubuntu 16.04 阿里源","slug":"ubuntu-16-04-阿里源","link":"#ubuntu-16-04-阿里源","children":[]},{"level":2,"title":"pip 国内源","slug":"pip-国内源","link":"#pip-国内源","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/docker.md"}');export{e as data}; diff --git a/assets/drone.html-9R06-RAX.js b/assets/drone.html-9R06-RAX.js new file mode 100644 index 0000000..a75ba65 --- /dev/null +++ b/assets/drone.html-9R06-RAX.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-33996b77","path":"/ops/drone.html","title":"drone","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"docker缓存(优先使用)","slug":"docker缓存-优先使用","link":"#docker缓存-优先使用","children":[]},{"level":2,"title":"本地缓存","slug":"本地缓存","link":"#本地缓存","children":[{"level":3,"title":"npm cache","slug":"npm-cache","link":"#npm-cache","children":[]},{"level":3,"title":"yarn cache","slug":"yarn-cache","link":"#yarn-cache","children":[]}]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"ops/drone.md"}');export{e as data}; diff --git a/assets/drone.html-zUPidYWq.js b/assets/drone.html-zUPidYWq.js new file mode 100644 index 0000000..329231d --- /dev/null +++ b/assets/drone.html-zUPidYWq.js @@ -0,0 +1,119 @@ +import{_ as e,o as n,c as i,a as d}from"./app-x8p6wK6B.js";const s={},a=d(`

drone

下面的例子中,项目名假定为citest

缓存类型优点缺点
docker缓存"1. 可以缓存全过程,2. 不限于某个runner节点"需要构建并推送额外的docker镜像
本地缓存简单"1. 无法缓存构建过程(如yarn build)2. 只生效在单一runner节点"

docker缓存(优先使用)

不限制构建的类型,原理是基于docker cache加速执行过的构建。下面的例子中,会将所有的依赖文件打包成一个docker镜像进行加速: .drone.yml

kind: pipeline
+type: ssh
+name: ci 
+trigger:
+  ref:
+    include:
+      - refs/heads/v[0-9]*
+      - refs/tags/v[0-9]*
+server:
+  host:
+    from_secret: be_runner
+  user:
+    from_secret: runner_user
+  ssh_key:
+    from_secret: runner_key
+steps:
+  - name: build
+    commands:
+      - echo $DOCKER_PASSWORD | docker login dcr.xxx.com -u $DOCKER_USERNAME --password-stdin
+      - IMAGE_TAG=\${DRONE_TAG##*/} make docker-build
+    environment:
+      DOCKER_USERNAME:
+        from_secret: docker_username
+      DOCKER_PASSWORD:
+        from_secret: docker_password
+

先构建依赖库的镜像,再构建最终使用的镜像 Makefile

REGISTRY ?= dcr.xxx.com
+IMAGE_NAME ?= xxx/citest
+IMAGE_TAG ?= latest
+
+docker-build:
+        DOCKER_BUILDKIT=1 docker build . \\
+                --file Dockerfile.base \\
+                --tag \${REGISTRY}/\${IMAGE_NAME}:deps \\
+                --cache-from \${REGISTRY}/\${IMAGE_NAME}:deps \\
+                --build-arg BUILDKIT_INLINE_CACHE=1
+
+        DOCKER_BUILDKIT=1 docker build . \\
+                --file Dockerfile \\
+                --tag \${REGISTRY}/\${IMAGE_NAME}:\${IMAGE_TAG} \\
+                --cache-from \${REGISTRY}/\${IMAGE_NAME}:deps \\
+                --build-arg BUILDKIT_INLINE_CACHE=1
+

依赖库镜像的Dockerfile Dockerfile.base

FROM node:lts-bullseye as build
+WORKDIR /app
+COPY ./package.json ./yarn.lock /app/
+COPY ./src /app/src
+COPY ./public /app/public
+RUN yarn --registry=https://registry.npm.taobao.org
+RUN yarn build
+

最终业务用镜像的Dockerfile Dockerfile

FROM node:lts-bullseye as build
+WORKDIR /app
+COPY ./package.json ./yarn.lock /app/
+COPY ./src /app/src
+COPY ./public /app/public
+RUN yarn --registry=https://registry.npm.taobao.org
+RUN yarn build
+
+FROM nginx:stable-alpine-slim
+COPY --from=build /app/dist/ /usr/share/nginx/html/
+EXPOSE 80
+

本地缓存

可以用于缓存npm/yarn的依赖库文件,原理是将每次构建时使用的依赖库文件同步到主机的指定目录,然后下一次构建时先同步回来。该方案只能加速下载依赖文件的流程,每次都要重新build,因此如果build时间太久,建议尝试使用上面docker缓存的方案。

npm cache

.drone.yml

kind: pipeline
+type: exec
+name: ci 
+trigger:
+  ref:
+    include:
+      - refs/heads/v[0-9]*
+      - refs/tags/v[0-9]*
+steps:
+  - name: restore-cache
+    commands:
+      # npm cache,一般缓存到drone的工作目录下
+      - mkdir -p /data/cache/citest/node_modules
+      - rsync -a /data/cache/citest/node_modules .
+
+  - name: build
+    commands:
+     - export YARN_CACHE_FOLDER="~/.yarn/cache"
+     - npm install --registry=https://registry.npm.taobao.org
+     - npm build
+
+  - name: rebuild-cache
+    commands:
+      # npm cache
+      - rsync -a ./node_modules /data/cache/cicdtest/
+
+

yarn cache

.drone.yml

kind: pipeline
+type: exec
+name: ci 
+trigger:
+  ref:
+    include:
+      - refs/heads/v[0-9]*
+      - refs/tags/v[0-9]*
+steps:
+- name: prepare
+  commands:
+    - |
+      cat <<EOF >> .yarnrc.yml
+      # 启用全局cache
+      enableGlobalCache: true
+      EOF
+      
+  - name: restore-cache
+    commands:
+      # yarn cache,这里不区分项目,共同使用一个缓存目录
+      - mkdir -p /data/cache/.yarn
+      - rsync -a /data/cache/.yarn ~/
+
+  - name: build
+    commands:
+     - export YARN_CACHE_FOLDER="~/.yarn/cache"
+     - yarn --registry=https://registry.npmmirror.com/
+     - yarn build
+
+  - name: rebuild-cache
+    commands:
+      # yarn cache
+      - rsync -a ~/.yarn /data/cache/
+
`,20),l=[a];function r(c,v){return n(),i("div",null,l)}const m=e(s,[["render",r],["__file","drone.html.vue"]]);export{m as default}; diff --git a/assets/ffmpeg.html--o2PJUEg.js b/assets/ffmpeg.html--o2PJUEg.js new file mode 100644 index 0000000..99a7101 --- /dev/null +++ b/assets/ffmpeg.html--o2PJUEg.js @@ -0,0 +1,23 @@ +import{_ as e,o as i,c as t,a as s}from"./app-x8p6wK6B.js";const n={},a=s(`

ffmpeg

接入监控系统后, 就需要对这些视频做一定的处理,水星安防app提供的云服务有事件录像、人形识别等功能,大概一年90元, 我们肯定是不会掏这个钱的,所以就需要自己处理

第一个应用 制作延时摄像

  1. 从每日的太阳升起到日落,将越12小时的视频,快进到10分钟左右
ffmpeg  -hwaccel auto -i /Users/teletraan/Downloads/2023-10-10T11-15-01.mp4 -c:v libx265  -vf "setpts=0.02*PTS,scale=640:-1,fps=15" -b:v 500K -an -ss 00:00:00 -t 00:01:00 output.mp4
+

由于我们录像机设置的最大是15分钟,所以还需要拼接一下

15分钟要102秒,那么12小时就是4×102s×12 =

优化,直接用copy,就不用重新编码了

ffmpeg  -hwaccel auto -i /Users/teletraan/Downloads/2023-10-10T11-15-01.mp4 -c:v copy  -vf "setpts=0.02*PTS,scale=640:-1,fps=15" -b:v 500K -an -ss 00:00:00 -t 00:01:00 output.mp4
+

错误的,改了码率,不能这么搞

windows 将一个目录下的所有图片剪辑为视频

@echo off
+setlocal enabledelayedexpansion
+
+set "input_folder=%~dp0"
+set "output_file=output.mp4"
+set "framerate=30"
+set "codec=hevc_qsv"
+set "pix_fmt=yuv420p"
+set "filelist=filelist.txt"
+set "input_files="
+(for %%i in ("*.jpg") do (
+  echo file '%%i'
+)) > "%filelist%"
+
+
+
+e:/ffmpeg-master-latest-win64-gpl/bin/ffmpeg.exe -f concat -safe 0 -i  "%filelist%"  -framerate %framerate% -c:v %codec% -pix_fmt %pix_fmt% "%output_file%"
+
+pause
+
+
`,11),l=[a];function d(u,o){return i(),t("div",null,l)}const r=e(n,[["render",d],["__file","ffmpeg.html.vue"]]);export{r as default}; diff --git a/assets/ffmpeg.html-8fiVg3eC.js b/assets/ffmpeg.html-8fiVg3eC.js new file mode 100644 index 0000000..f5c1522 --- /dev/null +++ b/assets/ffmpeg.html-8fiVg3eC.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-24dac847","path":"/video/ffmpeg.html","title":"ffmpeg","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"第一个应用 制作延时摄像","slug":"第一个应用-制作延时摄像","link":"#第一个应用-制作延时摄像","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"video/ffmpeg.md"}');export{e as data}; diff --git "a/assets/graphql\345\222\214python.html-LZqXIs1X.js" "b/assets/graphql\345\222\214python.html-LZqXIs1X.js" new file mode 100644 index 0000000..cdf9ef7 --- /dev/null +++ "b/assets/graphql\345\222\214python.html-LZqXIs1X.js" @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-b1bba884","path":"/notebook/graphql/graphql%E5%92%8Cpython.html","title":"graphql和python","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/graphql/graphql和python.md"}');export{t as data}; diff --git "a/assets/graphql\345\222\214python.html-k8cAeIZm.js" "b/assets/graphql\345\222\214python.html-k8cAeIZm.js" new file mode 100644 index 0000000..da36419 --- /dev/null +++ "b/assets/graphql\345\222\214python.html-k8cAeIZm.js" @@ -0,0 +1,25 @@ +import{_ as e,o as r,c as t,a as o}from"./app-x8p6wK6B.js";const n={},p=o(`

graphql和python

  1. graphql 定义 这里没有id这个东西, type ProductionGroup{ "班组ID" id: String! "班组名称" name: String! "班组长" groupLeader: Staff! "班组成员" groupMembers: [Staff!]! "备注" remark: String }

input CreateProductionGroupInput { name: String! groupLeader: StringIDInput! groupMembers: [StringIDInput!]! remark: String }

  1. 创建的流程

2.1 前端传递 group_leader: {id:"p1"}

然后types中收到这个input, 内容和gql中定义的一样

process: {"id":"p1"}

2.2 这时,解析给app层mutation.py中定义的command

class CreateGroupCommand(Command): tenant_id: str name: str group_leader: StringIDInput group_members: list[StringIDInput] remark: str | None

这里是command和graphql定义一样,还有一种是内部全部使用id,那么在这里就需要进行一些别名,包括内部的所有(聚合根,实体,orm,Representation)都带上id group_id: StringIDInput | None = Field(alias='group')

2.3 app层拿到command, 解析,并处理,构建Group对象

class Group(AggregateRoot): id: GroupId name: str tenant_id: TenantId group_leader: StaffId group_members: list[StaffId] remark: str | None

2.4 然后通过repo,将对象转换为orm对象,并保存到db

class GroupOrm(Base, TenantMixin, SoftDeleteMixin, TimeMixin): tablename = "group" entity = Group

id = sa.Column(sa.String, primary_key=True)
+name = sa.Column(sa.String)
+group_leader = sa.Column(sa.String)
+# 班组成员,不包含班组长
+group_members = sa.Column(ARRAY(sa.String), server_default="{}")
+# 班组人员字段,班组人员 包含班组长以及班组成员
+group_staffs = sa.Column(ARRAY(sa.String), server_default="{}")
+remark = sa.Column(sa.String)
+
+@classmethod
+def from_entity(cls, entity: Group):
+    orm_instance = entity.orm_instance() or cls()  # type: ignore
+    orm_instance.copy_from_entity(entity)
+    orm_instance.group_staffs = entity.group_members + [entity.group_leader]
+    return orm_instance
+

就此,创建流程结束

3 查询 3.1前端构建查询input,发送到types,转发给app层的queryService,得到filter字典、offset、limit、order_by """ 问题,这里filter的graphql定义也是不带id的,所以前端传过来StringIdInput,我们的filter类中,应当这样编写 """ class SectionFilter(FilterBase): search: str = FilterField(expression=lambda v: SectionOrm.name.like(f"%{v}%")) name: str = FilterField(column=SectionOrm.name) tenant_id: str = FilterField(column=SectionOrm.tenant_id) process: StringIDInput = FilterField(expression=lambda v: SectionOrm.process_ids.contains([v])) is_deleted: bool = FilterField(False, expression=lambda v: SectionOrm.is_deleted.is_(v))

3.2queryService 直接查询orm,并使用Representation返回给前端

class GroupRepresentation(Representation): id: str name: str group_leader: str group_members: list[str] remark: str | None

3.3 到达graphql层,controller根据types里的resolve,将对象进行解析,处理后返回给客户端

@managed() @dataclass class GroupType(ObjectType): name = "ProductionGroup"

@field_resolver("groupLeader")
+async def resolve_group_leader(self, parent: GroupRepresentation, info: GraphQLResolveInfo):
+    group_leader_id = get_attr(parent, "group_leader")
+    return {"id": group_leader_id}
+
+@field_resolver("groupMembers")
+async def resolve_group_members(self, parent: GroupRepresentation, info: GraphQLResolveInfo):
+    group_members = get_attr(parent, "group_members")
+    return [{"id": member_id} for member_id in group_members]
+
`,22),a=[p];function i(s,u){return r(),t("div",null,a)}const m=e(n,[["render",i],["__file","graphql和python.html.vue"]]);export{m as default}; diff --git "a/assets/graphql\351\201\207\345\210\260\350\277\207\347\232\204\351\227\256\351\242\230.html-HT1ruz5l.js" "b/assets/graphql\351\201\207\345\210\260\350\277\207\347\232\204\351\227\256\351\242\230.html-HT1ruz5l.js" new file mode 100644 index 0000000..2ce09e9 --- /dev/null +++ "b/assets/graphql\351\201\207\345\210\260\350\277\207\347\232\204\351\227\256\351\242\230.html-HT1ruz5l.js" @@ -0,0 +1 @@ +const a=JSON.parse('{"key":"v-67e92c6d","path":"/notebook/graphql/graphql%E9%81%87%E5%88%B0%E8%BF%87%E7%9A%84%E9%97%AE%E9%A2%98.html","title":"graphql遇到过的问题","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"1.schema编写问题","slug":"_1-schema编写问题","link":"#_1-schema编写问题","children":[]},{"level":2,"title":"2.dataload 问题","slug":"_2-dataload-问题","link":"#_2-dataload-问题","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/graphql/graphql遇到过的问题.md"}');export{a as data}; diff --git "a/assets/graphql\351\201\207\345\210\260\350\277\207\347\232\204\351\227\256\351\242\230.html-jjLgDvV-.js" "b/assets/graphql\351\201\207\345\210\260\350\277\207\347\232\204\351\227\256\351\242\230.html-jjLgDvV-.js" new file mode 100644 index 0000000..cb8130c --- /dev/null +++ "b/assets/graphql\351\201\207\345\210\260\350\277\207\347\232\204\351\227\256\351\242\230.html-jjLgDvV-.js" @@ -0,0 +1,18 @@ +import{_ as n,o as s,c as a,a as t}from"./app-x8p6wK6B.js";const p="/assets/514935909278883-YU9p5snK.png",e="/assets/27510892836406-L9knP75y.png",o={},c=t(`

graphql遇到过的问题

1.schema编写问题

正常情况下,需要在冒号右边加一个空格

type XXX{
+    
+    required: Boolean
+}
+
+

如果你不加的话,则会识别不到

http://spec.graphql.org/October2021/#sec-Language

2.dataload 问题

当有一个数据的resolve字段没查到,则所有的数据都不会返回

async def scheme_by_scheme_ids(self, scheme_ids: list[str]):
+    async with self.repo.new_session(expire_on_commit=False):
+        stmt = self.repo.select(MESSchemeOrm).filter(MESSchemeOrm.scheme_id.in_(scheme_ids))
+        result = await self.repo.all(stmt)
+        data = result.scalars().all()
+    return sort(scheme_ids, data, key_fn=attrgetter("scheme_id"))
+
@field_resolver("scheme")
+async def resolve_scheme(self, parent: ProcessRepresentation, info):
+    if process_id := get_attr(parent, "id"):
+        process_scheme_id = SchemeId(f"scheme:process:info:{process_id}")
+        loader = info.context["domain_loaders"]["scheme_by_scheme_ids"]
+        return await loader.load(process_scheme_id)
+
`,11),l=[c];function i(u,r){return s(),a("div",null,l)}const k=n(o,[["render",i],["__file","graphql遇到过的问题.html.vue"]]);export{k as default}; diff --git a/assets/index.html-1OhrB_6n.js b/assets/index.html-1OhrB_6n.js new file mode 100644 index 0000000..815960b --- /dev/null +++ b/assets/index.html-1OhrB_6n.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-ce20e166","path":"/video/","title":"这里是video","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"video/README.md"}');export{e as data}; diff --git a/assets/index.html-AndxTJYq.js b/assets/index.html-AndxTJYq.js new file mode 100644 index 0000000..9665092 --- /dev/null +++ b/assets/index.html-AndxTJYq.js @@ -0,0 +1 @@ +import{_ as t,o,c as s,b as e,d as a}from"./app-x8p6wK6B.js";const c={},n=e("h1",{id:"这里是ops",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#这里是ops","aria-hidden":"true"},"#"),a(" 这里是ops")],-1),r=[n];function d(_,i){return o(),s("div",null,r)}const l=t(c,[["render",d],["__file","index.html.vue"]]);export{l as default}; diff --git a/assets/index.html-BjbYssGN.js b/assets/index.html-BjbYssGN.js new file mode 100644 index 0000000..25de16f --- /dev/null +++ b/assets/index.html-BjbYssGN.js @@ -0,0 +1 @@ +import{_ as t,o as c,c as n,b as e,d as o}from"./app-x8p6wK6B.js";const a={},r=e("h1",{id:"这里是python-cv",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#这里是python-cv","aria-hidden":"true"},"#"),o(" 这里是python/cv")],-1),s=[r];function d(_,h){return c(),n("div",null,s)}const l=t(a,[["render",d],["__file","index.html.vue"]]);export{l as default}; diff --git a/assets/index.html-D-QLn7gm.js b/assets/index.html-D-QLn7gm.js new file mode 100644 index 0000000..9efaf89 --- /dev/null +++ b/assets/index.html-D-QLn7gm.js @@ -0,0 +1 @@ +import{_ as o,o as t,c as n,b as e,d as a}from"./app-x8p6wK6B.js";const c={},r=e("h1",{id:"这里是notebook",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#这里是notebook","aria-hidden":"true"},"#"),a(" 这里是notebook")],-1),s=[r];function d(_,i){return t(),n("div",null,s)}const l=o(c,[["render",d],["__file","index.html.vue"]]);export{l as default}; diff --git a/assets/index.html-GZKm3Qsm.js b/assets/index.html-GZKm3Qsm.js new file mode 100644 index 0000000..d8af3eb --- /dev/null +++ b/assets/index.html-GZKm3Qsm.js @@ -0,0 +1 @@ +import{_ as t,o as a,c,b as e,d as n}from"./app-x8p6wK6B.js";const o={},r=e("h1",{id:"这里是web",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#这里是web","aria-hidden":"true"},"#"),n(" 这里是web")],-1),s=[r];function d(_,i){return a(),c("div",null,s)}const l=t(o,[["render",d],["__file","index.html.vue"]]);export{l as default}; diff --git a/assets/index.html-JFy8A48P.js b/assets/index.html-JFy8A48P.js new file mode 100644 index 0000000..4500ca2 --- /dev/null +++ b/assets/index.html-JFy8A48P.js @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-17af9222","path":"/python/cv/","title":"这里是python/cv","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"python/cv/README.md"}');export{t as data}; diff --git a/assets/index.html-TThl94CJ.js b/assets/index.html-TThl94CJ.js new file mode 100644 index 0000000..ddade72 --- /dev/null +++ b/assets/index.html-TThl94CJ.js @@ -0,0 +1 @@ +import{_ as o,o as t,c as a,b as e,d as n}from"./app-x8p6wK6B.js";const r={},c=e("h1",{id:"这里是notebook-graphql",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#这里是notebook-graphql","aria-hidden":"true"},"#"),n(" 这里是notebook/graphql")],-1),s=[c];function d(_,h){return t(),a("div",null,s)}const l=o(r,[["render",d],["__file","index.html.vue"]]);export{l as default}; diff --git a/assets/index.html-TX7mQu1p.js b/assets/index.html-TX7mQu1p.js new file mode 100644 index 0000000..36a190f --- /dev/null +++ b/assets/index.html-TX7mQu1p.js @@ -0,0 +1 @@ +import{_ as t,o as r,c as o,b as e,d as a}from"./app-x8p6wK6B.js";const c={},n=e("h1",{id:"这里是router",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#这里是router","aria-hidden":"true"},"#"),a(" 这里是router")],-1),s=[n];function d(_,i){return r(),o("div",null,s)}const l=t(c,[["render",d],["__file","index.html.vue"]]);export{l as default}; diff --git a/assets/index.html-WtnzvEI5.js b/assets/index.html-WtnzvEI5.js new file mode 100644 index 0000000..5377261 --- /dev/null +++ b/assets/index.html-WtnzvEI5.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-68c3eedb","path":"/notebook/","title":"这里是notebook","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/README.md"}');export{e as data}; diff --git a/assets/index.html-biE9myrq.js b/assets/index.html-biE9myrq.js new file mode 100644 index 0000000..a21502c --- /dev/null +++ b/assets/index.html-biE9myrq.js @@ -0,0 +1 @@ +import{_ as t,o as n,c as o,b as e,d as a}from"./app-x8p6wK6B.js";const c={},r=e("h1",{id:"这里是python",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#这里是python","aria-hidden":"true"},"#"),a(" 这里是python")],-1),s=[r];function d(_,h){return n(),o("div",null,s)}const l=t(c,[["render",d],["__file","index.html.vue"]]);export{l as default}; diff --git a/assets/index.html-j6pj97yD.js b/assets/index.html-j6pj97yD.js new file mode 100644 index 0000000..544cb9a --- /dev/null +++ b/assets/index.html-j6pj97yD.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-744e6dd4","path":"/web/","title":"这里是web","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"web/README.md"}');export{e as data}; diff --git a/assets/index.html-oabfFboZ.js b/assets/index.html-oabfFboZ.js new file mode 100644 index 0000000..41e9514 --- /dev/null +++ b/assets/index.html-oabfFboZ.js @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-744af636","path":"/ops/","title":"这里是ops","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"ops/README.md"}');export{t as data}; diff --git a/assets/index.html-okFbtMfA.js b/assets/index.html-okFbtMfA.js new file mode 100644 index 0000000..dc1785d --- /dev/null +++ b/assets/index.html-okFbtMfA.js @@ -0,0 +1 @@ +import{_ as t,o,c as a,b as e,d as c}from"./app-x8p6wK6B.js";const d={},n=e("h1",{id:"这里是video",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#这里是video","aria-hidden":"true"},"#"),c(" 这里是video")],-1),r=[n];function s(i,_){return o(),a("div",null,r)}const l=t(d,[["render",s],["__file","index.html.vue"]]);export{l as default}; diff --git a/assets/index.html-qTwyPiP-.js b/assets/index.html-qTwyPiP-.js new file mode 100644 index 0000000..7e33379 --- /dev/null +++ b/assets/index.html-qTwyPiP-.js @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-86c67626","path":"/router/","title":"这里是router","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"router/README.md"}');export{t as data}; diff --git a/assets/index.html-rVR--s9I.js b/assets/index.html-rVR--s9I.js new file mode 100644 index 0000000..7df2083 --- /dev/null +++ b/assets/index.html-rVR--s9I.js @@ -0,0 +1 @@ +import{_ as o,o as t,c as n,b as e,d as a}from"./app-x8p6wK6B.js";const c={},d=e("h1",{id:"这里是notebook-3d建模",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#这里是notebook-3d建模","aria-hidden":"true"},"#"),a(" 这里是notebook/3D建模")],-1),r=[d];function s(_,i){return t(),n("div",null,r)}const l=o(c,[["render",s],["__file","index.html.vue"]]);export{l as default}; diff --git a/assets/index.html-vBYbJktd.js b/assets/index.html-vBYbJktd.js new file mode 100644 index 0000000..ad79bf2 --- /dev/null +++ b/assets/index.html-vBYbJktd.js @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-7181ad41","path":"/notebook/graphql/","title":"这里是notebook/graphql","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/graphql/README.md"}');export{t as data}; diff --git a/assets/index.html-wkt_QydO.js b/assets/index.html-wkt_QydO.js new file mode 100644 index 0000000..98369ac --- /dev/null +++ b/assets/index.html-wkt_QydO.js @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-211fff28","path":"/notebook/3D%E5%BB%BA%E6%A8%A1/","title":"这里是notebook/3D建模","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/3D建模/README.md"}');export{t as data}; diff --git a/assets/index.html-yNSHZEOF.js b/assets/index.html-yNSHZEOF.js new file mode 100644 index 0000000..910a981 --- /dev/null +++ b/assets/index.html-yNSHZEOF.js @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-63cd5dba","path":"/python/","title":"这里是python","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"python/README.md"}');export{t as data}; diff --git a/assets/k2p-luci.html-WodZTAGg.js b/assets/k2p-luci.html-WodZTAGg.js new file mode 100644 index 0000000..2f8240f --- /dev/null +++ b/assets/k2p-luci.html-WodZTAGg.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-0e6ec2eb","path":"/notebook/k2p-luci.html","title":"k2p-luci","lang":"en-US","frontmatter":{},"headers":[{"level":3,"title":"2022/6/1","slug":"_2022-6-1","link":"#_2022-6-1","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/k2p-luci.md"}');export{e as data}; diff --git a/assets/k2p-luci.html-t_XdYGXg.js b/assets/k2p-luci.html-t_XdYGXg.js new file mode 100644 index 0000000..7a5a9ea --- /dev/null +++ b/assets/k2p-luci.html-t_XdYGXg.js @@ -0,0 +1,10 @@ +import{_ as e,o as i,c as t,a as s}from"./app-x8p6wK6B.js";const a="/assets/20220207015340394_10855-WkKd7zDr.png",n="/assets/20220207020455741_14423-0hzHeQzp.png",l="/assets/20220601115731928_9728-YPmom_hm.png",p="/assets/20220601113611092_2486-dyOpFLRl.png",c="/assets/20220601135116316_3391-aO04G6Ii.png",d={},r=s('

k2p-luci

20220206 今天发现k2p的后台管理web一些功能无法使用了

为了修复这个问题,先对路由器上的web程序做了一下了解

后台服务器:uhttp 语言 lua

root@K2P:/# find  . -type d -iname 'luci'
+./rom/usr/lib/lua/luci
+./usr/lib/lua/luci
+

https://blog.csdn.net/qq_28812525/article/details/103870169

find / -type f -name "*.lua" | xargs grep "portfwd_add_rule" 配置文件:

/etc/luci/*
+/etc/init.d/portfwd 端口转发的配置转换
+/etc/config/appportfwd 
+
+
+iptables -L -v -n
+

2022/6/1

k2p动态ip失效

鸟哥的私房菜 http://cn.linux.vbird.org/linux_server/0250simple_firewall_5.php#nat_ip_share

iptables -t nat -A PREROUTING -i pppoe-wan -p tcp --dport 36000 -j DNAT --to-destination 192.168.2.190:22

iptables -t nat -L

',17),o=[r];function u(_,m){return i(),t("div",null,o)}const b=e(d,[["render",u],["__file","k2p-luci.html.vue"]]);export{b as default}; diff --git "a/assets/k2p_\346\233\264\346\226\260\345\256\230\346\224\271\345\233\272\344\273\266v1.9\344\270\255\347\232\204ssr-server.html-b_u5zeQ6.js" "b/assets/k2p_\346\233\264\346\226\260\345\256\230\346\224\271\345\233\272\344\273\266v1.9\344\270\255\347\232\204ssr-server.html-b_u5zeQ6.js" new file mode 100644 index 0000000..0aa81c4 --- /dev/null +++ "b/assets/k2p_\346\233\264\346\226\260\345\256\230\346\224\271\345\233\272\344\273\266v1.9\344\270\255\347\232\204ssr-server.html-b_u5zeQ6.js" @@ -0,0 +1,18 @@ +import{_ as s,o as e,c as t,a as i}from"./app-x8p6wK6B.js";const r="/assets/20220219222138020_909483616-DU3bFCqD.png",a="/assets/20220219222408266_2050018413-nSRpEmm5.png",p="/assets/20220219222636498_431834823-VNfMIq1D.png",c="/assets/20220219223839876_1500626948-s2_6NsQS.png",n="/assets/20220219223947700_989164668-_tlZGLdw.png",o="/assets/20220219224108809_1219663649-55uQuf5E.png",l="/assets/20220220001302388_1155538128-6X_Vxzk2.png",d="/assets/20220220001455371_1434697475-YC2uc6mo.png",m="/assets/20220220001811914_1014073809-MAyRD0ce.png",_="/assets/20220220001907411_1108285271-UpI37-ty.png",v="/assets/20220220002310307_1824879266-Uqw-Hsmf.png",g="/assets/20220220002509061_384377208-Vd2BzHf4.png",h="/assets/20220220003025856_596924680-kf1XdrQ2.png",u="/assets/20220220013115494_1616981623-MFQ5NXol.png",b={},k=i('

[k2p]更新官改固件v1.9中的ssr-server

目标:在k2p路由器上搭建ssr-server,在外网可以访问到家中的设备

遇到的问题:k2p官改固件v1.9 使用的ssr-server版本是shadowsocks-libev 2.5.6 with OpenSSL 1.0.1j 15 Oct 2014,支持的加密协议比较少

网络上比较推荐的加密算法是aes-256-gcm,打算更新路由器上的ssr-server

先到github https://github.com/shadowsocks/shadowsocks-libev 需要我们需要的安装包

root@K2P:~# cat /proc/version
+Linux version 3.10.14 (jenkins@SOHO-OPWRT) (gcc version 4.8.3 (OpenWrt/Linaro GCC 4.8-2014.04 unknown) ) #1 SMP Fri Apr 20 15:17:54 CST 2018
+

通过上面的命令,我们可以知道k2p官改是openwrt系列的系统,找到适用于openwrt的版本 https://github.com/shadowsocks/openwrt-shadowsocks

这个项目提供了预编译文件下载,我们到releases页面,进行下载 http://openwrt-dist.sourceforge.net/archives/shadowsocks-libev/3.3.5-1/

然后查看k2p的架构,我的k2p是a2版本,cpu是mt6621a,架构为mips 1004kc

但是我们并没有找到适合1004kc的软件包

经过google搜索,我在恩山无线论坛找到了解决方案:使用mips 24kc即可,是兼容的 https://www.right.com.cn/forum/thread-256669-1-1.html

使用wget 下载到/tmp目录后,我们使用opkg install shadowsocks-libev-server_3.3.5-1_ramips_24kec.ipk命令进行安装,发现opkg报错:pkg_hash_fetch_best_installation_candidate: Packages for shadowsocks-libev-server found, but incompatible with the architectures configured

这是因为opkg发现此安装包声明的架构与系统支持的架构不符,我们使用opkg print-architecture命令输出该系统支持的安装包

可以看到没有ramips_24kc

经google搜索,找到了解决方案

https://www.twblogs.net/a/5c766b60bd9eee339917f838 http://iotts.com.cn/blog/2020/12/13/OpenWrt-%E6%89%8B%E5%8A%A8%E5%AE%89%E8%A3%85ipk%E6%97%B6%E9%81%87%E5%88%B0%E7%9A%84%E9%97%AE%E9%A2%98/ https://blog.csdn.net/zengqz123/article/details/87915079


+vi /etc/opkg.conf
+然后在这个文件后面依次添加
+arch all 100
+arch ramips 150
+arch ramips_24kec 200
+arch ramips_1004kc 300
+

ok,再次尝试安装,发现缺少依赖

回到下载页面 http://openwrt-dist.sourceforge.net/archives/shadowsocks-libev/3.3.5-1/legacy/ramips/ 其实都在这里

wget http://openwrt-dist.sourceforge.net/archives/shadowsocks-libev/3.3.5-1/legacy/ramips/libev_4.27-1_ramips_24kec.ipk
+wget http://openwrt-dist.sourceforge.net/archives/shadowsocks-libev/3.3.5-1/legacy/ramips/libcares_1.15.0-4_ramips_24kec.ipk
+wget http://openwrt-dist.sourceforge.net/archives/shadowsocks-libev/3.3.5-1/legacy/ramips/libsodium_1.0.18-1_ramips_24kec.ipk
+wget http://openwrt-dist.sourceforge.net/archives/shadowsocks-libev/3.3.5-1/legacy/ramips/libmbedtls_2.9.0-2_ramips_24kec.ipk
+
+

安装成功

后面的错误信息其实无影响,安装后,可通过opkg查看文件信息

root@K2P:/tmp# opkg files shadowsocks-libev-server
+Package shadowsocks-libev-server (3.3.5-1) is installed on root and has the following files:
+/usr/bin/ss-server
+

安装成功!,aes-256-gcm可用

opkg命令(https://www.cxymm.net/article/qq_41453285/102523263) 修改opkg.conf (https://www.twblogs.net/a/5c766b60bd9eee339917f838) openwrt翻墙教程 https://fanqiang.software-download.name/

https://me2in.github.io/2020/11/30/%E5%9B%9E%E5%AE%B6%E7%9A%84%E8%AF%B1%E6%83%91-%E8%AE%BA%E5%A6%82%E4%BD%95%E6%9B%B4%E4%BC%98%E9%9B%85%E7%9A%84%E5%9B%9E%E5%AE%B6/

clash for windows https://docs.cfw.lbyczf.com/

cfw默认跳过内网地址

',39),w=[k];function f(E,x){return e(),t("div",null,w)}const B=s(b,[["render",f],["__file","k2p_更新官改固件v1.9中的ssr-server.html.vue"]]);export{B as default}; diff --git "a/assets/k2p_\346\233\264\346\226\260\345\256\230\346\224\271\345\233\272\344\273\266v1.9\344\270\255\347\232\204ssr-server.html-myu_DXA5.js" "b/assets/k2p_\346\233\264\346\226\260\345\256\230\346\224\271\345\233\272\344\273\266v1.9\344\270\255\347\232\204ssr-server.html-myu_DXA5.js" new file mode 100644 index 0000000..24af999 --- /dev/null +++ "b/assets/k2p_\346\233\264\346\226\260\345\256\230\346\224\271\345\233\272\344\273\266v1.9\344\270\255\347\232\204ssr-server.html-myu_DXA5.js" @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-50f44d9a","path":"/notebook/k2p_%E6%9B%B4%E6%96%B0%E5%AE%98%E6%94%B9%E5%9B%BA%E4%BB%B6v1.9%E4%B8%AD%E7%9A%84ssr-server.html","title":"[k2p]更新官改固件v1.9中的ssr-server","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/[k2p]更新官改固件v1.9中的ssr-server.md"}');export{e as data}; diff --git a/assets/k8s.html-LyXLVnMP.js b/assets/k8s.html-LyXLVnMP.js new file mode 100644 index 0000000..024e3da --- /dev/null +++ b/assets/k8s.html-LyXLVnMP.js @@ -0,0 +1 @@ +const l=JSON.parse('{"key":"v-57d5a7e9","path":"/ops/k8s.html","title":"k8s","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"alias k8s","slug":"alias-k8s","link":"#alias-k8s","children":[{"level":3,"title":"问题定位","slug":"问题定位","link":"#问题定位","children":[]},{"level":3,"title":"解决方案1","slug":"解决方案1","link":"#解决方案1","children":[]},{"level":3,"title":"解决方案2","slug":"解决方案2","link":"#解决方案2","children":[]}]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"ops/k8s.md"}');export{l as data}; diff --git a/assets/k8s.html-buAOIcob.js b/assets/k8s.html-buAOIcob.js new file mode 100644 index 0000000..6e13462 --- /dev/null +++ b/assets/k8s.html-buAOIcob.js @@ -0,0 +1 @@ +import{_ as e,o as a,c as o,a as t}from"./app-x8p6wK6B.js";const s={},c=t('

k8s

alias k8s

为了方便查看日志,编写了一个alias

alias klmes="kubectl logs -f kubectl get pods | grep '^mes-be' | grep 'Running' -m 1 | awk '{print $1}'"

但是在断网环境下打开新终端,发现zsh会尝试运行该命令, 在网络不通环境下打开新终端,则会导致终端卡死

问题定位

经过多次尝试,我编写了一个二进制程序echo222, 放在/usr/local/bin/下, 并编写了如下的alias

alias ee="echo222"

经测试,没有执行该语句

再次编写为

alias ee="echo echo222" 经测试,执行了双引情况下号下,``(反引号)包裹的语句,

再测试下单引号 alias ee='echo echo222' 经测试,问题解决

解决方案1

使用函数

klmes () { kubectl logs -f kubectl get pods | grep '^mes-be' | grep 'Running' -m 1 | awk '{print $1}' }

解决方案2

https://stackoverflow.com/questions/1250079/how-to-escape-single-quotes-within-single-quoted-strings

使用单引号包住 alias klmes='kubectl logs -f $(kubectl get pods | grep "^mes-be" | grep "Running" -m 1 | awk '"'"'{print $1}'"'"')'

',18),i=[c];function r(d,n){return a(),o("div",null,i)}const p=e(s,[["render",r],["__file","k8s.html.vue"]]);export{p as default}; diff --git a/assets/kodi.html-9pUgXDHi.js b/assets/kodi.html-9pUgXDHi.js new file mode 100644 index 0000000..3fde713 --- /dev/null +++ b/assets/kodi.html-9pUgXDHi.js @@ -0,0 +1 @@ +import{_ as n,r as o,o as r,c as h,b as t,d as l,e,a as s}from"./app-x8p6wK6B.js";const i={},a=t("h1",{id:"kodi",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#kodi","aria-hidden":"true"},"#"),l(" kodi")],-1),_=t("p",null,"打造家庭影院",-1),u=t("p",null,"NAS",-1),c=t("blockquote",null,[t("p",null,"NAS(Network Attached Storage:网络附属存储)按字面简单说就是连接在网络上,具备资料存储功能的装置,因此也称为“网络存储器”。它是一种专用数据存储服务器。它以数据为中心,将存储设备与服务器彻底分离,集中管理数据,从而释放带宽、提高性能、降低总拥有成本、保护投资。其成本远远低于使用服务器存储,而效率却远远高于后者。目前国际著名的NAS企业有Netapp、EMC、OUO等。")],-1),p=t("p",null,"HTPC",-1),m=t("blockquote",null,[t("p",null,"HTPC(Home Theater Personal Computer),即家庭影院电脑。 是以计算机担当信号源和控制的家庭影院,也就是一部预装了各种多媒体解码播放软件,可用来对应播放各种影音媒体,并具有各种接口,可与多种显示设备如电视机、投影机、等离子显示器、音频解码器、音频放大器等音频数字设备连接使用的个人电脑。")],-1),f={href:"https://kodi.tv/",target:"_blank",rel:"noopener noreferrer"},b=s('

家庭网络

品名价格功能备注时间
斐讯K2P¥150做路由,wifi,拨号挂v2ray
联通光猫300M网速
TCL 65v62999看电视,播放电影支持memc2019.10.3
电脑1200下载机器,htpc2020.1.2
斐讯N1盒子130刷yyf, 使用, kodi,千兆网口, usb2.02020.2.20
斐讯H1移动硬盘230移动存储,做N1盒子上面的存储type-c接口,usb3.02020.2.21

场景需求

  • [x] 玩游戏: 显示器hdmi线连接客厅电视,或者游戏机
  • [ ] 看视频: 电视内置软件, 投屏, kodi,
  • [ ] 照片备份:

我不在家

  • 使用HDP直播等软件播放CCTV等节目
  • 手机投屏(乐播投屏)

我在家

  • 使用远程下载下载到硬盘, 然后观看
  • 同步照片
  • 作为服务器,通过frp做远程服务器

插线板

名字价格功能
斐讯 tc1¥656 插口, 3usb(1*18w)
心水: 紫米插座1291个pd65w快充的插口+插线版

电脑

',11),k=t("thead",null,[t("tr",null,[t("th",null,"配件"),t("th",null,"型号"),t("th",null,"价格"),t("th",null,"备注"),t("th",null,"时间")])],-1),g=t("tr",null,[t("td",null,"cpu"),t("td",null,"g5500"),t("td",null,"¥200"),t("td",null,"二手"),t("td")],-1),x=t("td",null,"主板",-1),N={href:"https://detail.tmall.com/item.htm?id=602434722635",target:"_blank",rel:"noopener noreferrer"},y=t("td",null,"¥300",-1),C=t("td",null,"千兆",-1),v=t("td",null,null,-1),T=t("td",null,"内存",-1),w={href:"https://item.jd.com/100004880772.html",target:"_blank",rel:"noopener noreferrer"},H=t("td",null,"¥169",-1),P=t("td",null,null,-1),S=t("td",null,null,-1),V=t("td",null,"固态",-1),j={href:"https://detail.tmall.com/item.htm?id=575347597660",target:"_blank",rel:"noopener noreferrer"},A=t("td",null,"¥119",-1),E=t("td",null,null,-1),B=t("td",null,null,-1),L=t("tr",null,[t("td",null,"硬盘"),t("td",null,"西数蓝盘500g"),t("td",null,"¥0"),t("td"),t("td")],-1),q=t("td",null,"鼠标&键盘",-1),I={href:"https://item.jd.com/2291748.html",target:"_blank",rel:"noopener noreferrer"},M=t("td",null,"¥60",-1),O=t("td",null,null,-1),D=t("td",null,null,-1),K=t("td",null,"机箱",-1),U={href:"https://item.jd.com/100004160506.html",target:"_blank",rel:"noopener noreferrer"},z=t("td",null,"¥135",-1),F=t("td",null,null,-1),G=t("td",null,null,-1),J=t("td",null,"散热器",-1),Q={href:"https://item.jd.com/164112.html",target:"_blank",rel:"noopener noreferrer"},R=t("td",null,"¥32",-1),W=t("td",null,null,-1),X=t("td",null,null,-1),Y=t("td",null,"电源",-1),Z={href:"https://detail.tmall.com/item.htm?id=534193757651",target:"_blank",rel:"noopener noreferrer"},$=t("td",null,"¥99",-1),tt=t("td",null,null,-1),lt=t("td",null,null,-1),dt=t("tr",null,[t("td",null,"合计"),t("td"),t("td",null,"¥1133"),t("td"),t("td")],-1),et=t("p",null,"|设备|",-1);function nt(ot,rt){const d=o("ExternalLinkIcon");return r(),h("div",null,[a,_,u,c,p,m,t("p",null,[t("a",f,[l("官网链接"),e(d)])]),b,t("table",null,[k,t("tbody",null,[g,t("tr",null,[x,t("td",null,[t("a",N,[l("h310cm-hdv"),e(d)])]),y,C,v]),t("tr",null,[T,t("td",null,[t("a",w,[l("光威8g 2666"),e(d)])]),H,P,S]),t("tr",null,[V,t("td",null,[t("a",j,[l("铁甲战将120g"),e(d)])]),A,E,B]),L,t("tr",null,[q,t("td",null,[t("a",I,[l("罗技套装 mk275"),e(d)])]),M,O,D]),t("tr",null,[K,t("td",null,[t("a",U,[l("先马 黑金刚"),e(d)])]),z,F,G]),t("tr",null,[J,t("td",null,[t("a",Q,[l("超频三 红海"),e(d)])]),R,W,X]),t("tr",null,[Y,t("td",null,[t("a",Z,[l("金河田 300w"),e(d)])]),$,tt,lt]),dt])]),et])}const st=n(i,[["render",nt],["__file","kodi.html.vue"]]);export{st as default}; diff --git a/assets/kodi.html-o4IVGQ1p.js b/assets/kodi.html-o4IVGQ1p.js new file mode 100644 index 0000000..3af7ad4 --- /dev/null +++ b/assets/kodi.html-o4IVGQ1p.js @@ -0,0 +1 @@ +const l=JSON.parse('{"key":"v-67adb115","path":"/notebook/kodi.html","title":"kodi","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"家庭网络","slug":"家庭网络","link":"#家庭网络","children":[]},{"level":2,"title":"场景需求","slug":"场景需求","link":"#场景需求","children":[]},{"level":2,"title":"我不在家","slug":"我不在家","link":"#我不在家","children":[]},{"level":2,"title":"我在家","slug":"我在家","link":"#我在家","children":[]},{"level":2,"title":"插线板","slug":"插线板","link":"#插线板","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/kodi.md"}');export{l as data}; diff --git "a/assets/linux\345\205\263\351\227\255\350\256\277\351\227\256\346\227\245\345\277\227\345\217\212mysql.html-24tVYX00.js" "b/assets/linux\345\205\263\351\227\255\350\256\277\351\227\256\346\227\245\345\277\227\345\217\212mysql.html-24tVYX00.js" new file mode 100644 index 0000000..a98bccb --- /dev/null +++ "b/assets/linux\345\205\263\351\227\255\350\256\277\351\227\256\346\227\245\345\277\227\345\217\212mysql.html-24tVYX00.js" @@ -0,0 +1 @@ +const l=JSON.parse('{"key":"v-c65efaa2","path":"/notebook/linux%E5%85%B3%E9%97%AD%E8%AE%BF%E9%97%AE%E6%97%A5%E5%BF%97%E5%8F%8Amysql.html","title":"日志","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"关闭.bash_history","slug":"关闭-bash-history","link":"#关闭-bash-history","children":[]},{"level":2,"title":"关闭mysql连接日志","slug":"关闭mysql连接日志","link":"#关闭mysql连接日志","children":[]},{"level":2,"title":"关闭SSH日志","slug":"关闭ssh日志","link":"#关闭ssh日志","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/linux关闭访问日志及mysql.md"}');export{l as data}; diff --git "a/assets/linux\345\205\263\351\227\255\350\256\277\351\227\256\346\227\245\345\277\227\345\217\212mysql.html-amzU4nG6.js" "b/assets/linux\345\205\263\351\227\255\350\256\277\351\227\256\346\227\245\345\277\227\345\217\212mysql.html-amzU4nG6.js" new file mode 100644 index 0000000..488a0a4 --- /dev/null +++ "b/assets/linux\345\205\263\351\227\255\350\256\277\351\227\256\346\227\245\345\277\227\345\217\212mysql.html-amzU4nG6.js" @@ -0,0 +1,3 @@ +import{_ as t,r as a,o as l,c as o,b as e,d as n,e as r,a as i}from"./app-x8p6wK6B.js";const c={},d=i(`

日志

关闭.bash_history

已经在Ubuntu 16.04.6 LTS验证有效

我们可以修改/etc/profile文件中修改2个参数来控制历史命令记录和输出。

echo "export HISTFILESIZE=0" >> /etc/profile
+source /etc/profile
+
  1. https://www.cndba.cn/dave/article/4086
  2. https://blog.csdn.net/smasegain/article/details/46678113

关闭mysql连接日志

  1. ~/.mysql_history

https://www.cnblogs.com/milantgh/p/3602206.html

如何关闭MySQL的日志功能:删除日志:执行:/usr/local/mysql/bin/mysql -u root -p 输入密码登录后再执行:reset master; 再输入:quit 退出mysql命令模式。 彻底禁用MySQL日志:修改/etc/my.cnf 文件, 找到log-bin搜索=mysql-binbinlog_format=mixed再这两行前面加上#, 将其注释掉,再执行/etc/init.d/mysql restart即可。 或直接去目录/usr/local/mysql/var/删除日志文件即可正常使用! ———————————————— 版权声明:本文为CSDN博主「风火程序员」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/phpfenghuo/article/details/42262031

编辑 /etc/mysql/mysql.conf.d/mysqld.cnf

关闭SSH日志

编辑/etc/ssh/sshd_config

/var/log/syslog 没有这个文件

正常登录 Mar 23 03:10:40 ubuntu systemd[1]: Started Session 7 of user homepc.

grep sshd /var/log/auth.log

https://www.cnblogs.com/sparkdev/p/7694202.html

`,17),h={href:"https://blog.csdn.net/supertor/article/details/84334710?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task",target:"_blank",rel:"noopener noreferrer"},p=e("p",null,"[root@master ~]# vim /etc/ssh/sshd_config #SyslogFacility AUTH SyslogFacility AUTHPRIV #LogLevel INFO 改 SyslogFacility local1",-1),u=e("p",null,"更改日志服务配置 [root@master ~]# vim /etc/rsyslog.conf #sign local1.* /var/log/sshd.log //这里该成空,就可以全删除了",-1);function m(_,b){const s=a("ExternalLinkIcon");return l(),o("div",null,[d,e("p",null,[e("a",h,[n("ssh远程登陆日志分析"),r(s)])]),p,u])}const y=t(c,[["render",m],["__file","linux关闭访问日志及mysql.html.vue"]]);export{y as default}; diff --git "a/assets/linux\345\255\246\344\271\240.html--GCM8Al2.js" "b/assets/linux\345\255\246\344\271\240.html--GCM8Al2.js" new file mode 100644 index 0000000..f91ca10 --- /dev/null +++ "b/assets/linux\345\255\246\344\271\240.html--GCM8Al2.js" @@ -0,0 +1 @@ +const l=JSON.parse('{"key":"v-9fbc4e4a","path":"/notebook/linux%E5%AD%A6%E4%B9%A0.html","title":"linux学习","lang":"en-US","frontmatter":{},"headers":[{"level":3,"title":"删除含有行的文件","slug":"删除含有行的文件","link":"#删除含有行的文件","children":[]},{"level":2,"title":"软连接 2020/4/20","slug":"软连接-2020-4-20","link":"#软连接-2020-4-20","children":[{"level":3,"title":"删除所有以.log结尾的文件 20200806","slug":"删除所有以-log结尾的文件-20200806","link":"#删除所有以-log结尾的文件-20200806","children":[]}]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/linux学习.md"}');export{l as data}; diff --git "a/assets/linux\345\255\246\344\271\240.html-FUsT3kNP.js" "b/assets/linux\345\255\246\344\271\240.html-FUsT3kNP.js" new file mode 100644 index 0000000..828a58e --- /dev/null +++ "b/assets/linux\345\255\246\344\271\240.html-FUsT3kNP.js" @@ -0,0 +1,9 @@ +import{_ as e,o as n,c as a,a as s}from"./app-x8p6wK6B.js";const i={},r=s(`

linux学习

删除含有行的文件


+sed -e '/abc/d'  clickhouse-server.log  > a.log 
+chown clickhouse:clickhouse a.log
+chmod 640 a.log
+mv a.log clickhouse-server.log
+service clickhouse-server reload
+
+
+

软连接 2020/4/20

Usage: ln [OPTION]... [-T] TARGET LINK_NAME (1st form) or: ln [OPTION]... TARGET (2nd form) or: ln [OPTION]... TARGET... DIRECTORY (3rd form) or: ln [OPTION]... -t DIRECTORY TARGET... (4th form) In the 1st form, create a link to TARGET with the name LINK_NAME. In the 2nd form, create a link to TARGET in the current directory. In the 3rd and 4th forms, create links to each TARGET in DIRECTORY. Create hard links by default, symbolic links with --symbolic. By default, each destination (name of new link) should not already exist. When creating hard links, each TARGET must exist. Symbolic links can hold arbitrary text; if later resolved, a relative link is interpreted in relation to its parent directory.

删除所有以.log结尾的文件 20200806

find ./ -name "*.log" -exec rm {} ;

`,7),t=[r];function l(o,c){return n(),a("div",null,t)}const h=e(i,[["render",l],["__file","linux学习.html.vue"]]);export{h as default}; diff --git "a/assets/mac_win10\345\217\214\347\263\273\347\273\237\344\270\213\347\232\204\346\227\266\351\227\264\351\227\256\351\242\230.html-1VeVPUm0.js" "b/assets/mac_win10\345\217\214\347\263\273\347\273\237\344\270\213\347\232\204\346\227\266\351\227\264\351\227\256\351\242\230.html-1VeVPUm0.js" new file mode 100644 index 0000000..70b89b3 --- /dev/null +++ "b/assets/mac_win10\345\217\214\347\263\273\347\273\237\344\270\213\347\232\204\346\227\266\351\227\264\351\227\256\351\242\230.html-1VeVPUm0.js" @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-5be7464d","path":"/notebook/mac_win10%E5%8F%8C%E7%B3%BB%E7%BB%9F%E4%B8%8B%E7%9A%84%E6%97%B6%E9%97%B4%E9%97%AE%E9%A2%98.html","title":"mac+win10双系统下的时间问题","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"解决问题","slug":"解决问题","link":"#解决问题","children":[]},{"level":2,"title":"遇到的问题","slug":"遇到的问题","link":"#遇到的问题","children":[]},{"level":2,"title":"20220207 时间不同步的真正原因","slug":"_20220207-时间不同步的真正原因","link":"#_20220207-时间不同步的真正原因","children":[]},{"level":2,"title":"2022020 使用intel连接设置","slug":"_2022020-使用intel连接设置","link":"#_2022020-使用intel连接设置","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/mac+win10双系统下的时间问题.md"}');export{e as data}; diff --git "a/assets/mac_win10\345\217\214\347\263\273\347\273\237\344\270\213\347\232\204\346\227\266\351\227\264\351\227\256\351\242\230.html-Uil1Iztz.js" "b/assets/mac_win10\345\217\214\347\263\273\347\273\237\344\270\213\347\232\204\346\227\266\351\227\264\351\227\256\351\242\230.html-Uil1Iztz.js" new file mode 100644 index 0000000..d8e36db --- /dev/null +++ "b/assets/mac_win10\345\217\214\347\263\273\347\273\237\344\270\213\347\232\204\346\227\266\351\227\264\351\227\256\351\242\230.html-Uil1Iztz.js" @@ -0,0 +1,4 @@ +import{_ as s,o as i,c as e,a}from"./app-x8p6wK6B.js";const t="/assets/20220207233147081_24080-V7_vSr-g.png",n="/assets/20220207232816641_27744-ixb5EC4z.png",p="/assets/20220208000905799_19986-bR9eGTbv.png",o="/assets/20220208001114853_16951-jxhFg3uB.png",r="/assets/20220208001221680_4061-QG9ozPf4.png",c="/assets/20220207234131065_31240-himi3PAW.png",d="/assets/20220207233945612_13266-lT_z19WY.png",_="/assets/20220207234824158_14626-SIvcFdMC.png",m="/assets/20220209135741145_23408-ROZYQ1JU.png",l="/assets/20220209140136127_9585-FLB24hie.png",h="/assets/20220209140047704_18587-Fej0ZjCm.png",g="/assets/20220209140104734_21646-qwn7a-6c.png",u={},w=a('

mac+win10双系统下的时间问题

安装了 Windows/macOS 双系统的同学,一定遇到过双系统时间不同步的问题。具体表现是,一旦进入过 macOS 系统,Windows 中的时间就会比实际时间慢8个小时(以国内为准)。

解决问题

遇到这个问题,我第一个想法是编辑计划任务,在windows系统开机的时候执行时间同步(因为windows默认是7天与时间服务器同步一次)

具体的逻辑是开机后,识别到wifi连接上事件(id8001),则执行与时间服务器同步的脚本

首先是定位到wifi连接上的事件,打开事件查看器, 应用程序和服务日志-Microsoft-Windows-WLAN-AutoConfig 可以看到下图,我们找到8001事件,他的描述是WLAN 自动配置服务已成功连接到无线网络

我整理了一下,大概有7个事件

事件8000 WLAN 自动配置服务已开始连接无线网络。 事件8001 WLAN 自动配置服务已成功连接到无线网络。 事件8003 WLAN 自动配置服务已成功从无线网络断开。 事件8005 WLAN 自动配置服务已开始启动承载网络。 事件8006 WLAN 自动配置服务已完成启动承载网络。 事件8008 WLAN 自动配置服务已开始停止承载网络。 事件8011 连接到上一个正常网络

按照字面意思,我们应该使用8011事件作为触发器,但是查阅日志发现,最近几天我重启了好几次wifi,但是只有一次8011事件,可能有其他的因素在里面,我们还是选择事件8001作为触发器把。

在计算机管理-任务计划程序-新建计划任务,编辑触发器

下面是更新系统时间的vbs代码,保存在本地后,新建执行程序

Set ws = CreateObject("Wscript.Shell") 
+ws.Run "net start w32time",vbhide,true
+ws.Run "w32tm /resync",vbhide
+

注意要勾选常规选项卡中的使用最高权限运行

部署好后,每次启动笔记本,连接上wifi,时间就会自动同步到最新时间

遇到的问题

我开启了无线投屏,所以每次开机都会开放一个热点,然后系统自动连接上去,此时还没有连接到网络,所以同步失败,而且由于设置了重试和按需运行,导致3分钟连接到有网络的wifi并不会同步时间(因为按需运行)

20220207 时间不同步的真正原因

问题的成因是Windows和macOS处理时间的方式不同:

Windows把系统硬件时间当作本地时间(Local Time),即操作系统中显示的时间和 BIOS 中显示的时间是一样的 macOS 则把硬件时间当作 UTC,操作系统中显示的时间是硬件时间经过换算得来的,例如:假设 macOS 中设置了东八区时区,系统显示时间早上9:00,实际硬件储存时间就是UTC 1:00。这个时候重启进入 Windows,时间就变成了早上1:00。

办法也很简单,就是让Windows把硬件时间当作 UTC 时间,保持和 macOS 一致。

Window7 用户点击左下角 开始 -> 运行 -> 输入CMD

Window8/10用户按下 Win+X 组合键,使用管理员模式进入CMD

输入以下命令: Reg add HKLM\\SYSTEM\\CurrentControlSet\\Control\\TimeZoneInformation /v RealTimeIsUniversal /t REG_DWORD /d 1

不过看来这样bios时间又会出问题,所以我还是使用我的土方法把

2022020 使用intel连接设置

今天在发现局域网samba传输速度只有5MB, 于是点开了网络设置,发现使用intel设置可以实现连接到特定wifi后执行应用程序

路径为 控制面板-网络连接-选中你当前连接的WLAN-状态-无线属性-

',33),v=[w];function W(b,f){return i(),e("div",null,v)}const C=s(u,[["render",W],["__file","mac_win10双系统下的时间问题.html.vue"]]);export{C as default}; diff --git "a/assets/markdown\345\255\246\344\271\240.html-reKNUoVC.js" "b/assets/markdown\345\255\246\344\271\240.html-reKNUoVC.js" new file mode 100644 index 0000000..afdcf14 --- /dev/null +++ "b/assets/markdown\345\255\246\344\271\240.html-reKNUoVC.js" @@ -0,0 +1,18 @@ +import{_ as e,o as n,c as i,a}from"./app-x8p6wK6B.js";const r={},l=a(`

markdown学习

用HTML代码中的<br>
+
+如下所示,要在“身高”换行后加“体重”,可以在本行末尾输入<br>,再输入“体重”,则马上换行显示。
+
+
+
+假设我们想跳转到文档中的一个不是标题的位置(比如一张图表),则需要在该位置自定义一个锚。
+
+我们使用HTML语法来定义一个锚。可选的HTML标签很多,比如<span>、<a>等等。本文使用<span>示例。
+
+假设文档中有一个作息时间表,在文档的其他地方需要增加跳转到此表位置的链接,那么我们可以在此表的附近增加一行:
+
+<span id=”表1”>名称</span>
+
+
+
+
+

WARNING

here be dragons

::: alert-warning

alert-warning 黄色

:::

::: alert-info

alert-info 蓝色

:::

::: alert

alert-error 红色

:::

WARNING: be careful to baz the quux before initializing the retro encabulator!

⚠️ If you are using mobile browser: Be very careful here!

`,14),t=[l];function s(d,c){return n(),i("div",null,t)}const v=e(r,[["render",s],["__file","markdown学习.html.vue"]]);export{v as default}; diff --git "a/assets/markdown\345\255\246\344\271\240.html-z0qqMoTi.js" "b/assets/markdown\345\255\246\344\271\240.html-z0qqMoTi.js" new file mode 100644 index 0000000..c9eb93e --- /dev/null +++ "b/assets/markdown\345\255\246\344\271\240.html-z0qqMoTi.js" @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-2f05202c","path":"/notebook/markdown%E5%AD%A6%E4%B9%A0.html","title":"markdown学习","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/markdown学习.md"}');export{t as data}; diff --git "a/assets/mysql_\344\270\273\344\273\216\345\244\215\345\210\266.html-MzwNrIxL.js" "b/assets/mysql_\344\270\273\344\273\216\345\244\215\345\210\266.html-MzwNrIxL.js" new file mode 100644 index 0000000..c459a47 --- /dev/null +++ "b/assets/mysql_\344\270\273\344\273\216\345\244\215\345\210\266.html-MzwNrIxL.js" @@ -0,0 +1,68 @@ +import{_ as e,o as n,c as i,a as s}from"./app-x8p6wK6B.js";const a={},l=s(`

[mysql]主从复制

步骤

1,主开启binlog

docker run --name mydb2 -itd -e MYSQL_ROOT_PASSWORD=pwd -v /dbconf/:/etc/mysql/conf.d/ mariadb

[root@bogon ~]# vim /mydb1/conf/my.cnf [mysqld] server_id=1 log_bin=mysql-bin

show master status;
+show variables like '%%log_bin%';
+

2. 副修改server_id

[root@bogon ~]# vim /mydb2/conf/my.cnf [mysqld] server_id=2


+show variables like '%server_id%';      
+
+

3.副开启主从

MariaDB [(none)]> CHANGE MASTER TO MASTER_HOST='172.17.0.2', MASTER_USER='slave', MASTER_PASSWORD='slave', MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=511;     
+Query OK, 0 rows affected (0.015 sec)
+
+MariaDB [(none)]> start slave;
+Query OK, 0 rows affected (0.005 sec)
+
+MariaDB [(none)]> show slave status\\G
+*************************** 1. row ***************************
+                Slave_IO_State: Waiting for master to send event
+                   Master_Host: 172.17.0.2
+                   Master_User: slave
+                   Master_Port: 3306
+                 Connect_Retry: 60
+               Master_Log_File: mysql-bin.000001
+           Read_Master_Log_Pos: 511
+                Relay_Log_File: mysqld-relay-bin.000002
+                 Relay_Log_Pos: 555
+         Relay_Master_Log_File: mysql-bin.000001
+              Slave_IO_Running: Yes
+             Slave_SQL_Running: Yes
+               Replicate_Do_DB: 
+           Replicate_Ignore_DB: 
+            Replicate_Do_Table: 
+        Replicate_Ignore_Table: 
+       Replicate_Wild_Do_Table: 
+   Replicate_Wild_Ignore_Table: 
+                    Last_Errno: 0
+                    Last_Error: 
+                  Skip_Counter: 0
+           Exec_Master_Log_Pos: 511
+               Relay_Log_Space: 865
+               Until_Condition: None
+                Until_Log_File: 
+                 Until_Log_Pos: 0
+            Master_SSL_Allowed: No
+            Master_SSL_CA_File: 
+            Master_SSL_CA_Path: 
+               Master_SSL_Cert: 
+             Master_SSL_Cipher: 
+                Master_SSL_Key: 
+         Seconds_Behind_Master: 0
+ Master_SSL_Verify_Server_Cert: No
+                 Last_IO_Errno: 0
+                 Last_IO_Error: 
+                Last_SQL_Errno: 0
+                Last_SQL_Error: 
+   Replicate_Ignore_Server_Ids: 
+              Master_Server_Id: 1
+                Master_SSL_Crl: 
+            Master_SSL_Crlpath: 
+                    Using_Gtid: No
+                   Gtid_IO_Pos: 
+       Replicate_Do_Domain_Ids: 
+   Replicate_Ignore_Domain_Ids: 
+                 Parallel_Mode: conservative
+                     SQL_Delay: 0
+           SQL_Remaining_Delay: NULL
+       Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
+              Slave_DDL_Groups: 0
+Slave_Non_Transactional_Groups: 0
+    Slave_Transactional_Groups: 0
+1 row in set (0.000 sec)
+
`,11),d=[l];function r(v,c){return n(),i("div",null,d)}const t=e(a,[["render",r],["__file","mysql_主从复制.html.vue"]]);export{t as default}; diff --git "a/assets/mysql_\344\270\273\344\273\216\345\244\215\345\210\266.html-hhiDhYAg.js" "b/assets/mysql_\344\270\273\344\273\216\345\244\215\345\210\266.html-hhiDhYAg.js" new file mode 100644 index 0000000..df14b3d --- /dev/null +++ "b/assets/mysql_\344\270\273\344\273\216\345\244\215\345\210\266.html-hhiDhYAg.js" @@ -0,0 +1 @@ +const l=JSON.parse('{"key":"v-1306d2e8","path":"/ops/mysql_%E4%B8%BB%E4%BB%8E%E5%A4%8D%E5%88%B6.html","title":"[mysql]主从复制","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"步骤","slug":"步骤","link":"#步骤","children":[{"level":3,"title":"1,主开启binlog","slug":"_1-主开启binlog","link":"#_1-主开启binlog","children":[]},{"level":3,"title":"2. 副修改server_id","slug":"_2-副修改server-id","link":"#_2-副修改server-id","children":[]},{"level":3,"title":"3.副开启主从","slug":"_3-副开启主从","link":"#_3-副开启主从","children":[]}]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"ops/[mysql]主从复制.md"}');export{l as data}; diff --git "a/assets/mysql_\345\205\250\350\241\250\346\237\245\350\257\242\347\232\204\344\274\230\345\214\226.html-2oZQleTZ.js" "b/assets/mysql_\345\205\250\350\241\250\346\237\245\350\257\242\347\232\204\344\274\230\345\214\226.html-2oZQleTZ.js" new file mode 100644 index 0000000..086f8a1 --- /dev/null +++ "b/assets/mysql_\345\205\250\350\241\250\346\237\245\350\257\242\347\232\204\344\274\230\345\214\226.html-2oZQleTZ.js" @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-18f94f3e","path":"/web/mysql_%E5%85%A8%E8%A1%A8%E6%9F%A5%E8%AF%A2%E7%9A%84%E4%BC%98%E5%8C%96.html","title":"[mysql]全表查询的优化","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"web/[mysql]全表查询的优化.md"}');export{e as data}; diff --git "a/assets/mysql_\345\205\250\350\241\250\346\237\245\350\257\242\347\232\204\344\274\230\345\214\226.html-HycpRTEg.js" "b/assets/mysql_\345\205\250\350\241\250\346\237\245\350\257\242\347\232\204\344\274\230\345\214\226.html-HycpRTEg.js" new file mode 100644 index 0000000..d4616bf --- /dev/null +++ "b/assets/mysql_\345\205\250\350\241\250\346\237\245\350\257\242\347\232\204\344\274\230\345\214\226.html-HycpRTEg.js" @@ -0,0 +1,6 @@ +import{_ as e,o as s,c as n,a as i}from"./app-x8p6wK6B.js";const t="/assets/20220224210928822_228379039-jj5_jq4n.png",a="/assets/20220224210940314_813231284-I9WT5wLd.png",c="/assets/20220224210923170_2109960537-GwFjhZ3Z.jpg",d="/assets/20220224221723556_1392260680-_0RFBjlq.png",l="/assets/20220224230946729_743431048-3ursmqfX.png",o={},r=i('

[mysql]全表查询的优化

执行分析命令时,对于一个量级为110w的数据表进行全表扫描

ALTER TABLE `xx`\nADD PRIMARY KEY `id_score` (`id`, `score`),\nDROP INDEX `PRIMARY`;\n\n

47EBC50493F2C9AA5C928783E2D41307

先改一下表里的数据

update xxx set score=-1 where score is null
+    -> ;
+Query OK, 2637 rows affected (8.47 sec)
+Rows matched: 2637  Changed: 2637  Warnings: 0
+
+

然后改表的默认值,

然后加上这个联合主键

加主键的时候,我把score放前面了,又不行,必须把id放第一个

加完以后,又出问题

为什么推荐InnoDB引擎使用自增主键? https://www.kancloud.cn/db-design/mysql-dba/596722

MySQL PARTITION 分区表使用教程 https://news.sangniao.com/p/2684880278 结合业务场景选择分区键,避免跨分区查询 对分区表进行查询最好在WHERE从句中包含分区键 具有主键或唯一索引的表,主键或唯一索引必须是分区键的一部分(这也是为什么我们上面分区时去掉了主键登录日志id(login_id)的原因,不然就无法按照上面的按年份进行分区,所以分区表其实更适合在MyISAM引擎中) 关于MyISAM和Innodb的索引区别

1.关于自动增长

myisam引擎的自动增长列必须是索引,如果是组合索引,自动增长可以不是第一列,他可以根据前面几列进行排序后递增。

innodb引擎的自动增长咧必须是索引,如果是组合索引也必须是组合索引的第一列。

mysql 分区的真正作用? https://www.zhihu.com/question/38418707

',18),p=[r];function m(_,u){return s(),n("div",null,p)}const b=e(o,[["render",m],["__file","mysql_全表查询的优化.html.vue"]]);export{b as default}; diff --git "a/assets/n1\347\233\222\345\255\220_\344\275\277\347\224\250n1\347\233\222\345\255\220\344\273\245\345\217\212\347\275\227\346\212\200\346\221\204\345\203\217\345\244\264\350\277\233\350\241\214\347\233\264\346\222\255.html-1DGe_3H6.js" "b/assets/n1\347\233\222\345\255\220_\344\275\277\347\224\250n1\347\233\222\345\255\220\344\273\245\345\217\212\347\275\227\346\212\200\346\221\204\345\203\217\345\244\264\350\277\233\350\241\214\347\233\264\346\222\255.html-1DGe_3H6.js" new file mode 100644 index 0000000..f5d2193 --- /dev/null +++ "b/assets/n1\347\233\222\345\255\220_\344\275\277\347\224\250n1\347\233\222\345\255\220\344\273\245\345\217\212\347\275\227\346\212\200\346\221\204\345\203\217\345\244\264\350\277\233\350\241\214\347\233\264\346\222\255.html-1DGe_3H6.js" @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-5107f338","path":"/notebook/n1%E7%9B%92%E5%AD%90_%E4%BD%BF%E7%94%A8n1%E7%9B%92%E5%AD%90%E4%BB%A5%E5%8F%8A%E7%BD%97%E6%8A%80%E6%91%84%E5%83%8F%E5%A4%B4%E8%BF%9B%E8%A1%8C%E7%9B%B4%E6%92%AD.html","title":"[n1盒子]使用n1盒子以及罗技摄像头进行直播","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/[n1盒子]使用n1盒子以及罗技摄像头进行直播.md"}');export{t as data}; diff --git "a/assets/n1\347\233\222\345\255\220_\344\275\277\347\224\250n1\347\233\222\345\255\220\344\273\245\345\217\212\347\275\227\346\212\200\346\221\204\345\203\217\345\244\264\350\277\233\350\241\214\347\233\264\346\222\255.html-Awm7UpR8.js" "b/assets/n1\347\233\222\345\255\220_\344\275\277\347\224\250n1\347\233\222\345\255\220\344\273\245\345\217\212\347\275\227\346\212\200\346\221\204\345\203\217\345\244\264\350\277\233\350\241\214\347\233\264\346\222\255.html-Awm7UpR8.js" new file mode 100644 index 0000000..1a879bf --- /dev/null +++ "b/assets/n1\347\233\222\345\255\220_\344\275\277\347\224\250n1\347\233\222\345\255\220\344\273\245\345\217\212\347\275\227\346\212\200\346\221\204\345\203\217\345\244\264\350\277\233\350\241\214\347\233\264\346\222\255.html-Awm7UpR8.js" @@ -0,0 +1 @@ +import{_ as e,o as t,c,a as p}from"./app-x8p6wK6B.js";const d={},a=p('

[n1盒子]使用n1盒子以及罗技摄像头进行直播

方式1 ffserver 然后使用

ffmpeg -f v4l2 -i /dev/video1 -s 640x480 -r 24 -vcodec libx264 -an http://127.0.0.1:8090/feed1.ffm

把video1串流到ffm文件

之后使用播放器访问 rtsp://192.168.2.190:8554/live1.h264

使用webrtc转发 设备到web(未实现) docker run -p 8000:8000 -it mpromonet/webrtc-streamer -n raspicam -u rtsp://192.168.2.190:8554/live1.h264

方式2 通过vlc

cvlc --no-audio v4l2:///dev/video1 --v4l2-width 1920 --v4l2-height 1080 --v4l2-chroma h264 --v4l2-fps 30 --v4l2-hflip 1 --v4l2-vflip 1 --sout "#transcode{vcodec=mjpg,vb=25,scale=1.0,fps=24,acodec=none}:standard{access=http{mime=multipart/x-mixed-replace; boundary=7b3cc56e5f51db803f790dad720ed50a},mux=mpjpeg,dst=:8554/videostream.cgi}"

v4l2:///dev/video1:width=1920:height=1080:fps=30:chroma=MJPG:live-caching=300 --sout "#transcode{vcodec=mjpg,vb=25,scale=1.0,fps=24,acodec=none}:standard{access=http{mime=multipart/x-mixed-replace; boundary=7b3cc56e5f51db803f790dad720ed50a},mux=mpjpeg,dst=:8554/videostream.cgi}" 直接打开 8554端口即可

方式3 motion

修改下配置文件,设置局域网访问即可

vlc v4l2:///dev/video1 --sout "#std{access=http,mux=mpjpeg,dst=:8554/videostream.cgi}"

方式4 mjpg-streamer

这种方式只能推送图片,优点是延迟底,以及不需要安装软件,浏览器访问即可

',14),o=[a];function s(r,i){return t(),c("div",null,o)}const m=e(d,[["render",s],["__file","n1盒子_使用n1盒子以及罗技摄像头进行直播.html.vue"]]);export{m as default}; diff --git a/assets/nginx.html-5oTIskkv.js b/assets/nginx.html-5oTIskkv.js new file mode 100644 index 0000000..f400e2b --- /dev/null +++ b/assets/nginx.html-5oTIskkv.js @@ -0,0 +1,108 @@ +import{_ as n,o as s,c as a,a as e}from"./app-x8p6wK6B.js";const i={},p=e(`

nginx简洁

nginx是一个反向代理服务器,同时也是一个轻量的web服务器(php要配置php) 在一台服务器上,我们可以在不同的端口开设web服务,以 ip:port 的形式访问,但是这是不好看的 如果你有一个已经备案的域名,则可以在域名服务商处设置隐形url, 将二级域名转发到ip:port 如果你的服务器在国外,同时域名没有备案, 可以通过nginx来设置二级域名,

2022-2-6 nginx图片分层

存储大量图片时,可能会遇到linux文件夹文件数量的限制 我所使用的方案:保存图片时按照图片的md5前四位建立二级目录,例如md5为abcdefgxxx ,则保存后的文件目录为 /www/static/images/ab/cd/abcdefgxxx 然后使用nginx正则去获取文件的前四位


+location ~ ^/static/images/((..)(..).+) {
+    set $dir1 $2;
+    set $dir2 $3;
+    set $filename $1;
+    default_type image/jpeg;
+    alias /www/static/images/$dir1/$dir2/;
+    try_files $filename =404;
+}
+
+
+

nginx作为静态资源服务器

https://www.w3cschool.cn/nginxsysc/nginxsysc-cache.html

nginx简单操作


+//检测编写的配置文件是否有语法错误
+nginx -t 
+// 热重启nginx (nginx不重启的情况下重新加载配置文件)
+nginx -s reload  
+
+

通过nginx设置二级域名

首先, 需要在域名服务商处将 *.your.domain 解析到你的服务器

然后安装nginx服务,具体不细说

在/etc/nginx/conf.d 文件夹下新建 test.conf文件

假设你要将本机 3456端口的内容设置到blog这个二级域名

server_name 二级域名 proxy_pass 写你本机的地址

配置文件编写如下

server {
+  listen 80;
+  server_name blog.moyechen.cn;
+
+  location / {
+    proxy_set_header  X-Real-IP $remote_addr;
+    proxy_set_header  Host   $http_host;
+    proxy_pass     http://0.0.0.0:3456;
+  }
+}
+

nginx作为轻量的web服务器

root那里写web页面的路径
index写主页文件.可以多个

server {
+    listen       80;
+    server_name  scs.moyechen.cn;
+
+    index       index.html index.php;
+    root         /root/src/cnn/conv/;
+    location / {
+    proxy_set_header  X-Real-IP $remote_addr;
+    proxy_set_header  Host   $http_host;
+  }
+}
+

带PHP的页面

需要我们本地安装有PHP服务,然后设置一下PHP服务即可

server {
+    listen       80 default_server;
+    listen       [::]:80 default_server;
+    server_name  acm.moyechen.cn;
+
+    index       index.php;
+    root         /home/judge/src/web;
+
+    location / {
+
+    }
+    location ~ \\.php$ {
+            fastcgi_index               index.php;
+            fastcgi_pass                127.0.0.1:9000;
+            fastcgi_param               SCRIPT_FILENAME $document_root$fastcgi_script_name;
+            fastcgi_split_path_info     ^(.+\\.php)(/.+)$;
+            client_max_body_size        80m;
+            include                     fastcgi_params;
+    }
+}
+

直接偷别人的页面

但是好像不能登陆,可能是https导致的

server {
+  listen 80;
+  server_name vj.moyechen.cn;
+
+  location / {
+    proxy_set_header  X-Real-IP $remote_addr;
+    proxy_set_header  Host   $http_host;
+    proxy_pass     https://vjudge.net;
+  }
+}
+

frps 简单配置

server {
+    listen 80;
+    server_name *.frp.moyechen.cn;
+    location / {
+        proxy_pass http://127.0.0.1:7080;
+        proxy_set_header    Host            $host:80;
+        proxy_set_header    X-Real-IP       $remote_addr;
+        proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;
+        proxy_hide_header   X-Powered-By;
+    }
+}
+server {
+    listen 80;
+    server_name frp.moyechen.cn;
+    location / {
+        proxy_pass http://127.0.0.1:7500;
+        proxy_set_header    Host            $host:80;
+        proxy_set_header    X-Real-IP       $remote_addr;
+        proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;
+        proxy_hide_header   X-Powered-By;
+    }
+}
+

国内服务器如何不备案放到域名上

如果国内服务器不备案,并且被一个域名指向,那么几天后你访问就会出现需要备案的标记

我们可以用一台国外服务器来做中转,注意端口最好不要使用80以及443等常用端口
不然好像还会被封

假设国内服务器ip为 xxx.xxx.xxx.xxx 假设web服务开设在国内服务器5678端口

  • 第一步, 在域名服务商设置你的域名解析到国外服务器的ip
  • 第二步, 设置中转机器

中转机器配置信息:

server {
+  listen 80;
+  server_name 写你的域名;
+
+  location / {
+    proxy_set_header  X-Real-IP $remote_addr;
+    proxy_set_header  Host   $http_host;
+    proxy_pass     http://xxx.xxx.xxx.xxx:5678;
+  }
+}
+
+

那既然有国外服务器了,为什么还要用国内服务器开设web页面呢? 我也不知道

nginx日志审计

统计访问IP前十

awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -10

统计状态码

awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -10

nginx 安全

账户验证

在linux中,如果不安装apache,但是又需要用htpasswd生成登录账号,如:配置Nginx,pure-ftpd,subversion等。

那就需要找一个替代htpasswd生成密码的方法,用openssl就可以办到

# printf "user:$(openssl passwd -crypt 123456)\\n" >>conf/.htpasswd
+# cat conf/htpasswd
+

===结果=== user:xyJkVhXGAZ8tM

这样就生成了一个用户名为user,密码为123456的账号了。

server {
+         auth_basic      "login";
+         auth_basic_user_file    conf/.htpasswd;
+}
+
`,49),t=[p];function c(l,d){return s(),a("div",null,t)}const r=n(i,[["render",c],["__file","nginx.html.vue"]]);export{r as default}; diff --git a/assets/nginx.html-xodFXP41.js b/assets/nginx.html-xodFXP41.js new file mode 100644 index 0000000..37f15e9 --- /dev/null +++ b/assets/nginx.html-xodFXP41.js @@ -0,0 +1 @@ +const l=JSON.parse('{"key":"v-53b6469a","path":"/notebook/nginx.html","title":"nginx简洁","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"带PHP的页面","slug":"带php的页面","link":"#带php的页面","children":[]},{"level":2,"title":"nginx日志审计","slug":"nginx日志审计","link":"#nginx日志审计","children":[{"level":3,"title":"统计访问IP前十","slug":"统计访问ip前十","link":"#统计访问ip前十","children":[]},{"level":3,"title":"统计状态码","slug":"统计状态码","link":"#统计状态码","children":[]}]},{"level":2,"title":"nginx 安全","slug":"nginx-安全","link":"#nginx-安全","children":[{"level":3,"title":"账户验证","slug":"账户验证","link":"#账户验证","children":[]}]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/nginx.md"}');export{l as data}; diff --git a/assets/oceanus.html-wyQKBsB6.js b/assets/oceanus.html-wyQKBsB6.js new file mode 100644 index 0000000..0941e9d --- /dev/null +++ b/assets/oceanus.html-wyQKBsB6.js @@ -0,0 +1,12 @@ +import{_ as i,o as a,c as e,a as s}from"./app-x8p6wK6B.js";const t="/assets/20210706000854738_8657-_CyPZxwc.png",n="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJgAAABqCAIAAADP+g9kAAAACXBIWXMAABJNAAASTQHzl8SnAAAJ90lEQVR4nO2cMWwi2RnH/5fLjnSMkpspdqITaOVpcGEKkwIKiCIoTGMK3LgxiuASgRTYwiiy9yRcGEVnS4HicGGKgwI3liJTGCnCikCKcLFIESgyhWnYApo5nYZmKGabFAMYY7CxFxvu7ftVeN7jfc/zmzfvzcw3fPHmzRtQfvn8at4doMwGKpIQqEhCoCIJgYokBCqSEKhIQqAiCYGKJAQqkhCoSEKgIgmBiiQEKpIQqEhCoCIJgYokBCqSEKhIQqAiCYGKJAQqkhCoSEBnCf2Q/SFk0d3aavTFs8fbDt2ELy0aX3799dfz7sNc0Tl2kpE//I75rbjEVf9V+bm32Rj6+19/z7NvrA6j9O//fPg41z5OA7Ei9evb34X+/Jc//fE3/7yoTaxl9B38zfnNl4BcTUb+8d8bXz9XipLRYf3mq6++MZt1/7uo/TyxjcWA2FPrktm8bOAZ5r46xkDIJTKA2jw/jJW6twu7pdjheVMFGNG9HTI+Z19nAbEiH0bn8TkMDKBen0YzjXE1GplUqaUCEOy+rQWfLH/9HI3qVtb8WxtWUWAZAFDlZikdS112esWcLbDjtfdLocqtaj6VzNW7AGCLZiNmFmieb0QyWn1f/Mwtor+pV0Eq76eVTb99WWB7IVLRVKU7qNxHdJ+duXufh9oEVoKuZQaAXD3NjQzGGxqpfMMeNLHMsj24cpKoz2T3PAuzH5E6RzQZCzqX+54AhhddwbBN+8Poix9HXEOlYHiD1RtL7jxugchZdnddmsVeiPDu2iO+v+IyCgAgVU8mT6EALs6uZAAQjK6Vx/TvpZk0IkcP7I2N85Etd1GqcW/aGAuYeQCQr7KpVKHSht7i9GyuaXtc7wu4RAaA2iom944uO9yqbyfiXmbBWzeDK6Xpj3mGYSBfZRMHubZzP+k3sWCN9nVcZCIbGWDsyL6FRa95bJTa9weqVT4oVp6FoLcA9bt7ZoSxO0qpxr2xy2n/tScx4xGp91g1T83zvb1cpd0Fuu1K/ijy9vByuPg6v3t02QHQqWVihWsVAASjQ/+IUGrz/HAvV++ik29KAACGfT31t20GAQCgyA8eOqWW1jwnWB7RvZfmvjly5DjqHer34vk+DACQGqfjDvQlXhuYnfbQGrHb7H4EGIDll6bpco/21fgVyrPBMK8AIPPgfrhdwRc/cwvP2K0eMx6R3P3r/T7qR3m2cV8CRek8XGluzFhkXdIMCcbNcafJjqJoxUsbNysbnZHTxqnUqt5UfcX0augchk85oAft3OZy+vOlReAATHUWniMzFlkpNGQAYET3/r7HotcBOr1lPRT/YccGoF5sasXL6wchGweAs4UOXCIAqNfl0y7wUVUBAMKKd0WnW/HsJ8Nm9gk96bdjMIdt3LietiUA4EX7A4tRvUXkAUBqXjyhGy/GrK8ja8mT98awlQd4k3c36e1vV6r94qoxbObBGJyRtDMy+J5ync/kugAqhbpktQtgDK7YiQsAoKoqM90pe4hKuSFbrTwgWCPpMy3Q8Aq2XmzKdoGHYN6woT55Rbm6ZRYAoFXNPbC8nS8zv47slg7D0ePitaSo/U2KdF04Tl72imPhaPZ9Sx6UqnKrenYQeHfSW7rUEomzK0npFzYL8WDhKbvw8vAwPRxnlNpJuakCYFc2AxNvwOl9XjMPQL0uZRfaI76Y8KsevviZW3j+q5/5srp9vGcXtIulyJg1sNEX33eLzMTyqXihPfkZ32sFaolE/7b4TnRtZCbVOaI7bu2WeiH1wlc6T+CzFgk0MtFUVQbAm4Px7aEFrDF0EDbzgCqVUxNuqS8Wn7lIbdJOliW5eX6YqNxsbqRPii2lVUxsJ0afby0mz/L04xdGt5QIlu5srBy99Y6rvaBMWuxQfmFMOrX64mdn2ajtRftCJi+0Jz/7OZIUqEhCoCIJgYokBCqSEJ7nOpJbXd/yepwiPyZbZXzOy53UmpFMvOEKvaJ+5tXtLLxpQ2ipfL02VLlVzR0d5gd3cB4MsXDMWiRn821vOk2GpzxCHKCzhA62nYZJT642/UHnkCeGN1i9UYGLRDLTPqDQrWv5WsNN+Pfjrwe3xj89xEszY5GrAb/bxAOqVK3IRvvyJJ+TctsAQOeJbjsNDJRWtZg7vXjfaI+OA1VuFnOnuWKl3dXpLa5AwGviRdMaMNzk5BC69d1NEwvIV9lkIlfrcKue7bDXxIsun+f0nZbkOlWIRWLGImuFektkS8l4rm6OZu1PaWI1vL7MQK4mw3ey+Htk3n07+NxtV3InFteBc/p0EN2mw8RCbRUO93INAOjUcntJ4497Vl60uJDLfXqIOTDzDIHE2+AnNbDiFHmo1/lJFkfglhxbIbsAuZo/nTKCU9QDarOU6s+I3Kon7DfxABiDyYbcyIPDJ4SYA3O6aT5I5FdVWaqXT5OZ/gsFFr0AtH76GPr+eLDWUKTrcjqWqgypHV7PqK1ycu/OQ4qJIV6zDCD91IC2pvF7neJgBmA5I3A5bYhFYt6XHwzDG8zuyHHcN5xuYbD7nYPXAQBWWHbtJrZXJ7VhsIfj++uT8jXGhlAULvD9j+lY0CmygCpVs9kr5Z5u3h9iAXj5ETmc4MstWewbW1t2AyM6t9Yye4M8NVW+Lp1k8u8b7S635NjaDjgNgnljDbWLkVa4JYvD6980CyZ/KFB9m2pPGUJ0RcR+oPRh6rIDW3RjfEfHhlg45jsiOx8q+cRuqQWAZYcSYVul8LtUSVuudj6Ujg7L0kiNoRZyseDJlQoYjONe4rkbotNLlFSaxeOo/9t32mtiOtNrFpClu7mrD4ZYCOZ9agVgeMUAUFVtBvvQUQBB77yVVvyafXVvE8rH+98NvxWi8kECoDaLiaOLwRW+0W82AKrUqExo4qEQ82auIrXc5ahTAJTGZQEAUHrfVMCYNmMBh16n1fHsh6080GqMyRDmllYcgbjfzEK9Lo9ZVI4J0c5XmyoY0RWNelY5ANyqZ3/HKQBKPZ97fIjFYNZzZP9ttj6sOXKmpQf3LtBHKwCAKpXTB/ne4Lg4Kbr23aLoCidd4ZsqzfOj3uw09gac/D4V67+v+lCIdiZVMO27RcHs3UvfpHPI1XR8zIJ1bIjFY745O6oita8K2VSuNvR+TCMTjXXCgXWzge+/8Fw+TR1djE9lU+VWo5JLZUt37v88IsSY65tHhFgIPusE5ReBJihTHgMVSQhUJCFQkYRAE5QJgSYoPzc0QZnyGKhIQqAiCYGKJAQqkhCoSEKgIgmBiiQEKpIQqEhCuC9D4CZNY4pfUKYV7qlwT8bsrKAjkhDo0w9CoCOSEKhIQqAiCYGKJAQqkhCoSEKgIgmBiiQEKpIQqEhCoCIJgYokBCqSEKhIQqAiCYGKJAQqkhCoSEKgIgmBiiQEKpIQqEhCoCIJ4f8BQHmBQzAbWwAAAABJRU5ErkJggg==",c="/assets/20210710111354832_28033-d6IVyjbP.png",o="/assets/20210710111622380_22277-rkxmw4x3.png",r="/assets/20210710111717516_31301-jnrMYRo7.png",l="/assets/20210710111828345_24528-wV1biks8.png",p="/assets/20210712122439699_5581-wNjEpKjZ.png",d="/assets/20210712122457899_22964--zHa_imy.png",A="/assets/20210712122339853_29496-WHb4SxrT.png",h={},u=s('

oceanus

操作步骤

  1. oceaus 平台建表, 包括海力方表和ch表, 其中要注意ch表写入时间(一般60)和写入量(10000+)
  2. 新建任务
  3. 申请资源
  4. 运行任务

问题汇总

问题1

复制海力方表的tid过去后, 自动填充的字段类型有错误,需要手动检查修改

问题2

类型正确后, 启动任务不闪退了,但是没数据, 查看日志发现连接本地ch数据库出了问题 3. 通过百度了解到tcp端口为9000, 默认的http端口为8123, 但是我这里是修改过的, 因此是8080

修改为自定义的8080端口, ok

问题3:

使用select count(*) 查询数据量正常, 但是select sum(rows) 显示的数量要大的多

查找后发现是因为数据写入太快, 导致分区过多 可以看到前几天的数据都是一个分区, 这是ch后台合并的结果

但是查看当天的数据, 发现分了好多区,并且每一块都很小

发现是写入es批量太小, 且写入太快导致的

  1. 增大批量写条目数, 设置为100000(默认为1000), 如果表过大, 可调整
  2. 增大flush时间间隔 设置为60s(默认为1) https://oceanus.oa.com/#/table/list

优化前

优化后 优化后 查询语句

SELECT 
+    table,
+    partition,
+    sum(rows) AS row
+FROM system.parts
+WHERE (database = 'situation_awareness') AND (table = 'weilidai_antiCollection_socialUniformity_oceanus')
+GROUP BY 
+    table,
+    partition
+    WITH TOTALS
+ORDER BY partition ASC
+

问题4 数据消费问题

需设置savepoint, 防止重启任务时中间数据丢失问题

问题5 导出至clickhouse数据库

官方文档中有说明, 只有1.14版本支持导出

https://iwiki.woa.com/pages/viewpage.action?pageId=746586889

https://iwiki.woa.com/pages/viewpage.action?pageId=703323873

',27),b=[u];function m(g,C){return a(),e("div",null,b)}const I=i(h,[["render",m],["__file","oceanus.html.vue"]]);export{I as default}; diff --git a/assets/oceanus.html-xIXz_Fll.js b/assets/oceanus.html-xIXz_Fll.js new file mode 100644 index 0000000..ae76252 --- /dev/null +++ b/assets/oceanus.html-xIXz_Fll.js @@ -0,0 +1 @@ +const l=JSON.parse('{"key":"v-46b5f098","path":"/notebook/oceanus.html","title":"oceanus","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"操作步骤","slug":"操作步骤","link":"#操作步骤","children":[]},{"level":2,"title":"问题1","slug":"问题1","link":"#问题1","children":[]},{"level":2,"title":"问题2","slug":"问题2","link":"#问题2","children":[]},{"level":2,"title":"问题3:","slug":"问题3","link":"#问题3","children":[]},{"level":2,"title":"问题4 数据消费问题","slug":"问题4-数据消费问题","link":"#问题4-数据消费问题","children":[]},{"level":2,"title":"问题5 导出至clickhouse数据库","slug":"问题5-导出至clickhouse数据库","link":"#问题5-导出至clickhouse数据库","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/oceanus.md"}');export{l as data}; diff --git a/assets/oj.html-79YbMTzR.js b/assets/oj.html-79YbMTzR.js new file mode 100644 index 0000000..3b3368a --- /dev/null +++ b/assets/oj.html-79YbMTzR.js @@ -0,0 +1 @@ +const l=JSON.parse('{"key":"v-12fb3630","path":"/ops/oj.html","title":"oj","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"php7.2","slug":"php7-2","link":"#php7-2","children":[{"level":3,"title":"代码路径信息","slug":"代码路径信息","link":"#代码路径信息","children":[]}]},{"level":2,"title":"代码结构","slug":"代码结构","link":"#代码结构","children":[]},{"level":2,"title":"nginx","slug":"nginx","link":"#nginx","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"ops/oj.md"}');export{l as data}; diff --git a/assets/oj.html-DrprtZF7.js b/assets/oj.html-DrprtZF7.js new file mode 100644 index 0000000..4de18aa --- /dev/null +++ b/assets/oj.html-DrprtZF7.js @@ -0,0 +1,80 @@ +import{_ as n,o as e,c as s,a as i}from"./app-x8p6wK6B.js";const a="/assets/20221206100854428_16773-Jc0xcMb9.png",d={},l=i(`

oj

pdsuoj

php7.2

代码路径信息

php配置文件路径/etc/php/7.2/fpm/php.ini

这个文件修改后需重启php使修改生效service php7.2-fpm restart

代码路径/home/judge/src/web/

开发代码路径/home/judge/src/web-dev/

下面的信息都基于项目根目录

  • 数据库等配置文件的路径include/db_info.inc.php

代码结构

假设主目录为/home/judge/src/web/ 主目录下的php文件为后端文件,负责数据库查询,数组结构组装

其中前端在template/bs3/ 路径下 admin前端在 admin/ 路径下

tree -L 1
+
+├── ace                        在线编辑器组件
+├── acm_number.txt
+├── acm_ranking.php            acm排名页面
+├── admin
+├── bbs
+├── bbs.php
+├── blog_show.php               博客
+├── bootstrap
+├── config.yaml
+├── csrf.php
+├── discuss3
+├── edit_area
+├── faqcss
+├── favicon.ico
+├── fckeditor
+├── fonts
+├── gpl-2.0.txt
+├── highlight
+├── image
+├── include
+├── index.php
+├── kindeditor
+├── lang
+├── mergely
+├── newranking_guize.txt
+├── php_errors.log           日志,基本是警告与错误
+├── qrcodetmp
+├── reportlogin.html
+├── study_vedio              学习视频
+├── summary                  知识图谱   
+├── template
+└── upload
+
+

nginx

nginx 是最流行,性能最强的web服务器,使用多路复用,性能很强,基本替代了以前的apache

php-fpm与nginx访问流程图

nginx 配置文件路径 for 生产 /etc/nginx/sites-enabled/default

nginx 配置文件路径 for 开发 /etc/nginx/sites-enabled/web-dev

nginx 常用命令

nginx -t 检查配置文件是否正确

root@iZ2ze954cl1vua04rezfxcZ:/home/judge/src/web# nginx -t 
+nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
+nginx: configuration file /etc/nginx/nginx.conf test is successful
+

nginx -s reload 使用新的配置文件重载nginx(编辑配置后,需重载使nginx生效, 正常情况下无输出)

root@iZ2ze954cl1vua04rezfxcZ:/home/judge/src/web# nginx -s reload
+root@iZ2ze954cl1vua04rezfxcZ:/home/judge/src/web#
+
+

nginx配置文件demo

# 主要区别在于listen 的端口以及root 的位置, 创建新的文件,并修改这两个,即可设置多个站点
+server {
+    
+        listen 8000 default_server;            
+        listen [::]:8000 default_server;
+
+        include snippets/phpmyadmin.conf;
+        root /home/judge/src/web-dev;
+
+        # Add index.php to the list if you are using PHP
+        index index.php index.htm index.nginx-debian.html;
+
+        server_name _;
+
+        location / {
+                # First attempt to serve request as file, then
+                # as directory, then fall back to displaying a 404.
+                try_files $uri $uri/ =404;
+        }
+
+        # pass PHP scripts to FastCGI server
+        #
+        location ~ \\.php$ {
+                include snippets/fastcgi-php.conf;
+        #
+        #       # With php-fpm (or other unix sockets):
+                fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
+        #       # With php-cgi (or other tcp sockets):
+        #       fastcgi_pass 127.0.0.1:9000;
+        #}
+
+        }#added by hustoj
+
+
+
+}
+
+
+
`,26),c=[l];function t(p,r){return e(),s("div",null,c)}const v=n(d,[["render",t],["__file","oj.html.vue"]]);export{v as default}; diff --git "a/assets/project_\351\241\271\347\233\256\351\205\215\347\275\256\346\226\207\344\273\266.html-MQ8gDqA5.js" "b/assets/project_\351\241\271\347\233\256\351\205\215\347\275\256\346\226\207\344\273\266.html-MQ8gDqA5.js" new file mode 100644 index 0000000..accd9dc --- /dev/null +++ "b/assets/project_\351\241\271\347\233\256\351\205\215\347\275\256\346\226\207\344\273\266.html-MQ8gDqA5.js" @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-70851bec","path":"/web/project_%E9%A1%B9%E7%9B%AE%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6.html","title":"[project]项目配置文件","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"web/[project]项目配置文件.md"}');export{e as data}; diff --git "a/assets/project_\351\241\271\347\233\256\351\205\215\347\275\256\346\226\207\344\273\266.html-Yb36aCmH.js" "b/assets/project_\351\241\271\347\233\256\351\205\215\347\275\256\346\226\207\344\273\266.html-Yb36aCmH.js" new file mode 100644 index 0000000..b51f4db --- /dev/null +++ "b/assets/project_\351\241\271\347\233\256\351\205\215\347\275\256\346\226\207\344\273\266.html-Yb36aCmH.js" @@ -0,0 +1 @@ +import{_ as t,o as e,c as o,a as c}from"./app-x8p6wK6B.js";const p={},a=c('

[project]项目配置文件

2023-7-11

配置 pre-commit 以及setup.py setup.cfg, pyproject.toml

https://pre-commit.com/#python

使用flake8检查python代码格式 问题: 变量名确实长,因此超过了一行120字符限制

解决方案: 在这行后面加上 # noqa

https://github.com/PyCQA/flake8 ines that contain a # noqa comment at the end will not issue warnings.

',7),n=[a];function r(s,_){return e(),o("div",null,n)}const l=t(p,[["render",r],["__file","project_项目配置文件.html.vue"]]);export{l as default}; diff --git "a/assets/pydantic\347\211\271\346\256\212\351\252\214\350\257\201.html-HkEdQiyu.js" "b/assets/pydantic\347\211\271\346\256\212\351\252\214\350\257\201.html-HkEdQiyu.js" new file mode 100644 index 0000000..e7b79f6 --- /dev/null +++ "b/assets/pydantic\347\211\271\346\256\212\351\252\214\350\257\201.html-HkEdQiyu.js" @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-71f31afa","path":"/python/pydantic%E7%89%B9%E6%AE%8A%E9%AA%8C%E8%AF%81.html","title":"pydantic特殊验证","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"python/pydantic特殊验证.md"}');export{t as data}; diff --git "a/assets/pydantic\347\211\271\346\256\212\351\252\214\350\257\201.html-kxDwQ-i1.js" "b/assets/pydantic\347\211\271\346\256\212\351\252\214\350\257\201.html-kxDwQ-i1.js" new file mode 100644 index 0000000..b7325c5 --- /dev/null +++ "b/assets/pydantic\347\211\271\346\256\212\351\252\214\350\257\201.html-kxDwQ-i1.js" @@ -0,0 +1 @@ +import{_ as s,o as n,c,b as t,d as e}from"./app-x8p6wK6B.js";const a="/assets/280304492836402-eUylmFoN.png",_="/assets/267835701625494-p4jK1vfP.png",o={},i=t("h1",{id:"pydantic特殊验证",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#pydantic特殊验证","aria-hidden":"true"},"#"),e(" pydantic特殊验证")],-1),l=t("p",null,[t("img",{src:a,alt:""})],-1),d=t("p",null,[e("这里对应每种的验证是不一样的,例如,对于一般的config,lable的长度限制为12 对switch,则限制为40 "),t("img",{src:_,alt:""})],-1),r=t("p",null,"实测,使用时,已经转为MESFieldConfig 类型,会验证max_length=12,所以只能在基类去掉max_length的校验,改为单独编写",-1),p=[i,l,d,r];function h(m,f){return n(),c("div",null,p)}const g=s(o,[["render",h],["__file","pydantic特殊验证.html.vue"]]);export{g as default}; diff --git "a/assets/python_\344\273\245\345\233\276\346\220\234\345\233\276\347\263\273\347\273\237.html-TZtQBxRT.js" "b/assets/python_\344\273\245\345\233\276\346\220\234\345\233\276\347\263\273\347\273\237.html-TZtQBxRT.js" new file mode 100644 index 0000000..36c6ac1 --- /dev/null +++ "b/assets/python_\344\273\245\345\233\276\346\220\234\345\233\276\347\263\273\347\273\237.html-TZtQBxRT.js" @@ -0,0 +1 @@ +import{_ as e,o,c as _,b as t,d as s}from"./app-x8p6wK6B.js";const n="/assets/20220914154132929_32258-sJ3-Cxv6.png",c={},a=t("h1",{id:"python-以图搜图系统",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#python-以图搜图系统","aria-hidden":"true"},"#"),s(" [python]以图搜图系统")],-1),r=t("blockquote",null,[t("p",null,"https://blog.51cto.com/u_1539555/3246466?abTest=51cto")],-1),l=t("p",null,[t("img",{src:n,alt:""})],-1),h=[a,r,l];function d(i,p){return o(),_("div",null,h)}const m=e(c,[["render",d],["__file","python_以图搜图系统.html.vue"]]);export{m as default}; diff --git "a/assets/python_\344\273\245\345\233\276\346\220\234\345\233\276\347\263\273\347\273\237.html-o2hDWyzD.js" "b/assets/python_\344\273\245\345\233\276\346\220\234\345\233\276\347\263\273\347\273\237.html-o2hDWyzD.js" new file mode 100644 index 0000000..225a1c1 --- /dev/null +++ "b/assets/python_\344\273\245\345\233\276\346\220\234\345\233\276\347\263\273\347\273\237.html-o2hDWyzD.js" @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-3c9f71df","path":"/web/python_%E4%BB%A5%E5%9B%BE%E6%90%9C%E5%9B%BE%E7%B3%BB%E7%BB%9F.html","title":"[python]以图搜图系统","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"web/[python]以图搜图系统.md"}');export{t as data}; diff --git "a/assets/pythongui-\347\210\266\345\255\220\350\277\233\347\250\213\344\270\216\345\255\244\345\204\277\350\277\233\347\250\213.html-NY-oSU1C.js" "b/assets/pythongui-\347\210\266\345\255\220\350\277\233\347\250\213\344\270\216\345\255\244\345\204\277\350\277\233\347\250\213.html-NY-oSU1C.js" new file mode 100644 index 0000000..593316e --- /dev/null +++ "b/assets/pythongui-\347\210\266\345\255\220\350\277\233\347\250\213\344\270\216\345\255\244\345\204\277\350\277\233\347\250\213.html-NY-oSU1C.js" @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-6b835d08","path":"/python/pythongui-%E7%88%B6%E5%AD%90%E8%BF%9B%E7%A8%8B%E4%B8%8E%E5%AD%A4%E5%84%BF%E8%BF%9B%E7%A8%8B.html","title":"pythongui-父子进程与孤儿进程","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"python/pythongui-父子进程与孤儿进程.md"}');export{t as data}; diff --git "a/assets/pythongui-\347\210\266\345\255\220\350\277\233\347\250\213\344\270\216\345\255\244\345\204\277\350\277\233\347\250\213.html-gjByGcrm.js" "b/assets/pythongui-\347\210\266\345\255\220\350\277\233\347\250\213\344\270\216\345\255\244\345\204\277\350\277\233\347\250\213.html-gjByGcrm.js" new file mode 100644 index 0000000..f48bff8 --- /dev/null +++ "b/assets/pythongui-\347\210\266\345\255\220\350\277\233\347\250\213\344\270\216\345\255\244\345\204\277\350\277\233\347\250\213.html-gjByGcrm.js" @@ -0,0 +1 @@ +import{_ as o,o as e,c as s,b as t,d as n}from"./app-x8p6wK6B.js";const _="/assets/20220314140628431_1059217444-CI6eIG4g.png",c={},l=t("h1",{id:"pythongui-父子进程与孤儿进程",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#pythongui-父子进程与孤儿进程","aria-hidden":"true"},"#"),n(" pythongui-父子进程与孤儿进程")],-1),i=t("blockquote",null,[t("p",null,"https://www.cnblogs.com/Tour/p/5180801.html")],-1),p=t("p",null,"先介绍一下我的项目,项目的目标是使用一台计算机,通过usb集线板,控制n台手机 其中不同的任务封装为不同的程序,在python gui中通过subprocess.Popen 方法异步调用",-1),u=t("p",null,"这些python程序会通过adb库获取到所有已经连接到的安卓手机,并通过multiprocessing库并行执行相应的任务",-1),h=t("p",null,"这时,有一个需求是停止当前的演示程序,我们知道,通过subprocess.Popen方法可以获取一个进程对象,通过调用kill方法或terminate方法即可杀死进程",-1),r=t("p",null,[t("img",{src:_,alt:""})],-1),a=t("p",null,"但是随之而来的,就是子进程变为孤儿进程,仍在继续执行",-1),d=t("p",null,"通过查阅相关资料,我了解到可以设置deamon=True来使主进程在正常退出时,子进程也退出,但是我这里是中断操作",-1),m=[l,i,p,u,h,r,a,d];function g(b,f){return e(),s("div",null,m)}const x=o(c,[["render",g],["__file","pythongui-父子进程与孤儿进程.html.vue"]]);export{x as default}; diff --git "a/assets/python\344\273\273\345\212\241\351\230\237\345\210\227.html-MW7lRocT.js" "b/assets/python\344\273\273\345\212\241\351\230\237\345\210\227.html-MW7lRocT.js" new file mode 100644 index 0000000..513c938 --- /dev/null +++ "b/assets/python\344\273\273\345\212\241\351\230\237\345\210\227.html-MW7lRocT.js" @@ -0,0 +1,13 @@ +import{_ as a,o as e,c as i,a as d}from"./app-x8p6wK6B.js";const n={},r=d(`

任务队列

流程

最初版本

1.通过接口获取到今天的数据(.csv)

  1. 执行程序

aps版本

定义一个定时任务, 然后每天稳定拉取数据,到任务队列中, 程序读取此队列, 并将爬取结果保存到结果队列

四个进程

  • 任务获取进程
  • 爬虫进程
  • 上传进程
  • 监控进程

两个队列

  • 任务队列
  • 结果队列

这种方式看起来非常专业, 但是有时候临时需要跑一部分数据时, 就会很麻烦, 因此我想这在队列这里解决, 从python 自带的队列替换为 redis的list

redis 版本

在将python 的队列更改为redis 后, 我又编写了 redis_push.py , 可以手动将文件中的数据推送到redis 队列中, 非常的好用

但是过了周六周日两天后, 我发现 APScheduler 又出现了bug, 没有按时拉取数据, 我不由得怀疑这个库的稳定性 ,因此我又回到了crontab

crontab 版本

经过了近一个月, 多次的更改,我探究了最适合的方案

需要有以下几个优点

  • 可随时跑残缺数据 python run.py file
  • 网站变化频繁, 只需修改spider 文件即可, 比较方便

+- source_data/      原始数据
+- aaa/   爬虫aaa
+    --  spider.py  爬虫主体, 仅负责爬取数据
+    --  main.py     读取文件, 解析数据, 上传数据等等
+    --  data/        爬到的数据
+- bbb/
+    --  spider.py
+    --  main.py     
+    --  data/
+- download_data.py  拉取原始数据, 使用crontab 例行化
+
+
`,20),s=[r];function l(t,h){return e(),i("div",null,s)}const o=a(n,[["render",l],["__file","python任务队列.html.vue"]]);export{o as default}; diff --git "a/assets/python\344\273\273\345\212\241\351\230\237\345\210\227.html-QsoxeOWC.js" "b/assets/python\344\273\273\345\212\241\351\230\237\345\210\227.html-QsoxeOWC.js" new file mode 100644 index 0000000..fb319ba --- /dev/null +++ "b/assets/python\344\273\273\345\212\241\351\230\237\345\210\227.html-QsoxeOWC.js" @@ -0,0 +1 @@ +const l=JSON.parse('{"key":"v-7bcdc38f","path":"/python/python%E4%BB%BB%E5%8A%A1%E9%98%9F%E5%88%97.html","title":"任务队列","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"最初版本","slug":"最初版本","link":"#最初版本","children":[]},{"level":2,"title":"aps版本","slug":"aps版本","link":"#aps版本","children":[{"level":3,"title":"四个进程","slug":"四个进程","link":"#四个进程","children":[]},{"level":3,"title":"两个队列","slug":"两个队列","link":"#两个队列","children":[]}]},{"level":2,"title":"redis 版本","slug":"redis-版本","link":"#redis-版本","children":[]},{"level":2,"title":"crontab 版本","slug":"crontab-版本","link":"#crontab-版本","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"python/python任务队列.md"}');export{l as data}; diff --git "a/assets/python\344\275\277\347\224\250\346\255\243\345\210\231\350\277\207\346\273\244\350\241\250\346\203\205\347\254\246\345\217\267.html-0YAfmiVZ.js" "b/assets/python\344\275\277\347\224\250\346\255\243\345\210\231\350\277\207\346\273\244\350\241\250\346\203\205\347\254\246\345\217\267.html-0YAfmiVZ.js" new file mode 100644 index 0000000..3c9e223 --- /dev/null +++ "b/assets/python\344\275\277\347\224\250\346\255\243\345\210\231\350\277\207\346\273\244\350\241\250\346\203\205\347\254\246\345\217\267.html-0YAfmiVZ.js" @@ -0,0 +1,25 @@ +import{_ as e,o as n,c as u,a as i}from"./app-x8p6wK6B.js";const s={},t=i(`

python使用正则过滤表情符号

def remove_emojis(data):
+    emoj = re.compile("["
+        u"\\U0001F600-\\U0001F64F"  # emoticons
+        u"\\U0001F300-\\U0001F5FF"  # symbols & pictographs
+        u"\\U0001F680-\\U0001F6FF"  # transport & map symbols
+        u"\\U0001F1E0-\\U0001F1FF"  # flags (iOS)
+        # u"\\U00002500-\\U00002BEF"  # chinese char
+        u"\\U00002702-\\U000027B0"
+        u"\\U00002702-\\U000027B0"
+        # u"\\U000024C2-\\U0001F251" //中文
+        u"\\U0001f926-\\U0001f937"
+        u"\\U00010000-\\U0010ffff"
+        u"\\u2640-\\u2642" 
+        u"\\u2600-\\u2B55"
+        u"\\u200d"
+        u"\\u23cf"
+        u"\\u23e9"
+        u"\\u231a"
+        u"\\ufe0f"  # dingbats
+        u"\\u3030"
+                      "]+", re.UNICODE)
+    return re.sub(emoj, '', data)
+
+
+
`,2),o=[t];function d(l,a){return n(),u("div",null,o)}const v=e(s,[["render",d],["__file","python使用正则过滤表情符号.html.vue"]]);export{v as default}; diff --git "a/assets/python\344\275\277\347\224\250\346\255\243\345\210\231\350\277\207\346\273\244\350\241\250\346\203\205\347\254\246\345\217\267.html-enwOLL_3.js" "b/assets/python\344\275\277\347\224\250\346\255\243\345\210\231\350\277\207\346\273\244\350\241\250\346\203\205\347\254\246\345\217\267.html-enwOLL_3.js" new file mode 100644 index 0000000..75d8ba0 --- /dev/null +++ "b/assets/python\344\275\277\347\224\250\346\255\243\345\210\231\350\277\207\346\273\244\350\241\250\346\203\205\347\254\246\345\217\267.html-enwOLL_3.js" @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-26816455","path":"/python/python%E4%BD%BF%E7%94%A8%E6%AD%A3%E5%88%99%E8%BF%87%E6%BB%A4%E8%A1%A8%E6%83%85%E7%AC%A6%E5%8F%B7.html","title":"python使用正则过滤表情符号","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"python/python使用正则过滤表情符号.md"}');export{t as data}; diff --git "a/assets/python\345\257\271\346\257\224\344\270\244\344\270\252\346\227\266\351\227\264\345\255\227\347\254\246\344\270\262.html--3T0cbqc.js" "b/assets/python\345\257\271\346\257\224\344\270\244\344\270\252\346\227\266\351\227\264\345\255\227\347\254\246\344\270\262.html--3T0cbqc.js" new file mode 100644 index 0000000..27b6c7b --- /dev/null +++ "b/assets/python\345\257\271\346\257\224\344\270\244\344\270\252\346\227\266\351\227\264\345\255\227\347\254\246\344\270\262.html--3T0cbqc.js" @@ -0,0 +1,7 @@ +import{_ as n,r as a,o,c as i,b as e,d as r,e as s,a as d}from"./app-x8p6wK6B.js";const c={},l=d(`

python对比两个时间字符串

import time
+t1 = time.strptime(time1, "%Y%m%d")
+t2 = time.strptime(time2, "%Y%m%d")
+
+t1 > t2
+
+
`,2),m={href:"https://docs.python.org/zh-cn/3/howto/sorting.html",target:"_blank",rel:"noopener noreferrer"};function _(h,u){const t=a("ExternalLinkIcon");return o(),i("div",null,[l,e("p",null,[e("a",m,[r("官方文档"),s(t)])])])}const v=n(c,[["render",_],["__file","python对比两个时间字符串.html.vue"]]);export{v as default}; diff --git "a/assets/python\345\257\271\346\257\224\344\270\244\344\270\252\346\227\266\351\227\264\345\255\227\347\254\246\344\270\262.html-6-UMo1AV.js" "b/assets/python\345\257\271\346\257\224\344\270\244\344\270\252\346\227\266\351\227\264\345\255\227\347\254\246\344\270\262.html-6-UMo1AV.js" new file mode 100644 index 0000000..caef311 --- /dev/null +++ "b/assets/python\345\257\271\346\257\224\344\270\244\344\270\252\346\227\266\351\227\264\345\255\227\347\254\246\344\270\262.html-6-UMo1AV.js" @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-39784c24","path":"/python/python%E5%AF%B9%E6%AF%94%E4%B8%A4%E4%B8%AA%E6%97%B6%E9%97%B4%E5%AD%97%E7%AC%A6%E4%B8%B2.html","title":"python对比两个时间字符串","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"python/python对比两个时间字符串.md"}');export{t as data}; diff --git "a/assets/python\346\211\223\345\215\260\350\241\214\345\217\267.html-A1gPX7eV.js" "b/assets/python\346\211\223\345\215\260\350\241\214\345\217\267.html-A1gPX7eV.js" new file mode 100644 index 0000000..87463ea --- /dev/null +++ "b/assets/python\346\211\223\345\215\260\350\241\214\345\217\267.html-A1gPX7eV.js" @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-2a51215c","path":"/python/python%E6%89%93%E5%8D%B0%E8%A1%8C%E5%8F%B7.html","title":"skill","lang":"en-US","frontmatter":{},"headers":[{"level":3,"title":"python 打印行号","slug":"python-打印行号","link":"#python-打印行号","children":[]},{"level":3,"title":"python 获取当前脚本或其他模块的所有类","slug":"python-获取当前脚本或其他模块的所有类","link":"#python-获取当前脚本或其他模块的所有类","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"python/python打印行号.md"}');export{t as data}; diff --git "a/assets/python\346\211\223\345\215\260\350\241\214\345\217\267.html-o7fc7YJ0.js" "b/assets/python\346\211\223\345\215\260\350\241\214\345\217\267.html-o7fc7YJ0.js" new file mode 100644 index 0000000..7e54d0e --- /dev/null +++ "b/assets/python\346\211\223\345\215\260\350\241\214\345\217\267.html-o7fc7YJ0.js" @@ -0,0 +1,53 @@ +import{_ as n,o as s,c as a,a as t}from"./app-x8p6wK6B.js";const p={},e=t(`

skill

python 打印行号

import sys
+
+print(sys._getframe().f_code.co_name)  # 当前函数名
+print(sys._getframe().f_lineno)  # 当前行号
+

python 获取当前脚本或其他模块的所有类

背景: 一个py文件里有40+个类, 需要创建实例并执行共有的run方法, 简单的方法是写40+行代码完成任务, 也可以通过python高阶函数使用


+import sys, inspect
+
+
+def get_class(current_module):
+    cls = []
+    print("class:",end='')
+    for name, obj in inspect.getmembers(current_module):
+        if inspect.isclass(obj):
+            print(name, end=',')
+            cls.append(obj)
+    print()
+    return cls
+
+
+class A():
+    def run(self):
+        print("current class:", self.__class__.__name__)
+
+
+class B():
+    def run(self):
+        print("current class:", self.__class__.__name__)
+
+
+class C():
+    def run(self):
+        print("current class:", self.__class__.__name__)
+
+
+class D():
+    def run(self):
+        print("current class:", self.__class__.__name__)
+
+
+if __name__ == '__main__':
+    current_module = sys.modules[__name__]  获取当前文件对象
+
+    for cls in get_class(current_module):
+        cls().run()
+
+
+

运行结果

class:A,B,C,D,
+current class: A
+current class: B
+current class: C
+current class: D
+
+
`,8),c=[e];function o(l,i){return s(),a("div",null,c)}const d=n(p,[["render",o],["__file","python打印行号.html.vue"]]);export{d as default}; diff --git a/assets/pytorch.html-BGmtra1R.js b/assets/pytorch.html-BGmtra1R.js new file mode 100644 index 0000000..72108f9 --- /dev/null +++ b/assets/pytorch.html-BGmtra1R.js @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-d6e05f70","path":"/python/cv/pytorch.html","title":"pytorch","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"python/cv/pytorch.md"}');export{t as data}; diff --git a/assets/pytorch.html-T61jQByQ.js b/assets/pytorch.html-T61jQByQ.js new file mode 100644 index 0000000..f28f98e --- /dev/null +++ b/assets/pytorch.html-T61jQByQ.js @@ -0,0 +1 @@ +import{_ as t,o as c,c as o,b as e,d as r}from"./app-x8p6wK6B.js";const a={},s=e("h1",{id:"pytorch",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#pytorch","aria-hidden":"true"},"#"),r(" pytorch")],-1),n=[s];function _(h,d){return c(),o("div",null,n)}const l=t(a,[["render",_],["__file","pytorch.html.vue"]]);export{l as default}; diff --git "a/assets/shinobi-\345\274\200\346\272\220NVR.html-JZKGSKui.js" "b/assets/shinobi-\345\274\200\346\272\220NVR.html-JZKGSKui.js" new file mode 100644 index 0000000..0db68fa --- /dev/null +++ "b/assets/shinobi-\345\274\200\346\272\220NVR.html-JZKGSKui.js" @@ -0,0 +1 @@ +import{_ as s,o as t,c as n,b as e,d as o}from"./app-x8p6wK6B.js";const i="/assets/378723495836805-Akg88FZH.png",_={},a=e("h1",{id:"shinobi-开源nvr",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#shinobi-开源nvr","aria-hidden":"true"},"#"),o(" shinobi-开源NVR")],-1),c=e("p",null,[e("img",{src:i,alt:""})],-1),r=[a,c];function h(d,l){return t(),n("div",null,r)}const m=s(_,[["render",h],["__file","shinobi-开源NVR.html.vue"]]);export{m as default}; diff --git "a/assets/shinobi-\345\274\200\346\272\220NVR.html-mGkOVpVm.js" "b/assets/shinobi-\345\274\200\346\272\220NVR.html-mGkOVpVm.js" new file mode 100644 index 0000000..dbac301 --- /dev/null +++ "b/assets/shinobi-\345\274\200\346\272\220NVR.html-mGkOVpVm.js" @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-4a06d9af","path":"/video/shinobi-%E5%BC%80%E6%BA%90NVR.html","title":"shinobi-开源NVR","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"video/shinobi-开源NVR.md"}');export{t as data}; diff --git a/assets/style-0PEmhfVm.css b/assets/style-0PEmhfVm.css new file mode 100644 index 0000000..193f99a --- /dev/null +++ b/assets/style-0PEmhfVm.css @@ -0,0 +1 @@ +:root{--back-to-top-z-index: 5;--back-to-top-color: #3eaf7c;--back-to-top-color-hover: #71cda3}.back-to-top{cursor:pointer;position:fixed;bottom:2rem;right:2.5rem;width:2rem;height:1.2rem;background-color:var(--back-to-top-color);-webkit-mask:url("data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2049.484%2028.284'%3e%3cg%20transform='translate(-229%20-126.358)'%20fill='currentColor'%3e%3crect%20width='35'%20height='5'%20rx='2'%20transform='rotate(-45%20296.902%20-200.874)'/%3e%3crect%20width='35'%20height='5'%20rx='2'%20transform='rotate(-135%20169.502%2020.377)'/%3e%3c/g%3e%3c/svg%3e") no-repeat;mask:url("data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2049.484%2028.284'%3e%3cg%20transform='translate(-229%20-126.358)'%20fill='currentColor'%3e%3crect%20width='35'%20height='5'%20rx='2'%20transform='rotate(-45%20296.902%20-200.874)'/%3e%3crect%20width='35'%20height='5'%20rx='2'%20transform='rotate(-135%20169.502%2020.377)'/%3e%3c/g%3e%3c/svg%3e") no-repeat;z-index:var(--back-to-top-z-index)}.back-to-top:hover{background-color:var(--back-to-top-color-hover)}@media (max-width: 959px){.back-to-top{display:none}}@media print{.back-to-top{display:none}}.back-to-top-enter-active,.back-to-top-leave-active{transition:opacity .3s}.back-to-top-enter-from,.back-to-top-leave-to{opacity:0}:root{--external-link-icon-color: #aaa}.external-link-icon{position:relative;display:inline-block;color:var(--external-link-icon-color);vertical-align:middle;top:-1px}@media print{.external-link-icon{display:none}}.external-link-icon-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0;-webkit-user-select:none;-moz-user-select:none;user-select:none}:root{--nprogress-color: #29d;--nprogress-z-index: 1031}#nprogress{pointer-events:none}#nprogress .bar{background:var(--nprogress-color);position:fixed;z-index:var(--nprogress-z-index);top:0;left:0;width:100%;height:2px}:root{--c-brand: #3eaf7c;--c-brand-light: #4abf8a;--c-bg: #ffffff;--c-bg-light: #f3f4f5;--c-bg-lighter: #eeeeee;--c-bg-dark: #ebebec;--c-bg-darker: #e6e6e6;--c-bg-navbar: var(--c-bg);--c-bg-sidebar: var(--c-bg);--c-bg-arrow: #cccccc;--c-text: #2c3e50;--c-text-accent: var(--c-brand);--c-text-light: #3a5169;--c-text-lighter: #4e6e8e;--c-text-lightest: #6a8bad;--c-text-quote: #999999;--c-border: #eaecef;--c-border-dark: #dfe2e5;--c-tip: #42b983;--c-tip-bg: var(--c-bg-light);--c-tip-title: var(--c-text);--c-tip-text: var(--c-text);--c-tip-text-accent: var(--c-text-accent);--c-warning: #ffc310;--c-warning-bg: #fffae3;--c-warning-bg-light: #fff3ba;--c-warning-bg-lighter: #fff0b0;--c-warning-border-dark: #f7dc91;--c-warning-details-bg: #fff5ca;--c-warning-title: #f1b300;--c-warning-text: #746000;--c-warning-text-accent: #edb100;--c-warning-text-light: #c1971c;--c-warning-text-quote: #ccab49;--c-danger: #f11e37;--c-danger-bg: #ffe0e0;--c-danger-bg-light: #ffcfde;--c-danger-bg-lighter: #ffc9c9;--c-danger-border-dark: #f1abab;--c-danger-details-bg: #ffd4d4;--c-danger-title: #ed1e2c;--c-danger-text: #660000;--c-danger-text-accent: #bd1a1a;--c-danger-text-light: #b5474d;--c-danger-text-quote: #c15b5b;--c-details-bg: #eeeeee;--c-badge-tip: var(--c-tip);--c-badge-warning: #ecc808;--c-badge-warning-text: var(--c-bg);--c-badge-danger: #dc2626;--c-badge-danger-text: var(--c-bg);--t-color: .3s ease;--t-transform: .3s ease;--code-bg-color: #282c34;--code-hl-bg-color: rgba(0, 0, 0, .66);--code-ln-color: #9e9e9e;--code-ln-wrapper-width: 3.5rem;--font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;--font-family-code: Consolas, Monaco, "Andale Mono", "Ubuntu Mono", monospace;--navbar-height: 3.6rem;--navbar-padding-v: .7rem;--navbar-padding-h: 1.5rem;--sidebar-width: 20rem;--sidebar-width-mobile: calc(var(--sidebar-width) * .82);--content-width: 740px;--homepage-width: 960px}.back-to-top{--back-to-top-color: var(--c-brand);--back-to-top-color-hover: var(--c-brand-light)}.DocSearch{--docsearch-primary-color: var(--c-brand);--docsearch-text-color: var(--c-text);--docsearch-highlight-color: var(--c-brand);--docsearch-muted-color: var(--c-text-quote);--docsearch-container-background: rgba(9, 10, 17, .8);--docsearch-modal-background: var(--c-bg-light);--docsearch-searchbox-background: var(--c-bg-lighter);--docsearch-searchbox-focus-background: var(--c-bg);--docsearch-searchbox-shadow: inset 0 0 0 2px var(--c-brand);--docsearch-hit-color: var(--c-text-light);--docsearch-hit-active-color: var(--c-bg);--docsearch-hit-background: var(--c-bg);--docsearch-hit-shadow: 0 1px 3px 0 var(--c-border-dark);--docsearch-footer-background: var(--c-bg)}.external-link-icon{--external-link-icon-color: var(--c-text-quote)}.medium-zoom-overlay{--medium-zoom-bg-color: var(--c-bg)}#nprogress{--nprogress-color: var(--c-brand)}.pwa-popup{--pwa-popup-text-color: var(--c-text);--pwa-popup-bg-color: var(--c-bg);--pwa-popup-border-color: var(--c-brand);--pwa-popup-shadow: 0 4px 16px var(--c-brand);--pwa-popup-btn-text-color: var(--c-bg);--pwa-popup-btn-bg-color: var(--c-brand);--pwa-popup-btn-hover-bg-color: var(--c-brand-light)}.search-box{--search-bg-color: var(--c-bg);--search-accent-color: var(--c-brand);--search-text-color: var(--c-text);--search-border-color: var(--c-border);--search-item-text-color: var(--c-text-lighter);--search-item-focus-bg-color: var(--c-bg-light)}html.dark{--c-brand: #3aa675;--c-brand-light: #349469;--c-bg: #22272e;--c-bg-light: #2b313a;--c-bg-lighter: #262c34;--c-bg-dark: #343b44;--c-bg-darker: #37404c;--c-text: #adbac7;--c-text-light: #96a7b7;--c-text-lighter: #8b9eb0;--c-text-lightest: #8094a8;--c-border: #3e4c5a;--c-border-dark: #34404c;--c-tip: #318a62;--c-warning: #e0ad15;--c-warning-bg: #2d2f2d;--c-warning-bg-light: #423e2a;--c-warning-bg-lighter: #44442f;--c-warning-border-dark: #957c35;--c-warning-details-bg: #39392d;--c-warning-title: #fdca31;--c-warning-text: #d8d96d;--c-warning-text-accent: #ffbf00;--c-warning-text-light: #ddb84b;--c-warning-text-quote: #ccab49;--c-danger: #fc1e38;--c-danger-bg: #39232c;--c-danger-bg-light: #4b2b35;--c-danger-bg-lighter: #553040;--c-danger-border-dark: #a25151;--c-danger-details-bg: #482936;--c-danger-title: #fc2d3b;--c-danger-text: #ea9ca0;--c-danger-text-accent: #fd3636;--c-danger-text-light: #d9777c;--c-danger-text-quote: #d56b6b;--c-details-bg: #323843;--c-badge-warning: var(--c-warning);--c-badge-warning-text: #3c2e05;--c-badge-danger: var(--c-danger);--c-badge-danger-text: #401416;--code-hl-bg-color: #363b46}html.dark .DocSearch{--docsearch-logo-color: var(--c-text);--docsearch-modal-shadow: inset 1px 1px 0 0 #2c2e40, 0 3px 8px 0 #000309;--docsearch-key-shadow: inset 0 -2px 0 0 #282d55, inset 0 0 1px 1px #51577d, 0 2px 2px 0 rgba(3, 4, 9, .3);--docsearch-key-gradient: linear-gradient(-225deg, #444950, #1c1e21);--docsearch-footer-shadow: inset 0 1px 0 0 rgba(73, 76, 106, .5), 0 -4px 8px 0 rgba(0, 0, 0, .2)}html,body{padding:0;margin:0;background-color:var(--c-bg);transition:background-color var(--t-color)}html.dark{color-scheme:dark}html{font-size:16px}body{font-family:var(--font-family);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-size:1rem;color:var(--c-text)}a{font-weight:500;color:var(--c-text-accent);text-decoration:none;overflow-wrap:break-word}p a code{font-weight:400;color:var(--c-text-accent)}kbd{font-family:var(--font-family-code);color:var(--c-text);background:var(--c-bg-lighter);border:solid .15rem var(--c-border-dark);border-bottom:solid .25rem var(--c-border-dark);border-radius:.15rem;padding:0 .15em}code{font-family:var(--font-family-code);color:var(--c-text-lighter);padding:.25rem .5rem;margin:0;font-size:.85em;background-color:var(--c-bg-light);border-radius:3px;overflow-wrap:break-word;transition:background-color var(--t-color)}blockquote{font-size:1rem;color:var(--c-text-quote);border-left:.2rem solid var(--c-border-dark);margin:1rem 0;padding:.25rem 0 .25rem 1rem;overflow-wrap:break-word}blockquote>p{margin:0}ul,ol{padding-left:1.2em}strong{font-weight:600}h1,h2,h3,h4,h5,h6{font-weight:600;line-height:1.25;overflow-wrap:break-word}h1:focus-visible,h2:focus-visible,h3:focus-visible,h4:focus-visible,h5:focus-visible,h6:focus-visible{outline:none}h1:hover .header-anchor,h2:hover .header-anchor,h3:hover .header-anchor,h4:hover .header-anchor,h5:hover .header-anchor,h6:hover .header-anchor{opacity:1}h1{font-size:2.2rem}h2{font-size:1.65rem;padding-bottom:.3rem;border-bottom:1px solid var(--c-border);transition:border-color var(--t-color)}h3{font-size:1.35rem}h4{font-size:1.15rem}h5{font-size:1.05rem}h6{font-size:1rem}a.header-anchor{font-size:.85em;float:left;margin-left:-.87em;padding-right:.23em;margin-top:.125em;opacity:0;-webkit-user-select:none;-moz-user-select:none;user-select:none}@media print{a.header-anchor{display:none}}a.header-anchor:hover{text-decoration:none}a.header-anchor:focus-visible{opacity:1}@media print{a[href^="http://"]:after,a[href^="https://"]:after{content:" (" attr(href) ") "}}p,ul,ol{line-height:1.7;overflow-wrap:break-word}hr{border:0;border-top:1px solid var(--c-border)}table{border-collapse:collapse;margin:1rem 0;display:block;overflow-x:auto;transition:border-color var(--t-color)}tr{border-top:1px solid var(--c-border-dark);transition:border-color var(--t-color)}tr:nth-child(2n){background-color:var(--c-bg-light);transition:background-color var(--t-color)}tr:nth-child(2n) code{background-color:var(--c-bg-dark)}th,td{padding:.6em 1em;border:1px solid var(--c-border-dark);transition:border-color var(--t-color)}.arrow{display:inline-block;width:0;height:0}.arrow.up{border-left:4px solid transparent;border-right:4px solid transparent;border-bottom:6px solid var(--c-bg-arrow)}.arrow.down{border-left:4px solid transparent;border-right:4px solid transparent;border-top:6px solid var(--c-bg-arrow)}.arrow.right{border-top:4px solid transparent;border-bottom:4px solid transparent;border-left:6px solid var(--c-bg-arrow)}.arrow.left{border-top:4px solid transparent;border-bottom:4px solid transparent;border-right:6px solid var(--c-bg-arrow)}.badge{display:inline-block;font-size:14px;font-weight:600;height:18px;line-height:18px;border-radius:3px;padding:0 6px;color:var(--c-bg);vertical-align:top;transition:color var(--t-color),background-color var(--t-color)}.badge.tip{background-color:var(--c-badge-tip)}.badge.warning{background-color:var(--c-badge-warning);color:var(--c-badge-warning-text)}.badge.danger{background-color:var(--c-badge-danger);color:var(--c-badge-danger-text)}.badge+.badge{margin-left:5px}code[class*=language-],pre[class*=language-]{color:#ccc;background:none;font-family:var(--font-family-code);font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;hyphens:none}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto}:not(pre)>code[class*=language-],pre[class*=language-]{background:#2d2d2d}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal}.token.comment,.token.block-comment,.token.prolog,.token.doctype,.token.cdata{color:#999}.token.punctuation{color:#ccc}.token.tag,.token.attr-name,.token.namespace,.token.deleted{color:#ec5975}.token.function-name{color:#6196cc}.token.boolean,.token.number,.token.function{color:#f08d49}.token.property,.token.class-name,.token.constant,.token.symbol{color:#f8c555}.token.selector,.token.important,.token.atrule,.token.keyword,.token.builtin{color:#cc99cd}.token.string,.token.char,.token.attr-value,.token.regex,.token.variable{color:#7ec699}.token.operator,.token.entity,.token.url{color:#67cdcc}.token.important,.token.bold{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}.token.inserted{color:#3eaf7c}.theme-default-content pre,.theme-default-content pre[class*=language-]{line-height:1.375;padding:1.3rem 1.5rem;margin:.85rem 0;border-radius:6px;overflow:auto}.theme-default-content pre code,.theme-default-content pre[class*=language-] code{color:#fff;padding:0;background-color:transparent!important;border-radius:0;overflow-wrap:unset;-webkit-font-smoothing:auto;-moz-osx-font-smoothing:auto}.theme-default-content .line-number{font-family:var(--font-family-code)}div[class*=language-]{position:relative;background-color:var(--code-bg-color);border-radius:6px}div[class*=language-]:before{content:attr(data-ext);position:absolute;z-index:3;top:.8em;right:1em;font-size:.75rem;color:var(--code-ln-color)}div[class*=language-] pre,div[class*=language-] pre[class*=language-]{background:transparent!important;position:relative;z-index:1}div[class*=language-] .highlight-lines{-webkit-user-select:none;-moz-user-select:none;user-select:none;padding-top:1.3rem;position:absolute;top:0;left:0;width:100%;line-height:1.375}div[class*=language-] .highlight-lines .highlight-line{background-color:var(--code-hl-bg-color)}div[class*=language-]:not(.line-numbers-mode) .line-numbers{display:none}div[class*=language-].line-numbers-mode .highlight-lines .highlight-line{position:relative}div[class*=language-].line-numbers-mode .highlight-lines .highlight-line:before{content:" ";position:absolute;z-index:2;left:0;top:0;display:block;width:var(--code-ln-wrapper-width);height:100%}div[class*=language-].line-numbers-mode pre{margin-left:var(--code-ln-wrapper-width);padding-left:1rem;vertical-align:middle}div[class*=language-].line-numbers-mode .line-numbers{position:absolute;top:0;width:var(--code-ln-wrapper-width);text-align:center;color:var(--code-ln-color);padding-top:1.25rem;line-height:1.375;counter-reset:line-number}div[class*=language-].line-numbers-mode .line-numbers .line-number{position:relative;z-index:3;-webkit-user-select:none;-moz-user-select:none;user-select:none;height:1.375em}div[class*=language-].line-numbers-mode .line-numbers .line-number:before{counter-increment:line-number;content:counter(line-number);font-size:.85em}div[class*=language-].line-numbers-mode:after{content:"";position:absolute;top:0;left:0;width:var(--code-ln-wrapper-width);height:100%;border-radius:6px 0 0 6px;border-right:1px solid var(--code-hl-bg-color)}@media (max-width: 419px){.theme-default-content div[class*=language-]{margin:.85rem -1.5rem;border-radius:0}}.code-group__nav{margin-top:.85rem;margin-bottom:calc(-1.7rem - 6px);padding-bottom:calc(1.7rem - 6px);padding-left:10px;padding-top:10px;border-top-left-radius:6px;border-top-right-radius:6px;background-color:var(--code-bg-color)}.code-group__ul{margin:auto 0;padding-left:0;display:inline-flex;list-style:none}.code-group__nav-tab{border:0;padding:5px;cursor:pointer;background-color:transparent;font-size:.85em;line-height:1.4;color:#ffffffe6;font-weight:600}.code-group__nav-tab:focus{outline:none}.code-group__nav-tab:focus-visible{outline:1px solid rgba(255,255,255,.9)}.code-group__nav-tab-active{border-bottom:var(--c-brand) 1px solid}@media (max-width: 419px){.code-group__nav{margin-left:-1.5rem;margin-right:-1.5rem;border-radius:0}}.code-group-item{display:none}.code-group-item__active{display:block}.code-group-item>pre{background-color:orange}.custom-container{transition:color var(--t-color),border-color var(--t-color),background-color var(--t-color)}.custom-container .custom-container-title{font-weight:600}.custom-container .custom-container-title:not(:only-child){margin-bottom:-.4rem}.custom-container.tip,.custom-container.warning,.custom-container.danger{padding:.1rem 1.5rem;border-left-width:.5rem;border-left-style:solid;margin:1rem 0}.custom-container.tip{border-color:var(--c-tip);background-color:var(--c-tip-bg);color:var(--c-tip-text)}.custom-container.tip .custom-container-title{color:var(--c-tip-title)}.custom-container.tip a{color:var(--c-tip-text-accent)}.custom-container.tip code{background-color:var(--c-bg-dark)}.custom-container.warning{border-color:var(--c-warning);background-color:var(--c-warning-bg);color:var(--c-warning-text)}.custom-container.warning .custom-container-title{color:var(--c-warning-title)}.custom-container.warning a{color:var(--c-warning-text-accent)}.custom-container.warning blockquote{border-left-color:var(--c-warning-border-dark);color:var(--c-warning-text-quote)}.custom-container.warning code{color:var(--c-warning-text-light);background-color:var(--c-warning-bg-light)}.custom-container.warning details{background-color:var(--c-warning-details-bg)}.custom-container.warning details code{background-color:var(--c-warning-bg-lighter)}.custom-container.warning .external-link-icon{--external-link-icon-color: var(--c-warning-text-quote)}.custom-container.danger{border-color:var(--c-danger);background-color:var(--c-danger-bg);color:var(--c-danger-text)}.custom-container.danger .custom-container-title{color:var(--c-danger-title)}.custom-container.danger a{color:var(--c-danger-text-accent)}.custom-container.danger blockquote{border-left-color:var(--c-danger-border-dark);color:var(--c-danger-text-quote)}.custom-container.danger code{color:var(--c-danger-text-light);background-color:var(--c-danger-bg-light)}.custom-container.danger details{background-color:var(--c-danger-details-bg)}.custom-container.danger details code{background-color:var(--c-danger-bg-lighter)}.custom-container.danger .external-link-icon{--external-link-icon-color: var(--c-danger-text-quote)}.custom-container.details{display:block;position:relative;border-radius:2px;margin:1.6em 0;padding:1.6em;background-color:var(--c-details-bg)}.custom-container.details code{background-color:var(--c-bg-darker)}.custom-container.details h4{margin-top:0}.custom-container.details figure:last-child,.custom-container.details p:last-child{margin-bottom:0;padding-bottom:0}.custom-container.details summary{outline:none;cursor:pointer}.home{padding:var(--navbar-height) 2rem 0;max-width:var(--homepage-width);margin:0 auto;display:block}.home .hero{text-align:center}.home .hero img{max-width:100%;max-height:280px;display:block;margin:3rem auto 1.5rem}.home .hero h1{font-size:3rem}.home .hero h1,.home .hero .description,.home .hero .actions{margin:1.8rem auto}.home .hero .actions{display:flex;flex-wrap:wrap;gap:1rem;justify-content:center}.home .hero .description{max-width:35rem;font-size:1.6rem;line-height:1.3;color:var(--c-text-lightest)}.home .hero .action-button{display:inline-block;font-size:1.2rem;padding:.8rem 1.6rem;border-width:2px;border-style:solid;border-radius:4px;transition:background-color var(--t-color);box-sizing:border-box}.home .hero .action-button.primary{color:var(--c-bg);background-color:var(--c-brand);border-color:var(--c-brand)}.home .hero .action-button.primary:hover{background-color:var(--c-brand-light)}.home .hero .action-button.secondary{color:var(--c-brand);background-color:var(--c-bg);border-color:var(--c-brand)}.home .hero .action-button.secondary:hover{color:var(--c-bg);background-color:var(--c-brand-light)}.home .features{border-top:1px solid var(--c-border);transition:border-color var(--t-color);padding:1.2rem 0;margin-top:2.5rem;display:flex;flex-wrap:wrap;align-items:flex-start;align-content:stretch;justify-content:space-between}.home .feature{flex-grow:1;flex-basis:30%;max-width:30%}.home .feature h2{font-size:1.4rem;font-weight:500;border-bottom:none;padding-bottom:0;color:var(--c-text-light)}.home .feature p{color:var(--c-text-lighter)}.home .theme-default-content{padding:0;margin:0}.home .footer{padding:2.5rem;border-top:1px solid var(--c-border);text-align:center;color:var(--c-text-lighter);transition:border-color var(--t-color)}@media (max-width: 719px){.home .features{flex-direction:column}.home .feature{max-width:100%;padding:0 2.5rem}}@media (max-width: 419px){.home{padding-left:1.5rem;padding-right:1.5rem}.home .hero img{max-height:210px;margin:2rem auto 1.2rem}.home .hero h1{font-size:2rem}.home .hero h1,.home .hero .description,.home .hero .actions{margin:1.2rem auto}.home .hero .description{font-size:1.2rem}.home .hero .action-button{font-size:1rem;padding:.6rem 1.2rem}.home .feature h2{font-size:1.25rem}}.page{padding-top:var(--navbar-height);padding-left:var(--sidebar-width)}.navbar{position:fixed;z-index:20;top:0;left:0;right:0;height:var(--navbar-height);box-sizing:border-box;border-bottom:1px solid var(--c-border);background-color:var(--c-bg-navbar);transition:background-color var(--t-color),border-color var(--t-color)}.sidebar{font-size:16px;width:var(--sidebar-width);position:fixed;z-index:10;margin:0;top:var(--navbar-height);left:0;bottom:0;box-sizing:border-box;border-right:1px solid var(--c-border);overflow-y:auto;scrollbar-width:thin;scrollbar-color:var(--c-brand) var(--c-border);background-color:var(--c-bg-sidebar);transition:transform var(--t-transform),background-color var(--t-color),border-color var(--t-color)}.sidebar::-webkit-scrollbar{width:7px}.sidebar::-webkit-scrollbar-track{background-color:var(--c-border)}.sidebar::-webkit-scrollbar-thumb{background-color:var(--c-brand)}.sidebar-mask{position:fixed;z-index:9;top:0;left:0;width:100vw;height:100vh;display:none}.theme-container.sidebar-open .sidebar-mask{display:block}.theme-container.sidebar-open .navbar>.toggle-sidebar-button .icon span:nth-child(1){transform:rotate(45deg) translate3d(5.5px,5.5px,0)}.theme-container.sidebar-open .navbar>.toggle-sidebar-button .icon span:nth-child(2){transform:scale3d(0,1,1)}.theme-container.sidebar-open .navbar>.toggle-sidebar-button .icon span:nth-child(3){transform:rotate(-45deg) translate3d(6px,-6px,0)}.theme-container.sidebar-open .navbar>.toggle-sidebar-button .icon span:nth-child(1),.theme-container.sidebar-open .navbar>.toggle-sidebar-button .icon span:nth-child(3){transform-origin:center}.theme-container.no-navbar .theme-default-content h1,.theme-container.no-navbar .theme-default-content h2,.theme-container.no-navbar .theme-default-content h3,.theme-container.no-navbar .theme-default-content h4,.theme-container.no-navbar .theme-default-content h5,.theme-container.no-navbar .theme-default-content h6{margin-top:1.5rem;padding-top:0}.theme-container.no-navbar .page{padding-top:0}.theme-container.no-navbar .sidebar{top:0}.theme-container.no-sidebar .sidebar{display:none}@media (max-width: 719px){.theme-container.no-sidebar .sidebar{display:block}}.theme-container.no-sidebar .page{padding-left:0}.theme-default-content a:hover{text-decoration:underline}.theme-default-content img{max-width:100%}.theme-default-content h1,.theme-default-content h2,.theme-default-content h3,.theme-default-content h4,.theme-default-content h5,.theme-default-content h6{margin-top:calc(.5rem - var(--navbar-height));padding-top:calc(1rem + var(--navbar-height));margin-bottom:0}.theme-default-content h1:first-child,.theme-default-content h2:first-child,.theme-default-content h3:first-child,.theme-default-content h4:first-child,.theme-default-content h5:first-child,.theme-default-content h6:first-child{margin-bottom:1rem}.theme-default-content h1:first-child+p,.theme-default-content h1:first-child+pre,.theme-default-content h1:first-child+.custom-container,.theme-default-content h2:first-child+p,.theme-default-content h2:first-child+pre,.theme-default-content h2:first-child+.custom-container,.theme-default-content h3:first-child+p,.theme-default-content h3:first-child+pre,.theme-default-content h3:first-child+.custom-container,.theme-default-content h4:first-child+p,.theme-default-content h4:first-child+pre,.theme-default-content h4:first-child+.custom-container,.theme-default-content h5:first-child+p,.theme-default-content h5:first-child+pre,.theme-default-content h5:first-child+.custom-container,.theme-default-content h6:first-child+p,.theme-default-content h6:first-child+pre,.theme-default-content h6:first-child+.custom-container{margin-top:2rem}@media (max-width: 959px){.sidebar{font-size:15px;width:var(--sidebar-width-mobile)}.page{padding-left:var(--sidebar-width-mobile)}}@media (max-width: 719px){.sidebar{top:0;padding-top:var(--navbar-height);transform:translate(-100%)}.page{padding-left:0}.theme-container.sidebar-open .sidebar{transform:translate(0)}.theme-container.no-navbar .sidebar{padding-top:0}}@media (max-width: 419px){h1{font-size:1.9rem}}.navbar{--navbar-line-height: calc( var(--navbar-height) - 2 * var(--navbar-padding-v) );padding:var(--navbar-padding-v) var(--navbar-padding-h);line-height:var(--navbar-line-height)}.navbar .logo{height:var(--navbar-line-height);margin-right:var(--navbar-padding-v);vertical-align:top}.navbar .site-name{font-size:1.3rem;font-weight:600;color:var(--c-text);position:relative}.navbar .navbar-items-wrapper{display:flex;position:absolute;box-sizing:border-box;top:var(--navbar-padding-v);right:var(--navbar-padding-h);height:var(--navbar-line-height);padding-left:var(--navbar-padding-h);white-space:nowrap;font-size:.9rem}.navbar .navbar-items-wrapper .search-box{flex:0 0 auto;vertical-align:top}@media screen and (max-width: 719px){.navbar{padding-left:4rem}.navbar .site-name{display:block;width:calc(100vw - 11rem);overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.navbar .can-hide{display:none}}.navbar-items{display:inline-block}@media print{.navbar-items{display:none}}.navbar-items a{display:inline-block;line-height:1.4rem;color:inherit}.navbar-items a:hover,.navbar-items a.router-link-active{color:var(--c-text)}.navbar-items .navbar-item{position:relative;display:inline-block;margin-left:1.5rem;line-height:var(--navbar-line-height)}.navbar-items .navbar-item:first-child{margin-left:0}.navbar-items .navbar-item>a:hover,.navbar-items .navbar-item>a.router-link-active{margin-bottom:-2px;border-bottom:2px solid var(--c-text-accent)}@media (max-width: 719px){.navbar-items .navbar-item{margin-left:0}.navbar-items .navbar-item>a:hover,.navbar-items .navbar-item>a.router-link-active{margin-bottom:0;border-bottom:none}.navbar-items a:hover,.navbar-items a.router-link-active{color:var(--c-text-accent)}}.toggle-sidebar-button{position:absolute;top:.6rem;left:1rem;display:none;padding:.6rem;cursor:pointer}.toggle-sidebar-button .icon{display:flex;flex-direction:column;justify-content:center;align-items:center;width:1.25rem;height:1.25rem;cursor:inherit}.toggle-sidebar-button .icon span{display:inline-block;width:100%;height:2px;border-radius:2px;background-color:var(--c-text);transition:transform var(--t-transform)}.toggle-sidebar-button .icon span:nth-child(2){margin:6px 0}@media screen and (max-width: 719px){.toggle-sidebar-button{display:block}}.toggle-color-mode-button{display:flex;margin:auto;margin-left:1rem;border:0;background:none;color:var(--c-text);opacity:.8;cursor:pointer}@media print{.toggle-color-mode-button{display:none}}.toggle-color-mode-button:hover{opacity:1}.toggle-color-mode-button .icon{width:1.25rem;height:1.25rem}.DocSearch{transition:background-color var(--t-color)}.navbar-dropdown-wrapper{cursor:pointer}.navbar-dropdown-wrapper .navbar-dropdown-title,.navbar-dropdown-wrapper .navbar-dropdown-title-mobile{display:block;font-size:.9rem;font-family:inherit;cursor:inherit;padding:inherit;line-height:1.4rem;background:transparent;border:none;font-weight:500;color:var(--c-text)}.navbar-dropdown-wrapper .navbar-dropdown-title:hover,.navbar-dropdown-wrapper .navbar-dropdown-title-mobile:hover{border-color:transparent}.navbar-dropdown-wrapper .navbar-dropdown-title .arrow,.navbar-dropdown-wrapper .navbar-dropdown-title-mobile .arrow{vertical-align:middle;margin-top:-1px;margin-left:.4rem}.navbar-dropdown-wrapper .navbar-dropdown-title-mobile{display:none;font-weight:600;font-size:inherit}.navbar-dropdown-wrapper .navbar-dropdown-title-mobile:hover{color:var(--c-text-accent)}.navbar-dropdown-wrapper .navbar-dropdown .navbar-dropdown-item{color:inherit;line-height:1.7rem}.navbar-dropdown-wrapper .navbar-dropdown .navbar-dropdown-item .navbar-dropdown-subtitle{margin:.45rem 0 0;border-top:1px solid var(--c-border);padding:1rem 0 .45rem;font-size:.9rem}.navbar-dropdown-wrapper .navbar-dropdown .navbar-dropdown-item .navbar-dropdown-subtitle>span{padding:0 1.5rem 0 1.25rem}.navbar-dropdown-wrapper .navbar-dropdown .navbar-dropdown-item .navbar-dropdown-subtitle>a{font-weight:inherit}.navbar-dropdown-wrapper .navbar-dropdown .navbar-dropdown-item .navbar-dropdown-subtitle>a.router-link-active:after{display:none}.navbar-dropdown-wrapper .navbar-dropdown .navbar-dropdown-item .navbar-dropdown-subitem-wrapper{padding:0;list-style:none}.navbar-dropdown-wrapper .navbar-dropdown .navbar-dropdown-item .navbar-dropdown-subitem-wrapper .navbar-dropdown-subitem{font-size:.9em}.navbar-dropdown-wrapper .navbar-dropdown .navbar-dropdown-item a{display:block;line-height:1.7rem;position:relative;border-bottom:none;font-weight:400;margin-bottom:0;padding:0 1.5rem 0 1.25rem}.navbar-dropdown-wrapper .navbar-dropdown .navbar-dropdown-item a:hover,.navbar-dropdown-wrapper .navbar-dropdown .navbar-dropdown-item a.router-link-active{color:var(--c-text-accent)}.navbar-dropdown-wrapper .navbar-dropdown .navbar-dropdown-item a.router-link-active:after{content:"";width:0;height:0;border-left:5px solid var(--c-text-accent);border-top:3px solid transparent;border-bottom:3px solid transparent;position:absolute;top:calc(50% - 2px);left:9px}.navbar-dropdown-wrapper .navbar-dropdown .navbar-dropdown-item:first-child .navbar-dropdown-subtitle{margin-top:0;padding-top:0;border-top:0}.navbar-dropdown-wrapper.mobile.open .navbar-dropdown-title,.navbar-dropdown-wrapper.mobile.open .navbar-dropdown-title-mobile{margin-bottom:.5rem}.navbar-dropdown-wrapper.mobile .navbar-dropdown-title,.navbar-dropdown-wrapper.mobile .navbar-dropdown-title-mobile{display:none}.navbar-dropdown-wrapper.mobile .navbar-dropdown-title-mobile{display:block}.navbar-dropdown-wrapper.mobile .navbar-dropdown{transition:height .1s ease-out;overflow:hidden}.navbar-dropdown-wrapper.mobile .navbar-dropdown .navbar-dropdown-item .navbar-dropdown-subtitle{border-top:0;margin-top:0;padding-top:0;padding-bottom:0}.navbar-dropdown-wrapper.mobile .navbar-dropdown .navbar-dropdown-item .navbar-dropdown-subtitle,.navbar-dropdown-wrapper.mobile .navbar-dropdown .navbar-dropdown-item>a{font-size:15px;line-height:2rem}.navbar-dropdown-wrapper.mobile .navbar-dropdown .navbar-dropdown-item .navbar-dropdown-subitem{font-size:14px;padding-left:1rem}.navbar-dropdown-wrapper:not(.mobile){height:1.8rem}.navbar-dropdown-wrapper:not(.mobile):hover .navbar-dropdown,.navbar-dropdown-wrapper:not(.mobile).open .navbar-dropdown{display:block!important}.navbar-dropdown-wrapper:not(.mobile).open:blur{display:none}.navbar-dropdown-wrapper:not(.mobile) .navbar-dropdown{display:none;height:auto!important;box-sizing:border-box;max-height:calc(100vh - 2.7rem);overflow-y:auto;position:absolute;top:100%;right:0;background-color:var(--c-bg-navbar);padding:.6rem 0;border:1px solid var(--c-border);border-bottom-color:var(--c-border-dark);text-align:left;border-radius:.25rem;white-space:nowrap;margin:0}.page{padding-bottom:2rem;display:block}.page .theme-default-content{max-width:var(--content-width);margin:0 auto;padding:2rem 2.5rem;padding-top:0}@media (max-width: 959px){.page .theme-default-content{padding:2rem}}@media (max-width: 419px){.page .theme-default-content{padding:1.5rem}}.page-meta{max-width:var(--content-width);margin:0 auto;padding:1rem 2.5rem;overflow:auto}@media (max-width: 959px){.page-meta{padding:2rem}}@media (max-width: 419px){.page-meta{padding:1.5rem}}.page-meta .meta-item{cursor:default;margin-top:.8rem}.page-meta .meta-item .meta-item-label{font-weight:500;color:var(--c-text-lighter)}.page-meta .meta-item .meta-item-info{font-weight:400;color:var(--c-text-quote)}.page-meta .edit-link{display:inline-block;margin-right:.25rem}@media print{.page-meta .edit-link{display:none}}.page-meta .last-updated{float:right}@media (max-width: 719px){.page-meta .last-updated{font-size:.8em;float:none}.page-meta .contributors{font-size:.8em}}.page-nav{max-width:var(--content-width);margin:0 auto;padding:1rem 2.5rem 2rem;padding-bottom:0}@media (max-width: 959px){.page-nav{padding:2rem}}@media (max-width: 419px){.page-nav{padding:1.5rem}}.page-nav .inner{min-height:2rem;margin-top:0;border-top:1px solid var(--c-border);transition:border-color var(--t-color);padding-top:1rem;overflow:auto}.page-nav .prev a:before{content:"←"}.page-nav .next{float:right}.page-nav .next a:after{content:"→"}.sidebar ul{padding:0;margin:0;list-style-type:none}.sidebar a{display:inline-block}.sidebar .navbar-items{display:none;border-bottom:1px solid var(--c-border);transition:border-color var(--t-color);padding:.5rem 0 .75rem}.sidebar .navbar-items a{font-weight:600}.sidebar .navbar-items .navbar-item{display:block;line-height:1.25rem;font-size:1.1em;padding:.5rem 0 .5rem 1.5rem}.sidebar .sidebar-items{padding:1.5rem 0}@media (max-width: 719px){.sidebar .navbar-items{display:block}.sidebar .navbar-items .navbar-dropdown-wrapper .navbar-dropdown .navbar-dropdown-item a.router-link-active:after{top:calc(1rem - 2px)}.sidebar .sidebar-items{padding:1rem 0}}.sidebar-item{cursor:default;border-left:.25rem solid transparent;color:var(--c-text)}.sidebar-item:focus-visible{outline-width:1px;outline-offset:-1px}.sidebar-item.active:not(p.sidebar-heading){font-weight:600;color:var(--c-text-accent);border-left-color:var(--c-text-accent)}.sidebar-item.sidebar-heading{transition:color .15s ease;font-size:1.1em;font-weight:700;padding:.35rem 1.5rem .35rem 1.25rem;width:100%;box-sizing:border-box;margin:0}.sidebar-item.sidebar-heading+.sidebar-item-children{transition:height .1s ease-out;overflow:hidden;margin-bottom:.75rem}.sidebar-item.collapsible{cursor:pointer}.sidebar-item.collapsible .arrow{position:relative;top:-.12em;left:.5em}.sidebar-item:not(.sidebar-heading){font-size:1em;font-weight:400;display:inline-block;margin:0;padding:.35rem 1rem .35rem 2rem;line-height:1.4;width:100%;box-sizing:border-box}.sidebar-item:not(.sidebar-heading)+.sidebar-item-children{padding-left:1rem;font-size:.95em}.sidebar-item-children .sidebar-item-children .sidebar-item:not(.sidebar-heading){padding:.25rem 1rem .25rem 1.75rem}.sidebar-item-children .sidebar-item-children .sidebar-item:not(.sidebar-heading).active{font-weight:500;border-left-color:transparent}a.sidebar-heading+.sidebar-item-children .sidebar-item:not(.sidebar-heading).active{border-left-color:transparent}a.sidebar-item{cursor:pointer}a.sidebar-item:hover{color:var(--c-text-accent)}.table-of-contents .badge{vertical-align:middle}.dropdown-enter-from,.dropdown-leave-to{height:0!important}.fade-slide-y-enter-active{transition:all .2s ease}.fade-slide-y-leave-active{transition:all .2s cubic-bezier(1,.5,.8,1)}.fade-slide-y-enter-from,.fade-slide-y-leave-to{transform:translateY(10px);opacity:0}:root{--search-bg-color: #ffffff;--search-accent-color: #3eaf7c;--search-text-color: #2c3e50;--search-border-color: #eaecef;--search-item-text-color: #5d81a5;--search-item-focus-bg-color: #f3f4f5;--search-input-width: 8rem;--search-result-width: 20rem}.search-box{display:inline-block;position:relative;margin-left:1rem}@media print{.search-box{display:none}}.search-box input{-webkit-appearance:none;-moz-appearance:none;appearance:none;cursor:text;width:var(--search-input-width);height:2rem;color:var(--search-text-color);display:inline-block;border:1px solid var(--search-border-color);border-radius:2rem;font-size:.9rem;line-height:2rem;padding:0 .5rem 0 2rem;outline:none;transition:all ease .3s;background:var(--search-bg-color) url("data:image/svg+xml,%3c?xml%20version='1.0'%20encoding='UTF-8'?%3e%3csvg%20xmlns='http://www.w3.org/2000/svg'%20width='12'%20height='13'%3e%3cg%20stroke-width='2'%20stroke='%23aaa'%20fill='none'%3e%3cpath%20d='M11.29%2011.71l-4-4'/%3e%3ccircle%20cx='5'%20cy='5'%20r='4'/%3e%3c/g%3e%3c/svg%3e") .6rem .5rem no-repeat;background-size:1rem}.search-box input:focus{cursor:auto;border-color:var(--search-accent-color)}.search-box .suggestions{background:var(--search-bg-color);width:var(--search-result-width);position:absolute;top:2rem;right:0;border:1px solid var(--search-border-color);border-radius:6px;padding:.4rem;list-style-type:none}.search-box .suggestion{line-height:1.4;padding:.4rem .6rem;border-radius:4px;cursor:pointer}.search-box .suggestion.focus{background-color:var(--search-item-focus-bg-color)}.search-box .suggestion.focus a{color:var(--search-accent-color)}.search-box .suggestion a{white-space:normal;color:var(--search-item-text-color)}.search-box .suggestion .page-title{font-weight:600}.search-box .suggestion .page-header{font-size:.9em;margin-left:.25em}@media (max-width: 719px){.search-box input{cursor:pointer;width:0;border-color:transparent;position:relative}.search-box input:focus{cursor:text;left:0;width:10rem}}@media (max-width: 419px){.search-box input:focus{width:8rem}.search-box .suggestions{width:calc(100vw - 4rem);right:-.5rem}}:root{--medium-zoom-z-index: 100;--medium-zoom-bg-color: #ffffff;--medium-zoom-opacity: 1}.medium-zoom-overlay{background-color:var(--medium-zoom-bg-color)!important;z-index:var(--medium-zoom-z-index)}.medium-zoom-overlay~img{z-index:calc(var(--medium-zoom-z-index) + 1)}.medium-zoom--opened .medium-zoom-overlay{opacity:var(--medium-zoom-opacity)} diff --git a/assets/sudo.html-4XyrR9mM.js b/assets/sudo.html-4XyrR9mM.js new file mode 100644 index 0000000..0596223 --- /dev/null +++ b/assets/sudo.html-4XyrR9mM.js @@ -0,0 +1 @@ +import{_ as o,o as s,c as t,b as e,d as l}from"./app-x8p6wK6B.js";const a={},d=e("h1",{id:"sudo",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#sudo","aria-hidden":"true"},"#"),l(" sudo")],-1),r=e("p",null,"-i 参数(即 sudo -i ),在 sudo 的 man page 里指明了,会加载 [.profile,.bash_profile or .login will be read by the shell.] , 同时呢,会跳到 /root 家目录。",-1),c=e("blockquote",null,[e("p",null,"https://www.v2ex.com/t/885106#reply3")],-1),n=[d,r,c];function _(i,u){return s(),t("div",null,n)}const p=o(a,[["render",_],["__file","sudo.html.vue"]]);export{p as default}; diff --git a/assets/sudo.html-Qy0hDxEt.js b/assets/sudo.html-Qy0hDxEt.js new file mode 100644 index 0000000..acf3a41 --- /dev/null +++ b/assets/sudo.html-Qy0hDxEt.js @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-57e15916","path":"/ops/sudo.html","title":"sudo","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"ops/sudo.md"}');export{t as data}; diff --git "a/assets/teg\344\272\211\351\234\270\350\265\233.html-KE1DSMKT.js" "b/assets/teg\344\272\211\351\234\270\350\265\233.html-KE1DSMKT.js" new file mode 100644 index 0000000..8c74de8 --- /dev/null +++ "b/assets/teg\344\272\211\351\234\270\350\265\233.html-KE1DSMKT.js" @@ -0,0 +1,223 @@ +import{_ as n,o as s,c as a,a as p}from"./app-x8p6wK6B.js";const t={},e=p(`

teg争霸赛

第一关 刷到10000

直接返回a 即可

第二关

看js 返回a*a+a 即可

第三关 20201021

将js看懂后改写


+window = {}
+
+var bl5 = ['A5473788'];
+(function (bl1, bl2) {
+    var bl4 = function (bl3) {
+        while (--bl3) {
+            bl1['push'](bl1['shift']());
+        }
+    };
+    bl4(++bl2);
+}(bl5, 496));
+
+
+var _0x23fc = function (bl1, bl2) {
+    bl1 = bl1 - 0x0;
+    var bl4 = bl5[bl1];
+    return bl4;
+};
+
+window[_0x23fc('0x0')] = function (bl6) {
+    var bl9 = 199999;
+
+    for (var bl8 = 0; bl8 < 199999; bl8++) {
+        var bl7 = 0;
+        //for (var bl10 = 0; bl10 < bl8; bl10++) {
+        //  bl7 += bl6['a'][0];
+        //} 这里循环删掉
+        bl7 += bl6['a'][0] * bl8;
+
+        if (bl7 % bl6['a'][2] == bl6['a'][1] && bl8 < bl9) {
+            bl9 = bl8
+            break
+        }
+    }
+    return bl9;
+};
+
+console.log(window.A5473788)
+
+

第四关 20201022

原始代码直接放node里面, 报错,

一点点剥皮后发现node 里没有window 对象, 加上即可


+window = {}
+
+window.setTimeout = setTimeout
+
+window.A593C8B8 = async (b106) => (($, b106, b105, b104, b103) => {
+
+    let b102 = function* () {
+        while ([]) yield[    (b106, b105) => b106 + b105, (b106, b105) => b106 - b105, (b106, b105) => b106 * b105]   [++b105 % 3]['bind'](0, b104, b103)
+    }();
+
+    let b101 = function (b102, b101, b100) {
+        b103 = b102;
+        b104 = b101["next"]()['value']();
+
+        b105 == b106['a']["length"] && b100(-b104)
+
+    };
+    // return new Promise(b105 => b106['a']['forEach'](b104 => $["setTimeout"](b103 => b101(b104, b102, b105), b104)))
+
+
+    return new Promise(b105 => {
+
+        b106['a']['forEach'](b104 => {
+            setTimeout(b103 => {
+                b101(b104, b102, b105)
+            },b104/50)
+
+        })
+
+    })
+
+})(window, b106, 0, 0, 0)
+
+

可以运行,但是很慢, 搞懂后, 在延时处 b104/50 即可

第五关 20201023

这关用的wasm

https://www.wasm.com.cn/docs/semantics/


+(module
+  (func $Math.min (;0;) (import "Math" "min") (param i32 i32) (result i32))
+  (func $Math.max (;1;) (import "Math" "max") (param i32 i32) (result i32))
+  (func $Run (;2;) (export "Run") (param $var0 i32) (param $var1 i32) (result i32)
+    (local $var2 i32) (local $var3 i32) (local $var4 i32) (local $var5 i32) (local $var6 i32) (local $var7 i32)
+    local.get $var0
+    local.set $var2
+    local.get $var1
+    i32.const 1
+    i32.sub
+    local.tee $var4
+    if
+      loop $label1
+        local.get $var2
+        local.set $var3
+        i32.const 0
+        local.set $var6
+        i32.const 10
+        local.set $var7
+        loop $label0
+          local.get $var3
+          i32.const 10
+          i32.rem_u
+          local.set $var5
+          local.get $var3
+          i32.const 10
+          i32.div_u
+          local.set $var3
+          local.get $var5
+          local.get $var6
+          call $Math.max
+          local.set $var6
+          local.get $var5
+          local.get $var7
+          call $Math.min
+          local.set $var7
+          local.get $var3
+          i32.const 0
+          i32.gt_u
+          br_if $label0
+        end $label0
+        local.get $var2
+        local.get $var6
+        local.get $var7
+        i32.mul
+        i32.add
+        local.set $var2
+        local.get $var4
+        i32.const 1
+        i32.sub
+        local.tee $var4
+        br_if $label1
+      end $label1
+    end
+    local.get $var2
+  )
+)
+
+

https://github.com/WebAssembly/wabt

wasm 转c, 然后编译时加上 Ofast 优化 即可

gcc a.c -o a.out -Ofast


+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+ unsigned max(unsigned a,unsigned b){
+     if (a>b)
+     return a;
+     else return b;
+ }
+
+ unsigned min(unsigned a,unsigned b){
+     if (a<b)
+     return a;
+     else return b;
+ }
+ 
+
+int _Run(int _p0, int _p1) {
+  int _l2 = 0, _l3 = 0, _l4 = 0, _l5 = 0, _l6 = 0, _l7 = 0;
+//   FUNC_PROLOGUE;
+  int _i0, _i1, _i2;
+
+  
+  _l2 = _p0;
+  _i0 = _p1;
+  _i1 = 1u;
+  _i0 -= 1;
+  _l4 = _i0;
+  if (_i0) {
+    //   printf("i0 = %d\\n",_i0);
+    _L1: 
+    
+      _i0 = _l2;
+      _l3 = _i0;
+      _i0 = 0u;
+      _l6 = _i0;
+      _i0 = 10u;
+      _l7 = _i0;
+      _L2: 
+    //   printf("i0 = %d\\n",_i0);
+        _i0 = _l3;
+        _i1 = 10u;
+        // _i0 = REM_U(_i0, _i1);  //有符号求余数
+        _i0 = _i0 % _i1;
+        _l5 = _i0 ;
+        _i0 = _l3;
+        _i1 = 10u;
+        // _i0 = DIV_U(_i0, _i1);  //向下整除
+        _i0 = _i0 / _i1; 
+        _l3 = _i0;
+        _i0 = _l5;
+        _i1 = _l6;
+        _i0 = max(_i0, _i1);
+        _l6 = _i0;
+        _i0 = _l5;
+        _i1 = _l7;
+        _i0 = min(_i0, _i1);
+        _l7 = _i0;
+        _i0 = _l3;
+        _i1 = 0u;
+        _i0 = _i0 > _i1;
+        if (_i0) {goto _L2;}
+      _i0 = _l2;
+      _i1 = _l6;
+      _i2 = _l7;
+      _i1 *= _i2;
+      _i0 += _i1;
+      _l2 = _i0;
+      _i0 = _l4;
+      _i1 = 1u;
+      _i0 -= _i1;
+      _l4 = _i0;
+      if (_i0) {goto _L1;}
+  }
+  _i0 = _l2;
+//   FUNC_EPILOGUE;
+  return _i0;
+}
+
+int main( int argc, char *argv[]){
+    // int dd = _Run(211814391, 6301083);    
+    // printf("%s,%s",argv[1],argv[2]);
+    int dd = _Run(atoi(argv[1]),atoi(argv[2]));    
+    //211814400
+    printf("%d",dd);
+
+    return 0;
+}
+
+
`,21),o=[e];function c(l,i){return s(),a("div",null,o)}const k=n(t,[["render",c],["__file","teg争霸赛.html.vue"]]);export{k as default}; diff --git "a/assets/teg\344\272\211\351\234\270\350\265\233.html-O4OxJDqO.js" "b/assets/teg\344\272\211\351\234\270\350\265\233.html-O4OxJDqO.js" new file mode 100644 index 0000000..a933f5c --- /dev/null +++ "b/assets/teg\344\272\211\351\234\270\350\265\233.html-O4OxJDqO.js" @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-7d01c4b5","path":"/notebook/teg%E4%BA%89%E9%9C%B8%E8%B5%9B.html","title":"teg争霸赛","lang":"en-US","frontmatter":{},"headers":[{"level":3,"title":"第一关 刷到10000","slug":"第一关-刷到10000","link":"#第一关-刷到10000","children":[]},{"level":3,"title":"第二关","slug":"第二关","link":"#第二关","children":[]},{"level":3,"title":"第三关 20201021","slug":"第三关-20201021","link":"#第三关-20201021","children":[]},{"level":3,"title":"第四关 20201022","slug":"第四关-20201022","link":"#第四关-20201022","children":[]},{"level":3,"title":"第五关 20201023","slug":"第五关-20201023","link":"#第五关-20201023","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/teg争霸赛.md"}');export{e as data}; diff --git a/assets/ubuntu_x11.html-Qjrg3K8h.js b/assets/ubuntu_x11.html-Qjrg3K8h.js new file mode 100644 index 0000000..f41381f --- /dev/null +++ b/assets/ubuntu_x11.html-Qjrg3K8h.js @@ -0,0 +1 @@ +const l=JSON.parse('{"key":"v-1160d8a3","path":"/ops/ubuntu_x11.html","title":"ubuntu_x11","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"启动方式","slug":"启动方式","link":"#启动方式","children":[]},{"level":2,"title":"遇到的问题","slug":"遇到的问题","link":"#遇到的问题","children":[{"level":3,"title":"无法显示中文","slug":"无法显示中文","link":"#无法显示中文","children":[]},{"level":3,"title":"无法输入中文","slug":"无法输入中文","link":"#无法输入中文","children":[]}]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"ops/ubuntu_x11.md"}');export{l as data}; diff --git a/assets/ubuntu_x11.html-vAk25k69.js b/assets/ubuntu_x11.html-vAk25k69.js new file mode 100644 index 0000000..44a8b8e --- /dev/null +++ b/assets/ubuntu_x11.html-vAk25k69.js @@ -0,0 +1,7 @@ +import{_ as a,o as s,c as n,a as e}from"./app-x8p6wK6B.js";const t="/assets/20221017105043746_29382-EW-14mL8.png",i="/assets/20221017105049326_26966-WlMfoEfL.png",r={},l=e('

ubuntu_x11

启动方式

moye用户

先启动xterm

然后sudo pycharm.sh启动pycahrm

遇到的问题

无法显示中文

73 apt install x11-apps 74 exit 75 xclock 76 exit 77 apt install xinit 78 xterm & 79 apt install xterm 80 xterm & 81 exit 82 apt install gtk2-immodule-xim 83 apt install fcitx

# start_pycharm.sh
+export XIM_PROGRAM=fcitx
+export XIM=fcitx
+export XMODIFIERS=@im=fcitx
+export DEPENDS=fcitx
+/home/moyechen/pycharm-2022.2.3/bin/pycharm.sh
+

无法输入中文

暂时未解决

`,13),p=[l];function c(o,d){return s(),n("div",null,p)}const m=a(r,[["render",c],["__file","ubuntu_x11.html.vue"]]);export{m as default}; diff --git "a/assets/url\351\207\215\345\256\232\345\220\221.html-0RgneqCm.js" "b/assets/url\351\207\215\345\256\232\345\220\221.html-0RgneqCm.js" new file mode 100644 index 0000000..5348340 --- /dev/null +++ "b/assets/url\351\207\215\345\256\232\345\220\221.html-0RgneqCm.js" @@ -0,0 +1 @@ +import{_ as t,o as s,c as r,b as e,d as o}from"./app-x8p6wK6B.js";const _="/assets/20200414193656801_9782-A3TGyBfn.png",a={},c=e("h1",{id:"url",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#url","aria-hidden":"true"},"#"),o(" url")],-1),n=e("p",null,[e("img",{src:_,alt:"google变百度"})],-1),l=[c,n];function d(i,u){return s(),r("div",null,l)}const f=t(a,[["render",d],["__file","url重定向.html.vue"]]);export{f as default}; diff --git "a/assets/url\351\207\215\345\256\232\345\220\221.html-57srkQ1H.js" "b/assets/url\351\207\215\345\256\232\345\220\221.html-57srkQ1H.js" new file mode 100644 index 0000000..3afe68b --- /dev/null +++ "b/assets/url\351\207\215\345\256\232\345\220\221.html-57srkQ1H.js" @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-171fb32c","path":"/notebook/url%E9%87%8D%E5%AE%9A%E5%90%91.html","title":"url","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/url重定向.md"}');export{t as data}; diff --git "a/assets/vmware\350\231\232\346\213\237\346\234\272\347\241\254\347\233\230\350\260\203\346\225\264.html-BDfp_wEd.js" "b/assets/vmware\350\231\232\346\213\237\346\234\272\347\241\254\347\233\230\350\260\203\346\225\264.html-BDfp_wEd.js" new file mode 100644 index 0000000..c05537c --- /dev/null +++ "b/assets/vmware\350\231\232\346\213\237\346\234\272\347\241\254\347\233\230\350\260\203\346\225\264.html-BDfp_wEd.js" @@ -0,0 +1,13 @@ +import{_ as e,o as t,c as i,a}from"./app-x8p6wK6B.js";const n="/assets/20220728154343100_23767-GfAGAFuL.png",s={},l=a(`

vmware虚拟机硬盘调整

vmware 调整硬盘大小

https://www.cnblogs.com/ZHJ0125/p/12904471.html 安装gparted

x11授权 sudo xauth add $(xauth -f ~moyechen/.Xauthority list|tail -1)

如果遇到


+moyechen@moye:~$ sudo xauth add $(xauth -f ~moyechen/.Xauthority list|tail -1)
+xauth:  timeout in locking authority file /home/moyechen/.Xauthority
+xauth:  timeout in locking authority file /home/moyechen/.Xauthority
+
+
+

则执行

rm ~/.Xaut*
+exit
+再次登录时,会提示
+/usr/bin/xauth:  file /home/moyechen/.Xauthority does not exist
+
+然后创建该文件
+

https://superuser.com/questions/315050/xauth-x11-ssh-forwarding-errors-with-xauthority-file-not-writable

最后启动程序

sudo gparted

LVM

https://blog.csdn.net/Fly_1213/article/details/105142427

lvextend -L 80G /dev/mapper/ubuntu--vg-ubuntu--lv

resize2fs /dev/mapper/ubuntu--vg-ubuntu--lv

',16),r=[l];function d(u,o){return t(),i("div",null,r)}const m=e(s,[["render",d],["__file","vmware虚拟机硬盘调整.html.vue"]]);export{m as default}; diff --git "a/assets/vmware\350\231\232\346\213\237\346\234\272\347\241\254\347\233\230\350\260\203\346\225\264.html-LlXHLqrq.js" "b/assets/vmware\350\231\232\346\213\237\346\234\272\347\241\254\347\233\230\350\260\203\346\225\264.html-LlXHLqrq.js" new file mode 100644 index 0000000..5ccaa5b --- /dev/null +++ "b/assets/vmware\350\231\232\346\213\237\346\234\272\347\241\254\347\233\230\350\260\203\346\225\264.html-LlXHLqrq.js" @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-087e08e6","path":"/ops/vmware%E8%99%9A%E6%8B%9F%E6%9C%BA%E7%A1%AC%E7%9B%98%E8%B0%83%E6%95%B4.html","title":"vmware虚拟机硬盘调整","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"ops/vmware虚拟机硬盘调整.md"}');export{e as data}; diff --git "a/assets/vscode\346\233\277\344\273\243codeblock.html-QvZWRnPv.js" "b/assets/vscode\346\233\277\344\273\243codeblock.html-QvZWRnPv.js" new file mode 100644 index 0000000..2fdc842 --- /dev/null +++ "b/assets/vscode\346\233\277\344\273\243codeblock.html-QvZWRnPv.js" @@ -0,0 +1,8 @@ +import{_ as e,a as s}from"./20200216004851429_31590-ycX-VYgZ.js";import{_ as o,o as c,c as t,a as d}from"./app-x8p6wK6B.js";const p="/assets/20200216005034283_6861-hoVHTvC9.png",a="/assets/20200216164012830_18992-4J4_TkRN.png",i="/assets/20200216001653735_883-IQNkpcp5.png",r="/assets/20200216153319843_23184-3ZlR-OOz.png",n="/assets/20200216153545000_7574-O4HmZ0GH.png",l="/assets/20200216153609444_2629-ixahf16v.png",m="/assets/20200216154035988_9536-02LS7Lye.png",_="/assets/20200216154144431_6911-SPeYXN50.png",u="/assets/20200216154222027_24290-6_tTy4lT.png",h="/assets/20200216154335434_2501-StwAyUTR.png",g="/assets/20200216154747896_13220-aBXmIC1D.png",v="/assets/20200216154959017_19426-XDkjvjMW.png",b="/assets/20200216161057865_16709-Qp-cWsyF.png",x="/assets/20200216161132880_26553-09cgfzSI.png",f="/assets/20200216161321957_23988-DgbbbMPg.png",q="/assets/20200216162855158_2094-r5FBiv_f.png",k={},C=d('

vscode替代codeblocks

时间作者
2020/2/16 16:54moyechen

code block 这款ide在acm比赛中非常常见, 但是鉴于本人有以下需求

  • 代码补全
  • 一个方便的文件管理树
  • 自定义代码模板
  • 编译后生成的可执行文件(.exe) 定时清理

因此,本人折腾了文本编辑器 -- vscode

准备工作

首先下载vscode

官网链接: https://code.visualstudio.com/

接着,将编译器的目录添加到环境变量 如果你有code::blocks 可以参考以下:

打开code::blocks

复制蓝色内容,然后加上\\bin

例如 C:\\Program Files (x86)\\CodeBlocks\\MinGW\\bin , 记为compiler_path变量

接着,添加到系统环境变量

这里, 第六步我们输入 C:\\Program Files (x86)\\CodeBlocks\\MinGW\\bin (如果你的code::block是默认安装的话,否则,请你使用刚刚拼接的字符串compilar_path)

如果你没有code::block, 请你自行将g++编译器添加到环境变量

测试编译器是否可用

按住win键,然后输入r,在弹出的框中输入cmd

此时会打开一个黑框框

输入g++

如果出现下图,这说明编译器准备完毕

vscode配置

插件安装

安装好后, 点击左侧栏第5个按钮,依次安装下方3个插件

code runner (在输入框输入code runner进行搜索)

中文插件

在输入框输入 chinese 进行搜索

以及 C/C++ 插件

提示: 安装完毕后, 请重新启动vscode

vscode 初体验

重启过后, 我们打开一个文件夹

然后右键,新建文件,输入文件名,这里我输入的是test.cpp

接着,我们输入一个测试代码,可以看到, vscode已经可以智能补全了

输入完毕后, 右击输入区域, 点击第一项 Run Code ,可以在下方看到输出

这表示我们已经可以使用了

但是这个输入区域无法接受输入, 也就是我们无法拿测试用例进行调试 无法输入

解决输出区域无法输入的问题

我们将代码调试放在终端(之中,终端可以接受输入,就解决了这个问题

我们需要增加以下几条设置

首先, 打开setting.json

之后, 输入一条

"code-runner.runInTerminal": true,

Ctrl + S 保存后重启vscode, 重新运行代码, 可以看到已经可以输入了

生成文件放在固定目录,减少硬盘占用

默认设置中,生成的文件和代码文件同目录, 也就是说,对于每一个代码,我们都要生成这么一个.exe文件

一个.cpp 代码文件一般不会超过5kb, 但是一个可执行文件一般是 1mb左右

这不但增加了磁盘空间的负担,同时也使我们文件管理非常的混乱

使用以下操作解决:

打开 setting.json 添加这几条内容

    "terminal.integrated.shell.windows": "C:\\\\WINDOWS\\\\System32\\\\cmd.exe",
+    "code-runner.executorMap": {
+        "cpp": "cd $dir && g++ -o D:\\\\temp.exe \\"$fileName\\"  -std=c++11 &&  D:\\\\temp.exe"
+    }
+

这些代码的意思:

  • 第一行表示指定使用的终端为cmd, win10默认使用的PowerShell 语法与Cmd 的语法不大相同,我们选择熟悉的Cmd
  • 第二行表示执行代码是运行的命令,我们分开解析这条命令
    • cd $dir , 进入代码所在的目录
    • g++ -o D:\\\\temp.exe \\"$fileName\\" -std=c++11 , 使用c++11的标准编译你当前编辑的文件,然后生成可执行文件到 D:\\\\temp.exe, 可以更改为 -std=c++14 以使用更多特性, 或者更改 D:\\\\temp.exe 为你喜欢的路径
    • D:\\\\temp.exe ,执行你生成好的可执行文件
    • 其中&& 在c/c++语言中是且的意思, 也就是说, 执行完第一步 cd $dir 后, 我们才能安全的执行第二步操作,因此使用并且并且连接符

紧接着, 我们再添加以下内容:


+    "code-runner.preserveFocus": false,        
+    "code-runner.saveFileBeforeRun": true,
+

▲第一行: 运行后光标聚焦在终端 ▲第二行: 运行前自动保存文件

添加后的样子

接着,__重启__VsCode

已经可以使用了

',70),D=[C];function S(y,B){return c(),t("div",null,D)}const F=o(k,[["render",S],["__file","vscode替代codeblock.html.vue"]]);export{F as default}; diff --git "a/assets/vscode\346\233\277\344\273\243codeblock.html-i0KV3h8u.js" "b/assets/vscode\346\233\277\344\273\243codeblock.html-i0KV3h8u.js" new file mode 100644 index 0000000..b4c939c --- /dev/null +++ "b/assets/vscode\346\233\277\344\273\243codeblock.html-i0KV3h8u.js" @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-688e63da","path":"/notebook/vscode%E6%9B%BF%E4%BB%A3codeblock.html","title":"vscode替代codeblocks","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"准备工作","slug":"准备工作","link":"#准备工作","children":[{"level":3,"title":"测试编译器是否可用","slug":"测试编译器是否可用","link":"#测试编译器是否可用","children":[]}]},{"level":2,"title":"vscode配置","slug":"vscode配置","link":"#vscode配置","children":[{"level":3,"title":"插件安装","slug":"插件安装","link":"#插件安装","children":[]},{"level":3,"title":"vscode 初体验","slug":"vscode-初体验","link":"#vscode-初体验","children":[]},{"level":3,"title":"解决输出区域无法输入的问题","slug":"解决输出区域无法输入的问题","link":"#解决输出区域无法输入的问题","children":[]},{"level":3,"title":"生成文件放在固定目录,减少硬盘占用","slug":"生成文件放在固定目录-减少硬盘占用","link":"#生成文件放在固定目录-减少硬盘占用","children":[]}]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/vscode替代codeblock.md"}');export{e as data}; diff --git "a/assets/vue\344\277\256\346\224\271\346\225\260\347\273\204\345\206\205\347\232\204\345\257\271\350\261\241.html-1tLRHQAN.js" "b/assets/vue\344\277\256\346\224\271\346\225\260\347\273\204\345\206\205\347\232\204\345\257\271\350\261\241.html-1tLRHQAN.js" new file mode 100644 index 0000000..c2993c6 --- /dev/null +++ "b/assets/vue\344\277\256\346\224\271\346\225\260\347\273\204\345\206\205\347\232\204\345\257\271\350\261\241.html-1tLRHQAN.js" @@ -0,0 +1 @@ +import{_ as t,o as _,c as o,b as e,d as s}from"./app-x8p6wK6B.js";const n={},c=e("h1",{id:"vue修改数组内的对象",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#vue修改数组内的对象","aria-hidden":"true"},"#"),s(" vue修改数组内的对象")],-1),l=e("blockquote",null,[e("p",null,"https://blog.csdn.net/weixin_43368335/article/details/102801013")],-1),a=e("blockquote",null,[e("p",null,"https://juejin.im/post/6844903901175496711")],-1),i=[c,l,a];function r(d,u){return _(),o("div",null,i)}const p=t(n,[["render",r],["__file","vue修改数组内的对象.html.vue"]]);export{p as default}; diff --git "a/assets/vue\344\277\256\346\224\271\346\225\260\347\273\204\345\206\205\347\232\204\345\257\271\350\261\241.html-Zshm8zZm.js" "b/assets/vue\344\277\256\346\224\271\346\225\260\347\273\204\345\206\205\347\232\204\345\257\271\350\261\241.html-Zshm8zZm.js" new file mode 100644 index 0000000..879e65f --- /dev/null +++ "b/assets/vue\344\277\256\346\224\271\346\225\260\347\273\204\345\206\205\347\232\204\345\257\271\350\261\241.html-Zshm8zZm.js" @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-0ba06cdc","path":"/notebook/vue%E4%BF%AE%E6%94%B9%E6%95%B0%E7%BB%84%E5%86%85%E7%9A%84%E5%AF%B9%E8%B1%A1.html","title":"vue修改数组内的对象","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/vue修改数组内的对象.md"}');export{e as data}; diff --git "a/assets/web_web\346\250\241\345\236\213.html-XmBvhhvk.js" "b/assets/web_web\346\250\241\345\236\213.html-XmBvhhvk.js" new file mode 100644 index 0000000..d3423ba --- /dev/null +++ "b/assets/web_web\346\250\241\345\236\213.html-XmBvhhvk.js" @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-5a4912c0","path":"/web/web_web%E6%A8%A1%E5%9E%8B.html","title":"[web]web模型","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"web/[web]web模型.md"}');export{e as data}; diff --git "a/assets/web_web\346\250\241\345\236\213.html-gCwItGiF.js" "b/assets/web_web\346\250\241\345\236\213.html-gCwItGiF.js" new file mode 100644 index 0000000..39602fa --- /dev/null +++ "b/assets/web_web\346\250\241\345\236\213.html-gCwItGiF.js" @@ -0,0 +1 @@ +import{_ as n,o,c as t,b as e,d as s}from"./app-x8p6wK6B.js";const _={},c=e("h1",{id:"web-web模型",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#web-web模型","aria-hidden":"true"},"#"),s(" [web]web模型")],-1),i=e("p",null,"常见的python wsgi服务器,以及模型",-1),a=e("ol",null,[e("li",null,"nginx + uwsgi socket + django")],-1),r=e("p",null,"可以开进程线程,但是不懂区别",-1),l=e("ol",{start:"2"},[e("li",null,"nginx proxy_pass + gunicorn")],-1),d=e("p",null,"command = gunicorn -b 0.0.0.0:9004 -w %(ENV_WORKER)s --timeout 20 range_backend.asgi:application -k uvicorn.workers.UvicornWorker",-1),u=[c,i,a,r,l,d];function h(b,w){return o(),t("div",null,u)}const g=n(_,[["render",h],["__file","web_web模型.html.vue"]]);export{g as default}; diff --git "a/assets/web_\346\234\215\345\212\241\347\253\257\346\270\262\346\237\223\344\270\216\345\256\242\346\210\267\347\253\257\346\270\262\346\237\223.html-CUPLhHz3.js" "b/assets/web_\346\234\215\345\212\241\347\253\257\346\270\262\346\237\223\344\270\216\345\256\242\346\210\267\347\253\257\346\270\262\346\237\223.html-CUPLhHz3.js" new file mode 100644 index 0000000..2d4c368 --- /dev/null +++ "b/assets/web_\346\234\215\345\212\241\347\253\257\346\270\262\346\237\223\344\270\216\345\256\242\346\210\267\347\253\257\346\270\262\346\237\223.html-CUPLhHz3.js" @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-1ce7b414","path":"/web/web_%E6%9C%8D%E5%8A%A1%E7%AB%AF%E6%B8%B2%E6%9F%93%E4%B8%8E%E5%AE%A2%E6%88%B7%E7%AB%AF%E6%B8%B2%E6%9F%93.html","title":"[web]服务端渲染与客户端渲染","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"web/[web]服务端渲染与客户端渲染.md"}');export{e as data}; diff --git "a/assets/web_\346\234\215\345\212\241\347\253\257\346\270\262\346\237\223\344\270\216\345\256\242\346\210\267\347\253\257\346\270\262\346\237\223.html-d2iT7On5.js" "b/assets/web_\346\234\215\345\212\241\347\253\257\346\270\262\346\237\223\344\270\216\345\256\242\346\210\267\347\253\257\346\270\262\346\237\223.html-d2iT7On5.js" new file mode 100644 index 0000000..12d8903 --- /dev/null +++ "b/assets/web_\346\234\215\345\212\241\347\253\257\346\270\262\346\237\223\344\270\216\345\256\242\346\210\267\347\253\257\346\270\262\346\237\223.html-d2iT7On5.js" @@ -0,0 +1 @@ +import{_ as t,o as _,c as o,b as e,d as s}from"./app-x8p6wK6B.js";const n={},l=e("h1",{id:"web-服务端渲染与客户端渲染",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#web-服务端渲染与客户端渲染","aria-hidden":"true"},"#"),s(" [web]服务端渲染与客户端渲染")],-1),c=e("p",null,"大学时,老师教了jsp,使用的是模版引擎",-1),h=e("p",null,"在我第一次写web应用时,使用的后台是django,django支持模版引擎渲染,但是我觉得非常恶心,因为他要把html和模版语言写在一块",-1),a=e("p",null,"当时写的是内部网站,不需要seo,使用html写完代码以后,其中获取数据的部分使用jquery的ajax动态获取",-1),d=e("p",null,"后来编写博客的时候,用到vnote以及衍生品viki,viki使用js在前端将md文档渲染为html,非常好用,但是缺点是搜索引擎无法识别动态内容 借此机会,了解了一下服务端渲染和客户端渲染 现在pc上的老牌网站,例如淘宝,在2013年左右使用的是php,将php嵌入到html中,通过php调用函数,渲染html,在2014年,淘宝改为使用nodejs的中间层技术",-1),i=e("blockquote",null,[e("p",null,"淘宝、天猫首页技术从Node.js 换回PHP了么? https://www.zhihu.com/question/54777923")],-1),r=[l,c,h,a,d,i];function p(u,m){return _(),o("div",null,r)}const w=t(n,[["render",p],["__file","web_服务端渲染与客户端渲染.html.vue"]]);export{w as default}; diff --git "a/assets/web_\350\243\205\351\245\260\345\231\250\346\250\241\345\274\217\345\234\250canvas\351\207\214\347\232\204\345\272\224\347\224\250.html-8KA7vgn8.js" "b/assets/web_\350\243\205\351\245\260\345\231\250\346\250\241\345\274\217\345\234\250canvas\351\207\214\347\232\204\345\272\224\347\224\250.html-8KA7vgn8.js" new file mode 100644 index 0000000..737c2f5 --- /dev/null +++ "b/assets/web_\350\243\205\351\245\260\345\231\250\346\250\241\345\274\217\345\234\250canvas\351\207\214\347\232\204\345\272\224\347\224\250.html-8KA7vgn8.js" @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-6099f3b2","path":"/web/web_%E8%A3%85%E9%A5%B0%E5%99%A8%E6%A8%A1%E5%BC%8F%E5%9C%A8canvas%E9%87%8C%E7%9A%84%E5%BA%94%E7%94%A8.html","title":"[web]装饰器模式在canvas里的应用","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"web/[web]装饰器模式在canvas里的应用.md"}');export{e as data}; diff --git "a/assets/web_\350\243\205\351\245\260\345\231\250\346\250\241\345\274\217\345\234\250canvas\351\207\214\347\232\204\345\272\224\347\224\250.html-tqEN9jbM.js" "b/assets/web_\350\243\205\351\245\260\345\231\250\346\250\241\345\274\217\345\234\250canvas\351\207\214\347\232\204\345\272\224\347\224\250.html-tqEN9jbM.js" new file mode 100644 index 0000000..3a33a90 --- /dev/null +++ "b/assets/web_\350\243\205\351\245\260\345\231\250\346\250\241\345\274\217\345\234\250canvas\351\207\214\347\232\204\345\272\224\347\224\250.html-tqEN9jbM.js" @@ -0,0 +1 @@ +import{_ as s,o as a,c as _,a as e}from"./app-x8p6wK6B.js";const t="/assets/20220221181054219_1470266552-JVSSjxaF.png",c="/assets/20220221181100943_1823097082-9a4ulm3V.png",n="/assets/20220221181107838_495981778-XBC-v5cr.png",r={},o=e('

[web]装饰器模式在canvas里的应用

',4),i=[o];function p(l,m){return a(),_("div",null,i)}const h=s(r,[["render",p],["__file","web_装饰器模式在canvas里的应用.html.vue"]]);export{h as default}; diff --git "a/assets/webodm\351\205\215\347\275\256\345\256\211\350\243\205.html-_7-Ppzp6.js" "b/assets/webodm\351\205\215\347\275\256\345\256\211\350\243\205.html-_7-Ppzp6.js" new file mode 100644 index 0000000..a8bebf3 --- /dev/null +++ "b/assets/webodm\351\205\215\347\275\256\345\256\211\350\243\205.html-_7-Ppzp6.js" @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-7dfc8bcb","path":"/notebook/3D%E5%BB%BA%E6%A8%A1/webodm%E9%85%8D%E7%BD%AE%E5%AE%89%E8%A3%85.html","title":"webodm配置安装","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"moyechen 23.9.24","slug":"moyechen-23-9-24","link":"#moyechen-23-9-24","children":[{"level":3,"title":"步骤1 wsl2配置","slug":"步骤1-wsl2配置","link":"#步骤1-wsl2配置","children":[]},{"level":3,"title":"步骤1 安装docker desktop","slug":"步骤1-安装docker-desktop","link":"#步骤1-安装docker-desktop","children":[]},{"level":3,"title":"ubuntu nvidia驱动配置","slug":"ubuntu-nvidia驱动配置","link":"#ubuntu-nvidia驱动配置","children":[]},{"level":3,"title":"步骤3 拉取项目文件","slug":"步骤3-拉取项目文件","link":"#步骤3-拉取项目文件","children":[]},{"level":3,"title":"步骤4 启动","slug":"步骤4-启动","link":"#步骤4-启动","children":[]},{"level":3,"title":"mipc杂项","slug":"mipc杂项","link":"#mipc杂项","children":[]}]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/3D建模/webodm配置安装.md"}');export{e as data}; diff --git "a/assets/webodm\351\205\215\347\275\256\345\256\211\350\243\205.html-efDH4Tm-.js" "b/assets/webodm\351\205\215\347\275\256\345\256\211\350\243\205.html-efDH4Tm-.js" new file mode 100644 index 0000000..87dc7df --- /dev/null +++ "b/assets/webodm\351\205\215\347\275\256\345\256\211\350\243\205.html-efDH4Tm-.js" @@ -0,0 +1,31 @@ +import{_ as e,o as i,c as n,a}from"./app-x8p6wK6B.js";const s="/assets/339666605625810-SRbakhNE.png",d="/assets/44541929951561-LUCbnwYK.png",t={},r=a('

webodm配置安装

moyechen 23.9.24

环境配置 windows11

rtx4070 已在windwos部署好驱动,cuda

步骤1 wsl2配置

启动wsl 可能需要更新,wsl --update 打开微软应用闪电,搜索ubuntu,安装ubuntu

安装结束后,点击启动,需初始化ubuntu的账号密码

步骤1 安装docker desktop

从官网下载即可 启动后打开设置,勾选wsl2,选中刚安装的ubuntu

ubuntu nvidia驱动配置

https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html#installing-with-apt

进入ubuntu

配置gpgkey

curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg \\
+  && curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \\
+    sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \\
+    sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list \\
+  && \\
+    sudo apt-get update
+

安装工具包

sudo apt-get install -y nvidia-container-toolkit
+

执行

sudo nvidia-ctk runtime configure --runtime=docker
+

但是wsl的配置文件不在/etc/docker/下,我们吧工具增加的内容复制出来,去docker desktop配置即可

修改后点击右下角apply&restart

重启完成后,检测是否部署成功

sudo docker run --rm --runtime=nvidia --gpus all ubuntu nvidia-smi
+

Your output should resemble the following output:

+-----------------------------------------------------------------------------+
+| NVIDIA-SMI 535.86.10    Driver Version: 535.86.10    CUDA Version: 12.2     |
+|-------------------------------+----------------------+----------------------+
+| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
+| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
+|                               |                      |               MIG M. |
+|===============================+======================+======================|
+|   0  Tesla T4            On   | 00000000:00:1E.0 Off |                    0 |
+| N/A   34C    P8     9W /  70W |      0MiB / 15109MiB |      0%      Default |
+|                               |                      |                  N/A |
++-------------------------------+----------------------+----------------------+
+
++-----------------------------------------------------------------------------+
+| Processes:                                                                  |
+|  GPU   GI   CI        PID   Type   Process name                  GPU Memory |
+|        ID   ID                                                   Usage      |
+|=============================================================================|
+|  No running processes found                                                 |
++-----------------------------------------------------------------------------+
+

步骤3 拉取项目文件

在打开的ubuntu中, 拉取项目(需提前安装git)

git clone https://github.com/OpenDroneMap/WebODM
+

步骤4 启动

./webodm.sh start --gpu
+

mipc杂项

时间估算 132张照片大概一小时

132×132/5 ~= 3600

256张大概4小时

gpu 实际gpu使用率一直没上去,也不知道为啥

测试数据集

https://github.com/pierotofy/dataset_banana/tree/master

`,36),l=[r];function u(c,o){return i(),n("div",null,l)}const v=e(t,[["render",u],["__file","webodm配置安装.html.vue"]]);export{v as default}; diff --git a/assets/webpack-source_map.html-8aoWF3hJ.js b/assets/webpack-source_map.html-8aoWF3hJ.js new file mode 100644 index 0000000..88b4864 --- /dev/null +++ b/assets/webpack-source_map.html-8aoWF3hJ.js @@ -0,0 +1 @@ +import{_ as c,o,c as a,b as e,d as s}from"./app-x8p6wK6B.js";const t={},_=e("h1",{id:"webpack-source-map",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#webpack-source-map","aria-hidden":"true"},"#"),s(" webpack-source_map")],-1),r=e("p",null,"sourcemap 文件对混淆后的js代码与源文件做了映射, 可以在控制台查看打包后的js文件报错, 方便开发调试",-1),n=e("p",null,"参考资料:",-1),p=e("blockquote",null,[e("p",null,"https://www.v2ex.com/amp/t/671001")],-1),l=[_,r,n,p];function d(u,h){return o(),a("div",null,l)}const m=c(t,[["render",d],["__file","webpack-source_map.html.vue"]]);export{m as default}; diff --git a/assets/webpack-source_map.html-vldnKXpI.js b/assets/webpack-source_map.html-vldnKXpI.js new file mode 100644 index 0000000..2454470 --- /dev/null +++ b/assets/webpack-source_map.html-vldnKXpI.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-3b4cc106","path":"/notebook/webpack-source_map.html","title":"webpack-source_map","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/webpack-source_map.md"}');export{e as data}; diff --git a/assets/zerotier.html--ebF61CG.js b/assets/zerotier.html--ebF61CG.js new file mode 100644 index 0000000..d08e887 --- /dev/null +++ b/assets/zerotier.html--ebF61CG.js @@ -0,0 +1,13 @@ +import{_ as e,o as t,c as i,a}from"./app-x8p6wK6B.js";const r="/assets/388303814279280-O_8WYwxq.png",s="/assets/231835696836803-2nk4Z3C-.png",n="/assets/382107205625895-2OGByWCv.png",d="/assets/424924709279287-YfJWF5ev.png",l={},o=a('

zerotier

https://stray.love/jiao-cheng/zerotier-zhong-jie-jiao-cheng https://zhuanlan.zhihu.com/p/383471270

使用zerotier完成内网穿透

优点:无需公网ip,即可大概率p2p打通 缺点:移动的设备需要每台设备都安装客户端, 固定的设备可通过路由器安装zerotier直接管理

实战配置

zerotier安装在路由器时,可以自动管理 但是路由器装不了, 所以被迫安装到了n1盒子上,也可以通过设置路由表进行管理

网络情况如下:

hz ,路由器lan 192.168.5.1/24 安装zerotier客户端,分配虚拟ip 10.144.250.49 wz, 路由器lan 192.168.2.1/24 不能装zerotier客户端, 由局域网设备n1(192.168.2.190)安装,并分配虚拟ip 10.144.199.120

1 zerotier 配置

1.1设置路由

1.2 设置这两个设备允许 Allow Ethernet Bridging

zerotier 设置结束

2 客户端设置

2.1 路由器客户端设置

路由器可傻瓜配置,只需要勾选 "自动允许客户端 NAT" 即可

2.2 n1盒子设置

n1盒子没有提供简单的web ui界面, 因此需要手动管理路由表

首先使用 zerotier-cli listnetworks 命令, 查看网卡id

root@aml:~# zerotier-cli listnetworks
+200 listnetworks <nwid> <name> <mac> <status> <type> <dev> <ZT assigned ips>
+200 listnetworks 8bd5124fd6c7fc63 zt-home 62:0f:bf:0d:13:f1 OK PRIVATE zt0 10.144.199.120/16
+

PRIVATE 后面的zt0是网卡id

第一步,打开盒子的网络转发功能

#临时生效
+echo "1" > /proc/sys/net/ipv4/ip_forward
+#永久生效,需要修改sysctl.conf,然后执行sysctl -p
+net.ipv4.ip_forward = 1
+

接下来,处理防火墙规则

sudo iptables -A FORWARD -i zt0 -j ACCEPT
+sudo iptables -A FORWARD -o zt0 -j ACCEPT
+sudo iptables -t nat -A POSTROUTING  ! -o lo -j MASQUERADE
+

2023 10月16日, 发现这样的规则会导致该设备离线后其他设备不会通过网关访问其他设备,而是通过该设备,很尴尬

这里 zt0 为zerotier虚拟网卡 保存iptable规则

sudo apt-get install iptables-persistent
+sudo sh -c "iptables-save > /etc/iptables/rules.v4"
+
`,29),c=[o];function p(h,u){return t(),i("div",null,c)}const g=e(l,[["render",p],["__file","zerotier.html.vue"]]);export{g as default}; diff --git a/assets/zerotier.html-w6bwfzot.js b/assets/zerotier.html-w6bwfzot.js new file mode 100644 index 0000000..6ebdf54 --- /dev/null +++ b/assets/zerotier.html-w6bwfzot.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-357da27c","path":"/router/zerotier.html","title":"zerotier","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"实战配置","slug":"实战配置","link":"#实战配置","children":[{"level":3,"title":"1 zerotier 配置","slug":"_1-zerotier-配置","link":"#_1-zerotier-配置","children":[]},{"level":3,"title":"1.2 设置这两个设备允许 Allow Ethernet Bridging","slug":"_1-2-设置这两个设备允许-allow-ethernet-bridging","link":"#_1-2-设置这两个设备允许-allow-ethernet-bridging","children":[]},{"level":3,"title":"2 客户端设置","slug":"_2-客户端设置","link":"#_2-客户端设置","children":[]}]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"router/zerotier.md"}');export{e as data}; diff --git "a/assets/zerotier\343\200\201\344\272\214\347\272\247\350\267\257\347\224\261\343\200\201DMZ.html-1tr5uUKd.js" "b/assets/zerotier\343\200\201\344\272\214\347\272\247\350\267\257\347\224\261\343\200\201DMZ.html-1tr5uUKd.js" new file mode 100644 index 0000000..6096f75 --- /dev/null +++ "b/assets/zerotier\343\200\201\344\272\214\347\272\247\350\267\257\347\224\261\343\200\201DMZ.html-1tr5uUKd.js" @@ -0,0 +1 @@ +import{_ as t,o as r,c as _,b as e,d as o}from"./app-x8p6wK6B.js";const s="/assets/20221222175006341_28511-qud_ErsR.png",c={},a=e("h1",{id:"zerotier、二级路由、dmz",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#zerotier、二级路由、dmz","aria-hidden":"true"},"#"),o(" zerotier、二级路由、DMZ")],-1),n=e("p",null,"开启DMZ主机后,一级路由器的路由表规则如下",-1),i=e("p",null,[e("img",{src:s,alt:""})],-1),d=[a,n,i];function l(h,m){return r(),_("div",null,d)}const f=t(c,[["render",l],["__file","zerotier、二级路由、DMZ.html.vue"]]);export{f as default}; diff --git "a/assets/zerotier\343\200\201\344\272\214\347\272\247\350\267\257\347\224\261\343\200\201DMZ.html-dYsPzP-4.js" "b/assets/zerotier\343\200\201\344\272\214\347\272\247\350\267\257\347\224\261\343\200\201DMZ.html-dYsPzP-4.js" new file mode 100644 index 0000000..bd2cb6a --- /dev/null +++ "b/assets/zerotier\343\200\201\344\272\214\347\272\247\350\267\257\347\224\261\343\200\201DMZ.html-dYsPzP-4.js" @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-70e270ee","path":"/router/zerotier%E3%80%81%E4%BA%8C%E7%BA%A7%E8%B7%AF%E7%94%B1%E3%80%81DMZ.html","title":"zerotier、二级路由、DMZ","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"router/zerotier、二级路由、DMZ.md"}');export{e as data}; diff --git "a/assets/\343\200\220\350\277\220\347\273\264\343\200\221expect.html-Xo_NTm5r.js" "b/assets/\343\200\220\350\277\220\347\273\264\343\200\221expect.html-Xo_NTm5r.js" new file mode 100644 index 0000000..7700383 --- /dev/null +++ "b/assets/\343\200\220\350\277\220\347\273\264\343\200\221expect.html-Xo_NTm5r.js" @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-37242cf2","path":"/ops/%E3%80%90%E8%BF%90%E7%BB%B4%E3%80%91expect.html","title":"【运维】expect","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"ops/【运维】expect.md"}');export{e as data}; diff --git "a/assets/\343\200\220\350\277\220\347\273\264\343\200\221expect.html-r2NWxrez.js" "b/assets/\343\200\220\350\277\220\347\273\264\343\200\221expect.html-r2NWxrez.js" new file mode 100644 index 0000000..2b30766 --- /dev/null +++ "b/assets/\343\200\220\350\277\220\347\273\264\343\200\221expect.html-r2NWxrez.js" @@ -0,0 +1 @@ +import{_ as t,o as s,c as o,b as e,d as c}from"./app-x8p6wK6B.js";const l="/assets/20220913145345755_22381-WQ_61mxD.png",n={},_=e("h1",{id:"【运维】expect",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#【运维】expect","aria-hidden":"true"},"#"),c(" 【运维】expect")],-1),a=e("blockquote",null,[e("p",null,"https://ignorantshr.github.io/person-blog/shell/shell%E8%84%9A%E6%9C%AC%E8%87%AA%E5%8A%A8%E8%BE%93%E5%85%A5/")],-1),r=e("blockquote",null,[e("p",null,"https://www.cnblogs.com/lixigang/articles/4849527.html")],-1),i=e("p",null,[e("img",{src:l,alt:""})],-1),h=[_,a,r,i];function d(p,u){return s(),o("div",null,h)}const m=t(n,[["render",d],["__file","【运维】expect.html.vue"]]);export{m as default}; diff --git "a/assets/\344\271\220\350\247\202\351\224\201\343\200\201\346\202\262\350\247\202\351\224\201\343\200\201\345\210\206\345\270\203\345\274\217\351\224\201.html-P9kFGdGG.js" "b/assets/\344\271\220\350\247\202\351\224\201\343\200\201\346\202\262\350\247\202\351\224\201\343\200\201\345\210\206\345\270\203\345\274\217\351\224\201.html-P9kFGdGG.js" new file mode 100644 index 0000000..37fda77 --- /dev/null +++ "b/assets/\344\271\220\350\247\202\351\224\201\343\200\201\346\202\262\350\247\202\351\224\201\343\200\201\345\210\206\345\270\203\345\274\217\351\224\201.html-P9kFGdGG.js" @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-8100aa12","path":"/web/%E4%B9%90%E8%A7%82%E9%94%81%E3%80%81%E6%82%B2%E8%A7%82%E9%94%81%E3%80%81%E5%88%86%E5%B8%83%E5%BC%8F%E9%94%81.html","title":"乐观锁、悲观锁、分布式锁","lang":"en-US","frontmatter":{},"headers":[{"level":3,"title":"100并发","slug":"_100并发","link":"#_100并发","children":[]},{"level":3,"title":"并发100, 总共1000个","slug":"并发100-总共1000个","link":"#并发100-总共1000个","children":[]},{"level":3,"title":"并发200,总共1000","slug":"并发200-总共1000","link":"#并发200-总共1000","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"web/乐观锁、悲观锁、分布式锁.md"}');export{e as data}; diff --git "a/assets/\344\271\220\350\247\202\351\224\201\343\200\201\346\202\262\350\247\202\351\224\201\343\200\201\345\210\206\345\270\203\345\274\217\351\224\201.html-jTPLzWIf.js" "b/assets/\344\271\220\350\247\202\351\224\201\343\200\201\346\202\262\350\247\202\351\224\201\343\200\201\345\210\206\345\270\203\345\274\217\351\224\201.html-jTPLzWIf.js" new file mode 100644 index 0000000..a593dcd --- /dev/null +++ "b/assets/\344\271\220\350\247\202\351\224\201\343\200\201\346\202\262\350\247\202\351\224\201\343\200\201\345\210\206\345\270\203\345\274\217\351\224\201.html-jTPLzWIf.js" @@ -0,0 +1,119 @@ +import{_ as n,o as s,c as a,a as t}from"./app-x8p6wK6B.js";const p="/assets/284455698836999-JYle4GdA.png",e="/assets/147946907626091-Gwqindbp.png",o="/assets/500087022133366-w73em1gi.png",c="/assets/501727794900246-II9R_YS8.png",i="/assets/401180871947710-4AqukcNL.png",l="/assets/298007630951842-DxmUwS8I.png",u="/assets/287800781817896-Vpyzzqtw.png",r="/assets/239891913912036-u-9AFBdU.png",d="/assets/270522409533576-XXXpJ4s5.png",k="/assets/548223420659412-6QJypmJi.png",v={},m=t(`

乐观锁、悲观锁、分布式锁

假设抢购系统,1000用户在10秒内购买一个商品

"""
+并发更新速度测试
+ab -n 1000 -c 100 http://127.0.0.1:8000/
+"""
+
+from fastapi import FastAPI
+import pymysql
+# SQLALCHEMY_DATABASE_URL = "postgresql://postgres:postgres@localhost:5432/demo2"
+import redis
+from redis import Redis
+
+app = FastAPI()
+pool = redis.ConnectionPool(host='localhost', port=6379, max_connections=100) # 链接数量要大于最大并发数,否则实例化不出来
+
+
+def leguan(retry=0, db=None):
+    if db is None:
+        db = pymysql.Connect(host='localhost', user='root', password='example', db='moye')
+    db.begin()
+    cursor = db.cursor()
+    cursor.execute("select * from emp where id=1")
+    version = cursor.fetchone()[2]
+
+    count = cursor.execute("update emp set value=value-1, version=version+1 where id=1 and value-1>=0 and version="+str(version))
+    if count == 0:
+        db.rollback()
+        if retry <= 4:
+            return leguan(retry + 1, db)
+        return {"shibai":"shibail"}
+    db.commit()
+    return {"Hello": "World"}
+
+def beiguan():
+    db = pymysql.Connect(host='localhost', user='root', password='example', db='moye')
+    db.begin()
+    cursor = db.cursor()
+    cursor.execute("select * from emp where id=1 for update")
+    version = cursor.fetchone()[2]
+
+    count = cursor.execute("update emp set value=value-1, version=version+1 where id=1 and value-1>=0")
+    if count == 0:
+        db.rollback()
+        return {"shibai":"shibail"}
+    db.commit()
+    return {"Hello": "World"}
+
+def redis_():
+    redis_client: Redis = redis.Redis(connection_pool=pool)
+    # redis_client: Redis = redis.from_url("redis://localhost:6379")
+    with redis_client.lock(name='id_1',sleep=0.01, timeout=60, blocking_timeout=60):
+
+        db = pymysql.Connect(host='localhost', user='root', password='example', db='moye')
+        db.begin()
+        cursor = db.cursor()
+        cursor.execute("select * from emp where id=1")
+        version = cursor.fetchone()[2]
+
+        count = cursor.execute("update emp set value=value-1, version=version+1 where id=1 and value-1>=0")
+        if count == 0:
+            db.rollback()
+            return {"shibai": "shibail"}
+        db.commit()
+        return {"Hello": "World"}
+
+
+@app.get("/")
+def read_root():
+    # leguan() # 乐观锁100个请求,在一秒内只能成功5-15个
+    # beiguan() # 悲观锁速度没慢多少的同时,全部成功了
+    redis_() # redis由于需要cpu sleep ,属于是又慢又怕锁超时
+
+

使用ab压测

100并发

悲观锁

乐观锁

可惜只有6个购买成功

并发100, 总共1000个

乐观锁 成功147个

悲观锁

又快又好,真离谱

redis

并发200,总共1000

悲观锁

redis 分布式锁

悲观锁+async sqlalchemy

reids锁+ async aioreids

慢的离谱,cpu90%

"""
+并发更新速度测试
+ab -n 1000 -c 100 http://127.0.0.1:8000/
+"""
+
+from fastapi import FastAPI
+# SQLALCHEMY_DATABASE_URL = "postgresql://postgres:postgres@localhost:5432/demo2"
+import sqlalchemy as sa
+from aioredis import Redis
+import aioredis
+app = FastAPI()
+# pool = aioredis.ConnectionPool(host='localhost', port=6379, max_connections=100) # 链接数量要大于最大并发数,否则实例化不出来
+from sqlalchemy.ext.asyncio import create_async_engine
+
+engine = create_async_engine(
+    "mysql+asyncmy://root:example@localhost:3306/moye"
+)
+
+async def beiguan():
+
+    async with engine.connect() as db, db.begin():
+
+
+        result = await db.execute(sa.text("select * from emp where id=1 for update"))
+        version = result.fetchone()[2]
+
+        count = await db.execute(sa.text("update emp set value=value-1, version=version+1 where id=1 and value-1>=0"))
+    return {"Hello": "World"}
+
+async def redis_():
+    # redis_client: Redis = redis.Redis(connection_pool=pool)
+    redis_client: Redis = Redis.from_url("redis://localhost:6379")
+    async with redis_client.lock(name='id_1',sleep=0.01, timeout=60, blocking_timeout=60):
+        async with engine.connect() as db, db.begin():
+            result = await db.execute(sa.text("select * from emp where id=1"))
+            version = result.fetchone()[2]
+
+            count = await db.execute(sa.text("update emp set value=value-1, version=version+1 where id=1 and value-1>=0"))
+
+
+
+@app.get("/")
+async def read_root():
+    # leguan() # 乐观锁100个请求,在一秒内只能成功5-15个b
+    await beiguan() # 悲观锁速度没慢多少的同时,全部成功了
+    # await redis_() # redis由于需要cpu sleep ,属于是又慢又怕锁超时
+
+
`,30),b=[m];function h(g,y){return s(),a("div",null,b)}const _=n(v,[["render",h],["__file","乐观锁、悲观锁、分布式锁.html.vue"]]);export{_ as default}; diff --git "a/assets/\344\273\243\347\220\206\344\275\277\347\224\250.html-5t2ZHJgP.js" "b/assets/\344\273\243\347\220\206\344\275\277\347\224\250.html-5t2ZHJgP.js" new file mode 100644 index 0000000..5bae0c5 --- /dev/null +++ "b/assets/\344\273\243\347\220\206\344\275\277\347\224\250.html-5t2ZHJgP.js" @@ -0,0 +1 @@ +import{_ as t,o as e,c as o,a as r}from"./app-x8p6wK6B.js";const a={},h=r('

代理使用

环境变量

Linux

使用socks5 export http_proxy="socks5://127.0.0.1:10808" export https_proxy="socks5://127.0.0.1:10808" 使用http export http_proxy="http://127.0.0.1:10809" export https_proxy="http://127.0.0.1:10809" 指定不使用代理的域名和IP export no_proxy='a.test.com,127.0.0.1,192.168.0.0/16'

Windows

命令行 set http_proxy="http://127.0.0.1:10809" set https_proxy="http://127.0.0.1:10809" 或者在系统设置里设环境变量 http_proxy | http://127.0.0.1:10809 https_proxy | http://127.0.0.1:10809

Ubuntu apt

sudo tee /etc/apt/apt.conf.d/proxy.conf << EOF Acquire { HTTP::proxy "http://127.0.0.1:10809"; HTTPS::proxy "http://127.0.0.1:10809"; } EOF

Git

HTTP方式访问 git config --global http.proxy 'socks5://127.0.0.1:10808' git config --global https.proxy 'socks5://127.0.0.1:10808'

SSH方式访问,以github.com为例 ~/.ssh/config Host github.com # Mac/Ubuntu下,使用socks5 ProxyCommand nc -X 5 -x 127.0.0.1:10808 %h %p

Docker

Ubuntu下修改 /etc/default/docker CentOS下修改 /etc/sysconfig/docker export http_proxy="http://127.0.0.1:10809" export https_proxy="http://127.0.0.1:10809" export no_proxy='a.test.com,127.0.0.1,192.168.0.0/16' 重启docker后,运行docker info检查

Python代码

通过requests模块使用 proxies={ 'http': 'http://127.0.0.1:10809', 'https': 'http://127.0.0.1:10809' }

r = requests.get(url, proxies=proxies)

r = requests.post(url, headers=headers, json=payload, proxies=proxies)

浏览器插件

推荐使用SwitchyOmega,支持Chrome/Edge/Firefox。 首先配置一个场景模式,命名为proxy或任何你喜欢的名字,在里面添加SOCKS5或者HTTP代理,还可以手动添加你不想代理的地址列表,如内网IP段/指定域名等:

在auto switch中添加规则列表,并让规则列表默认走上面配置的proxy场景: https://raw.githubusercontent.com/gfwlist/gfwlist/master/gfwlist.txt

选择auto switch的场景模式,此时只有规则列表里的域名会走代理:

其他

常用包管理器的代理设置:https://github.com/comwrg/package-manager-proxy-settings

',23),p=[h];function s(i,c){return e(),o("div",null,p)}const n=t(a,[["render",s],["__file","代理使用.html.vue"]]);export{n as default}; diff --git "a/assets/\344\273\243\347\220\206\344\275\277\347\224\250.html-LkBfvjFZ.js" "b/assets/\344\273\243\347\220\206\344\275\277\347\224\250.html-LkBfvjFZ.js" new file mode 100644 index 0000000..2c32064 --- /dev/null +++ "b/assets/\344\273\243\347\220\206\344\275\277\347\224\250.html-LkBfvjFZ.js" @@ -0,0 +1 @@ +const l=JSON.parse('{"key":"v-bca00f24","path":"/ops/%E4%BB%A3%E7%90%86%E4%BD%BF%E7%94%A8.html","title":"代理使用","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"环境变量","slug":"环境变量","link":"#环境变量","children":[{"level":3,"title":"Linux","slug":"linux","link":"#linux","children":[]},{"level":3,"title":"Windows","slug":"windows","link":"#windows","children":[]}]},{"level":2,"title":"Ubuntu apt","slug":"ubuntu-apt","link":"#ubuntu-apt","children":[]},{"level":2,"title":"Git","slug":"git","link":"#git","children":[]},{"level":2,"title":"Docker","slug":"docker","link":"#docker","children":[]},{"level":2,"title":"Python代码","slug":"python代码","link":"#python代码","children":[]},{"level":2,"title":"浏览器插件","slug":"浏览器插件","link":"#浏览器插件","children":[]},{"level":2,"title":"其他","slug":"其他","link":"#其他","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"ops/代理使用.md"}');export{l as data}; diff --git "a/assets/\344\273\245\345\233\276\346\220\234\345\233\276.html-HBoOJ3G3.js" "b/assets/\344\273\245\345\233\276\346\220\234\345\233\276.html-HBoOJ3G3.js" new file mode 100644 index 0000000..bf95531 --- /dev/null +++ "b/assets/\344\273\245\345\233\276\346\220\234\345\233\276.html-HBoOJ3G3.js" @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-38e7669c","path":"/python/%E4%BB%A5%E5%9B%BE%E6%90%9C%E5%9B%BE.html","title":"以图搜图","lang":"en-US","frontmatter":{},"headers":[{"level":3,"title":"部署","slug":"部署","link":"#部署","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"python/以图搜图.md"}');export{t as data}; diff --git "a/assets/\344\273\245\345\233\276\346\220\234\345\233\276.html-rQJpjPS7.js" "b/assets/\344\273\245\345\233\276\346\220\234\345\233\276.html-rQJpjPS7.js" new file mode 100644 index 0000000..57c5977 --- /dev/null +++ "b/assets/\344\273\245\345\233\276\346\220\234\345\233\276.html-rQJpjPS7.js" @@ -0,0 +1 @@ +import{_ as s,o,c as n,b as e,d as t}from"./app-x8p6wK6B.js";const _={},a=e("h1",{id:"以图搜图",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#以图搜图","aria-hidden":"true"},"#"),t(" 以图搜图")],-1),c=e("h3",{id:"部署",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#部署","aria-hidden":"true"},"#"),t(" 部署")],-1),r=e("p",null,"安装扩展",-1),d=e("p",null,"安装指定版本pg_config",-1),i=e("p",null,"yum install postgresql12-devel --skip-broken",-1),l=[a,c,r,d,i];function h(u,f){return o(),n("div",null,l)}const m=s(_,[["render",h],["__file","以图搜图.html.vue"]]);export{m as default}; diff --git "a/assets/\344\275\277\347\224\250onedrive\345\234\250win10\345\222\214linux\344\271\213\351\227\264\345\220\214\346\255\245.html-DH2Z4RxM.js" "b/assets/\344\275\277\347\224\250onedrive\345\234\250win10\345\222\214linux\344\271\213\351\227\264\345\220\214\346\255\245.html-DH2Z4RxM.js" new file mode 100644 index 0000000..02b94b4 --- /dev/null +++ "b/assets/\344\275\277\347\224\250onedrive\345\234\250win10\345\222\214linux\344\271\213\351\227\264\345\220\214\346\255\245.html-DH2Z4RxM.js" @@ -0,0 +1,22 @@ +import{_ as t,r as o,o as l,c as d,b as e,d as n,e as a,a as i}from"./app-x8p6wK6B.js";const r={},c=e("h1",{id:"使用onedrive在win10和linux之间同步",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#使用onedrive在win10和linux之间同步","aria-hidden":"true"},"#"),n(" 使用onedrive在win10和linux之间同步")],-1),u=e("p",null,"我们在写代码的时候,经常有这样的场景: 在Windows下开发,然后放在服务器上跑",-1),p=e("p",null,"刚开始开发,整个项目只有一个文件(.py) ,这时候我使用xshell链接到服务器,使用rz命令上传文件, 就解决了问题",-1),h=e("p",null,"之后, 使用PyCharm 远程调试, 链接服务器进行同步, 也解决一定的问题,",-1),v=e("p",null,"最近跟风上了一年的OneDrive 365 (家庭版,6人240,一人40), onedrive 空间从免费的5g提升到了1tb,",-1),m={href:"https://github.com/skilion/onedrive",target:"_blank",rel:"noopener noreferrer"},b=i(`

!!!! 在ubuntu16上有些许问题, 因为大佬不在维护, 因此使用另外一个同学的产品 https://github.com/abraunegg/onedrive.git

本人环境: win10 , centos7(1g 1h 1m)

上手:

事前准备: Fedora/CentOS

sudo yum install libcurl-devel
+sudo yum install sqlite-devel
+curl -fsS https://dlang.org/install.sh | bash -s dmd
+

安装

git clone https://github.com/skilion/onedrive.git
+cd onedrive
+make
+sudo make install
+

卸载

sudo make uninstall
+# delete the application state
+rm -rf .config/onedrive
+

进行配置

如果不配置, 你Onedrive中的文件默认会下载到 ~/OneDrive这个目录,并且隐藏的文件会跳过 如果你想改变位置等等, 做以下操作

mkdir -p ~/.config/onedrive
+cp ./config ~/.config/onedrive/config
+vim ~/.config/onedrive/config
+

可用选项:

  • sync_dir: 本地的onedrive文件夹路径,onedrive中的文件会保存在本地的这个目录
  • skip_file: 设置跳过的文件

demo:

# Directory where the files will be synced
+sync_dir = "~/OneDrive"
+# Skip files and directories that match this pattern
+skip_file = ".*|~*"
+
`,17),_=e("code",null,"*",-1),f=e("code",null,"?",-1),g={href:"https://technet.microsoft.com/en-us/library/bb490639.aspx",target:"_blank",rel:"noopener noreferrer"},k=e("code",null,"|",-1),x=i(`

Note: 改变配置文件后, 应该执行 onedrive --resync 以获得同步

选择性同步

选择性同步允许你只同步一个文件夹,或者是一个文件 方法:

  • 首先,确保你做了上面的配置文件,如果没有,点击跳转
  • 然后, 在~/.config/onedrive/ 目录下创建文件 sync_list

sync_list:的一个例子

Backup
+Documents/latest_report.docx
+Work/ProjectX
+notes.txt
+

Note: 改变配置文件后, 应该执行 onedrive --resync 以获得同步

本人的使用方法

`,8),y={href:"https://github.com/tamlok/vnote",target:"_blank",rel:"noopener noreferrer"},w={href:"https://github.com/tamlok/viki",target:"_blank",rel:"noopener noreferrer"},N=e("p",null,"具体操作:",-1),q=e("li",null,[n("在onedrive 根目录下新建文件夹"),e("code",null,"blog")],-1),D=e("li",null,[n("打开vnote, 新建一个笔记本,并设置根目录为 "),e("code",null,"onedrive/blog")],-1),O={href:"https://github.com/tamlok/viki/archive/v2.0.1.zip",target:"_blank",rel:"noopener noreferrer"};function z(B,S){const s=o("ExternalLinkIcon");return l(),d("div",null,[c,u,p,h,v,e("p",null,[n("同时也看到了大佬的github "),e("a",m,[n("skilion"),a(s)]),n(",")]),b,e("p",null,[n("Patterns are case insensitive. "),_,n(" and "),f,n(),e("a",g,[n("wildcards characters"),a(s)]),n(" are supported. Use "),k,n(" to separate multiple patterns.")]),x,e("p",null,[n("本人使用 "),e("a",y,[n("vnote"),a(s)]),n(" 来编写笔记, 同时使用 "),e("a",w,[n("viki"),a(s)]),n(" 来作为web服务")]),N,e("ul",null,[q,D,e("li",null,[n("下载最新版的viki源文件, "),e("a",O,[n("下载链接"),a(s)]),n(",解压缩")])])])}const C=t(r,[["render",z],["__file","使用onedrive在win10和linux之间同步.html.vue"]]);export{C as default}; diff --git "a/assets/\344\275\277\347\224\250onedrive\345\234\250win10\345\222\214linux\344\271\213\351\227\264\345\220\214\346\255\245.html-wF-F4Tgw.js" "b/assets/\344\275\277\347\224\250onedrive\345\234\250win10\345\222\214linux\344\271\213\351\227\264\345\220\214\346\255\245.html-wF-F4Tgw.js" new file mode 100644 index 0000000..a9ec9a5 --- /dev/null +++ "b/assets/\344\275\277\347\224\250onedrive\345\234\250win10\345\222\214linux\344\271\213\351\227\264\345\220\214\346\255\245.html-wF-F4Tgw.js" @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-43c0d09a","path":"/notebook/%E4%BD%BF%E7%94%A8onedrive%E5%9C%A8win10%E5%92%8Clinux%E4%B9%8B%E9%97%B4%E5%90%8C%E6%AD%A5.html","title":"使用onedrive在win10和linux之间同步","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"上手:","slug":"上手","link":"#上手","children":[{"level":3,"title":"事前准备: Fedora/CentOS","slug":"事前准备-fedora-centos","link":"#事前准备-fedora-centos","children":[]},{"level":3,"title":"安装","slug":"安装","link":"#安装","children":[]},{"level":3,"title":"卸载","slug":"卸载","link":"#卸载","children":[]},{"level":3,"title":"进行配置","slug":"进行配置","link":"#进行配置","children":[]},{"level":3,"title":"选择性同步","slug":"选择性同步","link":"#选择性同步","children":[]}]},{"level":2,"title":"本人的使用方法","slug":"本人的使用方法","link":"#本人的使用方法","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/使用onedrive在win10和linux之间同步.md"}');export{e as data}; diff --git "a/assets/\344\275\277\347\224\250\347\275\227\346\212\200\346\221\204\345\203\217\345\244\264_\346\226\220\350\256\257n1\347\233\222\345\255\220\347\233\264\346\222\255.html-8Vw1sWwQ.js" "b/assets/\344\275\277\347\224\250\347\275\227\346\212\200\346\221\204\345\203\217\345\244\264_\346\226\220\350\256\257n1\347\233\222\345\255\220\347\233\264\346\222\255.html-8Vw1sWwQ.js" new file mode 100644 index 0000000..4354912 --- /dev/null +++ "b/assets/\344\275\277\347\224\250\347\275\227\346\212\200\346\221\204\345\203\217\345\244\264_\346\226\220\350\256\257n1\347\233\222\345\255\220\347\233\264\346\222\255.html-8Vw1sWwQ.js" @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-94b8d7f0","path":"/notebook/%E4%BD%BF%E7%94%A8%E7%BD%97%E6%8A%80%E6%91%84%E5%83%8F%E5%A4%B4_%E6%96%90%E8%AE%AFn1%E7%9B%92%E5%AD%90%E7%9B%B4%E6%92%AD.html","title":"使用罗技摄像头+斐讯n1盒子直播","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/使用罗技摄像头+斐讯n1盒子直播.md"}');export{t as data}; diff --git "a/assets/\344\275\277\347\224\250\347\275\227\346\212\200\346\221\204\345\203\217\345\244\264_\346\226\220\350\256\257n1\347\233\222\345\255\220\347\233\264\346\222\255.html-Sz6mkK-i.js" "b/assets/\344\275\277\347\224\250\347\275\227\346\212\200\346\221\204\345\203\217\345\244\264_\346\226\220\350\256\257n1\347\233\222\345\255\220\347\233\264\346\222\255.html-Sz6mkK-i.js" new file mode 100644 index 0000000..5d9f056 --- /dev/null +++ "b/assets/\344\275\277\347\224\250\347\275\227\346\212\200\346\221\204\345\203\217\345\244\264_\346\226\220\350\256\257n1\347\233\222\345\255\220\347\233\264\346\222\255.html-Sz6mkK-i.js" @@ -0,0 +1 @@ +import{_,o as t,c as n,b as e,d as a}from"./app-x8p6wK6B.js";const c={},o=e("h1",{id:"使用罗技摄像头-斐讯n1盒子直播",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#使用罗技摄像头-斐讯n1盒子直播","aria-hidden":"true"},"#"),a(" 使用罗技摄像头+斐讯n1盒子直播")],-1),r=[o];function s(d,i){return t(),n("div",null,r)}const l=_(c,[["render",s],["__file","使用罗技摄像头_斐讯n1盒子直播.html.vue"]]);export{l as default}; diff --git "a/assets/\345\210\206\350\276\250\347\216\207.html-A5Aya7jM.js" "b/assets/\345\210\206\350\276\250\347\216\207.html-A5Aya7jM.js" new file mode 100644 index 0000000..fbd1644 --- /dev/null +++ "b/assets/\345\210\206\350\276\250\347\216\207.html-A5Aya7jM.js" @@ -0,0 +1 @@ +const l=JSON.parse('{"key":"v-185ae8c4","path":"/notebook/%E5%88%86%E8%BE%A8%E7%8E%87.html","title":"分辨率","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"物理分辨率","slug":"物理分辨率","link":"#物理分辨率","children":[]},{"level":2,"title":"设置分辨率","slug":"设置分辨率","link":"#设置分辨率","children":[]},{"level":2,"title":"PPI","slug":"ppi","link":"#ppi","children":[]},{"level":2,"title":"ui分辨率","slug":"ui分辨率","link":"#ui分辨率","children":[]},{"level":2,"title":"游戏分辨率","slug":"游戏分辨率","link":"#游戏分辨率","children":[]},{"level":2,"title":"nvidia dsr","slug":"nvidia-dsr","link":"#nvidia-dsr","children":[]},{"level":2,"title":"推断","slug":"推断","link":"#推断","children":[]},{"level":2,"title":"4k显示器尺寸的选择","slug":"_4k显示器尺寸的选择","link":"#_4k显示器尺寸的选择","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/分辨率.md"}');export{l as data}; diff --git "a/assets/\345\210\206\350\276\250\347\216\207.html-RUfi1z9A.js" "b/assets/\345\210\206\350\276\250\347\216\207.html-RUfi1z9A.js" new file mode 100644 index 0000000..ed50f37 --- /dev/null +++ "b/assets/\345\210\206\350\276\250\347\216\207.html-RUfi1z9A.js" @@ -0,0 +1 @@ +import{_ as a,o as e,c as p,a as i}from"./app-x8p6wK6B.js";const h={},r=i('

分辨率

物理分辨率

物理分辨率是指显示器硬件所具有的分辨率

设置分辨率

一般和物理分辨率相符合

PPI

![](_v_images/20230116110508582_721.png =960x)

27寸4K:163.18 27寸2K:108.79 24寸1080P:91.79 14寸1366x768:111.94

R= 操作系统的目标ppi / 显示器的物理ppi

R表示在一定的缩放下,UI文字实际显示的大小和其设计目的大小的比值。

R会有3个结果,大于1,小于1,等于1;等于1说明显示器可以完美地展现UI和文字的设计大小,但没有显示器厂商做这种屏幕,只存在梦里;

R大于1,说明UI和文字实际显示的大小相比设计大小偏大;R小于1,说明UI文字的实际显示大小相比设计大小偏小。R越接近1,实际显示大小和设计大小越接近。

为什么27寸4K显示器“字儿会那么小”?因为当不缩放时,R = (96 * 100%) / 163.18 约等于 0.588,此时的R远小于1,UI和文字的实际显示大小只有设计大小的58%,当然会很小了。

为什么把缩放改成200%字儿就恢复了呢?因为R = (96 * 200%) / 163.18 约等于 1.177,R比1略大,UI和文字的实际显示大小相当于设计大小的117%

为了让UI和文字元素看着舒服,应该尽可能调整缩放让R接近1,也有潭友觉得“小一点无所谓,显示的东西太少太没效率了”,如果你的缩放能让R在0.8左右还是合适的,个人认为R再小就不可接受了。例如在27寸4K显示器上很多人使用150%缩放,得到的R为0.88,只能说大小缩为原来的九成,换更多的元素显示还是值得的。

最后,还有一个有趣的值:

27寸2K显示器,100%缩放,R=1.13 27寸4K显示器,200%缩放,R=1.17

显示元素大小居然差不太多

ui分辨率

win:使用缩放后,ui的等效分辨率,例如2k屏幕,200%缩放=720p, 150%缩放就是1706* 960, 125%缩放就是2048* 1152

https://bbs.saraba1st.com/2b/thread-1986336-1-1.html

游戏分辨率

老游戏可能对高分屏适配不够,会导致ui变小等(如红色警戒)

现代游戏应该是16:9,1080p为基础制作,高于此分辨率则会进行缩放,ui大小不变,但是会很清晰,例如4k中画质>2k高画质

nvidia dsr

N卡有dsr技术,超分辨率

全称Dynamic Super Resolution,中文为动态超级分辨率,也称“自定义分辨率”

使用场景:显示器1080p物理分辨率,但是显卡性能比较强时使用,以4k进行渲染然后输出给显示器

评论:这个设置就是打游戏用的,办公还是算了,挺糊的

DSR其实就类似SSAA抗锯齿,超采样缩放,对画质来说是有提升。但毕竟是要原生渲染4K画面,这对显卡的压力不是一般的小,像2060这样的显卡面对游戏以4K分辨率渲染基本上都是要跪的。简单来说,你要以4K渲染画面,那就只能降低特效才能保证帧率,用抗锯齿和画面的精细度去换低特效这无疑是捡了芝麻丢西瓜。所以NV现在都干脆没提及DSR了,技术没问题,就是一般显卡顶不住这样的压力。为了解决这个问题,DLSS就是最新的替代方案,只可惜没啥游戏支持而已。发布于 2020-06-23 15:11 作者:知乎用户 链接:https://www.zhihu.com/question/402549533/answer/1298403883 来源:知乎 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

这个技术已经是2014年的老技术了,开不开的对性能影响不算很大,而且现在抗锯齿用的就是类似这个技术的操作,没什么意义了已经 以上。

推断

基于以上信息,我的推断:

24寸1080p GTX1070 畅玩所有游戏(中画质60hz) 27寸1440p RTX3060ti 畅玩所有游戏(中画质60hz) 32寸2160p RTX4080 畅玩所有游戏 (中画质60hz)

4k显示器尺寸的选择

因为很多人觉得27”4K的字太小,导致一个两难的问题——不开缩放字体太小看不清;开了缩放,很多软件界面又会模糊,因为他们对缩放的支持很差。而32”因为屏幕更大,字体太小的问题就显得没那么严重了。

微星 mpg321ur

华硕 pg32uq

华硕 pg32uq

木头龙​​中央处理器 (CPU)等 3 个话题下的优秀答主​ 只接PS5玩游戏32寸,兼顾Windows应用27寸。只玩PS5的话,本来为了电视优化的画面,哪怕你坐的近一点也是OK的,尤其是主要是图片、视频内容的主机应用。这时候大屏就是正义,别犹豫直接上32。但你要兼顾电脑上的Windows的话,32寸开200%缩放,等效1920x1080,正常使用距离(50-60CM)时会显得偏大,PPI也高于视网膜分辨率。除非是电脑椅头靠在椅背靠枕上,但这个姿势看片子拿手柄玩游戏还好,敲键盘拿鼠标就很别扭了。开150%缩放的话等效2560x1440,显示元素会更多,但一般的Windows应用是GDI+,非整数缩放是向上取整渲染然后再通过算法缩放回来,所以4K分辨率开150%缩放显示等效2560x1440图像,先取整200%缩放用5120x2880渲染,然后再转换到3840x2160显示,这种做法会导致字体、色块边缘发虚模糊。(UWP应用是另一种渲染方式,字体、色块边缘清晰不少)27寸4K的话,57-60CM使用距离是达到视网膜分辨率的。200%缩放显示等效1920x1080,字体、色块边缘很清晰的,字体元素大小也比较适和。但如果凑得再近一点,达不到视网膜分辨率,仔细看字体边缘还是可以感觉到有点模糊。发布于 2022-05-26 21:11​赞同 37 ​​17 条评论

',40),d=[r];function t(n,s){return e(),p("div",null,d)}const c=a(h,[["render",t],["__file","分辨率.html.vue"]]);export{c as default}; diff --git "a/assets/\345\215\232\345\256\242\346\220\255\345\273\272.html-mnoPtCHz.js" "b/assets/\345\215\232\345\256\242\346\220\255\345\273\272.html-mnoPtCHz.js" new file mode 100644 index 0000000..874c860 --- /dev/null +++ "b/assets/\345\215\232\345\256\242\346\220\255\345\273\272.html-mnoPtCHz.js" @@ -0,0 +1 @@ +const l=JSON.parse('{"key":"v-e63c018a","path":"/notebook/%E5%8D%9A%E5%AE%A2%E6%90%AD%E5%BB%BA.html","title":"甲骨文服务器凉凉","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"20200911甲骨文复活辣","slug":"_20200911甲骨文复活辣","link":"#_20200911甲骨文复活辣","children":[]},{"level":2,"title":"2020/2/24","slug":"_2020-2-24","link":"#_2020-2-24","children":[]},{"level":2,"title":"20200215 甲骨文凉凉","slug":"_20200215-甲骨文凉凉","link":"#_20200215-甲骨文凉凉","children":[]},{"level":2,"title":"处理笔记的分类方式","slug":"处理笔记的分类方式","link":"#处理笔记的分类方式","children":[{"level":3,"title":"笔记的种类:","slug":"笔记的种类","link":"#笔记的种类","children":[]},{"level":3,"title":"可用的笔记,提醒,便签软件","slug":"可用的笔记-提醒-便签软件","link":"#可用的笔记-提醒-便签软件","children":[]},{"level":3,"title":"场景","slug":"场景","link":"#场景","children":[]}]},{"level":2,"title":"找到合适的写日记软件","slug":"找到合适的写日记软件","link":"#找到合适的写日记软件","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/博客搭建.md"}');export{l as data}; diff --git "a/assets/\345\215\232\345\256\242\346\220\255\345\273\272.html-z_tV2tys.js" "b/assets/\345\215\232\345\256\242\346\220\255\345\273\272.html-z_tV2tys.js" new file mode 100644 index 0000000..a6af2cb --- /dev/null +++ "b/assets/\345\215\232\345\256\242\346\220\255\345\273\272.html-z_tV2tys.js" @@ -0,0 +1 @@ +import{_ as r,a}from"./20200911144457950_30869-783m7FV3.js";import{_ as o,r as h,o as n,c as s,b as t,d as e,e as i,a as l}from"./app-x8p6wK6B.js";const c={},u=l('

甲骨文服务器凉凉

https://51.ruyo.net/14138.html 白嫖甲骨文vps 2019年9月17

20200911甲骨文复活辣

白嫖了两台, 一台使用tcp 链接, 一台使用websocket+tsl(需要域名解析) 链接, 测速如下

服务器传输协议下载上传延迟抖动丢包
132.145.112.212websocket+tsl11.53.2095ms12ms-
168.138.214.1tcp12.77.61331ms436ms

2020/2/24

',6),p={href:"https://drv.tw/",target:"_blank",rel:"noopener noreferrer"},_={href:"https://www.alexclassroom.com/web-building/webmaster-tool/how-to-build-site-on-onedrive-drivetoweb/",target:"_blank",rel:"noopener noreferrer"},b=l('
  • 本地使用VNote进行编辑,将笔记文件夹设置到 onedrive 目录下
  • 编辑后自动更新onedrive,免去手动同步的麻烦
  • 使用drive to web 配合域名cname指向,完成博客搭建

20200215 甲骨文凉凉

因此我需要一个新的服务器

需求:

  • 搭建博客
    • 同时要提供vnote - onedrive这种方式的 日记 - 博客 工作流
  • vpn
    • 平时使用谷歌服务
  • 内网穿透

因此, 可能需要国外服务器才能支持

博客搭建方案:

  1. github/gitee/coding pages
  2. 阿里云,其它云
  3. 虚拟主机
  4. 其它
  5. 阿里云(入口 nginx 转发)+ 腾讯云(应用+数据库)
  6. github pages + cloudflare
  7. 阿里云->vultr->github pages->netlify
  8. 利用 Gridea 同步到 GitHub,然后再同步到 Netlify http://fehey.com
  9. 本地 N1+frp
  10. cnblogs, csdn (不想)

大佬的博客:

  1. https://www.dute.org/

思考

处理笔记的分类方式

笔记的种类:

  • 灵感
  • 待办事项
  • 日记
  • 笔记
  • 特殊的( 印象笔记剪藏,马克)

可用的笔记,提醒,便签软件

品名平台云同步备注
OneNote全平台
印象笔记全平台,免费版最多两台设备
微软待办全平台
习惯android×
VNote桌面端×配合onedrive可以同步,以及搭建博客

场景

展示给别人看的博客 -- Vnote + viki + onedrive + drive to web 自己的日记 -- 印象笔记+ 日历

印象笔记记日记

找到合适的写日记软件

notion -- 颜值即是正义 notion

笔记型博客

',22),f={href:"http://dynalon.github.io/mdwiki/#!index.md",target:"_blank",rel:"noopener noreferrer"},m=t("ul",null,[t("li",null,"适合为开发的应用程序编写wiki"),t("li",null,"无法实现多层文件夹"),t("li",null,"具有github风格的markdown渲染器"),t("li",null,"可使用gimmicks, 以获得例如github-fork带子, 讨论区, 等插件")],-1),g={href:"https://github.com/tamlok/viki",target:"_blank",rel:"noopener noreferrer"},v=t("ul",null,[t("li",null,"配合vnote,以及onedrive云同步,适更合写笔记"),t("li",null,"有多层文件夹"),t("li",null,"渲染风格简陋,但是可以定制化(暂未找到方法)")],-1);function k(w,x){const d=h("ExternalLinkIcon");return n(),s("div",null,[u,t("p",null,[e("使用"),t("a",p,[e("drive to web"),i(d)])]),t("p",null,[t("a",_,[e("教程"),i(d)])]),b,t("p",null,[t("a",f,[e("MDwiki"),i(d)])]),m,t("p",null,[t("a",g,[e("vnote-viki"),i(d)])]),v])}const V=o(c,[["render",k],["__file","博客搭建.html.vue"]]);export{V as default}; diff --git "a/assets/\345\217\230\351\207\217\345\221\275\345\220\215\347\233\270\345\205\263.html-VlLPxf9A.js" "b/assets/\345\217\230\351\207\217\345\221\275\345\220\215\347\233\270\345\205\263.html-VlLPxf9A.js" new file mode 100644 index 0000000..b762b04 --- /dev/null +++ "b/assets/\345\217\230\351\207\217\345\221\275\345\220\215\347\233\270\345\205\263.html-VlLPxf9A.js" @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-42bda90c","path":"/notebook/%E5%8F%98%E9%87%8F%E5%91%BD%E5%90%8D%E7%9B%B8%E5%85%B3.html","title":"变量命名相关","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/变量命名相关.md"}');export{t as data}; diff --git "a/assets/\345\217\230\351\207\217\345\221\275\345\220\215\347\233\270\345\205\263.html-jVwTA9Zg.js" "b/assets/\345\217\230\351\207\217\345\221\275\345\220\215\347\233\270\345\205\263.html-jVwTA9Zg.js" new file mode 100644 index 0000000..abd48de --- /dev/null +++ "b/assets/\345\217\230\351\207\217\345\221\275\345\220\215\347\233\270\345\205\263.html-jVwTA9Zg.js" @@ -0,0 +1 @@ +import{_ as t,o as s,c as _,b as e,d as a}from"./app-x8p6wK6B.js";const c="/assets/486322292836512-Zfrvlyu0.png",o={},r=e("h1",{id:"变量命名相关",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#变量命名相关","aria-hidden":"true"},"#"),a(" 变量命名相关")],-1),n=e("p",null,[e("img",{src:c,alt:""})],-1),d=[r,n];function i(l,h){return s(),_("div",null,d)}const m=t(o,[["render",i],["__file","变量命名相关.html.vue"]]);export{m as default}; diff --git "a/assets/\345\233\276\345\275\242\346\212\227\351\224\257\351\275\277.html-QnGxD5ZW.js" "b/assets/\345\233\276\345\275\242\346\212\227\351\224\257\351\275\277.html-QnGxD5ZW.js" new file mode 100644 index 0000000..7ead1b5 --- /dev/null +++ "b/assets/\345\233\276\345\275\242\346\212\227\351\224\257\351\275\277.html-QnGxD5ZW.js" @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-68b2c946","path":"/notebook/%E5%9B%BE%E5%BD%A2%E6%8A%97%E9%94%AF%E9%BD%BF.html","title":"图形抗锯齿","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"","slug":"","link":"#","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/图形抗锯齿.md"}');export{t as data}; diff --git "a/assets/\345\233\276\345\275\242\346\212\227\351\224\257\351\275\277.html-swuZ5enR.js" "b/assets/\345\233\276\345\275\242\346\212\227\351\224\257\351\275\277.html-swuZ5enR.js" new file mode 100644 index 0000000..9269b93 --- /dev/null +++ "b/assets/\345\233\276\345\275\242\346\212\227\351\224\257\351\275\277.html-swuZ5enR.js" @@ -0,0 +1 @@ +import{_ as t,r as p,o as l,c as i,b as A,d as e,e as n,a as o}from"./app-x8p6wK6B.js";const r={},s=A("h1",{id:"图形抗锯齿",tabindex:"-1"},[A("a",{class:"header-anchor",href:"#图形抗锯齿","aria-hidden":"true"},"#"),e(" 图形抗锯齿")],-1),c={href:"https://tieba.baidu.com/p/5888162347",target:"_blank",rel:"noopener noreferrer"},_=o('

dlss是用来节约性能的,偷奸耍滑的抗锯齿都会有点副作用,txaa,fxaa照样糊,极限画质只认ssaa

游戏中常见的抗锯齿选项有以下几种:

1.关闭抗锯齿:是游戏中最常见的选项,关闭后游戏图像没有抗锯齿效果,会出现锯齿现象。对性能的需求较小,但视觉效果较差,100%的性能开销。

2.MSAA:Multi-Sample Anti-Aliasing(多重采样抗锯齿),MSAA支持各种MSAA级别,通常为x2、x4和x8等级别。 MSAA从3D场景中对每个像素进行多次采样以消除锯齿。 较高的MSAA级别会导致更好的视觉效果,但也会导致更多的性能开销,一般消耗10%~40%的性能开销。

3.FXAA:Fast Approximate Anti-Aliasing(快速近似抗锯齿),FXAA可在像素级别完成灰度反锯齿、多级反锯齿和对线条的效果。FXAA质量较好,性能开销小。在高分辨率下的效果更显著。一般消耗2%~10%的性能开销。

4.TXAA:Temporal Anti-Aliasing(时域抗锯齿),它使用我的时间成本将多个图像帧融合在一起,以提供更高质量的反锯齿以及抗锯齿的运动平滑性和更少的锯齿。对比MSAA和FXAA,TXAA的视觉效果和性能开销都更高,一般消耗20%~40%的性能开销。

5.SMAA:Subpixel Morphological Anti-Aliasing(亚像素形态抗锯齿),效果跟MSAA、FSAA非常接近,可以排除锯齿,同时减少不必要的混叠。 对于高性能的显卡来说没有太大的性能开销,但是在一些较低性能的显卡上则可能会出现效果不佳的情况。一般消耗2%~10%的性能开销。

总结:

性能消耗从低到高:FXAA < SMAA < MSAA < TXAA

效果质量从低到高:关闭抗锯齿 < FXAA < SMAA < MSAA < TXAA

游戏玩家通常可以根据自己的需要选择不同的抗锯齿选项,根据自己的电脑配置和游戏画面的需求选择不同的抗锯齿选项可以兼顾视觉效果与性能。

常见的抗锯齿选项包括:

  1. 无抗锯齿:游戏不使用任何抗锯齿技术,可以达到最高的帧率和最低的性能需求。

  2. FXAA(快速近似抗锯齿):这是一种快速且轻量级的抗锯齿技术,可以减少锯齿的数量,但可能会导致图像模糊或失真。该选项通常只需要额外的 1-2% 的 GPU 性能,适合运行时间敏感的游戏。

  3. MSAA(多重采样抗锯齿):这种抗锯齿技术通过对多个样本进行采样来减少锯齿的数量,它可以提供更好的图像质量,但需要更多的 GPU 性能。通常,MSAA 2x 可以消除大部分锯齿,但需要额外的 20-30% 的 GPU 性能;MSAA 4x 则可以消除更多的锯齿,但需要额外的 50% 或更多的 GPU 性能。

  4. SSAA(超采样抗锯齿):这是一种更高级的抗锯齿技术,可以通过在超过游戏分辨率的帧缓冲区中渲染图像来产生更高质量的图像。这种技术可以消除几乎所有的锯齿,但需要更高的 GPU 性能。由于需要更高的分辨率,因此 SSAA 的性能需求通常比 MSAA 更高,通常需要额外的 100-200% 的 GPU 性能。

总的来说,抗锯齿选项的性能需求和效果呈正相关。使用更高级的抗锯齿技术可以提供更好的图像质量,但需要更高的 GPU 性能。因此,在游戏设置中选择合适的抗锯齿选项可以平衡图像质量和性能之间的关系。

',15);function d(S,h){const a=p("ExternalLinkIcon");return l(),i("div",null,[s,A("p",null,[A("a",c,[e("5888162347"),n(a)])]),_])}const x=t(r,[["render",d],["__file","图形抗锯齿.html.vue"]]);export{x as default}; diff --git "a/assets/\345\237\272\344\272\216ddd\347\232\204\346\236\266\346\236\204.html-5cALh4sc.js" "b/assets/\345\237\272\344\272\216ddd\347\232\204\346\236\266\346\236\204.html-5cALh4sc.js" new file mode 100644 index 0000000..7c771e1 --- /dev/null +++ "b/assets/\345\237\272\344\272\216ddd\347\232\204\346\236\266\346\236\204.html-5cALh4sc.js" @@ -0,0 +1 @@ +const d=JSON.parse('{"key":"v-d0dc2cca","path":"/web/%E5%9F%BA%E4%BA%8Eddd%E7%9A%84%E6%9E%B6%E6%9E%84.html","title":"基于ddd的架构","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"web/基于ddd的架构.md"}');export{d as data}; diff --git "a/assets/\345\237\272\344\272\216ddd\347\232\204\346\236\266\346\236\204.html-lnxupp3Q.js" "b/assets/\345\237\272\344\272\216ddd\347\232\204\346\236\266\346\236\204.html-lnxupp3Q.js" new file mode 100644 index 0000000..ec2cc4a --- /dev/null +++ "b/assets/\345\237\272\344\272\216ddd\347\232\204\346\236\266\346\236\204.html-lnxupp3Q.js" @@ -0,0 +1 @@ +import{_ as d,o as t,c as s,b as e,d as _}from"./app-x8p6wK6B.js";const o="/assets/370660893836505-jwyokzhR.png",a={},c=e("h1",{id:"基于ddd的架构",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#基于ddd的架构","aria-hidden":"true"},"#"),_(" 基于ddd的架构")],-1),n=e("p",null,[e("img",{src:o,alt:""})],-1),r=[c,n];function i(l,h){return t(),s("div",null,r)}const m=d(a,[["render",i],["__file","基于ddd的架构.html.vue"]]);export{m as default}; diff --git "a/assets/\345\237\272\344\272\216yolov5\347\232\204cf\350\207\252\347\236\204.html-ftAqeGea.js" "b/assets/\345\237\272\344\272\216yolov5\347\232\204cf\350\207\252\347\236\204.html-ftAqeGea.js" new file mode 100644 index 0000000..b811490 --- /dev/null +++ "b/assets/\345\237\272\344\272\216yolov5\347\232\204cf\350\207\252\347\236\204.html-ftAqeGea.js" @@ -0,0 +1,9 @@ +import{_ as o,r as l,o as a,c as i,b as e,d as n,e as s,a as d}from"./app-x8p6wK6B.js";const r={},c=e("h1",{id:"基于yolov5的cf自瞄",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#基于yolov5的cf自瞄","aria-hidden":"true"},"#"),n(" 基于yolov5的cf自瞄")],-1),p=e("h2",{id:"环境配置",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#环境配置","aria-hidden":"true"},"#"),n(" 环境配置")],-1),v=e("p",null,[n("1.安装anconda,创建python3.8的环境 "),e("code",null,"conda create -n py38 python3.8")],-1),u={href:"https://pytorch.org/get-started/locally/",target:"_blank",rel:"noopener noreferrer"},h=d(`
conda activate py38
+conda install pytorch torchvision torchaudio pytorch-cuda=11.8 -c pytorch -c nvidia 
+
  1. 安装yolov5相关依赖 访问 https://github.com/ultralytics/yolov5/releases/tag/v7.0 获取yolov5最新源代码,并安装相关依赖 实测python3.11安装失败,确实scipy>=1.4的依赖,因此使用py3.8较好
git clone https://github.com/ultralytics/yolov5.git
+cd yolov5
+pip install -r requirements.txt coremltools onnx onnx-simplifier onnxruntime-gpu openvino-dev tensorflow
+
  1. 获取数据集,标注、训练,获得模型

  2. 捕获屏幕,可使用mss,或d3dshot截图(mss库,pyseral库)

pip install pyserial
+pip install mss
+pip install d3dshot
+
  1. 下载ghub dll
`,6);function m(_,y){const t=l("ExternalLinkIcon");return a(),i("div",null,[c,p,v,e("p",null,[n("2.切换到该环境,并下载pytroch>=1.7,使用conda会自动帮我们维护cuda(需要良好的网络) 这里我们使用pytorch2.0.1 "),e("a",u,[n("pytorch官方"),s(t)])]),h])}const b=o(r,[["render",m],["__file","基于yolov5的cf自瞄.html.vue"]]);export{b as default}; diff --git "a/assets/\345\237\272\344\272\216yolov5\347\232\204cf\350\207\252\347\236\204.html-uSvowgMd.js" "b/assets/\345\237\272\344\272\216yolov5\347\232\204cf\350\207\252\347\236\204.html-uSvowgMd.js" new file mode 100644 index 0000000..a45d400 --- /dev/null +++ "b/assets/\345\237\272\344\272\216yolov5\347\232\204cf\350\207\252\347\236\204.html-uSvowgMd.js" @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-3e81f7f2","path":"/python/cv/%E5%9F%BA%E4%BA%8Eyolov5%E7%9A%84cf%E8%87%AA%E7%9E%84.html","title":"基于yolov5的cf自瞄","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"环境配置","slug":"环境配置","link":"#环境配置","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"python/cv/基于yolov5的cf自瞄.md"}');export{t as data}; diff --git "a/assets/\345\257\206\347\240\201\347\256\241\347\220\206.html-n96BGOcg.js" "b/assets/\345\257\206\347\240\201\347\256\241\347\220\206.html-n96BGOcg.js" new file mode 100644 index 0000000..7fb2f7a --- /dev/null +++ "b/assets/\345\257\206\347\240\201\347\256\241\347\220\206.html-n96BGOcg.js" @@ -0,0 +1 @@ +import{_ as a,r as o,o as r,c as s,b as e,d as t,e as c}from"./app-x8p6wK6B.js";const _={},l=e("h1",{id:"密码管理",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#密码管理","aria-hidden":"true"},"#"),t(" 密码管理")],-1),d=e("p",null,"keepass",-1),i={href:"https://keepassxc.org/",target:"_blank",rel:"noopener noreferrer"};function h(p,f){const n=o("ExternalLinkIcon");return r(),s("div",null,[l,d,e("p",null,[t("mac客户端: "),e("a",i,[t("keepassxc"),c(n)]),t(" github start 16.6k")])])}const m=a(_,[["render",h],["__file","密码管理.html.vue"]]);export{m as default}; diff --git "a/assets/\345\257\206\347\240\201\347\256\241\347\220\206.html-zMIlL1m8.js" "b/assets/\345\257\206\347\240\201\347\256\241\347\220\206.html-zMIlL1m8.js" new file mode 100644 index 0000000..35431c8 --- /dev/null +++ "b/assets/\345\257\206\347\240\201\347\256\241\347\220\206.html-zMIlL1m8.js" @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-03b64b50","path":"/notebook/%E5%AF%86%E7%A0%81%E7%AE%A1%E7%90%86.html","title":"密码管理","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/密码管理.md"}');export{t as data}; diff --git "a/assets/\345\274\202\345\234\260\347\273\204\347\275\221.html-K2IP39Zi.js" "b/assets/\345\274\202\345\234\260\347\273\204\347\275\221.html-K2IP39Zi.js" new file mode 100644 index 0000000..cb0f404 --- /dev/null +++ "b/assets/\345\274\202\345\234\260\347\273\204\347\275\221.html-K2IP39Zi.js" @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-beb5c272","path":"/router/%E5%BC%82%E5%9C%B0%E7%BB%84%E7%BD%91.html","title":"异地组网","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"设备:k2p","slug":"设备-k2p","link":"#设备-k2p","children":[]},{"level":2,"title":"斐讯n1盒子","slug":"斐讯n1盒子","link":"#斐讯n1盒子","children":[]},{"level":2,"title":"wr1200js","slug":"wr1200js","link":"#wr1200js","children":[]},{"level":2,"title":"cloud server hk","slug":"cloud-server-hk","link":"#cloud-server-hk","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"router/异地组网.md"}');export{e as data}; diff --git "a/assets/\345\274\202\345\234\260\347\273\204\347\275\221.html-Tj0VW0Xz.js" "b/assets/\345\274\202\345\234\260\347\273\204\347\275\221.html-Tj0VW0Xz.js" new file mode 100644 index 0000000..cb2be19 --- /dev/null +++ "b/assets/\345\274\202\345\234\260\347\273\204\347\275\221.html-Tj0VW0Xz.js" @@ -0,0 +1,6 @@ +import{_ as a,o as e,c as s,a as r}from"./app-x8p6wK6B.js";const n={},i=r(`

异地组网

设备:k2p

配置:128g ram 千兆wifi、局域网 负责拨号,拥有公共ip

1.开机时执行的命令,用途为将2.xx这台设备转发到自己的36000端口

iptables -t nat -A PREROUTING -i pppoe-wan -p tcp --dport 36000 -j DNAT --to-destination 192.168.2.xx:22
+
  1. ddns

使用ardnspod实现,基于腾讯云的域名管理

使用方式:在脚本最后加入以下几行即可

arToken="token1,token2"
+arDdnsCheck domain.com www
+arDdnsCheck domain.com "*"
+arDdnsCheck domain.com @
+
  1. ss server 添加clash规则后,可直接通过clash访问内网资源,优点是不暴露端口在公网,无安全问题

斐讯n1盒子

配置: 安装ubuntu系统,arm芯片, 千兆网口,一个hdmi 两个usb2.0: 打印机 兄弟7060d 斐讯h1 1t硬盘

安装的软件: cups : 打印机管理 端口761 uwsgi: 托管python服务 supervistor: 负责管理后端启停 /etc/supervisor/conf.d/ docker: -mariadb 配置有主从同步服务

zerotier-one: 异地组网客户端 zabbix-agent: zabbix客户端,因为没有arm版本,当时还配置了好久 redis-server: 当时给爬虫服务使用的,后来就没用了 openresty: 学了手lua,不错 nginx: 可以转发一下 motion: 链接usb摄像头后,可以实时推流到web上jpeg-stream(无声音) fail2ban: 防ssh密码破解

wr1200js

配置:4核arm处理器,usb2.0口,千兆wifi、局域网 系统:openwrt

软件: zerotier客户端 wol 网络唤醒

可选:挂载硬盘

cloud server hk

安装 zerotier moon 服务器

`,20),t=[i];function d(o,p){return e(),s("div",null,t)}const c=a(n,[["render",d],["__file","异地组网.html.vue"]]);export{c as default}; diff --git "a/assets/\345\274\202\346\255\245\344\273\273\345\212\241\344\270\216\344\272\213\345\212\241_.html-Au8WpE6u.js" "b/assets/\345\274\202\346\255\245\344\273\273\345\212\241\344\270\216\344\272\213\345\212\241_.html-Au8WpE6u.js" new file mode 100644 index 0000000..33b1efd --- /dev/null +++ "b/assets/\345\274\202\346\255\245\344\273\273\345\212\241\344\270\216\344\272\213\345\212\241_.html-Au8WpE6u.js" @@ -0,0 +1 @@ +import{_ as t,o as e,c as d,a as r}from"./app-x8p6wK6B.js";const a={},_=r('

[异步任务与事务]

业务

用户可以开始任务

任务状态变成等待中,提交给celery,等待执行

这是,用户可以撤销任务

撤销任务:

任务状态变成ready

所以当还没被消费时,用户就撤销了,就很完美

但是已经开始消费了,用户再撤销,就会有bug

事务A start_task事务B revoke_task
判断Task state是否为cancel
修改Task state=cancel Save Task
update_network_check_item_state = SEARCH_CATALOG Save NetworkCheckItem
成功或失败 Save NetworkCheckItem
等待0.8秒
Save NetworkCheckItem
修改Task = RUNNING
Save Task
提交事务提交事务
',10),c=[_];function s(o,h){return e(),d("div",null,c)}const n=t(a,[["render",s],["__file","异步任务与事务_.html.vue"]]);export{n as default}; diff --git "a/assets/\345\274\202\346\255\245\344\273\273\345\212\241\344\270\216\344\272\213\345\212\241_.html-lnVlJxsu.js" "b/assets/\345\274\202\346\255\245\344\273\273\345\212\241\344\270\216\344\272\213\345\212\241_.html-lnVlJxsu.js" new file mode 100644 index 0000000..bcfcaa1 --- /dev/null +++ "b/assets/\345\274\202\346\255\245\344\273\273\345\212\241\344\270\216\344\272\213\345\212\241_.html-lnVlJxsu.js" @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-29eb5e8d","path":"/web/%E5%BC%82%E6%AD%A5%E4%BB%BB%E5%8A%A1%E4%B8%8E%E4%BA%8B%E5%8A%A1_.html","title":"[异步任务与事务]","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"web/[异步任务与事务].md"}');export{e as data}; diff --git "a/assets/\346\225\260\346\215\256\344\274\240\350\276\223.html-ZbCJKGuL.js" "b/assets/\346\225\260\346\215\256\344\274\240\350\276\223.html-ZbCJKGuL.js" new file mode 100644 index 0000000..6a95a0b --- /dev/null +++ "b/assets/\346\225\260\346\215\256\344\274\240\350\276\223.html-ZbCJKGuL.js" @@ -0,0 +1,7 @@ +import{_ as a,o as e,c as s,a as n}from"./app-x8p6wK6B.js";const r={},t=n(`

数据传输

mysql dump

mysqldump --tables myTable --where="id < 1000"
+
+
+mysqldump --databases X --tables Y --where="1 limit 1000000"
+
+--no-create-info
+
`,3),l=[t];function i(d,c){return e(),s("div",null,l)}const p=a(r,[["render",i],["__file","数据传输.html.vue"]]);export{p as default}; diff --git "a/assets/\346\225\260\346\215\256\344\274\240\350\276\223.html-b78wwm4X.js" "b/assets/\346\225\260\346\215\256\344\274\240\350\276\223.html-b78wwm4X.js" new file mode 100644 index 0000000..715ce0f --- /dev/null +++ "b/assets/\346\225\260\346\215\256\344\274\240\350\276\223.html-b78wwm4X.js" @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-07bbb0aa","path":"/notebook/%E6%95%B0%E6%8D%AE%E4%BC%A0%E8%BE%93.html","title":"数据传输","lang":"en-US","frontmatter":{},"headers":[{"level":3,"title":"mysql dump","slug":"mysql-dump","link":"#mysql-dump","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/数据传输.md"}');export{t as data}; diff --git "a/assets/\346\225\260\346\215\256\346\225\264\347\220\206.html-XAg1_BbR.js" "b/assets/\346\225\260\346\215\256\346\225\264\347\220\206.html-XAg1_BbR.js" new file mode 100644 index 0000000..0a75f9a --- /dev/null +++ "b/assets/\346\225\260\346\215\256\346\225\264\347\220\206.html-XAg1_BbR.js" @@ -0,0 +1 @@ +const l=JSON.parse('{"key":"v-6bb06026","path":"/notebook/%E6%95%B0%E6%8D%AE%E6%95%B4%E7%90%86.html","title":"数据整理","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"处理笔记的分类方式","slug":"处理笔记的分类方式","link":"#处理笔记的分类方式","children":[{"level":3,"title":"笔记的种类:","slug":"笔记的种类","link":"#笔记的种类","children":[]},{"level":3,"title":"可用的笔记,提醒,便签软件","slug":"可用的笔记-提醒-便签软件","link":"#可用的笔记-提醒-便签软件","children":[]},{"level":3,"title":"场景","slug":"场景","link":"#场景","children":[]},{"level":3,"title":"找到合适的写日记软件","slug":"找到合适的写日记软件","link":"#找到合适的写日记软件","children":[]}]},{"level":2,"title":"照片相片的备份, 归纳","slug":"照片相片的备份-归纳","link":"#照片相片的备份-归纳","children":[{"level":3,"title":"调研","slug":"调研","link":"#调研","children":[]},{"level":3,"title":"ondrive","slug":"ondrive","link":"#ondrive","children":[]},{"level":3,"title":"google photo","slug":"google-photo","link":"#google-photo","children":[]}]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/数据整理.md"}');export{l as data}; diff --git "a/assets/\346\225\260\346\215\256\346\225\264\347\220\206.html-nkuQTRl9.js" "b/assets/\346\225\260\346\215\256\346\225\264\347\220\206.html-nkuQTRl9.js" new file mode 100644 index 0000000..9805e88 --- /dev/null +++ "b/assets/\346\225\260\346\215\256\346\225\264\347\220\206.html-nkuQTRl9.js" @@ -0,0 +1 @@ +import{_ as t,a as d}from"./20200911144457950_30869-783m7FV3.js";import{_ as e,o as a,c as r,a as h}from"./app-x8p6wK6B.js";const i={},o=h('

数据整理

处理笔记的分类方式

笔记的种类:

  • 灵感
  • 待办事项
  • 日记
  • 笔记
  • 特殊的( 印象笔记剪藏,马克)

可用的笔记,提醒,便签软件

品名平台云同步备注
OneNote全平台编写代码感觉很差
印象笔记全平台,免费版最多两台设备用来写日记,适合个人喜欢
微软待办全平台
习惯android×可以用来打卡,带有提醒
VNote桌面端×配合onedrive可以同步,以及viki搭建博客
notion全平台√ (需要科学上网)
闪念胶囊

场景

展示给别人看的博客 -- Vnote + viki + onedrive + drive to web 自己的日记 -- 印象笔记+ 日历

印象笔记记日记

找到合适的写日记软件

notion -- 颜值即是正义 notion

照片相片的备份, 归纳

调研

途径价格功能备注
onedrive5g免费 ¥40/年 1t(可以存储其他文件)去年今日和windows 搭配
google photo15g免费 无限量的有损图片自动处理,分类,需要翻墙
nas机器费用+网络费用
百度云盘
微云

ondrive

家庭版本去闲鱼拼车大概可以做到 40一年 包含1t存储

google photo

平时在公司的时候使用,其他时候上网不稳定因此不多使用

',18),n=[o];function s(l,c){return a(),r("div",null,n)}const b=e(i,[["render",s],["__file","数据整理.html.vue"]]);export{b as default}; diff --git "a/assets/\346\226\207\344\273\266\346\217\217\350\277\260\347\254\246\344\270\216\347\274\223\345\206\262\345\214\272.html-Ih5dLzYg.js" "b/assets/\346\226\207\344\273\266\346\217\217\350\277\260\347\254\246\344\270\216\347\274\223\345\206\262\345\214\272.html-Ih5dLzYg.js" new file mode 100644 index 0000000..c62d114 --- /dev/null +++ "b/assets/\346\226\207\344\273\266\346\217\217\350\277\260\347\254\246\344\270\216\347\274\223\345\206\262\345\214\272.html-Ih5dLzYg.js" @@ -0,0 +1,32 @@ +import{_ as e,r as p,o as t,c as o,b as n,d as c,e as l,a as s}from"./app-x8p6wK6B.js";const i={},u=s('

文件描述符与缓冲区

文件描述符

在业务场景中,有时程序的log会把设备硬盘打满,这时就需要进行一个日志的删除,此时你会发现rm xx.log 并不能释放硬盘空间,重启程序后才可以释放

这是因为该程序已经申请了文件描述符,因此系统会保留文件,直到程序结束或停止占用。

不重启的方法是,echo '' > xx.log

java FileReader

',6),r={href:"https://www.v2ex.com/t/935599",target:"_blank",rel:"noopener noreferrer"},k=s(`
package io;
+
+import java.io.*;
+import java.util.concurrent.TimeUnit;
+
+public class InodeTest {
+    public static void main(String[] args) throws IOException, InterruptedException {
+        BufferedReader reader = new BufferedReader(new FileReader("/Downloads/2020.zip"), 2);
+        String line;
+        while ((line = reader.readLine()) != null) {
+            System.out.println(line);
+            TimeUnit.MILLISECONDS.sleep(10);
+        }
+    }
+}
+

博主说几百兆的文件,他认为并没有全部读取到内存中,但是删除文件,程序可以继续读取

这里也是,echo '' > /Downloads/2020.zip 即可

python demo

with open("demofile",'wb') as f:
+    for i in range(1000*1000):
+        f.write('asdasdasdasdasdasdasd\\n'.encode())
+import time
+
+f = open("demofile", 'r' ,encoding='utf8')
+
+index = 0
+for i in f:
+    index += 1
+    if index % 100 == 0:
+        print(index)
+        time.sleep(1)
+    # print(i)
+
+f.close()
+
`,5);function d(m,v){const a=p("ExternalLinkIcon");return t(),o("div",null,[u,n("blockquote",null,[n("p",null,[n("a",r,[c("935599"),l(a)])])]),k])}const h=e(i,[["render",d],["__file","文件描述符与缓冲区.html.vue"]]);export{h as default}; diff --git "a/assets/\346\226\207\344\273\266\346\217\217\350\277\260\347\254\246\344\270\216\347\274\223\345\206\262\345\214\272.html-ihVAix4D.js" "b/assets/\346\226\207\344\273\266\346\217\217\350\277\260\347\254\246\344\270\216\347\274\223\345\206\262\345\214\272.html-ihVAix4D.js" new file mode 100644 index 0000000..6eb219e --- /dev/null +++ "b/assets/\346\226\207\344\273\266\346\217\217\350\277\260\347\254\246\344\270\216\347\274\223\345\206\262\345\214\272.html-ihVAix4D.js" @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-579922c2","path":"/notebook/%E6%96%87%E4%BB%B6%E6%8F%8F%E8%BF%B0%E7%AC%A6%E4%B8%8E%E7%BC%93%E5%86%B2%E5%8C%BA.html","title":"文件描述符与缓冲区","lang":"en-US","frontmatter":{},"headers":[{"level":3,"title":"文件描述符","slug":"文件描述符","link":"#文件描述符","children":[]},{"level":3,"title":"java FileReader","slug":"java-filereader","link":"#java-filereader","children":[]},{"level":3,"title":"python demo","slug":"python-demo","link":"#python-demo","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/文件描述符与缓冲区.md"}');export{e as data}; diff --git "a/assets/\346\230\276\345\215\241.html-XE63hcjH.js" "b/assets/\346\230\276\345\215\241.html-XE63hcjH.js" new file mode 100644 index 0000000..7cd85e3 --- /dev/null +++ "b/assets/\346\230\276\345\215\241.html-XE63hcjH.js" @@ -0,0 +1 @@ +import{_ as t,o as s,c as p,a as e}from"./app-x8p6wK6B.js";const a="/assets/20221121134210181_20921-NCRj5vsy.png",o="/assets/20221121134247040_13313-01QZcw1E.png",n="/assets/20221121134803539_27462-FSYqWKCt.png",c="/assets/20221209180120985_22521-BGo8JcQo.png",i="/assets/20230117102418974_24620-A5goY1hE.png",r="/assets/194035815278790-0CpyiHN8.png",g={},_=e('

显卡

2023 5.19

970 4g 3700 980ti 5776 980 4337

1080 ti 8g 9875 1080 7542

2070s 10123 2070 8925 2080ti 11g 14655 2080s 11588 2080 10996

3060ti 8g 12200 4.88 3060 12g 8696 (notebook)3060 6g 8300
3070ti 8g 14826

3080ti 19568 3080 10g 17500 3090 24g 19799

4080 16g 28125 16g 8000 4070ti 12g 22753 12g 5800 3.92 4070 12g 17873 12g 4200 4.25 4060 8g 10200 2100

(*notebook)4080 12g 18890

6950xt 16g 21721 淘宝4400 6800xt 16g 19550 讯景6800XT海外版 3649 https://m.tb.cn/h.UF3ojs4 无个人送保 5.35 6750xt 12g 13588 瀚铠6750XT合金 2499元 5.43 6650xt 8g 10000 ️瀚铠6650XT合金 1789元 https://m.tb.cn/h.UE6t1Dh 5.58 6600xt 8g 9500 ④淘宝️⭐️瀚铠6600XT 1544 https://m.tb.cn/h.UFCpx8G 6.15

(*notebook)4060 10473 6000 (*notebook)4050 8300

game fps

因此,可以选4070+4k144,

4k144 = 2500 4070 = 4200

',20),h=[_];function m(d,l){return s(),p("div",null,h)}const x=t(g,[["render",m],["__file","显卡.html.vue"]]);export{x as default}; diff --git "a/assets/\346\230\276\345\215\241.html-uOqhkSyc.js" "b/assets/\346\230\276\345\215\241.html-uOqhkSyc.js" new file mode 100644 index 0000000..d7d6088 --- /dev/null +++ "b/assets/\346\230\276\345\215\241.html-uOqhkSyc.js" @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-0ad25c3f","path":"/notebook/%E6%98%BE%E5%8D%A1.html","title":"显卡","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"game fps","slug":"game-fps","link":"#game-fps","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/显卡.md"}');export{e as data}; diff --git "a/assets/\346\230\276\345\215\241\351\234\200\346\261\202\345\210\206\346\236\220.html-mEHcJKxM.js" "b/assets/\346\230\276\345\215\241\351\234\200\346\261\202\345\210\206\346\236\220.html-mEHcJKxM.js" new file mode 100644 index 0000000..6eabcd0 --- /dev/null +++ "b/assets/\346\230\276\345\215\241\351\234\200\346\261\202\345\210\206\346\236\220.html-mEHcJKxM.js" @@ -0,0 +1 @@ +import{_ as n,r as e,o as r,c as i,b as p,d as t,e as o,w as c,a as l}from"./app-x8p6wK6B.js";const h="/assets/194035815278790-0CpyiHN8.png",m="/assets/143302995899560-QLa9npRq.png",d="/assets/399381599836319-B5jf8FFP.png",_="/assets/21323416278796-xygIMZaK.png",k="/assets/19550911278872-YgjUDoc8.png",u="/assets/267571311278872-aiy3JK4f.png",g={},f=p("h1",{id:"显卡需求分析",tabindex:"-1"},[p("a",{class:"header-anchor",href:"#显卡需求分析","aria-hidden":"true"},"#"),t(" 显卡需求分析")],-1),b={href:"https://www.techpowerup.com/review/nvidia-geforce-rtx-4070-founders-edition/single-page.html#introduction",target:"_blank",rel:"noopener noreferrer"},x=l('

显卡fps表

4060ti 2k

4060ti 4k

上图中,是最高特效,所以,其实60帧数很优秀了

可以看到, 3060ti基本满足游戏4k60,但是2k144跑不满 可以考虑购买的,先买2k144,然后换4k144(因为4k144不成熟,价格不低,没必要一步到位) 或者直接买4k144,目前有2500的款式,感觉贵

方案1: 总价:3060ti 8g+2k 165(2500+1200 = 3700), 畅玩2k 90fps,可用3.5年 提升:换显卡换显示器(那不是全换了吗,傻逼) 方案2: 总价 4070 12g+4k 144(4200 + 2500 = 6700), 畅玩4k 73fps 可用6年 提升:加个2k显示器

2k又和1080p差不多,所以2k144

买2500的3060ti g6x,可以畅玩2k144 为了能用久一些,多加3000,购买4070,提升了

长度 30+ 35,都可

宽度: 6cm以内,50最好

gtx 970冰龙 长度:300mm,高度:111mm;厚度:约6cm 350 电竞判客 319 117 49 4200 turbo 329 133 64 4200 ultra w 337 150 60 4400

要解决几个问题

  1. 蚂蚁ant27vu这款,是不是有不满血hdmi2.1的问题

蚂蚁电竞 ANT27VU 2699元 【推荐度】:高。 【定位】:SDR游戏

【配置】:友达7.0 OC,400nit亮度,传统LED背光,双HDMI 2.1,USB Type-C 15W

【总评】:4K高刷中的性价比之王,LG 27GP95R的低价平替,知乎吴彦祖亲手调教的产物

【注意】:这个显示器已经从友达2.3升级到友达7.0,而且加量不加价!但是老款和新款名字是一样的,判断新老的方法很简单:4K 160Hz的就是友达7.0的新款,4K 144Hz的是友达2.3老款。

【优点】

1,友达7.0新面板带来更好的观感和响应速度(4.0ms),远超友达2.3,略胜群创E7B

2,接口丰富,做工良心,外观属于中配,比上面两个低配的要好很多。

3,背面RGB灯非常好看,正面还有投影灯(有点ROG的感觉,emmm,一定是借鉴!!!)

4,色域高,95% Adobe + 94% P3,同时适合摄影设计和大型单机游戏。

此外,就这个价位来说,它的均匀性还是不错的。得益于新面板它有着2.8ms的超快响应速度,逼近IPS面板的极限,所以也适合FPS游戏。

【缺点】

1,关机后显示器上的灯不会自动关闭,烦死人

2,HDMI 2.1接口在某些显卡上无法支持G-Sync,PC玩家用DP接口的话,可以无视这个缺点

  1. aoc u27g3x 这款,不带typec,有没有混发面板问题

AOC U27G3X 3199元 [推荐度]:高。(定位]: SDR游戏,护眼办公 [配置]: 友达7.0 0C,400nit亮度,传统LED背光,双HDMI 2.1 [总评] : 性价比很高的硬件低蓝光显示器,友达7.0新面板,值得无脑入手! [优点) 1,友达7.0新面板赋予了高响应速度,较好的观感,明显比友达2.3的一帮弟弟们要出色2,自带硬件抗蓝光,非常护眼,尤其适合文字工作者。虽然可能不是原厂模组,但是AOC也给 用上了支持硬件低蓝光的背光。 [缺点) 1,没有USB Type-C和USB-A扩展接口 2,调色方案比较激进,有些人可能觉得它的颜色太艳丽,也有些人恰好喜欢它的颜色 3,AOC这个系列的产品做工一般,远不如爱攻系列

  1. 泰坦p27a2v这款,面板是不是7.0

  2. hkc vg273upro 不带typec, 有没有问题 HKC VG273Upro 2699元 【推荐度】:中。 【定位】:SDR游戏

【配置】:友达7.0 OC,400nit亮度,传统LED背光,双HDMI 2.1,USB Type-C 15W

【总评】:这和蚂蚁ANT 27VU就是同一个东西,只是外壳不同,两个机器就是同一条生产线出来。HKC这台在外观做工上比蚂蚁ANT 27VU差,所以同价位下请买蚂蚁。

有时候VG273Upro会比ANT 27VU便宜100-200元,如果你不在乎外观,也可以买VG273Upro。

2k高刷&4k办公

Y27h-30。4USB-A+90W的Type-c 2k

飞利浦279P1 1999 90w 评论少 好评600 发布时间21年11月

vx2762-4k-mhdu 好评1000+,差评8,中评1 VX2880-4K-HDU-2 1499 hub hdr400 99%srgb tvu认证 65w 升降旋转 94% 2900+好评 VX2780-4K-HD-2 1650 hdr400 94% 1400好评 vx2731-4k 1299 99%srgb

aoc u27n3c 1799 唤醒慢 发布时间21年11月 5300好评 94% 每次从睡眠中唤醒,一线智联就不好用,typec线重新插拔一次

lg 27up600

27ul650 1750

雷电无信号:

ThinkPad的显示器识别问题和雷电接口故障解决 https://zhuanlan.zhihu.com/p/529323703

我的是关机拔掉充电器,长按电源键开机然后自动关机,再插上电源开机就好了 https://bbs.thinkpad.com/thread-7823411-1-1.html

为什么12代Intel笔记本雷电4或USB4外接显示器不支持Type-C DP独显直连? https://www.bilibili.com/read/cv16411870

notebook/图形抗锯齿.md

',47);function B(D,C){const s=e("ExternalLinkIcon"),a=e("RouterLink");return r(),i("div",null,[f,p("blockquote",null,[p("p",null,[t("4070 in techpower "),p("a",b,[t("single-page.html#introduction"),o(s)])])]),x,p("p",null,[o(a,{to:"/notebook/%E5%9B%BE%E5%BD%A2%E6%8A%97%E9%94%AF%E9%BD%BF.html"},{default:c(()=>[t("图形抗锯齿.md")]),_:1})])])}const w=n(g,[["render",B],["__file","显卡需求分析.html.vue"]]);export{w as default}; diff --git "a/assets/\346\230\276\345\215\241\351\234\200\346\261\202\345\210\206\346\236\220.html-s8yVhWzc.js" "b/assets/\346\230\276\345\215\241\351\234\200\346\261\202\345\210\206\346\236\220.html-s8yVhWzc.js" new file mode 100644 index 0000000..c48d950 --- /dev/null +++ "b/assets/\346\230\276\345\215\241\351\234\200\346\261\202\345\210\206\346\236\220.html-s8yVhWzc.js" @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-2305be92","path":"/notebook/%E6%98%BE%E5%8D%A1%E9%9C%80%E6%B1%82%E5%88%86%E6%9E%90.html","title":"显卡需求分析","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"显卡fps表","slug":"显卡fps表","link":"#显卡fps表","children":[]},{"level":2,"title":"2k高刷&4k办公","slug":"_2k高刷-4k办公","link":"#_2k高刷-4k办公","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/显卡需求分析.md"}');export{e as data}; diff --git "a/assets/\346\234\272\345\231\250\345\255\246\344\271\240-nsfw.html-LUhq-R2z.js" "b/assets/\346\234\272\345\231\250\345\255\246\344\271\240-nsfw.html-LUhq-R2z.js" new file mode 100644 index 0000000..46a936f --- /dev/null +++ "b/assets/\346\234\272\345\231\250\345\255\246\344\271\240-nsfw.html-LUhq-R2z.js" @@ -0,0 +1,10 @@ +import{_ as e,o as t,c as n,a as i}from"./app-x8p6wK6B.js";const o={},s=i(`

nsfw

调研

0. https://github.com/yahoo/open_nsfw

python2

训练好的模型 https://github.com/TechnikEmpire/NsfwSqueezenet

python3版本(不可用) -> https://github.com/rahiel/open_nsfw-

可远程调用版本 版本1 https://github.com/loretoparisi/docker/tree/master/nsfwaas

版本2 https://github.com/nikos-glikis/nsfw-docker

https://github.com/rockyzhengwu/nsfw

1. https://github.com/devzwy/open_nsfw_android

离线识别,基于TensorFlow实现。识别只需20ms,可断网测试,成功率99%,调用只要一行代码,从雅虎的开源项目open_nsfw移植,该模型文件可用于iOS、java、C++等平台

python 版本(识别率很低) https://github.com/devzwy/NSFW-Python

2. https://github.com/mdietrichstein/tensorflow-open_nsfw

仅支持jpeg

3. https://github.com/yangbisheng2009/nsfw-resnet

要自己训练

4. https://github.com/EugenCepoi/nsfw_api

一键docker 带api 可流式读取输出(非常快,目前使用)

docker run -it -p 127.0.0.1:5000:5000/tcp --env PORT=5000 eugencepoi/nsfw_api:latest
+
+
+curl -X GET -H 'Content-Type: application/json' http://localhost:5000\\?url\\=https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png
+
+{
+  "score": 0.00016061133646871895,
+  "url": "https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png"
+}
+
`,19),a=[s];function h(r,p){return t(),n("div",null,a)}const c=e(o,[["render",h],["__file","机器学习-nsfw.html.vue"]]);export{c as default}; diff --git "a/assets/\346\234\272\345\231\250\345\255\246\344\271\240-nsfw.html-WfHOs-eL.js" "b/assets/\346\234\272\345\231\250\345\255\246\344\271\240-nsfw.html-WfHOs-eL.js" new file mode 100644 index 0000000..7eb8725 --- /dev/null +++ "b/assets/\346\234\272\345\231\250\345\255\246\344\271\240-nsfw.html-WfHOs-eL.js" @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-4e710776","path":"/python/%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0-nsfw.html","title":"nsfw","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"0. https://github.com/yahoo/open_nsfw","slug":"_0-https-github-com-yahoo-open-nsfw","link":"#_0-https-github-com-yahoo-open-nsfw","children":[]},{"level":2,"title":"1. https://github.com/devzwy/open_nsfw_android","slug":"_1-https-github-com-devzwy-open-nsfw-android","link":"#_1-https-github-com-devzwy-open-nsfw-android","children":[]},{"level":2,"title":"2. https://github.com/mdietrichstein/tensorflow-open_nsfw","slug":"_2-https-github-com-mdietrichstein-tensorflow-open-nsfw","link":"#_2-https-github-com-mdietrichstein-tensorflow-open-nsfw","children":[]},{"level":2,"title":"3. https://github.com/yangbisheng2009/nsfw-resnet","slug":"_3-https-github-com-yangbisheng2009-nsfw-resnet","link":"#_3-https-github-com-yangbisheng2009-nsfw-resnet","children":[]},{"level":2,"title":"4. https://github.com/EugenCepoi/nsfw_api","slug":"_4-https-github-com-eugencepoi-nsfw-api","link":"#_4-https-github-com-eugencepoi-nsfw-api","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"python/机器学习-nsfw.md"}');export{t as data}; diff --git "a/assets/\347\210\254\350\231\253-pdd\350\260\203\347\240\224.html-iLBF0K6T.js" "b/assets/\347\210\254\350\231\253-pdd\350\260\203\347\240\224.html-iLBF0K6T.js" new file mode 100644 index 0000000..c5271a9 --- /dev/null +++ "b/assets/\347\210\254\350\231\253-pdd\350\260\203\347\240\224.html-iLBF0K6T.js" @@ -0,0 +1 @@ +const l=JSON.parse('{"key":"v-6e1b0644","path":"/python/%E7%88%AC%E8%99%AB-pdd%E8%B0%83%E7%A0%94.html","title":"pdd调研","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"h5端","slug":"h5端","link":"#h5端","children":[{"level":3,"title":"渠道一:首页","slug":"渠道一-首页","link":"#渠道一-首页","children":[]},{"level":3,"title":"渠道二:分类","slug":"渠道二-分类","link":"#渠道二-分类","children":[]},{"level":3,"title":"渠道三: 搜索","slug":"渠道三-搜索","link":"#渠道三-搜索","children":[]}]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"python/爬虫-pdd调研.md"}');export{l as data}; diff --git "a/assets/\347\210\254\350\231\253-pdd\350\260\203\347\240\224.html-ylPxeOwC.js" "b/assets/\347\210\254\350\231\253-pdd\350\260\203\347\240\224.html-ylPxeOwC.js" new file mode 100644 index 0000000..c005a02 --- /dev/null +++ "b/assets/\347\210\254\350\231\253-pdd\350\260\203\347\240\224.html-ylPxeOwC.js" @@ -0,0 +1 @@ +import{_ as s,o as t,c as a,a as p}from"./app-x8p6wK6B.js";const e="/assets/20201028153839771_805-cmkxF9kR.png",i="/assets/20201028154016449_11872-hdGUXOME.png",r="/assets/20201028111849591_17629-qHhsPnSN.png",_="/assets/20201028143720450_16306-kIRzpCo2.png",c="/assets/20201028143741429_31672-49mnKWTl.png",n="/assets/20201028112620077_29096-nP_fmyqj.png",o="/assets/20201028112637988_17637-ZPWbOD8Z.png",l="/assets/20201028112704364_31298-EEcfg45a.png",d="/assets/20201028112723365_22810-ZPTRYmvU.png",m="/assets/20201028112741659_23346-9v_O1g-B.png",h="/assets/20201028113043407_26300-eYJszmty.png",g="/assets/20201028143855586_15749-J-YRX282.png",f="/assets/20201028143917116_14446-Hif_DF24.png",u="/assets/20201028145335586_24818-wb6LNbXY.png",b="/assets/20201028145447224_19742-kmDrGdfN.png",k={},x=p('

pdd调研

需求: 全量爬取拼多多商品

拼多多有以下客户端:

  • h5端
  • app端

其中h5端有加密,无法破解

h5端

  1. 首页推荐下滑 不需要登录, 按推荐展示商品, 每个分类最多2000商品, 即使登录了也只有2000个
  2. 分类 需要登录, 理论上可获取选择的分类的所有商品
  3. 搜索 需要登录, 理论上可获取和搜索关键词有关的的所有商品

渠道一:首页

推荐: 下滑拉取400个后, 显示查看更多

这个推荐手动拉到600左右, 如果太快就会触发验证

登录后, 在首页进行下滑, 可拉取该分类的最多2000条商品(根据不同账号, 推荐可能不同)

经过尝试, 虽然有加密, 但是一个token可以多次发送请求(可模拟器拉取一次后重放), 但是最多有2000条数据

且频率太快会触发安全验证(使用模拟下滑,.8-20秒发一次请求, 近300次请求不会触发验证)

安全验证

demo1

渠道二:分类

参数如下

渠道三: 搜索

经测试这种方式获取商品无上限, 例如搜索手机 , page 设置为50000 仍可获取到数据(可能会给重复数据)

  • 需要关键词
',29),P=[x];function q(v,E){return t(),a("div",null,P)}const R=s(k,[["render",q],["__file","爬虫-pdd调研.html.vue"]]);export{R as default}; diff --git "a/assets/\347\210\254\350\231\253-\344\275\277\347\224\250\346\216\245\345\217\243\350\277\207tx\346\273\221\345\235\227\351\252\214\350\257\201.html-I3bwLb3R.js" "b/assets/\347\210\254\350\231\253-\344\275\277\347\224\250\346\216\245\345\217\243\350\277\207tx\346\273\221\345\235\227\351\252\214\350\257\201.html-I3bwLb3R.js" new file mode 100644 index 0000000..d23fe2d --- /dev/null +++ "b/assets/\347\210\254\350\231\253-\344\275\277\347\224\250\346\216\245\345\217\243\350\277\207tx\346\273\221\345\235\227\351\252\214\350\257\201.html-I3bwLb3R.js" @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-d4a5a1a8","path":"/python/%E7%88%AC%E8%99%AB-%E4%BD%BF%E7%94%A8%E6%8E%A5%E5%8F%A3%E8%BF%87tx%E6%BB%91%E5%9D%97%E9%AA%8C%E8%AF%81.html","title":"使用接口过tx滑块验证","lang":"en-US","frontmatter":{},"headers":[{"level":3,"title":"0x00 抓包分析","slug":"_0x00-抓包分析","link":"#_0x00-抓包分析","children":[]},{"level":3,"title":"0x01 获取ticket和randstr","slug":"_0x01-获取ticket和randstr","link":"#_0x01-获取ticket和randstr","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"python/爬虫-使用接口过tx滑块验证.md"}');export{t as data}; diff --git "a/assets/\347\210\254\350\231\253-\344\275\277\347\224\250\346\216\245\345\217\243\350\277\207tx\346\273\221\345\235\227\351\252\214\350\257\201.html-TeytDI-l.js" "b/assets/\347\210\254\350\231\253-\344\275\277\347\224\250\346\216\245\345\217\243\350\277\207tx\346\273\221\345\235\227\351\252\214\350\257\201.html-TeytDI-l.js" new file mode 100644 index 0000000..45ac5c3 --- /dev/null +++ "b/assets/\347\210\254\350\231\253-\344\275\277\347\224\250\346\216\245\345\217\243\350\277\207tx\346\273\221\345\235\227\351\252\214\350\257\201.html-TeytDI-l.js" @@ -0,0 +1,62 @@ +import{_ as n,o as s,c as a,a as t}from"./app-x8p6wK6B.js";const e="/assets/20200901183418861_6495-bTW84ikP.png",p="/assets/20200901183528812_6549-HohvyDgv.png",o="/assets/20200901193852676_25722-MuH2SkjC.png",i="/assets/20200901183708535_18118-C3ZqngYK.png",c="/assets/20200901183832304_18855-ATV1U73Z.png",l={},u=t('

使用接口过tx滑块验证

使用的接口 https://www.notion.so/T-X-HTTP-637bca0458704724a5692a0e283ff5aa

过验证码场景: 富途 https://passport.futunn.com/?target=https%3A%2F%2Fsetup2.futu5.com%2F&lang=zh-cn

0x00 抓包分析

首先我们手动操作一波, 发现三个和验证码有关的请求

  • 其中第一个是用来展示验证码的, 抓包可以得到aid

  • 第二个则是我们将滑块滑倒尾端后发出的验证请求, 如果成功则可以得到ticketrandstr

ticket和randstr

  • 接着是注册账号时发送短信验证码的请求, 可以看到里面有上个请求获取到的ticketrandstr字段

也就是说, 只要获取到ticket 等信息, 就可以发送短信验证码

0x01 获取ticket和randstr

以下代码是对api的进一步封装

用到的接口: https://www.notion.so/T-X-HTTP-637bca0458704724a5692a0e283ff5aa


+def get_ticket() -> dict:
+    import json
+    import time
+    import requests
+    """
+    返回可过验证码的ticket和randstr
+    :return:
+    {"ticket":"t039_9QCC5xXgpqgLzf2a3PsLAiF2mWGTo9NuFTGKnifb1Xp42wUqn5JUQ-XrAwsNLg4M3fvoZ-cQnCuXVKcDX5nOsPbozWMeQ_","randstr":"@qHZ"}
+    """
+    print("需要人机验证,获取中~")
+
+    aid = "2081701200" # 替换为你的aid
+    user = "******"
+    password = "******"
+
+    session = requests.session()
+
+    url = "http://gengduo.me/api/v1/alihd/wstask_tengx?aid={}&servertype=1&refer=&newtype=1&cap_cd=&asig=&user={}&pass={}".format(
+        aid,
+        user, password)
+
+    # 尝试三次, 获取任务ID
+    for i in range(3):
+        try:
+            res = session.get(url, timeout=7).json()
+            print(res)
+        except:
+            pass
+        else:  # 成功则停止
+            break
+    else:  # 均失败, 返回空
+        return {}
+
+    if "request_id" in res:
+
+        request_id = res["request_id"]
+
+        url = 'http://gengduo.me/api/v1/alihd/wstask_result?request_id={request_id}'.format(request_id=request_id)
+        print(url)
+        # 轮询60次
+        for i in range(60):
+            print(">>>", i)
+            try:
+                res = session.get(url, timeout=7).json()
+                print(res)
+            except:
+                continue
+
+            if "_status" in res and res["_status"] is True:
+                try:
+                    res_json = json.loads(res["_data"])
+                    ticket = res_json["data"]
+                    return ticket
+                except Exception as e:
+                    print(e)
+            elif "_data" in res and "error" in str(res["_data"]):
+                return {}
+            time.sleep(3)
+
+    return {}
+
`,14),r=[u];function d(k,v){return s(),a("div",null,r)}const b=n(l,[["render",d],["__file","爬虫-使用接口过tx滑块验证.html.vue"]]);export{b as default}; diff --git "a/assets/\347\210\254\350\231\253-\350\256\260\344\270\200\346\254\241\350\277\207\345\217\215\347\210\254\350\231\253\347\232\204\347\273\217\345\216\206.html-MTH-4UYK.js" "b/assets/\347\210\254\350\231\253-\350\256\260\344\270\200\346\254\241\350\277\207\345\217\215\347\210\254\350\231\253\347\232\204\347\273\217\345\216\206.html-MTH-4UYK.js" new file mode 100644 index 0000000..3d57855 --- /dev/null +++ "b/assets/\347\210\254\350\231\253-\350\256\260\344\270\200\346\254\241\350\277\207\345\217\215\347\210\254\350\231\253\347\232\204\347\273\217\345\216\206.html-MTH-4UYK.js" @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-323d42ea","path":"/python/%E7%88%AC%E8%99%AB-%E8%AE%B0%E4%B8%80%E6%AC%A1%E8%BF%87%E5%8F%8D%E7%88%AC%E8%99%AB%E7%9A%84%E7%BB%8F%E5%8E%86.html","title":"记一次过反爬虫的经历","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"python/爬虫-记一次过反爬虫的经历.md"}');export{t as data}; diff --git "a/assets/\347\210\254\350\231\253-\350\256\260\344\270\200\346\254\241\350\277\207\345\217\215\347\210\254\350\231\253\347\232\204\347\273\217\345\216\206.html-vh6R4q31.js" "b/assets/\347\210\254\350\231\253-\350\256\260\344\270\200\346\254\241\350\277\207\345\217\215\347\210\254\350\231\253\347\232\204\347\273\217\345\216\206.html-vh6R4q31.js" new file mode 100644 index 0000000..7cdfc3a --- /dev/null +++ "b/assets/\347\210\254\350\231\253-\350\256\260\344\270\200\346\254\241\350\277\207\345\217\215\347\210\254\350\231\253\347\232\204\347\273\217\345\216\206.html-vh6R4q31.js" @@ -0,0 +1 @@ +import{_ as e,o as t,c as l,b as _,d as o}from"./app-x8p6wK6B.js";const s={},n=_("h1",{id:"记一次过反爬虫的经历",tabindex:"-1"},[_("a",{class:"header-anchor",href:"#记一次过反爬虫的经历","aria-hidden":"true"},"#"),o(" 记一次过反爬虫的经历")],-1),i=_("p",null,"fakame.com",-1),c=_("p",null,"反爬表现特征: 1.云服务器第一次访问被拦截, 而本地调试时请求正常发送 2.被拦截时会返回一动态的js代码, 作用是重定向到当前网址 3.加上动态代理后, 即使访问该重定向网址, 下次请求也会被拦截 4.每天8点, 先使用代码访问, 被拦截, 此时使用浏览器访问一次, 然后再使用代码, 可正常工作",-1),a=_("p",null,"网站反爬模式 默认所有ip为黑ip, 当用户第一次访问时, 返回js代码重定向到原网页, 如果此次请求成功, 将该ip加白, 有效期约为1天",-1),d=_("p",null,"特征解读",-1),r=_("ol",null,[_("li",null,"调试时已使用浏览器访问过网站, 已经被加白"),_("li",null,"动态代理每次请求ip不同, 因此访问重定向网址的ip与原ip不同, 无法被加白, 即使被加白, 下次访问ip又发生变化, 无法抓取"),_("li",null,"使用本地浏览器访问, 即访问重定向网站, 给自己的ip加白, 此后使用本机ip即可正常访问")],-1),p=[n,i,c,a,d,r];function h(u,f){return t(),l("div",null,p)}const x=e(s,[["render",h],["__file","爬虫-记一次过反爬虫的经历.html.vue"]]);export{x as default}; diff --git "a/assets/\347\210\254\350\231\253-\350\277\207\347\256\200\345\215\225js\345\212\240\345\257\206.html-KN-jMbBx.js" "b/assets/\347\210\254\350\231\253-\350\277\207\347\256\200\345\215\225js\345\212\240\345\257\206.html-KN-jMbBx.js" new file mode 100644 index 0000000..3ce6776 --- /dev/null +++ "b/assets/\347\210\254\350\231\253-\350\277\207\347\256\200\345\215\225js\345\212\240\345\257\206.html-KN-jMbBx.js" @@ -0,0 +1,60 @@ +import{_ as n,o as s,c as a,a as t}from"./app-x8p6wK6B.js";const p="/assets/20200904175700699_9216-cL-SE0zR.png",o="/assets/20200907113712971_21558-UR7FKPl7.png",e={},c=t('

过简单js加密

背景: 爬虫需要过加密的, 其中使用了第三方库 pkg: https://www.cnblogs.com/mordom/p/8337337.html

0x00 chrome debug

在这里可以看到, 使用的是crypto-js

根据google 搜索到了这么一篇博文

https://www.codenong.com/js1a0dde3f1b57/

无奈本人对python 的Crypto模块 不太熟悉, 没能实现

只能编写js,并使用node 进行测试

使用前需安装node环境


+const r = require('crypto-js');
+
+const { program } = require('commander');
+//https://github.com/tj/commander.js
+
+let crypto = {
+    Encrypt: function (t) {
+        var e = r.enc.Utf8.parse("t171420100302rsa")
+            , n = r.enc.Utf8.parse("t171420100302rsa")
+            , o = r.enc.Utf8.parse(t)
+            , i = r.AES.encrypt(o, e, {
+            iv: n,
+            mode: r.mode.CBC,
+            padding: r.pad.Pkcs7
+        });
+        return r.enc.Base64.stringify(i.ciphertext)
+    },
+    decoto: function (t) {
+        var e = r.enc.Base64.parse(t)
+            , n = r.enc.Utf8.parse("t171420100302rsa")
+            , o = r.enc.Utf8.parse("t171420100302rsa")
+            , i = r.lib.CipherParams.create({
+            ciphertext: e
+        });
+        return r.AES.decrypt(i, n, {
+            iv: o,
+            mode: r.mode.CBC,
+            padding: r.pad.Pkcs7
+        }).toString(r.enc.Utf8)
+    }
+}
+
+let Encrypt=crypto.Encrypt;
+let Decoto = crypto.decoto;
+
+program
+    .version('0.0.1')
+    .option("-E, --Encrypt <str>","Encrypt str")
+    .option("-D, --Decoto <str>","decoto str")
+
+program.parse(process.argv);
+
+if (program.Encrypt){
+    console.log(Encrypt(program.Encrypt))
+}
+
+if (program.Decoto){
+    console.log(Decoto(program.Decoto))
+}
+
+

初始化npm 并安装js依赖

npm init
+npm i crypto-js
+npm i commander
+

然后使用命令行进行调用


+node main.js -D xxxxx
+
+

为了方便调用, 使用pkg 打包为linux 的可执行文件

pkg: https://www.cnblogs.com/mordom/p/8337337.html

pkg .
+
+

即可生成文件, 缺点是可执行文件比较大, 优点是开发成本比较低

使用:

-E 进行加密 -D 进行解密

',21),i=[c];function u(l,r){return s(),a("div",null,i)}const d=n(e,[["render",u],["__file","爬虫-过简单js加密.html.vue"]]);export{d as default}; diff --git "a/assets/\347\210\254\350\231\253-\350\277\207\347\256\200\345\215\225js\345\212\240\345\257\206.html-naBOMf9p.js" "b/assets/\347\210\254\350\231\253-\350\277\207\347\256\200\345\215\225js\345\212\240\345\257\206.html-naBOMf9p.js" new file mode 100644 index 0000000..bdeec67 --- /dev/null +++ "b/assets/\347\210\254\350\231\253-\350\277\207\347\256\200\345\215\225js\345\212\240\345\257\206.html-naBOMf9p.js" @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-75f9e5c3","path":"/python/%E7%88%AC%E8%99%AB-%E8%BF%87%E7%AE%80%E5%8D%95js%E5%8A%A0%E5%AF%86.html","title":"过简单js加密","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"0x00 chrome debug","slug":"_0x00-chrome-debug","link":"#_0x00-chrome-debug","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"python/爬虫-过简单js加密.md"}');export{e as data}; diff --git "a/assets/\347\233\221\346\216\247\346\237\220\344\270\252\346\234\215\345\212\241\346\255\243\345\270\270\350\277\220\350\241\214.html-L-VpgyeW.js" "b/assets/\347\233\221\346\216\247\346\237\220\344\270\252\346\234\215\345\212\241\346\255\243\345\270\270\350\277\220\350\241\214.html-L-VpgyeW.js" new file mode 100644 index 0000000..51c38d6 --- /dev/null +++ "b/assets/\347\233\221\346\216\247\346\237\220\344\270\252\346\234\215\345\212\241\346\255\243\345\270\270\350\277\220\350\241\214.html-L-VpgyeW.js" @@ -0,0 +1,26 @@ +import{_ as e,o as i,c as n,a as s}from"./app-x8p6wK6B.js";const r={},d=s(`

监控某个服务正常运行

#!/bin/sh
+check_time=120
+sserver_port=\`uci get sserver.config.port\`
+
+vcount=0
+while [ "1" = "1" ]  #死循环
+do
+  sleep $check_time
+
+   icount=\`ps -w|grep ssr-server |grep -v grep |wc -l\`
+
+   if [ $icount = 0  ] ;then
+   logger -t "ssr" "restart ssr server!"
+   /etc/init.d/sserver restart
+   exit 0
+   fi
+
+   icount=\`iptables -S|grep  $sserver_port|wc -l\`
+   if [ $icount = 0  ] ;then
+   logger -t "sserver" "recover iptables,restart ssr server!"
+   /etc/init.d/sserver restart
+   exit 0
+   fi
+
+done
+
`,2),l=[d];function t(v,c){return i(),n("div",null,l)}const u=e(r,[["render",t],["__file","监控某个服务正常运行.html.vue"]]);export{u as default}; diff --git "a/assets/\347\233\221\346\216\247\346\237\220\344\270\252\346\234\215\345\212\241\346\255\243\345\270\270\350\277\220\350\241\214.html-wDcK9f4R.js" "b/assets/\347\233\221\346\216\247\346\237\220\344\270\252\346\234\215\345\212\241\346\255\243\345\270\270\350\277\220\350\241\214.html-wDcK9f4R.js" new file mode 100644 index 0000000..ad22d43 --- /dev/null +++ "b/assets/\347\233\221\346\216\247\346\237\220\344\270\252\346\234\215\345\212\241\346\255\243\345\270\270\350\277\220\350\241\214.html-wDcK9f4R.js" @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-118904ce","path":"/router/%E7%9B%91%E6%8E%A7%E6%9F%90%E4%B8%AA%E6%9C%8D%E5%8A%A1%E6%AD%A3%E5%B8%B8%E8%BF%90%E8%A1%8C.html","title":"监控某个服务正常运行","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"router/监控某个服务正常运行.md"}');export{t as data}; diff --git "a/assets/\347\241\254\347\233\230\351\200\237\345\272\246\346\265\213\350\257\225.html-6gnct4wC.js" "b/assets/\347\241\254\347\233\230\351\200\237\345\272\246\346\265\213\350\257\225.html-6gnct4wC.js" new file mode 100644 index 0000000..fd03f83 --- /dev/null +++ "b/assets/\347\241\254\347\233\230\351\200\237\345\272\246\346\265\213\350\257\225.html-6gnct4wC.js" @@ -0,0 +1 @@ +const l=JSON.parse('{"key":"v-564889a0","path":"/ops/%E7%A1%AC%E7%9B%98%E9%80%9F%E5%BA%A6%E6%B5%8B%E8%AF%95.html","title":"硬盘速度测试","lang":"en-US","frontmatter":{},"headers":[{"level":3,"title":"linux 测试磁盘性能","slug":"linux-测试磁盘性能","link":"#linux-测试磁盘性能","children":[]},{"level":3,"title":"as ssd","slug":"as-ssd","link":"#as-ssd","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"ops/硬盘速度测试.md"}');export{l as data}; diff --git "a/assets/\347\241\254\347\233\230\351\200\237\345\272\246\346\265\213\350\257\225.html-Wn0S-23-.js" "b/assets/\347\241\254\347\233\230\351\200\237\345\272\246\346\265\213\350\257\225.html-Wn0S-23-.js" new file mode 100644 index 0000000..162d442 --- /dev/null +++ "b/assets/\347\241\254\347\233\230\351\200\237\345\272\246\346\265\213\350\257\225.html-Wn0S-23-.js" @@ -0,0 +1 @@ +import{_ as s,o as e,c as t,a}from"./app-x8p6wK6B.js";const r="/assets/20220906182537987_26393-RRpH7fSK.png",n="/assets/20220906182619519_25504-S5OXFblH.png",c="/assets/20220906183511031_14728-0w-7xDcr.png",i="/assets/20220906193542887_24307-KvnRTBLz.png",o="/assets/20220906193606268_13713-foGFoJlc.png",_="/assets/20220906201131109_32680-zvh61D5d.png",d="/assets/20220906201150745_32638-kwaoj9AS.png",p={},l=a('

硬盘速度测试

linux 测试磁盘性能

mkdir test-data fio --rw=write --ioengine=sync --fdatasync=1 --directory=test-data --size=2200m --bs=2300 --name=mytest

Ideally, your disk should reach over 500 IOPS and below 10ms for the 99th percentile fsync latency. Read the etcd Docs for more detailed requirements.

as ssd

660P 5GB

光威 1GB

660P 1GB

三星981 1GB

三星981 256G

C2000PRO 1T

C2000PRO 1T

',12),h=[l];function m(f,g){return e(),t("div",null,h)}const x=s(p,[["render",m],["__file","硬盘速度测试.html.vue"]]);export{x as default}; diff --git "a/assets/\347\256\200\346\230\223\347\233\221\346\216\247.html-C4Pk3813.js" "b/assets/\347\256\200\346\230\223\347\233\221\346\216\247.html-C4Pk3813.js" new file mode 100644 index 0000000..7b8721f --- /dev/null +++ "b/assets/\347\256\200\346\230\223\347\233\221\346\216\247.html-C4Pk3813.js" @@ -0,0 +1 @@ +import{_ as t,o as d,c as a,a as e}from"./app-x8p6wK6B.js";const r="/assets/262282302625813-_qHSbY-g.png",h="/assets/26585610279198-qDPAQFRs.png",p="/assets/161005792836721-bV5MJt_O.png",s="/assets/270663025951564-grm2JTEW.png",i={},n=e('

简易监控

23.9.20 开始写方案

方案1:POE录像机

tp 6104 120块钱 4口poe硬盘录像机 + 摄像头80*2 + 硬盘100~200 =280+100~280

可直播,可回放,不占用其他设备负载

方案2:单摄像头(纯娱乐)

海康摄像头dc(100) + n1(0)+1t(0) =100

串流直播,回放(存疑)

换新方案

pc+1tsata固态,拆下来500g用作POE录像机使用

pc+sata硬盘盒(利用海康威视1t)

鉴于目前我的1tssd也不够用,还是得早日提上日程 早用早享受

花费与寿命

4t机械=389 97.25 1t sata = 300 300 500g sata = 134 300 2t nvme = 500 250

综合以上,1tsata无任何意义,500gsata也无任何意义

本地pc花费老家pc花费监控方案年份总花费分析
1t+2t+4t5001t+pcie x4转接10poe录像机+poe摄像头✖️2+500g机械 130+80✖️24年510+x爽 ,4t可以退役给nas用
1t+1t+4t0500gsata159poe录像机+poe摄像机✖️2+500g机械 130+80✖️22年159+xsata老土,18年的ssd掉速

实践下,如果今天插上去测速还ok,则方案2 不ok,方案1

9.20 记录: c2000pro 速度还可以,而且里面有不少资料,还是留着较好

9.22记录

部署了开源nvr系统,购买了poe交换机+poe摄像头 n1部署nvr https://linuxpip.org/open-source-nvr/

最终方案

设备方案价格
NVR录像机斐讯n1+Shinobi$0(之前就有,150)开源录像系统,其实不是很专业,需要代替可以买80的录像机+好点的硬盘
硬盘斐讯h1 1t$0(之前就有,约250)
poe交换机tplink 百兆4口¥41
室内水星4312p$75
院子mipc428pw100
大门口mipc451100
双摄MIPC552W179

9.25

实际测试发现,2.8mm视角也比较小,并且半球没有云台,也不能动,因此4312p放一个差一点的位置,然后补充

mipc428pw 和

mipc451

即可完成构建

10.8

最终方案就是75+40+100的方案

',29),c=[n];function o(_,l){return d(),a("div",null,c)}const b=t(i,[["render",o],["__file","简易监控.html.vue"]]);export{b as default}; diff --git "a/assets/\347\256\200\346\230\223\347\233\221\346\216\247.html-QE5yoi6q.js" "b/assets/\347\256\200\346\230\223\347\233\221\346\216\247.html-QE5yoi6q.js" new file mode 100644 index 0000000..ef8d9db --- /dev/null +++ "b/assets/\347\256\200\346\230\223\347\233\221\346\216\247.html-QE5yoi6q.js" @@ -0,0 +1 @@ +const l=JSON.parse('{"key":"v-307698ed","path":"/router/%E7%AE%80%E6%98%93%E7%9B%91%E6%8E%A7.html","title":"简易监控","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"23.9.20 开始写方案","slug":"_23-9-20-开始写方案","link":"#_23-9-20-开始写方案","children":[{"level":3,"title":"方案1:POE录像机","slug":"方案1-poe录像机","link":"#方案1-poe录像机","children":[]},{"level":3,"title":"方案2:单摄像头(纯娱乐)","slug":"方案2-单摄像头-纯娱乐","link":"#方案2-单摄像头-纯娱乐","children":[]}]},{"level":2,"title":"9.22记录","slug":"_9-22记录","link":"#_9-22记录","children":[{"level":3,"title":"最终方案","slug":"最终方案","link":"#最终方案","children":[]}]},{"level":2,"title":"9.25","slug":"_9-25","link":"#_9-25","children":[]},{"level":2,"title":"10.8","slug":"_10-8","link":"#_10-8","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"router/简易监控.md"}');export{l as data}; diff --git "a/assets/\347\275\221\347\233\230\344\270\216\345\220\214\346\255\245.html-467twRhv.js" "b/assets/\347\275\221\347\233\230\344\270\216\345\220\214\346\255\245.html-467twRhv.js" new file mode 100644 index 0000000..525c87e --- /dev/null +++ "b/assets/\347\275\221\347\233\230\344\270\216\345\220\214\346\255\245.html-467twRhv.js" @@ -0,0 +1 @@ +import{_ as a,r as n,o as t,c as d,b as e,d as o,e as i,a as p}from"./app-x8p6wK6B.js";const s={},c=p('

网盘与同步

onedrive 个人版 5t 一年40人民币 而且网页版被墙

Seafile 自建网盘

alist 一个展示网盘内容的工具,支持多种云存储

腾讯云服务器自建 一个月30,总共30g

自己家的宽带: +自己的服务器 insync mac上的工具,要付费,可以吧数据同步到本地某个目录 cloudmaster:可以挂载云端硬盘,免费版可以挂载一个, 无法指定目录,固定在/Users/name/Library/CloudStorage/ 目录下

syncthing:p2p,不需自己建

cryptomator: 加密数据后再上传至云盘 https://cryptomator.org/downloads/mac/thanks/

目前的选择:OneDrive

windows

他人智慧

按照分类

国内选云存储确实操心,我也是废了很多时间在这个问题上,但并没有找到一致的解决方案。我个人认为,目前最优方案是分割需求,采取不同的工具:

  1. 根据内容采用不同的服务,照片就 google photo 或者 icloud。我的照片大多从手机上来,这两者是同步最方便(其他网盘甚至都不能及时保证同步),最省电的。而且万一梯子被墙,大不了就是这两天照片同步不了,不是什么大问题。

图书,pdf,文章我用 evernote。国内外能访问,月 10G,手机电脑客户端都很方便,还能打标签,记笔记,全文搜索。

工作文档坚果云,dropbox。同步速度快,技术可靠。onedrive 的客户端(除 win 外)实在是难用,而且我经常遇到同步失败,可能是本地运营商的问题,也可能是客户端的问题,但总之是没法拿来工作的。而 gdrive 我听同事抱怨过几人合作,文件损坏的情况。工作文档力求可靠,绝对不能出错,而且我这里通常文件不大,所以技术是第一位的。

备份 onedrive + arq 5,前者解决存储,后者解决备份技术,量大便宜。

  1. 国内国外访问分割开,这个没办法,就算自建也绕不开 wall。所以工作文档,我是国内用坚果云,国外用 dropbox。备份用 onedrive,如果人在国外 gdrive 可能更划算?

希望我的经验能帮到你,我也期待更好的解决方案。

',19),h={id:"知乎",tabindex:"-1"},l=e("a",{class:"header-anchor",href:"#知乎","aria-hidden":"true"},"#",-1),_={href:"https://zhuanlan.zhihu.com/p/57863415",target:"_blank",rel:"noopener noreferrer"},x=e("p",null,"如果有可靠的梯子,Dropbox绝对称得上佼佼者,我同时用Dropbox,Onedrive,老婆用坚果云同步1万多个科研数据,比较下来还是Dropbox最好用最省心,即使是通过梯子,同步速度也是很快的。目前我的方案是,工作数据通过Dropbox同步,家里群晖NAS通过Cloud Sync跟Dropbox和坚果云再双向同步备份一个,这样手机端就可以随时访问dropbox不用梯子了。然后电脑上其他文件在NAS上定期备份一下,再定期做一下冷备份,我觉得应该差不多了。Dropbox用的Basic免费版,通过各种活动扩容了不少,存工作文档基本够用,后期不行的话考虑开个plus就行。之前Google Drive用来存一些手机导出的照片,因为不占空间,有了NAS,基本也可以停用了。所以,如果要找个坚果云的替代品,公有云里面Dropbox是首选。",-1);function b(u,f){const r=n("ExternalLinkIcon");return t(),d("div",null,[c,e("h2",h,[l,o(),e("a",_,[o("知乎"),i(r)])]),x])}const v=a(s,[["render",b],["__file","网盘与同步.html.vue"]]);export{v as default}; diff --git "a/assets/\347\275\221\347\233\230\344\270\216\345\220\214\346\255\245.html-z5dwokBU.js" "b/assets/\347\275\221\347\233\230\344\270\216\345\220\214\346\255\245.html-z5dwokBU.js" new file mode 100644 index 0000000..93ea0d2 --- /dev/null +++ "b/assets/\347\275\221\347\233\230\344\270\216\345\220\214\346\255\245.html-z5dwokBU.js" @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-690fb1f4","path":"/ops/%E7%BD%91%E7%9B%98%E4%B8%8E%E5%90%8C%E6%AD%A5.html","title":"网盘与同步","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"目前的选择:OneDrive","slug":"目前的选择-onedrive","link":"#目前的选择-onedrive","children":[]},{"level":2,"title":"他人智慧","slug":"他人智慧","link":"#他人智慧","children":[]},{"level":2,"title":"按照分类","slug":"按照分类","link":"#按照分类","children":[]},{"level":2,"title":"知乎","slug":"知乎","link":"#知乎","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"ops/网盘与同步.md"}');export{e as data}; diff --git "a/assets/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234_iptables.html-0T1RzTzE.js" "b/assets/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234_iptables.html-0T1RzTzE.js" new file mode 100644 index 0000000..71c88a0 --- /dev/null +++ "b/assets/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234_iptables.html-0T1RzTzE.js" @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-e50f7ea8","path":"/web/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C_iptables.html","title":"[计算机网络]iptables","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"web/[计算机网络]iptables.md"}');export{e as data}; diff --git "a/assets/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234_iptables.html-oVpB3JjA.js" "b/assets/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234_iptables.html-oVpB3JjA.js" new file mode 100644 index 0000000..7a41ea7 --- /dev/null +++ "b/assets/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234_iptables.html-oVpB3JjA.js" @@ -0,0 +1 @@ +import{_ as t,o as s,c,b as e,d as o}from"./app-x8p6wK6B.js";const a={},_=e("h1",{id:"计算机网络-iptables",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#计算机网络-iptables","aria-hidden":"true"},"#"),o(" [计算机网络]iptables")],-1),i=e("p",null,"-A {INPUT|OUTPUT}:将防火墙规则附加到输入或输出链。 -p icmp:使用 ICMP 协议。 -p icmp --icmp-type {0|8}OR :icmp 按数字(如“0”)或名称(如“回显回复”)匹配选项。--icmp-type {echo-reply|echo-request} -j {ACCEPT|REJECT|DROP}:告诉 Linux 如果数据包匹配该怎么做。接受表示让数据包通过。丢弃或拒绝表示将数据包丢弃在地板上。当您希望另一端(客户端或主机或机器人)知道端口无法访问时,请使用 REJECT 并使用 DROP 连接到您不希望人员/机器人/客户端看到的主机。 -m state --state NEW,ESTABLISHED,RELATED:使用 or 选项进行扩展 icmp 数据包匹配。这些值是:--ctstate-m state INVALID:数据包与未知连接关联。 NEW:数据包已启动新连接或以其他方式与未在两个方向上看到数据包的连接相关联。 ESTABLISHED:数据包与在两个方向上看到数据包的连接相关联。 RELATED:数据包正在启动新连接,但与现有连接相关联,例如 FTP 数据传输或 ICMP 错误。",-1),l=e("blockquote",null,[e("p",null,"https://wooyun.js.org/drops/Iptables%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B.html")],-1),p=[_,i,l];function n(r,E){return s(),c("div",null,p)}const h=t(a,[["render",n],["__file","计算机网络_iptables.html.vue"]]);export{h as default}; diff --git "a/assets/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234_ip\345\215\217\350\256\256.html-Sv4FYo54.js" "b/assets/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234_ip\345\215\217\350\256\256.html-Sv4FYo54.js" new file mode 100644 index 0000000..3717429 --- /dev/null +++ "b/assets/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234_ip\345\215\217\350\256\256.html-Sv4FYo54.js" @@ -0,0 +1 @@ +import{_,o as t,c as s,b as e,d as l}from"./app-x8p6wK6B.js";const n="/assets/20220226143036597_1542929079-MxXugexT.png",o={},i=e("h1",{id:"计算机网络-ip协议",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#计算机网络-ip协议","aria-hidden":"true"},"#"),l(" [计算机网络]ip协议")],-1),c=e("p",null,"ip协议非常简单,没有丢失重传等额外功能,这是因为作为底层协议,要尽可能简单高效,而且可以让应用层自己选择想要的传输协议(例如在线视频就不需要重发之前的包,因为他们已经过期)",-1),a=e("p",null,"特性",-1),r=e("ul",null,[e("li",null,"以逐跳的方式发送数据报"),e("li",null,"不可靠,但尽力而为"),e("li",null,"无连接")],-1),d=e("p",null,[e("img",{src:n,alt:""})],-1),p=[i,c,a,r,d];function u(h,f){return t(),s("div",null,p)}const x=_(o,[["render",u],["__file","计算机网络_ip协议.html.vue"]]);export{x as default}; diff --git "a/assets/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234_ip\345\215\217\350\256\256.html-cIjAa45A.js" "b/assets/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234_ip\345\215\217\350\256\256.html-cIjAa45A.js" new file mode 100644 index 0000000..f7d7942 --- /dev/null +++ "b/assets/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234_ip\345\215\217\350\256\256.html-cIjAa45A.js" @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-75d78820","path":"/web/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C_ip%E5%8D%8F%E8%AE%AE.html","title":"[计算机网络]ip协议","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"web/[计算机网络]ip协议.md"}');export{t as data}; diff --git "a/assets/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234_\350\267\257\347\224\261\345\231\250.html--hNUIKTf.js" "b/assets/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234_\350\267\257\347\224\261\345\231\250.html--hNUIKTf.js" new file mode 100644 index 0000000..e15e34f --- /dev/null +++ "b/assets/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234_\350\267\257\347\224\261\345\231\250.html--hNUIKTf.js" @@ -0,0 +1 @@ +import{_,o as t,c as s,b as e,d as a}from"./app-x8p6wK6B.js";const c="/assets/20221213105953021_4596-gbj6KSr4.png",o={},r=e("h1",{id:"计算机网络-路由器",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#计算机网络-路由器","aria-hidden":"true"},"#"),a(" [计算机网络]路由器")],-1),n=e("p",null,[e("img",{src:c,alt:""})],-1),d=[r,n];function i(l,h){return t(),s("div",null,d)}const m=_(o,[["render",i],["__file","计算机网络_路由器.html.vue"]]);export{m as default}; diff --git "a/assets/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234_\350\267\257\347\224\261\345\231\250.html-2wDxlDEC.js" "b/assets/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234_\350\267\257\347\224\261\345\231\250.html-2wDxlDEC.js" new file mode 100644 index 0000000..ab13d78 --- /dev/null +++ "b/assets/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234_\350\267\257\347\224\261\345\231\250.html-2wDxlDEC.js" @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-8353569e","path":"/web/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C_%E8%B7%AF%E7%94%B1%E5%99%A8.html","title":"[计算机网络]路由器","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"web/[计算机网络]路由器.md"}');export{e as data}; diff --git "a/assets/\350\256\260\344\270\200\346\254\241\347\240\264\350\247\243\345\244\251\347\277\274\347\275\221\345\205\263.html-2ZogijjF.js" "b/assets/\350\256\260\344\270\200\346\254\241\347\240\264\350\247\243\345\244\251\347\277\274\347\275\221\345\205\263.html-2ZogijjF.js" new file mode 100644 index 0000000..99ad2db --- /dev/null +++ "b/assets/\350\256\260\344\270\200\346\254\241\347\240\264\350\247\243\345\244\251\347\277\274\347\275\221\345\205\263.html-2ZogijjF.js" @@ -0,0 +1,23 @@ +import{_ as n,o as s,c as a,a as t}from"./app-x8p6wK6B.js";const p="/assets/20221222170415632_6307-cQMYUYI0.png",e="/assets/20221222171347277_19524-9pq0v9TU.png",o="/assets/20221222170648272_2876-kQFMy3_2.png",c="/assets/20221222170242535_17309-awGBiN82.png",i="/assets/20221222170248974_17861-n-cpp9fj.png",l={},u=t('

记一次破解天翼网关

https://xz.aliyun.com/t/9046#toc-1

  1. 设备信息 设备信息

2.首先获取超级密码 访问http://192.168.1.1:8080/cgi-bin/baseinfoSet.cgi

凯撒密码,编写python脚本来解密

  1. 使用超级账号密码登录

访问http://192.168.1.1:8080/cgi-bin/telnet.cgi通过InputCmd参数可以直接执行系统命令, 访问http://192.168.1.1:8080/cgi-bin/submit.cgi可以看到执行结果,

编写简单的脚本, 方便看回显

from urllib import parse
+import requests
+
+host = "http://192.168.1.1:8080"
+send_url = host+"/cgi-bin/telnet.cgi"
+response_url = host+"/cgi-bin/submit.cgi"
+
+def f(cmd):
+	HEADERS = {'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'}
+	data = {"InputCmd":cmd}
+
+	r = requests.post(send_url, data=parse.urlencode(data)).text
+	print("[-] send done:")
+	print(r)
+
+	rep = requests.get(response_url).text
+	print('[-] resp:')
+	print(rep)
+if __name__ == '__main__':
+	while True:
+	    c = input("")
+	    f(c)
+
  1. 打开telnet

访问 192.168.1.1:8080/cgi-bin/telnetenable.cgi?telnetenable=1 即可

  1. 寻找telnet密码

尝试写入/etc/passwd, 但是不起作用,想着看看有没有明文密码

cat /flash/cfg/agentconf/factory.conf 没有 在/var 目录下找到一个密码文件,确定了

cat /var/telWan_passwd

',18),r=[u];function d(k,m){return s(),a("div",null,r)}const v=n(l,[["render",d],["__file","记一次破解天翼网关.html.vue"]]);export{v as default}; diff --git "a/assets/\350\256\260\344\270\200\346\254\241\347\240\264\350\247\243\345\244\251\347\277\274\347\275\221\345\205\263.html-yPGyP_KQ.js" "b/assets/\350\256\260\344\270\200\346\254\241\347\240\264\350\247\243\345\244\251\347\277\274\347\275\221\345\205\263.html-yPGyP_KQ.js" new file mode 100644 index 0000000..c423acd --- /dev/null +++ "b/assets/\350\256\260\344\270\200\346\254\241\347\240\264\350\247\243\345\244\251\347\277\274\347\275\221\345\205\263.html-yPGyP_KQ.js" @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-cd2572f4","path":"/router/%E8%AE%B0%E4%B8%80%E6%AC%A1%E7%A0%B4%E8%A7%A3%E5%A4%A9%E7%BF%BC%E7%BD%91%E5%85%B3.html","title":"记一次破解天翼网关","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"router/记一次破解天翼网关.md"}');export{t as data}; diff --git "a/assets/\350\264\255\344\271\260\345\217\202\350\200\203.html-hrg296u9.js" "b/assets/\350\264\255\344\271\260\345\217\202\350\200\203.html-hrg296u9.js" new file mode 100644 index 0000000..052d39a --- /dev/null +++ "b/assets/\350\264\255\344\271\260\345\217\202\350\200\203.html-hrg296u9.js" @@ -0,0 +1 @@ +import{_ as e,o as t,c as a,a as s}from"./app-x8p6wK6B.js";const c="/assets/20220913113645278_23384-f-keS_J0.png",o={},r=s('

购买参考

电池

https://post.smzdm.com/p/595316/

',4),_=[r];function n(d,h){return t(),a("div",null,_)}const l=e(o,[["render",n],["__file","购买参考.html.vue"]]);export{l as default}; diff --git "a/assets/\350\264\255\344\271\260\345\217\202\350\200\203.html-j4bizFuP.js" "b/assets/\350\264\255\344\271\260\345\217\202\350\200\203.html-j4bizFuP.js" new file mode 100644 index 0000000..6923e73 --- /dev/null +++ "b/assets/\350\264\255\344\271\260\345\217\202\350\200\203.html-j4bizFuP.js" @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-168cd3a7","path":"/ops/%E8%B4%AD%E4%B9%B0%E5%8F%82%E8%80%83.html","title":"购买参考","lang":"en-US","frontmatter":{},"headers":[{"level":3,"title":"电池","slug":"电池","link":"#电池","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"ops/购买参考.md"}');export{t as data}; diff --git "a/assets/\350\264\255\344\271\260\350\256\260\345\275\225.html-QfUG13El.js" "b/assets/\350\264\255\344\271\260\350\256\260\345\275\225.html-QfUG13El.js" new file mode 100644 index 0000000..f24dc96 --- /dev/null +++ "b/assets/\350\264\255\344\271\260\350\256\260\345\275\225.html-QfUG13El.js" @@ -0,0 +1 @@ +import{_ as e,r as o,o as s,c as _,b as t,d as l,e as d,a as u}from"./app-x8p6wK6B.js";const r="/assets/43397323951244-njmpsXEy.png",h={},i=t("h1",{id:"电子产品购买记录",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#电子产品购买记录","aria-hidden":"true"},"#"),l(" 电子产品购买记录")],-1),c=t("h2",{id:"大物件",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#大物件","aria-hidden":"true"},"#"),l(" 大物件")],-1),a=t("thead",null,[t("tr",null,[t("th",null,"时间"),t("th",null,"名称"),t("th",null,"链接"),t("th",null,"价格"),t("th",null,"备注")])],-1),m=t("td",null,"2022-7-12",-1),p=t("td",null,"明基",-1),f={href:"https://item.jd.com/100018492680.html",target:"_blank",rel:"noopener noreferrer"},b=t("td",null,"689",-1),k=t("td",null,"优惠价格,平时1000",-1),g=t("td",null,"2022-7-7",-1),j=t("td",null,"机械革命无界16",-1),x={href:"https://item.jd.com/100018385485.html",target:"_blank",rel:"noopener noreferrer"},z=t("td",null,"5149",-1),O=t("td",null,null,-1),w=t("td",null,"2022-2-21",-1),y=t("td",null,"宁芝82 蓝牙双模键盘",-1),E={href:"https://item.taobao.com/item.htm?spm=a1z09.2.0.0.74df2e8douxpER&id=669494951483&_u=32lhkof58479",target:"_blank",rel:"noopener noreferrer"},F=t("td",null,"495",-1),M=t("td",null,null,-1),R=t("td",null,"2021-4-25",-1),N=t("td",null,"qc35 二代",-1),v={href:"https://item.taobao.com/item.htm?spm=a1z09.2.0.0.74df2e8douxpER&id=636947020503&_u=32lhkof5ac78",target:"_blank",rel:"noopener noreferrer"},D=t("td",null,"941",-1),P=t("td",null,null,-1),V=t("td",null,"2020-12-10",-1),X=t("td",null,"松下EH-WNA8B",-1),B={href:"https://item.jd.com/4973774.html",target:"_blank",rel:"noopener noreferrer"},I=t("td",null,"349.20",-1),J=t("td",null,"现在639,好价格",-1),L=t("td",null,"2020-09-09",-1),G=t("td",null,"致巡黑",-1),K={href:"https://item.jd.com/100003311437.html",target:"_blank",rel:"noopener noreferrer"},T=t("td",null,"369",-1),q=t("td",null,null,-1),A=t("td",null,"2020-09-09",-1),S=t("td",null,"京东京造Q9吸尘器",-1),U={href:"https://item.jd.com/100002983704.html",target:"_blank",rel:"noopener noreferrer"},C=t("td",null,"759",-1),H=t("td",null,null,-1),Q=t("td",null,"2020-8-5",-1),W=t("td",null,"ipad air 3 + airpods",-1),Y={href:"https://item.taobao.com/item.htm?spm=a1z09.2.0.0.1e3e2e8d2MiFcO&id=622504595245&_u=32lhkof5923a",target:"_blank",rel:"noopener noreferrer"},Z=t("td",null,"3700",-1),$=t("td",null,null,-1),tt=t("td",null,"2020-5-26",-1),lt=t("td",null,"咪咕kindle",-1),nt={href:"https://item.jd.com/4426891.html",target:"_blank",rel:"noopener noreferrer"},dt=t("td",null,"468",-1),et=t("td",null,"白嫖失败",-1),ot=t("td",null,"2018-11-11",-1),st=t("td",null,"小米Pro 15.6英寸",-1),_t={href:"https://item.jd.com/5456134.html",target:"_blank",rel:"noopener noreferrer"},ut=t("td",null,"5499",-1),rt=t("td",null,"80京豆",-1),ht=t("td",null,"2018-10-20",-1),it=t("td",null,"松下台灯致言",-1),ct={href:"https://item.jd.com/7975035.html",target:"_blank",rel:"noopener noreferrer"},at=t("td",null,"284",-1),mt=t("td",null,null,-1),pt=t("td",null,"2018-9-11",-1),ft=t("td",null,"米动手表",-1),bt={href:"https://item.jd.com/6668183.html",target:"_blank",rel:"noopener noreferrer"},kt=t("td",null,"242",-1),gt=t("td",null,"凑单66的阿迪背包",-1),jt=t("tr",null,[t("td",null,"和"),t("td"),t("td"),t("td",null,"20155.2"),t("td")],-1),xt=t("h2",{id:"手机",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#手机","aria-hidden":"true"},"#"),l(" 手机")],-1),zt=t("thead",null,[t("tr",null,[t("th",null,"时间"),t("th",null,"名称"),t("th",null,"链接"),t("th",null,"价格"),t("th",null,"备注")])],-1),Ot=t("td",null,"2021-06-10",-1),wt=t("td",null,"OPPO Reno5 Pro+ 12+256 星河入梦",-1),yt={href:"https://item.jd.com/100017267996.html",target:"_blank",rel:"noopener noreferrer"},Et=t("td",null,"3299",-1),Ft=t("td",null,"用了70京豆",-1),Mt=t("td",null,"2020-6-21",-1),Rt=t("td",null,"二手坚果pro3",-1),Nt={href:"https://item.taobao.com/item.htm?spm=a1z09.2.0.0.1e3e2e8d2MiFcO&id=620482436619&_u=32lhkof59f91",target:"_blank",rel:"noopener noreferrer"},vt=t("td",null,"1800",-1),Dt=t("td",null,null,-1),Pt=t("td",null,"2018-11-01",-1),Vt=t("td",null,"锤子r1",-1),Xt={href:"https://item.jd.com/7341428.html",target:"_blank",rel:"noopener noreferrer"},Bt=t("td",null,"2149",-1),It=t("td",null,null,-1),Jt=t("td",null,"2018-1-19",-1),Lt=t("td",null,"lg g5",-1),Gt={href:"https://item.taobao.com/item.htm?spm=a1z09.2.0.0.1e3e2e8d2MiFcO&id=564426067469&_u=32lhkof521ec",target:"_blank",rel:"noopener noreferrer"},Kt=t("td",null,"371",-1),Tt=t("td",null,null,-1),qt=t("h2",{id:"小物件-price-200",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#小物件-price-200","aria-hidden":"true"},"#"),l(" 小物件 price<200")],-1),At=t("thead",null,[t("tr",null,[t("th",null,"时间"),t("th",null,"名称"),t("th",null,"链接"),t("th",null,"价格"),t("th",null,"备注")])],-1),St=t("td",null,"2019-05-18",-1),Ut=t("td",null,"床上桌",-1),Ct={href:"https://item.taobao.com/item.htm?spm=a1z09.2.0.0.1e3e2e8d2MiFcO&id=520039935490&_u=32lhkof5d163",target:"_blank",rel:"noopener noreferrer"},Ht=t("td",null,"73",-1),Qt=t("td",null,null,-1),Wt=t("td",null,"2022-8-3",-1),Yt=t("td",null,"rk r87 k黄轴",-1),Zt={href:"https://item.taobao.com/item.htm?spm=a1z09.2.0.0.1e3e2e8dqXY7ID&id=674948426625&_u=32lhkof53a87",target:"_blank",rel:"noopener noreferrer"},$t=t("td",null,"119",-1),tl=t("td",null,null,-1),ll=t("td",null,"2022-7-14",-1),nl=t("td",null,"小米空调伴侣",-1),dl={href:"https://item.jd.com/100002892977.html",target:"_blank",rel:"noopener noreferrer"},el=t("td",null,"76",-1),ol=t("td",null,null,-1),sl=t("td",null,"2022-6-14",-1),_l=t("td",null,"赛睿鼠标垫",-1),ul={href:"https://item.jd.com/100020677845.html",target:"_blank",rel:"noopener noreferrer"},rl=t("td",null,"59.00",-1),hl=t("td",null,null,-1),il=t("td",null,"2022-6-14",-1),cl=t("td",null,"g102白色",-1),al={href:"https://item.jd.com/100012720890.html",target:"_blank",rel:"noopener noreferrer"},ml=t("td",null,"99.00",-1),pl=t("td",null,null,-1),fl=t("td",null,"2022-7-27",-1),bl=t("td",null,"牙刷刷头*3",-1),kl={href:"https://item.jd.com/100026929949.html",target:"_blank",rel:"noopener noreferrer"},gl=t("td",null,"119",-1),jl=t("td",null,"用了68块钱京豆",-1),xl=t("td",null,"2022-2-23",-1),zl=t("td",null,"山寨屏幕挂灯",-1),Ol={href:"https://item.taobao.com/item.htm?spm=a1z09.2.0.0.74df2e8douxpER&id=621882049344&_u=32lhkof512fa",target:"_blank",rel:"noopener noreferrer"},wl=t("td",null,"125",-1),yl=t("td",null,null,-1),El=t("td",null,"2022-2-18",-1),Fl=t("td",null,"雷蛇八岐大蛇v2无线鼠标",-1),Ml={href:"https://item.jd.com/100020911378.html",target:"_blank",rel:"noopener noreferrer"},Rl=t("td",null,"228",-1),Nl=t("td",null,null,-1),vl=t("td",null,"2021-9-19",-1),Dl=t("td",null,"g102黑色换新",-1),Pl={href:"https://item.jd.com/100012720924.html",target:"_blank",rel:"noopener noreferrer"},Vl=t("td",null,"0",-1),Xl=t("td",null,"换新",-1),Bl=t("td",null,"2021-8-20",-1),Il=t("td",null,"米家智能插座",-1),Jl={href:"https://item.jd.com/10031978659734.html",target:"_blank",rel:"noopener noreferrer"},Ll=t("td",null,"28",-1),Gl=t("td",null,"红包-10",-1),Kl=t("td",null,"2021-08-20",-1),Tl=t("td",null,"卡王AX200PRO",-1),ql={href:"https://item.jd.com/100010702444.html",target:"_blank",rel:"noopener noreferrer"},Al=t("td",null,"129",-1),Sl=t("td",null,"用了83块礼品卡",-1),Ul=t("td",null,"2020-12-25",-1),Cl=t("td",null,"飞利浦电动牙刷头",-1),Hl={href:"https://item.jd.com/41510929895.html",target:"_blank",rel:"noopener noreferrer"},Ql=t("td",null,"101",-1),Wl=t("td",null,null,-1),Yl=t("td",null,"2020-10-14",-1),Zl=t("td",null,"路由器ups",-1),$l={href:"https://item.taobao.com/item.htm?spm=a1z09.2.0.0.1e3e2e8d2MiFcO&id=531878958487&_u=32lhkof50c80",target:"_blank",rel:"noopener noreferrer"},tn=t("td",null,"130",-1),ln=t("td",null,null,-1),nn=t("td",null,"2020-5-15",-1),dn=t("td",null,"g304+樱桃G80鼠标垫",-1),en={href:"https://item.jd.com/372416.html",target:"_blank",rel:"noopener noreferrer"},on=t("td",null,"213",-1),sn=t("td",null,null,-1),_n=t("td",null,"2020-4-20",-1),un=t("td",null,"锤子无线耳机",-1),rn={href:"https://item.jd.com/100010955652.html",target:"_blank",rel:"noopener noreferrer"},hn=t("td",null,"179",-1),cn=t("td",null,"10块京豆",-1),an=t("td",null,"2020-3-30",-1),mn=t("td",null,"飞利浦6511牙刷",-1),pn={href:"https://item.jd.com/361132.html",target:"_blank",rel:"noopener noreferrer"},fn=t("td",null,"189",-1),bn=t("td",null,"20京豆",-1),kn=t("td",null,"2018-11-12",-1),gn=t("td",null,"雷柏(Rapoo) V805",-1),jn={href:"https://item.jd.com/4619025.html",target:"_blank",rel:"noopener noreferrer"},xn=t("td",null,"174",-1),zn=t("td",null,null,-1),On=t("td",null,"2018-11-01",-1),wn=t("td",null,"g102黑色",-1),yn={href:"https://item.jd.com/4155894.html",target:"_blank",rel:"noopener noreferrer"},En=t("td",null,"99",-1),Fn=t("td",null,null,-1),Mn=t("td",null,"2019-12-10",-1),Rn=t("td",null,"usb-c扩展坞",-1),Nn={href:"https://item.taobao.com/item.htm?spm=a1z09.2.0.0.1e3e2e8d2MiFcO&id=606621738283&_u=32lhkof537f1",target:"_blank",rel:"noopener noreferrer"},vn=t("td",null,"98",-1),Dn=t("td",null,null,-1),Pn=t("td",null,"2019-10-16",-1),Vn=t("td",null,"坚果r1无线充电",-1),Xn={href:"https://item.taobao.com/item.htm?spm=a1z09.2.0.0.1e3e2e8d2MiFcO&id=570829887496&_u=32lhkof5e205",target:"_blank",rel:"noopener noreferrer"},Bn=t("td",null,"115",-1),In=t("td",null,null,-1),Jn=t("tr",null,[t("td",null,"和"),t("td"),t("td"),t("td",null,"1693"),t("td",null,"161")],-1),Ln=t("h2",{id:"家里",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#家里","aria-hidden":"true"},"#"),l(" 家里")],-1),Gn=t("thead",null,[t("tr",null,[t("th",null,"时间"),t("th",null,"名称"),t("th",null,"链接"),t("th",null,"价格"),t("th",null,"备注")])],-1),Kn=t("tr",null,[t("td",null,"2019-10-1"),t("td",null,"tcl 65寸电视 2+32"),t("td",null,"--"),t("td",null,"2999"),t("td")],-1),Tn=t("td",null,"2019-10-9",-1),qn=t("td",null,"米兔3c手表",-1),An={href:"https://item.taobao.com/item.htm?spm=a1z09.2.0.0.1e3e2e8d2MiFcO&id=602018590540&_u=32lhkof57f82",target:"_blank",rel:"noopener noreferrer"},Sn=t("td",null,"418",-1),Un=t("td",null,null,-1),Cn=t("td",null,"2021-9-24",-1),Hn=t("td",null,"创维27寸2K显示器",-1),Qn={href:"https://item.jd.com/100012151749.html",target:"_blank",rel:"noopener noreferrer"},Wn=t("td",null,"899",-1),Yn=t("td",null,null,-1),Zn=t("td",null,"2020-9-23",-1),$n=t("td",null,"10只斑马jj15",-1),td={href:"https://item.jd.com/4345581.html",target:"_blank",rel:"noopener noreferrer"},ld=t("td",null,"119",-1),nd=t("td",null,null,-1),dd=t("td",null,"2021-7-27",-1),ed=t("td",null,"7060d打印机",-1),od={href:"https://item.taobao.com/item.htm?spm=a1z09.2.0.0.74df2e8douxpER&id=651496330302&_u=32lhkof529cc",target:"_blank",rel:"noopener noreferrer"},sd=t("td",null,"530",-1),_d=t("td",null,null,-1),ud=t("tr",null,[t("td",null,"2022-6-29"),t("td",null,"打印机晒鼓-2600页"),t("td",null,"xx"),t("td",null,"34.00"),t("td")],-1),rd=t("tr",null,[t("td",null,"总价"),t("td"),t("td"),t("td",null,"4999"),t("td")],-1),hd=t("h2",{id:"电脑装机-2022-11",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#电脑装机-2022-11","aria-hidden":"true"},"#"),l(" 电脑装机 2022.11")],-1),id=t("thead",null,[t("tr",null,[t("th",null,"名称"),t("th",null,"价格"),t("th",null,"时间"),t("th",null,"连接"),t("th",null,"备注")])],-1),cd=t("tr",null,[t("td",null,"i5-12600kf"),t("td",null,"1600"),t("td",null,"2022-11-11"),t("td",null,"jd"),t("td",null,"板u套装")],-1),ad=t("tr",null,[t("td",null,"华硕 tuf b660m-plus d4"),t("td",null,"900"),t("td",null,"2022-11-11"),t("td",null,"jd"),t("td",null,"板u套装")],-1),md=t("td",null,"光威天策3200 32g",-1),pd=t("td",null,"375",-1),fd=t("td",null,"2022-11-11",-1),bd={href:"https://item.jd.com/100025295848.html",target:"_blank",rel:"noopener noreferrer"},kd=t("td",null,null,-1),gd=t("td",null,"光威天策3200 32g",-1),jd=t("td",null,"250",-1),xd=t("td",null,"2023-6-15",-1),zd={href:"https://item.jd.com/100025295848.html",target:"_blank",rel:"noopener noreferrer"},Od=t("td",null,"半年降价100",-1),wd=t("tr",null,[t("td",null,"利民pa120"),t("td",null,"150"),t("td",null,"2022-11-20"),t("td",null,"pdd"),t("td")],-1),yd=t("td",null,"金百达 1t固态pcie4.0",-1),Ed=t("td",null,"375",-1),Fd=t("td",null,"2022-11-23",-1),Md={href:"https://item.jd.com/100043568171.html",target:"_blank",rel:"noopener noreferrer"},Rd=t("td",null,null,-1),Nd=t("td",null,"鑫谷电源750w",-1),vd=t("td",null,"320",-1),Dd=t("td",null,"2022-11-22",-1),Pd={href:"https://item.jd.com/100015105542.html",target:"_blank",rel:"noopener noreferrer"},Vd=t("td",null,null,-1),Xd=t("tr",null,[t("td",null,"wifi网卡"),t("td",null,"100"),t("td",null,"2023-5-1"),t("td",null,"jd"),t("td")],-1),Bd=t("tr",null,[t("td",null,"七彩虹 RTX4070 ultra w v2"),t("td",null,"4300"),t("td",null,"2023-5-31"),t("td",null,"jd"),t("td")],-1),Id=t("tr",null,[t("td",null,"垃圾机箱"),t("td",null,"30"),t("td",null,"2022-12-3"),t("td",null,"闲鱼"),t("td")],-1),Jd=t("tr",null,[t("td",null,"总价(不带显示器)"),t("td",null,"8400"),t("td"),t("td"),t("td")],-1),Ld=t("tr",null,[t("td",null,"4k144hz KOIOS K2723UL青春版"),t("td",null,"1779"),t("td",null,"2023-5-31"),t("td",null,"jd第三方店"),t("td",null,"友达7.0 商品评价100左右")],-1),Gd=t("tr",null,[t("td",null,"nta N2823UG 4k152hz"),t("td",null,"1529"),t("td",null,"2023-5-31"),t("td",null,"jd第三方店"),t("td",null,"e7b面板,商品评价15左右,满血hdmi2.1, 可惜有竖线,已经退货")],-1),Kd=t("tr",null,[t("td",null,[t("strong",null,"全套总价(带显卡显示器)")]),t("td",null,"10200"),t("td"),t("td"),t("td")],-1),Td=t("tr",null,[t("td",null,"xbox手柄"),t("td",null,"429"),t("td",null,"2023-1-29"),t("td",null,"jd"),t("td")],-1),qd=t("tr",null,[t("td",null,"海康威视西数紫盘"),t("td",null,"320"),t("td",null,"2022-10-17"),t("td",null,"pdd"),t("td",null,"数据盘")],-1),Ad=t("tr",null,[t("td",null,"映众超级冰龙GTX970"),t("td",null,"350"),t("td",null,"2022-11-22"),t("td",null,"闲鱼"),t("td",null,"过渡")],-1),Sd=u('

主机

装机经验:

  1. 不要上太大的风冷,丑,不方便安装
  2. 主板要带wifi
  3. 不介意大小,最好买大的主板,而不是类似b660m这种m板
  4. 注意显卡厚度,ultra厚度为60mm,会占用三个pcie槽
  5. 购买ddr4内存的话,即使有大内存需求,也尽量买双通道,单通道影响cpu、显卡发挥,双通道前后,cpu从58w提升68w,显卡60w到64w,内存8.5w到17w, 提升较大
  6. 机箱上方部位多一些,方便走线

眼镜

时间名称链接价格备注
2023-5-1依视路钻晶x4(免费升级到膜致)404

猫粮

',6),Ud=t("thead",null,[t("tr",null,[t("th",null,"时间"),t("th",null,"名称"),t("th",null,"链接"),t("th",null,"价格"),t("th",null,"备注")])],-1),Cd=t("tr",null,[t("td",null,"2023-3-23"),t("td",null,"jd京造10kg"),t("td"),t("td",null,"249"),t("td")],-1),Hd=t("tr",null,[t("td",null,"2023-1-1"),t("td",null,"希宝猫条 60个"),t("td"),t("td",null,"58+15猫超卡"),t("td")],-1),Qd=t("td",null,"2022-11-05",-1),Wd={href:"https://item.jd.com/100006576027.html",target:"_blank",rel:"noopener noreferrer"},Yd=t("td",null,null,-1),Zd=t("td",null,"190",-1),$d=t("td",null,null,-1),te=t("tr",null,[t("td",null,"2022-6-30"),t("td",null,"京东京造三文鱼1.8kg"),t("td"),t("td",null,"60"),t("td")],-1),le=t("tr",null,[t("td",null,"2022-6-30"),t("td",null,"京东京造双拼1.8kgx2"),t("td"),t("td",null,"45x2"),t("td")],-1),ne=t("tr",null,[t("td",null,"2022-1-25"),t("td",null,"4x2.5kg猫砂"),t("td"),t("td",null,"52"),t("td")],-1),de=t("tr",null,[t("td",null,"2022-1-15"),t("td",null,"网易严选猫粮7.2kg"),t("td"),t("td",null,"205"),t("td")],-1),ee=t("tr",null,[t("td",null,"2021-12-04"),t("td",null,"牛油果 2kg x 2"),t("td",null,"xx"),t("td",null,"20"),t("td",null,"10喜豆")],-1),oe=t("tr",null,[t("td",null,"2021-11-12"),t("td",null,"冠能3.5kg"),t("td"),t("td",null,"67"),t("td")],-1),se=t("tr",null,[t("td",null,"2021-11-10"),t("td",null,"京萌2kg"),t("td"),t("td",null,"17"),t("td")],-1),_e=t("tr",null,[t("td",null,"2021-10-13"),t("td",null,"京萌2kg"),t("td"),t("td",null,"47"),t("td")],-1),ue=t("tr",null,[t("td",null,"2021-9-13"),t("td",null,"皇家0.8kg"),t("td"),t("td",null,"45"),t("td")],-1),re=t("tr",null,[t("td",null,"2021-9-9"),t("td",null,"猫砂6L*3"),t("td",null,"50"),t("td",null,"50"),t("td")],-1),he=t("tr",null,[t("td",null,"和"),t("td"),t("td"),t("td",null,"975"),t("td")],-1);function ie(ce,ae){const n=o("ExternalLinkIcon");return s(),_("div",null,[i,c,t("table",null,[a,t("tbody",null,[t("tr",null,[m,p,t("td",null,[t("a",f,[l("京东"),d(n)])]),b,k]),t("tr",null,[g,j,t("td",null,[t("a",x,[l("京东"),d(n)])]),z,O]),t("tr",null,[w,y,t("td",null,[t("a",E,[l("闲鱼"),d(n)])]),F,M]),t("tr",null,[R,N,t("td",null,[t("a",v,[l("tb"),d(n)])]),D,P]),t("tr",null,[V,X,t("td",null,[t("a",B,[l("jd"),d(n)])]),I,J]),t("tr",null,[L,G,t("td",null,[t("a",K,[l("jd"),d(n)])]),T,q]),t("tr",null,[A,S,t("td",null,[t("a",U,[l("jd"),d(n)])]),C,H]),t("tr",null,[Q,W,t("td",null,[t("a",Y,[l("tb"),d(n)])]),Z,$]),t("tr",null,[tt,lt,t("td",null,[t("a",nt,[l("jd"),d(n)])]),dt,et]),t("tr",null,[ot,st,t("td",null,[t("a",_t,[l("jd"),d(n)])]),ut,rt]),t("tr",null,[ht,it,t("td",null,[t("a",ct,[l("jd"),d(n)])]),at,mt]),t("tr",null,[pt,ft,t("td",null,[t("a",bt,[l("jd"),d(n)])]),kt,gt]),jt])]),xt,t("table",null,[zt,t("tbody",null,[t("tr",null,[Ot,wt,t("td",null,[t("a",yt,[l("jd"),d(n)])]),Et,Ft]),t("tr",null,[Mt,Rt,t("td",null,[t("a",Nt,[l("闲鱼"),d(n)])]),vt,Dt]),t("tr",null,[Pt,Vt,t("td",null,[t("a",Xt,[l("jd"),d(n)])]),Bt,It]),t("tr",null,[Jt,Lt,t("td",null,[t("a",Gt,[l("tb"),d(n)])]),Kt,Tt])])]),qt,t("table",null,[At,t("tbody",null,[t("tr",null,[St,Ut,t("td",null,[t("a",Ct,[l("tb"),d(n)])]),Ht,Qt]),t("tr",null,[Wt,Yt,t("td",null,[t("a",Zt,[l("tb"),d(n)])]),$t,tl]),t("tr",null,[ll,nl,t("td",null,[t("a",dl,[l("京东"),d(n)])]),el,ol]),t("tr",null,[sl,_l,t("td",null,[t("a",ul,[l("京东"),d(n)])]),rl,hl]),t("tr",null,[il,cl,t("td",null,[t("a",al,[l("jd"),d(n)])]),ml,pl]),t("tr",null,[fl,bl,t("td",null,[t("a",kl,[l("jd"),d(n)])]),gl,jl]),t("tr",null,[xl,zl,t("td",null,[t("a",Ol,[l("闲鱼"),d(n)])]),wl,yl]),t("tr",null,[El,Fl,t("td",null,[t("a",Ml,[l("jd"),d(n)])]),Rl,Nl]),t("tr",null,[vl,Dl,t("td",null,[t("a",Pl,[l("jd"),d(n)])]),Vl,Xl]),t("tr",null,[Bl,Il,t("td",null,[t("a",Jl,[l("jd"),d(n)])]),Ll,Gl]),t("tr",null,[Kl,Tl,t("td",null,[t("a",ql,[l("JD"),d(n)])]),Al,Sl]),t("tr",null,[Ul,Cl,t("td",null,[t("a",Hl,[l("jd"),d(n)])]),Ql,Wl]),t("tr",null,[Yl,Zl,t("td",null,[t("a",$l,[l("tb"),d(n)])]),tn,ln]),t("tr",null,[nn,dn,t("td",null,[t("a",en,[l("jd"),d(n)])]),on,sn]),t("tr",null,[_n,un,t("td",null,[t("a",rn,[l("jd"),d(n)])]),hn,cn]),t("tr",null,[an,mn,t("td",null,[t("a",pn,[l("jd"),d(n)])]),fn,bn]),t("tr",null,[kn,gn,t("td",null,[t("a",jn,[l("jd"),d(n)])]),xn,zn]),t("tr",null,[On,wn,t("td",null,[t("a",yn,[l("jd"),d(n)])]),En,Fn]),t("tr",null,[Mn,Rn,t("td",null,[t("a",Nn,[l("tb"),d(n)])]),vn,Dn]),t("tr",null,[Pn,Vn,t("td",null,[t("a",Xn,[l("tb"),d(n)])]),Bn,In]),Jn])]),Ln,t("table",null,[Gn,t("tbody",null,[Kn,t("tr",null,[Tn,qn,t("td",null,[t("a",An,[l("tb"),d(n)])]),Sn,Un]),t("tr",null,[Cn,Hn,t("td",null,[t("a",Qn,[l("jd"),d(n)])]),Wn,Yn]),t("tr",null,[Zn,$n,t("td",null,[t("a",td,[l("jd"),d(n)])]),ld,nd]),t("tr",null,[dd,ed,t("td",null,[t("a",od,[l("闲鱼"),d(n)])]),sd,_d]),ud,rd])]),hd,t("table",null,[id,t("tbody",null,[cd,ad,t("tr",null,[md,pd,fd,t("td",null,[t("a",bd,[l("JD"),d(n)])]),kd]),t("tr",null,[gd,jd,xd,t("td",null,[t("a",zd,[l("JD"),d(n)])]),Od]),wd,t("tr",null,[yd,Ed,Fd,t("td",null,[t("a",Md,[l("JD"),d(n)])]),Rd]),t("tr",null,[Nd,vd,Dd,t("td",null,[t("a",Pd,[l("jd"),d(n)])]),Vd]),Xd,Bd,Id,Jd,Ld,Gd,Kd,Td,qd,Ad])]),Sd,t("table",null,[Ud,t("tbody",null,[Cd,Hd,t("tr",null,[Qd,t("td",null,[t("a",Wd,[l("网易严选7.2kg"),d(n)])]),Yd,Zd,$d]),te,le,ne,de,ee,oe,se,_e,ue,re,he])])])}const pe=e(h,[["render",ie],["__file","购买记录.html.vue"]]);export{pe as default}; diff --git "a/assets/\350\264\255\344\271\260\350\256\260\345\275\225.html-jJ5CWRUF.js" "b/assets/\350\264\255\344\271\260\350\256\260\345\275\225.html-jJ5CWRUF.js" new file mode 100644 index 0000000..4377737 --- /dev/null +++ "b/assets/\350\264\255\344\271\260\350\256\260\345\275\225.html-jJ5CWRUF.js" @@ -0,0 +1 @@ +const l=JSON.parse('{"key":"v-526a70af","path":"/notebook/%E8%B4%AD%E4%B9%B0%E8%AE%B0%E5%BD%95.html","title":"电子产品购买记录","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"大物件","slug":"大物件","link":"#大物件","children":[]},{"level":2,"title":"手机","slug":"手机","link":"#手机","children":[]},{"level":2,"title":"小物件 price<200","slug":"小物件-price-200","link":"#小物件-price-200","children":[]},{"level":2,"title":"家里","slug":"家里","link":"#家里","children":[]},{"level":2,"title":"电脑装机 2022.11","slug":"电脑装机-2022-11","link":"#电脑装机-2022-11","children":[]},{"level":2,"title":"眼镜","slug":"眼镜","link":"#眼镜","children":[]},{"level":2,"title":"猫粮","slug":"猫粮","link":"#猫粮","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/购买记录.md"}');export{l as data}; diff --git "a/assets/\350\277\220\345\212\250\346\211\213\350\241\250.html-FcWbk867.js" "b/assets/\350\277\220\345\212\250\346\211\213\350\241\250.html-FcWbk867.js" new file mode 100644 index 0000000..cda50df --- /dev/null +++ "b/assets/\350\277\220\345\212\250\346\211\213\350\241\250.html-FcWbk867.js" @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-44a727a6","path":"/notebook/%E8%BF%90%E5%8A%A8%E6%89%8B%E8%A1%A8.html","title":"运动手表","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/运动手表.md"}');export{t as data}; diff --git "a/assets/\350\277\220\345\212\250\346\211\213\350\241\250.html-g1Ph5wO2.js" "b/assets/\350\277\220\345\212\250\346\211\213\350\241\250.html-g1Ph5wO2.js" new file mode 100644 index 0000000..1cc1483 --- /dev/null +++ "b/assets/\350\277\220\345\212\250\346\211\213\350\241\250.html-g1Ph5wO2.js" @@ -0,0 +1 @@ +import{_ as t,o as d,c as e,a as r}from"./app-x8p6wK6B.js";const s="/assets/515895892836525-h9GyQ7S-.png",a="/assets/493477101625617-8YwdJfeb.png",c="/assets/379880510279073-CwzzhgUw.png",h={},o=r('

运动手表

款式发布时间价格现价重量
apple watch se22022-919991999
apple watch s82022-929992999
华为watch gt runner2021-9199967038.5g(不含腕带)
华为手环8NFC2023-429925914.1(不含腕带)
小米手环8NFC2023-429922927(含腕带)
oppo手环2NFC2022-8279249

',5),_=[o];function n(p,i){return d(),e("div",null,_)}const m=t(h,[["render",n],["__file","运动手表.html.vue"]]);export{m as default}; diff --git "a/assets/\350\277\220\347\273\264\347\233\270\345\205\263.html-2LDRmBaI.js" "b/assets/\350\277\220\347\273\264\347\233\270\345\205\263.html-2LDRmBaI.js" new file mode 100644 index 0000000..7d7b89d --- /dev/null +++ "b/assets/\350\277\220\347\273\264\347\233\270\345\205\263.html-2LDRmBaI.js" @@ -0,0 +1 @@ +import{_ as e,o,c as s,b as t,d as n}from"./app-x8p6wK6B.js";const c={},l=t("h1",{id:"运维相关",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#运维相关","aria-hidden":"true"},"#"),n(" 运维相关")],-1),_=t("p",null,"想在多个机器上使用同一个 shell 脚本有什么好建议吗?",-1),a=t("p",null,"https://www.v2ex.com/t/845974 curl 执行暴露出来的脚本 scp git 私仓 ansible or saltstack (推荐后者)",-1),i=t("p",null,"安卓自动化:",-1),p=t("p",null,"https://github.com/Jinnrry/RobotHelper",-1),r=t("p",null,"tcp 连接 netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'",-1),d=t("p",null,"iptables 做端口转发",-1),h=t("p",null,[t("code",null,"iptables -t nat -A PREROUTING -i pppoe-wan -p tcp --dport 36000 -j DNAT --to-destination 192.168.2.190:22")],-1),u=[l,_,a,i,p,r,d,h];function f(m,b){return o(),s("div",null,u)}const N=e(c,[["render",f],["__file","运维相关.html.vue"]]);export{N as default}; diff --git "a/assets/\350\277\220\347\273\264\347\233\270\345\205\263.html-6v7-SYPQ.js" "b/assets/\350\277\220\347\273\264\347\233\270\345\205\263.html-6v7-SYPQ.js" new file mode 100644 index 0000000..4c4443e --- /dev/null +++ "b/assets/\350\277\220\347\273\264\347\233\270\345\205\263.html-6v7-SYPQ.js" @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-553c7882","path":"/web/%E8%BF%90%E7%BB%B4%E7%9B%B8%E5%85%B3.html","title":"运维相关","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"web/运维相关.md"}');export{t as data}; diff --git "a/assets/\350\277\233\347\250\213\347\256\241\347\220\206.html-JMs5DErA.js" "b/assets/\350\277\233\347\250\213\347\256\241\347\220\206.html-JMs5DErA.js" new file mode 100644 index 0000000..eaa347b --- /dev/null +++ "b/assets/\350\277\233\347\250\213\347\256\241\347\220\206.html-JMs5DErA.js" @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-4d543397","path":"/python/%E8%BF%9B%E7%A8%8B%E7%AE%A1%E7%90%86.html","title":"进程管理","lang":"en-US","frontmatter":{},"headers":[{"level":3,"title":"APScheduler","slug":"apscheduler","link":"#apscheduler","children":[]},{"level":3,"title":"20201026","slug":"_20201026","link":"#_20201026","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"python/进程管理.md"}');export{e as data}; diff --git "a/assets/\350\277\233\347\250\213\347\256\241\347\220\206.html-OXlKZbzZ.js" "b/assets/\350\277\233\347\250\213\347\256\241\347\220\206.html-OXlKZbzZ.js" new file mode 100644 index 0000000..1096886 --- /dev/null +++ "b/assets/\350\277\233\347\250\213\347\256\241\347\220\206.html-OXlKZbzZ.js" @@ -0,0 +1,49 @@ +import{_ as s,o as e,c as n,a}from"./app-x8p6wK6B.js";const t={},i=a(`

进程管理

supervisor 管理进程简明教程:https://www.jianshu.com/p/bf2b3f4dec73 使用 supervisor 管理进程:https://liyangliang.me/posts/2015/06/using-supervisor/ https://www.cnblogs.com/wswang/p/5795766.html

方便管理 =配置复杂

为实现进程管理, 需要先对程序做以下分类

  • demo 程序: 可能会出问题的程序, 需要保留程序上下文 1.使用screen 进行操作
screen -S screen_Name
+
+python3 main.py
+

2.nohup python3 main.py > log 2>&1 &

  • 例行任务
  1. crontab

这种是比较简单的方式,缺点在于移动文件时不好管理

  1. superversion + schedule(APScheduler)

配置较复杂 带有web接口

superversion program.conf

[program:zhonghua]
+command=python3 APScheduler_main.py              ; the program (relative uses PATH, can take args)
+process_name=%(program_name)s ; process_name expr (default %(program_name)s)
+numprocs=1                    ; number of processes copies to start (def 1)
+directory=/home/ubuntu/zorsong/zhonghua_task                ; directory to cwd to before exec (def no cwd)
+;umask=022                     ; umask for process (default None)
+;priority=999                  ; the relative start priority (default 999)
+;autostart=true                ; start at supervisord start (default: true)
+;startsecs=1                   ; # of secs prog must stay up to be running (def. 1)
+;startretries=3                ; max # of serial start failures when starting (default 3)
+autorestart=unexpected        ; when to restart if exited after running (def: unexpected)
+exitcodes=0,2                 ; 'expected' exit codes used with autorestart (default 0,2)
+stopsignal=QUIT               ; signal used to kill process (default TERM)
+stopwaitsecs=10               ; max num secs to wait b4 SIGKILL (default 10)
+stopasgroup=false             ; send stop signal to the UNIX process group (default false)
+killasgroup=false             ; SIGKILL the UNIX process group (def false)
+user=ubuntu                   ; setuid to this UNIX account to run the program
+redirect_stderr=true          ; redirect proc stderr to stdout (default false)
+stdout_logfile=/home/ubuntu/zorsong/zhonghua_task/logfile        ; stdout log path, NONE for none; default AUTO
+;stdout_logfile_maxbytes=1MB   ; max # logfile bytes b4 rotation (default 50MB)
+;stdout_logfile_backups=10     ; # of stdout logfile backups (default 10)
+;stdout_capture_maxbytes=1MB   ; number of bytes in 'capturemode' (default 0)
+;stdout_events_enabled=false   ; emit events on stdout writes (default false)
+stderr_logfile=/home/ubuntu/zorsong/zhonghua_task/logfile        ; stderr log path, NONE for none; default AUTO
+;stderr_logfile_maxbytes=1MB   ; max # logfile bytes b4 rotation (default 50MB)
+;stderr_logfile_backups=10     ; # of stderr logfile backups (default 10)
+;stderr_capture_maxbytes=1MB   ; number of bytes in 'capturemode' (default 0)
+;stderr_events_enabled=false   ; emit events on stderr writes (default false)
+;environment=A="1",B="2"       ; process environment additions (def no adds)
+;serverurl=AUTO                ; override serverurl computation (childutils)
+

APScheduler


+def foo():
+    print("foo")
+
+
+from apscheduler.schedulers.background import BackgroundScheduler
+
+sch = BackgroundScheduler()
+
+sch.add_job(foo) # 不加时间, 会在sch.start()后立即执行
+sch.add_job(foo,'interval',minutes=5)  # 每5分钟执行一次
+sch.add_job(foo, 'cron', hour='9') # 每天的09:00 执行一次
+
+
+
+

20201026

http://www.vuln.cn/9121

`,18),l=[i];function o(r,d){return e(),n("div",null,l)}const c=s(t,[["render",o],["__file","进程管理.html.vue"]]);export{c as default}; diff --git "a/assets/\351\203\250\347\275\262paddle\346\241\206\346\236\266\344\271\213ocr.html-5ZV3ZJJm.js" "b/assets/\351\203\250\347\275\262paddle\346\241\206\346\236\266\344\271\213ocr.html-5ZV3ZJJm.js" new file mode 100644 index 0000000..13297cb --- /dev/null +++ "b/assets/\351\203\250\347\275\262paddle\346\241\206\346\236\266\344\271\213ocr.html-5ZV3ZJJm.js" @@ -0,0 +1,65 @@ +import{_ as e,o as i,c as n,a as d}from"./app-x8p6wK6B.js";const l={},c=d(`

部署paddle框架之ocr

步骤

1.下载安装anconda 2. 创建一个环境先

conda create -n paddle_env
+conda activate paddle_env
+
# 安装FastDpeloy python包(详细文档请参考\`部署环境准备\`)
+
+# 约1.2g
+pip install fastdeploy-gpu-python -f https://www.paddlepaddle.org.cn/whl/fastdeploy.html
+
+# 约 3g
+conda config --add channels conda-forge && conda install cudatoolkit=11.2 cudnn=8.2
+
+# 下载部署示例代码
+git clone https://github.com/PaddlePaddle/FastDeploy.git
+cd  FastDeploy/examples/vision/ocr/PP-OCR/cpu-gpu/python
+
+# 如果您希望从PaddleOCR下载示例代码,请运行
+git clone https://github.com/PaddlePaddle/PaddleOCR.git
+# 注意:如果当前分支找不到下面的fastdeploy测试代码,请切换到dygraph分支
+git checkout dygraph
+cd PaddleOCR/deploy/fastdeploy/cpu-gpu/python
+
+# 下载PP-OCRv3文字检测模型
+wget https://paddleocr.bj.bcebos.com/PP-OCRv3/chinese/ch_PP-OCRv3_det_infer.tar
+tar -xvf ch_PP-OCRv3_det_infer.tar
+# 下载文字方向分类器模型
+wget https://paddleocr.bj.bcebos.com/dygraph_v2.0/ch/ch_ppocr_mobile_v2.0_cls_infer.tar
+tar -xvf ch_ppocr_mobile_v2.0_cls_infer.tar
+# 下载PP-OCRv3文字识别模型
+wget https://paddleocr.bj.bcebos.com/PP-OCRv3/chinese/ch_PP-OCRv3_rec_infer.tar
+tar -xvf ch_PP-OCRv3_rec_infer.tar
+
+# 下载预测图片与字典文件
+wget https://gitee.com/paddlepaddle/PaddleOCR/raw/release/2.6/doc/imgs/12.jpg
+wget https://gitee.com/paddlepaddle/PaddleOCR/raw/release/2.6/ppocr/utils/ppocr_keys_v1.txt
+
+# 运行部署示例
+# 在CPU上使用Paddle Inference推理
+python infer.py --det_model ch_PP-OCRv3_det_infer --cls_model ch_ppocr_mobile_v2.0_cls_infer --rec_model ch_PP-OCRv3_rec_infer --rec_label_file ppocr_keys_v1.txt --image 12.jpg --device cpu --backend paddle
+# 在CPU上使用OenVINO推理
+python infer.py --det_model ch_PP-OCRv3_det_infer --cls_model ch_ppocr_mobile_v2.0_cls_infer --rec_model ch_PP-OCRv3_rec_infer --rec_label_file ppocr_keys_v1.txt --image 12.jpg --device cpu --backend openvino
+# 在CPU上使用ONNX Runtime推理
+python infer.py --det_model ch_PP-OCRv3_det_infer --cls_model ch_ppocr_mobile_v2.0_cls_infer --rec_model ch_PP-OCRv3_rec_infer --rec_label_file ppocr_keys_v1.txt --image 12.jpg --device cpu --backend ort
+# 在CPU上使用Paddle Lite推理
+python infer.py --det_model ch_PP-OCRv3_det_infer --cls_model ch_ppocr_mobile_v2.0_cls_infer --rec_model ch_PP-OCRv3_rec_infer --rec_label_file ppocr_keys_v1.txt --image 12.jpg --device cpu --backend pplite
+# 在GPU上使用Paddle Inference推理
+python infer.py --det_model ch_PP-OCRv3_det_infer --cls_model ch_ppocr_mobile_v2.0_cls_infer --rec_model ch_PP-OCRv3_rec_infer --rec_label_file ppocr_keys_v1.txt --image 12.jpg --device gpu --backend paddle
+# 在GPU上使用Paddle TensorRT推理
+python infer.py --det_model ch_PP-OCRv3_det_infer --cls_model ch_ppocr_mobile_v2.0_cls_infer --rec_model ch_PP-OCRv3_rec_infer --rec_label_file ppocr_keys_v1.txt --image 12.jpg --device gpu --backend pptrt
+# 在GPU上使用ONNX Runtime推理
+python infer.py --det_model ch_PP-OCRv3_det_infer --cls_model ch_ppocr_mobile_v2.0_cls_infer --rec_model ch_PP-OCRv3_rec_infer --rec_label_file ppocr_keys_v1.txt --image 12.jpg --device gpu --backend ort
+# 在GPU上使用Nvidia TensorRT推理
+python infer.py --det_model ch_PP-OCRv3_det_infer --cls_model ch_ppocr_mobile_v2.0_cls_infer --rec_model ch_PP-OCRv3_rec_infer --rec_label_file ppocr_keys_v1.txt --image 12.jpg --device gpu --backend trt
+
+# 同时, FastDeploy提供文字检测,文字分类,文字识别三个模型的单独推理,
+# 有需要的用户, 请准备合适的图片, 同时根据自己的需求, 参考infer.py来配置自定义硬件与推理后端.
+
+# 在CPU上,单独使用文字检测模型部署
+python infer_det.py --det_model ch_PP-OCRv3_det_infer  --image 12.jpg --device cpu
+
+# 在CPU上,单独使用文字方向分类模型部署
+python infer_cls.py --cls_model ch_ppocr_mobile_v2.0_cls_infer --image 12.jpg --device cpu
+
+# 在CPU上,单独使用文字识别模型部署
+python infer_rec.py  --rec_model ch_PP-OCRv3_rec_infer --rec_label_file ppocr_keys_v1.txt --image 12.jpg --device cpu
+
+
`,5),r=[c];function s(a,_){return i(),n("div",null,r)}const t=e(l,[["render",s],["__file","部署paddle框架之ocr.html.vue"]]);export{t as default}; diff --git "a/assets/\351\203\250\347\275\262paddle\346\241\206\346\236\266\344\271\213ocr.html-vwkMyYHg.js" "b/assets/\351\203\250\347\275\262paddle\346\241\206\346\236\266\344\271\213ocr.html-vwkMyYHg.js" new file mode 100644 index 0000000..8a3eaf6 --- /dev/null +++ "b/assets/\351\203\250\347\275\262paddle\346\241\206\346\236\266\344\271\213ocr.html-vwkMyYHg.js" @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-689f17cc","path":"/python/cv/%E9%83%A8%E7%BD%B2paddle%E6%A1%86%E6%9E%B6%E4%B9%8Bocr.html","title":"部署paddle框架之ocr","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"步骤","slug":"步骤","link":"#步骤","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"python/cv/部署paddle框架之ocr.md"}');export{e as data}; diff --git "a/assets/\351\207\215\347\275\256CMD\350\256\276\347\275\256.html-Nvd1Q05q.js" "b/assets/\351\207\215\347\275\256CMD\350\256\276\347\275\256.html-Nvd1Q05q.js" new file mode 100644 index 0000000..ccaff47 --- /dev/null +++ "b/assets/\351\207\215\347\275\256CMD\350\256\276\347\275\256.html-Nvd1Q05q.js" @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-2466882a","path":"/notebook/%E9%87%8D%E7%BD%AECMD%E8%AE%BE%E7%BD%AE.html","title":"重置CMD设置","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/重置CMD设置.md"}');export{t as data}; diff --git "a/assets/\351\207\215\347\275\256CMD\350\256\276\347\275\256.html-WYxGHLc5.js" "b/assets/\351\207\215\347\275\256CMD\350\256\276\347\275\256.html-WYxGHLc5.js" new file mode 100644 index 0000000..793a555 --- /dev/null +++ "b/assets/\351\207\215\347\275\256CMD\350\256\276\347\275\256.html-WYxGHLc5.js" @@ -0,0 +1 @@ +import{_ as e,o as t,c,a as o}from"./app-x8p6wK6B.js";const s="/assets/20200313180023826_26780-wWVBxmWt.png",_={},a=o('

重置CMD设置

打开运行,输入regedit 打开注册表

找到如图下所示的文件夹,删除掉即可

按理说删除%SystemRoot%_System32_cmd.exe 即可, 实际中我删除后无效

因此我尝试将整个Console 文件夹删除掉,打开CMD后恢复了默认设置,成功

注册表编辑器

',6),d=[a];function r(n,p){return t(),c("div",null,d)}const m=e(_,[["render",r],["__file","重置CMD设置.html.vue"]]);export{m as default}; diff --git "a/assets/\351\235\242\350\257\225.html-mdJ2GoUw.js" "b/assets/\351\235\242\350\257\225.html-mdJ2GoUw.js" new file mode 100644 index 0000000..eb740c1 --- /dev/null +++ "b/assets/\351\235\242\350\257\225.html-mdJ2GoUw.js" @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-27f8a722","path":"/python/%E9%9D%A2%E8%AF%95.html","title":"面试","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"python/面试.md"}');export{t as data}; diff --git "a/assets/\351\235\242\350\257\225.html-o0gloVSU.js" "b/assets/\351\235\242\350\257\225.html-o0gloVSU.js" new file mode 100644 index 0000000..8a75e71 --- /dev/null +++ "b/assets/\351\235\242\350\257\225.html-o0gloVSU.js" @@ -0,0 +1,4 @@ +import{_ as o,o as e,c as p,a as t}from"./app-x8p6wK6B.js";const P="/assets/20220401140429373_9677-JkF4tT3w.png",n={},i=t(`

面试

1,网络 1.1 本地dns服务器如何获取

通过DHCP协议从DHCP服务器获取,就和自动获取IP一样,DNS只不过是其中一个option。

计算机设置自动获取后,它会向网内发送个广播,当服务器收到这个包时就会回应个地址给这台机器,机器取到回应后设置完成 路由器也是类似,从他连接到的运行商发送这个广播 通过DHCP协议从DHCP服务器获取,就和自动获取IP一样,DNS只不过是其中一个option。

车小胖​​计算机网络话题下的优秀答主19 人赞同了该回答主机在启动时,会发送一个广播DHCP报文来寻找DHCP服务器,来给自己分配上网用的IP地址,DNS服务器地址等信息:什么是DHCP?Dynamic Host Configuration Protocol,动态主机配置协议,它主要用来给用户的电脑分配以下信息:1)IP地址 如 10.1.1.22)IP地址对应的子网掩码 如 255.255.255.0 DHCP 里有很多选项option,子网掩码放在option 1里3)缺省网关 如 10.1.1.1 Option 3,当主机10.1.1.2 想访问互联网,需要把IP包先发给缺省网关10.1.1.1,然后缺省网关再发送给它上游的路由器4)DNS 服务器 如8.8.8.8这个DNS 服务器就是放在option 6信息字段里的,DNS 服务器负责域名和IP地址的翻译,比如你访问 http://www.zhihu.com ,DNS服务器可以把它翻译成115.21.37.139,然后主机就可以用这个IP地址来访问知乎了。那DHCP的安全漏洞是什么呢?如果一个邪恶软件伪造不同的Mac地址,不断发送DHCP discovery,比如1000个,如果没有安全措施,DHCP server很有可能就分配1000个IP地址给它,因为server是根据client Mac来分配IP的,这样很快就可以把地址池资源耗尽,其它的用户因为没有地址可用而无法上网!应对方法:配置DHCP option 82,DHCP discovery途径二层交换机时,交换机修改报文,增加option 82信息,即这条消息是从哪个端口收到的,把这个端口信息添加到DHCP discovery 报文里,服务器根据 “client Mac地址+ 交换机端口号” 来分配IP,即任意一个交换机端口最多分配一个IP,即使采用伪造的不同的Mac地址来请求也是一个!这就是DHCP反欺骗措施,DHCP Anti-Spoofing!----------回复@唐诗宋词评论----------Option 82 是 谁来添加到DHCP 消息报文? 添加到什么报文? 主要作用是什么?主要作用是什么?1) line ID 让Radius server 可以知道DHCP client location 信息,比如 switch x Port x/x/x ,可以提供安全认证服务器更多关于 client 具体位置,可以 tracking and logging DHCP client2) remote ID ,可以让DHCP server 依靠 remote ID + Hardware MAC 来分配IP,避免伪造 MAC 耗尽IP地址池。谁来添加到DHCP 消息报文?1) DHCP snooping switch2) DHCP relay router添加到什么报文? 1) DHCP Discovery2) DHCP Request编辑于 2016-07-17 10:08​赞同 19​​5 条评论​分享​收藏​喜欢收起​

由器转发 DNS 请求 1.2 更新域名指向,边缘dns服务器如何知道更新了 缓存获取后,再次查询

1.3 qq.com 如何承受这么大的访问量 cdn, dns根据所在地提供不同的ip 然后做负载均衡

1.4 https 密钥交换算法 DH算法 密钥协商算法

1.5 cc攻击, ddos攻击原理

tcp land攻击

1、SYN Flood攻击 SYN Flood攻击是当前网络上最为常见的DDoS攻击,它利用了TCP协议实现上的一个缺陷。通过向网络服务所在端口发送大量的伪造源地址的攻击报文,就可能造成目标服务器中的半开连接队列被占满,从而阻止其他合法用户进行访问。 [7] 2、UDP Flood攻击 UDP Flood是日渐猖厥的流量型DDoS攻击,原理也很简单。常见的情况是利用大量UDP小包冲击DNS服务器或Radius认证服务器、流媒体视频服务器。由于UDP协议是一种无连接的服务,在UDP Flood攻击中,攻击者可发送大量伪造源IP地址的小UDP包。 [7] 3、ICMP Flood攻击 ICMP Flood攻击属于流量型的攻击方式,是利用大的流量给服务器带来较大的负载,影响服务器的正常服务。由于目前很多防火墙直接过滤ICMP报文。因此ICMP Flood出现的频度较低。 [7] 4、Connection Flood攻击 Connection Flood是典型的利用小流量冲击大带宽网络服务的攻击方式,这种攻击的原理是利用真实的IP地址向服务器发起大量的连接。并且建立连接之后很长时间不释放,占用服务器的资源,造成服务器上残余连接(WAIT状态)过多,效率降低,甚至资源耗尽,无法响应其他客户所发起的链接。 [7] 5、HTTP Get攻击 这种攻击主要是针对存在ASP、JSP、PHP、CGI等脚本程序,特征是和服务器建立正常的TCP连接,并不断的向脚本程序提交查询、列表等大量耗费数据库资源的调用。这种攻击的特点是可以绕过普通的防火墙防护,可通过Proxy代理实施攻击,缺点是攻击静态页面的网站效果不佳,会暴露攻击者的lP地址。 [7] 6、UDP DNS Query Flood攻击 UDP DNS Query Flood攻击采用的方法是向被攻击的服务器发送大量的域名解析请求,通常请求解析的域名是随机生成或者是网络世界上根本不存在的域名。域名解析的过程给服务器带来了很大的负载,每秒钟域名解析请求超过一定的数量就会造成DNS服务器解析域名超时。 [7]

代理CC攻击是黑客借助代理服务器生成指向受害主机的合法网页请求,实现DDoS,和伪装就叫:cc(Challenge Collapsar)

1.6 负载均衡,如果一个机器挂掉,其他的机器应该怎么办

 按照处理极限接手部分流量,其余流量则丢弃
+

1.7 快速移动的情况下,会发生什么(基站带宽改变,基站切换

优化: 使用httpdns,内置一些ip服务器做httpdns
+    使用quic
+

弱网络优化

HttpDNSLib 1)lbs 返回服务器 ip 而非域名 2)本地缓存 lbs ip 地址备用,请求 lbs 时优先使用 ip 而非域名

icmp ping

',20),D=[i];function c(r,s){return e(),p("div",null,D)}const l=o(n,[["render",c],["__file","面试.html.vue"]]);export{l as default}; diff --git "a/notebook/2019\345\271\264\345\271\264\345\272\246\346\261\207\346\212\245.html" "b/notebook/2019\345\271\264\345\271\264\345\272\246\346\261\207\346\212\245.html" new file mode 100644 index 0000000..5d92dcc --- /dev/null +++ "b/notebook/2019\345\271\264\345\271\264\345\272\246\346\261\207\346\212\245.html" @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + diff --git "a/notebook/2022-8\346\234\272\346\242\260\351\224\256\347\233\230\351\234\200\346\261\202.html" "b/notebook/2022-8\346\234\272\346\242\260\351\224\256\347\233\230\351\234\200\346\261\202.html" new file mode 100644 index 0000000..7a989dd --- /dev/null +++ "b/notebook/2022-8\346\234\272\346\242\260\351\224\256\347\233\230\351\234\200\346\261\202.html" @@ -0,0 +1,34 @@ + + + + + + + + + 2022-8机械键盘需求 + + + + + + + + + diff --git "a/notebook/3D\345\273\272\346\250\241/index.html" "b/notebook/3D\345\273\272\346\250\241/index.html" new file mode 100644 index 0000000..a3d1281 --- /dev/null +++ "b/notebook/3D\345\273\272\346\250\241/index.html" @@ -0,0 +1,34 @@ + + + + + + + + + 这里是notebook/3D建模 + + + + + + + + + diff --git "a/notebook/3D\345\273\272\346\250\241/webodm\351\205\215\347\275\256\345\256\211\350\243\205.html" "b/notebook/3D\345\273\272\346\250\241/webodm\351\205\215\347\275\256\345\256\211\350\243\205.html" new file mode 100644 index 0000000..bb4852e --- /dev/null +++ "b/notebook/3D\345\273\272\346\250\241/webodm\351\205\215\347\275\256\345\256\211\350\243\205.html" @@ -0,0 +1,64 @@ + + + + + + + + + webodm配置安装 + + + + + +

webodm配置安装

moyechen 23.9.24

环境配置 windows11

rtx4070 已在windwos部署好驱动,cuda

步骤1 wsl2配置

启动wsl 可能需要更新,wsl --update 打开微软应用闪电,搜索ubuntu,安装ubuntu

安装结束后,点击启动,需初始化ubuntu的账号密码

步骤1 安装docker desktop

从官网下载即可 启动后打开设置,勾选wsl2,选中刚安装的ubuntu

ubuntu nvidia驱动配置

https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html#installing-with-apt

进入ubuntu

配置gpgkey

curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg \
+  && curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \
+    sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \
+    sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list \
+  && \
+    sudo apt-get update
+

安装工具包

sudo apt-get install -y nvidia-container-toolkit
+

执行

sudo nvidia-ctk runtime configure --runtime=docker
+

但是wsl的配置文件不在/etc/docker/下,我们吧工具增加的内容复制出来,去docker desktop配置即可

修改后点击右下角apply&restart

重启完成后,检测是否部署成功

sudo docker run --rm --runtime=nvidia --gpus all ubuntu nvidia-smi
+

Your output should resemble the following output:

+-----------------------------------------------------------------------------+
+| NVIDIA-SMI 535.86.10    Driver Version: 535.86.10    CUDA Version: 12.2     |
+|-------------------------------+----------------------+----------------------+
+| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
+| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
+|                               |                      |               MIG M. |
+|===============================+======================+======================|
+|   0  Tesla T4            On   | 00000000:00:1E.0 Off |                    0 |
+| N/A   34C    P8     9W /  70W |      0MiB / 15109MiB |      0%      Default |
+|                               |                      |                  N/A |
++-------------------------------+----------------------+----------------------+
+
++-----------------------------------------------------------------------------+
+| Processes:                                                                  |
+|  GPU   GI   CI        PID   Type   Process name                  GPU Memory |
+|        ID   ID                                                   Usage      |
+|=============================================================================|
+|  No running processes found                                                 |
++-----------------------------------------------------------------------------+
+

步骤3 拉取项目文件

在打开的ubuntu中, 拉取项目(需提前安装git)

git clone https://github.com/OpenDroneMap/WebODM
+

步骤4 启动

./webodm.sh start --gpu
+

mipc杂项

时间估算 132张照片大概一小时

132×132/5 ~= 3600

256张大概4小时

gpu 实际gpu使用率一直没上去,也不知道为啥

测试数据集

https://github.com/pierotofy/dataset_banana/tree/master

+ + + diff --git a/notebook/Mysql.html b/notebook/Mysql.html new file mode 100644 index 0000000..243a1c0 --- /dev/null +++ b/notebook/Mysql.html @@ -0,0 +1,84 @@ + + + + + + + + + Mysql + + + + + +

Mysql

2020/9/28

重置mysql密码

服务器版本: ubuntu

第一步:停止mysql服务 sudo /etc/init.d/mysqld stop or sudo service mysql stop

第二步, 以跳过密码验证模式启动mysql , 这一步窗口会阻塞, 需要再开启一个终端 sudo mysqld_safe --skip-grant-tables

可能有人这个时候报了一个错误, mysqld_safe Directory '/var/run/mysqld' for UNIX socket file don't exists

google 得到解决方案

https://stackoverflow.com/questions/42153059/mysqld-safe-directory-var-run-mysqld-for-unix-socket-file-dont-exists

sudo mkdir -p /var/run/mysqld
+sudo chown mysql:mysql /var/run/mysqld
+

问题解决

第三步: 进入mysql

mysql

第四步, 更新密码,这里我将密码改为your_password


+use mysql;
+
+update user set authentication_string = password("your_password") where user = "root";
+flush privileges;
+
+

然后重启mysql 即可

先杀掉我们
+

2020/4/5

select insert


+INSERT INTO table2
+(column_name(s))
+SELECT column_name(s)
+FROM table1;
+

2020/3/29

mysql 语句分析:

explain + sql语句

数据类型为text 的时间字段, 对比

  1. 最简形式 96s
SELECT * FROM `tousu_heimao_table` WHERE complaint_time > '2020-03-27'
+
+
+加入limit 50
+SELECT id FROM `tousu_heimao_table` WHERE complaint_time > '2020-03-27' ORDER BY complaint_time limit 50;  5s
+
+
  1. 使用时间戳,以及替换*为字段名 45s
SELECT id,identity_code,crawl_time,title,complain_man,website,object_of_complaint,question_type,appeal_type,details_of_complaint,process_flow,comment_data,complaint_time FROM `tousu_heimao_table` WHERE unix_timestamp(complaint_time) > 1585281379`
+
+
+
+
  1. 只查询id,没有设置limit
SELECT id FROM `tousu_heimao_table` WHERE unix_timestamp(complaint_time) > 1585281379 limit 50
+
  1. 前50个 6.5s, 第1000-1050个, 65s
SELECT id FROM `tousu_heimao_table` WHERE unix_timestamp(complaint_time) > 1585281379 ORDER BY complaint_time DESC limit 50
+
  1. 第100000-100050条 40s
SELECT id FROM `tousu_heimao_table` WHERE 1=1 ORDER BY complaint_time DESC limit 100000,50
+
  1. 稍微优化, 27s
SELECT id FROM `tousu_heimao_table` WHERE id > (select id from `tousu_heimao_table` ORDER BY complaint_time DESC limit 100000,1) limit 50
+

7.究极优化 3s

SELECT * FROM `tousu_heimao_table` WHERE id > (select id from `tousu_heimao_table` ORDER BY id  limit 100000,1) limit 50
+

8 .加入时间 2s

SELECT * FROM `tousu_heimao_table` WHERE id > (select id from `tousu_heimao_table` where complaint_time>'2019-3-27'    ORDER BY id  limit 100000,1) limit 50
+
  1. 字段数据类型设置为datetime
SELECT * FROM tousu_table WHERE complaint_time > '2020-3-27' limit 100;   7s
+
SELECT * FROM tousu_table WHERE complaint_time > '2020-03-27' limit 100;  10s
+

输出表的字段名 2020/03/26

select COLUMN_NAME from information_schema.COLUMNS where table_name = 'your_table_name' and table_schema = 'your_db_name';
+

查询所有符合要求的行数, 同时取limit数据

一般思路: 查一下count(1) , 然后把count(1) 换成 * , 后面加上limit 0, 50, 再次查询得到数据

优化: 博客open in new window

select SQL_CALC_FOUND_ROWS 
+    col_name1 as colName1,
+    col_name2 as colName2
+from table_name limit 0,10;
+select FOUND_ROWS() as count;
+ 
+在SELECT语句中加上修饰SQL_CALC_FOUND_ROWS 之后,SELECT FOUND_ROWS() 会返回满足条件记录的总数。
+

这样,你执行完 select SQL_CALC_FOUND_ROWS 之后,再取一下记录总数就行了。

3/29:

 SELECT SQL_CALC_FOUND_ROWS
+	*
+FROM
+	tousu_table 
+WHERE
+	(complaint_time <= '2020-03-30' AND complaint_time >= '2020-03-22' )
+ORDER BY
+	complaint_time 
+	LIMIT 0,
+	50
+

建立索引后,加与不加时间差异很大,加上后6.6s 不加1s

使用这个东西会导致全表扫描

+ + + diff --git a/notebook/adb.html b/notebook/adb.html new file mode 100644 index 0000000..f4132a1 --- /dev/null +++ b/notebook/adb.html @@ -0,0 +1,41 @@ + + + + + + + + + adb + + + + + +

adb

adb 更换壁纸 2020/4/29

am start -d file:////data/local/tmp/black_white.png -a android.service.wallpaper.CROP_AND_SET_WALLPAPER -f 0x1 com.android.launcher3/.WallpaperCropActivity

adb 授予/撤销 应用权限 2020/4/27

# 给微信授予高精度定位权限
+adb shell pm grant com.tencent.mm android.permission.ACCESS_FINE_LOCATION
+
+# 撤销
+adb shell pm revoke com.tencent.mm android.permission.ACCESS_FINE_LOCATION
+
+
+

有用的链接

  1. https://www.cnblogs.com/jianxu/p/5380882.html
  2. https://ligboy.org/?p=429 AppOps ,设置权限(在一加5, 7.1.1上简单测试未生效)

adb推送后,图片在相册中不显示 2020/4/26

解决方案open in new window

博客1open in new window

命令1刷新图片:adb shell am broadcast -a android.intent.action.MEDIA_SCANNER_SCAN_FILE -d file:///sdcard/Pictures/xx.png

命令2刷新目录:adb shell am broadcast -a android.intent.action.MEDIA_MOUNTED -d file:///sdcard/Pictures ▲ android < 4.4

EXTERNAL_CONTENT_URI

Intent.ACTION_MEDIA_MOUNTED

一般命令2比较有用。但是命令2,需要权限,因此使用命令1

———————————————— 版权声明:本文为CSDN博主「jimic0831」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/jimic0831/article/details/78274265

清空应用缓存 2020/4/19

adb shell pm clear <PACKAGE>

+ + + diff --git a/notebook/cf-tools.html b/notebook/cf-tools.html new file mode 100644 index 0000000..5ab0f11 --- /dev/null +++ b/notebook/cf-tools.html @@ -0,0 +1,60 @@ + + + + + + + + + cf-tools + + + + + +

cf-tools

时间作者
2020/2/16 0:43moyechen
## 下载&准备工作

GitHub 地址: xalanq/cf-toolopen in new window

cf-tool 是 Codeforces 的命令行界面的跨平台(支持 Windows、Linux、OS X)工具,其支持很多常用操作。

cf-tool下载

前往 cf-tool/releasesopen in new window 下载最新版。

之后的更新可以直接使用 upgrade 命令获取。

windows准备工作

你的电脑需要编译器才能调试你编写的代码

对于c/cpp, 我们需要g++这款编译器 如果你拥有自带mingw的code:block这款IDE, 可以从如下位置找到 2

▲将第三张图片红框中的路径复制下来, 记做compiler_path

将这个路径添加到环境变量中,什么,你还不会添加路径到环境变量? 点击以获得讲解

否则,可以访问 https://www.jianshu.com/p/ff24a81f3637 ,参考教程下载g++编译器

测试编译器是否可用

按住win键,然后输入r,在弹出的框中输入cmd

此时会打开一个黑框框

输入g++

如果出现下图,这说明编译器准备完毕

添加cf.exe到环境变量

首先先将下载到的cf.exe文件放到一个合适的目录

右击 我的电脑,在弹出的下来框中选择 属性 这个选项 然后按下图操作

至此, 打开cmd,输入cf,如果显示以下内容,即为cf 环境变量配置成功

LINUX 准备工作

准备cf

将下载到cf 文件放在合适的目录,进入这个目录

执行以下命令,给予执行权限并创建软连接


+chmod 775 ./cf
+ln ./cf /usr/bin/cf
+
+

输入cf 出现下图则成功

linux测试g++编译器是否可用

输入g++,出现下图,则为正常

如果没有, 请自行安装g++编译器

配置cf

终于将准备工作做完了

我们可以开始配置了

windows用户请打开cmd linxu 用户请进入shell

下图是我在linux的终端上操作的,windows和linux通用

输入以下命令 cf config

  1. username and password > 这个是用来配置用户名以及密码
  2. add a template > 添加一个代码模板,可以指定语言
  3. delete a template > 删除一个模板
  4. 设置默认模板
  5. 在解析题目结束后,自动生成模板代码
  6. 设置网站主体, 比如在中国我们可以设置为镜像站 https://codeforces.ml 以获得更好的体验

我们选择1

然后选择你要使用的编译器, 这里我们使用42号编译器 GNU G++11 5.1.0

紧接着

可以看到, cf-tool 提供了一些变量,比如 年月日, 以及你的用户名

这里我提供一个模板

#include<bits/stdc++.h>
+using namespace std;
+typedef long long ll;
+
+/*
+$%U%$
+$%Y%$-$%M%$-$%D%$  $%h%$:$%m%$
+*/
+
+const int maxn = 5e5 + 5;
+const int inf  = 0x3f3f3f3f;
+
+
+int main() {
+    std::ios::sync_with_stdio(false);
+    cin.tie(0);
+
+    return 0;
+}
+

你只需要复制到一个地方,然后记住他的绝对路径,并输入即可 例如:

  • ~/template.cpp (适用于linux)
  • D:/template.cpp (适用于windows,需要带上盘符)

在输入后, 配置程序给了几个询问,我来分别做以下解释

  1. The suffix of template above will be added by default. Other suffix? (e.g. "cxx cc"), empty is ok:

    默认情况下,将添加上面模板的后缀。 需要添加其他后缀吗?(例如,“cxx cc”),空的也是可以:

    这里我们不需要了,所以直接回车

  2. Template's alias (e.g. "cpp" "py"):

    模板别名,因为我们用的是cpp, 因此我输入了cpp, 别名在使用 cf gen 生成模板代码时可以用到, 比如输入cf gen cpp, 就会生成我们刚刚添加的模板

  3. Script in template: Template will run 3 scripts in sequence when you run "cf test":

    - before_script   (execute once)
    + - script          (execute the number of samples times)
    + - after_script    (execute once)
    +

    You could set "before_script" or "after_script" to empty string, meaning not executing. You have to run your program in "script" with standard input/output (no need to redirect).

    You can insert some placeholders in your scripts. When execute a script, cf will replace all placeholders by following rules:

    $%path%$ Path to source file (Excluding $%full%$, e.g. "/home/xalanq/") $%full%$ Full name of source file (e.g. "a.cpp") $%file%$ Name of source file (Excluding suffix, e.g. "a") $%rand%$ Random string with 8 character (including "a-z" "0-9")

    这一段讲的是工具的运作原理

    在你输入cf test之后

    • 首先工具执行你输入的 before_script 脚本, 例如 g++ $%full%$ -o /tmp/a.out -std=c++11, 来编译代码,并生成到/tmp/a.out
    • 然后执行 你输入的script脚本, 例如/tmp/a.out ,这代表执行这个刚刚编译好的程序, (ps, 这一步 是用来执行程序的)
    • 接下来执行你输入的after_script脚本,例如执行 rm $%file%$.exe 以将刚刚编译好的程序删除, 防止占用硬盘空间(ps. 一般来说,acm的代码不超过5kb, 但是编译好的控制台应用程序一般在1mb左右, 但是这个程序我们只用一次,比较浪费空间,因此可以在执行后删除)

    下面我讲解一下我的输入

    • 对于第一个问题before_script .我的回答是 g++ $%full%$ -o /tmp/a.out -std=c++11, 我每次都生成到同一个地方, 这次生成的会覆盖掉上次生成的, 也不需要删除了,其中 /tmp/a.out 是一个生成的路径, -std=c++11 是执行的c++标准, 我们可以改为-std=c++14 或者 -std=c++17以享用新特性
      • 在windows上,路径可以更改为 D:/tmp.exe 等等等等,需要加上盘符
    • 对于第二个问题script . 我的回答是 /tmp/a.out, 无论是linux 还是windows ,都需要写的是生成的文件的绝对路径
    • 第三个问题 after_script .我们不需要任何处理,因此,直接回车

最后,它询问我是否作为默认设置, 输入 y 确认

至此, 配置结束

简单的流程

准备比赛了, 首先拿到比赛编号,

▲可以在url中看到比赛编号

控制台输入 cf race 比赛编号

▼它就会为你解析比赛测试样例,并打开题面网站

▼如果比赛未开始,他会自动等待,然后在开始的一瞬间为你解析数据

然后使用cd命令切换到比赛目录,并进入a题文件夹

cd 比赛编号\a

使用cf gen命令生成一个模板

你可以使用别名,这样根据你对应的模板生成代码 cf gen cpp

然后开始编写你的代码:

  • 在linux 上 : vim a.cpp
  • 在windows上: 如果装有vscode ,则可以使用code -r a.cpp,否则, 可以使用notepad a.cpp使用记事本,当然,你也可以在你的IDE中添加这个文件夹,以使用IDE编写代码

编写结束 使用cf test测试样例数据

很好, 样例过了

使用cf submit提交你所在目录的题目

过题,

然后使用cd命令切换到其他题目的目录, 继续重复操作

+ + + diff --git "a/notebook/django\347\274\223\345\255\230.html" "b/notebook/django\347\274\223\345\255\230.html" new file mode 100644 index 0000000..a719022 --- /dev/null +++ "b/notebook/django\347\274\223\345\255\230.html" @@ -0,0 +1,34 @@ + + + + + + + + + django缓存 + + + + + + + + + diff --git a/notebook/docker.html b/notebook/docker.html new file mode 100644 index 0000000..7959671 --- /dev/null +++ b/notebook/docker.html @@ -0,0 +1,60 @@ + + + + + + + + + 2020/5/9 docKer 时区设置 + + + + + +

2020/5/9 docKer 时区设置

echo "Asia/Shanghai" > /etc/timezone
+dpkg-reconfigure -f noninteractive tzdata
+

如果没有tzdata,需要手动安装 apt-get install -y tzdata

docker

给容器换一个名字, 比如说 docker run -it --name=mycentos2 centos:7 /bin/bash, 可以解决问题. 将原来的容器删除

查询当前容器: docker container ls -all

删除当前容器: docker container rm mycentos(提示: 这一步要确定删除容器没问题的情况下, 才可以做)

Ubuntu 16.04 阿里源


+deb-src http://archive.ubuntu.com/ubuntu xenial main restricted #Added by software-properties
+deb http://mirrors.aliyun.com/ubuntu/ xenial main restricted
+deb-src http://mirrors.aliyun.com/ubuntu/ xenial main restricted multiverse universe #Added by software-properties
+deb http://mirrors.aliyun.com/ubuntu/ xenial-updates main restricted
+deb-src http://mirrors.aliyun.com/ubuntu/ xenial-updates main restricted multiverse universe #Added by software-properties
+deb http://mirrors.aliyun.com/ubuntu/ xenial universe
+deb http://mirrors.aliyun.com/ubuntu/ xenial-updates universe
+deb http://mirrors.aliyun.com/ubuntu/ xenial multiverse
+deb http://mirrors.aliyun.com/ubuntu/ xenial-updates multiverse
+deb http://mirrors.aliyun.com/ubuntu/ xenial-backports main restricted universe multiverse
+deb-src http://mirrors.aliyun.com/ubuntu/ xenial-backports main restricted universe multiverse #Added by software-properties
+deb http://archive.canonical.com/ubuntu xenial partner
+deb-src http://archive.canonical.com/ubuntu xenial partner
+deb http://mirrors.aliyun.com/ubuntu/ xenial-security main restricted
+deb-src http://mirrors.aliyun.com/ubuntu/ xenial-security main restricted multiverse universe #Added by software-properties
+deb http://mirrors.aliyun.com/ubuntu/ xenial-security universe
+deb http://mirrors.aliyun.com/ubuntu/ xenial-security multiverse
+
+

pip 国内源

pip3 install django==2.1 -i https://pypi.tuna.tsinghua.edu.cn/simple

cd ; mkdir .config ; cd .config ; mkdir pip ; cd pip ; vim pip.conf

[global]
+timeout = 6000
+index-url = http://mirrors.aliyun.com/pypi/simple/
+trusted-host = mirrors.aliyun.com
+
+
+ + + diff --git "a/notebook/graphql/ddd_graphql\346\225\260\346\215\256\346\265\201.html" "b/notebook/graphql/ddd_graphql\346\225\260\346\215\256\346\265\201.html" new file mode 100644 index 0000000..b5d2e2c --- /dev/null +++ "b/notebook/graphql/ddd_graphql\346\225\260\346\215\256\346\265\201.html" @@ -0,0 +1,37 @@ + + + + + + + + + ddd+graphql数据流 + + + + + +

ddd+graphql数据流

数据流 kong就是openresty的一个应用,nginx

前端 -> kong (解析token,装上user信息)->后端

-> controller层 ->resolve-> types -> graphql input -> 封装为command

-> 应用层-> mutation_service -> 调用各种domain、repo方法, -> domain 层, 领域方法 -> 调用domain层repo的方法(实现在infrastructure中),持久化到db

返回数据,在应用层中定义了各种Representation,可以序列化数据

与Django的映射: types = view之前的数据解析 apps = view

问题1:数据校验,唯一性校验应该db实现 问题2:数据默认值,应该在orm层实现,还是在app层实现 问题3:选择输入,如何判断输入数据有效性?

基础的,应该在domain的validate中定义,抛出ValueError即可
+复杂的,比如增加工段需要工序id,就需判断工序id是否存在,是否同一个租户下的,
+	这种应该在app层实现
+

问题4:关联关系时,db-orm只存储关联的id,那聚合根的model如何写? graphql的types怎么写?中间如何转换

+ + + diff --git "a/notebook/graphql/graphql\345\222\214python.html" "b/notebook/graphql/graphql\345\222\214python.html" new file mode 100644 index 0000000..77066ae --- /dev/null +++ "b/notebook/graphql/graphql\345\222\214python.html" @@ -0,0 +1,58 @@ + + + + + + + + + graphql和python + + + + + +

graphql和python

  1. graphql 定义 这里没有id这个东西, type ProductionGroup{ "班组ID" id: String! "班组名称" name: String! "班组长" groupLeader: Staff! "班组成员" groupMembers: [Staff!]! "备注" remark: String }

input CreateProductionGroupInput { name: String! groupLeader: StringIDInput! groupMembers: [StringIDInput!]! remark: String }

  1. 创建的流程

2.1 前端传递 group_leader: {id:"p1"}

然后types中收到这个input, 内容和gql中定义的一样

process: {"id":"p1"}

2.2 这时,解析给app层mutation.py中定义的command

class CreateGroupCommand(Command): tenant_id: str name: str group_leader: StringIDInput group_members: list[StringIDInput] remark: str | None

这里是command和graphql定义一样,还有一种是内部全部使用id,那么在这里就需要进行一些别名,包括内部的所有(聚合根,实体,orm,Representation)都带上id group_id: StringIDInput | None = Field(alias='group')

2.3 app层拿到command, 解析,并处理,构建Group对象

class Group(AggregateRoot): id: GroupId name: str tenant_id: TenantId group_leader: StaffId group_members: list[StaffId] remark: str | None

2.4 然后通过repo,将对象转换为orm对象,并保存到db

class GroupOrm(Base, TenantMixin, SoftDeleteMixin, TimeMixin): tablename = "group" entity = Group

id = sa.Column(sa.String, primary_key=True)
+name = sa.Column(sa.String)
+group_leader = sa.Column(sa.String)
+# 班组成员,不包含班组长
+group_members = sa.Column(ARRAY(sa.String), server_default="{}")
+# 班组人员字段,班组人员 包含班组长以及班组成员
+group_staffs = sa.Column(ARRAY(sa.String), server_default="{}")
+remark = sa.Column(sa.String)
+
+@classmethod
+def from_entity(cls, entity: Group):
+    orm_instance = entity.orm_instance() or cls()  # type: ignore
+    orm_instance.copy_from_entity(entity)
+    orm_instance.group_staffs = entity.group_members + [entity.group_leader]
+    return orm_instance
+

就此,创建流程结束

3 查询 3.1前端构建查询input,发送到types,转发给app层的queryService,得到filter字典、offset、limit、order_by """ 问题,这里filter的graphql定义也是不带id的,所以前端传过来StringIdInput,我们的filter类中,应当这样编写 """ class SectionFilter(FilterBase): search: str = FilterField(expression=lambda v: SectionOrm.name.like(f"%{v}%")) name: str = FilterField(column=SectionOrm.name) tenant_id: str = FilterField(column=SectionOrm.tenant_id) process: StringIDInput = FilterField(expression=lambda v: SectionOrm.process_ids.contains([v])) is_deleted: bool = FilterField(False, expression=lambda v: SectionOrm.is_deleted.is_(v))

3.2queryService 直接查询orm,并使用Representation返回给前端

class GroupRepresentation(Representation): id: str name: str group_leader: str group_members: list[str] remark: str | None

3.3 到达graphql层,controller根据types里的resolve,将对象进行解析,处理后返回给客户端

@managed() @dataclass class GroupType(ObjectType): name = "ProductionGroup"

@field_resolver("groupLeader")
+async def resolve_group_leader(self, parent: GroupRepresentation, info: GraphQLResolveInfo):
+    group_leader_id = get_attr(parent, "group_leader")
+    return {"id": group_leader_id}
+
+@field_resolver("groupMembers")
+async def resolve_group_members(self, parent: GroupRepresentation, info: GraphQLResolveInfo):
+    group_members = get_attr(parent, "group_members")
+    return [{"id": member_id} for member_id in group_members]
+
+ + + diff --git "a/notebook/graphql/graphql\351\201\207\345\210\260\350\277\207\347\232\204\351\227\256\351\242\230.html" "b/notebook/graphql/graphql\351\201\207\345\210\260\350\277\207\347\232\204\351\227\256\351\242\230.html" new file mode 100644 index 0000000..222791c --- /dev/null +++ "b/notebook/graphql/graphql\351\201\207\345\210\260\350\277\207\347\232\204\351\227\256\351\242\230.html" @@ -0,0 +1,51 @@ + + + + + + + + + graphql遇到过的问题 + + + + + +

graphql遇到过的问题

1.schema编写问题

正常情况下,需要在冒号右边加一个空格

type XXX{
+    
+    required: Boolean
+}
+
+

如果你不加的话,则会识别不到

http://spec.graphql.org/October2021/#sec-Language

2.dataload 问题

当有一个数据的resolve字段没查到,则所有的数据都不会返回

async def scheme_by_scheme_ids(self, scheme_ids: list[str]):
+    async with self.repo.new_session(expire_on_commit=False):
+        stmt = self.repo.select(MESSchemeOrm).filter(MESSchemeOrm.scheme_id.in_(scheme_ids))
+        result = await self.repo.all(stmt)
+        data = result.scalars().all()
+    return sort(scheme_ids, data, key_fn=attrgetter("scheme_id"))
+
@field_resolver("scheme")
+async def resolve_scheme(self, parent: ProcessRepresentation, info):
+    if process_id := get_attr(parent, "id"):
+        process_scheme_id = SchemeId(f"scheme:process:info:{process_id}")
+        loader = info.context["domain_loaders"]["scheme_by_scheme_ids"]
+        return await loader.load(process_scheme_id)
+
+ + + diff --git a/notebook/graphql/index.html b/notebook/graphql/index.html new file mode 100644 index 0000000..7e3539d --- /dev/null +++ b/notebook/graphql/index.html @@ -0,0 +1,34 @@ + + + + + + + + + 这里是notebook/graphql + + + + + + + + + diff --git a/notebook/index.html b/notebook/index.html new file mode 100644 index 0000000..8b92e3f --- /dev/null +++ b/notebook/index.html @@ -0,0 +1,34 @@ + + + + + + + + + 这里是notebook + + + + + + + + + diff --git a/notebook/k2p-luci.html b/notebook/k2p-luci.html new file mode 100644 index 0000000..b222d91 --- /dev/null +++ b/notebook/k2p-luci.html @@ -0,0 +1,43 @@ + + + + + + + + + k2p-luci + + + + + +

k2p-luci

20220206 今天发现k2p的后台管理web一些功能无法使用了

为了修复这个问题,先对路由器上的web程序做了一下了解

后台服务器:uhttp 语言 lua

root@K2P:/# find  . -type d -iname 'luci'
+./rom/usr/lib/lua/luci
+./usr/lib/lua/luci
+

https://blog.csdn.net/qq_28812525/article/details/103870169

find / -type f -name "*.lua" | xargs grep "portfwd_add_rule" 配置文件:

/etc/luci/*
+/etc/init.d/portfwd 端口转发的配置转换
+/etc/config/appportfwd 
+
+
+iptables -L -v -n
+

2022/6/1

k2p动态ip失效

鸟哥的私房菜 http://cn.linux.vbird.org/linux_server/0250simple_firewall_5.php#nat_ip_share

iptables -t nat -A PREROUTING -i pppoe-wan -p tcp --dport 36000 -j DNAT --to-destination 192.168.2.190:22

iptables -t nat -L

+ + + diff --git "a/notebook/k2p_\346\233\264\346\226\260\345\256\230\346\224\271\345\233\272\344\273\266v1.9\344\270\255\347\232\204ssr-server.html" "b/notebook/k2p_\346\233\264\346\226\260\345\256\230\346\224\271\345\233\272\344\273\266v1.9\344\270\255\347\232\204ssr-server.html" new file mode 100644 index 0000000..19bb183 --- /dev/null +++ "b/notebook/k2p_\346\233\264\346\226\260\345\256\230\346\224\271\345\233\272\344\273\266v1.9\344\270\255\347\232\204ssr-server.html" @@ -0,0 +1,51 @@ + + + + + + + + + [k2p]更新官改固件v1.9中的ssr-server + + + + + +

[k2p]更新官改固件v1.9中的ssr-server

目标:在k2p路由器上搭建ssr-server,在外网可以访问到家中的设备

遇到的问题:k2p官改固件v1.9 使用的ssr-server版本是shadowsocks-libev 2.5.6 with OpenSSL 1.0.1j 15 Oct 2014,支持的加密协议比较少

网络上比较推荐的加密算法是aes-256-gcm,打算更新路由器上的ssr-server

先到github https://github.com/shadowsocks/shadowsocks-libev 需要我们需要的安装包

root@K2P:~# cat /proc/version
+Linux version 3.10.14 (jenkins@SOHO-OPWRT) (gcc version 4.8.3 (OpenWrt/Linaro GCC 4.8-2014.04 unknown) ) #1 SMP Fri Apr 20 15:17:54 CST 2018
+

通过上面的命令,我们可以知道k2p官改是openwrt系列的系统,找到适用于openwrt的版本 https://github.com/shadowsocks/openwrt-shadowsocks

这个项目提供了预编译文件下载,我们到releases页面,进行下载 http://openwrt-dist.sourceforge.net/archives/shadowsocks-libev/3.3.5-1/

然后查看k2p的架构,我的k2p是a2版本,cpu是mt6621a,架构为mips 1004kc

但是我们并没有找到适合1004kc的软件包

经过google搜索,我在恩山无线论坛找到了解决方案:使用mips 24kc即可,是兼容的 https://www.right.com.cn/forum/thread-256669-1-1.html

使用wget 下载到/tmp目录后,我们使用opkg install shadowsocks-libev-server_3.3.5-1_ramips_24kec.ipk命令进行安装,发现opkg报错:pkg_hash_fetch_best_installation_candidate: Packages for shadowsocks-libev-server found, but incompatible with the architectures configured

这是因为opkg发现此安装包声明的架构与系统支持的架构不符,我们使用opkg print-architecture命令输出该系统支持的安装包

可以看到没有ramips_24kc

经google搜索,找到了解决方案

https://www.twblogs.net/a/5c766b60bd9eee339917f838 http://iotts.com.cn/blog/2020/12/13/OpenWrt-%E6%89%8B%E5%8A%A8%E5%AE%89%E8%A3%85ipk%E6%97%B6%E9%81%87%E5%88%B0%E7%9A%84%E9%97%AE%E9%A2%98/ https://blog.csdn.net/zengqz123/article/details/87915079


+vi /etc/opkg.conf
+然后在这个文件后面依次添加
+arch all 100
+arch ramips 150
+arch ramips_24kec 200
+arch ramips_1004kc 300
+

ok,再次尝试安装,发现缺少依赖

回到下载页面 http://openwrt-dist.sourceforge.net/archives/shadowsocks-libev/3.3.5-1/legacy/ramips/ 其实都在这里

wget http://openwrt-dist.sourceforge.net/archives/shadowsocks-libev/3.3.5-1/legacy/ramips/libev_4.27-1_ramips_24kec.ipk
+wget http://openwrt-dist.sourceforge.net/archives/shadowsocks-libev/3.3.5-1/legacy/ramips/libcares_1.15.0-4_ramips_24kec.ipk
+wget http://openwrt-dist.sourceforge.net/archives/shadowsocks-libev/3.3.5-1/legacy/ramips/libsodium_1.0.18-1_ramips_24kec.ipk
+wget http://openwrt-dist.sourceforge.net/archives/shadowsocks-libev/3.3.5-1/legacy/ramips/libmbedtls_2.9.0-2_ramips_24kec.ipk
+
+

安装成功

后面的错误信息其实无影响,安装后,可通过opkg查看文件信息

root@K2P:/tmp# opkg files shadowsocks-libev-server
+Package shadowsocks-libev-server (3.3.5-1) is installed on root and has the following files:
+/usr/bin/ss-server
+

安装成功!,aes-256-gcm可用

opkg命令(https://www.cxymm.net/article/qq_41453285/102523263) 修改opkg.conf (https://www.twblogs.net/a/5c766b60bd9eee339917f838) openwrt翻墙教程 https://fanqiang.software-download.name/

https://me2in.github.io/2020/11/30/%E5%9B%9E%E5%AE%B6%E7%9A%84%E8%AF%B1%E6%83%91-%E8%AE%BA%E5%A6%82%E4%BD%95%E6%9B%B4%E4%BC%98%E9%9B%85%E7%9A%84%E5%9B%9E%E5%AE%B6/

clash for windows https://docs.cfw.lbyczf.com/

cfw默认跳过内网地址

+ + + diff --git a/notebook/kodi.html b/notebook/kodi.html new file mode 100644 index 0000000..fca261f --- /dev/null +++ b/notebook/kodi.html @@ -0,0 +1,34 @@ + + + + + + + + + kodi + + + + + +

kodi

打造家庭影院

NAS

NAS(Network Attached Storage:网络附属存储)按字面简单说就是连接在网络上,具备资料存储功能的装置,因此也称为“网络存储器”。它是一种专用数据存储服务器。它以数据为中心,将存储设备与服务器彻底分离,集中管理数据,从而释放带宽、提高性能、降低总拥有成本、保护投资。其成本远远低于使用服务器存储,而效率却远远高于后者。目前国际著名的NAS企业有Netapp、EMC、OUO等。

HTPC

HTPC(Home Theater Personal Computer),即家庭影院电脑。 是以计算机担当信号源和控制的家庭影院,也就是一部预装了各种多媒体解码播放软件,可用来对应播放各种影音媒体,并具有各种接口,可与多种显示设备如电视机、投影机、等离子显示器、音频解码器、音频放大器等音频数字设备连接使用的个人电脑。

官网链接open in new window

家庭网络

品名价格功能备注时间
斐讯K2P¥150做路由,wifi,拨号挂v2ray
联通光猫300M网速
TCL 65v62999看电视,播放电影支持memc2019.10.3
电脑1200下载机器,htpc2020.1.2
斐讯N1盒子130刷yyf, 使用, kodi,千兆网口, usb2.02020.2.20
斐讯H1移动硬盘230移动存储,做N1盒子上面的存储type-c接口,usb3.02020.2.21

场景需求

  • [x] 玩游戏: 显示器hdmi线连接客厅电视,或者游戏机
  • [ ] 看视频: 电视内置软件, 投屏, kodi,
  • [ ] 照片备份:

我不在家

  • 使用HDP直播等软件播放CCTV等节目
  • 手机投屏(乐播投屏)

我在家

  • 使用远程下载下载到硬盘, 然后观看
  • 同步照片
  • 作为服务器,通过frp做远程服务器

插线板

名字价格功能
斐讯 tc1¥656 插口, 3usb(1*18w)
心水: 紫米插座1291个pd65w快充的插口+插线版

电脑

配件型号价格备注时间
cpug5500¥200二手
主板h310cm-hdvopen in new window¥300千兆
内存光威8g 2666open in new window¥169
固态铁甲战将120gopen in new window¥119
硬盘西数蓝盘500g¥0
鼠标&键盘罗技套装 mk275open in new window¥60
机箱先马 黑金刚open in new window¥135
散热器超频三 红海open in new window¥32
电源金河田 300wopen in new window¥99
合计¥1133

|设备|

+ + + diff --git "a/notebook/linux\345\205\263\351\227\255\350\256\277\351\227\256\346\227\245\345\277\227\345\217\212mysql.html" "b/notebook/linux\345\205\263\351\227\255\350\256\277\351\227\256\346\227\245\345\277\227\345\217\212mysql.html" new file mode 100644 index 0000000..71f6bd5 --- /dev/null +++ "b/notebook/linux\345\205\263\351\227\255\350\256\277\351\227\256\346\227\245\345\277\227\345\217\212mysql.html" @@ -0,0 +1,36 @@ + + + + + + + + + 日志 + + + + + +

日志

关闭.bash_history

已经在Ubuntu 16.04.6 LTS验证有效

我们可以修改/etc/profile文件中修改2个参数来控制历史命令记录和输出。

echo "export HISTFILESIZE=0" >> /etc/profile
+source /etc/profile
+
  1. https://www.cndba.cn/dave/article/4086
  2. https://blog.csdn.net/smasegain/article/details/46678113

关闭mysql连接日志

  1. ~/.mysql_history

https://www.cnblogs.com/milantgh/p/3602206.html

如何关闭MySQL的日志功能:删除日志:执行:/usr/local/mysql/bin/mysql -u root -p 输入密码登录后再执行:reset master; 再输入:quit 退出mysql命令模式。 彻底禁用MySQL日志:修改/etc/my.cnf 文件, 找到log-bin搜索=mysql-binbinlog_format=mixed再这两行前面加上#, 将其注释掉,再执行/etc/init.d/mysql restart即可。 或直接去目录/usr/local/mysql/var/删除日志文件即可正常使用! ———————————————— 版权声明:本文为CSDN博主「风火程序员」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/phpfenghuo/article/details/42262031

编辑 /etc/mysql/mysql.conf.d/mysqld.cnf

关闭SSH日志

编辑/etc/ssh/sshd_config

/var/log/syslog 没有这个文件

正常登录 Mar 23 03:10:40 ubuntu systemd[1]: Started Session 7 of user homepc.

grep sshd /var/log/auth.log

https://www.cnblogs.com/sparkdev/p/7694202.html

ssh远程登陆日志分析open in new window

[root@master ~]# vim /etc/ssh/sshd_config #SyslogFacility AUTH SyslogFacility AUTHPRIV #LogLevel INFO 改 SyslogFacility local1

更改日志服务配置 [root@master ~]# vim /etc/rsyslog.conf #sign local1.* /var/log/sshd.log //这里该成空,就可以全删除了

+ + + diff --git "a/notebook/linux\345\255\246\344\271\240.html" "b/notebook/linux\345\255\246\344\271\240.html" new file mode 100644 index 0000000..b78deb4 --- /dev/null +++ "b/notebook/linux\345\255\246\344\271\240.html" @@ -0,0 +1,42 @@ + + + + + + + + + linux学习 + + + + + +

linux学习

删除含有行的文件


+sed -e '/abc/d'  clickhouse-server.log  > a.log 
+chown clickhouse:clickhouse a.log
+chmod 640 a.log
+mv a.log clickhouse-server.log
+service clickhouse-server reload
+
+
+

软连接 2020/4/20

Usage: ln [OPTION]... [-T] TARGET LINK_NAME (1st form) or: ln [OPTION]... TARGET (2nd form) or: ln [OPTION]... TARGET... DIRECTORY (3rd form) or: ln [OPTION]... -t DIRECTORY TARGET... (4th form) In the 1st form, create a link to TARGET with the name LINK_NAME. In the 2nd form, create a link to TARGET in the current directory. In the 3rd and 4th forms, create links to each TARGET in DIRECTORY. Create hard links by default, symbolic links with --symbolic. By default, each destination (name of new link) should not already exist. When creating hard links, each TARGET must exist. Symbolic links can hold arbitrary text; if later resolved, a relative link is interpreted in relation to its parent directory.

删除所有以.log结尾的文件 20200806

find ./ -name "*.log" -exec rm {} ;

+ + + diff --git "a/notebook/mac_win10\345\217\214\347\263\273\347\273\237\344\270\213\347\232\204\346\227\266\351\227\264\351\227\256\351\242\230.html" "b/notebook/mac_win10\345\217\214\347\263\273\347\273\237\344\270\213\347\232\204\346\227\266\351\227\264\351\227\256\351\242\230.html" new file mode 100644 index 0000000..923b11d --- /dev/null +++ "b/notebook/mac_win10\345\217\214\347\263\273\347\273\237\344\270\213\347\232\204\346\227\266\351\227\264\351\227\256\351\242\230.html" @@ -0,0 +1,37 @@ + + + + + + + + + mac+win10双系统下的时间问题 + + + + + +

mac+win10双系统下的时间问题

安装了 Windows/macOS 双系统的同学,一定遇到过双系统时间不同步的问题。具体表现是,一旦进入过 macOS 系统,Windows 中的时间就会比实际时间慢8个小时(以国内为准)。

解决问题

遇到这个问题,我第一个想法是编辑计划任务,在windows系统开机的时候执行时间同步(因为windows默认是7天与时间服务器同步一次)

具体的逻辑是开机后,识别到wifi连接上事件(id8001),则执行与时间服务器同步的脚本

首先是定位到wifi连接上的事件,打开事件查看器, 应用程序和服务日志-Microsoft-Windows-WLAN-AutoConfig 可以看到下图,我们找到8001事件,他的描述是WLAN 自动配置服务已成功连接到无线网络

我整理了一下,大概有7个事件

事件8000 WLAN 自动配置服务已开始连接无线网络。 事件8001 WLAN 自动配置服务已成功连接到无线网络。 事件8003 WLAN 自动配置服务已成功从无线网络断开。 事件8005 WLAN 自动配置服务已开始启动承载网络。 事件8006 WLAN 自动配置服务已完成启动承载网络。 事件8008 WLAN 自动配置服务已开始停止承载网络。 事件8011 连接到上一个正常网络

按照字面意思,我们应该使用8011事件作为触发器,但是查阅日志发现,最近几天我重启了好几次wifi,但是只有一次8011事件,可能有其他的因素在里面,我们还是选择事件8001作为触发器把。

在计算机管理-任务计划程序-新建计划任务,编辑触发器

下面是更新系统时间的vbs代码,保存在本地后,新建执行程序

Set ws = CreateObject("Wscript.Shell") 
+ws.Run "net start w32time",vbhide,true
+ws.Run "w32tm /resync",vbhide
+

注意要勾选常规选项卡中的使用最高权限运行

部署好后,每次启动笔记本,连接上wifi,时间就会自动同步到最新时间

遇到的问题

我开启了无线投屏,所以每次开机都会开放一个热点,然后系统自动连接上去,此时还没有连接到网络,所以同步失败,而且由于设置了重试和按需运行,导致3分钟连接到有网络的wifi并不会同步时间(因为按需运行)

20220207 时间不同步的真正原因

问题的成因是Windows和macOS处理时间的方式不同:

Windows把系统硬件时间当作本地时间(Local Time),即操作系统中显示的时间和 BIOS 中显示的时间是一样的 macOS 则把硬件时间当作 UTC,操作系统中显示的时间是硬件时间经过换算得来的,例如:假设 macOS 中设置了东八区时区,系统显示时间早上9:00,实际硬件储存时间就是UTC 1:00。这个时候重启进入 Windows,时间就变成了早上1:00。

办法也很简单,就是让Windows把硬件时间当作 UTC 时间,保持和 macOS 一致。

Window7 用户点击左下角 开始 -> 运行 -> 输入CMD

Window8/10用户按下 Win+X 组合键,使用管理员模式进入CMD

输入以下命令: Reg add HKLM\SYSTEM\CurrentControlSet\Control\TimeZoneInformation /v RealTimeIsUniversal /t REG_DWORD /d 1

不过看来这样bios时间又会出问题,所以我还是使用我的土方法把

2022020 使用intel连接设置

今天在发现局域网samba传输速度只有5MB, 于是点开了网络设置,发现使用intel设置可以实现连接到特定wifi后执行应用程序

路径为 控制面板-网络连接-选中你当前连接的WLAN-状态-无线属性-

+ + + diff --git "a/notebook/markdown\345\255\246\344\271\240.html" "b/notebook/markdown\345\255\246\344\271\240.html" new file mode 100644 index 0000000..442f6b2 --- /dev/null +++ "b/notebook/markdown\345\255\246\344\271\240.html" @@ -0,0 +1,51 @@ + + + + + + + + + markdown学习 + + + + + +

markdown学习

用HTML代码中的<br>
+
+如下所示,要在“身高”换行后加“体重”,可以在本行末尾输入<br>,再输入“体重”,则马上换行显示。
+
+
+
+假设我们想跳转到文档中的一个不是标题的位置(比如一张图表),则需要在该位置自定义一个锚。
+
+我们使用HTML语法来定义一个锚。可选的HTML标签很多,比如<span>、<a>等等。本文使用<span>示例。
+
+假设文档中有一个作息时间表,在文档的其他地方需要增加跳转到此表位置的链接,那么我们可以在此表的附近增加一行:
+
+<span id=”表1”>名称</span>
+
+
+
+
+

WARNING

here be dragons

::: alert-warning

alert-warning 黄色

:::

::: alert-info

alert-info 蓝色

:::

::: alert

alert-error 红色

:::

WARNING: be careful to baz the quux before initializing the retro encabulator!

⚠️ If you are using mobile browser: Be very careful here!

+ + + diff --git "a/notebook/n1\347\233\222\345\255\220_\344\275\277\347\224\250n1\347\233\222\345\255\220\344\273\245\345\217\212\347\275\227\346\212\200\346\221\204\345\203\217\345\244\264\350\277\233\350\241\214\347\233\264\346\222\255.html" "b/notebook/n1\347\233\222\345\255\220_\344\275\277\347\224\250n1\347\233\222\345\255\220\344\273\245\345\217\212\347\275\227\346\212\200\346\221\204\345\203\217\345\244\264\350\277\233\350\241\214\347\233\264\346\222\255.html" new file mode 100644 index 0000000..2e748ad --- /dev/null +++ "b/notebook/n1\347\233\222\345\255\220_\344\275\277\347\224\250n1\347\233\222\345\255\220\344\273\245\345\217\212\347\275\227\346\212\200\346\221\204\345\203\217\345\244\264\350\277\233\350\241\214\347\233\264\346\222\255.html" @@ -0,0 +1,34 @@ + + + + + + + + + [n1盒子]使用n1盒子以及罗技摄像头进行直播 + + + + + +

[n1盒子]使用n1盒子以及罗技摄像头进行直播

方式1 ffserver 然后使用

ffmpeg -f v4l2 -i /dev/video1 -s 640x480 -r 24 -vcodec libx264 -an http://127.0.0.1:8090/feed1.ffm

把video1串流到ffm文件

之后使用播放器访问 rtsp://192.168.2.190:8554/live1.h264

使用webrtc转发 设备到web(未实现) docker run -p 8000:8000 -it mpromonet/webrtc-streamer -n raspicam -u rtsp://192.168.2.190:8554/live1.h264

方式2 通过vlc

cvlc --no-audio v4l2:///dev/video1 --v4l2-width 1920 --v4l2-height 1080 --v4l2-chroma h264 --v4l2-fps 30 --v4l2-hflip 1 --v4l2-vflip 1 --sout "#transcode{vcodec=mjpg,vb=25,scale=1.0,fps=24,acodec=none}:standard{access=http{mime=multipart/x-mixed-replace; boundary=7b3cc56e5f51db803f790dad720ed50a},mux=mpjpeg,dst=:8554/videostream.cgi}"

v4l2:///dev/video1:width=1920:height=1080:fps=30:chroma=MJPG:live-caching=300 --sout "#transcode{vcodec=mjpg,vb=25,scale=1.0,fps=24,acodec=none}:standard{access=http{mime=multipart/x-mixed-replace; boundary=7b3cc56e5f51db803f790dad720ed50a},mux=mpjpeg,dst=:8554/videostream.cgi}" 直接打开 8554端口即可

方式3 motion

修改下配置文件,设置局域网访问即可

vlc v4l2:///dev/video1 --sout "#std{access=http,mux=mpjpeg,dst=:8554/videostream.cgi}"

方式4 mjpg-streamer

这种方式只能推送图片,优点是延迟底,以及不需要安装软件,浏览器访问即可

+ + + diff --git a/notebook/nginx.html b/notebook/nginx.html new file mode 100644 index 0000000..62c2077 --- /dev/null +++ b/notebook/nginx.html @@ -0,0 +1,141 @@ + + + + + + + + + nginx简洁 + + + + + +

nginx简洁

nginx是一个反向代理服务器,同时也是一个轻量的web服务器(php要配置php) 在一台服务器上,我们可以在不同的端口开设web服务,以 ip:port 的形式访问,但是这是不好看的 如果你有一个已经备案的域名,则可以在域名服务商处设置隐形url, 将二级域名转发到ip:port 如果你的服务器在国外,同时域名没有备案, 可以通过nginx来设置二级域名,

2022-2-6 nginx图片分层

存储大量图片时,可能会遇到linux文件夹文件数量的限制 我所使用的方案:保存图片时按照图片的md5前四位建立二级目录,例如md5为abcdefgxxx ,则保存后的文件目录为 /www/static/images/ab/cd/abcdefgxxx 然后使用nginx正则去获取文件的前四位


+location ~ ^/static/images/((..)(..).+) {
+    set $dir1 $2;
+    set $dir2 $3;
+    set $filename $1;
+    default_type image/jpeg;
+    alias /www/static/images/$dir1/$dir2/;
+    try_files $filename =404;
+}
+
+
+

nginx作为静态资源服务器

https://www.w3cschool.cn/nginxsysc/nginxsysc-cache.html

nginx简单操作


+//检测编写的配置文件是否有语法错误
+nginx -t 
+// 热重启nginx (nginx不重启的情况下重新加载配置文件)
+nginx -s reload  
+
+

通过nginx设置二级域名

首先, 需要在域名服务商处将 *.your.domain 解析到你的服务器

然后安装nginx服务,具体不细说

在/etc/nginx/conf.d 文件夹下新建 test.conf文件

假设你要将本机 3456端口的内容设置到blog这个二级域名

server_name 二级域名 proxy_pass 写你本机的地址

配置文件编写如下

server {
+  listen 80;
+  server_name blog.moyechen.cn;
+
+  location / {
+    proxy_set_header  X-Real-IP $remote_addr;
+    proxy_set_header  Host   $http_host;
+    proxy_pass     http://0.0.0.0:3456;
+  }
+}
+

nginx作为轻量的web服务器

root那里写web页面的路径
index写主页文件.可以多个

server {
+    listen       80;
+    server_name  scs.moyechen.cn;
+
+    index       index.html index.php;
+    root         /root/src/cnn/conv/;
+    location / {
+    proxy_set_header  X-Real-IP $remote_addr;
+    proxy_set_header  Host   $http_host;
+  }
+}
+

带PHP的页面

需要我们本地安装有PHP服务,然后设置一下PHP服务即可

server {
+    listen       80 default_server;
+    listen       [::]:80 default_server;
+    server_name  acm.moyechen.cn;
+
+    index       index.php;
+    root         /home/judge/src/web;
+
+    location / {
+
+    }
+    location ~ \.php$ {
+            fastcgi_index               index.php;
+            fastcgi_pass                127.0.0.1:9000;
+            fastcgi_param               SCRIPT_FILENAME $document_root$fastcgi_script_name;
+            fastcgi_split_path_info     ^(.+\.php)(/.+)$;
+            client_max_body_size        80m;
+            include                     fastcgi_params;
+    }
+}
+

直接偷别人的页面

但是好像不能登陆,可能是https导致的

server {
+  listen 80;
+  server_name vj.moyechen.cn;
+
+  location / {
+    proxy_set_header  X-Real-IP $remote_addr;
+    proxy_set_header  Host   $http_host;
+    proxy_pass     https://vjudge.net;
+  }
+}
+

frps 简单配置

server {
+    listen 80;
+    server_name *.frp.moyechen.cn;
+    location / {
+        proxy_pass http://127.0.0.1:7080;
+        proxy_set_header    Host            $host:80;
+        proxy_set_header    X-Real-IP       $remote_addr;
+        proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;
+        proxy_hide_header   X-Powered-By;
+    }
+}
+server {
+    listen 80;
+    server_name frp.moyechen.cn;
+    location / {
+        proxy_pass http://127.0.0.1:7500;
+        proxy_set_header    Host            $host:80;
+        proxy_set_header    X-Real-IP       $remote_addr;
+        proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;
+        proxy_hide_header   X-Powered-By;
+    }
+}
+

国内服务器如何不备案放到域名上

如果国内服务器不备案,并且被一个域名指向,那么几天后你访问就会出现需要备案的标记

我们可以用一台国外服务器来做中转,注意端口最好不要使用80以及443等常用端口
不然好像还会被封

假设国内服务器ip为 xxx.xxx.xxx.xxx 假设web服务开设在国内服务器5678端口

  • 第一步, 在域名服务商设置你的域名解析到国外服务器的ip
  • 第二步, 设置中转机器

中转机器配置信息:

server {
+  listen 80;
+  server_name 写你的域名;
+
+  location / {
+    proxy_set_header  X-Real-IP $remote_addr;
+    proxy_set_header  Host   $http_host;
+    proxy_pass     http://xxx.xxx.xxx.xxx:5678;
+  }
+}
+
+

那既然有国外服务器了,为什么还要用国内服务器开设web页面呢? 我也不知道

nginx日志审计

统计访问IP前十

awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -10

统计状态码

awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -10

nginx 安全

账户验证

在linux中,如果不安装apache,但是又需要用htpasswd生成登录账号,如:配置Nginx,pure-ftpd,subversion等。

那就需要找一个替代htpasswd生成密码的方法,用openssl就可以办到

# printf "user:$(openssl passwd -crypt 123456)\n" >>conf/.htpasswd
+# cat conf/htpasswd
+

===结果=== user:xyJkVhXGAZ8tM

这样就生成了一个用户名为user,密码为123456的账号了。

server {
+         auth_basic      "login";
+         auth_basic_user_file    conf/.htpasswd;
+}
+
+ + + diff --git a/notebook/oceanus.html b/notebook/oceanus.html new file mode 100644 index 0000000..e07bd19 --- /dev/null +++ b/notebook/oceanus.html @@ -0,0 +1,45 @@ + + + + + + + + + oceanus + + + + + +

oceanus

操作步骤

  1. oceaus 平台建表, 包括海力方表和ch表, 其中要注意ch表写入时间(一般60)和写入量(10000+)
  2. 新建任务
  3. 申请资源
  4. 运行任务

问题汇总

问题1

复制海力方表的tid过去后, 自动填充的字段类型有错误,需要手动检查修改

问题2

类型正确后, 启动任务不闪退了,但是没数据, 查看日志发现连接本地ch数据库出了问题 3. 通过百度了解到tcp端口为9000, 默认的http端口为8123, 但是我这里是修改过的, 因此是8080

修改为自定义的8080端口, ok

问题3:

使用select count(*) 查询数据量正常, 但是select sum(rows) 显示的数量要大的多

查找后发现是因为数据写入太快, 导致分区过多 可以看到前几天的数据都是一个分区, 这是ch后台合并的结果

但是查看当天的数据, 发现分了好多区,并且每一块都很小

发现是写入es批量太小, 且写入太快导致的

  1. 增大批量写条目数, 设置为100000(默认为1000), 如果表过大, 可调整
  2. 增大flush时间间隔 设置为60s(默认为1) https://oceanus.oa.com/#/table/list

优化前

优化后 优化后 查询语句

SELECT 
+    table,
+    partition,
+    sum(rows) AS row
+FROM system.parts
+WHERE (database = 'situation_awareness') AND (table = 'weilidai_antiCollection_socialUniformity_oceanus')
+GROUP BY 
+    table,
+    partition
+    WITH TOTALS
+ORDER BY partition ASC
+

问题4 数据消费问题

需设置savepoint, 防止重启任务时中间数据丢失问题

问题5 导出至clickhouse数据库

官方文档中有说明, 只有1.14版本支持导出

https://iwiki.woa.com/pages/viewpage.action?pageId=746586889

https://iwiki.woa.com/pages/viewpage.action?pageId=703323873

+ + + diff --git "a/notebook/teg\344\272\211\351\234\270\350\265\233.html" "b/notebook/teg\344\272\211\351\234\270\350\265\233.html" new file mode 100644 index 0000000..39e0423 --- /dev/null +++ "b/notebook/teg\344\272\211\351\234\270\350\265\233.html" @@ -0,0 +1,256 @@ + + + + + + + + + teg争霸赛 + + + + + +

teg争霸赛

第一关 刷到10000

直接返回a 即可

第二关

看js 返回a*a+a 即可

第三关 20201021

将js看懂后改写


+window = {}
+
+var bl5 = ['A5473788'];
+(function (bl1, bl2) {
+    var bl4 = function (bl3) {
+        while (--bl3) {
+            bl1['push'](bl1['shift']());
+        }
+    };
+    bl4(++bl2);
+}(bl5, 496));
+
+
+var _0x23fc = function (bl1, bl2) {
+    bl1 = bl1 - 0x0;
+    var bl4 = bl5[bl1];
+    return bl4;
+};
+
+window[_0x23fc('0x0')] = function (bl6) {
+    var bl9 = 199999;
+
+    for (var bl8 = 0; bl8 < 199999; bl8++) {
+        var bl7 = 0;
+        //for (var bl10 = 0; bl10 < bl8; bl10++) {
+        //  bl7 += bl6['a'][0];
+        //} 这里循环删掉
+        bl7 += bl6['a'][0] * bl8;
+
+        if (bl7 % bl6['a'][2] == bl6['a'][1] && bl8 < bl9) {
+            bl9 = bl8
+            break
+        }
+    }
+    return bl9;
+};
+
+console.log(window.A5473788)
+
+

第四关 20201022

原始代码直接放node里面, 报错,

一点点剥皮后发现node 里没有window 对象, 加上即可


+window = {}
+
+window.setTimeout = setTimeout
+
+window.A593C8B8 = async (b106) => (($, b106, b105, b104, b103) => {
+
+    let b102 = function* () {
+        while ([]) yield[    (b106, b105) => b106 + b105, (b106, b105) => b106 - b105, (b106, b105) => b106 * b105]   [++b105 % 3]['bind'](0, b104, b103)
+    }();
+
+    let b101 = function (b102, b101, b100) {
+        b103 = b102;
+        b104 = b101["next"]()['value']();
+
+        b105 == b106['a']["length"] && b100(-b104)
+
+    };
+    // return new Promise(b105 => b106['a']['forEach'](b104 => $["setTimeout"](b103 => b101(b104, b102, b105), b104)))
+
+
+    return new Promise(b105 => {
+
+        b106['a']['forEach'](b104 => {
+            setTimeout(b103 => {
+                b101(b104, b102, b105)
+            },b104/50)
+
+        })
+
+    })
+
+})(window, b106, 0, 0, 0)
+
+

可以运行,但是很慢, 搞懂后, 在延时处 b104/50 即可

第五关 20201023

这关用的wasm

https://www.wasm.com.cn/docs/semantics/


+(module
+  (func $Math.min (;0;) (import "Math" "min") (param i32 i32) (result i32))
+  (func $Math.max (;1;) (import "Math" "max") (param i32 i32) (result i32))
+  (func $Run (;2;) (export "Run") (param $var0 i32) (param $var1 i32) (result i32)
+    (local $var2 i32) (local $var3 i32) (local $var4 i32) (local $var5 i32) (local $var6 i32) (local $var7 i32)
+    local.get $var0
+    local.set $var2
+    local.get $var1
+    i32.const 1
+    i32.sub
+    local.tee $var4
+    if
+      loop $label1
+        local.get $var2
+        local.set $var3
+        i32.const 0
+        local.set $var6
+        i32.const 10
+        local.set $var7
+        loop $label0
+          local.get $var3
+          i32.const 10
+          i32.rem_u
+          local.set $var5
+          local.get $var3
+          i32.const 10
+          i32.div_u
+          local.set $var3
+          local.get $var5
+          local.get $var6
+          call $Math.max
+          local.set $var6
+          local.get $var5
+          local.get $var7
+          call $Math.min
+          local.set $var7
+          local.get $var3
+          i32.const 0
+          i32.gt_u
+          br_if $label0
+        end $label0
+        local.get $var2
+        local.get $var6
+        local.get $var7
+        i32.mul
+        i32.add
+        local.set $var2
+        local.get $var4
+        i32.const 1
+        i32.sub
+        local.tee $var4
+        br_if $label1
+      end $label1
+    end
+    local.get $var2
+  )
+)
+
+

https://github.com/WebAssembly/wabt

wasm 转c, 然后编译时加上 Ofast 优化 即可

gcc a.c -o a.out -Ofast


+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+ unsigned max(unsigned a,unsigned b){
+     if (a>b)
+     return a;
+     else return b;
+ }
+
+ unsigned min(unsigned a,unsigned b){
+     if (a<b)
+     return a;
+     else return b;
+ }
+ 
+
+int _Run(int _p0, int _p1) {
+  int _l2 = 0, _l3 = 0, _l4 = 0, _l5 = 0, _l6 = 0, _l7 = 0;
+//   FUNC_PROLOGUE;
+  int _i0, _i1, _i2;
+
+  
+  _l2 = _p0;
+  _i0 = _p1;
+  _i1 = 1u;
+  _i0 -= 1;
+  _l4 = _i0;
+  if (_i0) {
+    //   printf("i0 = %d\n",_i0);
+    _L1: 
+    
+      _i0 = _l2;
+      _l3 = _i0;
+      _i0 = 0u;
+      _l6 = _i0;
+      _i0 = 10u;
+      _l7 = _i0;
+      _L2: 
+    //   printf("i0 = %d\n",_i0);
+        _i0 = _l3;
+        _i1 = 10u;
+        // _i0 = REM_U(_i0, _i1);  //有符号求余数
+        _i0 = _i0 % _i1;
+        _l5 = _i0 ;
+        _i0 = _l3;
+        _i1 = 10u;
+        // _i0 = DIV_U(_i0, _i1);  //向下整除
+        _i0 = _i0 / _i1; 
+        _l3 = _i0;
+        _i0 = _l5;
+        _i1 = _l6;
+        _i0 = max(_i0, _i1);
+        _l6 = _i0;
+        _i0 = _l5;
+        _i1 = _l7;
+        _i0 = min(_i0, _i1);
+        _l7 = _i0;
+        _i0 = _l3;
+        _i1 = 0u;
+        _i0 = _i0 > _i1;
+        if (_i0) {goto _L2;}
+      _i0 = _l2;
+      _i1 = _l6;
+      _i2 = _l7;
+      _i1 *= _i2;
+      _i0 += _i1;
+      _l2 = _i0;
+      _i0 = _l4;
+      _i1 = 1u;
+      _i0 -= _i1;
+      _l4 = _i0;
+      if (_i0) {goto _L1;}
+  }
+  _i0 = _l2;
+//   FUNC_EPILOGUE;
+  return _i0;
+}
+
+int main( int argc, char *argv[]){
+    // int dd = _Run(211814391, 6301083);    
+    // printf("%s,%s",argv[1],argv[2]);
+    int dd = _Run(atoi(argv[1]),atoi(argv[2]));    
+    //211814400
+    printf("%d",dd);
+
+    return 0;
+}
+
+
+ + + diff --git "a/notebook/url\351\207\215\345\256\232\345\220\221.html" "b/notebook/url\351\207\215\345\256\232\345\220\221.html" new file mode 100644 index 0000000..9866b70 --- /dev/null +++ "b/notebook/url\351\207\215\345\256\232\345\220\221.html" @@ -0,0 +1,34 @@ + + + + + + + + + url + + + + + + + + + diff --git "a/notebook/vscode\346\233\277\344\273\243codeblock.html" "b/notebook/vscode\346\233\277\344\273\243codeblock.html" new file mode 100644 index 0000000..c0fd73d --- /dev/null +++ "b/notebook/vscode\346\233\277\344\273\243codeblock.html" @@ -0,0 +1,41 @@ + + + + + + + + + vscode替代codeblocks + + + + + +

vscode替代codeblocks

时间作者
2020/2/16 16:54moyechen

code block 这款ide在acm比赛中非常常见, 但是鉴于本人有以下需求

  • 代码补全
  • 一个方便的文件管理树
  • 自定义代码模板
  • 编译后生成的可执行文件(.exe) 定时清理

因此,本人折腾了文本编辑器 -- vscode

准备工作

首先下载vscode

官网链接: https://code.visualstudio.com/

接着,将编译器的目录添加到环境变量 如果你有code::blocks 可以参考以下:

打开code::blocks

复制蓝色内容,然后加上\bin

例如 C:\Program Files (x86)\CodeBlocks\MinGW\bin , 记为compiler_path变量

接着,添加到系统环境变量

这里, 第六步我们输入 C:\Program Files (x86)\CodeBlocks\MinGW\bin (如果你的code::block是默认安装的话,否则,请你使用刚刚拼接的字符串compilar_path)

如果你没有code::block, 请你自行将g++编译器添加到环境变量

测试编译器是否可用

按住win键,然后输入r,在弹出的框中输入cmd

此时会打开一个黑框框

输入g++

如果出现下图,这说明编译器准备完毕

vscode配置

插件安装

安装好后, 点击左侧栏第5个按钮,依次安装下方3个插件

code runner (在输入框输入code runner进行搜索)

中文插件

在输入框输入 chinese 进行搜索

以及 C/C++ 插件

提示: 安装完毕后, 请重新启动vscode

vscode 初体验

重启过后, 我们打开一个文件夹

然后右键,新建文件,输入文件名,这里我输入的是test.cpp

接着,我们输入一个测试代码,可以看到, vscode已经可以智能补全了

输入完毕后, 右击输入区域, 点击第一项 Run Code ,可以在下方看到输出

这表示我们已经可以使用了

但是这个输入区域无法接受输入, 也就是我们无法拿测试用例进行调试 无法输入

解决输出区域无法输入的问题

我们将代码调试放在终端(之中,终端可以接受输入,就解决了这个问题

我们需要增加以下几条设置

首先, 打开setting.json

之后, 输入一条

"code-runner.runInTerminal": true,

Ctrl + S 保存后重启vscode, 重新运行代码, 可以看到已经可以输入了

生成文件放在固定目录,减少硬盘占用

默认设置中,生成的文件和代码文件同目录, 也就是说,对于每一个代码,我们都要生成这么一个.exe文件

一个.cpp 代码文件一般不会超过5kb, 但是一个可执行文件一般是 1mb左右

这不但增加了磁盘空间的负担,同时也使我们文件管理非常的混乱

使用以下操作解决:

打开 setting.json 添加这几条内容

    "terminal.integrated.shell.windows": "C:\\WINDOWS\\System32\\cmd.exe",
+    "code-runner.executorMap": {
+        "cpp": "cd $dir && g++ -o D:\\temp.exe \"$fileName\"  -std=c++11 &&  D:\\temp.exe"
+    }
+

这些代码的意思:

  • 第一行表示指定使用的终端为cmd, win10默认使用的PowerShell 语法与Cmd 的语法不大相同,我们选择熟悉的Cmd
  • 第二行表示执行代码是运行的命令,我们分开解析这条命令
    • cd $dir , 进入代码所在的目录
    • g++ -o D:\\temp.exe \"$fileName\" -std=c++11 , 使用c++11的标准编译你当前编辑的文件,然后生成可执行文件到 D:\\temp.exe, 可以更改为 -std=c++14 以使用更多特性, 或者更改 D:\\temp.exe 为你喜欢的路径
    • D:\\temp.exe ,执行你生成好的可执行文件
    • 其中&& 在c/c++语言中是且的意思, 也就是说, 执行完第一步 cd $dir 后, 我们才能安全的执行第二步操作,因此使用并且并且连接符

紧接着, 我们再添加以下内容:


+    "code-runner.preserveFocus": false,        
+    "code-runner.saveFileBeforeRun": true,
+

▲第一行: 运行后光标聚焦在终端 ▲第二行: 运行前自动保存文件

添加后的样子

接着,__重启__VsCode

已经可以使用了

+ + + diff --git "a/notebook/vue\344\277\256\346\224\271\346\225\260\347\273\204\345\206\205\347\232\204\345\257\271\350\261\241.html" "b/notebook/vue\344\277\256\346\224\271\346\225\260\347\273\204\345\206\205\347\232\204\345\257\271\350\261\241.html" new file mode 100644 index 0000000..9718a4f --- /dev/null +++ "b/notebook/vue\344\277\256\346\224\271\346\225\260\347\273\204\345\206\205\347\232\204\345\257\271\350\261\241.html" @@ -0,0 +1,34 @@ + + + + + + + + + vue修改数组内的对象 + + + + + + + + + diff --git a/notebook/webpack-source_map.html b/notebook/webpack-source_map.html new file mode 100644 index 0000000..3b62c61 --- /dev/null +++ b/notebook/webpack-source_map.html @@ -0,0 +1,34 @@ + + + + + + + + + webpack-source_map + + + + + + + + + diff --git "a/notebook/\344\275\277\347\224\250onedrive\345\234\250win10\345\222\214linux\344\271\213\351\227\264\345\220\214\346\255\245.html" "b/notebook/\344\275\277\347\224\250onedrive\345\234\250win10\345\222\214linux\344\271\213\351\227\264\345\220\214\346\255\245.html" new file mode 100644 index 0000000..9e8ad27 --- /dev/null +++ "b/notebook/\344\275\277\347\224\250onedrive\345\234\250win10\345\222\214linux\344\271\213\351\227\264\345\220\214\346\255\245.html" @@ -0,0 +1,55 @@ + + + + + + + + + 使用onedrive在win10和linux之间同步 + + + + + +

使用onedrive在win10和linux之间同步

我们在写代码的时候,经常有这样的场景: 在Windows下开发,然后放在服务器上跑

刚开始开发,整个项目只有一个文件(.py) ,这时候我使用xshell链接到服务器,使用rz命令上传文件, 就解决了问题

之后, 使用PyCharm 远程调试, 链接服务器进行同步, 也解决一定的问题,

最近跟风上了一年的OneDrive 365 (家庭版,6人240,一人40), onedrive 空间从免费的5g提升到了1tb,

同时也看到了大佬的github skilionopen in new window,

!!!! 在ubuntu16上有些许问题, 因为大佬不在维护, 因此使用另外一个同学的产品 https://github.com/abraunegg/onedrive.git

本人环境: win10 , centos7(1g 1h 1m)

上手:

事前准备: Fedora/CentOS

sudo yum install libcurl-devel
+sudo yum install sqlite-devel
+curl -fsS https://dlang.org/install.sh | bash -s dmd
+

安装

git clone https://github.com/skilion/onedrive.git
+cd onedrive
+make
+sudo make install
+

卸载

sudo make uninstall
+# delete the application state
+rm -rf .config/onedrive
+

进行配置

如果不配置, 你Onedrive中的文件默认会下载到 ~/OneDrive这个目录,并且隐藏的文件会跳过 如果你想改变位置等等, 做以下操作

mkdir -p ~/.config/onedrive
+cp ./config ~/.config/onedrive/config
+vim ~/.config/onedrive/config
+

可用选项:

  • sync_dir: 本地的onedrive文件夹路径,onedrive中的文件会保存在本地的这个目录
  • skip_file: 设置跳过的文件

demo:

# Directory where the files will be synced
+sync_dir = "~/OneDrive"
+# Skip files and directories that match this pattern
+skip_file = ".*|~*"
+

Patterns are case insensitive. * and ? wildcards charactersopen in new window are supported. Use | to separate multiple patterns.

Note: 改变配置文件后, 应该执行 onedrive --resync 以获得同步

选择性同步

选择性同步允许你只同步一个文件夹,或者是一个文件 方法:

  • 首先,确保你做了上面的配置文件,如果没有,点击跳转
  • 然后, 在~/.config/onedrive/ 目录下创建文件 sync_list

sync_list:的一个例子

Backup
+Documents/latest_report.docx
+Work/ProjectX
+notes.txt
+

Note: 改变配置文件后, 应该执行 onedrive --resync 以获得同步

本人的使用方法

本人使用 vnoteopen in new window 来编写笔记, 同时使用 vikiopen in new window 来作为web服务

具体操作:

  • 在onedrive 根目录下新建文件夹blog
  • 打开vnote, 新建一个笔记本,并设置根目录为 onedrive/blog
  • 下载最新版的viki源文件, 下载链接open in new window,解压缩
+ + + diff --git "a/notebook/\344\275\277\347\224\250\347\275\227\346\212\200\346\221\204\345\203\217\345\244\264_\346\226\220\350\256\257n1\347\233\222\345\255\220\347\233\264\346\222\255.html" "b/notebook/\344\275\277\347\224\250\347\275\227\346\212\200\346\221\204\345\203\217\345\244\264_\346\226\220\350\256\257n1\347\233\222\345\255\220\347\233\264\346\222\255.html" new file mode 100644 index 0000000..08f621b --- /dev/null +++ "b/notebook/\344\275\277\347\224\250\347\275\227\346\212\200\346\221\204\345\203\217\345\244\264_\346\226\220\350\256\257n1\347\233\222\345\255\220\347\233\264\346\222\255.html" @@ -0,0 +1,34 @@ + + + + + + + + + 使用罗技摄像头+斐讯n1盒子直播 + + + + + + + + + diff --git "a/notebook/\345\210\206\350\276\250\347\216\207.html" "b/notebook/\345\210\206\350\276\250\347\216\207.html" new file mode 100644 index 0000000..106b2ee --- /dev/null +++ "b/notebook/\345\210\206\350\276\250\347\216\207.html" @@ -0,0 +1,34 @@ + + + + + + + + + 分辨率 + + + + + +

分辨率

物理分辨率

物理分辨率是指显示器硬件所具有的分辨率

设置分辨率

一般和物理分辨率相符合

PPI

![](_v_images/20230116110508582_721.png =960x)

27寸4K:163.18 27寸2K:108.79 24寸1080P:91.79 14寸1366x768:111.94

R= 操作系统的目标ppi / 显示器的物理ppi

R表示在一定的缩放下,UI文字实际显示的大小和其设计目的大小的比值。

R会有3个结果,大于1,小于1,等于1;等于1说明显示器可以完美地展现UI和文字的设计大小,但没有显示器厂商做这种屏幕,只存在梦里;

R大于1,说明UI和文字实际显示的大小相比设计大小偏大;R小于1,说明UI文字的实际显示大小相比设计大小偏小。R越接近1,实际显示大小和设计大小越接近。

为什么27寸4K显示器“字儿会那么小”?因为当不缩放时,R = (96 * 100%) / 163.18 约等于 0.588,此时的R远小于1,UI和文字的实际显示大小只有设计大小的58%,当然会很小了。

为什么把缩放改成200%字儿就恢复了呢?因为R = (96 * 200%) / 163.18 约等于 1.177,R比1略大,UI和文字的实际显示大小相当于设计大小的117%

为了让UI和文字元素看着舒服,应该尽可能调整缩放让R接近1,也有潭友觉得“小一点无所谓,显示的东西太少太没效率了”,如果你的缩放能让R在0.8左右还是合适的,个人认为R再小就不可接受了。例如在27寸4K显示器上很多人使用150%缩放,得到的R为0.88,只能说大小缩为原来的九成,换更多的元素显示还是值得的。

最后,还有一个有趣的值:

27寸2K显示器,100%缩放,R=1.13 27寸4K显示器,200%缩放,R=1.17

显示元素大小居然差不太多

ui分辨率

win:使用缩放后,ui的等效分辨率,例如2k屏幕,200%缩放=720p, 150%缩放就是1706* 960, 125%缩放就是2048* 1152

https://bbs.saraba1st.com/2b/thread-1986336-1-1.html

游戏分辨率

老游戏可能对高分屏适配不够,会导致ui变小等(如红色警戒)

现代游戏应该是16:9,1080p为基础制作,高于此分辨率则会进行缩放,ui大小不变,但是会很清晰,例如4k中画质>2k高画质

nvidia dsr

N卡有dsr技术,超分辨率

全称Dynamic Super Resolution,中文为动态超级分辨率,也称“自定义分辨率”

使用场景:显示器1080p物理分辨率,但是显卡性能比较强时使用,以4k进行渲染然后输出给显示器

评论:这个设置就是打游戏用的,办公还是算了,挺糊的

DSR其实就类似SSAA抗锯齿,超采样缩放,对画质来说是有提升。但毕竟是要原生渲染4K画面,这对显卡的压力不是一般的小,像2060这样的显卡面对游戏以4K分辨率渲染基本上都是要跪的。简单来说,你要以4K渲染画面,那就只能降低特效才能保证帧率,用抗锯齿和画面的精细度去换低特效这无疑是捡了芝麻丢西瓜。所以NV现在都干脆没提及DSR了,技术没问题,就是一般显卡顶不住这样的压力。为了解决这个问题,DLSS就是最新的替代方案,只可惜没啥游戏支持而已。发布于 2020-06-23 15:11 作者:知乎用户 链接:https://www.zhihu.com/question/402549533/answer/1298403883 来源:知乎 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

这个技术已经是2014年的老技术了,开不开的对性能影响不算很大,而且现在抗锯齿用的就是类似这个技术的操作,没什么意义了已经 以上。

推断

基于以上信息,我的推断:

24寸1080p GTX1070 畅玩所有游戏(中画质60hz) 27寸1440p RTX3060ti 畅玩所有游戏(中画质60hz) 32寸2160p RTX4080 畅玩所有游戏 (中画质60hz)

4k显示器尺寸的选择

因为很多人觉得27”4K的字太小,导致一个两难的问题——不开缩放字体太小看不清;开了缩放,很多软件界面又会模糊,因为他们对缩放的支持很差。而32”因为屏幕更大,字体太小的问题就显得没那么严重了。

微星 mpg321ur

华硕 pg32uq

华硕 pg32uq

木头龙​​中央处理器 (CPU)等 3 个话题下的优秀答主​ 只接PS5玩游戏32寸,兼顾Windows应用27寸。只玩PS5的话,本来为了电视优化的画面,哪怕你坐的近一点也是OK的,尤其是主要是图片、视频内容的主机应用。这时候大屏就是正义,别犹豫直接上32。但你要兼顾电脑上的Windows的话,32寸开200%缩放,等效1920x1080,正常使用距离(50-60CM)时会显得偏大,PPI也高于视网膜分辨率。除非是电脑椅头靠在椅背靠枕上,但这个姿势看片子拿手柄玩游戏还好,敲键盘拿鼠标就很别扭了。开150%缩放的话等效2560x1440,显示元素会更多,但一般的Windows应用是GDI+,非整数缩放是向上取整渲染然后再通过算法缩放回来,所以4K分辨率开150%缩放显示等效2560x1440图像,先取整200%缩放用5120x2880渲染,然后再转换到3840x2160显示,这种做法会导致字体、色块边缘发虚模糊。(UWP应用是另一种渲染方式,字体、色块边缘清晰不少)27寸4K的话,57-60CM使用距离是达到视网膜分辨率的。200%缩放显示等效1920x1080,字体、色块边缘很清晰的,字体元素大小也比较适和。但如果凑得再近一点,达不到视网膜分辨率,仔细看字体边缘还是可以感觉到有点模糊。发布于 2022-05-26 21:11​赞同 37 ​​17 条评论

+ + + diff --git "a/notebook/\345\215\232\345\256\242\346\220\255\345\273\272.html" "b/notebook/\345\215\232\345\256\242\346\220\255\345\273\272.html" new file mode 100644 index 0000000..08ad2fa --- /dev/null +++ "b/notebook/\345\215\232\345\256\242\346\220\255\345\273\272.html" @@ -0,0 +1,34 @@ + + + + + + + + + 甲骨文服务器凉凉 + + + + + +

甲骨文服务器凉凉

https://51.ruyo.net/14138.html 白嫖甲骨文vps 2019年9月17

20200911甲骨文复活辣

白嫖了两台, 一台使用tcp 链接, 一台使用websocket+tsl(需要域名解析) 链接, 测速如下

服务器传输协议下载上传延迟抖动丢包
132.145.112.212websocket+tsl11.53.2095ms12ms-
168.138.214.1tcp12.77.61331ms436ms

2020/2/24

使用drive to webopen in new window

教程open in new window

  • 本地使用VNote进行编辑,将笔记文件夹设置到 onedrive 目录下
  • 编辑后自动更新onedrive,免去手动同步的麻烦
  • 使用drive to web 配合域名cname指向,完成博客搭建

20200215 甲骨文凉凉

因此我需要一个新的服务器

需求:

  • 搭建博客
    • 同时要提供vnote - onedrive这种方式的 日记 - 博客 工作流
  • vpn
    • 平时使用谷歌服务
  • 内网穿透

因此, 可能需要国外服务器才能支持

博客搭建方案:

  1. github/gitee/coding pages
  2. 阿里云,其它云
  3. 虚拟主机
  4. 其它
  5. 阿里云(入口 nginx 转发)+ 腾讯云(应用+数据库)
  6. github pages + cloudflare
  7. 阿里云->vultr->github pages->netlify
  8. 利用 Gridea 同步到 GitHub,然后再同步到 Netlify http://fehey.com
  9. 本地 N1+frp
  10. cnblogs, csdn (不想)

大佬的博客:

  1. https://www.dute.org/

思考

处理笔记的分类方式

笔记的种类:

  • 灵感
  • 待办事项
  • 日记
  • 笔记
  • 特殊的( 印象笔记剪藏,马克)

可用的笔记,提醒,便签软件

品名平台云同步备注
OneNote全平台
印象笔记全平台,免费版最多两台设备
微软待办全平台
习惯android×
VNote桌面端×配合onedrive可以同步,以及搭建博客

场景

展示给别人看的博客 -- Vnote + viki + onedrive + drive to web 自己的日记 -- 印象笔记+ 日历

印象笔记记日记

找到合适的写日记软件

notion -- 颜值即是正义 notion

笔记型博客

MDwikiopen in new window

  • 适合为开发的应用程序编写wiki
  • 无法实现多层文件夹
  • 具有github风格的markdown渲染器
  • 可使用gimmicks, 以获得例如github-fork带子, 讨论区, 等插件

vnote-vikiopen in new window

  • 配合vnote,以及onedrive云同步,适更合写笔记
  • 有多层文件夹
  • 渲染风格简陋,但是可以定制化(暂未找到方法)
+ + + diff --git "a/notebook/\345\217\230\351\207\217\345\221\275\345\220\215\347\233\270\345\205\263.html" "b/notebook/\345\217\230\351\207\217\345\221\275\345\220\215\347\233\270\345\205\263.html" new file mode 100644 index 0000000..14da1f7 --- /dev/null +++ "b/notebook/\345\217\230\351\207\217\345\221\275\345\220\215\347\233\270\345\205\263.html" @@ -0,0 +1,34 @@ + + + + + + + + + 变量命名相关 + + + + + + + + + diff --git "a/notebook/\345\233\276\345\275\242\346\212\227\351\224\257\351\275\277.html" "b/notebook/\345\233\276\345\275\242\346\212\227\351\224\257\351\275\277.html" new file mode 100644 index 0000000..a96a76c --- /dev/null +++ "b/notebook/\345\233\276\345\275\242\346\212\227\351\224\257\351\275\277.html" @@ -0,0 +1,34 @@ + + + + + + + + + 图形抗锯齿 + + + + + +

图形抗锯齿

5888162347open in new window

dlss是用来节约性能的,偷奸耍滑的抗锯齿都会有点副作用,txaa,fxaa照样糊,极限画质只认ssaa

游戏中常见的抗锯齿选项有以下几种:

1.关闭抗锯齿:是游戏中最常见的选项,关闭后游戏图像没有抗锯齿效果,会出现锯齿现象。对性能的需求较小,但视觉效果较差,100%的性能开销。

2.MSAA:Multi-Sample Anti-Aliasing(多重采样抗锯齿),MSAA支持各种MSAA级别,通常为x2、x4和x8等级别。 MSAA从3D场景中对每个像素进行多次采样以消除锯齿。 较高的MSAA级别会导致更好的视觉效果,但也会导致更多的性能开销,一般消耗10%~40%的性能开销。

3.FXAA:Fast Approximate Anti-Aliasing(快速近似抗锯齿),FXAA可在像素级别完成灰度反锯齿、多级反锯齿和对线条的效果。FXAA质量较好,性能开销小。在高分辨率下的效果更显著。一般消耗2%~10%的性能开销。

4.TXAA:Temporal Anti-Aliasing(时域抗锯齿),它使用我的时间成本将多个图像帧融合在一起,以提供更高质量的反锯齿以及抗锯齿的运动平滑性和更少的锯齿。对比MSAA和FXAA,TXAA的视觉效果和性能开销都更高,一般消耗20%~40%的性能开销。

5.SMAA:Subpixel Morphological Anti-Aliasing(亚像素形态抗锯齿),效果跟MSAA、FSAA非常接近,可以排除锯齿,同时减少不必要的混叠。 对于高性能的显卡来说没有太大的性能开销,但是在一些较低性能的显卡上则可能会出现效果不佳的情况。一般消耗2%~10%的性能开销。

总结:

性能消耗从低到高:FXAA < SMAA < MSAA < TXAA

效果质量从低到高:关闭抗锯齿 < FXAA < SMAA < MSAA < TXAA

游戏玩家通常可以根据自己的需要选择不同的抗锯齿选项,根据自己的电脑配置和游戏画面的需求选择不同的抗锯齿选项可以兼顾视觉效果与性能。

常见的抗锯齿选项包括:

  1. 无抗锯齿:游戏不使用任何抗锯齿技术,可以达到最高的帧率和最低的性能需求。

  2. FXAA(快速近似抗锯齿):这是一种快速且轻量级的抗锯齿技术,可以减少锯齿的数量,但可能会导致图像模糊或失真。该选项通常只需要额外的 1-2% 的 GPU 性能,适合运行时间敏感的游戏。

  3. MSAA(多重采样抗锯齿):这种抗锯齿技术通过对多个样本进行采样来减少锯齿的数量,它可以提供更好的图像质量,但需要更多的 GPU 性能。通常,MSAA 2x 可以消除大部分锯齿,但需要额外的 20-30% 的 GPU 性能;MSAA 4x 则可以消除更多的锯齿,但需要额外的 50% 或更多的 GPU 性能。

  4. SSAA(超采样抗锯齿):这是一种更高级的抗锯齿技术,可以通过在超过游戏分辨率的帧缓冲区中渲染图像来产生更高质量的图像。这种技术可以消除几乎所有的锯齿,但需要更高的 GPU 性能。由于需要更高的分辨率,因此 SSAA 的性能需求通常比 MSAA 更高,通常需要额外的 100-200% 的 GPU 性能。

总的来说,抗锯齿选项的性能需求和效果呈正相关。使用更高级的抗锯齿技术可以提供更好的图像质量,但需要更高的 GPU 性能。因此,在游戏设置中选择合适的抗锯齿选项可以平衡图像质量和性能之间的关系。

+ + + diff --git "a/notebook/\345\257\206\347\240\201\347\256\241\347\220\206.html" "b/notebook/\345\257\206\347\240\201\347\256\241\347\220\206.html" new file mode 100644 index 0000000..884d8d2 --- /dev/null +++ "b/notebook/\345\257\206\347\240\201\347\256\241\347\220\206.html" @@ -0,0 +1,34 @@ + + + + + + + + + 密码管理 + + + + + + + + + diff --git "a/notebook/\346\225\260\346\215\256\344\274\240\350\276\223.html" "b/notebook/\346\225\260\346\215\256\344\274\240\350\276\223.html" new file mode 100644 index 0000000..96a6ffa --- /dev/null +++ "b/notebook/\346\225\260\346\215\256\344\274\240\350\276\223.html" @@ -0,0 +1,40 @@ + + + + + + + + + 数据传输 + + + + + + + + + diff --git "a/notebook/\346\225\260\346\215\256\346\225\264\347\220\206.html" "b/notebook/\346\225\260\346\215\256\346\225\264\347\220\206.html" new file mode 100644 index 0000000..ed9966b --- /dev/null +++ "b/notebook/\346\225\260\346\215\256\346\225\264\347\220\206.html" @@ -0,0 +1,34 @@ + + + + + + + + + 数据整理 + + + + + +

数据整理

处理笔记的分类方式

笔记的种类:

  • 灵感
  • 待办事项
  • 日记
  • 笔记
  • 特殊的( 印象笔记剪藏,马克)

可用的笔记,提醒,便签软件

品名平台云同步备注
OneNote全平台编写代码感觉很差
印象笔记全平台,免费版最多两台设备用来写日记,适合个人喜欢
微软待办全平台
习惯android×可以用来打卡,带有提醒
VNote桌面端×配合onedrive可以同步,以及viki搭建博客
notion全平台√ (需要科学上网)
闪念胶囊

场景

展示给别人看的博客 -- Vnote + viki + onedrive + drive to web 自己的日记 -- 印象笔记+ 日历

印象笔记记日记

找到合适的写日记软件

notion -- 颜值即是正义 notion

照片相片的备份, 归纳

调研

途径价格功能备注
onedrive5g免费 ¥40/年 1t(可以存储其他文件)去年今日和windows 搭配
google photo15g免费 无限量的有损图片自动处理,分类,需要翻墙
nas机器费用+网络费用
百度云盘
微云

ondrive

家庭版本去闲鱼拼车大概可以做到 40一年 包含1t存储

google photo

平时在公司的时候使用,其他时候上网不稳定因此不多使用

+ + + diff --git "a/notebook/\346\226\207\344\273\266\346\217\217\350\277\260\347\254\246\344\270\216\347\274\223\345\206\262\345\214\272.html" "b/notebook/\346\226\207\344\273\266\346\217\217\350\277\260\347\254\246\344\270\216\347\274\223\345\206\262\345\214\272.html" new file mode 100644 index 0000000..b8ea240 --- /dev/null +++ "b/notebook/\346\226\207\344\273\266\346\217\217\350\277\260\347\254\246\344\270\216\347\274\223\345\206\262\345\214\272.html" @@ -0,0 +1,65 @@ + + + + + + + + + 文件描述符与缓冲区 + + + + + +

文件描述符与缓冲区

文件描述符

在业务场景中,有时程序的log会把设备硬盘打满,这时就需要进行一个日志的删除,此时你会发现rm xx.log 并不能释放硬盘空间,重启程序后才可以释放

这是因为该程序已经申请了文件描述符,因此系统会保留文件,直到程序结束或停止占用。

不重启的方法是,echo '' > xx.log

java FileReader

935599open in new window

package io;
+
+import java.io.*;
+import java.util.concurrent.TimeUnit;
+
+public class InodeTest {
+    public static void main(String[] args) throws IOException, InterruptedException {
+        BufferedReader reader = new BufferedReader(new FileReader("/Downloads/2020.zip"), 2);
+        String line;
+        while ((line = reader.readLine()) != null) {
+            System.out.println(line);
+            TimeUnit.MILLISECONDS.sleep(10);
+        }
+    }
+}
+

博主说几百兆的文件,他认为并没有全部读取到内存中,但是删除文件,程序可以继续读取

这里也是,echo '' > /Downloads/2020.zip 即可

python demo

with open("demofile",'wb') as f:
+    for i in range(1000*1000):
+        f.write('asdasdasdasdasdasdasd\n'.encode())
+import time
+
+f = open("demofile", 'r' ,encoding='utf8')
+
+index = 0
+for i in f:
+    index += 1
+    if index % 100 == 0:
+        print(index)
+        time.sleep(1)
+    # print(i)
+
+f.close()
+
+ + + diff --git "a/notebook/\346\230\276\345\215\241.html" "b/notebook/\346\230\276\345\215\241.html" new file mode 100644 index 0000000..c24e3ce --- /dev/null +++ "b/notebook/\346\230\276\345\215\241.html" @@ -0,0 +1,34 @@ + + + + + + + + + 显卡 + + + + + +

显卡

2023 5.19

970 4g 3700 980ti 5776 980 4337

1080 ti 8g 9875 1080 7542

2070s 10123 2070 8925 2080ti 11g 14655 2080s 11588 2080 10996

3060ti 8g 12200 4.88 3060 12g 8696 (notebook)3060 6g 8300
3070ti 8g 14826

3080ti 19568 3080 10g 17500 3090 24g 19799

4080 16g 28125 16g 8000 4070ti 12g 22753 12g 5800 3.92 4070 12g 17873 12g 4200 4.25 4060 8g 10200 2100

(*notebook)4080 12g 18890

6950xt 16g 21721 淘宝4400 6800xt 16g 19550 讯景6800XT海外版 3649 https://m.tb.cn/h.UF3ojs4 无个人送保 5.35 6750xt 12g 13588 瀚铠6750XT合金 2499元 5.43 6650xt 8g 10000 ️瀚铠6650XT合金 1789元 https://m.tb.cn/h.UE6t1Dh 5.58 6600xt 8g 9500 ④淘宝️⭐️瀚铠6600XT 1544 https://m.tb.cn/h.UFCpx8G 6.15

(*notebook)4060 10473 6000 (*notebook)4050 8300

game fps

因此,可以选4070+4k144,

4k144 = 2500 4070 = 4200

+ + + diff --git "a/notebook/\346\230\276\345\215\241\351\234\200\346\261\202\345\210\206\346\236\220.html" "b/notebook/\346\230\276\345\215\241\351\234\200\346\261\202\345\210\206\346\236\220.html" new file mode 100644 index 0000000..8f41e25 --- /dev/null +++ "b/notebook/\346\230\276\345\215\241\351\234\200\346\261\202\345\210\206\346\236\220.html" @@ -0,0 +1,34 @@ + + + + + + + + + 显卡需求分析 + + + + + +

显卡需求分析

4070 in techpower single-page.html#introductionopen in new window

显卡fps表

4060ti 2k

4060ti 4k

上图中,是最高特效,所以,其实60帧数很优秀了

可以看到, 3060ti基本满足游戏4k60,但是2k144跑不满 可以考虑购买的,先买2k144,然后换4k144(因为4k144不成熟,价格不低,没必要一步到位) 或者直接买4k144,目前有2500的款式,感觉贵

方案1: 总价:3060ti 8g+2k 165(2500+1200 = 3700), 畅玩2k 90fps,可用3.5年 提升:换显卡换显示器(那不是全换了吗,傻逼) 方案2: 总价 4070 12g+4k 144(4200 + 2500 = 6700), 畅玩4k 73fps 可用6年 提升:加个2k显示器

2k又和1080p差不多,所以2k144

买2500的3060ti g6x,可以畅玩2k144 为了能用久一些,多加3000,购买4070,提升了

长度 30+ 35,都可

宽度: 6cm以内,50最好

gtx 970冰龙 长度:300mm,高度:111mm;厚度:约6cm 350 电竞判客 319 117 49 4200 turbo 329 133 64 4200 ultra w 337 150 60 4400

要解决几个问题

  1. 蚂蚁ant27vu这款,是不是有不满血hdmi2.1的问题

蚂蚁电竞 ANT27VU 2699元 【推荐度】:高。 【定位】:SDR游戏

【配置】:友达7.0 OC,400nit亮度,传统LED背光,双HDMI 2.1,USB Type-C 15W

【总评】:4K高刷中的性价比之王,LG 27GP95R的低价平替,知乎吴彦祖亲手调教的产物

【注意】:这个显示器已经从友达2.3升级到友达7.0,而且加量不加价!但是老款和新款名字是一样的,判断新老的方法很简单:4K 160Hz的就是友达7.0的新款,4K 144Hz的是友达2.3老款。

【优点】

1,友达7.0新面板带来更好的观感和响应速度(4.0ms),远超友达2.3,略胜群创E7B

2,接口丰富,做工良心,外观属于中配,比上面两个低配的要好很多。

3,背面RGB灯非常好看,正面还有投影灯(有点ROG的感觉,emmm,一定是借鉴!!!)

4,色域高,95% Adobe + 94% P3,同时适合摄影设计和大型单机游戏。

此外,就这个价位来说,它的均匀性还是不错的。得益于新面板它有着2.8ms的超快响应速度,逼近IPS面板的极限,所以也适合FPS游戏。

【缺点】

1,关机后显示器上的灯不会自动关闭,烦死人

2,HDMI 2.1接口在某些显卡上无法支持G-Sync,PC玩家用DP接口的话,可以无视这个缺点

  1. aoc u27g3x 这款,不带typec,有没有混发面板问题

AOC U27G3X 3199元 [推荐度]:高。(定位]: SDR游戏,护眼办公 [配置]: 友达7.0 0C,400nit亮度,传统LED背光,双HDMI 2.1 [总评] : 性价比很高的硬件低蓝光显示器,友达7.0新面板,值得无脑入手! [优点) 1,友达7.0新面板赋予了高响应速度,较好的观感,明显比友达2.3的一帮弟弟们要出色2,自带硬件抗蓝光,非常护眼,尤其适合文字工作者。虽然可能不是原厂模组,但是AOC也给 用上了支持硬件低蓝光的背光。 [缺点) 1,没有USB Type-C和USB-A扩展接口 2,调色方案比较激进,有些人可能觉得它的颜色太艳丽,也有些人恰好喜欢它的颜色 3,AOC这个系列的产品做工一般,远不如爱攻系列

  1. 泰坦p27a2v这款,面板是不是7.0

  2. hkc vg273upro 不带typec, 有没有问题 HKC VG273Upro 2699元 【推荐度】:中。 【定位】:SDR游戏

【配置】:友达7.0 OC,400nit亮度,传统LED背光,双HDMI 2.1,USB Type-C 15W

【总评】:这和蚂蚁ANT 27VU就是同一个东西,只是外壳不同,两个机器就是同一条生产线出来。HKC这台在外观做工上比蚂蚁ANT 27VU差,所以同价位下请买蚂蚁。

有时候VG273Upro会比ANT 27VU便宜100-200元,如果你不在乎外观,也可以买VG273Upro。

2k高刷&4k办公

Y27h-30。4USB-A+90W的Type-c 2k

飞利浦279P1 1999 90w 评论少 好评600 发布时间21年11月

vx2762-4k-mhdu 好评1000+,差评8,中评1 VX2880-4K-HDU-2 1499 hub hdr400 99%srgb tvu认证 65w 升降旋转 94% 2900+好评 VX2780-4K-HD-2 1650 hdr400 94% 1400好评 vx2731-4k 1299 99%srgb

aoc u27n3c 1799 唤醒慢 发布时间21年11月 5300好评 94% 每次从睡眠中唤醒,一线智联就不好用,typec线重新插拔一次

lg 27up600

27ul650 1750

雷电无信号:

ThinkPad的显示器识别问题和雷电接口故障解决 https://zhuanlan.zhihu.com/p/529323703

我的是关机拔掉充电器,长按电源键开机然后自动关机,再插上电源开机就好了 https://bbs.thinkpad.com/thread-7823411-1-1.html

为什么12代Intel笔记本雷电4或USB4外接显示器不支持Type-C DP独显直连? https://www.bilibili.com/read/cv16411870

notebook/图形抗锯齿.md

图形抗锯齿.md

+ + + diff --git "a/notebook/\350\264\255\344\271\260\350\256\260\345\275\225.html" "b/notebook/\350\264\255\344\271\260\350\256\260\345\275\225.html" new file mode 100644 index 0000000..43201f8 --- /dev/null +++ "b/notebook/\350\264\255\344\271\260\350\256\260\345\275\225.html" @@ -0,0 +1,34 @@ + + + + + + + + + 电子产品购买记录 + + + + + +

电子产品购买记录

大物件

时间名称链接价格备注
2022-7-12明基京东open in new window689优惠价格,平时1000
2022-7-7机械革命无界16京东open in new window5149
2022-2-21宁芝82 蓝牙双模键盘闲鱼open in new window495
2021-4-25qc35 二代tbopen in new window941
2020-12-10松下EH-WNA8Bjdopen in new window349.20现在639,好价格
2020-09-09致巡黑jdopen in new window369
2020-09-09京东京造Q9吸尘器jdopen in new window759
2020-8-5ipad air 3 + airpodstbopen in new window3700
2020-5-26咪咕kindlejdopen in new window468白嫖失败
2018-11-11小米Pro 15.6英寸jdopen in new window549980京豆
2018-10-20松下台灯致言jdopen in new window284
2018-9-11米动手表jdopen in new window242凑单66的阿迪背包
20155.2

手机

时间名称链接价格备注
2021-06-10OPPO Reno5 Pro+ 12+256 星河入梦jdopen in new window3299用了70京豆
2020-6-21二手坚果pro3闲鱼open in new window1800
2018-11-01锤子r1jdopen in new window2149
2018-1-19lg g5tbopen in new window371

小物件 price<200

时间名称链接价格备注
2019-05-18床上桌tbopen in new window73
2022-8-3rk r87 k黄轴tbopen in new window119
2022-7-14小米空调伴侣京东open in new window76
2022-6-14赛睿鼠标垫京东open in new window59.00
2022-6-14g102白色jdopen in new window99.00
2022-7-27牙刷刷头*3jdopen in new window119用了68块钱京豆
2022-2-23山寨屏幕挂灯闲鱼open in new window125
2022-2-18雷蛇八岐大蛇v2无线鼠标jdopen in new window228
2021-9-19g102黑色换新jdopen in new window0换新
2021-8-20米家智能插座jdopen in new window28红包-10
2021-08-20卡王AX200PROJDopen in new window129用了83块礼品卡
2020-12-25飞利浦电动牙刷头jdopen in new window101
2020-10-14路由器upstbopen in new window130
2020-5-15g304+樱桃G80鼠标垫jdopen in new window213
2020-4-20锤子无线耳机jdopen in new window17910块京豆
2020-3-30飞利浦6511牙刷jdopen in new window18920京豆
2018-11-12雷柏(Rapoo) V805jdopen in new window174
2018-11-01g102黑色jdopen in new window99
2019-12-10usb-c扩展坞tbopen in new window98
2019-10-16坚果r1无线充电tbopen in new window115
1693161

家里

时间名称链接价格备注
2019-10-1tcl 65寸电视 2+32--2999
2019-10-9米兔3c手表tbopen in new window418
2021-9-24创维27寸2K显示器jdopen in new window899
2020-9-2310只斑马jj15jdopen in new window119
2021-7-277060d打印机闲鱼open in new window530
2022-6-29打印机晒鼓-2600页xx34.00
总价4999

电脑装机 2022.11

名称价格时间连接备注
i5-12600kf16002022-11-11jd板u套装
华硕 tuf b660m-plus d49002022-11-11jd板u套装
光威天策3200 32g3752022-11-11JDopen in new window
光威天策3200 32g2502023-6-15JDopen in new window半年降价100
利民pa1201502022-11-20pdd
金百达 1t固态pcie4.03752022-11-23JDopen in new window
鑫谷电源750w3202022-11-22jdopen in new window
wifi网卡1002023-5-1jd
七彩虹 RTX4070 ultra w v243002023-5-31jd
垃圾机箱302022-12-3闲鱼
总价(不带显示器)8400
4k144hz KOIOS K2723UL青春版17792023-5-31jd第三方店友达7.0 商品评价100左右
nta N2823UG 4k152hz15292023-5-31jd第三方店e7b面板,商品评价15左右,满血hdmi2.1, 可惜有竖线,已经退货
全套总价(带显卡显示器)10200
xbox手柄4292023-1-29jd
海康威视西数紫盘3202022-10-17pdd数据盘
映众超级冰龙GTX9703502022-11-22闲鱼过渡

主机

装机经验:

  1. 不要上太大的风冷,丑,不方便安装
  2. 主板要带wifi
  3. 不介意大小,最好买大的主板,而不是类似b660m这种m板
  4. 注意显卡厚度,ultra厚度为60mm,会占用三个pcie槽
  5. 购买ddr4内存的话,即使有大内存需求,也尽量买双通道,单通道影响cpu、显卡发挥,双通道前后,cpu从58w提升68w,显卡60w到64w,内存8.5w到17w, 提升较大
  6. 机箱上方部位多一些,方便走线

眼镜

时间名称链接价格备注
2023-5-1依视路钻晶x4(免费升级到膜致)404

猫粮

时间名称链接价格备注
2023-3-23jd京造10kg249
2023-1-1希宝猫条 60个58+15猫超卡
2022-11-05网易严选7.2kgopen in new window190
2022-6-30京东京造三文鱼1.8kg60
2022-6-30京东京造双拼1.8kgx245x2
2022-1-254x2.5kg猫砂52
2022-1-15网易严选猫粮7.2kg205
2021-12-04牛油果 2kg x 2xx2010喜豆
2021-11-12冠能3.5kg67
2021-11-10京萌2kg17
2021-10-13京萌2kg47
2021-9-13皇家0.8kg45
2021-9-9猫砂6L*35050
975
+ + + diff --git "a/notebook/\350\277\220\345\212\250\346\211\213\350\241\250.html" "b/notebook/\350\277\220\345\212\250\346\211\213\350\241\250.html" new file mode 100644 index 0000000..e5abafe --- /dev/null +++ "b/notebook/\350\277\220\345\212\250\346\211\213\350\241\250.html" @@ -0,0 +1,34 @@ + + + + + + + + + 运动手表 + + + + + + + + + diff --git "a/notebook/\351\207\215\347\275\256CMD\350\256\276\347\275\256.html" "b/notebook/\351\207\215\347\275\256CMD\350\256\276\347\275\256.html" new file mode 100644 index 0000000..039dbff --- /dev/null +++ "b/notebook/\351\207\215\347\275\256CMD\350\256\276\347\275\256.html" @@ -0,0 +1,34 @@ + + + + + + + + + 重置CMD设置 + + + + + + + + + diff --git a/ops/drone.html b/ops/drone.html new file mode 100644 index 0000000..2e05045 --- /dev/null +++ b/ops/drone.html @@ -0,0 +1,152 @@ + + + + + + + + + drone + + + + + +

drone

下面的例子中,项目名假定为citest

缓存类型优点缺点
docker缓存"1. 可以缓存全过程,2. 不限于某个runner节点"需要构建并推送额外的docker镜像
本地缓存简单"1. 无法缓存构建过程(如yarn build)2. 只生效在单一runner节点"

docker缓存(优先使用)

不限制构建的类型,原理是基于docker cache加速执行过的构建。下面的例子中,会将所有的依赖文件打包成一个docker镜像进行加速: .drone.yml

kind: pipeline
+type: ssh
+name: ci 
+trigger:
+  ref:
+    include:
+      - refs/heads/v[0-9]*
+      - refs/tags/v[0-9]*
+server:
+  host:
+    from_secret: be_runner
+  user:
+    from_secret: runner_user
+  ssh_key:
+    from_secret: runner_key
+steps:
+  - name: build
+    commands:
+      - echo $DOCKER_PASSWORD | docker login dcr.xxx.com -u $DOCKER_USERNAME --password-stdin
+      - IMAGE_TAG=${DRONE_TAG##*/} make docker-build
+    environment:
+      DOCKER_USERNAME:
+        from_secret: docker_username
+      DOCKER_PASSWORD:
+        from_secret: docker_password
+

先构建依赖库的镜像,再构建最终使用的镜像 Makefile

REGISTRY ?= dcr.xxx.com
+IMAGE_NAME ?= xxx/citest
+IMAGE_TAG ?= latest
+
+docker-build:
+        DOCKER_BUILDKIT=1 docker build . \
+                --file Dockerfile.base \
+                --tag ${REGISTRY}/${IMAGE_NAME}:deps \
+                --cache-from ${REGISTRY}/${IMAGE_NAME}:deps \
+                --build-arg BUILDKIT_INLINE_CACHE=1
+
+        DOCKER_BUILDKIT=1 docker build . \
+                --file Dockerfile \
+                --tag ${REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG} \
+                --cache-from ${REGISTRY}/${IMAGE_NAME}:deps \
+                --build-arg BUILDKIT_INLINE_CACHE=1
+

依赖库镜像的Dockerfile Dockerfile.base

FROM node:lts-bullseye as build
+WORKDIR /app
+COPY ./package.json ./yarn.lock /app/
+COPY ./src /app/src
+COPY ./public /app/public
+RUN yarn --registry=https://registry.npm.taobao.org
+RUN yarn build
+

最终业务用镜像的Dockerfile Dockerfile

FROM node:lts-bullseye as build
+WORKDIR /app
+COPY ./package.json ./yarn.lock /app/
+COPY ./src /app/src
+COPY ./public /app/public
+RUN yarn --registry=https://registry.npm.taobao.org
+RUN yarn build
+
+FROM nginx:stable-alpine-slim
+COPY --from=build /app/dist/ /usr/share/nginx/html/
+EXPOSE 80
+

本地缓存

可以用于缓存npm/yarn的依赖库文件,原理是将每次构建时使用的依赖库文件同步到主机的指定目录,然后下一次构建时先同步回来。该方案只能加速下载依赖文件的流程,每次都要重新build,因此如果build时间太久,建议尝试使用上面docker缓存的方案。

npm cache

.drone.yml

kind: pipeline
+type: exec
+name: ci 
+trigger:
+  ref:
+    include:
+      - refs/heads/v[0-9]*
+      - refs/tags/v[0-9]*
+steps:
+  - name: restore-cache
+    commands:
+      # npm cache,一般缓存到drone的工作目录下
+      - mkdir -p /data/cache/citest/node_modules
+      - rsync -a /data/cache/citest/node_modules .
+
+  - name: build
+    commands:
+     - export YARN_CACHE_FOLDER="~/.yarn/cache"
+     - npm install --registry=https://registry.npm.taobao.org
+     - npm build
+
+  - name: rebuild-cache
+    commands:
+      # npm cache
+      - rsync -a ./node_modules /data/cache/cicdtest/
+
+

yarn cache

.drone.yml

kind: pipeline
+type: exec
+name: ci 
+trigger:
+  ref:
+    include:
+      - refs/heads/v[0-9]*
+      - refs/tags/v[0-9]*
+steps:
+- name: prepare
+  commands:
+    - |
+      cat <<EOF >> .yarnrc.yml
+      # 启用全局cache
+      enableGlobalCache: true
+      EOF
+      
+  - name: restore-cache
+    commands:
+      # yarn cache,这里不区分项目,共同使用一个缓存目录
+      - mkdir -p /data/cache/.yarn
+      - rsync -a /data/cache/.yarn ~/
+
+  - name: build
+    commands:
+     - export YARN_CACHE_FOLDER="~/.yarn/cache"
+     - yarn --registry=https://registry.npmmirror.com/
+     - yarn build
+
+  - name: rebuild-cache
+    commands:
+      # yarn cache
+      - rsync -a ~/.yarn /data/cache/
+
+ + + diff --git a/ops/index.html b/ops/index.html new file mode 100644 index 0000000..24c7854 --- /dev/null +++ b/ops/index.html @@ -0,0 +1,34 @@ + + + + + + + + + 这里是ops + + + + + + + + + diff --git a/ops/k8s.html b/ops/k8s.html new file mode 100644 index 0000000..d854bd4 --- /dev/null +++ b/ops/k8s.html @@ -0,0 +1,34 @@ + + + + + + + + + k8s + + + + + +

k8s

alias k8s

为了方便查看日志,编写了一个alias

alias klmes="kubectl logs -f kubectl get pods | grep '^mes-be' | grep 'Running' -m 1 | awk '{print $1}'"

但是在断网环境下打开新终端,发现zsh会尝试运行该命令, 在网络不通环境下打开新终端,则会导致终端卡死

问题定位

经过多次尝试,我编写了一个二进制程序echo222, 放在/usr/local/bin/下, 并编写了如下的alias

alias ee="echo222"

经测试,没有执行该语句

再次编写为

alias ee="echo echo222" 经测试,执行了双引情况下号下,``(反引号)包裹的语句,

再测试下单引号 alias ee='echo echo222' 经测试,问题解决

解决方案1

使用函数

klmes () { kubectl logs -f kubectl get pods | grep '^mes-be' | grep 'Running' -m 1 | awk '{print $1}' }

解决方案2

https://stackoverflow.com/questions/1250079/how-to-escape-single-quotes-within-single-quoted-strings

使用单引号包住 alias klmes='kubectl logs -f $(kubectl get pods | grep "^mes-be" | grep "Running" -m 1 | awk '"'"'{print $1}'"'"')'

+ + + diff --git "a/ops/mysql_\344\270\273\344\273\216\345\244\215\345\210\266.html" "b/ops/mysql_\344\270\273\344\273\216\345\244\215\345\210\266.html" new file mode 100644 index 0000000..defef07 --- /dev/null +++ "b/ops/mysql_\344\270\273\344\273\216\345\244\215\345\210\266.html" @@ -0,0 +1,101 @@ + + + + + + + + + [mysql]主从复制 + + + + + +

[mysql]主从复制

步骤

1,主开启binlog

docker run --name mydb2 -itd -e MYSQL_ROOT_PASSWORD=pwd -v /dbconf/:/etc/mysql/conf.d/ mariadb

[root@bogon ~]# vim /mydb1/conf/my.cnf [mysqld] server_id=1 log_bin=mysql-bin

show master status;
+show variables like '%%log_bin%';
+

2. 副修改server_id

[root@bogon ~]# vim /mydb2/conf/my.cnf [mysqld] server_id=2


+show variables like '%server_id%';      
+
+

3.副开启主从

MariaDB [(none)]> CHANGE MASTER TO MASTER_HOST='172.17.0.2', MASTER_USER='slave', MASTER_PASSWORD='slave', MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=511;     
+Query OK, 0 rows affected (0.015 sec)
+
+MariaDB [(none)]> start slave;
+Query OK, 0 rows affected (0.005 sec)
+
+MariaDB [(none)]> show slave status\G
+*************************** 1. row ***************************
+                Slave_IO_State: Waiting for master to send event
+                   Master_Host: 172.17.0.2
+                   Master_User: slave
+                   Master_Port: 3306
+                 Connect_Retry: 60
+               Master_Log_File: mysql-bin.000001
+           Read_Master_Log_Pos: 511
+                Relay_Log_File: mysqld-relay-bin.000002
+                 Relay_Log_Pos: 555
+         Relay_Master_Log_File: mysql-bin.000001
+              Slave_IO_Running: Yes
+             Slave_SQL_Running: Yes
+               Replicate_Do_DB: 
+           Replicate_Ignore_DB: 
+            Replicate_Do_Table: 
+        Replicate_Ignore_Table: 
+       Replicate_Wild_Do_Table: 
+   Replicate_Wild_Ignore_Table: 
+                    Last_Errno: 0
+                    Last_Error: 
+                  Skip_Counter: 0
+           Exec_Master_Log_Pos: 511
+               Relay_Log_Space: 865
+               Until_Condition: None
+                Until_Log_File: 
+                 Until_Log_Pos: 0
+            Master_SSL_Allowed: No
+            Master_SSL_CA_File: 
+            Master_SSL_CA_Path: 
+               Master_SSL_Cert: 
+             Master_SSL_Cipher: 
+                Master_SSL_Key: 
+         Seconds_Behind_Master: 0
+ Master_SSL_Verify_Server_Cert: No
+                 Last_IO_Errno: 0
+                 Last_IO_Error: 
+                Last_SQL_Errno: 0
+                Last_SQL_Error: 
+   Replicate_Ignore_Server_Ids: 
+              Master_Server_Id: 1
+                Master_SSL_Crl: 
+            Master_SSL_Crlpath: 
+                    Using_Gtid: No
+                   Gtid_IO_Pos: 
+       Replicate_Do_Domain_Ids: 
+   Replicate_Ignore_Domain_Ids: 
+                 Parallel_Mode: conservative
+                     SQL_Delay: 0
+           SQL_Remaining_Delay: NULL
+       Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
+              Slave_DDL_Groups: 0
+Slave_Non_Transactional_Groups: 0
+    Slave_Transactional_Groups: 0
+1 row in set (0.000 sec)
+
+ + + diff --git a/ops/oj.html b/ops/oj.html new file mode 100644 index 0000000..dae1d02 --- /dev/null +++ b/ops/oj.html @@ -0,0 +1,113 @@ + + + + + + + + + oj + + + + + +

oj

pdsuoj

php7.2

代码路径信息

php配置文件路径/etc/php/7.2/fpm/php.ini

这个文件修改后需重启php使修改生效service php7.2-fpm restart

代码路径/home/judge/src/web/

开发代码路径/home/judge/src/web-dev/

下面的信息都基于项目根目录

  • 数据库等配置文件的路径include/db_info.inc.php

代码结构

假设主目录为/home/judge/src/web/ 主目录下的php文件为后端文件,负责数据库查询,数组结构组装

其中前端在template/bs3/ 路径下 admin前端在 admin/ 路径下

tree -L 1
+
+├── ace                        在线编辑器组件
+├── acm_number.txt
+├── acm_ranking.php            acm排名页面
+├── admin
+├── bbs
+├── bbs.php
+├── blog_show.php               博客
+├── bootstrap
+├── config.yaml
+├── csrf.php
+├── discuss3
+├── edit_area
+├── faqcss
+├── favicon.ico
+├── fckeditor
+├── fonts
+├── gpl-2.0.txt
+├── highlight
+├── image
+├── include
+├── index.php
+├── kindeditor
+├── lang
+├── mergely
+├── newranking_guize.txt
+├── php_errors.log           日志,基本是警告与错误
+├── qrcodetmp
+├── reportlogin.html
+├── study_vedio              学习视频
+├── summary                  知识图谱   
+├── template
+└── upload
+
+

nginx

nginx 是最流行,性能最强的web服务器,使用多路复用,性能很强,基本替代了以前的apache

php-fpm与nginx访问流程图

nginx 配置文件路径 for 生产 /etc/nginx/sites-enabled/default

nginx 配置文件路径 for 开发 /etc/nginx/sites-enabled/web-dev

nginx 常用命令

nginx -t 检查配置文件是否正确

root@iZ2ze954cl1vua04rezfxcZ:/home/judge/src/web# nginx -t 
+nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
+nginx: configuration file /etc/nginx/nginx.conf test is successful
+

nginx -s reload 使用新的配置文件重载nginx(编辑配置后,需重载使nginx生效, 正常情况下无输出)

root@iZ2ze954cl1vua04rezfxcZ:/home/judge/src/web# nginx -s reload
+root@iZ2ze954cl1vua04rezfxcZ:/home/judge/src/web#
+
+

nginx配置文件demo

# 主要区别在于listen 的端口以及root 的位置, 创建新的文件,并修改这两个,即可设置多个站点
+server {
+    
+        listen 8000 default_server;            
+        listen [::]:8000 default_server;
+
+        include snippets/phpmyadmin.conf;
+        root /home/judge/src/web-dev;
+
+        # Add index.php to the list if you are using PHP
+        index index.php index.htm index.nginx-debian.html;
+
+        server_name _;
+
+        location / {
+                # First attempt to serve request as file, then
+                # as directory, then fall back to displaying a 404.
+                try_files $uri $uri/ =404;
+        }
+
+        # pass PHP scripts to FastCGI server
+        #
+        location ~ \.php$ {
+                include snippets/fastcgi-php.conf;
+        #
+        #       # With php-fpm (or other unix sockets):
+                fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
+        #       # With php-cgi (or other tcp sockets):
+        #       fastcgi_pass 127.0.0.1:9000;
+        #}
+
+        }#added by hustoj
+
+
+
+}
+
+
+
+ + + diff --git a/ops/sudo.html b/ops/sudo.html new file mode 100644 index 0000000..207b51a --- /dev/null +++ b/ops/sudo.html @@ -0,0 +1,34 @@ + + + + + + + + + sudo + + + + + +

sudo

-i 参数(即 sudo -i ),在 sudo 的 man page 里指明了,会加载 [.profile,.bash_profile or .login will be read by the shell.] , 同时呢,会跳到 /root 家目录。

https://www.v2ex.com/t/885106#reply3

+ + + diff --git a/ops/ubuntu_x11.html b/ops/ubuntu_x11.html new file mode 100644 index 0000000..3003a7d --- /dev/null +++ b/ops/ubuntu_x11.html @@ -0,0 +1,40 @@ + + + + + + + + + ubuntu_x11 + + + + + +

ubuntu_x11

启动方式

moye用户

先启动xterm

然后sudo pycharm.sh启动pycahrm

遇到的问题

无法显示中文

73 apt install x11-apps 74 exit 75 xclock 76 exit 77 apt install xinit 78 xterm & 79 apt install xterm 80 xterm & 81 exit 82 apt install gtk2-immodule-xim 83 apt install fcitx

# start_pycharm.sh
+export XIM_PROGRAM=fcitx
+export XIM=fcitx
+export XMODIFIERS=@im=fcitx
+export DEPENDS=fcitx
+/home/moyechen/pycharm-2022.2.3/bin/pycharm.sh
+

无法输入中文

暂时未解决

+ + + diff --git "a/ops/vmware\350\231\232\346\213\237\346\234\272\347\241\254\347\233\230\350\260\203\346\225\264.html" "b/ops/vmware\350\231\232\346\213\237\346\234\272\347\241\254\347\233\230\350\260\203\346\225\264.html" new file mode 100644 index 0000000..81316c2 --- /dev/null +++ "b/ops/vmware\350\231\232\346\213\237\346\234\272\347\241\254\347\233\230\350\260\203\346\225\264.html" @@ -0,0 +1,46 @@ + + + + + + + + + vmware虚拟机硬盘调整 + + + + + +

vmware虚拟机硬盘调整

vmware 调整硬盘大小

https://www.cnblogs.com/ZHJ0125/p/12904471.html 安装gparted

x11授权 sudo xauth add $(xauth -f ~moyechen/.Xauthority list|tail -1)

如果遇到


+moyechen@moye:~$ sudo xauth add $(xauth -f ~moyechen/.Xauthority list|tail -1)
+xauth:  timeout in locking authority file /home/moyechen/.Xauthority
+xauth:  timeout in locking authority file /home/moyechen/.Xauthority
+
+
+

则执行

rm ~/.Xaut*
+exit
+再次登录时,会提示
+/usr/bin/xauth:  file /home/moyechen/.Xauthority does not exist
+
+然后创建该文件
+

https://superuser.com/questions/315050/xauth-x11-ssh-forwarding-errors-with-xauthority-file-not-writable

最后启动程序

sudo gparted

LVM

https://blog.csdn.net/Fly_1213/article/details/105142427

lvextend -L 80G /dev/mapper/ubuntu--vg-ubuntu--lv

resize2fs /dev/mapper/ubuntu--vg-ubuntu--lv

+ + + diff --git "a/ops/\343\200\220\350\277\220\347\273\264\343\200\221expect.html" "b/ops/\343\200\220\350\277\220\347\273\264\343\200\221expect.html" new file mode 100644 index 0000000..07da28c --- /dev/null +++ "b/ops/\343\200\220\350\277\220\347\273\264\343\200\221expect.html" @@ -0,0 +1,34 @@ + + + + + + + + + 【运维】expect + + + + + + + + + diff --git "a/ops/\344\273\243\347\220\206\344\275\277\347\224\250.html" "b/ops/\344\273\243\347\220\206\344\275\277\347\224\250.html" new file mode 100644 index 0000000..b506d27 --- /dev/null +++ "b/ops/\344\273\243\347\220\206\344\275\277\347\224\250.html" @@ -0,0 +1,34 @@ + + + + + + + + + 代理使用 + + + + + +

代理使用

环境变量

Linux

使用socks5 export http_proxy="socks5://127.0.0.1:10808" export https_proxy="socks5://127.0.0.1:10808" 使用http export http_proxy="http://127.0.0.1:10809" export https_proxy="http://127.0.0.1:10809" 指定不使用代理的域名和IP export no_proxy='a.test.com,127.0.0.1,192.168.0.0/16'

Windows

命令行 set http_proxy="http://127.0.0.1:10809" set https_proxy="http://127.0.0.1:10809" 或者在系统设置里设环境变量 http_proxy | http://127.0.0.1:10809 https_proxy | http://127.0.0.1:10809

Ubuntu apt

sudo tee /etc/apt/apt.conf.d/proxy.conf << EOF Acquire { HTTP::proxy "http://127.0.0.1:10809"; HTTPS::proxy "http://127.0.0.1:10809"; } EOF

Git

HTTP方式访问 git config --global http.proxy 'socks5://127.0.0.1:10808' git config --global https.proxy 'socks5://127.0.0.1:10808'

SSH方式访问,以github.com为例 ~/.ssh/config Host github.com # Mac/Ubuntu下,使用socks5 ProxyCommand nc -X 5 -x 127.0.0.1:10808 %h %p

Docker

Ubuntu下修改 /etc/default/docker CentOS下修改 /etc/sysconfig/docker export http_proxy="http://127.0.0.1:10809" export https_proxy="http://127.0.0.1:10809" export no_proxy='a.test.com,127.0.0.1,192.168.0.0/16' 重启docker后,运行docker info检查

Python代码

通过requests模块使用 proxies={ 'http': 'http://127.0.0.1:10809', 'https': 'http://127.0.0.1:10809' }

r = requests.get(url, proxies=proxies)

r = requests.post(url, headers=headers, json=payload, proxies=proxies)

浏览器插件

推荐使用SwitchyOmega,支持Chrome/Edge/Firefox。 首先配置一个场景模式,命名为proxy或任何你喜欢的名字,在里面添加SOCKS5或者HTTP代理,还可以手动添加你不想代理的地址列表,如内网IP段/指定域名等:

在auto switch中添加规则列表,并让规则列表默认走上面配置的proxy场景: https://raw.githubusercontent.com/gfwlist/gfwlist/master/gfwlist.txt

选择auto switch的场景模式,此时只有规则列表里的域名会走代理:

其他

常用包管理器的代理设置:https://github.com/comwrg/package-manager-proxy-settings

+ + + diff --git "a/ops/\347\241\254\347\233\230\351\200\237\345\272\246\346\265\213\350\257\225.html" "b/ops/\347\241\254\347\233\230\351\200\237\345\272\246\346\265\213\350\257\225.html" new file mode 100644 index 0000000..64b7cad --- /dev/null +++ "b/ops/\347\241\254\347\233\230\351\200\237\345\272\246\346\265\213\350\257\225.html" @@ -0,0 +1,34 @@ + + + + + + + + + 硬盘速度测试 + + + + + +

硬盘速度测试

linux 测试磁盘性能

mkdir test-data fio --rw=write --ioengine=sync --fdatasync=1 --directory=test-data --size=2200m --bs=2300 --name=mytest

Ideally, your disk should reach over 500 IOPS and below 10ms for the 99th percentile fsync latency. Read the etcd Docs for more detailed requirements.

as ssd

660P 5GB

光威 1GB

660P 1GB

三星981 1GB

三星981 256G

C2000PRO 1T

C2000PRO 1T

+ + + diff --git "a/ops/\347\275\221\347\233\230\344\270\216\345\220\214\346\255\245.html" "b/ops/\347\275\221\347\233\230\344\270\216\345\220\214\346\255\245.html" new file mode 100644 index 0000000..a5bb764 --- /dev/null +++ "b/ops/\347\275\221\347\233\230\344\270\216\345\220\214\346\255\245.html" @@ -0,0 +1,34 @@ + + + + + + + + + 网盘与同步 + + + + + +

网盘与同步

onedrive 个人版 5t 一年40人民币 而且网页版被墙

Seafile 自建网盘

alist 一个展示网盘内容的工具,支持多种云存储

腾讯云服务器自建 一个月30,总共30g

自己家的宽带: +自己的服务器 insync mac上的工具,要付费,可以吧数据同步到本地某个目录 cloudmaster:可以挂载云端硬盘,免费版可以挂载一个, 无法指定目录,固定在/Users/name/Library/CloudStorage/ 目录下

syncthing:p2p,不需自己建

cryptomator: 加密数据后再上传至云盘 https://cryptomator.org/downloads/mac/thanks/

目前的选择:OneDrive

windows

他人智慧

按照分类

国内选云存储确实操心,我也是废了很多时间在这个问题上,但并没有找到一致的解决方案。我个人认为,目前最优方案是分割需求,采取不同的工具:

  1. 根据内容采用不同的服务,照片就 google photo 或者 icloud。我的照片大多从手机上来,这两者是同步最方便(其他网盘甚至都不能及时保证同步),最省电的。而且万一梯子被墙,大不了就是这两天照片同步不了,不是什么大问题。

图书,pdf,文章我用 evernote。国内外能访问,月 10G,手机电脑客户端都很方便,还能打标签,记笔记,全文搜索。

工作文档坚果云,dropbox。同步速度快,技术可靠。onedrive 的客户端(除 win 外)实在是难用,而且我经常遇到同步失败,可能是本地运营商的问题,也可能是客户端的问题,但总之是没法拿来工作的。而 gdrive 我听同事抱怨过几人合作,文件损坏的情况。工作文档力求可靠,绝对不能出错,而且我这里通常文件不大,所以技术是第一位的。

备份 onedrive + arq 5,前者解决存储,后者解决备份技术,量大便宜。

  1. 国内国外访问分割开,这个没办法,就算自建也绕不开 wall。所以工作文档,我是国内用坚果云,国外用 dropbox。备份用 onedrive,如果人在国外 gdrive 可能更划算?

希望我的经验能帮到你,我也期待更好的解决方案。

知乎open in new window

如果有可靠的梯子,Dropbox绝对称得上佼佼者,我同时用Dropbox,Onedrive,老婆用坚果云同步1万多个科研数据,比较下来还是Dropbox最好用最省心,即使是通过梯子,同步速度也是很快的。目前我的方案是,工作数据通过Dropbox同步,家里群晖NAS通过Cloud Sync跟Dropbox和坚果云再双向同步备份一个,这样手机端就可以随时访问dropbox不用梯子了。然后电脑上其他文件在NAS上定期备份一下,再定期做一下冷备份,我觉得应该差不多了。Dropbox用的Basic免费版,通过各种活动扩容了不少,存工作文档基本够用,后期不行的话考虑开个plus就行。之前Google Drive用来存一些手机导出的照片,因为不占空间,有了NAS,基本也可以停用了。所以,如果要找个坚果云的替代品,公有云里面Dropbox是首选。

+ + + diff --git "a/ops/\350\264\255\344\271\260\345\217\202\350\200\203.html" "b/ops/\350\264\255\344\271\260\345\217\202\350\200\203.html" new file mode 100644 index 0000000..f43d23b --- /dev/null +++ "b/ops/\350\264\255\344\271\260\345\217\202\350\200\203.html" @@ -0,0 +1,34 @@ + + + + + + + + + 购买参考 + + + + + + + + + diff --git "a/python/celery\345\274\202\346\255\245\344\273\273\345\212\241.html" "b/python/celery\345\274\202\346\255\245\344\273\273\345\212\241.html" new file mode 100644 index 0000000..5cee3c2 --- /dev/null +++ "b/python/celery\345\274\202\346\255\245\344\273\273\345\212\241.html" @@ -0,0 +1,78 @@ + + + + + + + + + celery异步任务 + + + + + +

celery异步任务

在使用celery时,需要控制异步任务

任务终止有多种情况

  • 任务内部错误
  • celery被杀死
  • 手动结束任务(通过celery控制)

这些需要我们特殊注意

@shared_task(ignore_result=True, time_limit=3600*24)
+def scan(task_id, report_id):
+
+    def handle_stop(*args, **kwargs):
+        pass 
+        # 这里如果需要修改任务状态,则一定需要判断任务是否已结束,
+        # 停止任务之后保留任务记录,
+        # 杀死celery会走这里(SIGQUIT), 然后celery给该进程发送指令
+        # bug:任务已完成,但是celery进程还在,那么退出celery仍旧会执行handle_stop,因此需要在stop中增加对任务状态的判断。
+        # 如果机器断电,肯定走不到这里,所以需要在启动django的时候,将所有运行中的任务修改为失败
+
+    signal.signal(signal.SIGTERM, handle_stop) # 这里注册是对整个celery worker生效,因此
+    try:
+        openvas_scan(task_id, report_id)
+    except Exception as e:
+        with open("/home/bolean/logs/vulscan.los", 'a', encoding='utf8') as f:
+            f.write("漏洞扫描任务_{}_{}异常结束:handle_stop but in try except\n".format(task_id, report_id))
+        logger.warning("handle_stop, but in try except")
+        handle_stop()
+
+

异步任务prefork gevent的选择

使用gevent时,遇到问题


+Traceback (most recent call last):
+  File "/mnt/bolean/venv/lib/python3.10/site-packages/celery/app/trace.py", line 451, in trace_task
+    R = retval = fun(*args, **kwargs)
+  File "/mnt/bolean/venv/lib/python3.10/site-packages/celery/app/trace.py", line 734, in __protected_call__
+    return self.run(*args, **kwargs)
+  File "/mnt/bolean/sdp-backend/fuzz_testing/tasks.py", line 496, in task_test_case_result
+    test_case_obj = FuzzTestingTestCase.objects.get(id=test_case_id)
+  File "/mnt/bolean/venv/lib/python3.10/site-packages/django/db/models/manager.py", line 85, in manager_method
+    return getattr(self.get_queryset(), name)(*args, **kwargs)
+  File "/mnt/bolean/venv/lib/python3.10/site-packages/django/db/models/query.py", line 492, in get
+    num = len(clone)
+  File "/mnt/bolean/venv/lib/python3.10/site-packages/django/db/models/query.py", line 302, in __len__
+    self._fetch_all()
+  File "/mnt/bolean/venv/lib/python3.10/site-packages/django/db/models/query.py", line 1507, in _fetch_all
+    self._result_cache = list(self._iterable_class(self))
+  File "/mnt/bolean/venv/lib/python3.10/site-packages/django/db/models/query.py", line 57, in __iter__
+    results = compiler.execute_sql(
+  File "/mnt/bolean/venv/lib/python3.10/site-packages/django/db/models/sql/compiler.py", line 1359, in execute_sql
+    cursor = self.connection.cursor()
+  File "/mnt/bolean/venv/lib/python3.10/site-packages/django/utils/asyncio.py", line 24, in inner
+    raise SynchronousOnlyOperation(message)
+django.core.exceptions.SynchronousOnlyOperation: You cannot call this from an async context - use a thread or sync_to_async.
+
+

也就是说FuzzTestingTestCase.objects.get(id=test_case_id) 这个不能在gevent下执行

但是 这样的命令时可以执行的 models.Host.objects.filter(id=host_id, status=VulHostStatus.RUNNING.value).exists()

+ + + diff --git a/python/cv/conda.html b/python/cv/conda.html new file mode 100644 index 0000000..ae83c3d --- /dev/null +++ b/python/cv/conda.html @@ -0,0 +1,34 @@ + + + + + + + + + 环境部署 + + + + + +

环境部署

cuda

nvidia-smi 可以查看

cudaa

conda

科学计算时,使用conda可以方便的部署所需的python环境

conda vs anconda

https://zhuanlan.zhihu.com/p/379321816

安装

使用

  1. 查看版本信息 conda -V

  2. 创建虚拟环境 conda create -n your_env_name python=x.x

  3. 激活 conda active your_env_name

  4. 查看已经创建的虚拟环境 conda env list
    conda info -e

  5. 设置国内镜像

conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/

conda config --set show_channel_urls yes

  1. 恢复使用国内

conda config --remove-key channels

+ + + diff --git a/python/cv/cuda.html b/python/cv/cuda.html new file mode 100644 index 0000000..990c887 --- /dev/null +++ b/python/cv/cuda.html @@ -0,0 +1,34 @@ + + + + + + + + + cuda + + + + + + + + + diff --git a/python/cv/index.html b/python/cv/index.html new file mode 100644 index 0000000..d6ed169 --- /dev/null +++ b/python/cv/index.html @@ -0,0 +1,34 @@ + + + + + + + + + 这里是python/cv + + + + + + + + + diff --git a/python/cv/pytorch.html b/python/cv/pytorch.html new file mode 100644 index 0000000..f81fd09 --- /dev/null +++ b/python/cv/pytorch.html @@ -0,0 +1,34 @@ + + + + + + + + + pytorch + + + + + + + + + diff --git "a/python/cv/\345\237\272\344\272\216yolov5\347\232\204cf\350\207\252\347\236\204.html" "b/python/cv/\345\237\272\344\272\216yolov5\347\232\204cf\350\207\252\347\236\204.html" new file mode 100644 index 0000000..28e058e --- /dev/null +++ "b/python/cv/\345\237\272\344\272\216yolov5\347\232\204cf\350\207\252\347\236\204.html" @@ -0,0 +1,42 @@ + + + + + + + + + 基于yolov5的cf自瞄 + + + + + +

基于yolov5的cf自瞄

环境配置

1.安装anconda,创建python3.8的环境 conda create -n py38 python3.8

2.切换到该环境,并下载pytroch>=1.7,使用conda会自动帮我们维护cuda(需要良好的网络) 这里我们使用pytorch2.0.1 pytorch官方open in new window

conda activate py38
+conda install pytorch torchvision torchaudio pytorch-cuda=11.8 -c pytorch -c nvidia 
+
  1. 安装yolov5相关依赖 访问 https://github.com/ultralytics/yolov5/releases/tag/v7.0 获取yolov5最新源代码,并安装相关依赖 实测python3.11安装失败,确实scipy>=1.4的依赖,因此使用py3.8较好
git clone https://github.com/ultralytics/yolov5.git
+cd yolov5
+pip install -r requirements.txt coremltools onnx onnx-simplifier onnxruntime-gpu openvino-dev tensorflow
+
  1. 获取数据集,标注、训练,获得模型

  2. 捕获屏幕,可使用mss,或d3dshot截图(mss库,pyseral库)

pip install pyserial
+pip install mss
+pip install d3dshot
+
  1. 下载ghub dll
+ + + diff --git "a/python/cv/\351\203\250\347\275\262paddle\346\241\206\346\236\266\344\271\213ocr.html" "b/python/cv/\351\203\250\347\275\262paddle\346\241\206\346\236\266\344\271\213ocr.html" new file mode 100644 index 0000000..274f646 --- /dev/null +++ "b/python/cv/\351\203\250\347\275\262paddle\346\241\206\346\236\266\344\271\213ocr.html" @@ -0,0 +1,98 @@ + + + + + + + + + 部署paddle框架之ocr + + + + + +

部署paddle框架之ocr

步骤

1.下载安装anconda 2. 创建一个环境先

conda create -n paddle_env
+conda activate paddle_env
+
# 安装FastDpeloy python包(详细文档请参考`部署环境准备`)
+
+# 约1.2g
+pip install fastdeploy-gpu-python -f https://www.paddlepaddle.org.cn/whl/fastdeploy.html
+
+# 约 3g
+conda config --add channels conda-forge && conda install cudatoolkit=11.2 cudnn=8.2
+
+# 下载部署示例代码
+git clone https://github.com/PaddlePaddle/FastDeploy.git
+cd  FastDeploy/examples/vision/ocr/PP-OCR/cpu-gpu/python
+
+# 如果您希望从PaddleOCR下载示例代码,请运行
+git clone https://github.com/PaddlePaddle/PaddleOCR.git
+# 注意:如果当前分支找不到下面的fastdeploy测试代码,请切换到dygraph分支
+git checkout dygraph
+cd PaddleOCR/deploy/fastdeploy/cpu-gpu/python
+
+# 下载PP-OCRv3文字检测模型
+wget https://paddleocr.bj.bcebos.com/PP-OCRv3/chinese/ch_PP-OCRv3_det_infer.tar
+tar -xvf ch_PP-OCRv3_det_infer.tar
+# 下载文字方向分类器模型
+wget https://paddleocr.bj.bcebos.com/dygraph_v2.0/ch/ch_ppocr_mobile_v2.0_cls_infer.tar
+tar -xvf ch_ppocr_mobile_v2.0_cls_infer.tar
+# 下载PP-OCRv3文字识别模型
+wget https://paddleocr.bj.bcebos.com/PP-OCRv3/chinese/ch_PP-OCRv3_rec_infer.tar
+tar -xvf ch_PP-OCRv3_rec_infer.tar
+
+# 下载预测图片与字典文件
+wget https://gitee.com/paddlepaddle/PaddleOCR/raw/release/2.6/doc/imgs/12.jpg
+wget https://gitee.com/paddlepaddle/PaddleOCR/raw/release/2.6/ppocr/utils/ppocr_keys_v1.txt
+
+# 运行部署示例
+# 在CPU上使用Paddle Inference推理
+python infer.py --det_model ch_PP-OCRv3_det_infer --cls_model ch_ppocr_mobile_v2.0_cls_infer --rec_model ch_PP-OCRv3_rec_infer --rec_label_file ppocr_keys_v1.txt --image 12.jpg --device cpu --backend paddle
+# 在CPU上使用OenVINO推理
+python infer.py --det_model ch_PP-OCRv3_det_infer --cls_model ch_ppocr_mobile_v2.0_cls_infer --rec_model ch_PP-OCRv3_rec_infer --rec_label_file ppocr_keys_v1.txt --image 12.jpg --device cpu --backend openvino
+# 在CPU上使用ONNX Runtime推理
+python infer.py --det_model ch_PP-OCRv3_det_infer --cls_model ch_ppocr_mobile_v2.0_cls_infer --rec_model ch_PP-OCRv3_rec_infer --rec_label_file ppocr_keys_v1.txt --image 12.jpg --device cpu --backend ort
+# 在CPU上使用Paddle Lite推理
+python infer.py --det_model ch_PP-OCRv3_det_infer --cls_model ch_ppocr_mobile_v2.0_cls_infer --rec_model ch_PP-OCRv3_rec_infer --rec_label_file ppocr_keys_v1.txt --image 12.jpg --device cpu --backend pplite
+# 在GPU上使用Paddle Inference推理
+python infer.py --det_model ch_PP-OCRv3_det_infer --cls_model ch_ppocr_mobile_v2.0_cls_infer --rec_model ch_PP-OCRv3_rec_infer --rec_label_file ppocr_keys_v1.txt --image 12.jpg --device gpu --backend paddle
+# 在GPU上使用Paddle TensorRT推理
+python infer.py --det_model ch_PP-OCRv3_det_infer --cls_model ch_ppocr_mobile_v2.0_cls_infer --rec_model ch_PP-OCRv3_rec_infer --rec_label_file ppocr_keys_v1.txt --image 12.jpg --device gpu --backend pptrt
+# 在GPU上使用ONNX Runtime推理
+python infer.py --det_model ch_PP-OCRv3_det_infer --cls_model ch_ppocr_mobile_v2.0_cls_infer --rec_model ch_PP-OCRv3_rec_infer --rec_label_file ppocr_keys_v1.txt --image 12.jpg --device gpu --backend ort
+# 在GPU上使用Nvidia TensorRT推理
+python infer.py --det_model ch_PP-OCRv3_det_infer --cls_model ch_ppocr_mobile_v2.0_cls_infer --rec_model ch_PP-OCRv3_rec_infer --rec_label_file ppocr_keys_v1.txt --image 12.jpg --device gpu --backend trt
+
+# 同时, FastDeploy提供文字检测,文字分类,文字识别三个模型的单独推理,
+# 有需要的用户, 请准备合适的图片, 同时根据自己的需求, 参考infer.py来配置自定义硬件与推理后端.
+
+# 在CPU上,单独使用文字检测模型部署
+python infer_det.py --det_model ch_PP-OCRv3_det_infer  --image 12.jpg --device cpu
+
+# 在CPU上,单独使用文字方向分类模型部署
+python infer_cls.py --cls_model ch_ppocr_mobile_v2.0_cls_infer --image 12.jpg --device cpu
+
+# 在CPU上,单独使用文字识别模型部署
+python infer_rec.py  --rec_model ch_PP-OCRv3_rec_infer --rec_label_file ppocr_keys_v1.txt --image 12.jpg --device cpu
+
+
+ + + diff --git a/python/django.html b/python/django.html new file mode 100644 index 0000000..b8999a0 --- /dev/null +++ b/python/django.html @@ -0,0 +1,242 @@ + + + + + + + + + django + + + + + +

django

作者:PegasusWang 链接:https://www.zhihu.com/question/56472691/answer/292510026 来源:知乎 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

简单的说就是服务端监听 每次 accept 一个新的请求后,开一个处理 这个 socket 客户连接。如果你对底层实现原理感兴趣,可以继续看下去,从 socket 编程的角度来解释多线程 server。最后附上一个异步框架工作过程的视频讲解。这里我们自己撸一个简单的多线程 wsgi server 来看下原理,还是需要深入源码和 socket 编程你才能真正理解。 我们从 python 自带的一个 wsgi server 看下如何实现多线程处理请求。首先你需要熟悉下 wsgi。 看一个最简单的 wsgi app:

#!/usr/bin/env python
+# -*- coding:utf-8 -*-
+
+
+def application(environ, start_response):
+    status = '200 OK'
+    headers = [('Content-Type', 'text/html; charset=utf8')]
+
+    start_response(status, headers)
+    return [b"<h1>Hello</h1>"]
+
+
+if __name__ == '__main__':
+    from wsgiref.simple_server import make_server
+    httpd = make_server('127.0.0.1', 8000, application)
+    httpd.serve_forever()
+

然后用你的开发工具跟进去 make_server 这个函数,看下它的定义:

# lib/python2.7/wsgiref/simple_server.py
+
+def make_server(
+    host, port, app, server_class=WSGIServer, handler_class=WSGIRequestHandler
+):
+    """Create a new WSGI server listening on `host` and `port` for `app`"""
+    server = server_class((host, port), handler_class)
+    server.set_app(app)
+    return server
+
+class WSGIServer(HTTPServer):
+
+    """BaseHTTPServer that implements the Python WSGI protocol"""
+
+    application = None
+
+    def server_bind(self):
+        """Override server_bind to store the server name."""
+        HTTPServer.server_bind(self)
+        self.setup_environ()
+
+    def setup_environ(self):
+        # Set up base environment
+        env = self.base_environ = {}
+        env['SERVER_NAME'] = self.server_name
+        env['GATEWAY_INTERFACE'] = 'CGI/1.1'
+        env['SERVER_PORT'] = str(self.server_port)
+        env['REMOTE_HOST']=''
+        env['CONTENT_LENGTH']=''
+        env['SCRIPT_NAME'] = ''
+
+    def get_app(self):
+        return self.application
+
+    def set_app(self,application):
+        self.application = application
+

看到这个 WSGIServer 定义了吗,继承了一个 HttpServer。我们再继续追一下其定义:

# lib/python2.7/BaseHTTPServer.py
+
+class HTTPServer(SocketServer.TCPServer):
+
+    allow_reuse_address = 1    # Seems to make sense in testing environment
+
+    def server_bind(self):
+        """Override server_bind to store the server name."""
+        SocketServer.TCPServer.server_bind(self)
+        host, port = self.socket.getsockname()[:2]
+        self.server_name = socket.getfqdn(host)
+        self.server_port = port
+

到这里,我们继续追,看到 TcpServer 定义:

# lib/python2.7/SocketServer.py
+
+class TCPServer(BaseServer):
+    """这里我省略了定义"""
+

你还可以发现一个 ThreadingTCPServer 类:我们看下它的定义

class ThreadingTCPServer(ThreadingMixIn, TCPServer): 
+    pass
+

好了,怎么多线程处理请求呢?看下这个 ThreadingMixIn 类是如何实现的:

class ThreadingMixIn:
+    """Mix-in class to handle each request in a new thread."""
+
+    # Decides how threads will act upon termination of the
+    # main process
+    daemon_threads = False
+
+    def process_request_thread(self, request, client_address):
+        """Same as in BaseServer but as a thread.
+
+        In addition, exception handling is done here.
+
+        """
+        try:
+            self.finish_request(request, client_address)
+            self.shutdown_request(request)
+        except:
+            self.handle_error(request, client_address)
+            self.shutdown_request(request)
+
+    def process_request(self, request, client_address):
+        """Start a new thread to process the request."""
+        t = threading.Thread(target = self.process_request_thread,
+                             args = (request, client_address))
+        t.daemon = self.daemon_threads
+        t.start()
+

看到吗,其实就是对于每个新请求,会启动一个新的线程来处理 socket 请求。假如让我们自己实现一个多线程 socket server 应该怎么实现呢?先来写一个简单的单线程 socker echo server:

from socket import *  # 偷懒这么写
+s = socket(AF_INET, SOCK_STREAM)
+s.bind(("", 9000))
+s.listen(5)
+while True:
+    c, a = s.accept()
+    print "Received connection from", a
+    c.send("Hello %s\\n" % a[0])
+    c.close()
+

你可以用telnet之类的工具连上该端口看效果。 这样一次只能处理一个请求,如果想每次来一个请求用一个线程处理呢?我们可以这样做:

import threading
+from socket import *
+
+def handle_client(c):
+    # 处理 client 请求
+    c.send("Hello\n")
+    c.close()
+    return
+
+s = socket(AF_INET, SOCK_STREAM)
+s.bind(("", 9000))
+s.listen(5)
+while True:
+    c, a = s.accept()
+    t = threading.Thread(target=handle_client,
+                         args=(c,))
+

是不是很简单,这其实就是多线程工作的原理,每次 accept 得到一个新的客户端请求以后开一个线程去处理。当然 socket 编程还是偏底层,我们刚才看到了 python 提供了 SocketServer 模块来简化 socket 编程。我们使用 SocketServer 模块来发送数据:

import SocketServer
+import time
+
+class TimeHandler(SocketServer.BaseRequestHandler):
+    def handle(self):
+        # self.request 是一个 client socket 对象
+        self.request.sendall(.ctime() + "\n")
+
+serv = SocketServer.TCPServer(("", 8889), TimeHandler)
+serv.serve_forever()
+

它的执行原理是这样的:server 等待请求到来对每个 socket 连接,server 创建一个新的 handler 类handle() 方法调用处理 client socket 对象,比如发送数据handle() 方法返回后,连接关闭,同时 handler 实例对象销毁但是这个 server 的处理能力很差,一次只能处理一个请求,我们看下这个模块提供了几个类:TCPServer: 同步的 tcp serverForkingTCPServer: 多进程 tcp serverThreadingTCPServer: 多线程 tcp server怎么实现一个多线程 tcp server 呢?很简单:

# 改成 ThreadingTCPServer 就行了,代码其他部分不动
+serv = SocketServer.ThreadingTCPServer(("",8000),TimeHandler)
+serv.serve_forever()
+
+

这样一来,新的请求就能被新的线程去处理了。我们就通过线程来增强了并发能力,当然线程开销比较大,不如用协程(抽空会写个用协程实现异步的socker server)。 如果你浏览该模块,还能看到两个 Mixin:ForkingMixinThreadingMixIn我们只要继承它们就很容易实现一个多进程或者多线程的 server,比如实现一个多线程的 HTTPServerfrom BaseHTTPServer

import HTTPServer
+from SimpleHTTPServer import SimpleHTTPRequestHandler
+from SocketServer import ThreadingMixIn
+
+class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
+    pass
+
+serv = ThreadedHTTPServer(("", 8080), SimpleHTTPRequestHandler)
+

好了,看了这么多让我们改造下 Python 自带的 wsgi server 为多线程的:

import time
+import SocketServer
+import socket
+from SimpleHTTPServer import SimpleHTTPRequestHandler
+from SocketServer import ThreadingMixIn
+
+
+class HTTPServer(SocketServer.TCPServer):
+
+    allow_reuse_address = 1    # Seems to make sense in testing environment
+
+    def server_bind(self):
+        """Override server_bind to store the server name."""
+        SocketServer.TCPServer.server_bind(self)
+        host, port = self.socket.getsockname()[:2]
+        self.server_name = socket.getfqdn(host)
+        self.server_port = port
+
+
+class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
+    pass
+
+
+class ThreadWSGIServer(ThreadedHTTPServer):
+
+    """BaseHTTPServer that implements the Python WSGI protocol"""
+
+    application = None
+
+    def server_bind(self):
+        """Override server_bind to store the server name."""
+        HTTPServer.server_bind(self)
+        self.setup_environ()
+
+    def setup_environ(self):
+        # Set up base environment
+        env = self.base_environ = {}
+        env['SERVER_NAME'] = self.server_name
+        env['GATEWAY_INTERFACE'] = 'CGI/1.1'
+        env['SERVER_PORT'] = str(self.server_port)
+        env['REMOTE_HOST'] = ''
+        env['CONTENT_LENGTH'] = ''
+        env['SCRIPT_NAME'] = ''
+
+    def get_app(self):
+        return self.application
+
+    def set_app(self, application):
+        self.application = application
+
+
+def application(environ, start_response):
+    time.sleep(10)    # 注意这里的 sleep
+    status = '200 OK'
+    headers = [('Content-Type', 'text/html; charset=utf8')]
+
+    start_response(status, headers)
+    return [b"<h1>Hello</h1>"]
+
+
+if __name__ == '__main__':
+    from wsgiref.simple_server import make_server
+    httpd = make_server('127.0.0.1', 8000, application, server_class=ThreadWSGIServer)
+    httpd.serve_forever()
+
+

对了,我们怎么证明这个真是多线程的 wsgi server 了呢,很简单。你看我加了个 sleep(10)。 如果你在之前的单线程 wsgi server 跑,你可以开俩个终端去 curl,curl 完一个赶紧切到另一个 curl 。 单线程你会发现几乎是 10 + 10 秒,但是下边这个多线程 wsgi server 你会发现大概只用10秒,两个请求是并发的(当然我这种测试很 low,你可以随便用一个网络测试工具)。虽然我没看过 django wsgi server 的实现,但是它自己实现的开发服务器原理应该是类似的。如果你能坚持看到这里,是更明白了呢还是更懵了呢?你可以看下PegasusWang/notebooks 这个是手撸 web 框架的教程,看完你就对 wsgi,如何自己写 框架以及 gunicorn 部署有点概念了。最近在学习异步框架的工作原理,感兴趣可以看看,之后还会出个协程版本的。

https://zhuanlan.zhihu.com/p/42044997

+ + + diff --git a/python/index.html b/python/index.html new file mode 100644 index 0000000..30c4577 --- /dev/null +++ b/python/index.html @@ -0,0 +1,34 @@ + + + + + + + + + 这里是python + + + + + + + + + diff --git "a/python/pydantic\347\211\271\346\256\212\351\252\214\350\257\201.html" "b/python/pydantic\347\211\271\346\256\212\351\252\214\350\257\201.html" new file mode 100644 index 0000000..aaa30d9 --- /dev/null +++ "b/python/pydantic\347\211\271\346\256\212\351\252\214\350\257\201.html" @@ -0,0 +1,34 @@ + + + + + + + + + pydantic特殊验证 + + + + + + + + + diff --git "a/python/pythongui-\347\210\266\345\255\220\350\277\233\347\250\213\344\270\216\345\255\244\345\204\277\350\277\233\347\250\213.html" "b/python/pythongui-\347\210\266\345\255\220\350\277\233\347\250\213\344\270\216\345\255\244\345\204\277\350\277\233\347\250\213.html" new file mode 100644 index 0000000..8ad73e0 --- /dev/null +++ "b/python/pythongui-\347\210\266\345\255\220\350\277\233\347\250\213\344\270\216\345\255\244\345\204\277\350\277\233\347\250\213.html" @@ -0,0 +1,34 @@ + + + + + + + + + pythongui-父子进程与孤儿进程 + + + + + +

pythongui-父子进程与孤儿进程

https://www.cnblogs.com/Tour/p/5180801.html

先介绍一下我的项目,项目的目标是使用一台计算机,通过usb集线板,控制n台手机 其中不同的任务封装为不同的程序,在python gui中通过subprocess.Popen 方法异步调用

这些python程序会通过adb库获取到所有已经连接到的安卓手机,并通过multiprocessing库并行执行相应的任务

这时,有一个需求是停止当前的演示程序,我们知道,通过subprocess.Popen方法可以获取一个进程对象,通过调用kill方法或terminate方法即可杀死进程

但是随之而来的,就是子进程变为孤儿进程,仍在继续执行

通过查阅相关资料,我了解到可以设置deamon=True来使主进程在正常退出时,子进程也退出,但是我这里是中断操作

+ + + diff --git "a/python/python\344\273\273\345\212\241\351\230\237\345\210\227.html" "b/python/python\344\273\273\345\212\241\351\230\237\345\210\227.html" new file mode 100644 index 0000000..a15792e --- /dev/null +++ "b/python/python\344\273\273\345\212\241\351\230\237\345\210\227.html" @@ -0,0 +1,46 @@ + + + + + + + + + 任务队列 + + + + + +

任务队列

流程

最初版本

1.通过接口获取到今天的数据(.csv)

  1. 执行程序

aps版本

定义一个定时任务, 然后每天稳定拉取数据,到任务队列中, 程序读取此队列, 并将爬取结果保存到结果队列

四个进程

  • 任务获取进程
  • 爬虫进程
  • 上传进程
  • 监控进程

两个队列

  • 任务队列
  • 结果队列

这种方式看起来非常专业, 但是有时候临时需要跑一部分数据时, 就会很麻烦, 因此我想这在队列这里解决, 从python 自带的队列替换为 redis的list

redis 版本

在将python 的队列更改为redis 后, 我又编写了 redis_push.py , 可以手动将文件中的数据推送到redis 队列中, 非常的好用

但是过了周六周日两天后, 我发现 APScheduler 又出现了bug, 没有按时拉取数据, 我不由得怀疑这个库的稳定性 ,因此我又回到了crontab

crontab 版本

经过了近一个月, 多次的更改,我探究了最适合的方案

需要有以下几个优点

  • 可随时跑残缺数据 python run.py file
  • 网站变化频繁, 只需修改spider 文件即可, 比较方便

+- source_data/      原始数据
+- aaa/   爬虫aaa
+    --  spider.py  爬虫主体, 仅负责爬取数据
+    --  main.py     读取文件, 解析数据, 上传数据等等
+    --  data/        爬到的数据
+- bbb/
+    --  spider.py
+    --  main.py     
+    --  data/
+- download_data.py  拉取原始数据, 使用crontab 例行化
+
+
+ + + diff --git "a/python/python\344\275\277\347\224\250\346\255\243\345\210\231\350\277\207\346\273\244\350\241\250\346\203\205\347\254\246\345\217\267.html" "b/python/python\344\275\277\347\224\250\346\255\243\345\210\231\350\277\207\346\273\244\350\241\250\346\203\205\347\254\246\345\217\267.html" new file mode 100644 index 0000000..38af910 --- /dev/null +++ "b/python/python\344\275\277\347\224\250\346\255\243\345\210\231\350\277\207\346\273\244\350\241\250\346\203\205\347\254\246\345\217\267.html" @@ -0,0 +1,58 @@ + + + + + + + + + python使用正则过滤表情符号 + + + + + +

python使用正则过滤表情符号

def remove_emojis(data):
+    emoj = re.compile("["
+        u"\U0001F600-\U0001F64F"  # emoticons
+        u"\U0001F300-\U0001F5FF"  # symbols & pictographs
+        u"\U0001F680-\U0001F6FF"  # transport & map symbols
+        u"\U0001F1E0-\U0001F1FF"  # flags (iOS)
+        # u"\U00002500-\U00002BEF"  # chinese char
+        u"\U00002702-\U000027B0"
+        u"\U00002702-\U000027B0"
+        # u"\U000024C2-\U0001F251" //中文
+        u"\U0001f926-\U0001f937"
+        u"\U00010000-\U0010ffff"
+        u"\u2640-\u2642" 
+        u"\u2600-\u2B55"
+        u"\u200d"
+        u"\u23cf"
+        u"\u23e9"
+        u"\u231a"
+        u"\ufe0f"  # dingbats
+        u"\u3030"
+                      "]+", re.UNICODE)
+    return re.sub(emoj, '', data)
+
+
+
+ + + diff --git "a/python/python\345\257\271\346\257\224\344\270\244\344\270\252\346\227\266\351\227\264\345\255\227\347\254\246\344\270\262.html" "b/python/python\345\257\271\346\257\224\344\270\244\344\270\252\346\227\266\351\227\264\345\255\227\347\254\246\344\270\262.html" new file mode 100644 index 0000000..55c9fb3 --- /dev/null +++ "b/python/python\345\257\271\346\257\224\344\270\244\344\270\252\346\227\266\351\227\264\345\255\227\347\254\246\344\270\262.html" @@ -0,0 +1,40 @@ + + + + + + + + + python对比两个时间字符串 + + + + + + + + + diff --git "a/python/python\346\211\223\345\215\260\350\241\214\345\217\267.html" "b/python/python\346\211\223\345\215\260\350\241\214\345\217\267.html" new file mode 100644 index 0000000..ba8b465 --- /dev/null +++ "b/python/python\346\211\223\345\215\260\350\241\214\345\217\267.html" @@ -0,0 +1,86 @@ + + + + + + + + + skill + + + + + +

skill

python 打印行号

import sys
+
+print(sys._getframe().f_code.co_name)  # 当前函数名
+print(sys._getframe().f_lineno)  # 当前行号
+

python 获取当前脚本或其他模块的所有类

背景: 一个py文件里有40+个类, 需要创建实例并执行共有的run方法, 简单的方法是写40+行代码完成任务, 也可以通过python高阶函数使用


+import sys, inspect
+
+
+def get_class(current_module):
+    cls = []
+    print("class:",end='')
+    for name, obj in inspect.getmembers(current_module):
+        if inspect.isclass(obj):
+            print(name, end=',')
+            cls.append(obj)
+    print()
+    return cls
+
+
+class A():
+    def run(self):
+        print("current class:", self.__class__.__name__)
+
+
+class B():
+    def run(self):
+        print("current class:", self.__class__.__name__)
+
+
+class C():
+    def run(self):
+        print("current class:", self.__class__.__name__)
+
+
+class D():
+    def run(self):
+        print("current class:", self.__class__.__name__)
+
+
+if __name__ == '__main__':
+    current_module = sys.modules[__name__]  获取当前文件对象
+
+    for cls in get_class(current_module):
+        cls().run()
+
+
+

运行结果

class:A,B,C,D,
+current class: A
+current class: B
+current class: C
+current class: D
+
+
+ + + diff --git "a/python/\344\273\245\345\233\276\346\220\234\345\233\276.html" "b/python/\344\273\245\345\233\276\346\220\234\345\233\276.html" new file mode 100644 index 0000000..6da616d --- /dev/null +++ "b/python/\344\273\245\345\233\276\346\220\234\345\233\276.html" @@ -0,0 +1,34 @@ + + + + + + + + + 以图搜图 + + + + + + + + + diff --git "a/python/\346\234\272\345\231\250\345\255\246\344\271\240-nsfw.html" "b/python/\346\234\272\345\231\250\345\255\246\344\271\240-nsfw.html" new file mode 100644 index 0000000..4fc4469 --- /dev/null +++ "b/python/\346\234\272\345\231\250\345\255\246\344\271\240-nsfw.html" @@ -0,0 +1,43 @@ + + + + + + + + + nsfw + + + + + +

nsfw

调研

0. https://github.com/yahoo/open_nsfw

python2

训练好的模型 https://github.com/TechnikEmpire/NsfwSqueezenet

python3版本(不可用) -> https://github.com/rahiel/open_nsfw-

可远程调用版本 版本1 https://github.com/loretoparisi/docker/tree/master/nsfwaas

版本2 https://github.com/nikos-glikis/nsfw-docker

https://github.com/rockyzhengwu/nsfw

1. https://github.com/devzwy/open_nsfw_android

离线识别,基于TensorFlow实现。识别只需20ms,可断网测试,成功率99%,调用只要一行代码,从雅虎的开源项目open_nsfw移植,该模型文件可用于iOS、java、C++等平台

python 版本(识别率很低) https://github.com/devzwy/NSFW-Python

2. https://github.com/mdietrichstein/tensorflow-open_nsfw

仅支持jpeg

3. https://github.com/yangbisheng2009/nsfw-resnet

要自己训练

4. https://github.com/EugenCepoi/nsfw_api

一键docker 带api 可流式读取输出(非常快,目前使用)

docker run -it -p 127.0.0.1:5000:5000/tcp --env PORT=5000 eugencepoi/nsfw_api:latest
+
+
+curl -X GET -H 'Content-Type: application/json' http://localhost:5000\?url\=https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png
+
+{
+  "score": 0.00016061133646871895,
+  "url": "https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png"
+}
+
+ + + diff --git "a/python/\347\210\254\350\231\253-pdd\350\260\203\347\240\224.html" "b/python/\347\210\254\350\231\253-pdd\350\260\203\347\240\224.html" new file mode 100644 index 0000000..c81f268 --- /dev/null +++ "b/python/\347\210\254\350\231\253-pdd\350\260\203\347\240\224.html" @@ -0,0 +1,34 @@ + + + + + + + + + pdd调研 + + + + + +

pdd调研

需求: 全量爬取拼多多商品

拼多多有以下客户端:

  • h5端
  • app端

其中h5端有加密,无法破解

h5端

  1. 首页推荐下滑 不需要登录, 按推荐展示商品, 每个分类最多2000商品, 即使登录了也只有2000个
  2. 分类 需要登录, 理论上可获取选择的分类的所有商品
  3. 搜索 需要登录, 理论上可获取和搜索关键词有关的的所有商品

渠道一:首页

推荐: 下滑拉取400个后, 显示查看更多

这个推荐手动拉到600左右, 如果太快就会触发验证

登录后, 在首页进行下滑, 可拉取该分类的最多2000条商品(根据不同账号, 推荐可能不同)

经过尝试, 虽然有加密, 但是一个token可以多次发送请求(可模拟器拉取一次后重放), 但是最多有2000条数据

且频率太快会触发安全验证(使用模拟下滑,.8-20秒发一次请求, 近300次请求不会触发验证)

安全验证

demo1

渠道二:分类

参数如下

渠道三: 搜索

经测试这种方式获取商品无上限, 例如搜索手机 , page 设置为50000 仍可获取到数据(可能会给重复数据)

  • 需要关键词
+ + + diff --git "a/python/\347\210\254\350\231\253-\344\275\277\347\224\250\346\216\245\345\217\243\350\277\207tx\346\273\221\345\235\227\351\252\214\350\257\201.html" "b/python/\347\210\254\350\231\253-\344\275\277\347\224\250\346\216\245\345\217\243\350\277\207tx\346\273\221\345\235\227\351\252\214\350\257\201.html" new file mode 100644 index 0000000..00137c1 --- /dev/null +++ "b/python/\347\210\254\350\231\253-\344\275\277\347\224\250\346\216\245\345\217\243\350\277\207tx\346\273\221\345\235\227\351\252\214\350\257\201.html" @@ -0,0 +1,95 @@ + + + + + + + + + 使用接口过tx滑块验证 + + + + + +

使用接口过tx滑块验证

使用的接口 https://www.notion.so/T-X-HTTP-637bca0458704724a5692a0e283ff5aa

过验证码场景: 富途 https://passport.futunn.com/?target=https%3A%2F%2Fsetup2.futu5.com%2F&lang=zh-cn

0x00 抓包分析

首先我们手动操作一波, 发现三个和验证码有关的请求

  • 其中第一个是用来展示验证码的, 抓包可以得到aid

  • 第二个则是我们将滑块滑倒尾端后发出的验证请求, 如果成功则可以得到ticketrandstr

ticket和randstr

  • 接着是注册账号时发送短信验证码的请求, 可以看到里面有上个请求获取到的ticketrandstr字段

也就是说, 只要获取到ticket 等信息, 就可以发送短信验证码

0x01 获取ticket和randstr

以下代码是对api的进一步封装

用到的接口: https://www.notion.so/T-X-HTTP-637bca0458704724a5692a0e283ff5aa


+def get_ticket() -> dict:
+    import json
+    import time
+    import requests
+    """
+    返回可过验证码的ticket和randstr
+    :return:
+    {"ticket":"t039_9QCC5xXgpqgLzf2a3PsLAiF2mWGTo9NuFTGKnifb1Xp42wUqn5JUQ-XrAwsNLg4M3fvoZ-cQnCuXVKcDX5nOsPbozWMeQ_","randstr":"@qHZ"}
+    """
+    print("需要人机验证,获取中~")
+
+    aid = "2081701200" # 替换为你的aid
+    user = "******"
+    password = "******"
+
+    session = requests.session()
+
+    url = "http://gengduo.me/api/v1/alihd/wstask_tengx?aid={}&servertype=1&refer=&newtype=1&cap_cd=&asig=&user={}&pass={}".format(
+        aid,
+        user, password)
+
+    # 尝试三次, 获取任务ID
+    for i in range(3):
+        try:
+            res = session.get(url, timeout=7).json()
+            print(res)
+        except:
+            pass
+        else:  # 成功则停止
+            break
+    else:  # 均失败, 返回空
+        return {}
+
+    if "request_id" in res:
+
+        request_id = res["request_id"]
+
+        url = 'http://gengduo.me/api/v1/alihd/wstask_result?request_id={request_id}'.format(request_id=request_id)
+        print(url)
+        # 轮询60次
+        for i in range(60):
+            print(">>>", i)
+            try:
+                res = session.get(url, timeout=7).json()
+                print(res)
+            except:
+                continue
+
+            if "_status" in res and res["_status"] is True:
+                try:
+                    res_json = json.loads(res["_data"])
+                    ticket = res_json["data"]
+                    return ticket
+                except Exception as e:
+                    print(e)
+            elif "_data" in res and "error" in str(res["_data"]):
+                return {}
+            time.sleep(3)
+
+    return {}
+
+ + + diff --git "a/python/\347\210\254\350\231\253-\350\256\260\344\270\200\346\254\241\350\277\207\345\217\215\347\210\254\350\231\253\347\232\204\347\273\217\345\216\206.html" "b/python/\347\210\254\350\231\253-\350\256\260\344\270\200\346\254\241\350\277\207\345\217\215\347\210\254\350\231\253\347\232\204\347\273\217\345\216\206.html" new file mode 100644 index 0000000..ab10070 --- /dev/null +++ "b/python/\347\210\254\350\231\253-\350\256\260\344\270\200\346\254\241\350\277\207\345\217\215\347\210\254\350\231\253\347\232\204\347\273\217\345\216\206.html" @@ -0,0 +1,34 @@ + + + + + + + + + 记一次过反爬虫的经历 + + + + + +

记一次过反爬虫的经历

fakame.com

反爬表现特征: 1.云服务器第一次访问被拦截, 而本地调试时请求正常发送 2.被拦截时会返回一动态的js代码, 作用是重定向到当前网址 3.加上动态代理后, 即使访问该重定向网址, 下次请求也会被拦截 4.每天8点, 先使用代码访问, 被拦截, 此时使用浏览器访问一次, 然后再使用代码, 可正常工作

网站反爬模式 默认所有ip为黑ip, 当用户第一次访问时, 返回js代码重定向到原网页, 如果此次请求成功, 将该ip加白, 有效期约为1天

特征解读

  1. 调试时已使用浏览器访问过网站, 已经被加白
  2. 动态代理每次请求ip不同, 因此访问重定向网址的ip与原ip不同, 无法被加白, 即使被加白, 下次访问ip又发生变化, 无法抓取
  3. 使用本地浏览器访问, 即访问重定向网站, 给自己的ip加白, 此后使用本机ip即可正常访问
+ + + diff --git "a/python/\347\210\254\350\231\253-\350\277\207\347\256\200\345\215\225js\345\212\240\345\257\206.html" "b/python/\347\210\254\350\231\253-\350\277\207\347\256\200\345\215\225js\345\212\240\345\257\206.html" new file mode 100644 index 0000000..6e3e01d --- /dev/null +++ "b/python/\347\210\254\350\231\253-\350\277\207\347\256\200\345\215\225js\345\212\240\345\257\206.html" @@ -0,0 +1,93 @@ + + + + + + + + + 过简单js加密 + + + + + +

过简单js加密

背景: 爬虫需要过加密的, 其中使用了第三方库 pkg: https://www.cnblogs.com/mordom/p/8337337.html

0x00 chrome debug

在这里可以看到, 使用的是crypto-js

根据google 搜索到了这么一篇博文

https://www.codenong.com/js1a0dde3f1b57/

无奈本人对python 的Crypto模块 不太熟悉, 没能实现

只能编写js,并使用node 进行测试

使用前需安装node环境


+const r = require('crypto-js');
+
+const { program } = require('commander');
+//https://github.com/tj/commander.js
+
+let crypto = {
+    Encrypt: function (t) {
+        var e = r.enc.Utf8.parse("t171420100302rsa")
+            , n = r.enc.Utf8.parse("t171420100302rsa")
+            , o = r.enc.Utf8.parse(t)
+            , i = r.AES.encrypt(o, e, {
+            iv: n,
+            mode: r.mode.CBC,
+            padding: r.pad.Pkcs7
+        });
+        return r.enc.Base64.stringify(i.ciphertext)
+    },
+    decoto: function (t) {
+        var e = r.enc.Base64.parse(t)
+            , n = r.enc.Utf8.parse("t171420100302rsa")
+            , o = r.enc.Utf8.parse("t171420100302rsa")
+            , i = r.lib.CipherParams.create({
+            ciphertext: e
+        });
+        return r.AES.decrypt(i, n, {
+            iv: o,
+            mode: r.mode.CBC,
+            padding: r.pad.Pkcs7
+        }).toString(r.enc.Utf8)
+    }
+}
+
+let Encrypt=crypto.Encrypt;
+let Decoto = crypto.decoto;
+
+program
+    .version('0.0.1')
+    .option("-E, --Encrypt <str>","Encrypt str")
+    .option("-D, --Decoto <str>","decoto str")
+
+program.parse(process.argv);
+
+if (program.Encrypt){
+    console.log(Encrypt(program.Encrypt))
+}
+
+if (program.Decoto){
+    console.log(Decoto(program.Decoto))
+}
+
+

初始化npm 并安装js依赖

npm init
+npm i crypto-js
+npm i commander
+

然后使用命令行进行调用


+node main.js -D xxxxx
+
+

为了方便调用, 使用pkg 打包为linux 的可执行文件

pkg: https://www.cnblogs.com/mordom/p/8337337.html

pkg .
+
+

即可生成文件, 缺点是可执行文件比较大, 优点是开发成本比较低

使用:

-E 进行加密 -D 进行解密

+ + + diff --git "a/python/\350\277\233\347\250\213\347\256\241\347\220\206.html" "b/python/\350\277\233\347\250\213\347\256\241\347\220\206.html" new file mode 100644 index 0000000..765d834 --- /dev/null +++ "b/python/\350\277\233\347\250\213\347\256\241\347\220\206.html" @@ -0,0 +1,82 @@ + + + + + + + + + 进程管理 + + + + + +

进程管理

supervisor 管理进程简明教程:https://www.jianshu.com/p/bf2b3f4dec73 使用 supervisor 管理进程:https://liyangliang.me/posts/2015/06/using-supervisor/ https://www.cnblogs.com/wswang/p/5795766.html

方便管理 =配置复杂

为实现进程管理, 需要先对程序做以下分类

  • demo 程序: 可能会出问题的程序, 需要保留程序上下文 1.使用screen 进行操作
screen -S screen_Name
+
+python3 main.py
+

2.nohup python3 main.py > log 2>&1 &

  • 例行任务
  1. crontab

这种是比较简单的方式,缺点在于移动文件时不好管理

  1. superversion + schedule(APScheduler)

配置较复杂 带有web接口

superversion program.conf

[program:zhonghua]
+command=python3 APScheduler_main.py              ; the program (relative uses PATH, can take args)
+process_name=%(program_name)s ; process_name expr (default %(program_name)s)
+numprocs=1                    ; number of processes copies to start (def 1)
+directory=/home/ubuntu/zorsong/zhonghua_task                ; directory to cwd to before exec (def no cwd)
+;umask=022                     ; umask for process (default None)
+;priority=999                  ; the relative start priority (default 999)
+;autostart=true                ; start at supervisord start (default: true)
+;startsecs=1                   ; # of secs prog must stay up to be running (def. 1)
+;startretries=3                ; max # of serial start failures when starting (default 3)
+autorestart=unexpected        ; when to restart if exited after running (def: unexpected)
+exitcodes=0,2                 ; 'expected' exit codes used with autorestart (default 0,2)
+stopsignal=QUIT               ; signal used to kill process (default TERM)
+stopwaitsecs=10               ; max num secs to wait b4 SIGKILL (default 10)
+stopasgroup=false             ; send stop signal to the UNIX process group (default false)
+killasgroup=false             ; SIGKILL the UNIX process group (def false)
+user=ubuntu                   ; setuid to this UNIX account to run the program
+redirect_stderr=true          ; redirect proc stderr to stdout (default false)
+stdout_logfile=/home/ubuntu/zorsong/zhonghua_task/logfile        ; stdout log path, NONE for none; default AUTO
+;stdout_logfile_maxbytes=1MB   ; max # logfile bytes b4 rotation (default 50MB)
+;stdout_logfile_backups=10     ; # of stdout logfile backups (default 10)
+;stdout_capture_maxbytes=1MB   ; number of bytes in 'capturemode' (default 0)
+;stdout_events_enabled=false   ; emit events on stdout writes (default false)
+stderr_logfile=/home/ubuntu/zorsong/zhonghua_task/logfile        ; stderr log path, NONE for none; default AUTO
+;stderr_logfile_maxbytes=1MB   ; max # logfile bytes b4 rotation (default 50MB)
+;stderr_logfile_backups=10     ; # of stderr logfile backups (default 10)
+;stderr_capture_maxbytes=1MB   ; number of bytes in 'capturemode' (default 0)
+;stderr_events_enabled=false   ; emit events on stderr writes (default false)
+;environment=A="1",B="2"       ; process environment additions (def no adds)
+;serverurl=AUTO                ; override serverurl computation (childutils)
+

APScheduler


+def foo():
+    print("foo")
+
+
+from apscheduler.schedulers.background import BackgroundScheduler
+
+sch = BackgroundScheduler()
+
+sch.add_job(foo) # 不加时间, 会在sch.start()后立即执行
+sch.add_job(foo,'interval',minutes=5)  # 每5分钟执行一次
+sch.add_job(foo, 'cron', hour='9') # 每天的09:00 执行一次
+
+
+
+

20201026

http://www.vuln.cn/9121

+ + + diff --git "a/python/\351\235\242\350\257\225.html" "b/python/\351\235\242\350\257\225.html" new file mode 100644 index 0000000..2c6acf8 --- /dev/null +++ "b/python/\351\235\242\350\257\225.html" @@ -0,0 +1,37 @@ + + + + + + + + + 面试 + + + + + +

面试

1,网络 1.1 本地dns服务器如何获取

通过DHCP协议从DHCP服务器获取,就和自动获取IP一样,DNS只不过是其中一个option。

计算机设置自动获取后,它会向网内发送个广播,当服务器收到这个包时就会回应个地址给这台机器,机器取到回应后设置完成 路由器也是类似,从他连接到的运行商发送这个广播 通过DHCP协议从DHCP服务器获取,就和自动获取IP一样,DNS只不过是其中一个option。

车小胖​​计算机网络话题下的优秀答主19 人赞同了该回答主机在启动时,会发送一个广播DHCP报文来寻找DHCP服务器,来给自己分配上网用的IP地址,DNS服务器地址等信息:什么是DHCP?Dynamic Host Configuration Protocol,动态主机配置协议,它主要用来给用户的电脑分配以下信息:1)IP地址 如 10.1.1.22)IP地址对应的子网掩码 如 255.255.255.0 DHCP 里有很多选项option,子网掩码放在option 1里3)缺省网关 如 10.1.1.1 Option 3,当主机10.1.1.2 想访问互联网,需要把IP包先发给缺省网关10.1.1.1,然后缺省网关再发送给它上游的路由器4)DNS 服务器 如8.8.8.8这个DNS 服务器就是放在option 6信息字段里的,DNS 服务器负责域名和IP地址的翻译,比如你访问 http://www.zhihu.com ,DNS服务器可以把它翻译成115.21.37.139,然后主机就可以用这个IP地址来访问知乎了。那DHCP的安全漏洞是什么呢?如果一个邪恶软件伪造不同的Mac地址,不断发送DHCP discovery,比如1000个,如果没有安全措施,DHCP server很有可能就分配1000个IP地址给它,因为server是根据client Mac来分配IP的,这样很快就可以把地址池资源耗尽,其它的用户因为没有地址可用而无法上网!应对方法:配置DHCP option 82,DHCP discovery途径二层交换机时,交换机修改报文,增加option 82信息,即这条消息是从哪个端口收到的,把这个端口信息添加到DHCP discovery 报文里,服务器根据 “client Mac地址+ 交换机端口号” 来分配IP,即任意一个交换机端口最多分配一个IP,即使采用伪造的不同的Mac地址来请求也是一个!这就是DHCP反欺骗措施,DHCP Anti-Spoofing!----------回复@唐诗宋词评论----------Option 82 是 谁来添加到DHCP 消息报文? 添加到什么报文? 主要作用是什么?主要作用是什么?1) line ID 让Radius server 可以知道DHCP client location 信息,比如 switch x Port x/x/x ,可以提供安全认证服务器更多关于 client 具体位置,可以 tracking and logging DHCP client2) remote ID ,可以让DHCP server 依靠 remote ID + Hardware MAC 来分配IP,避免伪造 MAC 耗尽IP地址池。谁来添加到DHCP 消息报文?1) DHCP snooping switch2) DHCP relay router添加到什么报文? 1) DHCP Discovery2) DHCP Request编辑于 2016-07-17 10:08​赞同 19​​5 条评论​分享​收藏​喜欢收起​

由器转发 DNS 请求 1.2 更新域名指向,边缘dns服务器如何知道更新了 缓存获取后,再次查询

1.3 qq.com 如何承受这么大的访问量 cdn, dns根据所在地提供不同的ip 然后做负载均衡

1.4 https 密钥交换算法 DH算法 密钥协商算法

1.5 cc攻击, ddos攻击原理

tcp land攻击

1、SYN Flood攻击 SYN Flood攻击是当前网络上最为常见的DDoS攻击,它利用了TCP协议实现上的一个缺陷。通过向网络服务所在端口发送大量的伪造源地址的攻击报文,就可能造成目标服务器中的半开连接队列被占满,从而阻止其他合法用户进行访问。 [7] 2、UDP Flood攻击 UDP Flood是日渐猖厥的流量型DDoS攻击,原理也很简单。常见的情况是利用大量UDP小包冲击DNS服务器或Radius认证服务器、流媒体视频服务器。由于UDP协议是一种无连接的服务,在UDP Flood攻击中,攻击者可发送大量伪造源IP地址的小UDP包。 [7] 3、ICMP Flood攻击 ICMP Flood攻击属于流量型的攻击方式,是利用大的流量给服务器带来较大的负载,影响服务器的正常服务。由于目前很多防火墙直接过滤ICMP报文。因此ICMP Flood出现的频度较低。 [7] 4、Connection Flood攻击 Connection Flood是典型的利用小流量冲击大带宽网络服务的攻击方式,这种攻击的原理是利用真实的IP地址向服务器发起大量的连接。并且建立连接之后很长时间不释放,占用服务器的资源,造成服务器上残余连接(WAIT状态)过多,效率降低,甚至资源耗尽,无法响应其他客户所发起的链接。 [7] 5、HTTP Get攻击 这种攻击主要是针对存在ASP、JSP、PHP、CGI等脚本程序,特征是和服务器建立正常的TCP连接,并不断的向脚本程序提交查询、列表等大量耗费数据库资源的调用。这种攻击的特点是可以绕过普通的防火墙防护,可通过Proxy代理实施攻击,缺点是攻击静态页面的网站效果不佳,会暴露攻击者的lP地址。 [7] 6、UDP DNS Query Flood攻击 UDP DNS Query Flood攻击采用的方法是向被攻击的服务器发送大量的域名解析请求,通常请求解析的域名是随机生成或者是网络世界上根本不存在的域名。域名解析的过程给服务器带来了很大的负载,每秒钟域名解析请求超过一定的数量就会造成DNS服务器解析域名超时。 [7]

代理CC攻击是黑客借助代理服务器生成指向受害主机的合法网页请求,实现DDoS,和伪装就叫:cc(Challenge Collapsar)

1.6 负载均衡,如果一个机器挂掉,其他的机器应该怎么办

 按照处理极限接手部分流量,其余流量则丢弃
+

1.7 快速移动的情况下,会发生什么(基站带宽改变,基站切换

优化: 使用httpdns,内置一些ip服务器做httpdns
+    使用quic
+

弱网络优化

HttpDNSLib 1)lbs 返回服务器 ip 而非域名 2)本地缓存 lbs ip 地址备用,请求 lbs 时优先使用 ip 而非域名

icmp ping

+ + + diff --git a/router/index.html b/router/index.html new file mode 100644 index 0000000..a6a8d5c --- /dev/null +++ b/router/index.html @@ -0,0 +1,34 @@ + + + + + + + + + 这里是router + + + + + + + + + diff --git a/router/zerotier.html b/router/zerotier.html new file mode 100644 index 0000000..f91e011 --- /dev/null +++ b/router/zerotier.html @@ -0,0 +1,46 @@ + + + + + + + + + zerotier + + + + + +

zerotier

https://stray.love/jiao-cheng/zerotier-zhong-jie-jiao-cheng https://zhuanlan.zhihu.com/p/383471270

使用zerotier完成内网穿透

优点:无需公网ip,即可大概率p2p打通 缺点:移动的设备需要每台设备都安装客户端, 固定的设备可通过路由器安装zerotier直接管理

实战配置

zerotier安装在路由器时,可以自动管理 但是路由器装不了, 所以被迫安装到了n1盒子上,也可以通过设置路由表进行管理

网络情况如下:

hz ,路由器lan 192.168.5.1/24 安装zerotier客户端,分配虚拟ip 10.144.250.49 wz, 路由器lan 192.168.2.1/24 不能装zerotier客户端, 由局域网设备n1(192.168.2.190)安装,并分配虚拟ip 10.144.199.120

1 zerotier 配置

1.1设置路由

1.2 设置这两个设备允许 Allow Ethernet Bridging

zerotier 设置结束

2 客户端设置

2.1 路由器客户端设置

路由器可傻瓜配置,只需要勾选 "自动允许客户端 NAT" 即可

2.2 n1盒子设置

n1盒子没有提供简单的web ui界面, 因此需要手动管理路由表

首先使用 zerotier-cli listnetworks 命令, 查看网卡id

root@aml:~# zerotier-cli listnetworks
+200 listnetworks <nwid> <name> <mac> <status> <type> <dev> <ZT assigned ips>
+200 listnetworks 8bd5124fd6c7fc63 zt-home 62:0f:bf:0d:13:f1 OK PRIVATE zt0 10.144.199.120/16
+

PRIVATE 后面的zt0是网卡id

第一步,打开盒子的网络转发功能

#临时生效
+echo "1" > /proc/sys/net/ipv4/ip_forward
+#永久生效,需要修改sysctl.conf,然后执行sysctl -p
+net.ipv4.ip_forward = 1
+

接下来,处理防火墙规则

sudo iptables -A FORWARD -i zt0 -j ACCEPT
+sudo iptables -A FORWARD -o zt0 -j ACCEPT
+sudo iptables -t nat -A POSTROUTING  ! -o lo -j MASQUERADE
+

2023 10月16日, 发现这样的规则会导致该设备离线后其他设备不会通过网关访问其他设备,而是通过该设备,很尴尬

这里 zt0 为zerotier虚拟网卡 保存iptable规则

sudo apt-get install iptables-persistent
+sudo sh -c "iptables-save > /etc/iptables/rules.v4"
+
+ + + diff --git "a/router/zerotier\343\200\201\344\272\214\347\272\247\350\267\257\347\224\261\343\200\201DMZ.html" "b/router/zerotier\343\200\201\344\272\214\347\272\247\350\267\257\347\224\261\343\200\201DMZ.html" new file mode 100644 index 0000000..5f635a7 --- /dev/null +++ "b/router/zerotier\343\200\201\344\272\214\347\272\247\350\267\257\347\224\261\343\200\201DMZ.html" @@ -0,0 +1,34 @@ + + + + + + + + + zerotier、二级路由、DMZ + + + + + + + + + diff --git "a/router/\345\274\202\345\234\260\347\273\204\347\275\221.html" "b/router/\345\274\202\345\234\260\347\273\204\347\275\221.html" new file mode 100644 index 0000000..f99a458 --- /dev/null +++ "b/router/\345\274\202\345\234\260\347\273\204\347\275\221.html" @@ -0,0 +1,39 @@ + + + + + + + + + 异地组网 + + + + + +

异地组网

设备:k2p

配置:128g ram 千兆wifi、局域网 负责拨号,拥有公共ip

1.开机时执行的命令,用途为将2.xx这台设备转发到自己的36000端口

iptables -t nat -A PREROUTING -i pppoe-wan -p tcp --dport 36000 -j DNAT --to-destination 192.168.2.xx:22
+
  1. ddns

使用ardnspod实现,基于腾讯云的域名管理

使用方式:在脚本最后加入以下几行即可

arToken="token1,token2"
+arDdnsCheck domain.com www
+arDdnsCheck domain.com "*"
+arDdnsCheck domain.com @
+
  1. ss server 添加clash规则后,可直接通过clash访问内网资源,优点是不暴露端口在公网,无安全问题

斐讯n1盒子

配置: 安装ubuntu系统,arm芯片, 千兆网口,一个hdmi 两个usb2.0: 打印机 兄弟7060d 斐讯h1 1t硬盘

安装的软件: cups : 打印机管理 端口761 uwsgi: 托管python服务 supervistor: 负责管理后端启停 /etc/supervisor/conf.d/ docker: -mariadb 配置有主从同步服务

zerotier-one: 异地组网客户端 zabbix-agent: zabbix客户端,因为没有arm版本,当时还配置了好久 redis-server: 当时给爬虫服务使用的,后来就没用了 openresty: 学了手lua,不错 nginx: 可以转发一下 motion: 链接usb摄像头后,可以实时推流到web上jpeg-stream(无声音) fail2ban: 防ssh密码破解

wr1200js

配置:4核arm处理器,usb2.0口,千兆wifi、局域网 系统:openwrt

软件: zerotier客户端 wol 网络唤醒

可选:挂载硬盘

cloud server hk

安装 zerotier moon 服务器

+ + + diff --git "a/router/\347\233\221\346\216\247\346\237\220\344\270\252\346\234\215\345\212\241\346\255\243\345\270\270\350\277\220\350\241\214.html" "b/router/\347\233\221\346\216\247\346\237\220\344\270\252\346\234\215\345\212\241\346\255\243\345\270\270\350\277\220\350\241\214.html" new file mode 100644 index 0000000..eb3db64 --- /dev/null +++ "b/router/\347\233\221\346\216\247\346\237\220\344\270\252\346\234\215\345\212\241\346\255\243\345\270\270\350\277\220\350\241\214.html" @@ -0,0 +1,59 @@ + + + + + + + + + 监控某个服务正常运行 + + + + + +

监控某个服务正常运行

#!/bin/sh
+check_time=120
+sserver_port=`uci get sserver.config.port`
+
+vcount=0
+while [ "1" = "1" ]  #死循环
+do
+  sleep $check_time
+
+   icount=`ps -w|grep ssr-server |grep -v grep |wc -l`
+
+   if [ $icount = 0  ] ;then
+   logger -t "ssr" "restart ssr server!"
+   /etc/init.d/sserver restart
+   exit 0
+   fi
+
+   icount=`iptables -S|grep  $sserver_port|wc -l`
+   if [ $icount = 0  ] ;then
+   logger -t "sserver" "recover iptables,restart ssr server!"
+   /etc/init.d/sserver restart
+   exit 0
+   fi
+
+done
+
+ + + diff --git "a/router/\347\256\200\346\230\223\347\233\221\346\216\247.html" "b/router/\347\256\200\346\230\223\347\233\221\346\216\247.html" new file mode 100644 index 0000000..f5f4952 --- /dev/null +++ "b/router/\347\256\200\346\230\223\347\233\221\346\216\247.html" @@ -0,0 +1,34 @@ + + + + + + + + + 简易监控 + + + + + +

简易监控

23.9.20 开始写方案

方案1:POE录像机

tp 6104 120块钱 4口poe硬盘录像机 + 摄像头80*2 + 硬盘100~200 =280+100~280

可直播,可回放,不占用其他设备负载

方案2:单摄像头(纯娱乐)

海康摄像头dc(100) + n1(0)+1t(0) =100

串流直播,回放(存疑)

换新方案

pc+1tsata固态,拆下来500g用作POE录像机使用

pc+sata硬盘盒(利用海康威视1t)

鉴于目前我的1tssd也不够用,还是得早日提上日程 早用早享受

花费与寿命

4t机械=389 97.25 1t sata = 300 300 500g sata = 134 300 2t nvme = 500 250

综合以上,1tsata无任何意义,500gsata也无任何意义

本地pc花费老家pc花费监控方案年份总花费分析
1t+2t+4t5001t+pcie x4转接10poe录像机+poe摄像头✖️2+500g机械 130+80✖️24年510+x爽 ,4t可以退役给nas用
1t+1t+4t0500gsata159poe录像机+poe摄像机✖️2+500g机械 130+80✖️22年159+xsata老土,18年的ssd掉速

实践下,如果今天插上去测速还ok,则方案2 不ok,方案1

9.20 记录: c2000pro 速度还可以,而且里面有不少资料,还是留着较好

9.22记录

部署了开源nvr系统,购买了poe交换机+poe摄像头 n1部署nvr https://linuxpip.org/open-source-nvr/

最终方案

设备方案价格
NVR录像机斐讯n1+Shinobi$0(之前就有,150)开源录像系统,其实不是很专业,需要代替可以买80的录像机+好点的硬盘
硬盘斐讯h1 1t$0(之前就有,约250)
poe交换机tplink 百兆4口¥41
室内水星4312p$75
院子mipc428pw100
大门口mipc451100
双摄MIPC552W179

9.25

实际测试发现,2.8mm视角也比较小,并且半球没有云台,也不能动,因此4312p放一个差一点的位置,然后补充

mipc428pw 和

mipc451

即可完成构建

10.8

最终方案就是75+40+100的方案

+ + + diff --git "a/router/\350\256\260\344\270\200\346\254\241\347\240\264\350\247\243\345\244\251\347\277\274\347\275\221\345\205\263.html" "b/router/\350\256\260\344\270\200\346\254\241\347\240\264\350\247\243\345\244\251\347\277\274\347\275\221\345\205\263.html" new file mode 100644 index 0000000..1212942 --- /dev/null +++ "b/router/\350\256\260\344\270\200\346\254\241\347\240\264\350\247\243\345\244\251\347\277\274\347\275\221\345\205\263.html" @@ -0,0 +1,56 @@ + + + + + + + + + 记一次破解天翼网关 + + + + + +

记一次破解天翼网关

https://xz.aliyun.com/t/9046#toc-1

  1. 设备信息 设备信息

2.首先获取超级密码 访问http://192.168.1.1:8080/cgi-bin/baseinfoSet.cgi

凯撒密码,编写python脚本来解密

  1. 使用超级账号密码登录

访问http://192.168.1.1:8080/cgi-bin/telnet.cgi通过InputCmd参数可以直接执行系统命令, 访问http://192.168.1.1:8080/cgi-bin/submit.cgi可以看到执行结果,

编写简单的脚本, 方便看回显

from urllib import parse
+import requests
+
+host = "http://192.168.1.1:8080"
+send_url = host+"/cgi-bin/telnet.cgi"
+response_url = host+"/cgi-bin/submit.cgi"
+
+def f(cmd):
+	HEADERS = {'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'}
+	data = {"InputCmd":cmd}
+
+	r = requests.post(send_url, data=parse.urlencode(data)).text
+	print("[-] send done:")
+	print(r)
+
+	rep = requests.get(response_url).text
+	print('[-] resp:')
+	print(rep)
+if __name__ == '__main__':
+	while True:
+	    c = input("")
+	    f(c)
+
  1. 打开telnet

访问 192.168.1.1:8080/cgi-bin/telnetenable.cgi?telnetenable=1 即可

  1. 寻找telnet密码

尝试写入/etc/passwd, 但是不起作用,想着看看有没有明文密码

cat /flash/cfg/agentconf/factory.conf 没有 在/var 目录下找到一个密码文件,确定了

cat /var/telWan_passwd

+ + + diff --git a/video/ffmpeg.html b/video/ffmpeg.html new file mode 100644 index 0000000..ee85bc8 --- /dev/null +++ b/video/ffmpeg.html @@ -0,0 +1,56 @@ + + + + + + + + + ffmpeg + + + + + +

ffmpeg

接入监控系统后, 就需要对这些视频做一定的处理,水星安防app提供的云服务有事件录像、人形识别等功能,大概一年90元, 我们肯定是不会掏这个钱的,所以就需要自己处理

第一个应用 制作延时摄像

  1. 从每日的太阳升起到日落,将越12小时的视频,快进到10分钟左右
ffmpeg  -hwaccel auto -i /Users/teletraan/Downloads/2023-10-10T11-15-01.mp4 -c:v libx265  -vf "setpts=0.02*PTS,scale=640:-1,fps=15" -b:v 500K -an -ss 00:00:00 -t 00:01:00 output.mp4
+

由于我们录像机设置的最大是15分钟,所以还需要拼接一下

15分钟要102秒,那么12小时就是4×102s×12 =

优化,直接用copy,就不用重新编码了

ffmpeg  -hwaccel auto -i /Users/teletraan/Downloads/2023-10-10T11-15-01.mp4 -c:v copy  -vf "setpts=0.02*PTS,scale=640:-1,fps=15" -b:v 500K -an -ss 00:00:00 -t 00:01:00 output.mp4
+

错误的,改了码率,不能这么搞

windows 将一个目录下的所有图片剪辑为视频

@echo off
+setlocal enabledelayedexpansion
+
+set "input_folder=%~dp0"
+set "output_file=output.mp4"
+set "framerate=30"
+set "codec=hevc_qsv"
+set "pix_fmt=yuv420p"
+set "filelist=filelist.txt"
+set "input_files="
+(for %%i in ("*.jpg") do (
+  echo file '%%i'
+)) > "%filelist%"
+
+
+
+e:/ffmpeg-master-latest-win64-gpl/bin/ffmpeg.exe -f concat -safe 0 -i  "%filelist%"  -framerate %framerate% -c:v %codec% -pix_fmt %pix_fmt% "%output_file%"
+
+pause
+
+
+ + + diff --git a/video/index.html b/video/index.html new file mode 100644 index 0000000..96bbab0 --- /dev/null +++ b/video/index.html @@ -0,0 +1,34 @@ + + + + + + + + + 这里是video + + + + + + + + + diff --git "a/video/shinobi-\345\274\200\346\272\220NVR.html" "b/video/shinobi-\345\274\200\346\272\220NVR.html" new file mode 100644 index 0000000..5d24c54 --- /dev/null +++ "b/video/shinobi-\345\274\200\346\272\220NVR.html" @@ -0,0 +1,34 @@ + + + + + + + + + shinobi-开源NVR + + + + + + + + + diff --git "a/web/23-5-22pg\346\225\260\346\215\256\345\272\223\347\232\204\344\270\255\346\226\207\346\216\222\345\272\217.html" "b/web/23-5-22pg\346\225\260\346\215\256\345\272\223\347\232\204\344\270\255\346\226\207\346\216\222\345\272\217.html" new file mode 100644 index 0000000..3adc4b9 --- /dev/null +++ "b/web/23-5-22pg\346\225\260\346\215\256\345\272\223\347\232\204\344\270\255\346\226\207\346\216\222\345\272\217.html" @@ -0,0 +1,34 @@ + + + + + + + + + 23-5-22pg数据库的中文排序 + + + + + +

23-5-22pg数据库的中文排序

背景

pg数据库存储的utf8字段,需要按拼音进行排序

方案1

方案1:在了解到gbk编码按照拼音顺序编码后,使用convert函数将utf8字段转为gbk,然后ordr by即可 ORDER BY CONVERT(ColumnName USING gbk) 小问题:存储的emjoy等不能转换为utf8的,则会查询失败, 需要禁止输入非gbk编码

方案2

方案2:select * from process order by name collate "zh_CN" 前提db有这个collate,可以通过select * from pg_collation;查询

group_member_ids: list[StringIDInput] = Field(alias="group_members")

+ + + diff --git a/web/index.html b/web/index.html new file mode 100644 index 0000000..c61477b --- /dev/null +++ b/web/index.html @@ -0,0 +1,34 @@ + + + + + + + + + 这里是web + + + + + + + + + diff --git "a/web/mysql_\345\205\250\350\241\250\346\237\245\350\257\242\347\232\204\344\274\230\345\214\226.html" "b/web/mysql_\345\205\250\350\241\250\346\237\245\350\257\242\347\232\204\344\274\230\345\214\226.html" new file mode 100644 index 0000000..4eba4dd --- /dev/null +++ "b/web/mysql_\345\205\250\350\241\250\346\237\245\350\257\242\347\232\204\344\274\230\345\214\226.html" @@ -0,0 +1,43 @@ + + + + + + + + + [mysql]全表查询的优化 + + + + + +

[mysql]全表查询的优化

执行分析命令时,对于一个量级为110w的数据表进行全表扫描

ALTER TABLE `xx`
+ADD PRIMARY KEY `id_score` (`id`, `score`),
+DROP INDEX `PRIMARY`;
+
+

47EBC50493F2C9AA5C928783E2D41307

先改一下表里的数据

update xxx set score=-1 where score is null
+    -> ;
+Query OK, 2637 rows affected (8.47 sec)
+Rows matched: 2637  Changed: 2637  Warnings: 0
+
+

然后改表的默认值,

然后加上这个联合主键

加主键的时候,我把score放前面了,又不行,必须把id放第一个

加完以后,又出问题

为什么推荐InnoDB引擎使用自增主键? https://www.kancloud.cn/db-design/mysql-dba/596722

MySQL PARTITION 分区表使用教程 https://news.sangniao.com/p/2684880278 结合业务场景选择分区键,避免跨分区查询 对分区表进行查询最好在WHERE从句中包含分区键 具有主键或唯一索引的表,主键或唯一索引必须是分区键的一部分(这也是为什么我们上面分区时去掉了主键登录日志id(login_id)的原因,不然就无法按照上面的按年份进行分区,所以分区表其实更适合在MyISAM引擎中) 关于MyISAM和Innodb的索引区别

1.关于自动增长

myisam引擎的自动增长列必须是索引,如果是组合索引,自动增长可以不是第一列,他可以根据前面几列进行排序后递增。

innodb引擎的自动增长咧必须是索引,如果是组合索引也必须是组合索引的第一列。

mysql 分区的真正作用? https://www.zhihu.com/question/38418707

+ + + diff --git "a/web/project_\351\241\271\347\233\256\351\205\215\347\275\256\346\226\207\344\273\266.html" "b/web/project_\351\241\271\347\233\256\351\205\215\347\275\256\346\226\207\344\273\266.html" new file mode 100644 index 0000000..ca02809 --- /dev/null +++ "b/web/project_\351\241\271\347\233\256\351\205\215\347\275\256\346\226\207\344\273\266.html" @@ -0,0 +1,34 @@ + + + + + + + + + [project]项目配置文件 + + + + + +

[project]项目配置文件

2023-7-11

配置 pre-commit 以及setup.py setup.cfg, pyproject.toml

https://pre-commit.com/#python

使用flake8检查python代码格式 问题: 变量名确实长,因此超过了一行120字符限制

解决方案: 在这行后面加上 # noqa

https://github.com/PyCQA/flake8 ines that contain a # noqa comment at the end will not issue warnings.

+ + + diff --git "a/web/python_\344\273\245\345\233\276\346\220\234\345\233\276\347\263\273\347\273\237.html" "b/web/python_\344\273\245\345\233\276\346\220\234\345\233\276\347\263\273\347\273\237.html" new file mode 100644 index 0000000..61551f5 --- /dev/null +++ "b/web/python_\344\273\245\345\233\276\346\220\234\345\233\276\347\263\273\347\273\237.html" @@ -0,0 +1,34 @@ + + + + + + + + + [python]以图搜图系统 + + + + + + + + + diff --git "a/web/web_web\346\250\241\345\236\213.html" "b/web/web_web\346\250\241\345\236\213.html" new file mode 100644 index 0000000..427a32d --- /dev/null +++ "b/web/web_web\346\250\241\345\236\213.html" @@ -0,0 +1,34 @@ + + + + + + + + + [web]web模型 + + + + + + + + + diff --git "a/web/web_\346\234\215\345\212\241\347\253\257\346\270\262\346\237\223\344\270\216\345\256\242\346\210\267\347\253\257\346\270\262\346\237\223.html" "b/web/web_\346\234\215\345\212\241\347\253\257\346\270\262\346\237\223\344\270\216\345\256\242\346\210\267\347\253\257\346\270\262\346\237\223.html" new file mode 100644 index 0000000..b6132aa --- /dev/null +++ "b/web/web_\346\234\215\345\212\241\347\253\257\346\270\262\346\237\223\344\270\216\345\256\242\346\210\267\347\253\257\346\270\262\346\237\223.html" @@ -0,0 +1,34 @@ + + + + + + + + + [web]服务端渲染与客户端渲染 + + + + + +

[web]服务端渲染与客户端渲染

大学时,老师教了jsp,使用的是模版引擎

在我第一次写web应用时,使用的后台是django,django支持模版引擎渲染,但是我觉得非常恶心,因为他要把html和模版语言写在一块

当时写的是内部网站,不需要seo,使用html写完代码以后,其中获取数据的部分使用jquery的ajax动态获取

后来编写博客的时候,用到vnote以及衍生品viki,viki使用js在前端将md文档渲染为html,非常好用,但是缺点是搜索引擎无法识别动态内容 借此机会,了解了一下服务端渲染和客户端渲染 现在pc上的老牌网站,例如淘宝,在2013年左右使用的是php,将php嵌入到html中,通过php调用函数,渲染html,在2014年,淘宝改为使用nodejs的中间层技术

淘宝、天猫首页技术从Node.js 换回PHP了么? https://www.zhihu.com/question/54777923

+ + + diff --git "a/web/web_\350\243\205\351\245\260\345\231\250\346\250\241\345\274\217\345\234\250canvas\351\207\214\347\232\204\345\272\224\347\224\250.html" "b/web/web_\350\243\205\351\245\260\345\231\250\346\250\241\345\274\217\345\234\250canvas\351\207\214\347\232\204\345\272\224\347\224\250.html" new file mode 100644 index 0000000..8694cce --- /dev/null +++ "b/web/web_\350\243\205\351\245\260\345\231\250\346\250\241\345\274\217\345\234\250canvas\351\207\214\347\232\204\345\272\224\347\224\250.html" @@ -0,0 +1,34 @@ + + + + + + + + + [web]装饰器模式在canvas里的应用 + + + + + + + + + diff --git "a/web/\344\271\220\350\247\202\351\224\201\343\200\201\346\202\262\350\247\202\351\224\201\343\200\201\345\210\206\345\270\203\345\274\217\351\224\201.html" "b/web/\344\271\220\350\247\202\351\224\201\343\200\201\346\202\262\350\247\202\351\224\201\343\200\201\345\210\206\345\270\203\345\274\217\351\224\201.html" new file mode 100644 index 0000000..1788901 --- /dev/null +++ "b/web/\344\271\220\350\247\202\351\224\201\343\200\201\346\202\262\350\247\202\351\224\201\343\200\201\345\210\206\345\270\203\345\274\217\351\224\201.html" @@ -0,0 +1,152 @@ + + + + + + + + + 乐观锁、悲观锁、分布式锁 + + + + + +

乐观锁、悲观锁、分布式锁

假设抢购系统,1000用户在10秒内购买一个商品

"""
+并发更新速度测试
+ab -n 1000 -c 100 http://127.0.0.1:8000/
+"""
+
+from fastapi import FastAPI
+import pymysql
+# SQLALCHEMY_DATABASE_URL = "postgresql://postgres:postgres@localhost:5432/demo2"
+import redis
+from redis import Redis
+
+app = FastAPI()
+pool = redis.ConnectionPool(host='localhost', port=6379, max_connections=100) # 链接数量要大于最大并发数,否则实例化不出来
+
+
+def leguan(retry=0, db=None):
+    if db is None:
+        db = pymysql.Connect(host='localhost', user='root', password='example', db='moye')
+    db.begin()
+    cursor = db.cursor()
+    cursor.execute("select * from emp where id=1")
+    version = cursor.fetchone()[2]
+
+    count = cursor.execute("update emp set value=value-1, version=version+1 where id=1 and value-1>=0 and version="+str(version))
+    if count == 0:
+        db.rollback()
+        if retry <= 4:
+            return leguan(retry + 1, db)
+        return {"shibai":"shibail"}
+    db.commit()
+    return {"Hello": "World"}
+
+def beiguan():
+    db = pymysql.Connect(host='localhost', user='root', password='example', db='moye')
+    db.begin()
+    cursor = db.cursor()
+    cursor.execute("select * from emp where id=1 for update")
+    version = cursor.fetchone()[2]
+
+    count = cursor.execute("update emp set value=value-1, version=version+1 where id=1 and value-1>=0")
+    if count == 0:
+        db.rollback()
+        return {"shibai":"shibail"}
+    db.commit()
+    return {"Hello": "World"}
+
+def redis_():
+    redis_client: Redis = redis.Redis(connection_pool=pool)
+    # redis_client: Redis = redis.from_url("redis://localhost:6379")
+    with redis_client.lock(name='id_1',sleep=0.01, timeout=60, blocking_timeout=60):
+
+        db = pymysql.Connect(host='localhost', user='root', password='example', db='moye')
+        db.begin()
+        cursor = db.cursor()
+        cursor.execute("select * from emp where id=1")
+        version = cursor.fetchone()[2]
+
+        count = cursor.execute("update emp set value=value-1, version=version+1 where id=1 and value-1>=0")
+        if count == 0:
+            db.rollback()
+            return {"shibai": "shibail"}
+        db.commit()
+        return {"Hello": "World"}
+
+
+@app.get("/")
+def read_root():
+    # leguan() # 乐观锁100个请求,在一秒内只能成功5-15个
+    # beiguan() # 悲观锁速度没慢多少的同时,全部成功了
+    redis_() # redis由于需要cpu sleep ,属于是又慢又怕锁超时
+
+

使用ab压测

100并发

悲观锁

乐观锁

可惜只有6个购买成功

并发100, 总共1000个

乐观锁 成功147个

悲观锁

又快又好,真离谱

redis

并发200,总共1000

悲观锁

redis 分布式锁

悲观锁+async sqlalchemy

reids锁+ async aioreids

慢的离谱,cpu90%

"""
+并发更新速度测试
+ab -n 1000 -c 100 http://127.0.0.1:8000/
+"""
+
+from fastapi import FastAPI
+# SQLALCHEMY_DATABASE_URL = "postgresql://postgres:postgres@localhost:5432/demo2"
+import sqlalchemy as sa
+from aioredis import Redis
+import aioredis
+app = FastAPI()
+# pool = aioredis.ConnectionPool(host='localhost', port=6379, max_connections=100) # 链接数量要大于最大并发数,否则实例化不出来
+from sqlalchemy.ext.asyncio import create_async_engine
+
+engine = create_async_engine(
+    "mysql+asyncmy://root:example@localhost:3306/moye"
+)
+
+async def beiguan():
+
+    async with engine.connect() as db, db.begin():
+
+
+        result = await db.execute(sa.text("select * from emp where id=1 for update"))
+        version = result.fetchone()[2]
+
+        count = await db.execute(sa.text("update emp set value=value-1, version=version+1 where id=1 and value-1>=0"))
+    return {"Hello": "World"}
+
+async def redis_():
+    # redis_client: Redis = redis.Redis(connection_pool=pool)
+    redis_client: Redis = Redis.from_url("redis://localhost:6379")
+    async with redis_client.lock(name='id_1',sleep=0.01, timeout=60, blocking_timeout=60):
+        async with engine.connect() as db, db.begin():
+            result = await db.execute(sa.text("select * from emp where id=1"))
+            version = result.fetchone()[2]
+
+            count = await db.execute(sa.text("update emp set value=value-1, version=version+1 where id=1 and value-1>=0"))
+
+
+
+@app.get("/")
+async def read_root():
+    # leguan() # 乐观锁100个请求,在一秒内只能成功5-15个b
+    await beiguan() # 悲观锁速度没慢多少的同时,全部成功了
+    # await redis_() # redis由于需要cpu sleep ,属于是又慢又怕锁超时
+
+
+ + + diff --git "a/web/\345\237\272\344\272\216ddd\347\232\204\346\236\266\346\236\204.html" "b/web/\345\237\272\344\272\216ddd\347\232\204\346\236\266\346\236\204.html" new file mode 100644 index 0000000..a11dd2c --- /dev/null +++ "b/web/\345\237\272\344\272\216ddd\347\232\204\346\236\266\346\236\204.html" @@ -0,0 +1,34 @@ + + + + + + + + + 基于ddd的架构 + + + + + + + + + diff --git "a/web/\345\274\202\346\255\245\344\273\273\345\212\241\344\270\216\344\272\213\345\212\241_.html" "b/web/\345\274\202\346\255\245\344\273\273\345\212\241\344\270\216\344\272\213\345\212\241_.html" new file mode 100644 index 0000000..49fc4c2 --- /dev/null +++ "b/web/\345\274\202\346\255\245\344\273\273\345\212\241\344\270\216\344\272\213\345\212\241_.html" @@ -0,0 +1,34 @@ + + + + + + + + + [异步任务与事务] + + + + + +

[异步任务与事务]

业务

用户可以开始任务

任务状态变成等待中,提交给celery,等待执行

这是,用户可以撤销任务

撤销任务:

任务状态变成ready

所以当还没被消费时,用户就撤销了,就很完美

但是已经开始消费了,用户再撤销,就会有bug

事务A start_task事务B revoke_task
判断Task state是否为cancel
修改Task state=cancel Save Task
update_network_check_item_state = SEARCH_CATALOG Save NetworkCheckItem
成功或失败 Save NetworkCheckItem
等待0.8秒
Save NetworkCheckItem
修改Task = RUNNING
Save Task
提交事务提交事务
+ + + diff --git "a/web/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234_iptables.html" "b/web/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234_iptables.html" new file mode 100644 index 0000000..ed9a391 --- /dev/null +++ "b/web/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234_iptables.html" @@ -0,0 +1,34 @@ + + + + + + + + + [计算机网络]iptables + + + + + +

[计算机网络]iptables

-A {INPUT|OUTPUT}:将防火墙规则附加到输入或输出链。 -p icmp:使用 ICMP 协议。 -p icmp --icmp-type {0|8}OR :icmp 按数字(如“0”)或名称(如“回显回复”)匹配选项。--icmp-type {echo-reply|echo-request} -j {ACCEPT|REJECT|DROP}:告诉 Linux 如果数据包匹配该怎么做。接受表示让数据包通过。丢弃或拒绝表示将数据包丢弃在地板上。当您希望另一端(客户端或主机或机器人)知道端口无法访问时,请使用 REJECT 并使用 DROP 连接到您不希望人员/机器人/客户端看到的主机。 -m state --state NEW,ESTABLISHED,RELATED:使用 or 选项进行扩展 icmp 数据包匹配。这些值是:--ctstate-m state INVALID:数据包与未知连接关联。 NEW:数据包已启动新连接或以其他方式与未在两个方向上看到数据包的连接相关联。 ESTABLISHED:数据包与在两个方向上看到数据包的连接相关联。 RELATED:数据包正在启动新连接,但与现有连接相关联,例如 FTP 数据传输或 ICMP 错误。

https://wooyun.js.org/drops/Iptables%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B.html

+ + + diff --git "a/web/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234_ip\345\215\217\350\256\256.html" "b/web/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234_ip\345\215\217\350\256\256.html" new file mode 100644 index 0000000..706b7af --- /dev/null +++ "b/web/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234_ip\345\215\217\350\256\256.html" @@ -0,0 +1,34 @@ + + + + + + + + + [计算机网络]ip协议 + + + + + +

[计算机网络]ip协议

ip协议非常简单,没有丢失重传等额外功能,这是因为作为底层协议,要尽可能简单高效,而且可以让应用层自己选择想要的传输协议(例如在线视频就不需要重发之前的包,因为他们已经过期)

特性

  • 以逐跳的方式发送数据报
  • 不可靠,但尽力而为
  • 无连接

+ + + diff --git "a/web/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234_\350\267\257\347\224\261\345\231\250.html" "b/web/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234_\350\267\257\347\224\261\345\231\250.html" new file mode 100644 index 0000000..284e117 --- /dev/null +++ "b/web/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234_\350\267\257\347\224\261\345\231\250.html" @@ -0,0 +1,34 @@ + + + + + + + + + [计算机网络]路由器 + + + + + + + + + diff --git "a/web/\350\277\220\347\273\264\347\233\270\345\205\263.html" "b/web/\350\277\220\347\273\264\347\233\270\345\205\263.html" new file mode 100644 index 0000000..8858f5b --- /dev/null +++ "b/web/\350\277\220\347\273\264\347\233\270\345\205\263.html" @@ -0,0 +1,34 @@ + + + + + + + + + 运维相关 + + + + + +

运维相关

想在多个机器上使用同一个 shell 脚本有什么好建议吗?

https://www.v2ex.com/t/845974 curl 执行暴露出来的脚本 scp git 私仓 ansible or saltstack (推荐后者)

安卓自动化:

https://github.com/Jinnrry/RobotHelper

tcp 连接 netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'

iptables 做端口转发

iptables -t nat -A PREROUTING -i pppoe-wan -p tcp --dport 36000 -j DNAT --to-destination 192.168.2.190:22

+ + +