commit aff3ffb68dd5f6f5efa8c43425ff03918de5f981 Author: Yufan Sheng <syhily@gmail.com> Date: Fri Jun 14 02:11:26 2024 +0800 A new start diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..f06235c --- /dev/null +++ b/.dockerignore @@ -0,0 +1,2 @@ +node_modules +dist diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..6845745 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,25 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true + +[*.{md,mdx}] +indent_size = tab +trim_trailing_whitespace = false + +[*.{js,jsx,ts,tsx,css,less,sass,scss}] +indent_style = space +indent_size = 2 + +[*.{yml,yaml,json}] +indent_style = space +indent_size = 2 + +[*.go] +indent_style = tab + +[Makefile] +indent_size = tab \ No newline at end of file diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..e9667ee --- /dev/null +++ b/.env.example @@ -0,0 +1,14 @@ +# Since the ".env" file is gitignored, you can use the ".env.example" file to +# build a new ".env" file when you clone the repo. Keep this file up-to-date +# when you add new variables to `.env`. + +# This file will be committed to version control, so make sure not to have any +# secrets in it. If you are cloning this repo, create a copy of this file named +# ".env" and populate it with your secrets. + +# PostgreSQL configuration. +POSTGRES_HOST= +POSTGRES_PORT= +POSTGRES_USERNAME= +POSTGRES_PASSWORD= +POSTGRES_DATABASE= diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..58b89fd --- /dev/null +++ b/.gitattributes @@ -0,0 +1,162 @@ +# This file is inspired by https://github.com/alexkaratarakis/gitattributes +# +# Auto detect text files and perform LF normalization +# http://davidlaing.com/2012/09/19/customise-your-gitattributes-to-become-a-git-ninja/ +* text=auto + +# The above will handle all files NOT found below +# These files are text and should be normalized (Convert crlf => lf) + +*.bat text eol=crlf +*.cmd text eol=crlf +*.coffee text +*.css text +*.cql text +*.df text +*.ejs text +*.html text +*.java text +*.js text +*.json text +*.less text +*.properties text +*.sass text +*.scss text +*.sh text +*.sql text +*.txt text +*.ts text +*.xml text +*.yaml text +*.yml text + +# Documents +*.doc diff=astextplain +*.DOC diff=astextplain +*.docx diff=astextplain +*.DOCX diff=astextplain +*.dot diff=astextplain +*.DOT diff=astextplain +*.pdf diff=astextplain +*.PDF diff=astextplain +*.rtf diff=astextplain +*.RTF diff=astextplain +*.markdown text +*.md text +*.adoc text +*.textile text +*.mustache text +*.csv text +*.tab text +*.tsv text +*.txt text +*.config text +AUTHORS text +CHANGELOG text +CHANGES text +CONTRIBUTING text +COPYING text +copyright text +*COPYRIGHT* text +INSTALL text +license text +LICENSE text +NEWS text +readme text +*README* text +TODO text +Jenkinsfile text + +# Graphics +*.png binary +*.jpg binary +*.jpeg binary +*.gif binary +*.tif binary +*.tiff binary +*.ico binary +# SVG treated as an asset (binary) by default. If you want to treat it as text, +# comment-out the following line and uncomment the line after. +*.svg binary +#*.svg text +*.eps binary +*.sketch binary + +# These files are binary and should be left untouched +# (binary is a macro for -text -diff) +*.class binary +*.jar binary +*.war binary + +## LINTERS +.csslintrc text +.eslintrc text +.jscsrc text +.jshintrc text +.jshintignore text +.stylelintrc text +.prettierignore text +.prettierrc text +.scalafmt.conf text + +## CONFIGS +*.bowerrc text +*.conf text +*.config text +.editorconfig text +.gitattributes text +.gitconfig text +.gitignore text +.htaccess text +*.npmignore text + +## HEROKU +Procfile text +.slugignore text + +## AUDIO +*.kar binary +*.m4a binary +*.mid binary +*.midi binary +*.mp3 binary +*.ogg binary +*.ra binary + +## VIDEO +*.3gpp binary +*.3gp binary +*.as binary +*.asf binary +*.asx binary +*.fla binary +*.flv binary +*.m4v binary +*.mng binary +*.mov binary +*.mp4 binary +*.mpeg binary +*.mpg binary +*.swc binary +*.swf binary +*.webm binary + +## ARCHIVES +*.7z binary +*.gz binary +*.rar binary +*.tar binary +*.zip binary + +## FONTS +*.ttf binary +*.eot binary +*.otf binary +*.woff binary +*.woff2 binary + +## Bun +*.lockb binary diff=lockb + +## License File +LICENSE.* text diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..216c1ea --- /dev/null +++ b/.gitignore @@ -0,0 +1,29 @@ +# build output +dist/ +.zeabur/ + +# generated types +.astro/ + +# dependencies +node_modules/ + +# logs +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* + +# environment variables +.env +.env.production + +# macOS-specific files +.DS_Store + +# jetbrains setting folder +!.idea/icon.svg +.idea/ + +# Hide the SQL session +*.session.sql diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100644 index 0000000..2312dc5 --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1 @@ +npx lint-staged diff --git a/.idea/icon.svg b/.idea/icon.svg new file mode 100644 index 0000000..13eb2db --- /dev/null +++ b/.idea/icon.svg @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="UTF-8"?> +<svg width="300px" height="300px" viewBox="0 0 300 300" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <title>favicon</title> + <g id="favicon" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> + <rect fill="#263148" x="0" y="0" width="300" height="300" /> + <g id="logo-white" transform="translate(9, 3.888)"> + <path d="M159,154.195523 C167.013592,152.617424 174.05936,152.751451 180.129673,154.674602 C190.120795,157.839913 194.348511,161.02564 199.517296,168.40144 C202.925628,173.265093 205.718707,181.861769 208,194.149433 C202.817237,195.503225 198.494331,195.463815 195.074572,193.809733 C188.963104,190.853715 183.30068,186.732689 175.022826,177.505654 C169.768056,171.648346 164.430736,163.875789 159,154.195523 Z" id="font1-dot" fill="#EEB4B4" /> + <path d="M151.486676,25.701431 C155.616373,28.5082875 160.109234,31.601356 164.965286,34.9806001 C165.393463,35.2785613 165.822641,35.5757097 166.255249,35.8738863 L167.105716,36.458366 C168.619019,37.4954138 170.108644,38.5008303 171.499238,39.4303971 L172.608374,40.1697969 C174.26724,41.2727003 175.735093,42.2354804 176.860606,42.9690389 L176.448028,45.1207071 L166.710146,84.6326462 C180.591569,66.4261557 193.885083,57.2272012 206.997372,58.6211808 C208.743695,58.806834 210.475625,59.0033727 212.18144,59.2464237 C212.733943,59.3251464 213.291751,59.4029337 213.853878,59.4813177 C215.158468,59.6632319 216.474026,59.8465926 217.787079,60.0508718 L218.661915,60.1902579 C225.09927,61.241972 231.826526,62.8614549 236.986443,68.0144332 C240.889249,71.9119921 243.813448,77.8014483 245.23642,86.708071 C247.095663,98.3453903 243.120654,117.723729 238.770002,139.330906 L238.580551,140.271866 C237.890376,143.700241 237.191343,147.180322 236.50179,150.693982 L236.044022,153.039529 C235.556986,155.549827 235.077075,158.073824 234.610494,160.607168 L234.263405,162.507565 L233.922672,164.406776 C228.900089,192.67064 226.130123,221.241925 234.44056,240.371255 C240.652266,254.669635 245.935235,262.932333 250.296038,267.670416 C253.412465,271.056463 256.180453,272.79959 258.553083,273.698031 C262.383549,275.148509 265.383302,274.528886 267.668585,273.982958 C268.14919,273.865733 268.422366,273.767797 268.665926,273.767797 C271.112421,273.767797 275.809409,272.387068 282.731388,269.370175 C283.375366,277.48654 282.878184,284.333295 281.156359,289.899262 C280.659157,291.506519 280.558961,292.472131 279.535062,293.024782 C275.748117,295.068793 270.498503,293.963559 265.488631,292.694915 C256.722323,290.485677 244.816282,287.548472 234.696635,275.178958 C233.697221,273.957347 232.737161,272.794212 231.813783,271.675534 C222.758366,260.704951 217.370091,254.220034 212.983093,237.93167 C209.908658,226.516685 208.870828,218.179476 208.826484,204.259903 L208.825284,202.840608 C208.836884,194.672214 209.157933,184.633261 209.605114,171.185381 C210.376069,148.00078 213.79261,132.71409 216.334239,121.332289 C218.054209,113.629996 219.354132,107.626433 219.354132,102.212372 C219.354132,100.105514 219.634597,97.1568247 219.926173,94.0567601 L220.027967,92.9734861 C220.416501,88.8241101 220.77388,84.5552796 220.633396,81.5249303 C220.563268,80.0122213 220.36004,78.7458615 220.056532,77.8111784 C219.39849,75.7846738 218.218924,74.7926623 217.050886,74.319003 C213.016784,72.6831053 207.083752,73.8938983 200.767445,77.2643023 C193.5468,81.1172643 185.881323,87.4227388 181.226749,92.1251087 C170.078149,103.388189 168.197052,106.181552 163.449564,130.566909 C160.514746,145.641534 157.152557,190.083423 153.408527,263.882996 C148.310625,260.529506 144.573436,256.539474 142.267189,251.849384 C137.44815,242.049164 135.781889,238.498147 133.16629,221.130117 C131.151349,207.750561 132.216961,189.426224 132.839043,178.568221 C133.052135,174.848508 133.207609,172.07036 133.207609,170.48586 C133.207609,164.09523 134.233106,147.312148 137.188741,122.72916 C137.780573,117.806695 138.265493,113.776123 138.700893,110.283341 L138.823994,109.299731 C139.331717,105.259782 139.777004,101.934213 140.256685,98.7255887 L140.372518,97.9574584 L140.582929,96.5951823 L140.761224,95.4724241 L140.885706,94.7044198 C141.871689,88.670391 143.122232,82.1576033 145.272592,71.2270532 C148.154429,56.5783156 150.225956,41.4023262 151.486676,25.701431 Z" id="font1-right" fill="#FFFFFF" /> + <path d="M78.8891291,0 L95.8005079,20.9095227 C95.225924,21.6575488 94.6661502,22.3687531 94.1213578,23.0610595 C90.498037,27.665481 87.5143717,31.5165865 85.0892155,38.8498924 C84.5933419,40.3493393 84.11666,41.7284904 83.6520528,43.0728622 C83.5490334,43.3709557 83.4494774,43.6590286 83.3486814,43.9513373 L82.9235478,45.1899741 L82.6412306,46.0224097 L82.2485912,47.2004158 C80.4111972,52.7806913 78.6427308,59.1891547 76.4859025,71.9475546 C76.3776982,72.5876213 76.2738377,73.2121994 76.1751238,73.8203757 L75.8128598,76.0522841 L78.072301,76.1393226 C78.6520627,76.1616563 79.233139,76.1970078 79.8150176,76.2458239 C87.4717734,76.8881795 94.6057156,79.8018442 100.240592,83.8134948 C106.031451,87.9361953 110.302115,93.214716 111.609957,98.4281539 C115.240663,112.901207 110.993666,140.365178 108.836316,154.571762 C108.454224,157.088603 108.185012,158.862829 107.988397,160.271632 C107.819607,161.481054 107.625793,162.940163 107.407149,164.586499 C106.781752,169.295591 105.954511,175.526376 104.92697,181.804864 L104.678362,183.301099 C104.604458,183.739061 104.529572,184.176727 104.455334,184.604273 L104.223432,185.919703 L103.986615,187.248058 C102.465647,195.80355 101.02459,204.149885 98.485251,205.777632 C97.1963754,206.603817 95.9047926,207.065865 94.5842529,207.065865 C93.8588313,207.065865 93.1344185,206.927653 92.4069507,206.668298 L95.4781875,150.606035 L95.4781875,125.416711 C95.4781875,119.629476 93.0062228,110.908957 89.011414,104.252932 C85.2823118,98.0396202 80.2711525,93.9905379 75.163077,93.8351964 C74.0775524,93.8021846 72.9925685,93.9378881 71.9187092,94.2290372 L71.4263054,96.8428337 C70.7159074,100.613041 70.0525722,104.126731 69.4322911,107.412363 C64.7908163,131.998276 62.5529774,143.865744 61.0463793,154.851795 L60.8656498,156.191994 L60.6074832,158.19028 L60.4564922,159.410154 C59.6660213,165.902037 59.0513782,172.654885 58.2694423,182.117243 L58.1071301,184.090317 C57.9422433,186.102896 57.7692971,188.236388 57.5853124,190.511952 C54.4936668,228.750117 54.5110376,253.296254 57.6025561,277.724448 C58.251829,282.854795 58.3254515,286.119184 57.7997112,287.772531 C57.3533443,287.365152 56.8839604,286.712284 56.3626176,285.917213 C52.9105561,280.652664 48.8648383,269.062761 47.655685,256.055841 C44.8625825,226.010303 44.1900887,198.199537 45.6450201,172.623459 C47.1003171,147.040956 50.0546274,122.362378 54.5097037,98.5879441 C54.6592145,97.7900827 54.8106671,96.9918965 54.9640617,96.1933855 C55.1162766,95.4010154 55.2701489,94.6096509 55.4255602,93.8194108 C54.5845527,93.7480795 53.7194585,93.7489156 52.8332622,93.823043 C51.80541,93.9090195 50.8219304,94.0875047 49.8871243,94.3559954 C40.9569857,96.920869 32.323789,109.590977 26.0163924,128.220937 C25.5897822,129.481002 25.1964216,130.603972 24.8064948,131.717231 C23.9716729,134.100687 23.1541733,136.435766 22.0577662,139.963149 C20.3672515,146.863794 19.2883814,155.11982 17.6274898,174.892165 L17.5002077,176.41617 C17.0934812,181.313351 16.6513406,186.891553 16.1571801,193.292133 C9.8071489,188.98619 5.71118886,185.065024 4.00517668,181.431253 C1.70360048,176.528943 0.414450227,167.507602 0,154.408561 C0.00301447963,88.3903589 8.23407782,59.6337727 27.7303891,30.3791899 L35.9962997,39.4225457 C36.9078334,45.6050425 36.6691333,52.0098284 36.334543,58.397272 L36.1828539,61.2074098 C35.9059422,66.2844755 35.6468393,71.3361913 35.8481016,76.2587175 L59.2444284,76.2587175 L59.8164199,73.1824272 C62.3280788,59.6740418 63.7105033,52.2383301 64.7073785,47.2643843 C65.3214048,44.2279628 65.7161407,42.4192098 66.1158122,40.7377245 L66.5998483,38.7653101 C67.0726403,36.911647 67.4709203,35.4207871 67.9619662,33.5825073 C70.1167026,25.5160341 74.7481339,10.4984271 78.8891291,0 Z" id="font1-left" fill="#FFFFFF" /> + </g> + </g> +</svg> diff --git a/.ncurc.json b/.ncurc.json new file mode 100644 index 0000000..6f681ee --- /dev/null +++ b/.ncurc.json @@ -0,0 +1,3 @@ +{ + "upgrade": true +} diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..6e564af --- /dev/null +++ b/.prettierignore @@ -0,0 +1,7 @@ +dist +.zeabur +node_modules +public/images + +# The MDX files +*.mdx diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..eee2597 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,20 @@ +{ + "trailingComma": "all", + "tabWidth": 2, + "semi": true, + "singleQuote": true, + "printWidth": 120, + "bracketSpacing": true, + "astroAllowShorthand": true, + "astroOrganizeImportsMode": "All", + "endOfLine": "lf", + "plugins": ["prettier-plugin-astro", "prettier-plugin-organize-imports", "prettier-plugin-astro-organize-imports"], + "overrides": [ + { + "files": "**/*.astro", + "options": { + "parser": "astro" + } + } + ] +} diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..647984c --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,4 @@ +{ + "recommendations": ["astro-build.astro-vscode", "esbenp.prettier-vscode", "biomejs.Biome"], + "unwantedRecommendations": [] +} diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..d642209 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,11 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "command": "./node_modules/.bin/astro dev", + "name": "Development server", + "request": "launch", + "type": "node-terminal" + } + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..73ee75d --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,146 @@ +{ + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.formatOnSave": true, + "editor.codeActionsOnSave": { + "quickfix.biome": "explicit" + }, + "[javascript]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "[astro]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "cSpell.words": [ + "alexinea", + "ameho", + "amehochan", + "aplayer", + "artalk", + "astro", + "astrojs", + "batang", + "bigserial", + "biomejs", + "blogster", + "blurhash", + "captainofphb", + "cfilter", + "cimage", + "ckenh", + "cnip", + "csvg", + "ctan", + "cynosura", + "datetime", + "dichen", + "dinesh", + "dotum", + "duoshuo", + "emde", + "eparams", + "firis", + "flexdinesh", + "fmoran", + "fong", + "forencrypt", + "giscus", + "gotop", + "gungseo", + "hefei", + "heiti", + "HONORBKK", + "HUAWEIYAL", + "ianvs", + "iconfont", + "iroha", + "isodate", + "jamo", + "jian", + "jiasm", + "jing", + "jungshik", + "khalil", + "KHTML", + "koanughi", + "koaunghi", + "lantinghei", + "lastmod", + "lazyload", + "linuxapi", + "loveness", + "luoli", + "luxon", + "mboker", + "minagi", + "Miui", + "MMWEBID", + "MMWEBSDK", + "mochi", + "napi", + "netease", + "nextval", + "nian", + "noto", + "oppo", + "opposans", + "pandiyan", + "penheulim", + "pilgi", + "plaiceholder", + "playform", + "psql", + "pwsz", + "qrcode", + "quan", + "recma", + "Redmi", + "regclass", + "sauvignon", + "sheng", + "shiki", + "shinmun", + "shmily", + "skrs", + "syhily", + "taza", + "teruteru", + "timestamptz", + "toolsmp", + "tsconfigs", + "ultrahtml", + "unpic", + "urlset", + "varchar", + "velite", + "vercel", + "weapi", + "wechat", + "weibo", + "xiao", + "xinsenz", + "XWEB", + "yefengs", + "yetgul", + "ying", + "yuaanlin", + "yual", + "yufan", + "yyjn", + "zeabur" + ], + "sqltools.connections": [ + { + "previewLimit": 50, + "server": "localhost", + "port": 5432, + "driver": "PostgreSQL", + "name": "DuoShuo", + "database": "duoshuo", + "username": "duoshuo", + "password": "Twgdh@2024" + } + ], + "[mdx]": { + "editor.defaultFormatter": "unifiedjs.vscode-mdx" + } +} diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..f367eaa --- /dev/null +++ b/Dockerfile @@ -0,0 +1,18 @@ +FROM node:lts-alpine AS base +WORKDIR /app +COPY package.json package-lock.json ./ + +FROM base AS build +COPY . . + +ENV ASTRO_TELEMETRY_DISABLED=1 +RUN NODE_ENV=development npm install +RUN npm run build + +FROM base AS runtime +RUN npm install --omit=dev +COPY --from=build /app/dist ./dist +ENV HOST=0.0.0.0 +ENV PORT=4321 +EXPOSE 4321 +CMD node ./dist/server/entry.mjs diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..3af2f2d --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Yufan Sheng + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..19bb882 --- /dev/null +++ b/README.md @@ -0,0 +1,240 @@ + + + +# Yufan Personal Weblog + +This is a personal weblog for [Yufan Sheng](https://github.com/syhily) +which is built on [Astro](https://astro.build) and hosted on [zeabur](https://zeabur.com). + +[](https://zeabur.com?referralCode=syhily&utm_source=syhily) + +## History + +The blog's source code has evolved through four stages. Initially, it was built on WordPress in 2011. +In 2017, I switched to Hexo and converted all my blog posts to Markdown; +the code is available in the [Hexo branch](https://github.com/syhily/yufan.me/tree/hexo). +By 2024, the blog had been rewritten using Next.js with App Router; +you can find this version in the [Next branch](https://github.com/syhily/yufan.me/tree/next). +Currently, the blog has transitioned to Astro, which is located in +the [Astro branch](https://github.com/syhily/yufan.me/tree/astro). + +## Core Frameworks + +- [Node.js](https://nodejs.org): The latest Node.js LTS +- [Astro](https://astro.build): Core engine +- [Artalk](https://artalk.js.org): The self-hosted comment system +- [Fuse.js](https://www.fusejs.io): Search engine +- [Postgres](https://zeabur.com/docs/marketplace/postgresql): The view counter and like button for all my posts + +## Local Development + +This weblog is still under [development](#todo-checklist). Many ideas and thoughts are in my checklists. +You can fork and clone this project for your own use. But do so at your own risk. + +The project uses npm for development. Run it locally with these commands: + +```shell +# Install the dependencies by using bun. +npm install + +# Init git hooks. +npx husky + +# Check the newer dependencies. +npm update + +# Start local development with a live preview. The weblog is hosted on http://localhost:4321 +npm run dev +``` + +### Postgres Database + +This blog uses Postgres to store post views and favorites. For security reasons, +the configuration isn't defined in the `.env` file. +Modify the `.env.example` file and rename it to `.env` for local development. + +You can create a Postgres database by installing [Postgres.app](https://postgresapp.com). +The default username is `your system username`, with no password. + +Create and initialize the database and user with these commands: + +```sql +-- Create a database. +CREATE DATABASE <db>; + +-- Create a user. +CREATE USER <db_user> PASSWORD '<strong_password>'; + +-- Grant the connection. +GRANT CONNECT ON DATABASE <db> TO <db_user>; + +-- Grant the database privilege. +GRANT ALL PRIVILEGES ON DATABASE <db> TO <db_user>; + +-- If you are using Postgres 15 or above. +-- Switch to the created database and execute SQL. +GRANT ALL ON SCHEMA public TO <db_user>; +``` + +Most tables are created by the Artalk. [Execute the Artalk](https://artalk.js.org/guide/deploy.html) to create the tables. + +The like table should be created manually. Execute the SQL below. + +```sql +-- Sequence and defined type +CREATE SEQUENCE IF NOT EXISTS atk_likes_id_seq; + +-- Table Definition +CREATE TABLE "public"."atk_likes" ( + "id" int8 NOT NULL DEFAULT nextval('atk_likes_id_seq'::regclass), + "created_at" timestamptz, + "updated_at" timestamptz, + "deleted_at" timestamptz, + "token" varchar(255), + "page_key" varchar(255), + PRIMARY KEY ("id") +); + +-- Create table index +CREATE INDEX IF NOT EXISTS "idx_atk_likes_token" ON "public"."atk_likes" ("token"); +``` + +### Comments Integration + +This weblog use artalk as its backend comment service. But since artalk didn't provide the latest comments API. +We decide to query it directly from Postgres database. So the comments and fav clicks are living in the same database. + +## Writing + +All the posts should be placed in `src/content/posts` directory with MDX format. +All the pages should be placed in `src/content/pages` directory with MDX format. +You can add any scripts or other customizable features by leveraging the MDX. + +### Front Matter + +Front-matter is a block of YAML at the beginning of the file that is used to configure settings for your writings. +Front-matter is terminated by three dashes when written in YAML. + +```yaml +--- +title: Hello World +date: 2013/7/13 20:46:25 +--- +``` + +### Post Front Matter Settings + +| Setting | Description | Required | Default | +| ----------- | ------------------------------------ | -------- | -------------------- | +| `id` | ID (unique), used as the permalink | true | Filename | +| `title` | Title | true | Filename | +| `date` | Published date | true | | +| `updated` | Updated date | false | Published date | +| `comments` | Enables comment feature for the post | false | `true` | +| `tags` | Tags | false | `null` | +| `category` | Category | true | `null` | +| `summary` | Post summary in plain text | false | First 140 characters | +| `cover` | The cover image | false | `null` | +| `published` | Whether the post should be published | false | `true` | + +### Pages Front Matter Settings + +| Setting | Description | Required | Default | +| ----------- | ------------------------------------ | -------- | -------------- | +| `id` | ID (unique), used as the permalink | true | Filename | +| `title` | Title | true | Filename | +| `date` | Published date | true | | +| `updated` | Updated date | false | Published date | +| `comments` | Enables comment feature for the post | false | `true` | +| `cover` | The cover image | false | `null` | +| `published` | Whether the post should be published | false | `true` | + +## Weblog Design + +Almost all the design resources are placed in the file [yufan.me.sketch](docs/yufan.me.sketch). +I mainly use the [Sketch](https://www.sketch.com) as my design tools. + +The favicon is almost the same as the weblog logo. The main different is that we simplify the elements used in logo. +Pick up the main park from the logo and change the dot color for readability in small icon. +The background color is included in the exported favicon. +That is because we want to make sure it could be viewed clearly in any browser. + +The size of the favicon is following this +[tutorial](https://evilmartians.com/chronicles/how-to-favicon-in-2021-six-files-that-fit-most-needs) +to get it worked everywhere. + +## Deploy the Weblog + +This weblog is deployed on the [zeabur](https://zeabur.com) platform. +You can check their documents and get your own weblog to be published without any budget at first. + +Or you can host on your own machine. Use [Dockerfile](./Dockerfile) to build a image and run it locally. + +The comment system is leverage the [Artalk](https://artalk.js.org), a self-hosted comment system. +You should host it on your own machine. +But it can be modified and changed to any other comment solutions. +For instance, the [giscus](https://giscus.app) is an opinionated choice. + +## TODO Checklist + +- [ ] Check article grammar errors by using ChatGPT. Remain **54** posts. +- [ ] Add music to the articles. Remain **54** posts. +- [ ] Clean up the legacy links in the weblog comments. +- [ ] External the article inner links with different target. +- [ ] Artalk integration with custom stylesheet. +- [ ] Slide share components integration. + +### Long Term Goals + +- [ ] Add han.js support for better typography. +- [ ] Drop bootstrap, in favor of tailwind css. +- [ ] Use self developed duoshuo as the comments solution. + +## License + +The source code of this blog is licensed under the [MIT](LICENSE) license, +feel to free to use it without any legal risks. + +The [content](src/content) of this blog's posts is licensed under the +[CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/) license. + +### Logo Fonts License + +The fonts used in weblog logo is [M+A1](https://booth.pm/ja/items/2347968) with [license](licenses/LICENSE.m-plus.txt), +[UnGungseo](https://kldp.net/unfonts) with [license](licenses/LICENSE.un-fonts.txt), +and [Iroha Mochi](https://modi.jpn.org/font_iroha-mochi.php) with [license](licenses/LICENSE.iroha-mochi.txt). + +They are the fonts that can be used in business without any charge. + +### Article Font License + +The [OPPOSans 3.0](https://www.coloros.com/article/A00000050) is used for reading in my weblog. +It can be used in business scenarios without any modification. +I just placed it under the [opposans](src/asserts/styles/opposans/) directory for better integration. +The license file is [here](licenses/LICENSE.oppo-sans.txt) + +### Open Graph Font License + +The [Noto Sans Simplified Chinese](https://fonts.google.com/noto/specimen/Noto+Sans+SC) +is used for rendering the open graph image in my weblog. +It can be used in business scenarios without any modification. +The license file is [here](LICENSE.noto-sans-sc.txt) + +### Third Party Codes License + +Some codes in this project is copied from other project. I have add the comments in the files's header. + +The source codes used from third party projects are: + +- [seo.ts](src/helpers/seo.ts) + from [flexdinesh/blogster](https://github.com/flexdinesh/blogster/blob/main/packages/shared/src/seo.ts) + with [license](licenses/LICENSE.flexdinesh.txt) +- [og.ts](src/helpers/og.ts) + from [yuaanlin/yual.in](https://github.com/yuaanlin/yual.in/blob/main/pages/og_image/%5Bslug%5D.tsx) + with [permission](licenses/LICENSE.yuaanlin.jpg) +- [images.ts](src/helpers/images.ts) + from [zce/velite](https://github.com/zce/velite/blob/main/src/assets.ts) + with [license](licenses/LICENSE.zce.txt) +- [images.ts](src/helpers/images.ts) + from [vercel/next.js](https://github.com/vercel/next.js/blob/canary/packages/next/src/shared/lib/image-blur-svg.ts) + with [license](licenses/LICENSE.vercel.txt) diff --git a/astro.config.ts b/astro.config.ts new file mode 100644 index 0000000..daad670 --- /dev/null +++ b/astro.config.ts @@ -0,0 +1,57 @@ +import mdx from '@astrojs/mdx'; +import node from '@astrojs/node'; +import { defineConfig, envField } from 'astro/config'; +import arraybuffer from 'vite-plugin-arraybuffer'; +import { astroImage } from './remark-plugins/images'; + +// Dynamic switch the site. This is hard coded. +const port = 4321; +const site = import.meta.env.PROD ? 'https://yufan.me' : `http://localhost:${port}`; + +// https://astro.build/config +export default defineConfig({ + site: site, + output: 'server', + security: { + checkOrigin: true, + }, + experimental: { + env: { + schema: { + POSTGRES_HOST: envField.string({ context: 'server', access: 'secret' }), + POSTGRES_PORT: envField.number({ context: 'server', access: 'secret' }), + POSTGRES_USERNAME: envField.string({ context: 'server', access: 'secret' }), + POSTGRES_PASSWORD: envField.string({ context: 'server', access: 'secret' }), + POSTGRES_DATABASE: envField.string({ context: 'server', access: 'secret' }), + }, + }, + }, + integrations: [ + mdx({ + remarkPlugins: [astroImage], + }), + ], + adapter: node({ + mode: 'standalone', + }), + markdown: { + gfm: true, + shikiConfig: { + theme: 'solarized-light', + wrap: false, + }, + }, + server: { + host: true, + port: port, + }, + devToolbar: { + // I don't need such toolbar. + enabled: false, + }, + vite: { + plugins: [arraybuffer()], + // Add this for avoiding the needless import optimize in Vite. + optimizeDeps: { exclude: ['@napi-rs/canvas'] }, + }, +}); diff --git a/biome.json b/biome.json new file mode 100644 index 0000000..6368b30 --- /dev/null +++ b/biome.json @@ -0,0 +1,11 @@ +{ + "$schema": "https://biomejs.dev/schemas/1.8.0/schema.json", + "formatter": { "enabled": false }, + "organizeImports": { "enabled": false }, + "linter": { "enabled": true, "rules": { "recommended": true } }, + "vcs": { + "enabled": true, + "clientKind": "git", + "useIgnoreFile": true + } +} diff --git a/docs/poster/github-poster-dark.png b/docs/poster/github-poster-dark.png new file mode 100644 index 0000000..43ea2c6 Binary files /dev/null and b/docs/poster/github-poster-dark.png differ diff --git a/docs/poster/github-poster.png b/docs/poster/github-poster.png new file mode 100644 index 0000000..0f29c66 Binary files /dev/null and b/docs/poster/github-poster.png differ diff --git a/docs/yufan.me.sketch b/docs/yufan.me.sketch new file mode 100644 index 0000000..4ae865b Binary files /dev/null and b/docs/yufan.me.sketch differ diff --git a/licenses/LICENSE.flexdinesh.txt b/licenses/LICENSE.flexdinesh.txt new file mode 100644 index 0000000..7173736 --- /dev/null +++ b/licenses/LICENSE.flexdinesh.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 Dinesh Pandiyan + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/licenses/LICENSE.iroha-mochi.txt b/licenses/LICENSE.iroha-mochi.txt new file mode 100644 index 0000000..d392d68 --- /dev/null +++ b/licenses/LICENSE.iroha-mochi.txt @@ -0,0 +1,64 @@ +いろはモチ ver.1.00 +OpenType形式 + +公開日 2018.01.12 +MODI工場/倒神神倒 + +紹介・詳細ページ +http://modi.jpn.org/font_iroha-mochi.php + +---------------------------------------------- + +懐かしい絵本みたいなひらがなフォントです。 + +ウェイト(太さ)は1種類のみです。 + +---------------------------------------------- +## 仕様・収録文字について + +−ひらがな・カタカナ +−illustratorやInDesignの合成フォント機能における「かな」に含まれる全文字です。 +−おまけでいくつか基本的な約物(記号) + +ぁあぃいぅうぇえぉおかがきぎくぐけげこごさざしじすずせぜそぞただちぢっつづてでとどなにぬねのはばぱひびぴふぶぷへべぺほぼぽまみむめもゃやゅゆょよらりるれろゎわゐゑをんゝゞ +ァアィイゥウェエォオカガキギクグケゲコゴサザシジスズセゼソゾタダチヂッツヅテデトドナニヌネノハバパヒビピフブプヘベペホボポマミムメモャヤュユョヨラリルレロヮワヰヱヲンヴヵヶーヽヾ +濁点付きの『う』 +小書きの『か』 +小書きの『け』 +濁点付きの『ワ』 +濁点付きの『ヰ』 +濁点付きの『ヱ』 +濁点付きの『ヲ』 +"',{}、。,.・:;?!゛゜´`¨^ ̄_〆ー—‐/〜|…‥‘’“”()〔〕[]{}〈〉《》「」『』【】′″ + +---------------------------------------------- +## ライセンスについて + +−「いろはモチ」は、MODI工場独自ライセンスです。 + +−連絡表記不要。商用、非商用問わずご自由にどうぞ。素材集書籍などへの収録も同様です。 + +−通常利用、商用利用、改変、再配布、埋め込みもOK。とにかくご自由にどうぞ。 + +−オリジナル・改造フォントともに、フォント単体で有料販売してはいけません。 + +---------------------------------------------- +## 免責事項 + +このフォントの使用に関してはすべて無保証とさせていただきます。 + +---------------------------------------------- +## 更新履歴 + +■2018.01.12 v1.00 +公開 + +---------------------------------------------- +## MODI工場ホームページ +http://modi.jpn.org/ + +## 連絡先 +modi@modi.jpn.org + +誤字などのミスがあったら教えていただければ幸いです。 +お返事はできないですがご了承ください。 diff --git a/licenses/LICENSE.m-plus.txt b/licenses/LICENSE.m-plus.txt new file mode 100644 index 0000000..d04c73e --- /dev/null +++ b/licenses/LICENSE.m-plus.txt @@ -0,0 +1,10 @@ +M+ FONTS Copyright (C) 2002-2019 M+ FONTS PROJECT + +- + +These fonts are free software. +Unlimited permission is granted to use, copy, and distribute them, with +or without modification, either commercially or noncommercially. +THESE FONTS ARE PROVIDED "AS IS" WITHOUT WARRANTY. + +http://mplus-fonts.osdn.jp diff --git a/licenses/LICENSE.noto-sans-sc.txt b/licenses/LICENSE.noto-sans-sc.txt new file mode 100644 index 0000000..d57ea9c --- /dev/null +++ b/licenses/LICENSE.noto-sans-sc.txt @@ -0,0 +1,93 @@ +Copyright 2014-2021 Adobe (http://www.adobe.com/), with Reserved Font Name 'Source' + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +https://openfontlicense.org + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/licenses/LICENSE.oppo-sans.txt b/licenses/LICENSE.oppo-sans.txt new file mode 100644 index 0000000..94cea9f --- /dev/null +++ b/licenses/LICENSE.oppo-sans.txt @@ -0,0 +1,6 @@ +* OPPO Sans(含中文及西文,3 款字重)允许个人或企业免费使用,含商业用途,版权归 OPPO 广东移动通信有限公司所有。 +您应遵守以下条款,违者将会被追究法律责任: +1. 不对字体进行改编或二次开发; +2. 不对外售卖字体; +3. 不向他方提供其他下载渠道; +4. 不用于违法用途。 diff --git a/licenses/LICENSE.un-fonts.txt b/licenses/LICENSE.un-fonts.txt new file mode 100644 index 0000000..a96ebc4 --- /dev/null +++ b/licenses/LICENSE.un-fonts.txt @@ -0,0 +1,37 @@ +Copyright (c) 1998-2004 Koanughi Un. + +Please see the enclosed file COPYING for license information (GPL). If you +did not receive this file, see http://www.gnu.org/licenses/gpl.txt. + + +Un-fonts is comes from the HLaTeX as type1 fonts in 1998 by Koaunghi Un, +he made type1 fonts to use with Korean TeX(HLaTeX [1]) in the late 1990's and +release it under the GNU GPL license. + +It converted to TrueType with the FontForge(PfaEdit) by Won-kyu Park in 2003. + + +Core families (9 fonts) + * UnBatang, UnBatangBold: serif + * UnDotum, UnDotumBold: sans-serif + * UnGraphic, UnGraphicBold: sans-serif style + * UnPilgi, UnPilgiBold: script + * UnGungseo: cursive, brush-stroke + +Extra families (10 fonts) + * UnPen, UnPenheulim: script + * UnTaza: typewriter style + * UnBom: decorative + * UnShinmun + * UnYetgul: old Korean printing style + * UnJamoSora, UnJamoNovel, UnJamoDotum, UnJamoBatang + +Please send problems and feedback at http://kldp.net/projects/unfonts/ + + +Project maintainers: + + * Won-kyu Park <wkpark@kldp.org> + * Jungshik Shin <jshin@mailaps.org> +---- +[1] http://ftp.dante.de/tex-archive/fonts/korean/HLaTeX and other CTAN archives) diff --git a/licenses/LICENSE.vercel.txt b/licenses/LICENSE.vercel.txt new file mode 100644 index 0000000..ec9dcd9 --- /dev/null +++ b/licenses/LICENSE.vercel.txt @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2024 Vercel, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/licenses/LICENSE.yuaanlin.jpg b/licenses/LICENSE.yuaanlin.jpg new file mode 100644 index 0000000..ce44364 Binary files /dev/null and b/licenses/LICENSE.yuaanlin.jpg differ diff --git a/licenses/LICENSE.zce.txt b/licenses/LICENSE.zce.txt new file mode 100644 index 0000000..1e93ffe --- /dev/null +++ b/licenses/LICENSE.zce.txt @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2024 zce <w@zce.me> (https://zce.me) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..799fb48 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,9418 @@ +{ + "name": "yufan.me", + "version": "3.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "yufan.me", + "version": "3.0.0", + "license": "MIT", + "dependencies": { + "@astrojs/mdx": "^3.1.0", + "@astrojs/node": "^8.3.0", + "@astrojs/rss": "^4.0.6", + "astro": "^4.10.2", + "drizzle-orm": "^0.31.2", + "fuse.js": "^7.0.0", + "lodash": "^4.17.21", + "luxon": "^3.4.4", + "pg": "^8.12.0", + "qrcode-svg": "^1.1.0", + "ultrahtml": "^1.5.3" + }, + "devDependencies": { + "@astrojs/check": "^0.7.0", + "@biomejs/biome": "^1.8.1", + "@napi-rs/canvas": "^0.1.53", + "@types/lodash": "^4.17.5", + "@types/luxon": "^3.4.2", + "@types/node": "^20.14.2", + "@types/pg": "^8.11.6", + "@types/qrcode-svg": "^1.1.4", + "@types/unist": "^3.0.2", + "aplayer": "^1.10.1", + "artalk": "^2.8.7", + "bootstrap": "^5.3.3", + "prettier": "^3.3.2", + "prettier-plugin-astro": "^0.14.0", + "prettier-plugin-astro-organize-imports": "^0.4.8", + "prettier-plugin-organize-imports": "^3.2.4", + "resize-sensor": "^0.0.6", + "rimraf": "^5.0.7", + "sharp": "^0.33.4", + "typescript": "^5.4.5", + "unist-util-visit": "^5.0.0", + "vite-plugin-arraybuffer": "^0.0.7" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "license": "Apache-2.0", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@astrojs/check": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@astrojs/check/-/check-0.7.0.tgz", + "integrity": "sha512-UTqwOeKNu9IYZmJXEeWnQuTdSd/pX58Hl4TUARsMlT97SVDL//kLBE4T/ctxRz6J573N87oE5ddtW/uOOnQTug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@astrojs/language-server": "^2.10.0", + "chokidar": "^3.5.3", + "fast-glob": "^3.3.1", + "kleur": "^4.1.5", + "yargs": "^17.7.2" + }, + "bin": { + "astro-check": "dist/bin.js" + }, + "peerDependencies": { + "typescript": "^5.0.0" + } + }, + "node_modules/@astrojs/compiler": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/@astrojs/compiler/-/compiler-2.8.0.tgz", + "integrity": "sha512-yrpD1WRGqsJwANaDIdtHo+YVjvIOFAjC83lu5qENIgrafwZcJgSXDuwVMXOgok4tFzpeKLsFQ6c3FoUdloLWBQ==", + "license": "MIT" + }, + "node_modules/@astrojs/internal-helpers": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@astrojs/internal-helpers/-/internal-helpers-0.4.0.tgz", + "integrity": "sha512-6B13lz5n6BrbTqCTwhXjJXuR1sqiX/H6rTxzlXx+lN1NnV4jgnq/KJldCQaUWJzPL5SiWahQyinxAbxQtwgPHA==", + "license": "MIT" + }, + "node_modules/@astrojs/language-server": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@astrojs/language-server/-/language-server-2.10.0.tgz", + "integrity": "sha512-crHXpqYfA5qWioiuZnZFpTsNItgBlF1f0S9MzDYS7/pfCALkHNJ7K3w9U/j0uMKymsT4hC7BfMaX0DYlfdSzHg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@astrojs/compiler": "^2.7.0", + "@jridgewell/sourcemap-codec": "^1.4.15", + "@volar/kit": "~2.2.3", + "@volar/language-core": "~2.2.3", + "@volar/language-server": "~2.2.3", + "@volar/language-service": "~2.2.3", + "@volar/typescript": "~2.2.3", + "fast-glob": "^3.2.12", + "volar-service-css": "0.0.45", + "volar-service-emmet": "0.0.45", + "volar-service-html": "0.0.45", + "volar-service-prettier": "0.0.45", + "volar-service-typescript": "0.0.45", + "volar-service-typescript-twoslash-queries": "0.0.45", + "vscode-html-languageservice": "^5.2.0", + "vscode-uri": "^3.0.8" + }, + "bin": { + "astro-ls": "bin/nodeServer.js" + }, + "peerDependencies": { + "prettier": "^3.0.0", + "prettier-plugin-astro": ">=0.11.0" + }, + "peerDependenciesMeta": { + "prettier": { + "optional": true + }, + "prettier-plugin-astro": { + "optional": true + } + } + }, + "node_modules/@astrojs/markdown-remark": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@astrojs/markdown-remark/-/markdown-remark-5.1.0.tgz", + "integrity": "sha512-S6Z3K2hOB7MfjeDoHsotnP/q2UsnEDB8NlNAaCjMDsGBZfTUbWxyLW3CaphEWw08f6KLZi2ibK9yC3BaMhh2NQ==", + "license": "MIT", + "dependencies": { + "@astrojs/prism": "^3.1.0", + "github-slugger": "^2.0.0", + "hast-util-from-html": "^2.0.0", + "hast-util-to-text": "^4.0.0", + "import-meta-resolve": "^4.0.0", + "mdast-util-definitions": "^6.0.0", + "rehype-raw": "^7.0.0", + "rehype-stringify": "^10.0.0", + "remark-gfm": "^4.0.0", + "remark-parse": "^11.0.0", + "remark-rehype": "^11.0.0", + "remark-smartypants": "^2.0.0", + "shiki": "^1.1.2", + "unified": "^11.0.4", + "unist-util-remove-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "unist-util-visit-parents": "^6.0.0", + "vfile": "^6.0.1" + } + }, + "node_modules/@astrojs/markdown-remark/node_modules/@types/nlcst": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@types/nlcst/-/nlcst-1.0.4.tgz", + "integrity": "sha512-ABoYdNQ/kBSsLvZAekMhIPMQ3YUZvavStpKYs7BjLLuKVmIMA0LUgZ7b54zzuWJRbHF80v1cNf4r90Vd6eMQDg==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2" + } + }, + "node_modules/@astrojs/markdown-remark/node_modules/@types/unist": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", + "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==", + "license": "MIT" + }, + "node_modules/@astrojs/markdown-remark/node_modules/nlcst-to-string": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/nlcst-to-string/-/nlcst-to-string-3.1.1.tgz", + "integrity": "sha512-63mVyqaqt0cmn2VcI2aH6kxe1rLAmSROqHMA0i4qqg1tidkfExgpb0FGMikMCn86mw5dFtBtEANfmSSK7TjNHw==", + "license": "MIT", + "dependencies": { + "@types/nlcst": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@astrojs/markdown-remark/node_modules/parse-latin": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/parse-latin/-/parse-latin-5.0.1.tgz", + "integrity": "sha512-b/K8ExXaWC9t34kKeDV8kGXBkXZ1HCSAZRYE7HR14eA1GlXX5L8iWhs8USJNhQU9q5ci413jCKF0gOyovvyRBg==", + "license": "MIT", + "dependencies": { + "nlcst-to-string": "^3.0.0", + "unist-util-modify-children": "^3.0.0", + "unist-util-visit-children": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/@astrojs/markdown-remark/node_modules/remark-smartypants": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/remark-smartypants/-/remark-smartypants-2.1.0.tgz", + "integrity": "sha512-qoF6Vz3BjU2tP6OfZqHOvCU0ACmu/6jhGaINSQRI9mM7wCxNQTKB3JUAN4SVoN2ybElEDTxBIABRep7e569iJw==", + "license": "MIT", + "dependencies": { + "retext": "^8.1.0", + "retext-smartypants": "^5.2.0", + "unist-util-visit": "^5.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/@astrojs/markdown-remark/node_modules/retext": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/retext/-/retext-8.1.0.tgz", + "integrity": "sha512-N9/Kq7YTn6ZpzfiGW45WfEGJqFf1IM1q8OsRa1CGzIebCJBNCANDRmOrholiDRGKo/We7ofKR4SEvcGAWEMD3Q==", + "license": "MIT", + "dependencies": { + "@types/nlcst": "^1.0.0", + "retext-latin": "^3.0.0", + "retext-stringify": "^3.0.0", + "unified": "^10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@astrojs/markdown-remark/node_modules/retext-latin": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/retext-latin/-/retext-latin-3.1.0.tgz", + "integrity": "sha512-5MrD1tuebzO8ppsja5eEu+ZbBeUNCjoEarn70tkXOS7Bdsdf6tNahsv2bY0Z8VooFF6cw7/6S+d3yI/TMlMVVQ==", + "license": "MIT", + "dependencies": { + "@types/nlcst": "^1.0.0", + "parse-latin": "^5.0.0", + "unherit": "^3.0.0", + "unified": "^10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@astrojs/markdown-remark/node_modules/retext-latin/node_modules/unified": { + "version": "10.1.2", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.2.tgz", + "integrity": "sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@astrojs/markdown-remark/node_modules/retext-latin/node_modules/vfile": { + "version": "5.3.7", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.3.7.tgz", + "integrity": "sha512-r7qlzkgErKjobAmyNIkkSpizsFPYiUPuJb5pNW1RB4JcYVZhs4lIbVqk8XPk033CV/1z8ss5pkax8SuhGpcG8g==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@astrojs/markdown-remark/node_modules/retext-smartypants": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/retext-smartypants/-/retext-smartypants-5.2.0.tgz", + "integrity": "sha512-Do8oM+SsjrbzT2UNIKgheP0hgUQTDDQYyZaIY3kfq0pdFzoPk+ZClYJ+OERNXveog4xf1pZL4PfRxNoVL7a/jw==", + "license": "MIT", + "dependencies": { + "@types/nlcst": "^1.0.0", + "nlcst-to-string": "^3.0.0", + "unified": "^10.0.0", + "unist-util-visit": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@astrojs/markdown-remark/node_modules/retext-smartypants/node_modules/unified": { + "version": "10.1.2", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.2.tgz", + "integrity": "sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@astrojs/markdown-remark/node_modules/retext-smartypants/node_modules/unist-util-visit": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.1.2.tgz", + "integrity": "sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.1.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@astrojs/markdown-remark/node_modules/retext-smartypants/node_modules/unist-util-visit-parents": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.3.tgz", + "integrity": "sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@astrojs/markdown-remark/node_modules/retext-smartypants/node_modules/vfile": { + "version": "5.3.7", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.3.7.tgz", + "integrity": "sha512-r7qlzkgErKjobAmyNIkkSpizsFPYiUPuJb5pNW1RB4JcYVZhs4lIbVqk8XPk033CV/1z8ss5pkax8SuhGpcG8g==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@astrojs/markdown-remark/node_modules/retext-stringify": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/retext-stringify/-/retext-stringify-3.1.0.tgz", + "integrity": "sha512-767TLOaoXFXyOnjx/EggXlb37ZD2u4P1n0GJqVdpipqACsQP+20W+BNpMYrlJkq7hxffnFk+jc6mAK9qrbuB8w==", + "license": "MIT", + "dependencies": { + "@types/nlcst": "^1.0.0", + "nlcst-to-string": "^3.0.0", + "unified": "^10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@astrojs/markdown-remark/node_modules/retext-stringify/node_modules/unified": { + "version": "10.1.2", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.2.tgz", + "integrity": "sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@astrojs/markdown-remark/node_modules/retext-stringify/node_modules/vfile": { + "version": "5.3.7", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.3.7.tgz", + "integrity": "sha512-r7qlzkgErKjobAmyNIkkSpizsFPYiUPuJb5pNW1RB4JcYVZhs4lIbVqk8XPk033CV/1z8ss5pkax8SuhGpcG8g==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@astrojs/markdown-remark/node_modules/retext/node_modules/unified": { + "version": "10.1.2", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.2.tgz", + "integrity": "sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@astrojs/markdown-remark/node_modules/retext/node_modules/vfile": { + "version": "5.3.7", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.3.7.tgz", + "integrity": "sha512-r7qlzkgErKjobAmyNIkkSpizsFPYiUPuJb5pNW1RB4JcYVZhs4lIbVqk8XPk033CV/1z8ss5pkax8SuhGpcG8g==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@astrojs/markdown-remark/node_modules/unist-util-is": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.2.1.tgz", + "integrity": "sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@astrojs/markdown-remark/node_modules/unist-util-modify-children": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/unist-util-modify-children/-/unist-util-modify-children-3.1.1.tgz", + "integrity": "sha512-yXi4Lm+TG5VG+qvokP6tpnk+r1EPwyYL04JWDxLvgvPV40jANh7nm3udk65OOWquvbMDe+PL9+LmkxDpTv/7BA==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "array-iterate": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@astrojs/markdown-remark/node_modules/unist-util-stringify-position": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.3.tgz", + "integrity": "sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@astrojs/markdown-remark/node_modules/unist-util-visit-children": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-children/-/unist-util-visit-children-2.0.2.tgz", + "integrity": "sha512-+LWpMFqyUwLGpsQxpumsQ9o9DG2VGLFrpz+rpVXYIEdPy57GSy5HioC0g3bg/8WP9oCLlapQtklOzQ8uLS496Q==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@astrojs/markdown-remark/node_modules/vfile-message": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.1.4.tgz", + "integrity": "sha512-fa0Z6P8HUrQN4BZaX05SIVXic+7kE3b05PWAtPuYP9QLHsLKYR7/AlLW3NtOrpXRLeawpDLMsVkmk5DG0NXgWw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@astrojs/mdx": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@astrojs/mdx/-/mdx-3.1.0.tgz", + "integrity": "sha512-yuGDaOcCAfYgLQvUAlJDezYGK4twHlzW1Kvpyg3inxtDJuAsHdyVyYLWl0Wo5nwkyrbZktdrjnoW5scqzoAqAg==", + "license": "MIT", + "dependencies": { + "@astrojs/markdown-remark": "5.1.0", + "@mdx-js/mdx": "^3.0.1", + "acorn": "^8.11.3", + "es-module-lexer": "^1.5.3", + "estree-util-visit": "^2.0.0", + "github-slugger": "^2.0.0", + "gray-matter": "^4.0.3", + "hast-util-to-html": "^9.0.1", + "kleur": "^4.1.5", + "rehype-raw": "^7.0.0", + "remark-gfm": "^4.0.0", + "remark-smartypants": "^3.0.1", + "source-map": "^0.7.4", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.1" + }, + "engines": { + "node": "^18.17.1 || ^20.3.0 || >=21.0.0" + }, + "peerDependencies": { + "astro": "^4.8.0" + } + }, + "node_modules/@astrojs/node": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/@astrojs/node/-/node-8.3.0.tgz", + "integrity": "sha512-XskynbRTrpY9nqzc4NDrulNWoynRvVO+8UmEKjw6KZABUYUmjZqN88sa/RXtXl0CPI2sPZ5Gzi3WXH8y2PKd5Q==", + "license": "MIT", + "dependencies": { + "send": "^0.18.0", + "server-destroy": "^1.0.1" + }, + "peerDependencies": { + "astro": "^4.2.0" + } + }, + "node_modules/@astrojs/prism": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@astrojs/prism/-/prism-3.1.0.tgz", + "integrity": "sha512-Z9IYjuXSArkAUx3N6xj6+Bnvx8OdUSHA8YoOgyepp3+zJmtVYJIl/I18GozdJVW1p5u/CNpl3Km7/gwTJK85cw==", + "license": "MIT", + "dependencies": { + "prismjs": "^1.29.0" + }, + "engines": { + "node": "^18.17.1 || ^20.3.0 || >=21.0.0" + } + }, + "node_modules/@astrojs/rss": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@astrojs/rss/-/rss-4.0.6.tgz", + "integrity": "sha512-hpfHz6OZVD4ME1ZmpNQim0yV0AOetVFUHv0vmL8+Bw4GNcmL0ibGkGtMv+PY72HLJUVfDtizrBjfN5HHg+LScA==", + "license": "MIT", + "dependencies": { + "fast-xml-parser": "^4.3.6", + "kleur": "^4.1.5" + } + }, + "node_modules/@astrojs/telemetry": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@astrojs/telemetry/-/telemetry-3.1.0.tgz", + "integrity": "sha512-/ca/+D8MIKEC8/A9cSaPUqQNZm+Es/ZinRv0ZAzvu2ios7POQSsVD+VOj7/hypWNsNM3T7RpfgNq7H2TU1KEHA==", + "license": "MIT", + "dependencies": { + "ci-info": "^4.0.0", + "debug": "^4.3.4", + "dlv": "^1.1.3", + "dset": "^3.1.3", + "is-docker": "^3.0.0", + "is-wsl": "^3.0.0", + "which-pm-runs": "^1.1.0" + }, + "engines": { + "node": "^18.17.1 || ^20.3.0 || >=21.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", + "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", + "license": "MIT", + "dependencies": { + "@babel/highlight": "^7.24.7", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.7.tgz", + "integrity": "sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.7.tgz", + "integrity": "sha512-nykK+LEK86ahTkX/3TgauT0ikKoNCfKHEaZYTUVupJdTLzGNvrblu4u6fa7DhZONAltdf8e662t/abY8idrd/g==", + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.24.7", + "@babel/helper-compilation-targets": "^7.24.7", + "@babel/helper-module-transforms": "^7.24.7", + "@babel/helpers": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/template": "^7.24.7", + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.7.tgz", + "integrity": "sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.24.7", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz", + "integrity": "sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.7.tgz", + "integrity": "sha512-ctSdRHBi20qWOfy27RUb4Fhp07KSJ3sXcuSvTrXrc4aG8NSYDo1ici3Vhg9bg69y5bj0Mr1lh0aeEgTvc12rMg==", + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.24.7", + "@babel/helper-validator-option": "^7.24.7", + "browserslist": "^4.22.2", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", + "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz", + "integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==", + "license": "MIT", + "dependencies": { + "@babel/template": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz", + "integrity": "sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", + "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.7.tgz", + "integrity": "sha512-1fuJEwIrp+97rM4RWdO+qrRsZlAeL1lQJoPqtCYWv0NL115XM93hIH4CSRln2w52SqvmY5hqdtauB6QFCDiZNQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-simple-access": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", + "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", + "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", + "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.7.tgz", + "integrity": "sha512-yy1/KvjhV/ZCL+SM7hBrvnZJ3ZuT9OuZgIJAGpPEToANvc3iM6iDvBnRjtElWibHU6n8/LPR/EjX9EtIEYO3pw==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.7.tgz", + "integrity": "sha512-NlmJJtvcw72yRJRcnCmGvSi+3jDEg8qFu3z0AFoymmzLx5ERVWyzd9kVXr7Th9/8yIJi2Zc6av4Tqz3wFs8QWg==", + "license": "MIT", + "dependencies": { + "@babel/template": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", + "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.24.7", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz", + "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==", + "license": "MIT", + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.7.tgz", + "integrity": "sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.24.7.tgz", + "integrity": "sha512-+Dj06GDZEFRYvclU6k4bme55GKBEWUmByM/eoKuqg4zTNQHiApWRhQph5fxQB2wAEFvRzL1tOEj1RJ19wJrhoA==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-jsx": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", + "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.7.tgz", + "integrity": "sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.24.7", + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-function-name": "^7.24.7", + "@babel/helper-hoist-variables": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/types": "^7.24.7", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", + "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@biomejs/biome": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-1.8.1.tgz", + "integrity": "sha512-fQXGfvq6DIXem12dGQCM2tNF+vsNHH1qs3C7WeOu75Pd0trduoTmoO7G4ntLJ2qDs5wuw981H+cxQhi1uHnAtA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT OR Apache-2.0", + "bin": { + "biome": "bin/biome" + }, + "engines": { + "node": ">=14.21.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/biome" + }, + "optionalDependencies": { + "@biomejs/cli-darwin-arm64": "1.8.1", + "@biomejs/cli-darwin-x64": "1.8.1", + "@biomejs/cli-linux-arm64": "1.8.1", + "@biomejs/cli-linux-arm64-musl": "1.8.1", + "@biomejs/cli-linux-x64": "1.8.1", + "@biomejs/cli-linux-x64-musl": "1.8.1", + "@biomejs/cli-win32-arm64": "1.8.1", + "@biomejs/cli-win32-x64": "1.8.1" + } + }, + "node_modules/@biomejs/cli-darwin-arm64": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-1.8.1.tgz", + "integrity": "sha512-XLiB7Uu6GALIOBWzQ2aMD0ru4Ly5/qSeQF7kk3AabzJ/kwsEWSe33iVySBP/SS2qv25cgqNiLksjGcw2bHT3mw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-darwin-x64": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-1.8.1.tgz", + "integrity": "sha512-uMTSxVLMfqkBVqyc25hSn83jBbp+wtWjzM/pHFlKXt3htJuw7FErVGW0nmQ9Sxa9vJ7GcqoltLMl28VQRIMYzg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-arm64": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-1.8.1.tgz", + "integrity": "sha512-3SzZRuC/9Oi2P2IBNPsEj0KXxSXUEYRR2kfRF/Ve8QAfGgrt4qnwuWd6QQKKN5R+oYH691qjm+cXBKEcrP1v/Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-arm64-musl": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-1.8.1.tgz", + "integrity": "sha512-UQ8Wc01J0wQL+5AYOc7qkJn20B4PZmQL1KrmDZh7ot0DvD6aX4+8mmfd/dG5b6Zjo/44QvCKcvkFGCMRYuhWZA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-x64": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-1.8.1.tgz", + "integrity": "sha512-AeBycVdNrTzsyYKEOtR2R0Ph0hCD0sCshcp2aOnfGP0hCZbtFg09D0SdKLbyzKntisY41HxKVrydYiaApp+2uw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-x64-musl": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-1.8.1.tgz", + "integrity": "sha512-fYbP/kNu/rtZ4kKzWVocIdqZOtBSUEg9qUhZaao3dy3CRzafR6u6KDtBeSCnt47O+iLnks1eOR1TUxzr5+QuqA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-win32-arm64": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-1.8.1.tgz", + "integrity": "sha512-6tEd1H/iFKpgpE3OIB7oNgW5XkjiVMzMRPL8zYoZ036YfuJ5nMYm9eB9H/y81+8Z76vL48fiYzMPotJwukGPqQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-win32-x64": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-1.8.1.tgz", + "integrity": "sha512-g2H31jJzYmS4jkvl6TiyEjEX+Nv79a5km/xn+5DARTp5MBFzC9gwceusSSB2AkJKqZzY131AiACAWjKrVt5Ijw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@emmetio/abbreviation": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/@emmetio/abbreviation/-/abbreviation-2.3.3.tgz", + "integrity": "sha512-mgv58UrU3rh4YgbE/TzgLQwJ3pFsHHhCLqY20aJq+9comytTXUDNGG/SMtSeMJdkpxgXSXunBGLD8Boka3JyVA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@emmetio/scanner": "^1.0.4" + } + }, + "node_modules/@emmetio/css-abbreviation": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@emmetio/css-abbreviation/-/css-abbreviation-2.1.8.tgz", + "integrity": "sha512-s9yjhJ6saOO/uk1V74eifykk2CBYi01STTK3WlXWGOepyKa23ymJ053+DNQjpFcy1ingpaO7AxCcwLvHFY9tuw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@emmetio/scanner": "^1.0.4" + } + }, + "node_modules/@emmetio/css-parser": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@emmetio/css-parser/-/css-parser-0.4.0.tgz", + "integrity": "sha512-z7wkxRSZgrQHXVzObGkXG+Vmj3uRlpM11oCZ9pbaz0nFejvCDmAiNDpY75+wgXOcffKpj4rzGtwGaZxfJKsJxw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@emmetio/stream-reader": "^2.2.0", + "@emmetio/stream-reader-utils": "^0.1.0" + } + }, + "node_modules/@emmetio/html-matcher": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@emmetio/html-matcher/-/html-matcher-1.3.0.tgz", + "integrity": "sha512-NTbsvppE5eVyBMuyGfVu2CRrLvo7J4YHb6t9sBFLyY03WYhXET37qA4zOYUjBWFCRHO7pS1B9khERtY0f5JXPQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "@emmetio/scanner": "^1.0.0" + } + }, + "node_modules/@emmetio/scanner": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@emmetio/scanner/-/scanner-1.0.4.tgz", + "integrity": "sha512-IqRuJtQff7YHHBk4G8YZ45uB9BaAGcwQeVzgj/zj8/UdOhtQpEIupUhSk8dys6spFIWVZVeK20CzGEnqR5SbqA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@emmetio/stream-reader": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@emmetio/stream-reader/-/stream-reader-2.2.0.tgz", + "integrity": "sha512-fXVXEyFA5Yv3M3n8sUGT7+fvecGrZP4k6FnWWMSZVQf69kAq0LLpaBQLGcPR30m3zMmKYhECP4k/ZkzvhEW5kw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@emmetio/stream-reader-utils": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@emmetio/stream-reader-utils/-/stream-reader-utils-0.1.0.tgz", + "integrity": "sha512-ZsZ2I9Vzso3Ho/pjZFsmmZ++FWeEd/txqybHTm4OgaZzdS8V9V/YYWQwg5TC38Z7uLWUV1vavpLLbjJtKubR1A==", + "dev": true, + "license": "MIT" + }, + "node_modules/@emnapi/runtime": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.2.0.tgz", + "integrity": "sha512-bV21/9LQmcQeCPEg3BDFtvwL6cwiTMksYNWQQ4KOxCZikEGalWtenoZ0wCiukJINlGCIi2KXx01g4FoH/LxpzQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.33.4", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.4.tgz", + "integrity": "sha512-p0suNqXufJs9t3RqLBO6vvrgr5OhgbWp76s5gTRvdmxmuv9E1rcaqGUsl3l4mKVmXPkTkTErXediAui4x+8PSA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "glibc": ">=2.26", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.0.2" + } + }, + "node_modules/@img/sharp-darwin-x64": { + "version": "0.33.4", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.4.tgz", + "integrity": "sha512-0l7yRObwtTi82Z6ebVI2PnHT8EB2NxBgpK2MiKJZJ7cz32R4lxd001ecMhzzsZig3Yv9oclvqqdV93jo9hy+Dw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "glibc": ">=2.26", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.0.2" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.2.tgz", + "integrity": "sha512-tcK/41Rq8IKlSaKRCCAuuY3lDJjQnYIW1UXU1kxcEKrfL8WR7N6+rzNoOxoQRJWTAECuKwgAHnPvqXGN8XfkHA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "macos": ">=11", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.2.tgz", + "integrity": "sha512-Ofw+7oaWa0HiiMiKWqqaZbaYV3/UGL2wAPeLuJTx+9cXpCRdvQhCLG0IH8YGwM0yGWGLpsF4Su9vM1o6aer+Fw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "macos": ">=10.13", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.0.2.tgz", + "integrity": "sha512-iLWCvrKgeFoglQxdEwzu1eQV04o8YeYGFXtfWU26Zr2wWT3q3MTzC+QTCO3ZQfWd3doKHT4Pm2kRmLbupT+sZw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.28", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.0.2.tgz", + "integrity": "sha512-x7kCt3N00ofFmmkkdshwj3vGPCnmiDh7Gwnd4nUwZln2YjqPxV1NlTyZOvoDWdKQVDL911487HOueBvrpflagw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.26", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.0.2.tgz", + "integrity": "sha512-cmhQ1J4qVhfmS6szYW7RT+gLJq9dH2i4maq+qyXayUSn9/3iY2ZeWpbAgSpSVbV2E1JUL2Gg7pwnYQ1h8rQIog==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.28", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.2.tgz", + "integrity": "sha512-E441q4Qdb+7yuyiADVi5J+44x8ctlrqn8XgkDTwr4qPJzWkaHwD489iZ4nGDgcuya4iMN3ULV6NwbhRZJ9Z7SQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.26", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.0.2.tgz", + "integrity": "sha512-3CAkndNpYUrlDqkCM5qhksfE+qSIREVpyoeHIU6jd48SJZViAmznoQQLAv4hVXF7xyUB9zf+G++e2v1ABjCbEQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "musl": ">=1.2.2", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.2.tgz", + "integrity": "sha512-VI94Q6khIHqHWNOh6LLdm9s2Ry4zdjWJwH56WoiJU7NTeDwyApdZZ8c+SADC8OH98KWNQXnE01UdJ9CSfZvwZw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "musl": ">=1.2.2", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.33.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.4.tgz", + "integrity": "sha512-RUgBD1c0+gCYZGCCe6mMdTiOFS0Zc/XrN0fYd6hISIKcDUbAW5NtSQW9g/powkrXYm6Vzwd6y+fqmExDuCdHNQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.28", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.0.2" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.33.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.4.tgz", + "integrity": "sha512-2800clwVg1ZQtxwSoTlHvtm9ObgAax7V6MTAB/hDT945Tfyy3hVkmiHpeLPCKYqYR1Gcmv1uDZ3a4OFwkdBL7Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.26", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.0.2" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.33.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.33.4.tgz", + "integrity": "sha512-h3RAL3siQoyzSoH36tUeS0PDmb5wINKGYzcLB5C6DIiAn2F3udeFAum+gj8IbA/82+8RGCTn7XW8WTFnqag4tQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.31", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.0.2" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.33.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.4.tgz", + "integrity": "sha512-GoR++s0XW9DGVi8SUGQ/U4AeIzLdNjHka6jidVwapQ/JebGVQIpi52OdyxCNVRE++n1FCLzjDovJNozif7w/Aw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.26", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.0.2" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.33.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.4.tgz", + "integrity": "sha512-nhr1yC3BlVrKDTl6cO12gTpXMl4ITBUZieehFvMntlCXFzH2bvKG76tBL2Y/OqhupZt81pR7R+Q5YhJxW0rGgQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "musl": ">=1.2.2", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.0.2" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.33.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.4.tgz", + "integrity": "sha512-uCPTku0zwqDmZEOi4ILyGdmW76tH7dm8kKlOIV1XC5cLyJ71ENAAqarOHQh0RLfpIpbV5KOpXzdU6XkJtS0daw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "musl": ">=1.2.2", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.0.2" + } + }, + "node_modules/@img/sharp-wasm32": { + "version": "0.33.4", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.33.4.tgz", + "integrity": "sha512-Bmmauh4sXUsUqkleQahpdNXKvo+wa1V9KhT2pDA4VJGKwnKMJXiSTGphn0gnJrlooda0QxCtXc6RX1XAU6hMnQ==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.1.1" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-ia32": { + "version": "0.33.4", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.33.4.tgz", + "integrity": "sha512-99SJ91XzUhYHbx7uhK3+9Lf7+LjwMGQZMDlO/E/YVJ7Nc3lyDFZPGhjwiYdctoH2BOzW9+TnfqcaMKt0jHLdqw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.33.4", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.4.tgz", + "integrity": "sha512-3QLocdTRVIrFNye5YocZl+KKpYKP+fksi1QhmOArgx7GyhIbQp/WrJRu176jm8IxromS7RIkzMiMINVdBtC8Aw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "license": "MIT", + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@mdx-js/mdx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-3.0.1.tgz", + "integrity": "sha512-eIQ4QTrOWyL3LWEe/bu6Taqzq2HQvHcyTMaOrI95P2/LmJE7AsfPfgJGuFLPVqBUE1BC1rik3VIhU+s9u72arA==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdx": "^2.0.0", + "collapse-white-space": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-build-jsx": "^3.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "estree-util-to-js": "^2.0.0", + "estree-walker": "^3.0.0", + "hast-util-to-estree": "^3.0.0", + "hast-util-to-jsx-runtime": "^2.0.0", + "markdown-extensions": "^2.0.0", + "periscopic": "^3.0.0", + "remark-mdx": "^3.0.0", + "remark-parse": "^11.0.0", + "remark-rehype": "^11.0.0", + "source-map": "^0.7.0", + "unified": "^11.0.0", + "unist-util-position-from-estree": "^2.0.0", + "unist-util-stringify-position": "^4.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@napi-rs/canvas": { + "version": "0.1.53", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas/-/canvas-0.1.53.tgz", + "integrity": "sha512-XsEZi97+kKykmAiPpY+IpZoHxJY1srqFZp8jDt1/RySzC0kB0iZYt/VMIFqQKpLCARZjD7SOAz2AULtwYlesCA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10" + }, + "optionalDependencies": { + "@napi-rs/canvas-android-arm64": "0.1.53", + "@napi-rs/canvas-darwin-arm64": "0.1.53", + "@napi-rs/canvas-darwin-x64": "0.1.53", + "@napi-rs/canvas-linux-arm-gnueabihf": "0.1.53", + "@napi-rs/canvas-linux-arm64-gnu": "0.1.53", + "@napi-rs/canvas-linux-arm64-musl": "0.1.53", + "@napi-rs/canvas-linux-x64-gnu": "0.1.53", + "@napi-rs/canvas-linux-x64-musl": "0.1.53", + "@napi-rs/canvas-win32-x64-msvc": "0.1.53" + } + }, + "node_modules/@napi-rs/canvas-android-arm64": { + "version": "0.1.53", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-android-arm64/-/canvas-android-arm64-0.1.53.tgz", + "integrity": "sha512-2YhxfVsZguATlRWE0fZdTx35SE9+r5D7HV5GPNDataZOKmHf+zZ5//dspuuBSbOriQdoicaFrgXKCUqI0pK3WQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/canvas-darwin-arm64": { + "version": "0.1.53", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-darwin-arm64/-/canvas-darwin-arm64-0.1.53.tgz", + "integrity": "sha512-ls+CWLMusf4RAGo5BvIIzA6dNcc0elwVp6LKjHfQECHA8KKmvdB58YuE5BQcTlb2rzk0SEKtBC/Th3NI2oNdfg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/canvas-darwin-x64": { + "version": "0.1.53", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-darwin-x64/-/canvas-darwin-x64-0.1.53.tgz", + "integrity": "sha512-ZAgcoCH5+5OKS2P8Lxx+jbkAPKkyLD2x6OvSrHg1U6ppdxmLA+CkJlRl8w45HCXwuyIiP7OeymECRtiNYTwznQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/canvas-linux-arm-gnueabihf": { + "version": "0.1.53", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-arm-gnueabihf/-/canvas-linux-arm-gnueabihf-0.1.53.tgz", + "integrity": "sha512-p9km/3C/loDxu3AvA8/vtpIS1BGMd/Ehkl2Iu/v/Gw8N/KUIt3HUvTS7AKApyVE28bxTfq96wJQjtcT8jzDncw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/canvas-linux-arm64-gnu": { + "version": "0.1.53", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-arm64-gnu/-/canvas-linux-arm64-gnu-0.1.53.tgz", + "integrity": "sha512-QKK+sykEiYwjwd+ogyLcpcnH38DNZ8KViBlnfEpoGA2Wa+21/cWQKfMxnbgb/rbvm5tazJinZcihFvH577WQ5g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/canvas-linux-arm64-musl": { + "version": "0.1.53", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-arm64-musl/-/canvas-linux-arm64-musl-0.1.53.tgz", + "integrity": "sha512-2N41U0X8RnrTKzpTtPv1ozlYkJtPsUdbfF3uP/KEd/BsULGd8Y8ghkGMS6CM+821au4ex0dPrWOOdT9wC1rSqQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/canvas-linux-x64-gnu": { + "version": "0.1.53", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-x64-gnu/-/canvas-linux-x64-gnu-0.1.53.tgz", + "integrity": "sha512-7XjuTvDKCODtf/vMwF43VGDrjfgwYKgS91ggdcX3UrJaBYWyWu/+eqNvNj+zdXSe/0x+YOjf5jG4m8xIXdBMQA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/canvas-linux-x64-musl": { + "version": "0.1.53", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-x64-musl/-/canvas-linux-x64-musl-0.1.53.tgz", + "integrity": "sha512-970WEvB8vmj+uxvgdBZ+AGFV7uq9GJhXrqG5PGQ5lWciHX0P0d/OhS2F7TITgFR0LsKDQZ7XQgzMxsYOfwZ0FQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/canvas-win32-x64-msvc": { + "version": "0.1.53", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-win32-x64-msvc/-/canvas-win32-x64-msvc-0.1.53.tgz", + "integrity": "sha512-rLFQCSJaWg/sv54Aap9nAhaodi4Vyb4un50EgW+PNkk8icMziU6KLRKirGBdQr9ZdxnshAPeQXD1g2ArStujKA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@popperjs/core": { + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "dev": true, + "license": "MIT", + "peer": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.18.0.tgz", + "integrity": "sha512-Tya6xypR10giZV1XzxmH5wr25VcZSncG0pZIjfePT0OVBvqNEurzValetGNarVrGiq66EBVAFn15iYX4w6FKgQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.18.0.tgz", + "integrity": "sha512-avCea0RAP03lTsDhEyfy+hpfr85KfyTctMADqHVhLAF3MlIkq83CP8UfAHUssgXTYd+6er6PaAhx/QGv4L1EiA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.18.0.tgz", + "integrity": "sha512-IWfdwU7KDSm07Ty0PuA/W2JYoZ4iTj3TUQjkVsO/6U+4I1jN5lcR71ZEvRh52sDOERdnNhhHU57UITXz5jC1/w==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.18.0.tgz", + "integrity": "sha512-n2LMsUz7Ynu7DoQrSQkBf8iNrjOGyPLrdSg802vk6XT3FtsgX6JbE8IHRvposskFm9SNxzkLYGSq9QdpLYpRNA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.18.0.tgz", + "integrity": "sha512-C/zbRYRXFjWvz9Z4haRxcTdnkPt1BtCkz+7RtBSuNmKzMzp3ZxdM28Mpccn6pt28/UWUCTXa+b0Mx1k3g6NOMA==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.18.0.tgz", + "integrity": "sha512-l3m9ewPgjQSXrUMHg93vt0hYCGnrMOcUpTz6FLtbwljo2HluS4zTXFy2571YQbisTnfTKPZ01u/ukJdQTLGh9A==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.18.0.tgz", + "integrity": "sha512-rJ5D47d8WD7J+7STKdCUAgmQk49xuFrRi9pZkWoRD1UeSMakbcepWXPF8ycChBoAqs1pb2wzvbY6Q33WmN2ftw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.18.0.tgz", + "integrity": "sha512-be6Yx37b24ZwxQ+wOQXXLZqpq4jTckJhtGlWGZs68TgdKXJgw54lUUoFYrg6Zs/kjzAQwEwYbp8JxZVzZLRepQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.18.0.tgz", + "integrity": "sha512-hNVMQK+qrA9Todu9+wqrXOHxFiD5YmdEi3paj6vP02Kx1hjd2LLYR2eaN7DsEshg09+9uzWi2W18MJDlG0cxJA==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.18.0.tgz", + "integrity": "sha512-ROCM7i+m1NfdrsmvwSzoxp9HFtmKGHEqu5NNDiZWQtXLA8S5HBCkVvKAxJ8U+CVctHwV2Gb5VUaK7UAkzhDjlg==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.18.0.tgz", + "integrity": "sha512-0UyyRHyDN42QL+NbqevXIIUnKA47A+45WyasO+y2bGJ1mhQrfrtXUpTxCOrfxCR4esV3/RLYyucGVPiUsO8xjg==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.18.0.tgz", + "integrity": "sha512-xuglR2rBVHA5UsI8h8UbX4VJ470PtGCf5Vpswh7p2ukaqBGFTnsfzxUBetoWBWymHMxbIG0Cmx7Y9qDZzr648w==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.18.0.tgz", + "integrity": "sha512-LKaqQL9osY/ir2geuLVvRRs+utWUNilzdE90TpyoX0eNqPzWjRm14oMEE+YLve4k/NAqCdPkGYDaDF5Sw+xBfg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.18.0.tgz", + "integrity": "sha512-7J6TkZQFGo9qBKH0pk2cEVSRhJbL6MtfWxth7Y5YmZs57Pi+4x6c2dStAUvaQkHQLnEQv1jzBUW43GvZW8OFqA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.18.0.tgz", + "integrity": "sha512-Txjh+IxBPbkUB9+SXZMpv+b/vnTEtFyfWZgJ6iyCmt2tdx0OF5WhFowLmnh8ENGNpfUlUZkdI//4IEmhwPieNg==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.18.0.tgz", + "integrity": "sha512-UOo5FdvOL0+eIVTgS4tIdbW+TtnBLWg1YBCcU2KWM7nuNwRz9bksDX1bekJJCpu25N1DVWaCwnT39dVQxzqS8g==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@shikijs/core": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-1.6.4.tgz", + "integrity": "sha512-WTU9rzZae1p2v6LOxMf6LhtmZOkIHYYW160IuahUyJy7YXPPjyWZLR1ag+SgD22ZMxZtz1gfU6Tccc8t0Il/XA==", + "license": "MIT" + }, + "node_modules/@types/acorn": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@types/acorn/-/acorn-4.0.6.tgz", + "integrity": "sha512-veQTnWP+1D/xbxVrPC3zHnCZRjSrKfhbMUlEA43iMZLu7EsnTtkJklIuwrCPbOi8YkvDQAiW05VQQFvvz9oieQ==", + "license": "MIT", + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.6.8", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", + "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.20.6", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz", + "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.20.7" + } + }, + "node_modules/@types/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==", + "license": "MIT" + }, + "node_modules/@types/debug": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "license": "MIT", + "dependencies": { + "@types/ms": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "license": "MIT" + }, + "node_modules/@types/estree-jsx": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.5.tgz", + "integrity": "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==", + "license": "MIT", + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/lodash": { + "version": "4.17.5", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.5.tgz", + "integrity": "sha512-MBIOHVZqVqgfro1euRDWX7OO0fBVUUMrN6Pwm8LQsz8cWhEpihlvR70ENj3f40j58TNxZaWv2ndSkInykNBBJw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/luxon": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/@types/luxon/-/luxon-3.4.2.tgz", + "integrity": "sha512-TifLZlFudklWlMBfhubvgqTXRzLDI5pCbGa4P8a3wPyUQSW+1xQ5eDsreP9DWHX3tjq1ke96uYG/nwundroWcA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/mdast": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", + "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/mdx": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.13.tgz", + "integrity": "sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==", + "license": "MIT" + }, + "node_modules/@types/ms": { + "version": "0.7.34", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz", + "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==", + "license": "MIT" + }, + "node_modules/@types/nlcst": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/nlcst/-/nlcst-2.0.3.tgz", + "integrity": "sha512-vSYNSDe6Ix3q+6Z7ri9lyWqgGhJTmzRjZRqyq15N0Z/1/UnVsno9G/N40NBijoYx2seFDIl0+B2mgAb9mezUCA==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/node": { + "version": "20.14.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.2.tgz", + "integrity": "sha512-xyu6WAMVwv6AKFLB+e/7ySZVr/0zLCzOa7rSpq6jNwpqOrUbcACDWC+53d4n2QHOnDou0fbIsg8wZu/sxrnI4Q==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/pg": { + "version": "8.11.6", + "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.11.6.tgz", + "integrity": "sha512-/2WmmBXHLsfRqzfHW7BNZ8SbYzE8OSk7i3WjFYvfgRHj7S1xj+16Je5fUKv3lVdVzk/zn9TXOqf+avFCFIE0yQ==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "pg-protocol": "*", + "pg-types": "^4.0.1" + } + }, + "node_modules/@types/qrcode-svg": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@types/qrcode-svg/-/qrcode-svg-1.1.4.tgz", + "integrity": "sha512-gh+atEBHXpU5iO72Tg4q03YdGKoY0zH1Yr4mGl+NSzFpyPuJcgurs8F3aRpH0Gs93GFuB1rDoQj6U4Xshn72PA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/unist": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", + "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==", + "license": "MIT" + }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "license": "ISC" + }, + "node_modules/@volar/kit": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/@volar/kit/-/kit-2.2.5.tgz", + "integrity": "sha512-Bmn0UCaT43xUGGRwcmFG9lKhiCCLjRT4ScSLLPn5C9ltUcSGnIFFDlbZZa1PreHYHq25/4zkXt9Ap32klAh17w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@volar/language-service": "2.2.5", + "@volar/typescript": "2.2.5", + "typesafe-path": "^0.2.2", + "vscode-languageserver-textdocument": "^1.0.11", + "vscode-uri": "^3.0.8" + }, + "peerDependencies": { + "typescript": "*" + } + }, + "node_modules/@volar/language-core": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-2.2.5.tgz", + "integrity": "sha512-2htyAuxRrAgETmFeUhT4XLELk3LiEcqoW/B8YUXMF6BrGWLMwIR09MFaZYvrA2UhbdAeSyeQ726HaWSWkexUcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@volar/source-map": "2.2.5" + } + }, + "node_modules/@volar/language-server": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/@volar/language-server/-/language-server-2.2.5.tgz", + "integrity": "sha512-PV/jkUkI+m72HTXwnY7hsGqLY3VNi96ZRoWFRzVC9QG/853bixxjveXPJIiydMJ9I739lO3kcj3hnGrF5Sm+HA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@volar/language-core": "2.2.5", + "@volar/language-service": "2.2.5", + "@volar/snapshot-document": "2.2.5", + "@volar/typescript": "2.2.5", + "@vscode/l10n": "^0.0.16", + "path-browserify": "^1.0.1", + "request-light": "^0.7.0", + "vscode-languageserver": "^9.0.1", + "vscode-languageserver-protocol": "^3.17.5", + "vscode-languageserver-textdocument": "^1.0.11", + "vscode-uri": "^3.0.8" + } + }, + "node_modules/@volar/language-service": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/@volar/language-service/-/language-service-2.2.5.tgz", + "integrity": "sha512-a97e/0uCe+uSu23F4zvgvldqJtZe6jugQeEHWjTfhgOEO8+Be0t5CZNNVItQqmPyAsD8eElg0S/cP6uxvCmCSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@volar/language-core": "2.2.5", + "vscode-languageserver-protocol": "^3.17.5", + "vscode-languageserver-textdocument": "^1.0.11", + "vscode-uri": "^3.0.8" + } + }, + "node_modules/@volar/snapshot-document": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/@volar/snapshot-document/-/snapshot-document-2.2.5.tgz", + "integrity": "sha512-MTOvWVKxM7ugKO3Amffkv2pND03fe2JtfygYaputqjVFML7YxtTXj8SPnI2pODLeSwOKzDYL6Q8r5j6Y5AgUzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "vscode-languageserver-protocol": "^3.17.5", + "vscode-languageserver-textdocument": "^1.0.11" + } + }, + "node_modules/@volar/source-map": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-2.2.5.tgz", + "integrity": "sha512-wrOEIiZNf4E+PWB0AxyM4tfhkfldPsb3bxg8N6FHrxJH2ohar7aGu48e98bp3pR9HUA7P/pR9VrLmkTrgCCnWQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "muggle-string": "^0.4.0" + } + }, + "node_modules/@volar/typescript": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-2.2.5.tgz", + "integrity": "sha512-eSV/n75+ppfEVugMC/salZsI44nXDPAyL6+iTYCNLtiLHGJsnMv9GwiDMujrvAUj/aLQyqRJgYtXRoxop2clCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@volar/language-core": "2.2.5", + "path-browserify": "^1.0.1" + } + }, + "node_modules/@vscode/emmet-helper": { + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/@vscode/emmet-helper/-/emmet-helper-2.9.3.tgz", + "integrity": "sha512-rB39LHWWPQYYlYfpv9qCoZOVioPCftKXXqrsyqN1mTWZM6dTnONT63Db+03vgrBbHzJN45IrgS/AGxw9iiqfEw==", + "dev": true, + "license": "MIT", + "dependencies": { + "emmet": "^2.4.3", + "jsonc-parser": "^2.3.0", + "vscode-languageserver-textdocument": "^1.0.1", + "vscode-languageserver-types": "^3.15.1", + "vscode-uri": "^2.1.2" + } + }, + "node_modules/@vscode/emmet-helper/node_modules/vscode-uri": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.2.tgz", + "integrity": "sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A==", + "dev": true, + "license": "MIT" + }, + "node_modules/@vscode/l10n": { + "version": "0.0.16", + "resolved": "https://registry.npmjs.org/@vscode/l10n/-/l10n-0.0.16.tgz", + "integrity": "sha512-JT5CvrIYYCrmB+dCana8sUqJEcGB1ZDXNLMQ2+42bW995WmNoenijWMUdZfwmuQUTQcEVVIa2OecZzTYWUW9Cg==", + "dev": true, + "license": "MIT" + }, + "node_modules/abortcontroller-polyfill": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/abortcontroller-polyfill/-/abortcontroller-polyfill-1.7.5.tgz", + "integrity": "sha512-JMJ5soJWP18htbbxJjG7bG6yuI6pRhgJ0scHHTfkUjf6wjP912xZWvM+A4sJK3gqd9E8fcPbDnOefbA9Th/FIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/acorn": { + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ansi-align": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", + "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", + "license": "ISC", + "dependencies": { + "string-width": "^4.1.0" + } + }, + "node_modules/ansi-align/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-align/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/ansi-align/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-align/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/aplayer": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/aplayer/-/aplayer-1.10.1.tgz", + "integrity": "sha512-HAfyxgCUTLAqtYlxzzK9Fyqg6y+kZ9CqT1WfeWE8FSzwspT6oBqWOZHANPHF3RGTtC33IsyEgrfthPDzU5r9kQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balloon-css": "^0.5.0", + "promise-polyfill": "7.1.0", + "smoothscroll": "0.4.0" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" + }, + "node_modules/aria-query": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "license": "Apache-2.0", + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/array-iterate": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/array-iterate/-/array-iterate-2.0.1.tgz", + "integrity": "sha512-I1jXZMjAgCMmxT4qxXfPXa6SthSoE8h6gkSI9BGGNv8mP8G/v0blc+qFnZu6K42vTOiuME596QaLO0TP3Lk0xg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/artalk": { + "version": "2.8.7", + "resolved": "https://registry.npmjs.org/artalk/-/artalk-2.8.7.tgz", + "integrity": "sha512-Pl6oKnG0mLf6/c0X93SEmUm7RqqO1zsfvf4j8EzO25pvcDn9pJdYQqLrWKupaHwO7JLvEcgq5pBBrJCLmBKGpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "abortcontroller-polyfill": "^1.7.5", + "hanabi": "^0.4.0", + "insane": "^2.6.2", + "marked": "^12.0.2" + } + }, + "node_modules/assignment": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/assignment/-/assignment-2.0.0.tgz", + "integrity": "sha512-naMULXjtgCs9SVUEtyvJNt68aF18em7/W+dhbR59kbz9cXWPEvUkCun2tqlgqRPSqZaKPpqLc5ZnwL8jVmJRvw==", + "dev": true + }, + "node_modules/astring": { + "version": "1.8.6", + "resolved": "https://registry.npmjs.org/astring/-/astring-1.8.6.tgz", + "integrity": "sha512-ISvCdHdlTDlH5IpxQJIex7BWBywFWgjJSVdwst+/iQCoEYnyOaQ95+X1JGshuBjGp6nxKUy1jMgE3zPqN7fQdg==", + "license": "MIT", + "bin": { + "astring": "bin/astring" + } + }, + "node_modules/astro": { + "version": "4.10.2", + "resolved": "https://registry.npmjs.org/astro/-/astro-4.10.2.tgz", + "integrity": "sha512-SBdkoOanPsxKlKVU4uu/XG0G7NYAFoqmfBtq9SPMJ34B7Hr1MxVdEugERs8IwYN6UaxdDVcqA++9PvH6Onq2cg==", + "license": "MIT", + "dependencies": { + "@astrojs/compiler": "^2.8.0", + "@astrojs/internal-helpers": "0.4.0", + "@astrojs/markdown-remark": "5.1.0", + "@astrojs/telemetry": "3.1.0", + "@babel/core": "^7.24.7", + "@babel/generator": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/plugin-transform-react-jsx": "^7.24.7", + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7", + "@types/babel__core": "^7.20.5", + "@types/cookie": "^0.6.0", + "acorn": "^8.11.3", + "aria-query": "^5.3.0", + "axobject-query": "^4.0.0", + "boxen": "^7.1.1", + "chokidar": "^3.6.0", + "ci-info": "^4.0.0", + "clsx": "^2.1.1", + "common-ancestor-path": "^1.0.1", + "cookie": "^0.6.0", + "cssesc": "^3.0.0", + "debug": "^4.3.5", + "deterministic-object-hash": "^2.0.2", + "devalue": "^5.0.0", + "diff": "^5.2.0", + "dlv": "^1.1.3", + "dset": "^3.1.3", + "es-module-lexer": "^1.5.3", + "esbuild": "^0.21.5", + "estree-walker": "^3.0.3", + "execa": "^8.0.1", + "fast-glob": "^3.3.2", + "flattie": "^1.1.1", + "github-slugger": "^2.0.0", + "gray-matter": "^4.0.3", + "html-escaper": "^3.0.3", + "http-cache-semantics": "^4.1.1", + "js-yaml": "^4.1.0", + "kleur": "^4.1.5", + "magic-string": "^0.30.10", + "mrmime": "^2.0.0", + "ora": "^8.0.1", + "p-limit": "^5.0.0", + "p-queue": "^8.0.1", + "path-to-regexp": "^6.2.2", + "preferred-pm": "^3.1.3", + "prompts": "^2.4.2", + "rehype": "^13.0.1", + "resolve": "^1.22.8", + "semver": "^7.6.2", + "shiki": "^1.6.3", + "string-width": "^7.1.0", + "strip-ansi": "^7.1.0", + "tsconfck": "^3.1.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.1", + "vite": "^5.2.13", + "vitefu": "^0.2.5", + "which-pm": "^2.2.0", + "yargs-parser": "^21.1.1", + "zod": "^3.23.8", + "zod-to-json-schema": "^3.23.0" + }, + "bin": { + "astro": "astro.js" + }, + "engines": { + "node": "^18.17.1 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0" + }, + "optionalDependencies": { + "sharp": "^0.33.3" + } + }, + "node_modules/axobject-query": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.0.0.tgz", + "integrity": "sha512-+60uv1hiVFhHZeO+Lz0RYzsVHy5Wr1ayX0mwda9KPDVLNJgZ1T9Ny7VmFbLDzxsH0D87I86vgj3gFrjTJUYznw==", + "license": "Apache-2.0", + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/bail": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", + "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/balloon-css": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/balloon-css/-/balloon-css-0.5.2.tgz", + "integrity": "sha512-zheJpzwyNrG4t39vusA67v3BYg1HTVXOF8cErPEHzWK88PEOFwgo6Ea9VHOgOWNMgeuOtFVtB73NE2NWl9uDyQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/base-64": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/base-64/-/base-64-1.0.0.tgz", + "integrity": "sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg==", + "license": "MIT" + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bootstrap": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.3.tgz", + "integrity": "sha512-8HLCdWgyoMguSO9o+aH+iuZ+aht+mzW0u3HIMzVu7Srrpv7EBBxTnrFlSCskwdY1+EOFQSm7uMJhNQHkdPcmjg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/twbs" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/bootstrap" + } + ], + "license": "MIT", + "peerDependencies": { + "@popperjs/core": "^2.11.8" + } + }, + "node_modules/boxen": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-7.1.1.tgz", + "integrity": "sha512-2hCgjEmP8YLWQ130n2FerGv7rYpfBmnmp9Uy2Le1vge6X3gZIfSmEzP5QTDElFxcvVcXlEn8Aq6MU/PZygIOog==", + "license": "MIT", + "dependencies": { + "ansi-align": "^3.0.1", + "camelcase": "^7.0.1", + "chalk": "^5.2.0", + "cli-boxes": "^3.0.0", + "string-width": "^5.1.2", + "type-fest": "^2.13.0", + "widest-line": "^4.0.1", + "wrap-ansi": "^8.1.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/boxen/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/boxen/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "license": "MIT" + }, + "node_modules/boxen/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.23.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.1.tgz", + "integrity": "sha512-TUfofFo/KsK/bWZ9TWQ5O26tsWW4Uhmt8IYklbnUa70udB6P2wA7w7o4PY4muaEPBQaAX+CEnmmIA41NVHtPVw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "caniuse-lite": "^1.0.30001629", + "electron-to-chromium": "^1.4.796", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.16" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/camelcase": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-7.0.1.tgz", + "integrity": "sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==", + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001633", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001633.tgz", + "integrity": "sha512-6sT0yf/z5jqf8tISAgpJDrmwOpLsrpnyCdD/lOZKvKkkJK4Dn0X5i7KF7THEZhOq+30bmhwBlNEaqPUiHiKtZg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/ccount": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", + "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/character-entities": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-html4": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", + "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-legacy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", + "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-reference-invalid": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", + "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/ci-info": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.0.0.tgz", + "integrity": "sha512-TdHqgGf9odd8SXNuxtUBVx8Nv+qZOejE6qyqiy5NtbYYQOeFa6zmHkxlPzmaLxWWHsU6nJmB7AETdVPi+2NBUg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-boxes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz", + "integrity": "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", + "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", + "license": "MIT", + "dependencies": { + "restore-cursor": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-spinners": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/cliui/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/cliui/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/cliui/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/cliui/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/cliui/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/collapse-white-space": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-2.1.0.tgz", + "integrity": "sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/color": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", + "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1", + "color-string": "^1.9.0" + }, + "engines": { + "node": ">=12.5.0" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "license": "MIT" + }, + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "node_modules/color/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/comma-separated-tokens": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", + "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/comment-regex": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/comment-regex/-/comment-regex-1.0.1.tgz", + "integrity": "sha512-IWlN//Yfby92tOIje7J18HkNmWRR7JESA/BK8W7wqY/akITpU5B0JQWnbTjCfdChSrDNb0DrdA9jfAxiiBXyiQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/common-ancestor-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/common-ancestor-path/-/common-ancestor-path-1.0.1.tgz", + "integrity": "sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w==", + "license": "ISC" + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "license": "MIT" + }, + "node_modules/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decode-named-character-reference": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz", + "integrity": "sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==", + "license": "MIT", + "dependencies": { + "character-entities": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "license": "MIT", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/detect-libc": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", + "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", + "devOptional": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/deterministic-object-hash": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/deterministic-object-hash/-/deterministic-object-hash-2.0.2.tgz", + "integrity": "sha512-KxektNH63SrbfUyDiwXqRb1rLwKt33AmMv+5Nhsw1kqZ13SJBRTgZHtGbE+hH3a1mVW1cz+4pqSWVPAtLVXTzQ==", + "license": "MIT", + "dependencies": { + "base-64": "^1.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/devalue": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.0.0.tgz", + "integrity": "sha512-gO+/OMXF7488D+u3ue+G7Y4AA3ZmUnB3eHJXmBTgNHvr4ZNzl36A0ZtG+XCRNYCkYx/bFmw4qtkoFLa+wSrwAA==", + "license": "MIT" + }, + "node_modules/devlop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", + "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "license": "MIT", + "dependencies": { + "dequal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/diff": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", + "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", + "license": "MIT" + }, + "node_modules/drizzle-orm": { + "version": "0.31.2", + "resolved": "https://registry.npmjs.org/drizzle-orm/-/drizzle-orm-0.31.2.tgz", + "integrity": "sha512-QnenevbnnAzmbNzQwbhklvIYrDE8YER8K7kSrAWQSV1YvFCdSQPzj+jzqRdTSsV2cDqSpQ0NXGyL1G9I43LDLg==", + "license": "Apache-2.0", + "peerDependencies": { + "@aws-sdk/client-rds-data": ">=3", + "@cloudflare/workers-types": ">=3", + "@electric-sql/pglite": ">=0.1.1", + "@libsql/client": "*", + "@neondatabase/serverless": ">=0.1", + "@op-engineering/op-sqlite": ">=2", + "@opentelemetry/api": "^1.4.1", + "@planetscale/database": ">=1", + "@tidbcloud/serverless": "*", + "@types/better-sqlite3": "*", + "@types/pg": "*", + "@types/react": ">=18", + "@types/sql.js": "*", + "@vercel/postgres": ">=0.8.0", + "@xata.io/client": "*", + "better-sqlite3": ">=7", + "bun-types": "*", + "expo-sqlite": ">=13.2.0", + "knex": "*", + "kysely": "*", + "mysql2": ">=2", + "pg": ">=8", + "postgres": ">=3", + "react": ">=18", + "sql.js": ">=1", + "sqlite3": ">=5" + }, + "peerDependenciesMeta": { + "@aws-sdk/client-rds-data": { + "optional": true + }, + "@cloudflare/workers-types": { + "optional": true + }, + "@electric-sql/pglite": { + "optional": true + }, + "@libsql/client": { + "optional": true + }, + "@neondatabase/serverless": { + "optional": true + }, + "@op-engineering/op-sqlite": { + "optional": true + }, + "@opentelemetry/api": { + "optional": true + }, + "@planetscale/database": { + "optional": true + }, + "@tidbcloud/serverless": { + "optional": true + }, + "@types/better-sqlite3": { + "optional": true + }, + "@types/pg": { + "optional": true + }, + "@types/react": { + "optional": true + }, + "@types/sql.js": { + "optional": true + }, + "@vercel/postgres": { + "optional": true + }, + "@xata.io/client": { + "optional": true + }, + "better-sqlite3": { + "optional": true + }, + "bun-types": { + "optional": true + }, + "expo-sqlite": { + "optional": true + }, + "knex": { + "optional": true + }, + "kysely": { + "optional": true + }, + "mysql2": { + "optional": true + }, + "pg": { + "optional": true + }, + "postgres": { + "optional": true + }, + "react": { + "optional": true + }, + "sql.js": { + "optional": true + }, + "sqlite3": { + "optional": true + } + } + }, + "node_modules/dset": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/dset/-/dset-3.1.3.tgz", + "integrity": "sha512-20TuZZHCEZ2O71q9/+8BwKwZ0QtD9D8ObhrihJPr+vLLYlSuAU3/zL4cSlgbfeoGHTjCSJBa7NGcrF9/Bx/WJQ==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "license": "MIT" + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "license": "MIT" + }, + "node_modules/electron-to-chromium": { + "version": "1.4.802", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.802.tgz", + "integrity": "sha512-TnTMUATbgNdPXVSHsxvNVSG0uEd6cSZsANjm8c9HbvflZVVn1yTRcmVXYT1Ma95/ssB/Dcd30AHweH2TE+dNpA==", + "license": "ISC" + }, + "node_modules/emmet": { + "version": "2.4.7", + "resolved": "https://registry.npmjs.org/emmet/-/emmet-2.4.7.tgz", + "integrity": "sha512-O5O5QNqtdlnQM2bmKHtJgyChcrFMgQuulI+WdiOw2NArzprUqqxUW6bgYtKvzKgrsYpuLWalOkdhNP+1jluhCA==", + "dev": true, + "license": "MIT", + "workspaces": [ + "./packages/scanner", + "./packages/abbreviation", + "./packages/css-abbreviation", + "./" + ], + "dependencies": { + "@emmetio/abbreviation": "^2.3.3", + "@emmetio/css-abbreviation": "^2.1.8" + } + }, + "node_modules/emoji-regex": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", + "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==", + "license": "MIT" + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/es-module-lexer": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.3.tgz", + "integrity": "sha512-i1gCgmR9dCl6Vil6UKPI/trA69s08g/syhiDK9TG0Nf1RJjjFI+AzoWW7sPufzkgYAn861skuCwJa0pIIHYxvg==", + "license": "MIT" + }, + "node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "node_modules/escalade": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT" + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/estree-util-attach-comments": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/estree-util-attach-comments/-/estree-util-attach-comments-3.0.0.tgz", + "integrity": "sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-build-jsx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/estree-util-build-jsx/-/estree-util-build-jsx-3.0.1.tgz", + "integrity": "sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "estree-walker": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-is-identifier-name": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz", + "integrity": "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-to-js": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/estree-util-to-js/-/estree-util-to-js-2.0.0.tgz", + "integrity": "sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "astring": "^1.8.0", + "source-map": "^0.7.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-visit": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/estree-util-visit/-/estree-util-visit-2.0.0.tgz", + "integrity": "sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "license": "MIT" + }, + "node_modules/execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "license": "MIT" + }, + "node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "license": "MIT", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-xml-parser": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.4.0.tgz", + "integrity": "sha512-kLY3jFlwIYwBNDojclKsNAC12sfD6NwW74QB2CoNGPvtVxjliYehVunB3HYyNi+n4Tt1dAcgwYvmKF/Z18flqg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + }, + { + "type": "paypal", + "url": "https://paypal.me/naturalintelligence" + } + ], + "license": "MIT", + "dependencies": { + "strnum": "^1.0.5" + }, + "bin": { + "fxparser": "src/cli/cli.js" + } + }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/find-yarn-workspace-root2": { + "version": "1.2.16", + "resolved": "https://registry.npmjs.org/find-yarn-workspace-root2/-/find-yarn-workspace-root2-1.2.16.tgz", + "integrity": "sha512-hr6hb1w8ePMpPVUK39S4RlwJzi+xPLuVuG8XlwXU3KD5Yn3qgBWVfy3AzNlDhWvE1EORCE65/Qm26rFQt3VLVA==", + "license": "Apache-2.0", + "dependencies": { + "micromatch": "^4.0.2", + "pkg-dir": "^4.2.0" + } + }, + "node_modules/flattie": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/flattie/-/flattie-1.1.1.tgz", + "integrity": "sha512-9UbaD6XdAL97+k/n+N7JwX46K/M6Zc6KcFYskrYL8wbBV/Uyk0CTAMY0VT+qiK5PM7AIc9aTWYtq65U7T+aCNQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/foreground-child": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.2.0.tgz", + "integrity": "sha512-CrWQNaEl1/6WeZoarcM9LHupTo3RpZO2Pdk1vktwzPiQTsJnAKJmm3TACKeG5UZbWDfaH2AbvYxzP96y0MT7fA==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/fuse.js": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/fuse.js/-/fuse.js-7.0.0.tgz", + "integrity": "sha512-14F4hBIxqKvD4Zz/XjDc3y94mNZN6pRv3U13Udo0lNLCWRBUsrMv2xwcF/y/Z5sV6+FQW+/ow68cHpm4sunt8Q==", + "license": "Apache-2.0", + "engines": { + "node": ">=10" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-east-asian-width": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.2.0.tgz", + "integrity": "sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/github-slugger": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-2.0.0.tgz", + "integrity": "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==", + "license": "ISC" + }, + "node_modules/glob": { + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.1.tgz", + "integrity": "sha512-2jelhlq3E4ho74ZyVLN03oKdAZVUa6UDZzFLVH1H7dnoax+y9qyaq8zBkfDIggjniU19z0wU18y16jMB2eyVIw==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "license": "ISC" + }, + "node_modules/gray-matter": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-4.0.3.tgz", + "integrity": "sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==", + "license": "MIT", + "dependencies": { + "js-yaml": "^3.13.1", + "kind-of": "^6.0.2", + "section-matter": "^1.0.0", + "strip-bom-string": "^1.0.0" + }, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/gray-matter/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/gray-matter/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/hanabi": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/hanabi/-/hanabi-0.4.0.tgz", + "integrity": "sha512-ixJH94fwmmVzUSdxl7TMkVZJmsq4d2JKrxedpM5V1V+91iVHL0q6NnJi4xiDahK6Vo00xT17H8H6b4F6RVbsOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "comment-regex": "^1.0.0" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hast-util-from-html": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/hast-util-from-html/-/hast-util-from-html-2.0.1.tgz", + "integrity": "sha512-RXQBLMl9kjKVNkJTIO6bZyb2n+cUH8LFaSSzo82jiLT6Tfc+Pt7VQCS+/h3YwG4jaNE2TA2sdJisGWR+aJrp0g==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "devlop": "^1.1.0", + "hast-util-from-parse5": "^8.0.0", + "parse5": "^7.0.0", + "vfile": "^6.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-from-parse5": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-8.0.1.tgz", + "integrity": "sha512-Er/Iixbc7IEa7r/XLtuG52zoqn/b3Xng/w6aZQ0xGVxzhw5xUFxcRqdPzP6yFi/4HBYRaifaI5fQ1RH8n0ZeOQ==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "hastscript": "^8.0.0", + "property-information": "^6.0.0", + "vfile": "^6.0.0", + "vfile-location": "^5.0.0", + "web-namespaces": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-is-element": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-3.0.0.tgz", + "integrity": "sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-parse-selector": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz", + "integrity": "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-raw": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-9.0.3.tgz", + "integrity": "sha512-ICWvVOF2fq4+7CMmtCPD5CM4QKjPbHpPotE6+8tDooV0ZuyJVUzHsrNX+O5NaRbieTf0F7FfeBOMAwi6Td0+yQ==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "@ungap/structured-clone": "^1.0.0", + "hast-util-from-parse5": "^8.0.0", + "hast-util-to-parse5": "^8.0.0", + "html-void-elements": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "parse5": "^7.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-estree": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hast-util-to-estree/-/hast-util-to-estree-3.1.0.tgz", + "integrity": "sha512-lfX5g6hqVh9kjS/B9E2gSkvHH4SZNiQFiqWS0x9fENzEl+8W12RqdRxX6d/Cwxi30tPQs3bIO+aolQJNp1bIyw==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-attach-comments": "^3.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "hast-util-whitespace": "^3.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "style-to-object": "^0.4.0", + "unist-util-position": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-html": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-9.0.1.tgz", + "integrity": "sha512-hZOofyZANbyWo+9RP75xIDV/gq+OUKx+T46IlwERnKmfpwp81XBFbT9mi26ws+SJchA4RVUQwIBJpqEOBhMzEQ==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-raw": "^9.0.0", + "hast-util-whitespace": "^3.0.0", + "html-void-elements": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "stringify-entities": "^4.0.0", + "zwitch": "^2.0.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-jsx-runtime": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.0.tgz", + "integrity": "sha512-H/y0+IWPdsLLS738P8tDnrQ8Z+dj12zQQ6WC11TIM21C8WFVoIxcqWXf2H3hiTVZjF1AWqoimGwrTWecWrnmRQ==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "hast-util-whitespace": "^3.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "style-to-object": "^1.0.0", + "unist-util-position": "^5.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-jsx-runtime/node_modules/inline-style-parser": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.3.tgz", + "integrity": "sha512-qlD8YNDqyTKTyuITrDOffsl6Tdhv+UC4hcdAVuQsK4IMQ99nSgd1MIA/Q+jQYoh9r3hVUXhYh7urSRmXPkW04g==", + "license": "MIT" + }, + "node_modules/hast-util-to-jsx-runtime/node_modules/style-to-object": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.6.tgz", + "integrity": "sha512-khxq+Qm3xEyZfKd/y9L3oIWQimxuc4STrQKtQn8aSDRHb8mFgpukgX1hdzfrMEW6JCjyJ8p89x+IUMVnCBI1PA==", + "license": "MIT", + "dependencies": { + "inline-style-parser": "0.2.3" + } + }, + "node_modules/hast-util-to-parse5": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-8.0.0.tgz", + "integrity": "sha512-3KKrV5ZVI8if87DVSi1vDeByYrkGzg4mEfeu4alwgmmIeARiBLKCZS2uw5Gb6nU9x9Yufyj3iudm6i7nl52PFw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-text": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/hast-util-to-text/-/hast-util-to-text-4.0.2.tgz", + "integrity": "sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "hast-util-is-element": "^3.0.0", + "unist-util-find-after": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-whitespace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", + "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hastscript": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-8.0.0.tgz", + "integrity": "sha512-dMOtzCEd3ABUeSIISmrETiKuyydk1w0pa+gE/uormcTpSYuaNJPbX1NU3JLyscSLjwAQM8bWMhhIlnCqnRvDTw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-parse-selector": "^4.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/he": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/he/-/he-0.5.0.tgz", + "integrity": "sha512-DoufbNNOFzwRPy8uecq+j+VCPQ+JyDelHTmSgygrA5TsR8Cbw4Qcir5sGtWiusB4BdT89nmlaVDhSJOqC/33vw==", + "dev": true, + "license": "MIT", + "bin": { + "he": "bin/he" + } + }, + "node_modules/html-escaper": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-3.0.3.tgz", + "integrity": "sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==", + "license": "MIT" + }, + "node_modules/html-void-elements": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz", + "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/http-cache-semantics": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", + "license": "BSD-2-Clause" + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "license": "MIT", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=16.17.0" + } + }, + "node_modules/import-meta-resolve": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.1.0.tgz", + "integrity": "sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/inline-style-parser": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz", + "integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==", + "license": "MIT" + }, + "node_modules/insane": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/insane/-/insane-2.6.2.tgz", + "integrity": "sha512-BqEL1CJsjJi+/C/zKZxv31zs3r6zkLH5Nz1WMFb7UBX2KHY2yXDpbFTSEmNHzomBbGDysIfkTX55A0mQZ2CQiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "assignment": "2.0.0", + "he": "0.5.0" + } + }, + "node_modules/is-alphabetical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", + "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-alphanumerical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", + "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", + "license": "MIT", + "dependencies": { + "is-alphabetical": "^2.0.0", + "is-decimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-buffer": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", + "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/is-core-module": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "license": "MIT", + "dependencies": { + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-decimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", + "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-hexadecimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", + "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "license": "MIT", + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-interactive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz", + "integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-reference": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.2.tgz", + "integrity": "sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==", + "license": "MIT", + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-unicode-supported": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.0.0.tgz", + "integrity": "sha512-FRdAyx5lusK1iHG0TWpVtk9+1i+GjrzRffhDg4ovQ7mcidMQ6mj+MhKPmvh7Xwyv5gIS06ns49CA7Sqg7lC22Q==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-wsl": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", + "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", + "license": "MIT", + "dependencies": { + "is-inside-container": "^1.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "license": "ISC" + }, + "node_modules/jackspeak": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.0.tgz", + "integrity": "sha512-JVYhQnN59LVPFCEcVa2C3CrEKYacvjRfqIQl+h8oi91aLYQVWRYbxjPcv1bUiUy/kLmQaANrYfNMCO3kuEDHfw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonc-parser": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-2.3.1.tgz", + "integrity": "sha512-H8jvkz1O50L3dMZCsLqiuB2tA7muqbSg1AtGEkN0leAqGjsUzDJir3Zwr02BhqdcITPg3ei3mZ+HjMocAknhhg==", + "dev": true, + "license": "MIT" + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/load-yaml-file": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/load-yaml-file/-/load-yaml-file-0.2.0.tgz", + "integrity": "sha512-OfCBkGEw4nN6JLtgRidPX6QxjBQGQf72q3si2uvqyFEMbycSFFHwAZeXx6cJgFM9wmLrf9zBwCP3Ivqa+LLZPw==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.5", + "js-yaml": "^3.13.0", + "pify": "^4.0.1", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/load-yaml-file/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/load-yaml-file/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "license": "MIT" + }, + "node_modules/log-symbols": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-6.0.0.tgz", + "integrity": "sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw==", + "license": "MIT", + "dependencies": { + "chalk": "^5.3.0", + "is-unicode-supported": "^1.3.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-symbols/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/log-symbols/node_modules/is-unicode-supported": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", + "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/longest-streak": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", + "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/luxon": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.4.4.tgz", + "integrity": "sha512-zobTr7akeGHnv7eBOXcRgMeCP6+uyYsczwmeRCauvpvaAltgNyTbLH/+VaEAPUeWBT+1GuNmz4wC/6jtQzbbVA==", + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/magic-string": { + "version": "0.30.10", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz", + "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15" + } + }, + "node_modules/markdown-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/markdown-extensions/-/markdown-extensions-2.0.0.tgz", + "integrity": "sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==", + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/markdown-table": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.3.tgz", + "integrity": "sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/marked": { + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/marked/-/marked-12.0.2.tgz", + "integrity": "sha512-qXUm7e/YKFoqFPYPa3Ukg9xlI5cyAtGmyEIzMfW//m6kXwCy2Ps9DYf5ioijFKQ8qyuscrHoY04iJGctu2Kg0Q==", + "dev": true, + "license": "MIT", + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/mdast-util-definitions": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-6.0.0.tgz", + "integrity": "sha512-scTllyX6pnYNZH/AIp/0ePz6s4cZtARxImwoPJ7kS42n+MnVsI4XbnG6d4ibehRIldYMWM2LD7ImQblVhUejVQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "unist-util-visit": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-find-and-replace": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.1.tgz", + "integrity": "sha512-SG21kZHGC3XRTSUhtofZkBzZTJNM5ecCi0SK2IMKmSXR8vO3peL+kb1O0z7Zl83jKtutG4k5Wv/W7V3/YHvzPA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "escape-string-regexp": "^5.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-find-and-replace/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mdast-util-from-markdown": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.1.tgz", + "integrity": "sha512-aJEUyzZ6TzlsX2s5B4Of7lN7EQtAxvtradMMglCQDyaTFgse6CmtmdJ15ElnVRlCg1vpNyVtbem0PWzlNieZsA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark": "^4.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.0.0.tgz", + "integrity": "sha512-dgQEX5Amaq+DuUqf26jJqSK9qgixgd6rYDHAv4aTBuA92cTknZlKpPfa86Z/s8Dj8xsAQpFfBmPUHWJBWqS4Bw==", + "license": "MIT", + "dependencies": { + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-gfm-autolink-literal": "^2.0.0", + "mdast-util-gfm-footnote": "^2.0.0", + "mdast-util-gfm-strikethrough": "^2.0.0", + "mdast-util-gfm-table": "^2.0.0", + "mdast-util-gfm-task-list-item": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-autolink-literal": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.0.tgz", + "integrity": "sha512-FyzMsduZZHSc3i0Px3PQcBT4WJY/X/RCtEJKuybiC6sjPqLv7h1yqAkmILZtuxMSsUyaLUWNp71+vQH2zqp5cg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "ccount": "^2.0.0", + "devlop": "^1.0.0", + "mdast-util-find-and-replace": "^3.0.0", + "micromark-util-character": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-footnote": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.0.0.tgz", + "integrity": "sha512-5jOT2boTSVkMnQ7LTrd6n/18kqwjmuYqo7JUPe+tRCY6O7dAuTFMtTPauYYrMPpox9hlN0uOx/FL8XvEfG9/mQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-strikethrough": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", + "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-table": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", + "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "markdown-table": "^3.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-task-list-item": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", + "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-mdx/-/mdast-util-mdx-3.0.0.tgz", + "integrity": "sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==", + "license": "MIT", + "dependencies": { + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-expression": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.0.tgz", + "integrity": "sha512-fGCu8eWdKUKNu5mohVGkhBXCXGnOTLuFqOvGMvdikr+J1w7lDJgxThOKpwRWzzbyXAU2hhSwsmssOY4yTokluw==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-jsx": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.1.2.tgz", + "integrity": "sha512-eKMQDeywY2wlHc97k5eD8VC+9ASMjN8ItEZQNGwJ6E0XWKiW/Z0V5/H8pvoXUf+y+Mj0VIgeRRbujBmFn4FTyA==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "parse-entities": "^4.0.0", + "stringify-entities": "^4.0.0", + "unist-util-remove-position": "^5.0.0", + "unist-util-stringify-position": "^4.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdxjs-esm": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz", + "integrity": "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-phrasing": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", + "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-hast": { + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz", + "integrity": "sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@ungap/structured-clone": "^1.0.0", + "devlop": "^1.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "trim-lines": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-markdown": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.0.tgz", + "integrity": "sha512-SR2VnIEdVNCJbP6y7kVTJgPLifdr8WEU440fQec7qHoHOUz/oJ2jmNRqdDQ3rbiStOXb2mCDGTuwsK5OPUgYlQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "longest-streak": "^3.0.0", + "mdast-util-phrasing": "^4.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark-util-decode-string": "^2.0.0", + "unist-util-visit": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", + "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "license": "MIT" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromark": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.0.tgz", + "integrity": "sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.1.tgz", + "integrity": "sha512-CUQyKr1e///ZODyD1U3xit6zXwy1a8q2a1S1HKtIlmgvurrEpaw/Y9y6KSIbF8P59cn/NjzHyO+Q2fAyYLQrAA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-destination": "^2.0.0", + "micromark-factory-label": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-title": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-html-tag-name": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", + "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", + "license": "MIT", + "dependencies": { + "micromark-extension-gfm-autolink-literal": "^2.0.0", + "micromark-extension-gfm-footnote": "^2.0.0", + "micromark-extension-gfm-strikethrough": "^2.0.0", + "micromark-extension-gfm-table": "^2.0.0", + "micromark-extension-gfm-tagfilter": "^2.0.0", + "micromark-extension-gfm-task-list-item": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.0.0.tgz", + "integrity": "sha512-rTHfnpt/Q7dEAK1Y5ii0W8bhfJlVJFnJMHIPisfPK3gpVNuOP0VnRl96+YJ3RYWV/P4gFeQoGKNlT3RhuvpqAg==", + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-footnote": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.0.0.tgz", + "integrity": "sha512-6Rzu0CYRKDv3BfLAUnZsSlzx3ak6HAoI85KTiijuKIz5UxZxbUI+pD6oHgw+6UtQuiRwnGRhzMmPRv4smcz0fg==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-strikethrough": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.0.0.tgz", + "integrity": "sha512-c3BR1ClMp5fxxmwP6AoOY2fXO9U8uFMKs4ADD66ahLTNcwzSCyRVU4k7LPV5Nxo/VJiR4TdzxRQY2v3qIUceCw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-table": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.0.0.tgz", + "integrity": "sha512-PoHlhypg1ItIucOaHmKE8fbin3vTLpDOUg8KAr8gRCF1MOZI9Nquq2i/44wFvviM4WuxJzc3demT8Y3dkfvYrw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-tagfilter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz", + "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-task-list-item": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.0.1.tgz", + "integrity": "sha512-cY5PzGcnULaN5O7T+cOzfMoHjBW7j+T9D2sucA5d/KbsBTPcYdebm9zUd9zzdgJGCwahV+/W78Z3nbulBYVbTw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdx-expression": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-expression/-/micromark-extension-mdx-expression-3.0.0.tgz", + "integrity": "sha512-sI0nwhUDz97xyzqJAbHQhp5TfaxEvZZZ2JDqUo+7NvyIYG6BZ5CPPqj2ogUoPJlmXHBnyZUzISg9+oUmU6tUjQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-mdx-expression": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdx-jsx": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-jsx/-/micromark-extension-mdx-jsx-3.0.0.tgz", + "integrity": "sha512-uvhhss8OGuzR4/N17L1JwvmJIpPhAd8oByMawEKx6NVdBCbesjH4t+vjEp3ZXft9DwvlKSD07fCeI44/N0Vf2w==", + "license": "MIT", + "dependencies": { + "@types/acorn": "^4.0.0", + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "micromark-factory-mdx-expression": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdx-md": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-md/-/micromark-extension-mdx-md-2.0.0.tgz", + "integrity": "sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==", + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdxjs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs/-/micromark-extension-mdxjs-3.0.0.tgz", + "integrity": "sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==", + "license": "MIT", + "dependencies": { + "acorn": "^8.0.0", + "acorn-jsx": "^5.0.0", + "micromark-extension-mdx-expression": "^3.0.0", + "micromark-extension-mdx-jsx": "^3.0.0", + "micromark-extension-mdx-md": "^2.0.0", + "micromark-extension-mdxjs-esm": "^3.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdxjs-esm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs-esm/-/micromark-extension-mdxjs-esm-3.0.0.tgz", + "integrity": "sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-position-from-estree": "^2.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-factory-destination": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.0.tgz", + "integrity": "sha512-j9DGrQLm/Uhl2tCzcbLhy5kXsgkHUrjJHg4fFAeoMRwJmJerT9aw4FEhIbZStWN8A3qMwOp1uzHr4UL8AInxtA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-label": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.0.tgz", + "integrity": "sha512-RR3i96ohZGde//4WSe/dJsxOX6vxIg9TimLAS3i4EhBAFx8Sm5SmqVfR8E87DPSR31nEAjZfbt91OMZWcNgdZw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-mdx-expression": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-mdx-expression/-/micromark-factory-mdx-expression-2.0.1.tgz", + "integrity": "sha512-F0ccWIUHRLRrYp5TC9ZYXmZo+p2AM13ggbsW4T0b5CRKP8KHVRB8t4pwtBgTxtjRmwrK0Irwm7vs2JOZabHZfg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-position-from-estree": "^2.0.0", + "vfile-message": "^4.0.0" + } + }, + "node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-title": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.0.tgz", + "integrity": "sha512-jY8CSxmpWLOxS+t8W+FG3Xigc0RDQA9bKMY/EwILvsesiRniiVMejYTE4wumNc2f4UbAa4WsHqe3J1QS1sli+A==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-whitespace": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.0.tgz", + "integrity": "sha512-28kbwaBjc5yAI1XadbdPYHX/eDnqaUFVikLwrO7FDnKG7lpgxnvk/XGRhX/PN0mOZ+dBSZ+LgunHS+6tYQAzhA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-chunked": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.0.tgz", + "integrity": "sha512-anK8SWmNphkXdaKgz5hJvGa7l00qmcaUQoMYsBwDlSKFKjc6gjGXPDw3FNL3Nbwq5L8gE+RCbGqTw49FK5Qyvg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-classify-character": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.0.tgz", + "integrity": "sha512-S0ze2R9GH+fu41FA7pbSqNWObo/kzwf8rN/+IGlW/4tC6oACOs8B++bh+i9bVyNnwCcuksbFwsBme5OCKXCwIw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-combine-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.0.tgz", + "integrity": "sha512-vZZio48k7ON0fVS3CUgFatWHoKbbLTK/rT7pzpJ4Bjp5JjkZeasRfrS9wsBdDJK2cJLHMckXZdzPSSr1B8a4oQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-chunked": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-numeric-character-reference": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.1.tgz", + "integrity": "sha512-bmkNc7z8Wn6kgjZmVHOX3SowGmVdhYS7yBpMnuMnPzDq/6xwVA604DuOXMZTO1lvq01g+Adfa0pE2UKGlxL1XQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.0.tgz", + "integrity": "sha512-r4Sc6leeUTn3P6gk20aFMj2ntPwn6qpDZqWvYmAG6NgvFTIlj4WtrAudLi65qYoaGdXYViXYw2pkmn7QnIFasA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-encode": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.0.tgz", + "integrity": "sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-events-to-acorn": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-events-to-acorn/-/micromark-util-events-to-acorn-2.0.2.tgz", + "integrity": "sha512-Fk+xmBrOv9QZnEDguL9OI9/NQQp6Hz4FuQ4YmCb/5V7+9eAh1s6AYSvL20kHkD67YIg7EpE54TiSlcsf3vyZgA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/acorn": "^4.0.0", + "@types/estree": "^1.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "estree-util-visit": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "vfile-message": "^4.0.0" + } + }, + "node_modules/micromark-util-html-tag-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.0.tgz", + "integrity": "sha512-xNn4Pqkj2puRhKdKTm8t1YHC/BAjx6CEwRFXntTaRf/x16aqka6ouVoutm+QdkISTlT7e2zU7U4ZdlDLJd2Mcw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-normalize-identifier": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.0.tgz", + "integrity": "sha512-2xhYT0sfo85FMrUPtHcPo2rrp1lwbDEEzpx7jiH2xXJLqBuy4H0GgXk5ToU8IEwoROtXuL8ND0ttVa4rNqYK3w==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-resolve-all": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.0.tgz", + "integrity": "sha512-6KU6qO7DZ7GJkaCgwBNtplXCvGkJToU86ybBAUdavvgsCiG8lSSvYxr9MhwmQ+udpzywHsl4RpGJsYWG1pDOcA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.0.tgz", + "integrity": "sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-subtokenize": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.0.1.tgz", + "integrity": "sha512-jZNtiFl/1aY73yS3UGQkutD0UbhTt68qnRpw2Pifmz5wV9h8gOVsN70v+Lq/f1rKaU/W8pxRe8y8Q9FX1AOe1Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-types": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.0.tgz", + "integrity": "sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", + "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/minimatch": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", + "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/mrmime": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz", + "integrity": "sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "license": "MIT" + }, + "node_modules/muggle-string": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/muggle-string/-/muggle-string-0.4.1.tgz", + "integrity": "sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/nlcst-to-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/nlcst-to-string/-/nlcst-to-string-4.0.0.tgz", + "integrity": "sha512-YKLBCcUYKAg0FNlOBT6aI91qFmSiFKiluk655WzPF+DDMA02qIyy8uiRqI8QXtcFpEvll12LpL5MXqEmAZ+dcA==", + "license": "MIT", + "dependencies": { + "@types/nlcst": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/node-releases": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", + "license": "MIT" + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "license": "MIT", + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "license": "MIT", + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-8.0.1.tgz", + "integrity": "sha512-ANIvzobt1rls2BDny5fWZ3ZVKyD6nscLvfFRpQgfWsythlcsVUC9kL0zq6j2Z5z9wwp1kd7wpsD/T9qNPVLCaQ==", + "license": "MIT", + "dependencies": { + "chalk": "^5.3.0", + "cli-cursor": "^4.0.0", + "cli-spinners": "^2.9.2", + "is-interactive": "^2.0.0", + "is-unicode-supported": "^2.0.0", + "log-symbols": "^6.0.0", + "stdin-discarder": "^0.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/p-limit": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-5.0.0.tgz", + "integrity": "sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==", + "license": "MIT", + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate/node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-queue": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-8.0.1.tgz", + "integrity": "sha512-NXzu9aQJTAzbBqOt2hwsR63ea7yvxJc0PwN/zobNAudYfb1B7R08SzB4TsLeSbUCuG467NhnoT0oO6w1qRO+BA==", + "license": "MIT", + "dependencies": { + "eventemitter3": "^5.0.1", + "p-timeout": "^6.1.2" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-timeout": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-6.1.2.tgz", + "integrity": "sha512-UbD77BuZ9Bc9aABo74gfXhNvzC9Tx7SxtHSh1fxvx3jTLLYvmVhiQZZrJzqqU0jKbN32kb5VOKiLEQI/3bIjgQ==", + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-entities": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.1.tgz", + "integrity": "sha512-SWzvYcSJh4d/SGLIOQfZ/CoNv6BTlI6YEQ7Nj82oDVnRpwe/Z/F1EMx42x3JAOwGBlCjeCH0BRJQbQ/opHL17w==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "character-entities": "^2.0.0", + "character-entities-legacy": "^3.0.0", + "character-reference-invalid": "^2.0.0", + "decode-named-character-reference": "^1.0.0", + "is-alphanumerical": "^2.0.0", + "is-decimal": "^2.0.0", + "is-hexadecimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/parse-entities/node_modules/@types/unist": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", + "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==", + "license": "MIT" + }, + "node_modules/parse-latin": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/parse-latin/-/parse-latin-7.0.0.tgz", + "integrity": "sha512-mhHgobPPua5kZ98EF4HWiH167JWBfl4pvAIXXdbaVohtK7a6YBOy56kvhCqduqyo/f3yrHFWmqmiMg/BkBkYYQ==", + "license": "MIT", + "dependencies": { + "@types/nlcst": "^2.0.0", + "@types/unist": "^3.0.0", + "nlcst-to-string": "^4.0.0", + "unist-util-modify-children": "^4.0.0", + "unist-util-visit-children": "^3.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/parse5": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "license": "MIT", + "dependencies": { + "entities": "^4.4.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/path-browserify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "license": "MIT" + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.2.tgz", + "integrity": "sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "14 || >=16.14" + } + }, + "node_modules/path-to-regexp": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.2.tgz", + "integrity": "sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==", + "license": "MIT" + }, + "node_modules/periscopic": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz", + "integrity": "sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^3.0.0", + "is-reference": "^3.0.0" + } + }, + "node_modules/pg": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.12.0.tgz", + "integrity": "sha512-A+LHUSnwnxrnL/tZ+OLfqR1SxLN3c/pgDztZ47Rpbsd4jUytsTtwQo/TLPRzPJMp/1pbhYVhH9cuSZLAajNfjQ==", + "license": "MIT", + "dependencies": { + "pg-connection-string": "^2.6.4", + "pg-pool": "^3.6.2", + "pg-protocol": "^1.6.1", + "pg-types": "^2.1.0", + "pgpass": "1.x" + }, + "engines": { + "node": ">= 8.0.0" + }, + "optionalDependencies": { + "pg-cloudflare": "^1.1.1" + }, + "peerDependencies": { + "pg-native": ">=3.0.1" + }, + "peerDependenciesMeta": { + "pg-native": { + "optional": true + } + } + }, + "node_modules/pg-cloudflare": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.1.1.tgz", + "integrity": "sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==", + "license": "MIT", + "optional": true + }, + "node_modules/pg-connection-string": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.4.tgz", + "integrity": "sha512-v+Z7W/0EO707aNMaAEfiGnGL9sxxumwLl2fJvCQtMn9Fxsg+lPpPkdcyBSv/KFgpGdYkMfn+EI1Or2EHjpgLCA==", + "license": "MIT" + }, + "node_modules/pg-int8": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", + "license": "ISC", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/pg-numeric": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pg-numeric/-/pg-numeric-1.0.2.tgz", + "integrity": "sha512-BM/Thnrw5jm2kKLE5uJkXqqExRUY/toLHda65XgFTBTFYZyopbKjBe29Ii3RbkvlsMoFwD+tHeGaCjjv0gHlyw==", + "devOptional": true, + "license": "ISC", + "engines": { + "node": ">=4" + } + }, + "node_modules/pg-pool": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.6.2.tgz", + "integrity": "sha512-Htjbg8BlwXqSBQ9V8Vjtc+vzf/6fVUuak/3/XXKA9oxZprwW3IMDQTGHP+KDmVL7rtd+R1QjbnCFPuTHm3G4hg==", + "license": "MIT", + "peerDependencies": { + "pg": ">=8.0" + } + }, + "node_modules/pg-protocol": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.6.1.tgz", + "integrity": "sha512-jPIlvgoD63hrEuihvIg+tJhoGjUsLPn6poJY9N5CnlPd91c2T18T/9zBtLxZSb1EhYxBRoZJtzScCaWlYLtktg==", + "license": "MIT" + }, + "node_modules/pg-types": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-4.0.2.tgz", + "integrity": "sha512-cRL3JpS3lKMGsKaWndugWQoLOCoP+Cic8oseVcbr0qhPzYD5DWXK+RZ9LY9wxRf7RQia4SCwQlXk0q6FCPrVng==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "pg-int8": "1.0.1", + "pg-numeric": "1.0.2", + "postgres-array": "~3.0.1", + "postgres-bytea": "~3.0.0", + "postgres-date": "~2.1.0", + "postgres-interval": "^3.0.0", + "postgres-range": "^1.1.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/pg/node_modules/pg-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "license": "MIT", + "dependencies": { + "pg-int8": "1.0.1", + "postgres-array": "~2.0.0", + "postgres-bytea": "~1.0.0", + "postgres-date": "~1.0.4", + "postgres-interval": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pg/node_modules/postgres-array": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/pg/node_modules/postgres-bytea": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", + "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pg/node_modules/postgres-date": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pg/node_modules/postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", + "license": "MIT", + "dependencies": { + "xtend": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pgpass": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz", + "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", + "license": "MIT", + "dependencies": { + "split2": "^4.1.0" + } + }, + "node_modules/picocolors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "license": "MIT", + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-dir/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/postcss": { + "version": "8.4.38", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", + "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.0", + "source-map-js": "^1.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postgres-array": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-3.0.2.tgz", + "integrity": "sha512-6faShkdFugNQCLwucjPcY5ARoW1SlbnrZjmGl0IrrqewpvxvhSLHimCVzqeuULCbG0fQv7Dtk1yDbG3xv7Veog==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/postgres-bytea": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-3.0.0.tgz", + "integrity": "sha512-CNd4jim9RFPkObHSjVHlVrxoVQXz7quwNFpz7RY1okNNme49+sVyiTvTRobiLV548Hx/hb1BG+iE7h9493WzFw==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "obuf": "~1.1.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/postgres-date": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-2.1.0.tgz", + "integrity": "sha512-K7Juri8gtgXVcDfZttFKVmhglp7epKb1K4pgrkLxehjqkrgPhfG6OO8LHLkfaqkbpjNRnra018XwAr1yQFWGcA==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/postgres-interval": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-3.0.0.tgz", + "integrity": "sha512-BSNDnbyZCXSxgA+1f5UU2GmwhoI0aU5yMxRGO8CdFEcY2BQF9xm/7MqKnYoM1nJDk8nONNWDk9WeSmePFhQdlw==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/postgres-range": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/postgres-range/-/postgres-range-1.1.4.tgz", + "integrity": "sha512-i/hbxIE9803Alj/6ytL7UHQxRvZkI9O4Sy+J3HGc4F4oo/2eQAjTSNJ0bfxyse3bH0nuVesCk+3IRLaMtG3H6w==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/preferred-pm": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/preferred-pm/-/preferred-pm-3.1.3.tgz", + "integrity": "sha512-MkXsENfftWSRpzCzImcp4FRsCc3y1opwB73CfCNWyzMqArju2CrlMHlqB7VexKiPEOjGMbttv1r9fSCn5S610w==", + "license": "MIT", + "dependencies": { + "find-up": "^5.0.0", + "find-yarn-workspace-root2": "1.2.16", + "path-exists": "^4.0.0", + "which-pm": "2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/preferred-pm/node_modules/which-pm": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-pm/-/which-pm-2.0.0.tgz", + "integrity": "sha512-Lhs9Pmyph0p5n5Z3mVnN0yWcbQYUAD7rbQUiMsQxOJ3T57k7RFe35SUwWMf7dsbDZks1uOmw4AecB/JMDj3v/w==", + "license": "MIT", + "dependencies": { + "load-yaml-file": "^0.2.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8.15" + } + }, + "node_modules/prettier": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.2.tgz", + "integrity": "sha512-rAVeHYMcv8ATV5d508CFdn+8/pHPpXeIid1DdrPwXnaAdH7cqjVbpJaT5eq4yRAFU/lsbwYwSF/n5iNrdJHPQA==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/prettier-plugin-astro": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/prettier-plugin-astro/-/prettier-plugin-astro-0.14.0.tgz", + "integrity": "sha512-7jRGJsexaRIyUzTk8uzXlP45cw6DQ5Ci4bTe0xCBCcuO1Fff8jJy9oI+kRCQKSdDFTSAArMSg8GpvzlKBtSaZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@astrojs/compiler": "^1.5.5", + "prettier": "^3.0.0", + "sass-formatter": "^0.7.6" + }, + "engines": { + "node": "^14.15.0 || >=16.0.0" + } + }, + "node_modules/prettier-plugin-astro-organize-imports": { + "version": "0.4.8", + "resolved": "https://registry.npmjs.org/prettier-plugin-astro-organize-imports/-/prettier-plugin-astro-organize-imports-0.4.8.tgz", + "integrity": "sha512-CwE/oT6to5udHK7vSTZiU6TTzdbfBW5WiLTzmkmC2zmF9dREJNtqVPB/Yl11I763cEf/sxyORa+jOf88f8aEyg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@astrojs/compiler": "^2.8.0", + "typescript": "^5.4.5" + }, + "peerDependencies": { + "prettier": "^3.0", + "prettier-plugin-astro": "*", + "prettier-plugin-tailwindcss": "*" + }, + "peerDependenciesMeta": { + "prettier-plugin-astro": { + "optional": true + }, + "prettier-plugin-tailwindcss": { + "optional": true + } + } + }, + "node_modules/prettier-plugin-astro/node_modules/@astrojs/compiler": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/@astrojs/compiler/-/compiler-1.8.2.tgz", + "integrity": "sha512-o/ObKgtMzl8SlpIdzaxFnt7SATKPxu4oIP/1NL+HDJRzxfJcAkOTAb/ZKMRyULbz4q+1t2/DAebs2Z1QairkZw==", + "dev": true, + "license": "MIT" + }, + "node_modules/prettier-plugin-organize-imports": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/prettier-plugin-organize-imports/-/prettier-plugin-organize-imports-3.2.4.tgz", + "integrity": "sha512-6m8WBhIp0dfwu0SkgfOxJqh+HpdyfqSSLfKKRZSFbDuEQXDDndb8fTpRWkUrX/uBenkex3MgnVk0J3b3Y5byog==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@volar/vue-language-plugin-pug": "^1.0.4", + "@volar/vue-typescript": "^1.0.4", + "prettier": ">=2.0", + "typescript": ">=2.9" + }, + "peerDependenciesMeta": { + "@volar/vue-language-plugin-pug": { + "optional": true + }, + "@volar/vue-typescript": { + "optional": true + } + } + }, + "node_modules/prismjs": { + "version": "1.29.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz", + "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/promise-polyfill": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-7.1.0.tgz", + "integrity": "sha512-P6NJ2wU/8fac44ENORsuqT8TiolKGB2u0fEClPtXezn7w5cmLIjM/7mhPlTebke2EPr6tmqZbXvnX0TxwykGrg==", + "dev": true, + "license": "MIT" + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "license": "MIT", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/prompts/node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/property-information": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.5.0.tgz", + "integrity": "sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/qrcode-svg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/qrcode-svg/-/qrcode-svg-1.1.0.tgz", + "integrity": "sha512-XyQCIXux1zEIA3NPb0AeR8UMYvXZzWEhgdBgBjH9gO7M48H9uoHzviNz8pXw3UzrAcxRRRn9gxHewAVK7bn9qw==", + "license": "MIT", + "bin": { + "qrcode-svg": "bin/qrcode-svg.js" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/rehype": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/rehype/-/rehype-13.0.1.tgz", + "integrity": "sha512-AcSLS2mItY+0fYu9xKxOu1LhUZeBZZBx8//5HKzF+0XP+eP8+6a5MXn2+DW2kfXR6Dtp1FEXMVrjyKAcvcU8vg==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "rehype-parse": "^9.0.0", + "rehype-stringify": "^10.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-parse": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/rehype-parse/-/rehype-parse-9.0.0.tgz", + "integrity": "sha512-WG7nfvmWWkCR++KEkZevZb/uw41E8TsH4DsY9UxsTbIXCVGbAs4S+r8FrQ+OtH5EEQAs+5UxKC42VinkmpA1Yw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-from-html": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-raw": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-7.0.0.tgz", + "integrity": "sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-raw": "^9.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-stringify": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/rehype-stringify/-/rehype-stringify-10.0.0.tgz", + "integrity": "sha512-1TX1i048LooI9QoecrXy7nGFFbFSufxVRAfc6Y9YMRAi56l+oB0zP51mLSV312uRuvVLPV1opSlJmslozR1XHQ==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-to-html": "^9.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-gfm": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.0.tgz", + "integrity": "sha512-U92vJgBPkbw4Zfu/IiW2oTZLSL3Zpv+uI7My2eq8JxKgqraFdU8YUGicEJCEgSbeaG+QDFqIcwwfMTOEelPxuA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-gfm": "^3.0.0", + "micromark-extension-gfm": "^3.0.0", + "remark-parse": "^11.0.0", + "remark-stringify": "^11.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-mdx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/remark-mdx/-/remark-mdx-3.0.1.tgz", + "integrity": "sha512-3Pz3yPQ5Rht2pM5R+0J2MrGoBSrzf+tJG94N+t/ilfdh8YLyyKYtidAYwTveB20BoHAcwIopOUqhcmh2F7hGYA==", + "license": "MIT", + "dependencies": { + "mdast-util-mdx": "^3.0.0", + "micromark-extension-mdxjs": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-parse": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", + "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-rehype": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.1.0.tgz", + "integrity": "sha512-z3tJrAs2kIs1AqIIy6pzHmAHlF1hWQ+OdY4/hv+Wxe35EhyLKcajL33iUEn3ScxtFox9nUvRufR/Zre8Q08H/g==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "mdast-util-to-hast": "^13.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-smartypants": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/remark-smartypants/-/remark-smartypants-3.0.1.tgz", + "integrity": "sha512-qyshfCl2eLO0i0558e79ZJsfojC5wjnYLByjt0FmjJQN6aYwcRxpoj784LZJSoWCdnA2ubh5rLNGb8Uur/wDng==", + "license": "MIT", + "dependencies": { + "retext": "^9.0.0", + "retext-smartypants": "^6.0.0", + "unified": "^11.0.4", + "unist-util-visit": "^5.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/remark-stringify": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz", + "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-to-markdown": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/request-light": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/request-light/-/request-light-0.7.0.tgz", + "integrity": "sha512-lMbBMrDoxgsyO+yB3sDcrDuX85yYt7sS8BfQd11jtbW/z5ZWgLZRcEGLsLoYw7I0WSUGQBs8CC8ScIxkTX1+6Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resize-sensor": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/resize-sensor/-/resize-sensor-0.0.6.tgz", + "integrity": "sha512-e+3wwdki9elemYP6AnyG2BK9/Gd7ak46wZN+Z62WwmWfhn2La1XV2rPRRIcar+PhRhfiQDXi29TapGMTIbI3Pg==", + "dev": true + }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "license": "MIT", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/restore-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", + "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", + "license": "MIT", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/restore-cursor/node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/restore-cursor/node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/restore-cursor/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "license": "ISC" + }, + "node_modules/retext": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/retext/-/retext-9.0.0.tgz", + "integrity": "sha512-sbMDcpHCNjvlheSgMfEcVrZko3cDzdbe1x/e7G66dFp0Ff7Mldvi2uv6JkJQzdRcvLYE8CA8Oe8siQx8ZOgTcA==", + "license": "MIT", + "dependencies": { + "@types/nlcst": "^2.0.0", + "retext-latin": "^4.0.0", + "retext-stringify": "^4.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/retext-latin": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/retext-latin/-/retext-latin-4.0.0.tgz", + "integrity": "sha512-hv9woG7Fy0M9IlRQloq/N6atV82NxLGveq+3H2WOi79dtIYWN8OaxogDm77f8YnVXJL2VD3bbqowu5E3EMhBYA==", + "license": "MIT", + "dependencies": { + "@types/nlcst": "^2.0.0", + "parse-latin": "^7.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/retext-smartypants": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/retext-smartypants/-/retext-smartypants-6.1.0.tgz", + "integrity": "sha512-LDPXg95346bqFZnDMHo0S7Rq5p64+B+N8Vz733+wPMDtwb9rCOs9LIdIEhrUOU+TAywX9St+ocQWJt8wrzivcQ==", + "license": "MIT", + "dependencies": { + "@types/nlcst": "^2.0.0", + "nlcst-to-string": "^4.0.0", + "unist-util-visit": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/retext-stringify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/retext-stringify/-/retext-stringify-4.0.0.tgz", + "integrity": "sha512-rtfN/0o8kL1e+78+uxPTqu1Klt0yPzKuQ2BfWwwfgIUSayyzxpM1PJzkKt4V8803uB9qSy32MvI7Xep9khTpiA==", + "license": "MIT", + "dependencies": { + "@types/nlcst": "^2.0.0", + "nlcst-to-string": "^4.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.7.tgz", + "integrity": "sha512-nV6YcJo5wbLW77m+8KjH8aB/7/rxQy9SZ0HY5shnwULfS+9nmTtVXAJET5NdZmCzA4fPI/Hm1wo/Po/4mopOdg==", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^10.3.7" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rollup": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.18.0.tgz", + "integrity": "sha512-QmJz14PX3rzbJCN1SG4Xe/bAAX2a6NpCP8ab2vfu2GiUr8AQcr2nCV/oEO3yneFarB67zk8ShlIyWb2LGTb3Sg==", + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.5" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.18.0", + "@rollup/rollup-android-arm64": "4.18.0", + "@rollup/rollup-darwin-arm64": "4.18.0", + "@rollup/rollup-darwin-x64": "4.18.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.18.0", + "@rollup/rollup-linux-arm-musleabihf": "4.18.0", + "@rollup/rollup-linux-arm64-gnu": "4.18.0", + "@rollup/rollup-linux-arm64-musl": "4.18.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.18.0", + "@rollup/rollup-linux-riscv64-gnu": "4.18.0", + "@rollup/rollup-linux-s390x-gnu": "4.18.0", + "@rollup/rollup-linux-x64-gnu": "4.18.0", + "@rollup/rollup-linux-x64-musl": "4.18.0", + "@rollup/rollup-win32-arm64-msvc": "4.18.0", + "@rollup/rollup-win32-ia32-msvc": "4.18.0", + "@rollup/rollup-win32-x64-msvc": "4.18.0", + "fsevents": "~2.3.2" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/s.color": { + "version": "0.0.15", + "resolved": "https://registry.npmjs.org/s.color/-/s.color-0.0.15.tgz", + "integrity": "sha512-AUNrbEUHeKY8XsYr/DYpl+qk5+aM+DChopnWOPEzn8YKzOhv4l2zH6LzZms3tOZP3wwdOyc0RmTciyi46HLIuA==", + "dev": true, + "license": "MIT" + }, + "node_modules/sass-formatter": { + "version": "0.7.9", + "resolved": "https://registry.npmjs.org/sass-formatter/-/sass-formatter-0.7.9.tgz", + "integrity": "sha512-CWZ8XiSim+fJVG0cFLStwDvft1VI7uvXdCNJYXhDvowiv+DsbD1nXLiQ4zrE5UBvj5DWZJ93cwN0NX5PMsr1Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "suf-log": "^2.5.3" + } + }, + "node_modules/section-matter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz", + "integrity": "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==", + "license": "MIT", + "dependencies": { + "extend-shallow": "^2.0.1", + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/server-destroy": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/server-destroy/-/server-destroy-1.0.1.tgz", + "integrity": "sha512-rb+9B5YBIEzYcD6x2VKidaa+cqYBJQKnU4oe4E3ANwRRN56yk/ua1YCJT1n21NTS8w6CcOclAKNP3PhdCXKYtQ==", + "license": "ISC" + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC" + }, + "node_modules/sharp": { + "version": "0.33.4", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.33.4.tgz", + "integrity": "sha512-7i/dt5kGl7qR4gwPRD2biwD2/SvBn3O04J77XKFgL2OnZtQw+AG9wnuS/csmu80nPRHLYE9E41fyEiG8nhH6/Q==", + "devOptional": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "color": "^4.2.3", + "detect-libc": "^2.0.3", + "semver": "^7.6.0" + }, + "engines": { + "libvips": ">=8.15.2", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.33.4", + "@img/sharp-darwin-x64": "0.33.4", + "@img/sharp-libvips-darwin-arm64": "1.0.2", + "@img/sharp-libvips-darwin-x64": "1.0.2", + "@img/sharp-libvips-linux-arm": "1.0.2", + "@img/sharp-libvips-linux-arm64": "1.0.2", + "@img/sharp-libvips-linux-s390x": "1.0.2", + "@img/sharp-libvips-linux-x64": "1.0.2", + "@img/sharp-libvips-linuxmusl-arm64": "1.0.2", + "@img/sharp-libvips-linuxmusl-x64": "1.0.2", + "@img/sharp-linux-arm": "0.33.4", + "@img/sharp-linux-arm64": "0.33.4", + "@img/sharp-linux-s390x": "0.33.4", + "@img/sharp-linux-x64": "0.33.4", + "@img/sharp-linuxmusl-arm64": "0.33.4", + "@img/sharp-linuxmusl-x64": "0.33.4", + "@img/sharp-wasm32": "0.33.4", + "@img/sharp-win32-ia32": "0.33.4", + "@img/sharp-win32-x64": "0.33.4" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/shiki": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-1.6.4.tgz", + "integrity": "sha512-X88chM7w8jnadoZtjPTi5ahCJx9pc9f8GfEkZAEYUTlcUZIEw2D/RY86HI/LkkE7Nj8TQWkiBfaFTJ3VJT6ESg==", + "license": "MIT", + "dependencies": { + "@shikijs/core": "1.6.4" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "license": "MIT" + }, + "node_modules/smoothscroll": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/smoothscroll/-/smoothscroll-0.4.0.tgz", + "integrity": "sha512-sggQ3U2Un38b3+q/j1P4Y4fCboCtoUIaBYoge+Lb6Xg1H8RTIif/hugVr+ErMtIDpvBbhQfTjtiTeYAfbw1ZGQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">= 8" + } + }, + "node_modules/source-map-js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/space-separated-tokens": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", + "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "license": "ISC", + "engines": { + "node": ">= 10.x" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "license": "BSD-3-Clause" + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/stdin-discarder": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/stdin-discarder/-/stdin-discarder-0.2.2.tgz", + "integrity": "sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.1.0.tgz", + "integrity": "sha512-SEIJCWiX7Kg4c129n48aDRwLbFb2LJmXXFrWBG4NGaRtMQ3myKPKbwrD1BKqQn74oCoNMBVrfDEr5M9YxCsrkw==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/stringify-entities": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", + "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", + "license": "MIT", + "dependencies": { + "character-entities-html4": "^2.0.0", + "character-entities-legacy": "^3.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-bom-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", + "integrity": "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strnum": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", + "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==", + "license": "MIT" + }, + "node_modules/style-to-object": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.4.4.tgz", + "integrity": "sha512-HYNoHZa2GorYNyqiCaBgsxvcJIn7OHq6inEga+E6Ke3m5JkoqpQbnFssk4jwe+K7AhGa2fcha4wSOf1Kn01dMg==", + "license": "MIT", + "dependencies": { + "inline-style-parser": "0.1.1" + } + }, + "node_modules/suf-log": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/suf-log/-/suf-log-2.5.3.tgz", + "integrity": "sha512-KvC8OPjzdNOe+xQ4XWJV2whQA0aM1kGVczMQ8+dStAO6KfEB140JEVQ9dE76ONZ0/Ylf67ni4tILPJB41U0eow==", + "dev": true, + "license": "MIT", + "dependencies": { + "s.color": "0.0.15" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/trim-lines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", + "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/trough": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", + "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/tsconfck": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/tsconfck/-/tsconfck-3.1.0.tgz", + "integrity": "sha512-CMjc5zMnyAjcS9sPLytrbFmj89st2g+JYtY/c02ug4Q+CZaAtCgbyviI0n1YvjZE/pzoc6FbNsINS13DOL1B9w==", + "license": "MIT", + "bin": { + "tsconfck": "bin/tsconfck.js" + }, + "engines": { + "node": "^18 || >=20" + }, + "peerDependencies": { + "typescript": "^5.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", + "dev": true, + "license": "0BSD", + "optional": true + }, + "node_modules/type-fest": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", + "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typesafe-path": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/typesafe-path/-/typesafe-path-0.2.2.tgz", + "integrity": "sha512-OJabfkAg1WLZSqJAJ0Z6Sdt3utnbzr/jh+NAHoyWHJe8CMSy79Gm085094M9nvTPy22KzTVn5Zq5mbapCI/hPA==", + "dev": true, + "license": "MIT" + }, + "node_modules/typescript": { + "version": "5.4.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", + "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", + "devOptional": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/typescript-auto-import-cache": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/typescript-auto-import-cache/-/typescript-auto-import-cache-0.3.2.tgz", + "integrity": "sha512-+laqe5SFL1vN62FPOOJSUDTZxtgsoOXjneYOXIpx5rQ4UMiN89NAtJLpqLqyebv9fgQ/IMeeTX+mQyRnwvJzvg==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.3.8" + } + }, + "node_modules/ultrahtml": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/ultrahtml/-/ultrahtml-1.5.3.tgz", + "integrity": "sha512-GykOvZwgDWZlTQMtp5jrD4BVL+gNn2NVlVafjcFUJ7taY20tqYdwdoWBFy6GBJsNTZe1GkGPkSl5knQAjtgceg==", + "license": "MIT" + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/unherit": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/unherit/-/unherit-3.0.1.tgz", + "integrity": "sha512-akOOQ/Yln8a2sgcLj4U0Jmx0R5jpIg2IUyRrWOzmEbjBtGzBdHtSeFKgoEcoH4KYIG/Pb8GQ/BwtYm0GCq1Sqg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/unified": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.4.tgz", + "integrity": "sha512-apMPnyLjAX+ty4OrNap7yumyVAMlKx5IWU2wlzzUdYJO9A8f1p9m/gywF/GM2ZDFcjQPrx59Mc90KwmxsoklxQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "bail": "^2.0.0", + "devlop": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-find-after": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-find-after/-/unist-util-find-after-5.0.0.tgz", + "integrity": "sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-is": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", + "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-modify-children": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-modify-children/-/unist-util-modify-children-4.0.0.tgz", + "integrity": "sha512-+tdN5fGNddvsQdIzUF3Xx82CU9sMM+fA0dLgR9vOmT0oPT2jH+P1nd5lSqfCfXAw+93NhcXNY2qqvTUtE4cQkw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "array-iterate": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", + "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position-from-estree": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unist-util-position-from-estree/-/unist-util-position-from-estree-2.0.0.tgz", + "integrity": "sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-remove-position": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-5.0.0.tgz", + "integrity": "sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-visit": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", + "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-children": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-children/-/unist-util-visit-children-3.0.0.tgz", + "integrity": "sha512-RgmdTfSBOg04sdPcpTSD1jzoNBjt9a80/ZCzp5cI9n1qPzLZWF9YdvWGN2zmTumP1HWhXKdUWexjy/Wy/lJ7tA==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-parents": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", + "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.16.tgz", + "integrity": "sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.1.2", + "picocolors": "^1.0.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/vfile": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.1.tgz", + "integrity": "sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-location": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-5.0.2.tgz", + "integrity": "sha512-NXPYyxyBSH7zB5U6+3uDdd6Nybz6o6/od9rk8bp9H8GR3L+cm/fC0uUTbqBmUTnMCUDslAGBOIKNfvvb+gGlDg==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-message": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", + "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vite": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.0.tgz", + "integrity": "sha512-hA6vAVK977NyW1Qw+fLvqSo7xDPej7von7C3DwwqPRmnnnK36XEBC/J3j1V5lP8fbt7y0TgTKJbpNGSwM+Bdeg==", + "license": "MIT", + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.38", + "rollup": "^4.13.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vite-plugin-arraybuffer": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/vite-plugin-arraybuffer/-/vite-plugin-arraybuffer-0.0.7.tgz", + "integrity": "sha512-c4Egxj7NUGco2Ggw9KUBToOxuc7Ws7mWm0hz/QnaT5Ph8ycC7ypMBOD31NuhPSx+wdUvgIbS1XpMvJLSdHakPA==", + "dev": true, + "license": "MIT" + }, + "node_modules/vitefu": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-0.2.5.tgz", + "integrity": "sha512-SgHtMLoqaeeGnd2evZ849ZbACbnwQCIwRH57t18FxcXoZop0uQu0uzlIhJBlF/eWVzuce0sHeqPcDo+evVcg8Q==", + "license": "MIT", + "peerDependencies": { + "vite": "^3.0.0 || ^4.0.0 || ^5.0.0" + }, + "peerDependenciesMeta": { + "vite": { + "optional": true + } + } + }, + "node_modules/volar-service-css": { + "version": "0.0.45", + "resolved": "https://registry.npmjs.org/volar-service-css/-/volar-service-css-0.0.45.tgz", + "integrity": "sha512-f+AlUI1+kESbcZSVaNJVAnK0c/9Da5StoxzPqA5/8VqUHJWNdubWNnwG5xpFVTfgh6pgTcey3UBhBfHytFaIOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "vscode-css-languageservice": "^6.2.10", + "vscode-languageserver-textdocument": "^1.0.11", + "vscode-uri": "^3.0.8" + }, + "peerDependencies": { + "@volar/language-service": "~2.2.3" + }, + "peerDependenciesMeta": { + "@volar/language-service": { + "optional": true + } + } + }, + "node_modules/volar-service-emmet": { + "version": "0.0.45", + "resolved": "https://registry.npmjs.org/volar-service-emmet/-/volar-service-emmet-0.0.45.tgz", + "integrity": "sha512-9nLXSDkR1vA/3fQkFEsSXAu3XovQxOpTkVG2jilQgfek/K1ZLkaA/WMhN/TtmPmQg4NxE9Ni6mA5udBQ5gVXIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@emmetio/css-parser": "^0.4.0", + "@emmetio/html-matcher": "^1.3.0", + "@vscode/emmet-helper": "^2.9.2" + }, + "peerDependencies": { + "@volar/language-service": "~2.2.3" + }, + "peerDependenciesMeta": { + "@volar/language-service": { + "optional": true + } + } + }, + "node_modules/volar-service-html": { + "version": "0.0.45", + "resolved": "https://registry.npmjs.org/volar-service-html/-/volar-service-html-0.0.45.tgz", + "integrity": "sha512-tLTJqfy1v5C4nmeAsfekFIKPl4r4qDMyL0L9MWywr/EApZzPCsbeUGxCqdzxSMC2q7PMCfX2i167txDo+J0LVA==", + "dev": true, + "license": "MIT", + "dependencies": { + "vscode-html-languageservice": "npm:@johnsoncodehk/vscode-html-languageservice@5.2.0-34a5462", + "vscode-languageserver-textdocument": "^1.0.11", + "vscode-uri": "^3.0.8" + }, + "peerDependencies": { + "@volar/language-service": "~2.2.3" + }, + "peerDependenciesMeta": { + "@volar/language-service": { + "optional": true + } + } + }, + "node_modules/volar-service-html/node_modules/@vscode/l10n": { + "version": "0.0.18", + "resolved": "https://registry.npmjs.org/@vscode/l10n/-/l10n-0.0.18.tgz", + "integrity": "sha512-KYSIHVmslkaCDyw013pphY+d7x1qV8IZupYfeIfzNA+nsaWHbn5uPuQRvdRFsa9zFzGeudPuoGoZ1Op4jrJXIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/volar-service-html/node_modules/vscode-html-languageservice": { + "name": "@johnsoncodehk/vscode-html-languageservice", + "version": "5.2.0-34a5462", + "resolved": "https://registry.npmjs.org/@johnsoncodehk/vscode-html-languageservice/-/vscode-html-languageservice-5.2.0-34a5462.tgz", + "integrity": "sha512-etqLfpSJ5zaw76KUNF603be6d6QsiQPmaHr9FKEp4zhLZJzWCCMH6Icak7MtLUFLZLMpL761mZNImi/joBo1ZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vscode/l10n": "^0.0.18", + "vscode-languageserver-textdocument": "^1.0.11", + "vscode-languageserver-types": "^3.17.5", + "vscode-uri": "^3.0.8" + } + }, + "node_modules/volar-service-prettier": { + "version": "0.0.45", + "resolved": "https://registry.npmjs.org/volar-service-prettier/-/volar-service-prettier-0.0.45.tgz", + "integrity": "sha512-+mBS2EsDgp/kunKEBnHvhBwIQm5v2ahw4NKpKdg4sTpXy3UxqHt+Fq/wRYQ7Z8LlNVNRVfp75ThjM+w2zaZBAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "vscode-uri": "^3.0.8" + }, + "peerDependencies": { + "@volar/language-service": "~2.2.3", + "prettier": "^2.2 || ^3.0" + }, + "peerDependenciesMeta": { + "@volar/language-service": { + "optional": true + }, + "prettier": { + "optional": true + } + } + }, + "node_modules/volar-service-typescript": { + "version": "0.0.45", + "resolved": "https://registry.npmjs.org/volar-service-typescript/-/volar-service-typescript-0.0.45.tgz", + "integrity": "sha512-i/mMIIAMastJ2kgPo3qvX0Rrl7NyxhIYZ0ug/B4ambZcLPI1vzBgS2fmvyWX3jhBYHh8NmbAotFj+0Y9JtN47A==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-browserify": "^1.0.1", + "semver": "^7.5.4", + "typescript-auto-import-cache": "^0.3.1", + "vscode-languageserver-textdocument": "^1.0.11", + "vscode-nls": "^5.2.0" + }, + "peerDependencies": { + "@volar/language-service": "~2.2.3" + }, + "peerDependenciesMeta": { + "@volar/language-service": { + "optional": true + } + } + }, + "node_modules/volar-service-typescript-twoslash-queries": { + "version": "0.0.45", + "resolved": "https://registry.npmjs.org/volar-service-typescript-twoslash-queries/-/volar-service-typescript-twoslash-queries-0.0.45.tgz", + "integrity": "sha512-KrPUUvKggZgV9mrDpstCzmf20irgv0ooMv+FGDzIIQUkya+d2+nSS8Mx2h9FvsYgLccUVw5jU3Rhwhd3pv/7qg==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@volar/language-service": "~2.2.3" + }, + "peerDependenciesMeta": { + "@volar/language-service": { + "optional": true + } + } + }, + "node_modules/vscode-css-languageservice": { + "version": "6.2.14", + "resolved": "https://registry.npmjs.org/vscode-css-languageservice/-/vscode-css-languageservice-6.2.14.tgz", + "integrity": "sha512-5UPQ9Y1sUTnuMyaMBpO7LrBkqjhEJb5eAwdUlDp+Uez8lry+Tspnk3+3p2qWS4LlNsr4p3v9WkZxUf1ltgFpgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vscode/l10n": "^0.0.18", + "vscode-languageserver-textdocument": "^1.0.11", + "vscode-languageserver-types": "3.17.5", + "vscode-uri": "^3.0.8" + } + }, + "node_modules/vscode-css-languageservice/node_modules/@vscode/l10n": { + "version": "0.0.18", + "resolved": "https://registry.npmjs.org/@vscode/l10n/-/l10n-0.0.18.tgz", + "integrity": "sha512-KYSIHVmslkaCDyw013pphY+d7x1qV8IZupYfeIfzNA+nsaWHbn5uPuQRvdRFsa9zFzGeudPuoGoZ1Op4jrJXIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/vscode-html-languageservice": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/vscode-html-languageservice/-/vscode-html-languageservice-5.2.0.tgz", + "integrity": "sha512-cdNMhyw57/SQzgUUGSIMQ66jikqEN6nBNyhx5YuOyj9310+eY9zw8Q0cXpiKzDX8aHYFewQEXRnigl06j/TVwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vscode/l10n": "^0.0.18", + "vscode-languageserver-textdocument": "^1.0.11", + "vscode-languageserver-types": "^3.17.5", + "vscode-uri": "^3.0.8" + } + }, + "node_modules/vscode-html-languageservice/node_modules/@vscode/l10n": { + "version": "0.0.18", + "resolved": "https://registry.npmjs.org/@vscode/l10n/-/l10n-0.0.18.tgz", + "integrity": "sha512-KYSIHVmslkaCDyw013pphY+d7x1qV8IZupYfeIfzNA+nsaWHbn5uPuQRvdRFsa9zFzGeudPuoGoZ1Op4jrJXIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/vscode-jsonrpc": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0.tgz", + "integrity": "sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/vscode-languageserver": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-9.0.1.tgz", + "integrity": "sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g==", + "dev": true, + "license": "MIT", + "dependencies": { + "vscode-languageserver-protocol": "3.17.5" + }, + "bin": { + "installServerIntoExtension": "bin/installServerIntoExtension" + } + }, + "node_modules/vscode-languageserver-protocol": { + "version": "3.17.5", + "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.5.tgz", + "integrity": "sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==", + "dev": true, + "license": "MIT", + "dependencies": { + "vscode-jsonrpc": "8.2.0", + "vscode-languageserver-types": "3.17.5" + } + }, + "node_modules/vscode-languageserver-textdocument": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.11.tgz", + "integrity": "sha512-X+8T3GoiwTVlJbicx/sIAF+yuJAqz8VvwJyoMVhwEMoEKE/fkDmrqUgDMyBECcM2A2frVZIUj5HI/ErRXCfOeA==", + "dev": true, + "license": "MIT" + }, + "node_modules/vscode-languageserver-types": { + "version": "3.17.5", + "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.5.tgz", + "integrity": "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==", + "dev": true, + "license": "MIT" + }, + "node_modules/vscode-nls": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-5.2.0.tgz", + "integrity": "sha512-RAaHx7B14ZU04EU31pT+rKz2/zSl7xMsfIZuo8pd+KZO6PXtQmpevpq3vxvWNcrGbdmhM/rr5Uw5Mz+NBfhVng==", + "dev": true, + "license": "MIT" + }, + "node_modules/vscode-uri": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.8.tgz", + "integrity": "sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==", + "dev": true, + "license": "MIT" + }, + "node_modules/web-namespaces": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz", + "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-pm": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/which-pm/-/which-pm-2.2.0.tgz", + "integrity": "sha512-MOiaDbA5ZZgUjkeMWM5EkJp4loW5ZRoa5bc3/aeMox/PJelMhE6t7S/mLuiY43DBupyxH+S0U1bTui9kWUlmsw==", + "license": "MIT", + "dependencies": { + "load-yaml-file": "^0.2.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8.15" + } + }, + "node_modules/which-pm-runs": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.1.0.tgz", + "integrity": "sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/widest-line": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-4.0.1.tgz", + "integrity": "sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==", + "license": "MIT", + "dependencies": { + "string-width": "^5.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/widest-line/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "license": "MIT" + }, + "node_modules/widest-line/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "license": "MIT" + }, + "node_modules/wrap-ansi/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "license": "MIT", + "engines": { + "node": ">=0.4" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "license": "ISC" + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/yargs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yocto-queue": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", + "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", + "license": "MIT", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zod": { + "version": "3.23.8", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz", + "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/zod-to-json-schema": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.23.0.tgz", + "integrity": "sha512-az0uJ243PxsRIa2x1WmNE/pnuA05gUq/JB8Lwe1EDCCL/Fz9MgjYQ0fPlyc2Tcv6aF2ZA7WM5TWaRZVEFaAIag==", + "license": "ISC", + "peerDependencies": { + "zod": "^3.23.3" + } + }, + "node_modules/zwitch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", + "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..3bf4861 --- /dev/null +++ b/package.json @@ -0,0 +1,80 @@ +{ + "name": "yufan.me", + "version": "3.0.0", + "private": true, + "keywords": [ + "blog", + "astro", + "yufan", + "ameho", + "syhily" + ], + "homepage": "https://yufan.me", + "bugs": { + "url": "https://github.com/syhily/yufan.me/issues", + "email": "syhily@gmail.com" + }, + "repository": { + "type": "git", + "url": "https://github.com/syhily/yufan.me.git" + }, + "license": "MIT", + "author": { + "name": "Yufan Sheng", + "email": "syhily@gmail.com", + "url": "https://yufan.me" + }, + "type": "module", + "scripts": { + "astro": "astro", + "build": "rimraf dist && astro check && astro build", + "dev": "astro dev", + "lint": "biome check --write --use-server . && prettier . --write", + "prepare": "npx husky", + "preview": "astro preview", + "start": "astro dev" + }, + "lint-staged": { + "**/*": [ + "biome check --no-errors-on-unmatched --files-ignore-unknown=true", + "prettier --write --ignore-unknown" + ] + }, + "dependencies": { + "@astrojs/mdx": "^3.1.0", + "@astrojs/node": "^8.3.0", + "@astrojs/rss": "^4.0.6", + "astro": "^4.10.2", + "drizzle-orm": "^0.31.2", + "fuse.js": "^7.0.0", + "lodash": "^4.17.21", + "luxon": "^3.4.4", + "pg": "^8.12.0", + "qrcode-svg": "^1.1.0", + "ultrahtml": "^1.5.3" + }, + "devDependencies": { + "@astrojs/check": "^0.7.0", + "@biomejs/biome": "^1.8.1", + "@napi-rs/canvas": "^0.1.53", + "@types/lodash": "^4.17.5", + "@types/luxon": "^3.4.2", + "@types/node": "^20.14.2", + "@types/pg": "^8.11.6", + "@types/qrcode-svg": "^1.1.4", + "@types/unist": "^3.0.2", + "aplayer": "^1.10.1", + "artalk": "^2.8.7", + "bootstrap": "^5.3.3", + "prettier": "^3.3.2", + "prettier-plugin-astro": "^0.14.0", + "prettier-plugin-astro-organize-imports": "^0.4.8", + "prettier-plugin-organize-imports": "^3.2.4", + "resize-sensor": "^0.0.6", + "rimraf": "^5.0.7", + "sharp": "^0.33.4", + "typescript": "^5.4.5", + "unist-util-visit": "^5.0.0", + "vite-plugin-arraybuffer": "^0.0.7" + } +} diff --git a/public/apple-touch-icon.png b/public/apple-touch-icon.png new file mode 100644 index 0000000..ee0b2d2 Binary files /dev/null and b/public/apple-touch-icon.png differ diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000..076c336 Binary files /dev/null and b/public/favicon.ico differ diff --git a/public/favicon.svg b/public/favicon.svg new file mode 100644 index 0000000..13eb2db --- /dev/null +++ b/public/favicon.svg @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="UTF-8"?> +<svg width="300px" height="300px" viewBox="0 0 300 300" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <title>favicon</title> + <g id="favicon" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> + <rect fill="#263148" x="0" y="0" width="300" height="300" /> + <g id="logo-white" transform="translate(9, 3.888)"> + <path d="M159,154.195523 C167.013592,152.617424 174.05936,152.751451 180.129673,154.674602 C190.120795,157.839913 194.348511,161.02564 199.517296,168.40144 C202.925628,173.265093 205.718707,181.861769 208,194.149433 C202.817237,195.503225 198.494331,195.463815 195.074572,193.809733 C188.963104,190.853715 183.30068,186.732689 175.022826,177.505654 C169.768056,171.648346 164.430736,163.875789 159,154.195523 Z" id="font1-dot" fill="#EEB4B4" /> + <path d="M151.486676,25.701431 C155.616373,28.5082875 160.109234,31.601356 164.965286,34.9806001 C165.393463,35.2785613 165.822641,35.5757097 166.255249,35.8738863 L167.105716,36.458366 C168.619019,37.4954138 170.108644,38.5008303 171.499238,39.4303971 L172.608374,40.1697969 C174.26724,41.2727003 175.735093,42.2354804 176.860606,42.9690389 L176.448028,45.1207071 L166.710146,84.6326462 C180.591569,66.4261557 193.885083,57.2272012 206.997372,58.6211808 C208.743695,58.806834 210.475625,59.0033727 212.18144,59.2464237 C212.733943,59.3251464 213.291751,59.4029337 213.853878,59.4813177 C215.158468,59.6632319 216.474026,59.8465926 217.787079,60.0508718 L218.661915,60.1902579 C225.09927,61.241972 231.826526,62.8614549 236.986443,68.0144332 C240.889249,71.9119921 243.813448,77.8014483 245.23642,86.708071 C247.095663,98.3453903 243.120654,117.723729 238.770002,139.330906 L238.580551,140.271866 C237.890376,143.700241 237.191343,147.180322 236.50179,150.693982 L236.044022,153.039529 C235.556986,155.549827 235.077075,158.073824 234.610494,160.607168 L234.263405,162.507565 L233.922672,164.406776 C228.900089,192.67064 226.130123,221.241925 234.44056,240.371255 C240.652266,254.669635 245.935235,262.932333 250.296038,267.670416 C253.412465,271.056463 256.180453,272.79959 258.553083,273.698031 C262.383549,275.148509 265.383302,274.528886 267.668585,273.982958 C268.14919,273.865733 268.422366,273.767797 268.665926,273.767797 C271.112421,273.767797 275.809409,272.387068 282.731388,269.370175 C283.375366,277.48654 282.878184,284.333295 281.156359,289.899262 C280.659157,291.506519 280.558961,292.472131 279.535062,293.024782 C275.748117,295.068793 270.498503,293.963559 265.488631,292.694915 C256.722323,290.485677 244.816282,287.548472 234.696635,275.178958 C233.697221,273.957347 232.737161,272.794212 231.813783,271.675534 C222.758366,260.704951 217.370091,254.220034 212.983093,237.93167 C209.908658,226.516685 208.870828,218.179476 208.826484,204.259903 L208.825284,202.840608 C208.836884,194.672214 209.157933,184.633261 209.605114,171.185381 C210.376069,148.00078 213.79261,132.71409 216.334239,121.332289 C218.054209,113.629996 219.354132,107.626433 219.354132,102.212372 C219.354132,100.105514 219.634597,97.1568247 219.926173,94.0567601 L220.027967,92.9734861 C220.416501,88.8241101 220.77388,84.5552796 220.633396,81.5249303 C220.563268,80.0122213 220.36004,78.7458615 220.056532,77.8111784 C219.39849,75.7846738 218.218924,74.7926623 217.050886,74.319003 C213.016784,72.6831053 207.083752,73.8938983 200.767445,77.2643023 C193.5468,81.1172643 185.881323,87.4227388 181.226749,92.1251087 C170.078149,103.388189 168.197052,106.181552 163.449564,130.566909 C160.514746,145.641534 157.152557,190.083423 153.408527,263.882996 C148.310625,260.529506 144.573436,256.539474 142.267189,251.849384 C137.44815,242.049164 135.781889,238.498147 133.16629,221.130117 C131.151349,207.750561 132.216961,189.426224 132.839043,178.568221 C133.052135,174.848508 133.207609,172.07036 133.207609,170.48586 C133.207609,164.09523 134.233106,147.312148 137.188741,122.72916 C137.780573,117.806695 138.265493,113.776123 138.700893,110.283341 L138.823994,109.299731 C139.331717,105.259782 139.777004,101.934213 140.256685,98.7255887 L140.372518,97.9574584 L140.582929,96.5951823 L140.761224,95.4724241 L140.885706,94.7044198 C141.871689,88.670391 143.122232,82.1576033 145.272592,71.2270532 C148.154429,56.5783156 150.225956,41.4023262 151.486676,25.701431 Z" id="font1-right" fill="#FFFFFF" /> + <path d="M78.8891291,0 L95.8005079,20.9095227 C95.225924,21.6575488 94.6661502,22.3687531 94.1213578,23.0610595 C90.498037,27.665481 87.5143717,31.5165865 85.0892155,38.8498924 C84.5933419,40.3493393 84.11666,41.7284904 83.6520528,43.0728622 C83.5490334,43.3709557 83.4494774,43.6590286 83.3486814,43.9513373 L82.9235478,45.1899741 L82.6412306,46.0224097 L82.2485912,47.2004158 C80.4111972,52.7806913 78.6427308,59.1891547 76.4859025,71.9475546 C76.3776982,72.5876213 76.2738377,73.2121994 76.1751238,73.8203757 L75.8128598,76.0522841 L78.072301,76.1393226 C78.6520627,76.1616563 79.233139,76.1970078 79.8150176,76.2458239 C87.4717734,76.8881795 94.6057156,79.8018442 100.240592,83.8134948 C106.031451,87.9361953 110.302115,93.214716 111.609957,98.4281539 C115.240663,112.901207 110.993666,140.365178 108.836316,154.571762 C108.454224,157.088603 108.185012,158.862829 107.988397,160.271632 C107.819607,161.481054 107.625793,162.940163 107.407149,164.586499 C106.781752,169.295591 105.954511,175.526376 104.92697,181.804864 L104.678362,183.301099 C104.604458,183.739061 104.529572,184.176727 104.455334,184.604273 L104.223432,185.919703 L103.986615,187.248058 C102.465647,195.80355 101.02459,204.149885 98.485251,205.777632 C97.1963754,206.603817 95.9047926,207.065865 94.5842529,207.065865 C93.8588313,207.065865 93.1344185,206.927653 92.4069507,206.668298 L95.4781875,150.606035 L95.4781875,125.416711 C95.4781875,119.629476 93.0062228,110.908957 89.011414,104.252932 C85.2823118,98.0396202 80.2711525,93.9905379 75.163077,93.8351964 C74.0775524,93.8021846 72.9925685,93.9378881 71.9187092,94.2290372 L71.4263054,96.8428337 C70.7159074,100.613041 70.0525722,104.126731 69.4322911,107.412363 C64.7908163,131.998276 62.5529774,143.865744 61.0463793,154.851795 L60.8656498,156.191994 L60.6074832,158.19028 L60.4564922,159.410154 C59.6660213,165.902037 59.0513782,172.654885 58.2694423,182.117243 L58.1071301,184.090317 C57.9422433,186.102896 57.7692971,188.236388 57.5853124,190.511952 C54.4936668,228.750117 54.5110376,253.296254 57.6025561,277.724448 C58.251829,282.854795 58.3254515,286.119184 57.7997112,287.772531 C57.3533443,287.365152 56.8839604,286.712284 56.3626176,285.917213 C52.9105561,280.652664 48.8648383,269.062761 47.655685,256.055841 C44.8625825,226.010303 44.1900887,198.199537 45.6450201,172.623459 C47.1003171,147.040956 50.0546274,122.362378 54.5097037,98.5879441 C54.6592145,97.7900827 54.8106671,96.9918965 54.9640617,96.1933855 C55.1162766,95.4010154 55.2701489,94.6096509 55.4255602,93.8194108 C54.5845527,93.7480795 53.7194585,93.7489156 52.8332622,93.823043 C51.80541,93.9090195 50.8219304,94.0875047 49.8871243,94.3559954 C40.9569857,96.920869 32.323789,109.590977 26.0163924,128.220937 C25.5897822,129.481002 25.1964216,130.603972 24.8064948,131.717231 C23.9716729,134.100687 23.1541733,136.435766 22.0577662,139.963149 C20.3672515,146.863794 19.2883814,155.11982 17.6274898,174.892165 L17.5002077,176.41617 C17.0934812,181.313351 16.6513406,186.891553 16.1571801,193.292133 C9.8071489,188.98619 5.71118886,185.065024 4.00517668,181.431253 C1.70360048,176.528943 0.414450227,167.507602 0,154.408561 C0.00301447963,88.3903589 8.23407782,59.6337727 27.7303891,30.3791899 L35.9962997,39.4225457 C36.9078334,45.6050425 36.6691333,52.0098284 36.334543,58.397272 L36.1828539,61.2074098 C35.9059422,66.2844755 35.6468393,71.3361913 35.8481016,76.2587175 L59.2444284,76.2587175 L59.8164199,73.1824272 C62.3280788,59.6740418 63.7105033,52.2383301 64.7073785,47.2643843 C65.3214048,44.2279628 65.7161407,42.4192098 66.1158122,40.7377245 L66.5998483,38.7653101 C67.0726403,36.911647 67.4709203,35.4207871 67.9619662,33.5825073 C70.1167026,25.5160341 74.7481339,10.4984271 78.8891291,0 Z" id="font1-left" fill="#FFFFFF" /> + </g> + </g> +</svg> diff --git a/public/feed.xsl b/public/feed.xsl new file mode 100644 index 0000000..baf6f13 --- /dev/null +++ b/public/feed.xsl @@ -0,0 +1,68 @@ +<?xml version="1.0" encoding="utf-8"?> +<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/"> + <xsl:output method="html" version="1.0" encoding="UTF-8" indent="yes"/> + <xsl:template match="/"> + <html xmlns="http://www.w3.org/1999/xhtml"> + <head> + <title>订阅 - <xsl:value-of select="/rss/channel/title"/></title> + <link rel="icon" type="image/svg+xml" href="/favicon.svg" /> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> + <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/> + <style type="text/css">body{text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;margin:0;color:rgba(0,0,0,.86);font:16px/1.42 -apple-system,BlinkMacSystemFont,Helvetica Neue,PingFang SC,Hiragino Sans GB,Droid Sans Fallback,Microsoft YaHei,sans-serif}img{max-width:100%}.inner{max-width:860px;margin:0 auto;padding:0 20px;box-sizing:border-box}.top{margin-top:40px;font-size:12px}.top,.top a{color:#9ea0a6}.head{padding-top:80px;padding-bottom:40px}.head_logo{float:left;width:120px;height:120px;margin-right:20px}.head_main{overflow:hidden}.head h1{font-size:36px;font-weight:400;margin:0;color:#000}.head p{margin:0 0 10px;font-size:18px;font-weight:300;color:#9ea0a6}.head .head_link{font-size:14px;font-weight:600;color:#333;text-decoration:none}.links{margin:30px auto}.links a{display:inline-block;text-decoration:none;line-height:28px;padding-left:30px;background-position:0;background-size:24px 24px;background-repeat:no-repeat;font-weight:600;color:#333}.links a+a{margin-left:1.4em}.podcast{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMiIgaGVpZ2h0PSIzMiI+PHBhdGggZmlsbD0iIzkzYyIgZD0iTTE1LjkwNyAzMnMzLjUxMSAwIDMuNTExLTEwLjM5MmMwLTEuOTM1LTEuNTczLTMuNTExLTMuNTExLTMuNTExcy0zLjUxMiAxLjU3Ni0zLjUxMiAzLjUxMUMxMi4zOTUgMzIgMTUuOTA3IDMyIDE1LjkwNyAzMnptNC4zMDYtMy41NDFhMTguODQgMTguODQgMCAwIDAgLjM2Ny0xLjgwMWwuMDcxLS40OGMuMTUzLS4wNjcuMzA3LS4xMzEuNDYxLS4yYTEyLjY4NyAxMi42ODcgMCAwIDAgNS43OTctNS4zMjQgMTIuNTIzIDEyLjUyMyAwIDAgMCAxLjI5Ny0zLjQyOSAxMi4zMyAxMi4zMyAwIDAgMCAuMjIxLTQuMTE3QTExLjg4IDExLjg4IDAgMCAwIDI3LjQgOS4zOTJhMTIuMTMzIDEyLjEzMyAwIDAgMC0yLjU2NS0zLjcxMiAxMi41NzQgMTIuNTc0IDAgMCAwLTMuODMzLTIuNjI5Yy0xLjQ2NC0uNjYxLTMuMDcxLTEuMDAzLTQuNjkzLTEuMDQzYTEyLjUwNCAxMi41MDQgMCAwIDAtNC43NzYuODA0IDEyLjU1IDEyLjU1IDAgMCAwLTYuNyA2LjAxNiAxMi45MDIgMTIuOTAyIDAgMCAwLTEuMjAzIDMuNjMxIDEyLjY1OCAxMi42NTggMCAwIDAgMS4wMDMgNy4zNjQgMTIuNjcyIDEyLjY3MiAwIDAgMCA1LjY3NyA1Ljg1OWMuMzAxLjEzOS42MDEuMjguOTIzLjQxOS4wMi4xNjEuMDYxLjM0MS4wOC41MjMuMS41ODQuMjIxIDEuMTg1LjM2MSAxLjc2N2ExNS42NiAxNS42NiAwIDAgMS0xLjYwNS0uNjI0IDE0LjY0NyAxNC42NDcgMCAwIDEtNi44MDEtNi4zMzkgMTQuOTU1IDE0Ljk1NSAwIDAgMS0xLjQ2NC00LjAxMyAxMy44OTggMTMuODk4IDAgMCAxLS4yLTQuNzU1Yy4yLTEuNDgzLjYyMS0yLjk0OCAxLjI0NC00LjI5M2ExNC45MTEgMTQuOTExIDAgMCAxIDMuMDI4LTQuMjcyIDEzLjk3NCAxMy45NzQgMCAwIDEgNC40MTMtMi45NDhBMTQuNjU0IDE0LjY1NCAwIDAgMSAxNS43Ny4wMDRjMS44ODMtLjAyIDMuNzY1LjMyIDUuNTE5IDEuMDExYTE0LjUzNiAxNC41MzYgMCAwIDEgNC41NzMgMi44ODggMTQuNTUzIDE0LjU1MyAwIDAgMSAzLjEyOCA0LjE4NSAxNC4zMTcgMTQuMzE3IDAgMCAxIDEuMzQ0IDQuMjMzIDE0LjE0IDE0LjE0IDAgMCAxLS4wMjEgNC41OTVjLS4yMjEgMS40MDQtLjY4MyAyLjc4OC0xLjMwNSA0LjA3MWExNC42MzUgMTQuNjM1IDAgMCAxLTYuNTYgNi41NjNjLS43MDMuMzQxLTEuNDQ1LjY0MS0yLjIwNy44ODFsLS4wMjguMDMxem0uNjk0LTUuNzI3bC4wMTMtLjYyN2MwLS40MjEgMC0uODQzLS4wNjEtMS4yNTctLjAyLS4xNjEtLjA2LS4zMDEtLjEtLjQ2MWE3LjI2NSA3LjI2NSAwIDAgMCAxLjgyNS0yLjIyNyA3LjUxNSA3LjUxNSAwIDAgMCAuNzQzLTIuMDY4Yy4xNjEtLjgwMy4yLTEuNjQ0LjA4MS0yLjQ4N2E4LjAxMiA4LjAxMiAwIDAgMC0uNjAxLTIuMTQ3IDcuODA4IDcuODA4IDAgMCAwLTEuNTQ0LTIuMjI3IDcuOTIzIDcuOTIzIDAgMCAwLTIuMjQ4LTEuNTQ1IDcuODM2IDcuODM2IDAgMCAwLTIuOTI5LS42NjEgNy45MDUgNy45MDUgMCAwIDAtMi45NjkuNTIzIDcuNzEgNy43MSAwIDAgMC0yLjMwNyAxLjQ0NCA3LjIwMyA3LjIwMyAwIDAgMC0xLjY0NyAyLjE2NSA3LjY4NCA3LjY4NCAwIDAgMC0uNzIzIDIuMTA3IDcuNDc2IDcuNDc2IDAgMCAwLS4wNiAyLjMwN2MuMS43NDMuMzAxIDEuNDY1LjYwMSAyLjE0NWE3Ljg0OSA3Ljg0OSAwIDAgMCAxLjk4NyAyLjY2OWwtLjEyMS41NDFjLS4wOC40MjEtLjA2LjgyMy0uMDYgMS4yNjN2LjU2M2E5LjQ3MyA5LjQ3MyAwIDAgMS0zLjM1MS0zLjU1MSA4Ljc4MiA4Ljc4MiAwIDAgMS0uOTY0LTIuNjI5IDkuMTA5IDkuMTA5IDAgMCAxLS4xMi0zLjEyOWMuMTItLjk0My4zODEtMS44NjUuNzYzLTIuNzA5LjQ2MS0xLjA0MSAxLjE0My0yLjAwNSAxLjk0NS0yLjgyOGE5LjM2NCA5LjM2NCAwIDAgMSAyLjgyOC0xLjk0NSA5LjgyIDkuODIgMCAwIDEgMy42OTItLjg0MyA5Ljg3MiA5Ljg3MiAwIDAgMSAzLjc1MS42NjMgOS4zOTYgOS4zOTYgMCAwIDEgMi45MjkgMS44MjQgOS44NTYgOS44NTYgMCAwIDEgMi4wODUgMi43MjljLjQyMS44NDMuNzQzIDEuNzQ1LjkwNCAyLjY2OC4xNjEuOTY0LjIgMS45NDUuMDYgMi45MDlhOS4xNTcgOS4xNTcgMCAwIDEtLjc4NCAyLjcyOCA5LjUxIDkuNTEgMCAwIDEtMy43NzEgNC4yMzVsLjE1Mi0uMTQxem0tNS0xMi43NjdhMy41NCAzLjU0IDAgMCAxIDMuNTM5IDMuNTQxIDMuNTQyIDMuNTQyIDAgMCAxLTMuNTM5IDMuNTQ5Yy0xLjk1NiAwLTMuNTQtMS41ODUtMy41NC0zLjUzMXMxLjU4NC0zLjUzMiAzLjU0LTMuNTMydi0uMDI4eiIvPjwvc3ZnPg==)}.castro{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMiIgaGVpZ2h0PSIzMiI+PHBhdGggZmlsbD0iIzAwYjI2NSIgZD0iTTE2IDBDNy4xNjMgMCAwIDcuMTY0IDAgMTZzNy4xNjMgMTYgMTYgMTZjOC44MzYgMCAxNi03LjE2NCAxNi0xNlMyNC44MzYgMCAxNiAwem0tLjAwMyAxOC42NTVhMi43MzcgMi43MzcgMCAwIDEgMC01LjQ3NCAyLjczNyAyLjczNyAwIDAgMSAwIDUuNDc0em02LjY2IDYuNDdsLTIuNjgzLTMuNzIxYTYuNzc5IDYuNzc5IDAgMSAwLTcuOTk1LjAwM2wuMDE5LjAxMy0yLjY4NSAzLjcyNGMtMi44NjktMi4wOS00LjcxMi01LjQzOC00LjcxMi05LjIxNiAwLTYuMjc4IDUuMDktMTEuMzY4IDExLjM2OC0xMS4zNjhoLjAwM2M2LjI3OCAwIDExLjM2OCA1LjA5IDExLjM2OCAxMS4zNjh2LjAxM2MwIDMuNzYzLTEuODMxIDcuMDk3LTQuNjUxIDkuMTYybC0uMDMyLjAyMnoiLz48L3N2Zz4=)}.google{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMiIgaGVpZ2h0PSIzMiI+PHBhdGggZmlsbD0iIzQyODVmNCIgZD0iTTIgMTIuOTA3Yy0xLjEwNyAwLTIgLjg5My0yIDJ2Mi4xNzNhMiAyIDAgMSAwIDQgMHYtMi4xNzNjMC0xLjEwNy0uODkzLTItMi0yem0yOCAwYy0xLjEwNyAwLTIgLjg5My0yIDJ2Mi4xNzNhMiAyIDAgMSAwIDQgMHYtMi4xNzNjMC0xLjEwNy0uODkzLTItMi0yek04LjkwNyAxOS40NTNjLTEuMTA3IDAtMiAuODkzLTIgMnYyLjE3M2EyIDIgMCAxIDAgNCAwdi0yLjE2YzAtMS4xMDctLjg5My0yLTItMnptMC0xMy4wOTNjLTEuMTA3IDAtMiAuODkzLTIgMnY3LjE0N2EyIDIgMCAxIDAgNCAwdi03LjE2YzAtMS4xMDctLjg5My0yLTItMnptMTQuMTg2IDBjLTEuMTA3IDAtMiAuODkzLTIgMnYyLjE4N2EyIDIgMCAxIDAgNCAwVjguMzZjMC0xLjEwNy0uODkzLTItMi0yek0xNiAwYy0xLjEwNyAwLTIgLjg5My0yIDJ2Mi4xNzNhMiAyIDAgMSAwIDQgMFYyYzAtMS4xMDctLjg5My0yLTItMnptMCAyNS44MTNjLTEuMTA3IDAtMiAuODkzLTIgMnYyLjE5NGEyIDIgMCAwIDAgNCAuMDA3di0yLjE4N2MwLTEuMDkzLS44OTMtMi0yLTJ6bTcuMDkzLTExLjI4Yy0xLjEwNyAwLTIgLjkwNy0yIDJ2Ny4xMDdhMiAyIDAgMSAwIDQgMHYtNy4xMDdjMC0xLjEwNy0uODkzLTItMi0yek0xNiA4LjE3M2MtMS4xMDcgMC0yIC45MDctMiAydjExLjY0YTIgMiAwIDEgMCA0IDBWMTAuMTg2YzAtMS4xMDctLjg5My0yLTItMnoiLz48L3N2Zz4=)}.spotify{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMiIgaGVpZ2h0PSIzMiI+PHBhdGggZmlsbD0iIzFlZDc2MCIgZD0iTTE2IDBDNy4yIDAgMCA3LjIgMCAxNnM3LjIgMTYgMTYgMTYgMTYtNy4yIDE2LTE2UzI0Ljg4IDAgMTYgMHptNy4zNjEgMjMuMTJjLS4zMi40NzktLjg4LjY0LTEuMzYxLjMyLTMuNzYtMi4zMi04LjQ4LTIuODAxLTE0LjA4MS0xLjUyMS0uNTU3LjE2My0xLjAzOS0uMjM5LTEuMTk5LS43MTktLjE2LS41NjEuMjQtMS4wNC43Mi0xLjIgNi4wOC0xLjM2MSAxMS4zNi0uOCAxNS41MiAxLjc2LjU2LjI0LjYzOS44NzkuNDAxIDEuMzZ6bTEuOTItNC40Yy0uNDAxLjU2LTEuMTIxLjgtMS42ODMuNC00LjMxOS0yLjY0LTEwLjg3OS0zLjQ0LTE1LjkxOS0xLjg0LS42MzkuMTYtMS4zNi0uMTYtMS41Mi0uOHMuMTYtMS4zNjEuOC0xLjUyMWM1Ljg0LTEuNzU5IDEzLjA0LS44NzcgMTggMi4xNjEuNDgxLjI0MS43MiAxLjA0LjMyMSAxLjZ6bS4xNi00LjQ4QzIwLjMyIDExLjIgMTEuNzYgMTAuODggNi44OCAxMi40MDFjLS44LjIzOS0xLjYtLjI0MS0xLjg0LS45NjEtLjI0LS44MDEuMjQtMS42Ljk2LTEuODQxIDUuNjgtMS42OCAxNS4wNC0xLjM2IDIwLjk2MSAyLjE2MS43MTkuNC45NTkgMS4zNi41NTkgMi4wOC0uMzk5LjU2MS0xLjM2Ljc5OS0yLjA3OS40eiIvPjwvc3ZnPg==)}.overcast{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMiIgaGVpZ2h0PSIzMiI+PHBhdGggZmlsbD0iI2ZjN2UwZiIgZD0iTTE2IDMyQzcuMTg1IDMyLjAyNC4wMjMgMjQuODk1IDAgMTYuMDgxVjE2QzAgNy4xMzMgNy4xMzUgMCAxNiAwczE2IDcuMTMzIDE2IDE2YzAgOC44NjUtNy4xMzUgMTYtMTYgMTZ6bTAtNi4zMzVsMS4yLTEuMTk5LTEuMi00LjYtMS4yIDQuNiAxLjIgMS4xOTl6bS0xLjUzMy0uMDY2bC0uNiAyLjI2OCAxLjQtMS40MDMtLjgtLjg2NXptMy4wNjYgMGwtLjguODAxIDEuNCAxLjQwMS0uNi0yLjIwM3ptMS4xMzQgNC4xMzZMMTYgMjcuMDY3bC0yLjY2NyAyLjY2OEMxNC4yIDI5Ljg2OCAxNS4wNjYgMzAgMTYgMzBzMS44LS4wNjcgMi42NjctLjI2NXpNMTYgMkM4LjI2OCAyIDIgOC4yNjggMiAxNmExMy45MyAxMy45MyAwIDAgMCA5LjQwMSAxMy4xOTlsMy0xMS4xMzNhMi41OTcgMi41OTcgMCAwIDEtMS4wNjgtMi4xMzNjMC0xLjQ2OCAxLjItMi42NjggMi42NjctMi42NjhzMi42NjcgMS4yIDIuNjY3IDIuNjY4YzAgLjg2NS0uNDAxIDEuNi0xLjA2OCAyLjEzM2wzIDExLjEzM0ExMy45MjcgMTMuOTI3IDAgMCAwIDMwIDE2YzAtNy43MzItNi4yNjgtMTQtMTQtMTR6bTkuMTMzIDIwLjkzM2MtLjM0LjQyNS0uOTUyLjUxMy0xLjM5OS4yYS45MDguOTA4IDAgMCAxLS4yLTEuMzM1czEuOC0yLjM5OSAxLjgtNS44LTEuOC01LjgtMS44LTUuOGEuOTA3LjkwNyAwIDAgMSAuMTIxLTEuMjc2Yy4wMjctLjAyMS4wNTItLjA0MS4wOC0uMDU5YTEuMDMzIDEuMDMzIDAgMCAxIDEuMzk5LjJjLjEzMy4xMzUgMi4yIDIuODY3IDIuMiA2LjkzM3MtMi4wNjkgNi44MDMtMi4yMDEgNi45MzZ6bS00Ljg2OC0yLjZjLS40LS40LS4zMzItMS4xMzMuMDY4LTEuNTMzIDAgMCAxLTEuMDY1IDEtMi44cy0xLTIuNzM1LTEtMi44Yy0uNC0uNDAxLS40LTEuMDY4LS4wNjgtMS41MzNhLjkyMS45MjEgMCAwIDEgMS40MDEtLjA2OGMuMDY4LjA2OCAxLjY2NyAxLjczNSAxLjY2NyA0LjQwMXMtMS41OTkgNC4zMzMtMS42NjcgNC40MDFjLS40MDEuMzk5LTEgLjMzMy0xLjQwMS0uMDY4em0tOC41MyAwYy0uNDAxLjQwMS0xIC40NjctMS40MDEuMDY4LS4wNjgtLjEzNi0xLjY2Ny0xLjczNS0xLjY2Ny00LjQwMXMxLjU5OS00LjI2NSAxLjY2Ny00LjQwMWMuNDAxLS4zOTkgMS4wNjgtLjM5OSAxLjQwMS4wNjguNC40LjMzMiAxLjEzMy0uMDY4IDEuNTMzIDAgLjA2NS0xIDEuMDY1LTEgMi44czEgMi44IDEgMi44Yy40LjQuNDY4IDEuMDY1LjA2OCAxLjUzM3ptLTMuNDcgMi44MDJhMS4wMzUgMS4wMzUgMCAwIDEtMS40LS4yQzYuNzM0IDIyLjggNC42NjYgMjAuMDY3IDQuNjY2IDE2czIuMDY4LTYuOCAyLjE5OS02LjkzM2ExLjAzMiAxLjAzMiAwIDAgMSAxLjQtLjIuOTA4LjkwOCAwIDAgMSAuMjU5IDEuMjU1Yy0uMDE3LjAyNy0uMDM3LjA1My0uMDU3LjA3OSAwIDAtMS44IDIuMzk5LTEuOCA1LjhzMS44IDUuOCAxLjggNS44Yy4zMzMuNC4yIDEtLjIwMSAxLjMzNXoiLz48L3N2Zz4=)}.links a.podcast:hover{color:#93c}.links a.castro:hover{color:#00b265}.links a.google:hover{color:#4285f4}.links a.spotify:hover{color:#1ed760}.links a.overcast:hover{color:#fc7e0f}.item{border-top:1px solid rgba(0,0,0,.04);padding:20px;margin:20px auto}.item_meta{font-size:14px;color:#9ea0a6}.item a{color:rgba(0,0,0,.98);text-decoration:none}.item>h2{margin:0}.item>h3{margin:6px 0 10px;font-size:18px;font-weight:300;color:#9ea0a6}.item>audio{display:block;width:100%;margin-top:20px}.footer{border-top:1px solid rgba(0,0,0,.04);padding:10px 20px}.footer .title{text-decoration:none;text-transform:uppercase;font-size:16px;font-weight:900;color:rgba(0,0,0,.2);letter-spacing:.02em;margin-right:1em}.footer nav{display:inline-block}.footer nav>a{text-decoration:none;color:rgba(0,0,0,.6);-webkit-transition:color .2s ease;transition:color .2s ease;font-size:.92em}.footer nav>a+a:before{content:" / ";font-size:10px;color:rgba(0,0,0,.1)}</style> + </head> + <body> + <div class="top inner"> + <p><strong>This is a web feed,</strong> also known as an RSS feed. <strong>Subscribe</strong> by copying the URL from the address bar into your newsreader. Visit <a href="https://aboutfeeds.com">About Feeds</a> to get started with newsreaders and subscribing. It's free.</p> + <p><strong>这是一个网络订阅,</strong>也称为 RSS 订阅。将地址栏中的 URL 复制到新闻阅读器中即可<strong>订阅</strong>。访问<a href="https://aboutfeeds.com">关于订阅</a>以开始使用新闻阅读器和订阅。并且是免费的。</p> + </div> + <div class="head inner"> + <a class="head_logo"> + <xsl:attribute name="href"> + <xsl:value-of select="/rss/channel/link"/> + </xsl:attribute> + <img> + <xsl:attribute name="src">/logo.svg</xsl:attribute> + <xsl:attribute name="title"> + <xsl:value-of select="/rss/channel/title"/> + </xsl:attribute> + </img> + </a> + <div class="head_main"> + <h1><xsl:value-of select="/rss/channel/title"/></h1> + <p><xsl:value-of select="/rss/channel/description"/></p> + <a class="head_link" target="_blank"> + <xsl:attribute name="href"> + <xsl:value-of select="/rss/channel/link"/> + </xsl:attribute> + 访问网站 → + </a> + </div> + </div> + <xsl:for-each select="/rss/channel/item"> + <div class="item inner"> + <div class="item_meta"> + <span><xsl:value-of select="pubDate" /></span> + </div> + <h2> + <a target="_blank"> + <xsl:attribute name="href"> + <xsl:value-of select="link"/> + </xsl:attribute> + <xsl:value-of select="title"/> + </a> + </h2> + </div> + </xsl:for-each> + <div class="footer"> + <a class="title" href="https://yufan.me" target="_blank">且听书吟</a> + <nav> + <a href="https://yufan.me/about">关于</a> + <a href="https://yufan.me/links">友链</a> + <a href="https://yufan.me/cats/article">文章</a> + <a href="https://yufan.me/cats/think">杂思</a> + </nav> + </div> + </body> + </html> + </xsl:template> +</xsl:stylesheet> diff --git a/public/icon-192.png b/public/icon-192.png new file mode 100644 index 0000000..a8a2446 Binary files /dev/null and b/public/icon-192.png differ diff --git a/public/icon-512.png b/public/icon-512.png new file mode 100644 index 0000000..8e0d255 Binary files /dev/null and b/public/icon-512.png differ diff --git a/public/images/2011/04/2011041420484000.jpg b/public/images/2011/04/2011041420484000.jpg new file mode 100644 index 0000000..6c0c831 Binary files /dev/null and b/public/images/2011/04/2011041420484000.jpg differ diff --git a/public/images/2011/04/2011041520510800.jpg b/public/images/2011/04/2011041520510800.jpg new file mode 100644 index 0000000..4408c64 Binary files /dev/null and b/public/images/2011/04/2011041520510800.jpg differ diff --git a/public/images/2011/04/2011041520580200.jpg b/public/images/2011/04/2011041520580200.jpg new file mode 100644 index 0000000..08923fa Binary files /dev/null and b/public/images/2011/04/2011041520580200.jpg differ diff --git a/public/images/2011/04/2011041522562500.jpg b/public/images/2011/04/2011041522562500.jpg new file mode 100644 index 0000000..70adca5 Binary files /dev/null and b/public/images/2011/04/2011041522562500.jpg differ diff --git a/public/images/2011/04/2011042321083500.jpg b/public/images/2011/04/2011042321083500.jpg new file mode 100644 index 0000000..d6d440c Binary files /dev/null and b/public/images/2011/04/2011042321083500.jpg differ diff --git a/public/images/2011/04/2011042321142000.jpg b/public/images/2011/04/2011042321142000.jpg new file mode 100644 index 0000000..4cad2de Binary files /dev/null and b/public/images/2011/04/2011042321142000.jpg differ diff --git a/public/images/2011/04/2011042321143500.jpg b/public/images/2011/04/2011042321143500.jpg new file mode 100644 index 0000000..c82c01d Binary files /dev/null and b/public/images/2011/04/2011042321143500.jpg differ diff --git a/public/images/2011/04/2011042321155000.jpg b/public/images/2011/04/2011042321155000.jpg new file mode 100644 index 0000000..0d4e6ab Binary files /dev/null and b/public/images/2011/04/2011042321155000.jpg differ diff --git a/public/images/2011/04/2011042511393900.jpg b/public/images/2011/04/2011042511393900.jpg new file mode 100644 index 0000000..5e47103 Binary files /dev/null and b/public/images/2011/04/2011042511393900.jpg differ diff --git a/public/images/2011/04/2011042521290100.jpg b/public/images/2011/04/2011042521290100.jpg new file mode 100644 index 0000000..edbc167 Binary files /dev/null and b/public/images/2011/04/2011042521290100.jpg differ diff --git a/public/images/2011/04/2011042521292600.jpg b/public/images/2011/04/2011042521292600.jpg new file mode 100644 index 0000000..ed1a674 Binary files /dev/null and b/public/images/2011/04/2011042521292600.jpg differ diff --git a/public/images/2011/04/2011042521293200.jpg b/public/images/2011/04/2011042521293200.jpg new file mode 100644 index 0000000..b0331c5 Binary files /dev/null and b/public/images/2011/04/2011042521293200.jpg differ diff --git a/public/images/2011/04/2011042521302200.jpg b/public/images/2011/04/2011042521302200.jpg new file mode 100644 index 0000000..8f76be4 Binary files /dev/null and b/public/images/2011/04/2011042521302200.jpg differ diff --git a/public/images/2011/04/2011042521302700.jpg b/public/images/2011/04/2011042521302700.jpg new file mode 100644 index 0000000..a75d52a Binary files /dev/null and b/public/images/2011/04/2011042521302700.jpg differ diff --git a/public/images/2011/04/2011042521351900.jpg b/public/images/2011/04/2011042521351900.jpg new file mode 100644 index 0000000..5611dd6 Binary files /dev/null and b/public/images/2011/04/2011042521351900.jpg differ diff --git a/public/images/2011/04/2011042521393900.jpg b/public/images/2011/04/2011042521393900.jpg new file mode 100644 index 0000000..1eb1b5a Binary files /dev/null and b/public/images/2011/04/2011042521393900.jpg differ diff --git a/public/images/2011/05/2011051421445100.jpg b/public/images/2011/05/2011051421445100.jpg new file mode 100644 index 0000000..00ecdf0 Binary files /dev/null and b/public/images/2011/05/2011051421445100.jpg differ diff --git a/public/images/2011/05/2011051421472100.jpg b/public/images/2011/05/2011051421472100.jpg new file mode 100644 index 0000000..5b2a268 Binary files /dev/null and b/public/images/2011/05/2011051421472100.jpg differ diff --git a/public/images/2011/05/2011051521491300.jpg b/public/images/2011/05/2011051521491300.jpg new file mode 100644 index 0000000..b78e12f Binary files /dev/null and b/public/images/2011/05/2011051521491300.jpg differ diff --git a/public/images/2011/05/2011052622280900.jpg b/public/images/2011/05/2011052622280900.jpg new file mode 100644 index 0000000..e1575ed Binary files /dev/null and b/public/images/2011/05/2011052622280900.jpg differ diff --git a/public/images/2011/05/2011052622281600.jpg b/public/images/2011/05/2011052622281600.jpg new file mode 100644 index 0000000..ca9b6e2 Binary files /dev/null and b/public/images/2011/05/2011052622281600.jpg differ diff --git a/public/images/2011/05/2011052622282200.jpg b/public/images/2011/05/2011052622282200.jpg new file mode 100644 index 0000000..d95762d Binary files /dev/null and b/public/images/2011/05/2011052622282200.jpg differ diff --git a/public/images/2011/05/2011052622285100.jpg b/public/images/2011/05/2011052622285100.jpg new file mode 100644 index 0000000..016896c Binary files /dev/null and b/public/images/2011/05/2011052622285100.jpg differ diff --git a/public/images/2011/06/2011061816481300.jpg b/public/images/2011/06/2011061816481300.jpg new file mode 100644 index 0000000..1d2ab32 Binary files /dev/null and b/public/images/2011/06/2011061816481300.jpg differ diff --git a/public/images/2011/06/2011061816505900.jpg b/public/images/2011/06/2011061816505900.jpg new file mode 100644 index 0000000..6c950fc Binary files /dev/null and b/public/images/2011/06/2011061816505900.jpg differ diff --git a/public/images/2011/06/2011062418273300.jpg b/public/images/2011/06/2011062418273300.jpg new file mode 100644 index 0000000..d35db04 Binary files /dev/null and b/public/images/2011/06/2011062418273300.jpg differ diff --git a/public/images/2011/06/2011062418362900.jpg b/public/images/2011/06/2011062418362900.jpg new file mode 100644 index 0000000..49397b9 Binary files /dev/null and b/public/images/2011/06/2011062418362900.jpg differ diff --git a/public/images/2011/06/2011062418383500.jpg b/public/images/2011/06/2011062418383500.jpg new file mode 100644 index 0000000..eb8b4eb Binary files /dev/null and b/public/images/2011/06/2011062418383500.jpg differ diff --git a/public/images/2011/06/2011062418552500.jpg b/public/images/2011/06/2011062418552500.jpg new file mode 100644 index 0000000..3224df9 Binary files /dev/null and b/public/images/2011/06/2011062418552500.jpg differ diff --git a/public/images/2011/07/2011070220190200.jpg b/public/images/2011/07/2011070220190200.jpg new file mode 100644 index 0000000..35816f6 Binary files /dev/null and b/public/images/2011/07/2011070220190200.jpg differ diff --git a/public/images/2011/07/2011070220314300.jpg b/public/images/2011/07/2011070220314300.jpg new file mode 100644 index 0000000..01186d4 Binary files /dev/null and b/public/images/2011/07/2011070220314300.jpg differ diff --git a/public/images/2011/07/2011070220315100.jpg b/public/images/2011/07/2011070220315100.jpg new file mode 100644 index 0000000..bef58f6 Binary files /dev/null and b/public/images/2011/07/2011070220315100.jpg differ diff --git a/public/images/2011/07/2011070220315800.jpg b/public/images/2011/07/2011070220315800.jpg new file mode 100644 index 0000000..96710a1 Binary files /dev/null and b/public/images/2011/07/2011070220315800.jpg differ diff --git a/public/images/2011/07/2011070220320500.jpg b/public/images/2011/07/2011070220320500.jpg new file mode 100644 index 0000000..edb45e4 Binary files /dev/null and b/public/images/2011/07/2011070220320500.jpg differ diff --git a/public/images/2011/07/2011070220322300.jpg b/public/images/2011/07/2011070220322300.jpg new file mode 100644 index 0000000..80574a0 Binary files /dev/null and b/public/images/2011/07/2011070220322300.jpg differ diff --git a/public/images/2011/07/2011070220323300.jpg b/public/images/2011/07/2011070220323300.jpg new file mode 100644 index 0000000..f0c54d7 Binary files /dev/null and b/public/images/2011/07/2011070220323300.jpg differ diff --git a/public/images/2011/07/2011070220324000.jpg b/public/images/2011/07/2011070220324000.jpg new file mode 100644 index 0000000..a74a525 Binary files /dev/null and b/public/images/2011/07/2011070220324000.jpg differ diff --git a/public/images/2011/07/2011070220324800.jpg b/public/images/2011/07/2011070220324800.jpg new file mode 100644 index 0000000..3ed90b7 Binary files /dev/null and b/public/images/2011/07/2011070220324800.jpg differ diff --git a/public/images/2011/07/2011070220325600.jpg b/public/images/2011/07/2011070220325600.jpg new file mode 100644 index 0000000..9db9064 Binary files /dev/null and b/public/images/2011/07/2011070220325600.jpg differ diff --git a/public/images/2011/07/2011070220330400.jpg b/public/images/2011/07/2011070220330400.jpg new file mode 100644 index 0000000..7f87aee Binary files /dev/null and b/public/images/2011/07/2011070220330400.jpg differ diff --git a/public/images/2011/07/2011070220331000.jpg b/public/images/2011/07/2011070220331000.jpg new file mode 100644 index 0000000..a23dacd Binary files /dev/null and b/public/images/2011/07/2011070220331000.jpg differ diff --git a/public/images/2011/07/2011070220331700.jpg b/public/images/2011/07/2011070220331700.jpg new file mode 100644 index 0000000..99a148f Binary files /dev/null and b/public/images/2011/07/2011070220331700.jpg differ diff --git a/public/images/2011/07/2011070220332300.jpg b/public/images/2011/07/2011070220332300.jpg new file mode 100644 index 0000000..6dc9642 Binary files /dev/null and b/public/images/2011/07/2011070220332300.jpg differ diff --git a/public/images/2011/07/2011070220332900.jpg b/public/images/2011/07/2011070220332900.jpg new file mode 100644 index 0000000..c84a3fc Binary files /dev/null and b/public/images/2011/07/2011070220332900.jpg differ diff --git a/public/images/2011/07/2011070220544000.jpg b/public/images/2011/07/2011070220544000.jpg new file mode 100644 index 0000000..bc77b04 Binary files /dev/null and b/public/images/2011/07/2011070220544000.jpg differ diff --git a/public/images/2011/07/2011070220550500.jpg b/public/images/2011/07/2011070220550500.jpg new file mode 100644 index 0000000..a9f742d Binary files /dev/null and b/public/images/2011/07/2011070220550500.jpg differ diff --git a/public/images/2011/07/2011070220552500.jpg b/public/images/2011/07/2011070220552500.jpg new file mode 100644 index 0000000..a0c65c9 Binary files /dev/null and b/public/images/2011/07/2011070220552500.jpg differ diff --git a/public/images/2011/07/2011070220554100.jpg b/public/images/2011/07/2011070220554100.jpg new file mode 100644 index 0000000..3cada17 Binary files /dev/null and b/public/images/2011/07/2011070220554100.jpg differ diff --git a/public/images/2011/07/2011070220560200.jpg b/public/images/2011/07/2011070220560200.jpg new file mode 100644 index 0000000..b95497b Binary files /dev/null and b/public/images/2011/07/2011070220560200.jpg differ diff --git a/public/images/2012/01/2012011519234100.jpg b/public/images/2012/01/2012011519234100.jpg new file mode 100644 index 0000000..8b50c52 Binary files /dev/null and b/public/images/2012/01/2012011519234100.jpg differ diff --git a/public/images/2012/01/2012011819285800.jpg b/public/images/2012/01/2012011819285800.jpg new file mode 100644 index 0000000..ff6a819 Binary files /dev/null and b/public/images/2012/01/2012011819285800.jpg differ diff --git a/public/images/2012/01/2012011819343900.jpg b/public/images/2012/01/2012011819343900.jpg new file mode 100644 index 0000000..7164c99 Binary files /dev/null and b/public/images/2012/01/2012011819343900.jpg differ diff --git a/public/images/2012/02/2012020222465000.jpg b/public/images/2012/02/2012020222465000.jpg new file mode 100644 index 0000000..4b399d1 Binary files /dev/null and b/public/images/2012/02/2012020222465000.jpg differ diff --git a/public/images/2012/02/2012020521241800.jpg b/public/images/2012/02/2012020521241800.jpg new file mode 100644 index 0000000..29c0d2d Binary files /dev/null and b/public/images/2012/02/2012020521241800.jpg differ diff --git a/public/images/2012/02/2012020521304400.jpg b/public/images/2012/02/2012020521304400.jpg new file mode 100644 index 0000000..b757890 Binary files /dev/null and b/public/images/2012/02/2012020521304400.jpg differ diff --git a/public/images/2012/02/2012020521334700.jpg b/public/images/2012/02/2012020521334700.jpg new file mode 100644 index 0000000..4506b77 Binary files /dev/null and b/public/images/2012/02/2012020521334700.jpg differ diff --git a/public/images/2012/02/2012020821400300.jpg b/public/images/2012/02/2012020821400300.jpg new file mode 100644 index 0000000..2030cd4 Binary files /dev/null and b/public/images/2012/02/2012020821400300.jpg differ diff --git a/public/images/2012/02/2012020821442400.jpg b/public/images/2012/02/2012020821442400.jpg new file mode 100644 index 0000000..68c17f6 Binary files /dev/null and b/public/images/2012/02/2012020821442400.jpg differ diff --git a/public/images/2012/02/2012020821481600.jpg b/public/images/2012/02/2012020821481600.jpg new file mode 100644 index 0000000..bacce16 Binary files /dev/null and b/public/images/2012/02/2012020821481600.jpg differ diff --git a/public/images/2012/02/2012020922491700.jpg b/public/images/2012/02/2012020922491700.jpg new file mode 100644 index 0000000..7ffaa6f Binary files /dev/null and b/public/images/2012/02/2012020922491700.jpg differ diff --git a/public/images/2012/02/2012021222511100.jpg b/public/images/2012/02/2012021222511100.jpg new file mode 100644 index 0000000..79c7765 Binary files /dev/null and b/public/images/2012/02/2012021222511100.jpg differ diff --git a/public/images/2012/02/2012021422120000.jpg b/public/images/2012/02/2012021422120000.jpg new file mode 100644 index 0000000..8fc9c73 Binary files /dev/null and b/public/images/2012/02/2012021422120000.jpg differ diff --git a/public/images/2012/02/2012021422134400.jpg b/public/images/2012/02/2012021422134400.jpg new file mode 100644 index 0000000..32847ab Binary files /dev/null and b/public/images/2012/02/2012021422134400.jpg differ diff --git a/public/images/2012/02/2012021422134700.jpg b/public/images/2012/02/2012021422134700.jpg new file mode 100644 index 0000000..217f071 Binary files /dev/null and b/public/images/2012/02/2012021422134700.jpg differ diff --git a/public/images/2012/02/2012021423061000.jpg b/public/images/2012/02/2012021423061000.jpg new file mode 100644 index 0000000..3fe3c44 Binary files /dev/null and b/public/images/2012/02/2012021423061000.jpg differ diff --git a/public/images/2012/02/2012021521553500.jpg b/public/images/2012/02/2012021521553500.jpg new file mode 100644 index 0000000..a43b852 Binary files /dev/null and b/public/images/2012/02/2012021521553500.jpg differ diff --git a/public/images/2012/02/2012021522061800.jpg b/public/images/2012/02/2012021522061800.jpg new file mode 100644 index 0000000..2c3bd8f Binary files /dev/null and b/public/images/2012/02/2012021522061800.jpg differ diff --git a/public/images/2012/02/2012021822255600.jpg b/public/images/2012/02/2012021822255600.jpg new file mode 100644 index 0000000..1a734ae Binary files /dev/null and b/public/images/2012/02/2012021822255600.jpg differ diff --git a/public/images/2012/02/2012021822273700.jpg b/public/images/2012/02/2012021822273700.jpg new file mode 100644 index 0000000..58af0cc Binary files /dev/null and b/public/images/2012/02/2012021822273700.jpg differ diff --git a/public/images/2012/02/2012021822292100.jpg b/public/images/2012/02/2012021822292100.jpg new file mode 100644 index 0000000..e5ffacd Binary files /dev/null and b/public/images/2012/02/2012021822292100.jpg differ diff --git a/public/images/2012/02/2012022022154700.jpg b/public/images/2012/02/2012022022154700.jpg new file mode 100644 index 0000000..6e3e7d9 Binary files /dev/null and b/public/images/2012/02/2012022022154700.jpg differ diff --git a/public/images/2012/02/2012022122162200.jpg b/public/images/2012/02/2012022122162200.jpg new file mode 100644 index 0000000..725513c Binary files /dev/null and b/public/images/2012/02/2012022122162200.jpg differ diff --git a/public/images/2012/02/2012022122173300.jpg b/public/images/2012/02/2012022122173300.jpg new file mode 100644 index 0000000..8dc381d Binary files /dev/null and b/public/images/2012/02/2012022122173300.jpg differ diff --git a/public/images/2012/03/2012030819164800.jpg b/public/images/2012/03/2012030819164800.jpg new file mode 100644 index 0000000..1072113 Binary files /dev/null and b/public/images/2012/03/2012030819164800.jpg differ diff --git a/public/images/2012/03/2012031120464600.jpg b/public/images/2012/03/2012031120464600.jpg new file mode 100644 index 0000000..a44ca45 Binary files /dev/null and b/public/images/2012/03/2012031120464600.jpg differ diff --git a/public/images/2012/03/2012032502314500.jpg b/public/images/2012/03/2012032502314500.jpg new file mode 100644 index 0000000..183c306 Binary files /dev/null and b/public/images/2012/03/2012032502314500.jpg differ diff --git a/public/images/2012/03/2012032522505100.jpg b/public/images/2012/03/2012032522505100.jpg new file mode 100644 index 0000000..edbfd5c Binary files /dev/null and b/public/images/2012/03/2012032522505100.jpg differ diff --git a/public/images/2012/03/2012032522524300.jpg b/public/images/2012/03/2012032522524300.jpg new file mode 100644 index 0000000..0187a8f Binary files /dev/null and b/public/images/2012/03/2012032522524300.jpg differ diff --git a/public/images/2012/03/2012032522551000.jpg b/public/images/2012/03/2012032522551000.jpg new file mode 100644 index 0000000..44ad8b8 Binary files /dev/null and b/public/images/2012/03/2012032522551000.jpg differ diff --git a/public/images/2012/04/2012040101152600.jpg b/public/images/2012/04/2012040101152600.jpg new file mode 100644 index 0000000..95c9f02 Binary files /dev/null and b/public/images/2012/04/2012040101152600.jpg differ diff --git a/public/images/2012/04/2012040201181900.jpg b/public/images/2012/04/2012040201181900.jpg new file mode 100644 index 0000000..76c44c0 Binary files /dev/null and b/public/images/2012/04/2012040201181900.jpg differ diff --git a/public/images/2012/04/2012040801480400.jpg b/public/images/2012/04/2012040801480400.jpg new file mode 100644 index 0000000..9a7ede8 Binary files /dev/null and b/public/images/2012/04/2012040801480400.jpg differ diff --git a/public/images/2012/04/2012040801491700.jpg b/public/images/2012/04/2012040801491700.jpg new file mode 100644 index 0000000..28b6fb9 Binary files /dev/null and b/public/images/2012/04/2012040801491700.jpg differ diff --git a/public/images/2012/04/2012040801511700.jpg b/public/images/2012/04/2012040801511700.jpg new file mode 100644 index 0000000..6970e02 Binary files /dev/null and b/public/images/2012/04/2012040801511700.jpg differ diff --git a/public/images/2012/04/2012040801560900.jpg b/public/images/2012/04/2012040801560900.jpg new file mode 100644 index 0000000..c04f3ab Binary files /dev/null and b/public/images/2012/04/2012040801560900.jpg differ diff --git a/public/images/2012/04/2012040802192000.jpg b/public/images/2012/04/2012040802192000.jpg new file mode 100644 index 0000000..7480e3d Binary files /dev/null and b/public/images/2012/04/2012040802192000.jpg differ diff --git a/public/images/2012/04/2012040802235300.jpg b/public/images/2012/04/2012040802235300.jpg new file mode 100644 index 0000000..c226696 Binary files /dev/null and b/public/images/2012/04/2012040802235300.jpg differ diff --git a/public/images/2012/04/2012040802264300.jpg b/public/images/2012/04/2012040802264300.jpg new file mode 100644 index 0000000..931db41 Binary files /dev/null and b/public/images/2012/04/2012040802264300.jpg differ diff --git a/public/images/2012/04/2012041301591600.jpg b/public/images/2012/04/2012041301591600.jpg new file mode 100644 index 0000000..37d8bff Binary files /dev/null and b/public/images/2012/04/2012041301591600.jpg differ diff --git a/public/images/2012/04/2012041302022500.jpg b/public/images/2012/04/2012041302022500.jpg new file mode 100644 index 0000000..e77c912 Binary files /dev/null and b/public/images/2012/04/2012041302022500.jpg differ diff --git a/public/images/2012/04/2012041302080500.jpg b/public/images/2012/04/2012041302080500.jpg new file mode 100644 index 0000000..399b318 Binary files /dev/null and b/public/images/2012/04/2012041302080500.jpg differ diff --git a/public/images/2012/04/2012042002132500.jpg b/public/images/2012/04/2012042002132500.jpg new file mode 100644 index 0000000..649025a Binary files /dev/null and b/public/images/2012/04/2012042002132500.jpg differ diff --git a/public/images/2012/04/2012042002155800.jpg b/public/images/2012/04/2012042002155800.jpg new file mode 100644 index 0000000..f2d2947 Binary files /dev/null and b/public/images/2012/04/2012042002155800.jpg differ diff --git a/public/images/2012/04/2012042002155900.jpg b/public/images/2012/04/2012042002155900.jpg new file mode 100644 index 0000000..100920f Binary files /dev/null and b/public/images/2012/04/2012042002155900.jpg differ diff --git a/public/images/2012/04/2012042820485500.jpg b/public/images/2012/04/2012042820485500.jpg new file mode 100644 index 0000000..5896be0 Binary files /dev/null and b/public/images/2012/04/2012042820485500.jpg differ diff --git a/public/images/2012/04/2012042820514100.jpg b/public/images/2012/04/2012042820514100.jpg new file mode 100644 index 0000000..f4d6d87 Binary files /dev/null and b/public/images/2012/04/2012042820514100.jpg differ diff --git a/public/images/2012/04/2012042820532500.jpg b/public/images/2012/04/2012042820532500.jpg new file mode 100644 index 0000000..246c8cb Binary files /dev/null and b/public/images/2012/04/2012042820532500.jpg differ diff --git a/public/images/2012/05/2012050221032900.jpg b/public/images/2012/05/2012050221032900.jpg new file mode 100644 index 0000000..e63de2f Binary files /dev/null and b/public/images/2012/05/2012050221032900.jpg differ diff --git a/public/images/2012/05/2012050320564300.jpg b/public/images/2012/05/2012050320564300.jpg new file mode 100644 index 0000000..8acab06 Binary files /dev/null and b/public/images/2012/05/2012050320564300.jpg differ diff --git a/public/images/2012/05/2012050320583300.jpg b/public/images/2012/05/2012050320583300.jpg new file mode 100644 index 0000000..9045b02 Binary files /dev/null and b/public/images/2012/05/2012050320583300.jpg differ diff --git a/public/images/2012/05/2012050321012100.jpg b/public/images/2012/05/2012050321012100.jpg new file mode 100644 index 0000000..5e627c5 Binary files /dev/null and b/public/images/2012/05/2012050321012100.jpg differ diff --git a/public/images/2012/05/2012050521085500.jpg b/public/images/2012/05/2012050521085500.jpg new file mode 100644 index 0000000..13620e8 Binary files /dev/null and b/public/images/2012/05/2012050521085500.jpg differ diff --git a/public/images/2012/05/2012050521120700.jpg b/public/images/2012/05/2012050521120700.jpg new file mode 100644 index 0000000..018cb5c Binary files /dev/null and b/public/images/2012/05/2012050521120700.jpg differ diff --git a/public/images/2012/05/2012050521172300.jpg b/public/images/2012/05/2012050521172300.jpg new file mode 100644 index 0000000..38e02a4 Binary files /dev/null and b/public/images/2012/05/2012050521172300.jpg differ diff --git a/public/images/2012/05/2012051121064800.jpg b/public/images/2012/05/2012051121064800.jpg new file mode 100644 index 0000000..22baa5f Binary files /dev/null and b/public/images/2012/05/2012051121064800.jpg differ diff --git a/public/images/2012/05/2012051121114900.jpg b/public/images/2012/05/2012051121114900.jpg new file mode 100644 index 0000000..d7d3b90 Binary files /dev/null and b/public/images/2012/05/2012051121114900.jpg differ diff --git a/public/images/2012/05/2012051121115700.jpg b/public/images/2012/05/2012051121115700.jpg new file mode 100644 index 0000000..34ad355 Binary files /dev/null and b/public/images/2012/05/2012051121115700.jpg differ diff --git a/public/images/2012/05/2012051121120000.jpg b/public/images/2012/05/2012051121120000.jpg new file mode 100644 index 0000000..2491e62 Binary files /dev/null and b/public/images/2012/05/2012051121120000.jpg differ diff --git a/public/images/2012/05/2012051221344000.jpg b/public/images/2012/05/2012051221344000.jpg new file mode 100644 index 0000000..62bac1c Binary files /dev/null and b/public/images/2012/05/2012051221344000.jpg differ diff --git a/public/images/2012/05/2012051221344500.jpg b/public/images/2012/05/2012051221344500.jpg new file mode 100644 index 0000000..012b25f Binary files /dev/null and b/public/images/2012/05/2012051221344500.jpg differ diff --git a/public/images/2012/05/2012051221344700.jpg b/public/images/2012/05/2012051221344700.jpg new file mode 100644 index 0000000..8f69f37 Binary files /dev/null and b/public/images/2012/05/2012051221344700.jpg differ diff --git a/public/images/2012/05/2012051221345000.jpg b/public/images/2012/05/2012051221345000.jpg new file mode 100644 index 0000000..f634a83 Binary files /dev/null and b/public/images/2012/05/2012051221345000.jpg differ diff --git a/public/images/2012/05/2012051221345300.jpg b/public/images/2012/05/2012051221345300.jpg new file mode 100644 index 0000000..169ec15 Binary files /dev/null and b/public/images/2012/05/2012051221345300.jpg differ diff --git a/public/images/2012/05/2012051221345500.jpg b/public/images/2012/05/2012051221345500.jpg new file mode 100644 index 0000000..6b3a967 Binary files /dev/null and b/public/images/2012/05/2012051221345500.jpg differ diff --git a/public/images/2012/05/2012051421440600.jpg b/public/images/2012/05/2012051421440600.jpg new file mode 100644 index 0000000..2839f1d Binary files /dev/null and b/public/images/2012/05/2012051421440600.jpg differ diff --git a/public/images/2012/05/2012051422003500.jpg b/public/images/2012/05/2012051422003500.jpg new file mode 100644 index 0000000..8a0331d Binary files /dev/null and b/public/images/2012/05/2012051422003500.jpg differ diff --git a/public/images/2012/05/2012051422070900.jpg b/public/images/2012/05/2012051422070900.jpg new file mode 100644 index 0000000..979a69e Binary files /dev/null and b/public/images/2012/05/2012051422070900.jpg differ diff --git a/public/images/2012/05/2012051622352100.jpg b/public/images/2012/05/2012051622352100.jpg new file mode 100644 index 0000000..053a1a2 Binary files /dev/null and b/public/images/2012/05/2012051622352100.jpg differ diff --git a/public/images/2012/05/2012051622362800.jpg b/public/images/2012/05/2012051622362800.jpg new file mode 100644 index 0000000..4899c96 Binary files /dev/null and b/public/images/2012/05/2012051622362800.jpg differ diff --git a/public/images/2012/05/2012051622363300.jpg b/public/images/2012/05/2012051622363300.jpg new file mode 100644 index 0000000..cdf6140 Binary files /dev/null and b/public/images/2012/05/2012051622363300.jpg differ diff --git a/public/images/2012/05/2012051622403100.jpg b/public/images/2012/05/2012051622403100.jpg new file mode 100644 index 0000000..f20748f Binary files /dev/null and b/public/images/2012/05/2012051622403100.jpg differ diff --git a/public/images/2012/05/2012051623044800.jpg b/public/images/2012/05/2012051623044800.jpg new file mode 100644 index 0000000..aabefbf Binary files /dev/null and b/public/images/2012/05/2012051623044800.jpg differ diff --git a/public/images/2012/05/2012051822452400.jpg b/public/images/2012/05/2012051822452400.jpg new file mode 100644 index 0000000..d11211d Binary files /dev/null and b/public/images/2012/05/2012051822452400.jpg differ diff --git a/public/images/2012/05/2012051822495900.jpg b/public/images/2012/05/2012051822495900.jpg new file mode 100644 index 0000000..f629679 Binary files /dev/null and b/public/images/2012/05/2012051822495900.jpg differ diff --git a/public/images/2012/05/2012051822565000.jpg b/public/images/2012/05/2012051822565000.jpg new file mode 100644 index 0000000..2a1f390 Binary files /dev/null and b/public/images/2012/05/2012051822565000.jpg differ diff --git a/public/images/2012/05/2012051823010500.jpg b/public/images/2012/05/2012051823010500.jpg new file mode 100644 index 0000000..4aa78c2 Binary files /dev/null and b/public/images/2012/05/2012051823010500.jpg differ diff --git a/public/images/2012/05/2012051823075400.jpg b/public/images/2012/05/2012051823075400.jpg new file mode 100644 index 0000000..3094290 Binary files /dev/null and b/public/images/2012/05/2012051823075400.jpg differ diff --git a/public/images/2012/05/2012051823112900.jpg b/public/images/2012/05/2012051823112900.jpg new file mode 100644 index 0000000..43aa01e Binary files /dev/null and b/public/images/2012/05/2012051823112900.jpg differ diff --git a/public/images/2012/05/2012052618260200.jpg b/public/images/2012/05/2012052618260200.jpg new file mode 100644 index 0000000..cf8c9e6 Binary files /dev/null and b/public/images/2012/05/2012052618260200.jpg differ diff --git a/public/images/2012/05/2012052618260900.jpg b/public/images/2012/05/2012052618260900.jpg new file mode 100644 index 0000000..ec02ce0 Binary files /dev/null and b/public/images/2012/05/2012052618260900.jpg differ diff --git a/public/images/2012/05/2012052618262000.jpg b/public/images/2012/05/2012052618262000.jpg new file mode 100644 index 0000000..9aae9e4 Binary files /dev/null and b/public/images/2012/05/2012052618262000.jpg differ diff --git a/public/images/2012/06/2012060318520600.jpg b/public/images/2012/06/2012060318520600.jpg new file mode 100644 index 0000000..52f8498 Binary files /dev/null and b/public/images/2012/06/2012060318520600.jpg differ diff --git a/public/images/2012/06/2012060318543000.jpg b/public/images/2012/06/2012060318543000.jpg new file mode 100644 index 0000000..8081d6b Binary files /dev/null and b/public/images/2012/06/2012060318543000.jpg differ diff --git a/public/images/2012/06/2012060319082400.jpg b/public/images/2012/06/2012060319082400.jpg new file mode 100644 index 0000000..6364df5 Binary files /dev/null and b/public/images/2012/06/2012060319082400.jpg differ diff --git a/public/images/2012/06/2012060719153400.jpg b/public/images/2012/06/2012060719153400.jpg new file mode 100644 index 0000000..d530039 Binary files /dev/null and b/public/images/2012/06/2012060719153400.jpg differ diff --git a/public/images/2012/06/2012060719184100.jpg b/public/images/2012/06/2012060719184100.jpg new file mode 100644 index 0000000..74fbbd5 Binary files /dev/null and b/public/images/2012/06/2012060719184100.jpg differ diff --git a/public/images/2012/06/2012060719205200.jpg b/public/images/2012/06/2012060719205200.jpg new file mode 100644 index 0000000..1b078cb Binary files /dev/null and b/public/images/2012/06/2012060719205200.jpg differ diff --git a/public/images/2012/06/2012061019245600.jpg b/public/images/2012/06/2012061019245600.jpg new file mode 100644 index 0000000..3b0db8a Binary files /dev/null and b/public/images/2012/06/2012061019245600.jpg differ diff --git a/public/images/2012/06/2012061019294200.jpg b/public/images/2012/06/2012061019294200.jpg new file mode 100644 index 0000000..67082a7 Binary files /dev/null and b/public/images/2012/06/2012061019294200.jpg differ diff --git a/public/images/2012/06/2012061019294700.jpg b/public/images/2012/06/2012061019294700.jpg new file mode 100644 index 0000000..b03fb31 Binary files /dev/null and b/public/images/2012/06/2012061019294700.jpg differ diff --git a/public/images/2012/06/2012061100345100.jpg b/public/images/2012/06/2012061100345100.jpg new file mode 100644 index 0000000..0e0d7c9 Binary files /dev/null and b/public/images/2012/06/2012061100345100.jpg differ diff --git a/public/images/2012/06/2012061119343300.jpg b/public/images/2012/06/2012061119343300.jpg new file mode 100644 index 0000000..9d06068 Binary files /dev/null and b/public/images/2012/06/2012061119343300.jpg differ diff --git a/public/images/2012/06/2012061119414600.jpg b/public/images/2012/06/2012061119414600.jpg new file mode 100644 index 0000000..10678b4 Binary files /dev/null and b/public/images/2012/06/2012061119414600.jpg differ diff --git a/public/images/2012/06/2012061119415100.jpg b/public/images/2012/06/2012061119415100.jpg new file mode 100644 index 0000000..a850b56 Binary files /dev/null and b/public/images/2012/06/2012061119415100.jpg differ diff --git a/public/images/2012/06/2012061119415700.jpg b/public/images/2012/06/2012061119415700.jpg new file mode 100644 index 0000000..66960d0 Binary files /dev/null and b/public/images/2012/06/2012061119415700.jpg differ diff --git a/public/images/2012/06/2012061119420300.jpg b/public/images/2012/06/2012061119420300.jpg new file mode 100644 index 0000000..aa9c38c Binary files /dev/null and b/public/images/2012/06/2012061119420300.jpg differ diff --git a/public/images/2012/06/2012061321240400.jpg b/public/images/2012/06/2012061321240400.jpg new file mode 100644 index 0000000..bba6062 Binary files /dev/null and b/public/images/2012/06/2012061321240400.jpg differ diff --git a/public/images/2012/06/2012061321255600.jpg b/public/images/2012/06/2012061321255600.jpg new file mode 100644 index 0000000..c1782da Binary files /dev/null and b/public/images/2012/06/2012061321255600.jpg differ diff --git a/public/images/2012/06/2012061321260500.jpg b/public/images/2012/06/2012061321260500.jpg new file mode 100644 index 0000000..b392b8d Binary files /dev/null and b/public/images/2012/06/2012061321260500.jpg differ diff --git a/public/images/2012/06/2012061421301300.jpg b/public/images/2012/06/2012061421301300.jpg new file mode 100644 index 0000000..a7ab63d Binary files /dev/null and b/public/images/2012/06/2012061421301300.jpg differ diff --git a/public/images/2012/06/2012061421341600.jpg b/public/images/2012/06/2012061421341600.jpg new file mode 100644 index 0000000..c3c9400 Binary files /dev/null and b/public/images/2012/06/2012061421341600.jpg differ diff --git a/public/images/2012/06/2012061421342000.jpg b/public/images/2012/06/2012061421342000.jpg new file mode 100644 index 0000000..71f1b5b Binary files /dev/null and b/public/images/2012/06/2012061421342000.jpg differ diff --git a/public/images/2012/06/2012061822004800.jpg b/public/images/2012/06/2012061822004800.jpg new file mode 100644 index 0000000..abf6dd7 Binary files /dev/null and b/public/images/2012/06/2012061822004800.jpg differ diff --git a/public/images/2012/06/2012061822023600.jpg b/public/images/2012/06/2012061822023600.jpg new file mode 100644 index 0000000..3de6b88 Binary files /dev/null and b/public/images/2012/06/2012061822023600.jpg differ diff --git a/public/images/2012/06/2012061822064600.jpg b/public/images/2012/06/2012061822064600.jpg new file mode 100644 index 0000000..e4cc3aa Binary files /dev/null and b/public/images/2012/06/2012061822064600.jpg differ diff --git a/public/images/2012/06/2012061822101400.jpg b/public/images/2012/06/2012061822101400.jpg new file mode 100644 index 0000000..e67dac1 Binary files /dev/null and b/public/images/2012/06/2012061822101400.jpg differ diff --git a/public/images/2012/06/2012061822102000.jpg b/public/images/2012/06/2012061822102000.jpg new file mode 100644 index 0000000..79f44c3 Binary files /dev/null and b/public/images/2012/06/2012061822102000.jpg differ diff --git a/public/images/2012/06/2012062122492500.jpg b/public/images/2012/06/2012062122492500.jpg new file mode 100644 index 0000000..526a92e Binary files /dev/null and b/public/images/2012/06/2012062122492500.jpg differ diff --git a/public/images/2012/06/2012062122522200.jpg b/public/images/2012/06/2012062122522200.jpg new file mode 100644 index 0000000..53de900 Binary files /dev/null and b/public/images/2012/06/2012062122522200.jpg differ diff --git a/public/images/2012/06/2012062122543800.jpg b/public/images/2012/06/2012062122543800.jpg new file mode 100644 index 0000000..8b1d60b Binary files /dev/null and b/public/images/2012/06/2012062122543800.jpg differ diff --git a/public/images/2012/06/2012062222340200.jpg b/public/images/2012/06/2012062222340200.jpg new file mode 100644 index 0000000..1165185 Binary files /dev/null and b/public/images/2012/06/2012062222340200.jpg differ diff --git a/public/images/2012/06/2012062222380700.jpg b/public/images/2012/06/2012062222380700.jpg new file mode 100644 index 0000000..7933f86 Binary files /dev/null and b/public/images/2012/06/2012062222380700.jpg differ diff --git a/public/images/2012/06/2012062222394000.jpg b/public/images/2012/06/2012062222394000.jpg new file mode 100644 index 0000000..b10c1f0 Binary files /dev/null and b/public/images/2012/06/2012062222394000.jpg differ diff --git a/public/images/2012/06/2012062423110400.jpg b/public/images/2012/06/2012062423110400.jpg new file mode 100644 index 0000000..18f3df4 Binary files /dev/null and b/public/images/2012/06/2012062423110400.jpg differ diff --git a/public/images/2012/06/2012062423141100.jpg b/public/images/2012/06/2012062423141100.jpg new file mode 100644 index 0000000..2f1fdd7 Binary files /dev/null and b/public/images/2012/06/2012062423141100.jpg differ diff --git a/public/images/2012/06/2012062423151000.jpg b/public/images/2012/06/2012062423151000.jpg new file mode 100644 index 0000000..62ac4f4 Binary files /dev/null and b/public/images/2012/06/2012062423151000.jpg differ diff --git a/public/images/2012/06/2012062423174400.jpg b/public/images/2012/06/2012062423174400.jpg new file mode 100644 index 0000000..0cbe18f Binary files /dev/null and b/public/images/2012/06/2012062423174400.jpg differ diff --git a/public/images/2012/06/2012062623222100.jpg b/public/images/2012/06/2012062623222100.jpg new file mode 100644 index 0000000..abe05fb Binary files /dev/null and b/public/images/2012/06/2012062623222100.jpg differ diff --git a/public/images/2012/06/2012062623233400.jpg b/public/images/2012/06/2012062623233400.jpg new file mode 100644 index 0000000..3a4541c Binary files /dev/null and b/public/images/2012/06/2012062623233400.jpg differ diff --git a/public/images/2012/06/2012062623233900.jpg b/public/images/2012/06/2012062623233900.jpg new file mode 100644 index 0000000..712b63c Binary files /dev/null and b/public/images/2012/06/2012062623233900.jpg differ diff --git a/public/images/2012/06/2012062823283400.jpg b/public/images/2012/06/2012062823283400.jpg new file mode 100644 index 0000000..4de18ad Binary files /dev/null and b/public/images/2012/06/2012062823283400.jpg differ diff --git a/public/images/2012/06/2012062823295700.jpg b/public/images/2012/06/2012062823295700.jpg new file mode 100644 index 0000000..01df1a4 Binary files /dev/null and b/public/images/2012/06/2012062823295700.jpg differ diff --git a/public/images/2012/06/2012062823300200.jpg b/public/images/2012/06/2012062823300200.jpg new file mode 100644 index 0000000..fdd7654 Binary files /dev/null and b/public/images/2012/06/2012062823300200.jpg differ diff --git a/public/images/2012/07/2012071223421000.jpg b/public/images/2012/07/2012071223421000.jpg new file mode 100644 index 0000000..e975a9f Binary files /dev/null and b/public/images/2012/07/2012071223421000.jpg differ diff --git a/public/images/2012/07/2012071223421600.jpg b/public/images/2012/07/2012071223421600.jpg new file mode 100644 index 0000000..c638ee0 Binary files /dev/null and b/public/images/2012/07/2012071223421600.jpg differ diff --git a/public/images/2012/07/2012071223422100.jpg b/public/images/2012/07/2012071223422100.jpg new file mode 100644 index 0000000..8dfcc77 Binary files /dev/null and b/public/images/2012/07/2012071223422100.jpg differ diff --git a/public/images/2012/07/2012072022533700.jpg b/public/images/2012/07/2012072022533700.jpg new file mode 100644 index 0000000..af9b7f0 Binary files /dev/null and b/public/images/2012/07/2012072022533700.jpg differ diff --git a/public/images/2012/07/2012072022545900.jpg b/public/images/2012/07/2012072022545900.jpg new file mode 100644 index 0000000..bce69d7 Binary files /dev/null and b/public/images/2012/07/2012072022545900.jpg differ diff --git a/public/images/2012/07/2012072022550500.jpg b/public/images/2012/07/2012072022550500.jpg new file mode 100644 index 0000000..209c001 Binary files /dev/null and b/public/images/2012/07/2012072022550500.jpg differ diff --git a/public/images/2012/07/2012072523060500.jpg b/public/images/2012/07/2012072523060500.jpg new file mode 100644 index 0000000..1726520 Binary files /dev/null and b/public/images/2012/07/2012072523060500.jpg differ diff --git a/public/images/2012/07/2012072523090800.jpg b/public/images/2012/07/2012072523090800.jpg new file mode 100644 index 0000000..c39cf6a Binary files /dev/null and b/public/images/2012/07/2012072523090800.jpg differ diff --git a/public/images/2012/07/2012072523091100.jpg b/public/images/2012/07/2012072523091100.jpg new file mode 100644 index 0000000..d6541fd Binary files /dev/null and b/public/images/2012/07/2012072523091100.jpg differ diff --git a/public/images/2012/07/2012072523091300.jpg b/public/images/2012/07/2012072523091300.jpg new file mode 100644 index 0000000..15bbfa8 Binary files /dev/null and b/public/images/2012/07/2012072523091300.jpg differ diff --git a/public/images/2012/07/2012072523091700.jpg b/public/images/2012/07/2012072523091700.jpg new file mode 100644 index 0000000..028fedc Binary files /dev/null and b/public/images/2012/07/2012072523091700.jpg differ diff --git a/public/images/2012/08/2012080819554000.jpg b/public/images/2012/08/2012080819554000.jpg new file mode 100644 index 0000000..315e238 Binary files /dev/null and b/public/images/2012/08/2012080819554000.jpg differ diff --git a/public/images/2012/08/2012080819561600.jpg b/public/images/2012/08/2012080819561600.jpg new file mode 100644 index 0000000..ca36fc5 Binary files /dev/null and b/public/images/2012/08/2012080819561600.jpg differ diff --git a/public/images/2012/08/2012080819562000.jpg b/public/images/2012/08/2012080819562000.jpg new file mode 100644 index 0000000..fb1995e Binary files /dev/null and b/public/images/2012/08/2012080819562000.jpg differ diff --git a/public/images/2012/08/2012082820070400.jpg b/public/images/2012/08/2012082820070400.jpg new file mode 100644 index 0000000..c76a1b1 Binary files /dev/null and b/public/images/2012/08/2012082820070400.jpg differ diff --git a/public/images/2012/08/2012082820071600.jpg b/public/images/2012/08/2012082820071600.jpg new file mode 100644 index 0000000..58b8481 Binary files /dev/null and b/public/images/2012/08/2012082820071600.jpg differ diff --git a/public/images/2012/08/2012082820072500.jpg b/public/images/2012/08/2012082820072500.jpg new file mode 100644 index 0000000..2844631 Binary files /dev/null and b/public/images/2012/08/2012082820072500.jpg differ diff --git a/public/images/2012/09/2012090220180700.jpg b/public/images/2012/09/2012090220180700.jpg new file mode 100644 index 0000000..c9b47d0 Binary files /dev/null and b/public/images/2012/09/2012090220180700.jpg differ diff --git a/public/images/2012/09/2012090220233200.jpg b/public/images/2012/09/2012090220233200.jpg new file mode 100644 index 0000000..b3528d1 Binary files /dev/null and b/public/images/2012/09/2012090220233200.jpg differ diff --git a/public/images/2012/09/2012090220242000.jpg b/public/images/2012/09/2012090220242000.jpg new file mode 100644 index 0000000..dc94736 Binary files /dev/null and b/public/images/2012/09/2012090220242000.jpg differ diff --git a/public/images/2012/09/2012090220242500.jpg b/public/images/2012/09/2012090220242500.jpg new file mode 100644 index 0000000..e8966e5 Binary files /dev/null and b/public/images/2012/09/2012090220242500.jpg differ diff --git a/public/images/2012/09/2012090720304800.jpg b/public/images/2012/09/2012090720304800.jpg new file mode 100644 index 0000000..f27b0f6 Binary files /dev/null and b/public/images/2012/09/2012090720304800.jpg differ diff --git a/public/images/2012/09/2012090720323100.jpg b/public/images/2012/09/2012090720323100.jpg new file mode 100644 index 0000000..24428f1 Binary files /dev/null and b/public/images/2012/09/2012090720323100.jpg differ diff --git a/public/images/2012/09/2012090720323500.jpg b/public/images/2012/09/2012090720323500.jpg new file mode 100644 index 0000000..813e6c8 Binary files /dev/null and b/public/images/2012/09/2012090720323500.jpg differ diff --git a/public/images/2012/09/2012091420414300.jpg b/public/images/2012/09/2012091420414300.jpg new file mode 100644 index 0000000..d770ee0 Binary files /dev/null and b/public/images/2012/09/2012091420414300.jpg differ diff --git a/public/images/2012/09/2012091420462600.jpg b/public/images/2012/09/2012091420462600.jpg new file mode 100644 index 0000000..9476d58 Binary files /dev/null and b/public/images/2012/09/2012091420462600.jpg differ diff --git a/public/images/2012/09/2012091420484600.jpg b/public/images/2012/09/2012091420484600.jpg new file mode 100644 index 0000000..7465cb5 Binary files /dev/null and b/public/images/2012/09/2012091420484600.jpg differ diff --git a/public/images/2012/09/2012091821015000.jpg b/public/images/2012/09/2012091821015000.jpg new file mode 100644 index 0000000..787d6d3 Binary files /dev/null and b/public/images/2012/09/2012091821015000.jpg differ diff --git a/public/images/2012/09/2012091821040800.jpg b/public/images/2012/09/2012091821040800.jpg new file mode 100644 index 0000000..3acd549 Binary files /dev/null and b/public/images/2012/09/2012091821040800.jpg differ diff --git a/public/images/2012/09/2012091821082200.jpg b/public/images/2012/09/2012091821082200.jpg new file mode 100644 index 0000000..6a3af1a Binary files /dev/null and b/public/images/2012/09/2012091821082200.jpg differ diff --git a/public/images/2012/09/2012091821131300.jpg b/public/images/2012/09/2012091821131300.jpg new file mode 100644 index 0000000..dd3511b Binary files /dev/null and b/public/images/2012/09/2012091821131300.jpg differ diff --git a/public/images/2012/09/2012092721182400.jpg b/public/images/2012/09/2012092721182400.jpg new file mode 100644 index 0000000..82b1895 Binary files /dev/null and b/public/images/2012/09/2012092721182400.jpg differ diff --git a/public/images/2012/09/2012092721202300.jpg b/public/images/2012/09/2012092721202300.jpg new file mode 100644 index 0000000..38310ae Binary files /dev/null and b/public/images/2012/09/2012092721202300.jpg differ diff --git a/public/images/2012/09/2012092721395300.jpg b/public/images/2012/09/2012092721395300.jpg new file mode 100644 index 0000000..2856342 Binary files /dev/null and b/public/images/2012/09/2012092721395300.jpg differ diff --git a/public/images/2012/09/2012093021252300.jpg b/public/images/2012/09/2012093021252300.jpg new file mode 100644 index 0000000..bb99a26 Binary files /dev/null and b/public/images/2012/09/2012093021252300.jpg differ diff --git a/public/images/2012/09/2012093021302700.jpg b/public/images/2012/09/2012093021302700.jpg new file mode 100644 index 0000000..50fef5f Binary files /dev/null and b/public/images/2012/09/2012093021302700.jpg differ diff --git a/public/images/2012/09/2012093021303100.jpg b/public/images/2012/09/2012093021303100.jpg new file mode 100644 index 0000000..998b127 Binary files /dev/null and b/public/images/2012/09/2012093021303100.jpg differ diff --git a/public/images/2012/10/2012102720033500.jpg b/public/images/2012/10/2012102720033500.jpg new file mode 100644 index 0000000..d3f03a3 Binary files /dev/null and b/public/images/2012/10/2012102720033500.jpg differ diff --git a/public/images/2012/10/2012102720131600.jpg b/public/images/2012/10/2012102720131600.jpg new file mode 100644 index 0000000..18765b1 Binary files /dev/null and b/public/images/2012/10/2012102720131600.jpg differ diff --git a/public/images/2012/10/2012102720132100.jpg b/public/images/2012/10/2012102720132100.jpg new file mode 100644 index 0000000..a479275 Binary files /dev/null and b/public/images/2012/10/2012102720132100.jpg differ diff --git a/public/images/2012/10/2012102720132600.jpg b/public/images/2012/10/2012102720132600.jpg new file mode 100644 index 0000000..719c665 Binary files /dev/null and b/public/images/2012/10/2012102720132600.jpg differ diff --git a/public/images/2012/11/2012110720214400.jpg b/public/images/2012/11/2012110720214400.jpg new file mode 100644 index 0000000..d5e8f95 Binary files /dev/null and b/public/images/2012/11/2012110720214400.jpg differ diff --git a/public/images/2012/11/2012110720214600.jpg b/public/images/2012/11/2012110720214600.jpg new file mode 100644 index 0000000..fa5e64d Binary files /dev/null and b/public/images/2012/11/2012110720214600.jpg differ diff --git a/public/images/2012/11/2012110720214800.jpg b/public/images/2012/11/2012110720214800.jpg new file mode 100644 index 0000000..1f485ae Binary files /dev/null and b/public/images/2012/11/2012110720214800.jpg differ diff --git a/public/images/2012/11/2012110720214900.jpg b/public/images/2012/11/2012110720214900.jpg new file mode 100644 index 0000000..4a70195 Binary files /dev/null and b/public/images/2012/11/2012110720214900.jpg differ diff --git a/public/images/2012/11/2012110720215200.jpg b/public/images/2012/11/2012110720215200.jpg new file mode 100644 index 0000000..56a23d3 Binary files /dev/null and b/public/images/2012/11/2012110720215200.jpg differ diff --git a/public/images/2012/11/2012110720215500.jpg b/public/images/2012/11/2012110720215500.jpg new file mode 100644 index 0000000..3ad067d Binary files /dev/null and b/public/images/2012/11/2012110720215500.jpg differ diff --git a/public/images/2012/11/2012110720215700.jpg b/public/images/2012/11/2012110720215700.jpg new file mode 100644 index 0000000..cb13813 Binary files /dev/null and b/public/images/2012/11/2012110720215700.jpg differ diff --git a/public/images/2012/11/2012111120345400.jpg b/public/images/2012/11/2012111120345400.jpg new file mode 100644 index 0000000..c01949a Binary files /dev/null and b/public/images/2012/11/2012111120345400.jpg differ diff --git a/public/images/2012/11/2012111121163300.jpg b/public/images/2012/11/2012111121163300.jpg new file mode 100644 index 0000000..ba48660 Binary files /dev/null and b/public/images/2012/11/2012111121163300.jpg differ diff --git a/public/images/2012/11/2012111121163800.jpg b/public/images/2012/11/2012111121163800.jpg new file mode 100644 index 0000000..a56838f Binary files /dev/null and b/public/images/2012/11/2012111121163800.jpg differ diff --git a/public/images/2012/11/2012111121164200.jpg b/public/images/2012/11/2012111121164200.jpg new file mode 100644 index 0000000..6b56176 Binary files /dev/null and b/public/images/2012/11/2012111121164200.jpg differ diff --git a/public/images/2012/11/2012111521361400.jpg b/public/images/2012/11/2012111521361400.jpg new file mode 100644 index 0000000..6fb8299 Binary files /dev/null and b/public/images/2012/11/2012111521361400.jpg differ diff --git a/public/images/2012/11/2012111521361800.jpg b/public/images/2012/11/2012111521361800.jpg new file mode 100644 index 0000000..41468bd Binary files /dev/null and b/public/images/2012/11/2012111521361800.jpg differ diff --git a/public/images/2012/11/2012111521362300.jpg b/public/images/2012/11/2012111521362300.jpg new file mode 100644 index 0000000..fc6e282 Binary files /dev/null and b/public/images/2012/11/2012111521362300.jpg differ diff --git a/public/images/2012/11/2012112821464700.jpg b/public/images/2012/11/2012112821464700.jpg new file mode 100644 index 0000000..5331628 Binary files /dev/null and b/public/images/2012/11/2012112821464700.jpg differ diff --git a/public/images/2012/11/2012112821481600.jpg b/public/images/2012/11/2012112821481600.jpg new file mode 100644 index 0000000..96d610d Binary files /dev/null and b/public/images/2012/11/2012112821481600.jpg differ diff --git a/public/images/2012/11/2012112821482100.jpg b/public/images/2012/11/2012112821482100.jpg new file mode 100644 index 0000000..2151ee1 Binary files /dev/null and b/public/images/2012/11/2012112821482100.jpg differ diff --git a/public/images/2012/12/2012121021594300.jpg b/public/images/2012/12/2012121021594300.jpg new file mode 100644 index 0000000..142572a Binary files /dev/null and b/public/images/2012/12/2012121021594300.jpg differ diff --git a/public/images/2012/12/2012121022012400.jpg b/public/images/2012/12/2012121022012400.jpg new file mode 100644 index 0000000..b6aa22b Binary files /dev/null and b/public/images/2012/12/2012121022012400.jpg differ diff --git a/public/images/2012/12/2012121022012900.jpg b/public/images/2012/12/2012121022012900.jpg new file mode 100644 index 0000000..ee41e90 Binary files /dev/null and b/public/images/2012/12/2012121022012900.jpg differ diff --git a/public/images/2012/12/2012121122120900.jpg b/public/images/2012/12/2012121122120900.jpg new file mode 100644 index 0000000..0c56d10 Binary files /dev/null and b/public/images/2012/12/2012121122120900.jpg differ diff --git a/public/images/2012/12/2012121122144500.jpg b/public/images/2012/12/2012121122144500.jpg new file mode 100644 index 0000000..9961910 Binary files /dev/null and b/public/images/2012/12/2012121122144500.jpg differ diff --git a/public/images/2012/12/2012121122170800.jpg b/public/images/2012/12/2012121122170800.jpg new file mode 100644 index 0000000..3d6de84 Binary files /dev/null and b/public/images/2012/12/2012121122170800.jpg differ diff --git a/public/images/2012/12/2012121422373000.jpg b/public/images/2012/12/2012121422373000.jpg new file mode 100644 index 0000000..5f479e8 Binary files /dev/null and b/public/images/2012/12/2012121422373000.jpg differ diff --git a/public/images/2012/12/2012121422380800.jpg b/public/images/2012/12/2012121422380800.jpg new file mode 100644 index 0000000..eb588de Binary files /dev/null and b/public/images/2012/12/2012121422380800.jpg differ diff --git a/public/images/2012/12/2012121422381400.jpg b/public/images/2012/12/2012121422381400.jpg new file mode 100644 index 0000000..900124b Binary files /dev/null and b/public/images/2012/12/2012121422381400.jpg differ diff --git a/public/images/2013/01/2013010122575800.jpg b/public/images/2013/01/2013010122575800.jpg new file mode 100644 index 0000000..2145510 Binary files /dev/null and b/public/images/2013/01/2013010122575800.jpg differ diff --git a/public/images/2013/01/2013010123020800.jpg b/public/images/2013/01/2013010123020800.jpg new file mode 100644 index 0000000..7ca5f6e Binary files /dev/null and b/public/images/2013/01/2013010123020800.jpg differ diff --git a/public/images/2013/01/2013010123033300.jpg b/public/images/2013/01/2013010123033300.jpg new file mode 100644 index 0000000..c868a85 Binary files /dev/null and b/public/images/2013/01/2013010123033300.jpg differ diff --git a/public/images/2013/01/2013010123075700.jpg b/public/images/2013/01/2013010123075700.jpg new file mode 100644 index 0000000..b3b0666 Binary files /dev/null and b/public/images/2013/01/2013010123075700.jpg differ diff --git a/public/images/2013/01/2013010712171200.jpg b/public/images/2013/01/2013010712171200.jpg new file mode 100644 index 0000000..253f3fb Binary files /dev/null and b/public/images/2013/01/2013010712171200.jpg differ diff --git a/public/images/2013/01/2013010923141500.jpg b/public/images/2013/01/2013010923141500.jpg new file mode 100644 index 0000000..2122e98 Binary files /dev/null and b/public/images/2013/01/2013010923141500.jpg differ diff --git a/public/images/2013/01/2013010923203400.jpg b/public/images/2013/01/2013010923203400.jpg new file mode 100644 index 0000000..8f9dcf8 Binary files /dev/null and b/public/images/2013/01/2013010923203400.jpg differ diff --git a/public/images/2013/01/2013010923242700.jpg b/public/images/2013/01/2013010923242700.jpg new file mode 100644 index 0000000..1d2bb87 Binary files /dev/null and b/public/images/2013/01/2013010923242700.jpg differ diff --git a/public/images/2013/01/2013010923260800.jpg b/public/images/2013/01/2013010923260800.jpg new file mode 100644 index 0000000..e7937dc Binary files /dev/null and b/public/images/2013/01/2013010923260800.jpg differ diff --git a/public/images/2013/01/2013011017463500.jpg b/public/images/2013/01/2013011017463500.jpg new file mode 100644 index 0000000..6f809e0 Binary files /dev/null and b/public/images/2013/01/2013011017463500.jpg differ diff --git a/public/images/2013/01/2013011323292300.jpg b/public/images/2013/01/2013011323292300.jpg new file mode 100644 index 0000000..5f3218c Binary files /dev/null and b/public/images/2013/01/2013011323292300.jpg differ diff --git a/public/images/2013/01/2013011323344400.jpg b/public/images/2013/01/2013011323344400.jpg new file mode 100644 index 0000000..8727bf6 Binary files /dev/null and b/public/images/2013/01/2013011323344400.jpg differ diff --git a/public/images/2013/01/2013011323372700.jpg b/public/images/2013/01/2013011323372700.jpg new file mode 100644 index 0000000..149d9e9 Binary files /dev/null and b/public/images/2013/01/2013011323372700.jpg differ diff --git a/public/images/2013/01/2013011323391300.jpg b/public/images/2013/01/2013011323391300.jpg new file mode 100644 index 0000000..ae5e369 Binary files /dev/null and b/public/images/2013/01/2013011323391300.jpg differ diff --git a/public/images/2013/01/2013012920023000.jpg b/public/images/2013/01/2013012920023000.jpg new file mode 100644 index 0000000..5282c49 Binary files /dev/null and b/public/images/2013/01/2013012920023000.jpg differ diff --git a/public/images/2013/01/2013012920112800.jpg b/public/images/2013/01/2013012920112800.jpg new file mode 100644 index 0000000..f630837 Binary files /dev/null and b/public/images/2013/01/2013012920112800.jpg differ diff --git a/public/images/2013/01/2013012920123600.jpg b/public/images/2013/01/2013012920123600.jpg new file mode 100644 index 0000000..4303c06 Binary files /dev/null and b/public/images/2013/01/2013012920123600.jpg differ diff --git a/public/images/2013/01/2013012920140500.jpg b/public/images/2013/01/2013012920140500.jpg new file mode 100644 index 0000000..f0f375b Binary files /dev/null and b/public/images/2013/01/2013012920140500.jpg differ diff --git a/public/images/2013/01/2013012920154100.jpg b/public/images/2013/01/2013012920154100.jpg new file mode 100644 index 0000000..06ebe8c Binary files /dev/null and b/public/images/2013/01/2013012920154100.jpg differ diff --git a/public/images/2013/01/2013013120175200.jpg b/public/images/2013/01/2013013120175200.jpg new file mode 100644 index 0000000..7a7c27b Binary files /dev/null and b/public/images/2013/01/2013013120175200.jpg differ diff --git a/public/images/2013/01/2013013120222500.jpg b/public/images/2013/01/2013013120222500.jpg new file mode 100644 index 0000000..700c8ef Binary files /dev/null and b/public/images/2013/01/2013013120222500.jpg differ diff --git a/public/images/2013/01/2013013120320300.jpg b/public/images/2013/01/2013013120320300.jpg new file mode 100644 index 0000000..fd311b6 Binary files /dev/null and b/public/images/2013/01/2013013120320300.jpg differ diff --git a/public/images/2013/01/2013013120385500.jpg b/public/images/2013/01/2013013120385500.jpg new file mode 100644 index 0000000..e4167d7 Binary files /dev/null and b/public/images/2013/01/2013013120385500.jpg differ diff --git a/public/images/2013/01/2013013120403900.jpg b/public/images/2013/01/2013013120403900.jpg new file mode 100644 index 0000000..2843733 Binary files /dev/null and b/public/images/2013/01/2013013120403900.jpg differ diff --git a/public/images/2013/02/2013021404315100.jpg b/public/images/2013/02/2013021404315100.jpg new file mode 100644 index 0000000..f0fdc08 Binary files /dev/null and b/public/images/2013/02/2013021404315100.jpg differ diff --git a/public/images/2013/03/2013030220520400.jpg b/public/images/2013/03/2013030220520400.jpg new file mode 100644 index 0000000..b0bf0e0 Binary files /dev/null and b/public/images/2013/03/2013030220520400.jpg differ diff --git a/public/images/2013/03/2013030220535900.jpg b/public/images/2013/03/2013030220535900.jpg new file mode 100644 index 0000000..cfb88e1 Binary files /dev/null and b/public/images/2013/03/2013030220535900.jpg differ diff --git a/public/images/2013/03/2013030220565000.jpg b/public/images/2013/03/2013030220565000.jpg new file mode 100644 index 0000000..490e768 Binary files /dev/null and b/public/images/2013/03/2013030220565000.jpg differ diff --git a/public/images/2013/03/2013030220581600.jpg b/public/images/2013/03/2013030220581600.jpg new file mode 100644 index 0000000..032e8e1 Binary files /dev/null and b/public/images/2013/03/2013030220581600.jpg differ diff --git a/public/images/2013/03/2013030821022700.jpg b/public/images/2013/03/2013030821022700.jpg new file mode 100644 index 0000000..7c1b851 Binary files /dev/null and b/public/images/2013/03/2013030821022700.jpg differ diff --git a/public/images/2013/03/2013030821042700.jpg b/public/images/2013/03/2013030821042700.jpg new file mode 100644 index 0000000..f71b210 Binary files /dev/null and b/public/images/2013/03/2013030821042700.jpg differ diff --git a/public/images/2013/03/2013030821055700.jpg b/public/images/2013/03/2013030821055700.jpg new file mode 100644 index 0000000..c3c68db Binary files /dev/null and b/public/images/2013/03/2013030821055700.jpg differ diff --git a/public/images/2013/03/2013030821095600.jpg b/public/images/2013/03/2013030821095600.jpg new file mode 100644 index 0000000..49a190a Binary files /dev/null and b/public/images/2013/03/2013030821095600.jpg differ diff --git a/public/images/2013/03/2013031621203200.jpg b/public/images/2013/03/2013031621203200.jpg new file mode 100644 index 0000000..8c4cd6c Binary files /dev/null and b/public/images/2013/03/2013031621203200.jpg differ diff --git a/public/images/2013/03/2013031621223800.jpg b/public/images/2013/03/2013031621223800.jpg new file mode 100644 index 0000000..337ce30 Binary files /dev/null and b/public/images/2013/03/2013031621223800.jpg differ diff --git a/public/images/2013/03/2013031621245200.jpg b/public/images/2013/03/2013031621245200.jpg new file mode 100644 index 0000000..964251e Binary files /dev/null and b/public/images/2013/03/2013031621245200.jpg differ diff --git a/public/images/2013/03/2013031621265500.jpg b/public/images/2013/03/2013031621265500.jpg new file mode 100644 index 0000000..00a3d28 Binary files /dev/null and b/public/images/2013/03/2013031621265500.jpg differ diff --git a/public/images/2013/04/2013040621410400.jpg b/public/images/2013/04/2013040621410400.jpg new file mode 100644 index 0000000..74d9036 Binary files /dev/null and b/public/images/2013/04/2013040621410400.jpg differ diff --git a/public/images/2013/04/2013040621452600.jpg b/public/images/2013/04/2013040621452600.jpg new file mode 100644 index 0000000..02e5517 Binary files /dev/null and b/public/images/2013/04/2013040621452600.jpg differ diff --git a/public/images/2013/04/2013040621482300.jpg b/public/images/2013/04/2013040621482300.jpg new file mode 100644 index 0000000..57ac1c3 Binary files /dev/null and b/public/images/2013/04/2013040621482300.jpg differ diff --git a/public/images/2013/04/2013040621510000.jpg b/public/images/2013/04/2013040621510000.jpg new file mode 100644 index 0000000..cad75a2 Binary files /dev/null and b/public/images/2013/04/2013040621510000.jpg differ diff --git a/public/images/2013/04/2013042722324600.jpg b/public/images/2013/04/2013042722324600.jpg new file mode 100644 index 0000000..4095956 Binary files /dev/null and b/public/images/2013/04/2013042722324600.jpg differ diff --git a/public/images/2013/04/2013042823510900.jpg b/public/images/2013/04/2013042823510900.jpg new file mode 100644 index 0000000..a3c3a2a Binary files /dev/null and b/public/images/2013/04/2013042823510900.jpg differ diff --git a/public/images/2013/04/2013043022435500.jpg b/public/images/2013/04/2013043022435500.jpg new file mode 100644 index 0000000..e8d3002 Binary files /dev/null and b/public/images/2013/04/2013043022435500.jpg differ diff --git a/public/images/2013/04/2013043022480300.jpg b/public/images/2013/04/2013043022480300.jpg new file mode 100644 index 0000000..921058b Binary files /dev/null and b/public/images/2013/04/2013043022480300.jpg differ diff --git a/public/images/2013/04/2013043022492800.jpg b/public/images/2013/04/2013043022492800.jpg new file mode 100644 index 0000000..2e7b9fe Binary files /dev/null and b/public/images/2013/04/2013043022492800.jpg differ diff --git a/public/images/2013/04/2013043022510700.jpg b/public/images/2013/04/2013043022510700.jpg new file mode 100644 index 0000000..5a385f6 Binary files /dev/null and b/public/images/2013/04/2013043022510700.jpg differ diff --git a/public/images/2013/04/2013043022511000.jpg b/public/images/2013/04/2013043022511000.jpg new file mode 100644 index 0000000..3454f03 Binary files /dev/null and b/public/images/2013/04/2013043022511000.jpg differ diff --git a/public/images/2013/05/2013051722351900.jpg b/public/images/2013/05/2013051722351900.jpg new file mode 100644 index 0000000..5be765e Binary files /dev/null and b/public/images/2013/05/2013051722351900.jpg differ diff --git a/public/images/2013/05/2013051722363500.jpg b/public/images/2013/05/2013051722363500.jpg new file mode 100644 index 0000000..faf68ac Binary files /dev/null and b/public/images/2013/05/2013051722363500.jpg differ diff --git a/public/images/2013/05/2013051722381700.jpg b/public/images/2013/05/2013051722381700.jpg new file mode 100644 index 0000000..ebfaf13 Binary files /dev/null and b/public/images/2013/05/2013051722381700.jpg differ diff --git a/public/images/2013/05/2013051722382300.jpg b/public/images/2013/05/2013051722382300.jpg new file mode 100644 index 0000000..d81268c Binary files /dev/null and b/public/images/2013/05/2013051722382300.jpg differ diff --git a/public/images/2013/05/2013051722382500.jpg b/public/images/2013/05/2013051722382500.jpg new file mode 100644 index 0000000..0d1bf75 Binary files /dev/null and b/public/images/2013/05/2013051722382500.jpg differ diff --git a/public/images/2013/05/2013052022592400.jpg b/public/images/2013/05/2013052022592400.jpg new file mode 100644 index 0000000..2095d50 Binary files /dev/null and b/public/images/2013/05/2013052022592400.jpg differ diff --git a/public/images/2013/05/2013052023024000.jpg b/public/images/2013/05/2013052023024000.jpg new file mode 100644 index 0000000..cadc8ee Binary files /dev/null and b/public/images/2013/05/2013052023024000.jpg differ diff --git a/public/images/2013/05/2013052023095200.jpg b/public/images/2013/05/2013052023095200.jpg new file mode 100644 index 0000000..57f44fd Binary files /dev/null and b/public/images/2013/05/2013052023095200.jpg differ diff --git a/public/images/2013/05/2013052023120700.jpg b/public/images/2013/05/2013052023120700.jpg new file mode 100644 index 0000000..c0c2f4d Binary files /dev/null and b/public/images/2013/05/2013052023120700.jpg differ diff --git a/public/images/2013/06/2013062023165500.jpg b/public/images/2013/06/2013062023165500.jpg new file mode 100644 index 0000000..2cfbc73 Binary files /dev/null and b/public/images/2013/06/2013062023165500.jpg differ diff --git a/public/images/2013/06/2013062023193800.jpg b/public/images/2013/06/2013062023193800.jpg new file mode 100644 index 0000000..d9c51ec Binary files /dev/null and b/public/images/2013/06/2013062023193800.jpg differ diff --git a/public/images/2013/06/2013062023222900.jpg b/public/images/2013/06/2013062023222900.jpg new file mode 100644 index 0000000..b7c618c Binary files /dev/null and b/public/images/2013/06/2013062023222900.jpg differ diff --git a/public/images/2013/06/2013062923260700.jpg b/public/images/2013/06/2013062923260700.jpg new file mode 100644 index 0000000..87f4799 Binary files /dev/null and b/public/images/2013/06/2013062923260700.jpg differ diff --git a/public/images/2013/06/2013062923282500.jpg b/public/images/2013/06/2013062923282500.jpg new file mode 100644 index 0000000..99f1c20 Binary files /dev/null and b/public/images/2013/06/2013062923282500.jpg differ diff --git a/public/images/2013/06/2013062923304000.jpg b/public/images/2013/06/2013062923304000.jpg new file mode 100644 index 0000000..8260b81 Binary files /dev/null and b/public/images/2013/06/2013062923304000.jpg differ diff --git a/public/images/2013/06/2013062923361600.jpg b/public/images/2013/06/2013062923361600.jpg new file mode 100644 index 0000000..fac7259 Binary files /dev/null and b/public/images/2013/06/2013062923361600.jpg differ diff --git a/public/images/2013/07/2013071822320501.jpg b/public/images/2013/07/2013071822320501.jpg new file mode 100644 index 0000000..63c4d83 Binary files /dev/null and b/public/images/2013/07/2013071822320501.jpg differ diff --git a/public/images/2013/07/2013071823431400.jpg b/public/images/2013/07/2013071823431400.jpg new file mode 100644 index 0000000..7c25d8c Binary files /dev/null and b/public/images/2013/07/2013071823431400.jpg differ diff --git a/public/images/2013/07/2013071823450900.jpg b/public/images/2013/07/2013071823450900.jpg new file mode 100644 index 0000000..e43bf2f Binary files /dev/null and b/public/images/2013/07/2013071823450900.jpg differ diff --git a/public/images/2013/07/2013071823470800.jpg b/public/images/2013/07/2013071823470800.jpg new file mode 100644 index 0000000..1896366 Binary files /dev/null and b/public/images/2013/07/2013071823470800.jpg differ diff --git a/public/images/2013/07/2013071823490400.jpg b/public/images/2013/07/2013071823490400.jpg new file mode 100644 index 0000000..ffb10d9 Binary files /dev/null and b/public/images/2013/07/2013071823490400.jpg differ diff --git a/public/images/2013/07/2013072700011200.jpg b/public/images/2013/07/2013072700011200.jpg new file mode 100644 index 0000000..c3ba6f8 Binary files /dev/null and b/public/images/2013/07/2013072700011200.jpg differ diff --git a/public/images/2013/07/2013072700022500.jpg b/public/images/2013/07/2013072700022500.jpg new file mode 100644 index 0000000..11c36f2 Binary files /dev/null and b/public/images/2013/07/2013072700022500.jpg differ diff --git a/public/images/2013/07/2013072723570200.jpg b/public/images/2013/07/2013072723570200.jpg new file mode 100644 index 0000000..7881bd8 Binary files /dev/null and b/public/images/2013/07/2013072723570200.jpg differ diff --git a/public/images/2013/07/2013072723584300.jpg b/public/images/2013/07/2013072723584300.jpg new file mode 100644 index 0000000..446da48 Binary files /dev/null and b/public/images/2013/07/2013072723584300.jpg differ diff --git a/public/images/2013/08/2013080200113300.jpg b/public/images/2013/08/2013080200113300.jpg new file mode 100644 index 0000000..402c453 Binary files /dev/null and b/public/images/2013/08/2013080200113300.jpg differ diff --git a/public/images/2013/08/2013080200132700.jpg b/public/images/2013/08/2013080200132700.jpg new file mode 100644 index 0000000..60627f9 Binary files /dev/null and b/public/images/2013/08/2013080200132700.jpg differ diff --git a/public/images/2013/08/2013080200173500.jpg b/public/images/2013/08/2013080200173500.jpg new file mode 100644 index 0000000..b7229bc Binary files /dev/null and b/public/images/2013/08/2013080200173500.jpg differ diff --git a/public/images/2013/08/2013080200191900.jpg b/public/images/2013/08/2013080200191900.jpg new file mode 100644 index 0000000..5c3d0be Binary files /dev/null and b/public/images/2013/08/2013080200191900.jpg differ diff --git a/public/images/2013/08/2013080700214600.jpg b/public/images/2013/08/2013080700214600.jpg new file mode 100644 index 0000000..3bf7452 Binary files /dev/null and b/public/images/2013/08/2013080700214600.jpg differ diff --git a/public/images/2013/08/2013080700242200.jpg b/public/images/2013/08/2013080700242200.jpg new file mode 100644 index 0000000..18298a9 Binary files /dev/null and b/public/images/2013/08/2013080700242200.jpg differ diff --git a/public/images/2013/08/2013080700290300.jpg b/public/images/2013/08/2013080700290300.jpg new file mode 100644 index 0000000..7d249d9 Binary files /dev/null and b/public/images/2013/08/2013080700290300.jpg differ diff --git a/public/images/2013/08/2013080700290500.jpg b/public/images/2013/08/2013080700290500.jpg new file mode 100644 index 0000000..ca46518 Binary files /dev/null and b/public/images/2013/08/2013080700290500.jpg differ diff --git a/public/images/2013/08/2013080700290700.jpg b/public/images/2013/08/2013080700290700.jpg new file mode 100644 index 0000000..b273ff4 Binary files /dev/null and b/public/images/2013/08/2013080700290700.jpg differ diff --git a/public/images/2013/09/2013092100390300.jpg b/public/images/2013/09/2013092100390300.jpg new file mode 100644 index 0000000..ac328f2 Binary files /dev/null and b/public/images/2013/09/2013092100390300.jpg differ diff --git a/public/images/2013/09/2013092100464200.jpg b/public/images/2013/09/2013092100464200.jpg new file mode 100644 index 0000000..a3f44da Binary files /dev/null and b/public/images/2013/09/2013092100464200.jpg differ diff --git a/public/images/2013/09/2013092100465400.jpg b/public/images/2013/09/2013092100465400.jpg new file mode 100644 index 0000000..f44f82e Binary files /dev/null and b/public/images/2013/09/2013092100465400.jpg differ diff --git a/public/images/2013/09/2013092121155300.jpg b/public/images/2013/09/2013092121155300.jpg new file mode 100644 index 0000000..4e600cd Binary files /dev/null and b/public/images/2013/09/2013092121155300.jpg differ diff --git a/public/images/2013/10/2013100501035200.jpg b/public/images/2013/10/2013100501035200.jpg new file mode 100644 index 0000000..970035a Binary files /dev/null and b/public/images/2013/10/2013100501035200.jpg differ diff --git a/public/images/2013/10/2013100501103300.jpg b/public/images/2013/10/2013100501103300.jpg new file mode 100644 index 0000000..7f89d1c Binary files /dev/null and b/public/images/2013/10/2013100501103300.jpg differ diff --git a/public/images/2013/10/2013100501130100.jpg b/public/images/2013/10/2013100501130100.jpg new file mode 100644 index 0000000..6525171 Binary files /dev/null and b/public/images/2013/10/2013100501130100.jpg differ diff --git a/public/images/2013/10/2013100501170700.jpg b/public/images/2013/10/2013100501170700.jpg new file mode 100644 index 0000000..0acfe3b Binary files /dev/null and b/public/images/2013/10/2013100501170700.jpg differ diff --git a/public/images/2013/11/2013110400534500.jpg b/public/images/2013/11/2013110400534500.jpg new file mode 100644 index 0000000..be00ca9 Binary files /dev/null and b/public/images/2013/11/2013110400534500.jpg differ diff --git a/public/images/2013/11/2013110400564500.jpg b/public/images/2013/11/2013110400564500.jpg new file mode 100644 index 0000000..68ac7d4 Binary files /dev/null and b/public/images/2013/11/2013110400564500.jpg differ diff --git a/public/images/2013/11/2013110400564800.jpg b/public/images/2013/11/2013110400564800.jpg new file mode 100644 index 0000000..cb46f3a Binary files /dev/null and b/public/images/2013/11/2013110400564800.jpg differ diff --git a/public/images/2013/11/2013110400595700.jpg b/public/images/2013/11/2013110400595700.jpg new file mode 100644 index 0000000..39a8136 Binary files /dev/null and b/public/images/2013/11/2013110400595700.jpg differ diff --git a/public/images/2013/11/2013111801235800.jpg b/public/images/2013/11/2013111801235800.jpg new file mode 100644 index 0000000..ba164e2 Binary files /dev/null and b/public/images/2013/11/2013111801235800.jpg differ diff --git a/public/images/2013/11/2013111801261300.jpg b/public/images/2013/11/2013111801261300.jpg new file mode 100644 index 0000000..afcc975 Binary files /dev/null and b/public/images/2013/11/2013111801261300.jpg differ diff --git a/public/images/2013/11/2013111801282600.jpg b/public/images/2013/11/2013111801282600.jpg new file mode 100644 index 0000000..0e08a1d Binary files /dev/null and b/public/images/2013/11/2013111801282600.jpg differ diff --git a/public/images/2013/11/2013111801302100.jpg b/public/images/2013/11/2013111801302100.jpg new file mode 100644 index 0000000..70f7762 Binary files /dev/null and b/public/images/2013/11/2013111801302100.jpg differ diff --git a/public/images/2013/11/2013112501343300.jpg b/public/images/2013/11/2013112501343300.jpg new file mode 100644 index 0000000..f32a5b1 Binary files /dev/null and b/public/images/2013/11/2013112501343300.jpg differ diff --git a/public/images/2013/11/2013112501353300.jpg b/public/images/2013/11/2013112501353300.jpg new file mode 100644 index 0000000..a1048d4 Binary files /dev/null and b/public/images/2013/11/2013112501353300.jpg differ diff --git a/public/images/2013/12/2013120201424100.jpg b/public/images/2013/12/2013120201424100.jpg new file mode 100644 index 0000000..7a08cac Binary files /dev/null and b/public/images/2013/12/2013120201424100.jpg differ diff --git a/public/images/2013/12/2013120201503000.jpg b/public/images/2013/12/2013120201503000.jpg new file mode 100644 index 0000000..563c28c Binary files /dev/null and b/public/images/2013/12/2013120201503000.jpg differ diff --git a/public/images/2013/12/2013120201523700.jpg b/public/images/2013/12/2013120201523700.jpg new file mode 100644 index 0000000..0108aa8 Binary files /dev/null and b/public/images/2013/12/2013120201523700.jpg differ diff --git a/public/images/2013/12/2013120201524100.jpg b/public/images/2013/12/2013120201524100.jpg new file mode 100644 index 0000000..edb2119 Binary files /dev/null and b/public/images/2013/12/2013120201524100.jpg differ diff --git a/public/images/2013/12/2013123101375300.jpg b/public/images/2013/12/2013123101375300.jpg new file mode 100644 index 0000000..e54160c Binary files /dev/null and b/public/images/2013/12/2013123101375300.jpg differ diff --git a/public/images/2013/12/2013123101553100.jpg b/public/images/2013/12/2013123101553100.jpg new file mode 100644 index 0000000..729c1df Binary files /dev/null and b/public/images/2013/12/2013123101553100.jpg differ diff --git a/public/images/2013/12/2013123101571500.jpg b/public/images/2013/12/2013123101571500.jpg new file mode 100644 index 0000000..25f2915 Binary files /dev/null and b/public/images/2013/12/2013123101571500.jpg differ diff --git a/public/images/2019/05/2019050901494935.jpg b/public/images/2019/05/2019050901494935.jpg new file mode 100644 index 0000000..1f28273 Binary files /dev/null and b/public/images/2019/05/2019050901494935.jpg differ diff --git a/public/images/2019/05/2019050902101874.jpg b/public/images/2019/05/2019050902101874.jpg new file mode 100644 index 0000000..0f48935 Binary files /dev/null and b/public/images/2019/05/2019050902101874.jpg differ diff --git a/public/images/2019/05/2019050902175888.jpg b/public/images/2019/05/2019050902175888.jpg new file mode 100644 index 0000000..bee996c Binary files /dev/null and b/public/images/2019/05/2019050902175888.jpg differ diff --git a/public/images/2019/05/2019050902252161.jpg b/public/images/2019/05/2019050902252161.jpg new file mode 100644 index 0000000..d62c222 Binary files /dev/null and b/public/images/2019/05/2019050902252161.jpg differ diff --git a/public/images/2019/05/2019050902332168.jpg b/public/images/2019/05/2019050902332168.jpg new file mode 100644 index 0000000..2aa840a Binary files /dev/null and b/public/images/2019/05/2019050902332168.jpg differ diff --git a/public/images/2019/05/2019050902371572.jpg b/public/images/2019/05/2019050902371572.jpg new file mode 100644 index 0000000..d93a6d9 Binary files /dev/null and b/public/images/2019/05/2019050902371572.jpg differ diff --git a/public/images/2019/05/2019050902442970.jpg b/public/images/2019/05/2019050902442970.jpg new file mode 100644 index 0000000..d5d132a Binary files /dev/null and b/public/images/2019/05/2019050902442970.jpg differ diff --git a/public/images/2019/05/2019050902470727.jpg b/public/images/2019/05/2019050902470727.jpg new file mode 100644 index 0000000..f14ddaa Binary files /dev/null and b/public/images/2019/05/2019050902470727.jpg differ diff --git a/public/images/2019/05/2019050902474279.jpg b/public/images/2019/05/2019050902474279.jpg new file mode 100644 index 0000000..f99ca43 Binary files /dev/null and b/public/images/2019/05/2019050902474279.jpg differ diff --git a/public/images/2019/05/2019050902483348.jpg b/public/images/2019/05/2019050902483348.jpg new file mode 100644 index 0000000..1c9c964 Binary files /dev/null and b/public/images/2019/05/2019050902483348.jpg differ diff --git a/public/images/2019/05/2019050902492485.jpg b/public/images/2019/05/2019050902492485.jpg new file mode 100644 index 0000000..4f4e85f Binary files /dev/null and b/public/images/2019/05/2019050902492485.jpg differ diff --git a/public/images/2019/05/2019050902504379.jpg b/public/images/2019/05/2019050902504379.jpg new file mode 100644 index 0000000..12de637 Binary files /dev/null and b/public/images/2019/05/2019050902504379.jpg differ diff --git a/public/images/2019/05/2019050908152192.jpg b/public/images/2019/05/2019050908152192.jpg new file mode 100644 index 0000000..22b1a8a Binary files /dev/null and b/public/images/2019/05/2019050908152192.jpg differ diff --git a/public/images/2019/05/2019050908220042.png b/public/images/2019/05/2019050908220042.png new file mode 100644 index 0000000..b10080c Binary files /dev/null and b/public/images/2019/05/2019050908220042.png differ diff --git a/public/images/2019/05/2019050908223772.png b/public/images/2019/05/2019050908223772.png new file mode 100644 index 0000000..1cc883a Binary files /dev/null and b/public/images/2019/05/2019050908223772.png differ diff --git a/public/images/2019/05/2019050908233838.gif b/public/images/2019/05/2019050908233838.gif new file mode 100644 index 0000000..cb8d20b Binary files /dev/null and b/public/images/2019/05/2019050908233838.gif differ diff --git a/public/images/2019/05/2019050908243939.png b/public/images/2019/05/2019050908243939.png new file mode 100644 index 0000000..8c791f1 Binary files /dev/null and b/public/images/2019/05/2019050908243939.png differ diff --git a/public/images/2019/05/2019050908302180.jpg b/public/images/2019/05/2019050908302180.jpg new file mode 100644 index 0000000..74fd89e Binary files /dev/null and b/public/images/2019/05/2019050908302180.jpg differ diff --git a/public/images/2019/05/2019050908380382.jpg b/public/images/2019/05/2019050908380382.jpg new file mode 100644 index 0000000..01c0c41 Binary files /dev/null and b/public/images/2019/05/2019050908380382.jpg differ diff --git a/public/images/2019/05/2019050909495525.jpg b/public/images/2019/05/2019050909495525.jpg new file mode 100644 index 0000000..d694028 Binary files /dev/null and b/public/images/2019/05/2019050909495525.jpg differ diff --git a/public/images/2019/05/2019050909531558.jpg b/public/images/2019/05/2019050909531558.jpg new file mode 100644 index 0000000..9ef6296 Binary files /dev/null and b/public/images/2019/05/2019050909531558.jpg differ diff --git a/public/images/2019/05/2019050913525690.jpg b/public/images/2019/05/2019050913525690.jpg new file mode 100644 index 0000000..aa435e2 Binary files /dev/null and b/public/images/2019/05/2019050913525690.jpg differ diff --git a/public/images/2019/05/2019051406433394.jpg b/public/images/2019/05/2019051406433394.jpg new file mode 100644 index 0000000..82e0a65 Binary files /dev/null and b/public/images/2019/05/2019051406433394.jpg differ diff --git a/public/images/2019/05/2019051406483929.jpg b/public/images/2019/05/2019051406483929.jpg new file mode 100644 index 0000000..ec60834 Binary files /dev/null and b/public/images/2019/05/2019051406483929.jpg differ diff --git a/public/images/2019/05/2019051406592297.jpg b/public/images/2019/05/2019051406592297.jpg new file mode 100644 index 0000000..dffe3b9 Binary files /dev/null and b/public/images/2019/05/2019051406592297.jpg differ diff --git a/public/images/2019/05/2019051407200569.jpg b/public/images/2019/05/2019051407200569.jpg new file mode 100644 index 0000000..518c8f3 Binary files /dev/null and b/public/images/2019/05/2019051407200569.jpg differ diff --git a/public/images/2019/05/2019051407531632.jpg b/public/images/2019/05/2019051407531632.jpg new file mode 100644 index 0000000..4ad077c Binary files /dev/null and b/public/images/2019/05/2019051407531632.jpg differ diff --git a/public/images/2019/05/2019051408020581.jpg b/public/images/2019/05/2019051408020581.jpg new file mode 100644 index 0000000..7ff67a6 Binary files /dev/null and b/public/images/2019/05/2019051408020581.jpg differ diff --git a/public/images/2019/05/2019051408021050.jpg b/public/images/2019/05/2019051408021050.jpg new file mode 100644 index 0000000..af87c4e Binary files /dev/null and b/public/images/2019/05/2019051408021050.jpg differ diff --git a/public/images/2019/05/2019051408062596.jpg b/public/images/2019/05/2019051408062596.jpg new file mode 100644 index 0000000..6681fb8 Binary files /dev/null and b/public/images/2019/05/2019051408062596.jpg differ diff --git a/public/images/2019/05/2019051817144382.jpg b/public/images/2019/05/2019051817144382.jpg new file mode 100644 index 0000000..de62389 Binary files /dev/null and b/public/images/2019/05/2019051817144382.jpg differ diff --git a/public/images/2019/05/2019051817144785.jpg b/public/images/2019/05/2019051817144785.jpg new file mode 100644 index 0000000..39228fd Binary files /dev/null and b/public/images/2019/05/2019051817144785.jpg differ diff --git a/public/images/2019/05/2019051818094781.jpg b/public/images/2019/05/2019051818094781.jpg new file mode 100644 index 0000000..dbd459c Binary files /dev/null and b/public/images/2019/05/2019051818094781.jpg differ diff --git a/public/images/2019/05/2019051818123745.jpg b/public/images/2019/05/2019051818123745.jpg new file mode 100644 index 0000000..78bc2e9 Binary files /dev/null and b/public/images/2019/05/2019051818123745.jpg differ diff --git a/public/images/2019/05/2019051818154567.jpg b/public/images/2019/05/2019051818154567.jpg new file mode 100644 index 0000000..c99cea5 Binary files /dev/null and b/public/images/2019/05/2019051818154567.jpg differ diff --git a/public/images/2019/05/2019051818191979.jpg b/public/images/2019/05/2019051818191979.jpg new file mode 100644 index 0000000..c394e47 Binary files /dev/null and b/public/images/2019/05/2019051818191979.jpg differ diff --git a/public/images/2019/05/2019051818210131.jpg b/public/images/2019/05/2019051818210131.jpg new file mode 100644 index 0000000..99031f9 Binary files /dev/null and b/public/images/2019/05/2019051818210131.jpg differ diff --git a/public/images/2019/05/2019051818253816.jpg b/public/images/2019/05/2019051818253816.jpg new file mode 100644 index 0000000..5f9f595 Binary files /dev/null and b/public/images/2019/05/2019051818253816.jpg differ diff --git a/public/images/2019/05/2019051818284917.jpg b/public/images/2019/05/2019051818284917.jpg new file mode 100644 index 0000000..1c4146c Binary files /dev/null and b/public/images/2019/05/2019051818284917.jpg differ diff --git a/public/images/2019/05/2019051818392913.jpg b/public/images/2019/05/2019051818392913.jpg new file mode 100644 index 0000000..7f180bf Binary files /dev/null and b/public/images/2019/05/2019051818392913.jpg differ diff --git a/public/images/2019/05/2019051818531636.jpg b/public/images/2019/05/2019051818531636.jpg new file mode 100644 index 0000000..69e1de6 Binary files /dev/null and b/public/images/2019/05/2019051818531636.jpg differ diff --git a/public/images/2019/05/2019051819045635.jpg b/public/images/2019/05/2019051819045635.jpg new file mode 100644 index 0000000..2230ca6 Binary files /dev/null and b/public/images/2019/05/2019051819045635.jpg differ diff --git a/public/images/2019/05/2019051819045868.jpg b/public/images/2019/05/2019051819045868.jpg new file mode 100644 index 0000000..cf3729e Binary files /dev/null and b/public/images/2019/05/2019051819045868.jpg differ diff --git a/public/images/2019/05/2019051819050372.jpg b/public/images/2019/05/2019051819050372.jpg new file mode 100644 index 0000000..6b24136 Binary files /dev/null and b/public/images/2019/05/2019051819050372.jpg differ diff --git a/public/images/2019/05/2019051819204032.jpg b/public/images/2019/05/2019051819204032.jpg new file mode 100644 index 0000000..823069e Binary files /dev/null and b/public/images/2019/05/2019051819204032.jpg differ diff --git a/public/images/2019/05/2019051819204562.jpg b/public/images/2019/05/2019051819204562.jpg new file mode 100644 index 0000000..14fc3ba Binary files /dev/null and b/public/images/2019/05/2019051819204562.jpg differ diff --git a/public/images/2019/05/2019051819205590.jpg b/public/images/2019/05/2019051819205590.jpg new file mode 100644 index 0000000..7c09ae9 Binary files /dev/null and b/public/images/2019/05/2019051819205590.jpg differ diff --git a/public/images/2019/05/2019051819264475.jpg b/public/images/2019/05/2019051819264475.jpg new file mode 100644 index 0000000..ffb51ba Binary files /dev/null and b/public/images/2019/05/2019051819264475.jpg differ diff --git a/public/images/2019/05/2019051819371735.jpg b/public/images/2019/05/2019051819371735.jpg new file mode 100644 index 0000000..f6ab2c1 Binary files /dev/null and b/public/images/2019/05/2019051819371735.jpg differ diff --git a/public/images/2019/05/2019051819372187.jpg b/public/images/2019/05/2019051819372187.jpg new file mode 100644 index 0000000..8253194 Binary files /dev/null and b/public/images/2019/05/2019051819372187.jpg differ diff --git a/public/images/2019/05/2019051819385367.jpg b/public/images/2019/05/2019051819385367.jpg new file mode 100644 index 0000000..7ae843d Binary files /dev/null and b/public/images/2019/05/2019051819385367.jpg differ diff --git a/public/images/2019/05/2019051819432258.jpg b/public/images/2019/05/2019051819432258.jpg new file mode 100644 index 0000000..4609265 Binary files /dev/null and b/public/images/2019/05/2019051819432258.jpg differ diff --git a/public/images/2019/05/2019051819444155.jpg b/public/images/2019/05/2019051819444155.jpg new file mode 100644 index 0000000..c3e88ee Binary files /dev/null and b/public/images/2019/05/2019051819444155.jpg differ diff --git a/public/images/2019/05/2019051819515850.jpg b/public/images/2019/05/2019051819515850.jpg new file mode 100644 index 0000000..2136658 Binary files /dev/null and b/public/images/2019/05/2019051819515850.jpg differ diff --git a/public/images/2019/05/2019051819555579.jpg b/public/images/2019/05/2019051819555579.jpg new file mode 100644 index 0000000..0963ee2 Binary files /dev/null and b/public/images/2019/05/2019051819555579.jpg differ diff --git a/public/images/2019/05/2019051820015162.jpg b/public/images/2019/05/2019051820015162.jpg new file mode 100644 index 0000000..1d845aa Binary files /dev/null and b/public/images/2019/05/2019051820015162.jpg differ diff --git a/public/images/2019/05/2019051820063483.jpg b/public/images/2019/05/2019051820063483.jpg new file mode 100644 index 0000000..57b7fb9 Binary files /dev/null and b/public/images/2019/05/2019051820063483.jpg differ diff --git a/public/images/2019/05/2019051820064137.jpg b/public/images/2019/05/2019051820064137.jpg new file mode 100644 index 0000000..96ba22c Binary files /dev/null and b/public/images/2019/05/2019051820064137.jpg differ diff --git a/public/images/2019/05/2019051820064669.jpg b/public/images/2019/05/2019051820064669.jpg new file mode 100644 index 0000000..80ec190 Binary files /dev/null and b/public/images/2019/05/2019051820064669.jpg differ diff --git a/public/images/2019/05/2019051820203226.jpg b/public/images/2019/05/2019051820203226.jpg new file mode 100644 index 0000000..ae6dc6e Binary files /dev/null and b/public/images/2019/05/2019051820203226.jpg differ diff --git a/public/images/2019/05/2019051820203620.jpg b/public/images/2019/05/2019051820203620.jpg new file mode 100644 index 0000000..adda8b8 Binary files /dev/null and b/public/images/2019/05/2019051820203620.jpg differ diff --git a/public/images/2019/05/2019051820214283.jpg b/public/images/2019/05/2019051820214283.jpg new file mode 100644 index 0000000..5867399 Binary files /dev/null and b/public/images/2019/05/2019051820214283.jpg differ diff --git a/public/images/2019/05/2019051820293355.jpg b/public/images/2019/05/2019051820293355.jpg new file mode 100644 index 0000000..beb1264 Binary files /dev/null and b/public/images/2019/05/2019051820293355.jpg differ diff --git a/public/images/2019/05/2019051820293559.jpg b/public/images/2019/05/2019051820293559.jpg new file mode 100644 index 0000000..906743e Binary files /dev/null and b/public/images/2019/05/2019051820293559.jpg differ diff --git a/public/images/2019/05/2019051820583532.jpg b/public/images/2019/05/2019051820583532.jpg new file mode 100644 index 0000000..bb610f7 Binary files /dev/null and b/public/images/2019/05/2019051820583532.jpg differ diff --git a/public/images/2019/05/2019051820594178.jpg b/public/images/2019/05/2019051820594178.jpg new file mode 100644 index 0000000..038e00e Binary files /dev/null and b/public/images/2019/05/2019051820594178.jpg differ diff --git a/public/images/2019/05/2019051821092623.jpg b/public/images/2019/05/2019051821092623.jpg new file mode 100644 index 0000000..af6a349 Binary files /dev/null and b/public/images/2019/05/2019051821092623.jpg differ diff --git a/public/images/2019/05/2019051821153851.jpg b/public/images/2019/05/2019051821153851.jpg new file mode 100644 index 0000000..4859339 Binary files /dev/null and b/public/images/2019/05/2019051821153851.jpg differ diff --git a/public/images/2019/05/2019051821154097.jpg b/public/images/2019/05/2019051821154097.jpg new file mode 100644 index 0000000..771508b Binary files /dev/null and b/public/images/2019/05/2019051821154097.jpg differ diff --git a/public/images/2019/05/2019051821154311.jpg b/public/images/2019/05/2019051821154311.jpg new file mode 100644 index 0000000..b07f305 Binary files /dev/null and b/public/images/2019/05/2019051821154311.jpg differ diff --git a/public/images/2019/05/2019051821195094.jpg b/public/images/2019/05/2019051821195094.jpg new file mode 100644 index 0000000..13915bf Binary files /dev/null and b/public/images/2019/05/2019051821195094.jpg differ diff --git a/public/images/2019/05/2019051821225090.jpg b/public/images/2019/05/2019051821225090.jpg new file mode 100644 index 0000000..eddcc86 Binary files /dev/null and b/public/images/2019/05/2019051821225090.jpg differ diff --git a/public/images/2019/05/2019051821225466.jpg b/public/images/2019/05/2019051821225466.jpg new file mode 100644 index 0000000..9bbc943 Binary files /dev/null and b/public/images/2019/05/2019051821225466.jpg differ diff --git a/public/images/2019/05/2019051821422182.jpg b/public/images/2019/05/2019051821422182.jpg new file mode 100644 index 0000000..4acecc8 Binary files /dev/null and b/public/images/2019/05/2019051821422182.jpg differ diff --git a/public/images/2019/05/2019051821474615.png b/public/images/2019/05/2019051821474615.png new file mode 100644 index 0000000..4cdcfc6 Binary files /dev/null and b/public/images/2019/05/2019051821474615.png differ diff --git a/public/images/2019/05/2019052211311784.jpg b/public/images/2019/05/2019052211311784.jpg new file mode 100644 index 0000000..bd157f1 Binary files /dev/null and b/public/images/2019/05/2019052211311784.jpg differ diff --git a/public/images/2019/05/2019052708543516.jpg b/public/images/2019/05/2019052708543516.jpg new file mode 100644 index 0000000..0c1f0e4 Binary files /dev/null and b/public/images/2019/05/2019052708543516.jpg differ diff --git a/public/images/2019/05/2019052708550328.jpg b/public/images/2019/05/2019052708550328.jpg new file mode 100644 index 0000000..e28303c Binary files /dev/null and b/public/images/2019/05/2019052708550328.jpg differ diff --git a/public/images/2019/05/2019052708553042.jpg b/public/images/2019/05/2019052708553042.jpg new file mode 100644 index 0000000..da98325 Binary files /dev/null and b/public/images/2019/05/2019052708553042.jpg differ diff --git a/public/images/2019/06/2019060512012051.jpg b/public/images/2019/06/2019060512012051.jpg new file mode 100644 index 0000000..483fc93 Binary files /dev/null and b/public/images/2019/06/2019060512012051.jpg differ diff --git a/public/images/2019/06/2019060512074454.jpg b/public/images/2019/06/2019060512074454.jpg new file mode 100644 index 0000000..e3aab39 Binary files /dev/null and b/public/images/2019/06/2019060512074454.jpg differ diff --git a/public/images/2019/06/2019060512093940.jpg b/public/images/2019/06/2019060512093940.jpg new file mode 100644 index 0000000..e44cc7c Binary files /dev/null and b/public/images/2019/06/2019060512093940.jpg differ diff --git a/public/images/2019/06/2019060512135888.jpg b/public/images/2019/06/2019060512135888.jpg new file mode 100644 index 0000000..d3c8c58 Binary files /dev/null and b/public/images/2019/06/2019060512135888.jpg differ diff --git a/public/images/2019/06/2019060512145995.jpg b/public/images/2019/06/2019060512145995.jpg new file mode 100644 index 0000000..14475fc Binary files /dev/null and b/public/images/2019/06/2019060512145995.jpg differ diff --git a/public/images/2019/06/2019060512164612.jpg b/public/images/2019/06/2019060512164612.jpg new file mode 100644 index 0000000..41d8d76 Binary files /dev/null and b/public/images/2019/06/2019060512164612.jpg differ diff --git a/public/images/2019/06/2019060607035266.jpg b/public/images/2019/06/2019060607035266.jpg new file mode 100644 index 0000000..e2e9ba5 Binary files /dev/null and b/public/images/2019/06/2019060607035266.jpg differ diff --git a/public/images/2019/06/2019060607035676.jpg b/public/images/2019/06/2019060607035676.jpg new file mode 100644 index 0000000..d65f2ff Binary files /dev/null and b/public/images/2019/06/2019060607035676.jpg differ diff --git a/public/images/2019/06/2019060607083452.jpg b/public/images/2019/06/2019060607083452.jpg new file mode 100644 index 0000000..d2e709a Binary files /dev/null and b/public/images/2019/06/2019060607083452.jpg differ diff --git a/public/images/2019/06/2019060607142477.jpg b/public/images/2019/06/2019060607142477.jpg new file mode 100644 index 0000000..57086fe Binary files /dev/null and b/public/images/2019/06/2019060607142477.jpg differ diff --git a/public/images/2019/06/2019060607161615.jpg b/public/images/2019/06/2019060607161615.jpg new file mode 100644 index 0000000..cdf5735 Binary files /dev/null and b/public/images/2019/06/2019060607161615.jpg differ diff --git a/public/images/2019/06/2019060607183287.jpg b/public/images/2019/06/2019060607183287.jpg new file mode 100644 index 0000000..d376871 Binary files /dev/null and b/public/images/2019/06/2019060607183287.jpg differ diff --git a/public/images/2019/06/2019060607210889.jpg b/public/images/2019/06/2019060607210889.jpg new file mode 100644 index 0000000..2a6f113 Binary files /dev/null and b/public/images/2019/06/2019060607210889.jpg differ diff --git a/public/images/2019/06/2019060607242852.jpg b/public/images/2019/06/2019060607242852.jpg new file mode 100644 index 0000000..f2481e6 Binary files /dev/null and b/public/images/2019/06/2019060607242852.jpg differ diff --git a/public/images/2019/06/2019060607270480.jpg b/public/images/2019/06/2019060607270480.jpg new file mode 100644 index 0000000..89c6d12 Binary files /dev/null and b/public/images/2019/06/2019060607270480.jpg differ diff --git a/public/images/2019/06/2019060607290148.jpg b/public/images/2019/06/2019060607290148.jpg new file mode 100644 index 0000000..5939ec7 Binary files /dev/null and b/public/images/2019/06/2019060607290148.jpg differ diff --git a/public/images/2019/06/2019060608035798.jpg b/public/images/2019/06/2019060608035798.jpg new file mode 100644 index 0000000..8f0e91d Binary files /dev/null and b/public/images/2019/06/2019060608035798.jpg differ diff --git a/public/images/2019/06/2019060608043422.jpg b/public/images/2019/06/2019060608043422.jpg new file mode 100644 index 0000000..d9734ba Binary files /dev/null and b/public/images/2019/06/2019060608043422.jpg differ diff --git a/public/images/2019/06/2019060608094516.jpg b/public/images/2019/06/2019060608094516.jpg new file mode 100644 index 0000000..2896be1 Binary files /dev/null and b/public/images/2019/06/2019060608094516.jpg differ diff --git a/public/images/2019/06/2019060608113231.jpg b/public/images/2019/06/2019060608113231.jpg new file mode 100644 index 0000000..28b8c7e Binary files /dev/null and b/public/images/2019/06/2019060608113231.jpg differ diff --git a/public/images/2019/06/2019061004374698.jpg b/public/images/2019/06/2019061004374698.jpg new file mode 100644 index 0000000..a17aeac Binary files /dev/null and b/public/images/2019/06/2019061004374698.jpg differ diff --git a/public/images/2019/06/2019061004383676.jpg b/public/images/2019/06/2019061004383676.jpg new file mode 100644 index 0000000..23ecb54 Binary files /dev/null and b/public/images/2019/06/2019061004383676.jpg differ diff --git a/public/images/2019/06/2019061004393184.jpg b/public/images/2019/06/2019061004393184.jpg new file mode 100644 index 0000000..f139cd9 Binary files /dev/null and b/public/images/2019/06/2019061004393184.jpg differ diff --git a/public/images/2019/07/2019070506303116.jpg b/public/images/2019/07/2019070506303116.jpg new file mode 100644 index 0000000..89b327f Binary files /dev/null and b/public/images/2019/07/2019070506303116.jpg differ diff --git a/public/images/2019/07/2019071213435191.jpg b/public/images/2019/07/2019071213435191.jpg new file mode 100644 index 0000000..c3c07d8 Binary files /dev/null and b/public/images/2019/07/2019071213435191.jpg differ diff --git a/public/images/2019/07/2019071213470131.jpg b/public/images/2019/07/2019071213470131.jpg new file mode 100644 index 0000000..686e94b Binary files /dev/null and b/public/images/2019/07/2019071213470131.jpg differ diff --git a/public/images/2019/07/2019071213533026.jpg b/public/images/2019/07/2019071213533026.jpg new file mode 100644 index 0000000..2d0b945 Binary files /dev/null and b/public/images/2019/07/2019071213533026.jpg differ diff --git a/public/images/2019/07/2019071213590880.jpg b/public/images/2019/07/2019071213590880.jpg new file mode 100644 index 0000000..d28a975 Binary files /dev/null and b/public/images/2019/07/2019071213590880.jpg differ diff --git a/public/images/2019/07/2019071214005288.jpg b/public/images/2019/07/2019071214005288.jpg new file mode 100644 index 0000000..b8d4520 Binary files /dev/null and b/public/images/2019/07/2019071214005288.jpg differ diff --git a/public/images/2019/07/2019071214170923.jpg b/public/images/2019/07/2019071214170923.jpg new file mode 100644 index 0000000..5d3c495 Binary files /dev/null and b/public/images/2019/07/2019071214170923.jpg differ diff --git a/public/images/2019/07/2019071214171174.jpg b/public/images/2019/07/2019071214171174.jpg new file mode 100644 index 0000000..b64f4c0 Binary files /dev/null and b/public/images/2019/07/2019071214171174.jpg differ diff --git a/public/images/2019/07/2019071310502777.jpg b/public/images/2019/07/2019071310502777.jpg new file mode 100644 index 0000000..00b7592 Binary files /dev/null and b/public/images/2019/07/2019071310502777.jpg differ diff --git a/public/images/2019/07/2019071310542523.jpg b/public/images/2019/07/2019071310542523.jpg new file mode 100644 index 0000000..1c2424f Binary files /dev/null and b/public/images/2019/07/2019071310542523.jpg differ diff --git a/public/images/2019/07/2019071310585310.jpg b/public/images/2019/07/2019071310585310.jpg new file mode 100644 index 0000000..bf839af Binary files /dev/null and b/public/images/2019/07/2019071310585310.jpg differ diff --git a/public/images/2019/08/2019081209080360.jpg b/public/images/2019/08/2019081209080360.jpg new file mode 100644 index 0000000..a5e8f77 Binary files /dev/null and b/public/images/2019/08/2019081209080360.jpg differ diff --git a/public/images/2019/08/2019081209080689.jpg b/public/images/2019/08/2019081209080689.jpg new file mode 100644 index 0000000..93238ae Binary files /dev/null and b/public/images/2019/08/2019081209080689.jpg differ diff --git a/public/images/2020/09/2020090412164155.jpg b/public/images/2020/09/2020090412164155.jpg new file mode 100644 index 0000000..f8c0ea7 Binary files /dev/null and b/public/images/2020/09/2020090412164155.jpg differ diff --git a/public/images/2020/09/2020090412291981.jpg b/public/images/2020/09/2020090412291981.jpg new file mode 100644 index 0000000..08eb559 Binary files /dev/null and b/public/images/2020/09/2020090412291981.jpg differ diff --git a/public/images/2020/09/2020090412370067.jpg b/public/images/2020/09/2020090412370067.jpg new file mode 100644 index 0000000..398ff4a Binary files /dev/null and b/public/images/2020/09/2020090412370067.jpg differ diff --git a/public/images/2020/09/2020090412405393.jpg b/public/images/2020/09/2020090412405393.jpg new file mode 100644 index 0000000..8f871b6 Binary files /dev/null and b/public/images/2020/09/2020090412405393.jpg differ diff --git a/public/images/2020/09/2020090412432012.jpg b/public/images/2020/09/2020090412432012.jpg new file mode 100644 index 0000000..ebc615e Binary files /dev/null and b/public/images/2020/09/2020090412432012.jpg differ diff --git a/public/images/2020/09/2020090412582582.jpg b/public/images/2020/09/2020090412582582.jpg new file mode 100644 index 0000000..b33bcc6 Binary files /dev/null and b/public/images/2020/09/2020090412582582.jpg differ diff --git a/public/images/2020/09/2020090412582748.jpg b/public/images/2020/09/2020090412582748.jpg new file mode 100644 index 0000000..06728de Binary files /dev/null and b/public/images/2020/09/2020090412582748.jpg differ diff --git a/public/images/2020/09/2020090413054831.jpg b/public/images/2020/09/2020090413054831.jpg new file mode 100644 index 0000000..bca762e Binary files /dev/null and b/public/images/2020/09/2020090413054831.jpg differ diff --git a/public/images/2020/09/2020090413160041.jpg b/public/images/2020/09/2020090413160041.jpg new file mode 100644 index 0000000..cffa248 Binary files /dev/null and b/public/images/2020/09/2020090413160041.jpg differ diff --git a/public/images/2020/09/2020090413182340.jpg b/public/images/2020/09/2020090413182340.jpg new file mode 100644 index 0000000..ce342c8 Binary files /dev/null and b/public/images/2020/09/2020090413182340.jpg differ diff --git a/public/images/2020/09/2020090413365426.jpg b/public/images/2020/09/2020090413365426.jpg new file mode 100644 index 0000000..50a85dc Binary files /dev/null and b/public/images/2020/09/2020090413365426.jpg differ diff --git a/public/images/2020/09/2020090418594290.jpg b/public/images/2020/09/2020090418594290.jpg new file mode 100644 index 0000000..2ac3eb0 Binary files /dev/null and b/public/images/2020/09/2020090418594290.jpg differ diff --git a/public/images/2020/09/2020090419083649.jpg b/public/images/2020/09/2020090419083649.jpg new file mode 100644 index 0000000..98dbae6 Binary files /dev/null and b/public/images/2020/09/2020090419083649.jpg differ diff --git a/public/images/2020/09/2020090419102255.jpg b/public/images/2020/09/2020090419102255.jpg new file mode 100644 index 0000000..702e4bd Binary files /dev/null and b/public/images/2020/09/2020090419102255.jpg differ diff --git a/public/images/2020/09/2020090419142440.jpg b/public/images/2020/09/2020090419142440.jpg new file mode 100644 index 0000000..ed391e6 Binary files /dev/null and b/public/images/2020/09/2020090419142440.jpg differ diff --git a/public/images/2020/09/2020090419171074.jpg b/public/images/2020/09/2020090419171074.jpg new file mode 100644 index 0000000..2c12bde Binary files /dev/null and b/public/images/2020/09/2020090419171074.jpg differ diff --git a/public/images/2020/09/2020090419174830.jpg b/public/images/2020/09/2020090419174830.jpg new file mode 100644 index 0000000..fa64b1a Binary files /dev/null and b/public/images/2020/09/2020090419174830.jpg differ diff --git a/public/images/2020/09/2020090419234660.jpg b/public/images/2020/09/2020090419234660.jpg new file mode 100644 index 0000000..fe1dc26 Binary files /dev/null and b/public/images/2020/09/2020090419234660.jpg differ diff --git a/public/images/2020/09/2020090419235130.png b/public/images/2020/09/2020090419235130.png new file mode 100644 index 0000000..e6f0ee0 Binary files /dev/null and b/public/images/2020/09/2020090419235130.png differ diff --git a/public/images/2020/09/2020090419260539.png b/public/images/2020/09/2020090419260539.png new file mode 100644 index 0000000..88de729 Binary files /dev/null and b/public/images/2020/09/2020090419260539.png differ diff --git a/public/images/2020/09/2020090419305167.jpg b/public/images/2020/09/2020090419305167.jpg new file mode 100644 index 0000000..86083b7 Binary files /dev/null and b/public/images/2020/09/2020090419305167.jpg differ diff --git a/public/images/2020/09/2020090419362643.jpg b/public/images/2020/09/2020090419362643.jpg new file mode 100644 index 0000000..169fe6d Binary files /dev/null and b/public/images/2020/09/2020090419362643.jpg differ diff --git a/public/images/2020/09/2020090419384411.jpg b/public/images/2020/09/2020090419384411.jpg new file mode 100644 index 0000000..e0bbcc2 Binary files /dev/null and b/public/images/2020/09/2020090419384411.jpg differ diff --git a/public/images/2020/09/2020090419425564.jpg b/public/images/2020/09/2020090419425564.jpg new file mode 100644 index 0000000..9041a75 Binary files /dev/null and b/public/images/2020/09/2020090419425564.jpg differ diff --git a/public/images/2020/09/2020090419493263.jpg b/public/images/2020/09/2020090419493263.jpg new file mode 100644 index 0000000..c21c045 Binary files /dev/null and b/public/images/2020/09/2020090419493263.jpg differ diff --git a/public/images/2020/09/2020090419530721.jpg b/public/images/2020/09/2020090419530721.jpg new file mode 100644 index 0000000..af1d2e8 Binary files /dev/null and b/public/images/2020/09/2020090419530721.jpg differ diff --git a/public/images/2020/09/2020090419532852.jpg b/public/images/2020/09/2020090419532852.jpg new file mode 100644 index 0000000..c1e6a52 Binary files /dev/null and b/public/images/2020/09/2020090419532852.jpg differ diff --git a/public/images/2020/09/2020090420094090.jpg b/public/images/2020/09/2020090420094090.jpg new file mode 100644 index 0000000..4a5b852 Binary files /dev/null and b/public/images/2020/09/2020090420094090.jpg differ diff --git a/public/images/2020/09/2020090420111684.jpg b/public/images/2020/09/2020090420111684.jpg new file mode 100644 index 0000000..b9f6cda Binary files /dev/null and b/public/images/2020/09/2020090420111684.jpg differ diff --git a/public/images/2020/09/2020090420194343.jpg b/public/images/2020/09/2020090420194343.jpg new file mode 100644 index 0000000..1cf1ba7 Binary files /dev/null and b/public/images/2020/09/2020090420194343.jpg differ diff --git a/public/images/2020/09/2020090420223787.jpg b/public/images/2020/09/2020090420223787.jpg new file mode 100644 index 0000000..e4abc83 Binary files /dev/null and b/public/images/2020/09/2020090420223787.jpg differ diff --git a/public/images/2020/09/2020090420290983.jpg b/public/images/2020/09/2020090420290983.jpg new file mode 100644 index 0000000..1b544b9 Binary files /dev/null and b/public/images/2020/09/2020090420290983.jpg differ diff --git a/public/images/2020/09/2020090420550333.jpg b/public/images/2020/09/2020090420550333.jpg new file mode 100644 index 0000000..647561c Binary files /dev/null and b/public/images/2020/09/2020090420550333.jpg differ diff --git a/public/images/2020/09/2020090420592363.jpg b/public/images/2020/09/2020090420592363.jpg new file mode 100644 index 0000000..ea0f02c Binary files /dev/null and b/public/images/2020/09/2020090420592363.jpg differ diff --git a/public/images/2020/09/2020090421041564.jpg b/public/images/2020/09/2020090421041564.jpg new file mode 100644 index 0000000..b29fd17 Binary files /dev/null and b/public/images/2020/09/2020090421041564.jpg differ diff --git a/public/images/2020/09/2020090421041838.jpg b/public/images/2020/09/2020090421041838.jpg new file mode 100644 index 0000000..b02f2c3 Binary files /dev/null and b/public/images/2020/09/2020090421041838.jpg differ diff --git a/public/images/2020/09/2020090421113833.jpg b/public/images/2020/09/2020090421113833.jpg new file mode 100644 index 0000000..e18a347 Binary files /dev/null and b/public/images/2020/09/2020090421113833.jpg differ diff --git a/public/images/2020/09/2020090421160773.jpg b/public/images/2020/09/2020090421160773.jpg new file mode 100644 index 0000000..941f9ca Binary files /dev/null and b/public/images/2020/09/2020090421160773.jpg differ diff --git a/public/images/2020/09/2020090421241938.jpg b/public/images/2020/09/2020090421241938.jpg new file mode 100644 index 0000000..1dc0dcf Binary files /dev/null and b/public/images/2020/09/2020090421241938.jpg differ diff --git a/public/images/2020/09/2020090421450493.jpg b/public/images/2020/09/2020090421450493.jpg new file mode 100644 index 0000000..afa73c8 Binary files /dev/null and b/public/images/2020/09/2020090421450493.jpg differ diff --git a/public/images/2020/09/2020090421472732.jpg b/public/images/2020/09/2020090421472732.jpg new file mode 100644 index 0000000..2b519b3 Binary files /dev/null and b/public/images/2020/09/2020090421472732.jpg differ diff --git a/public/images/2020/09/2020090421492124.jpg b/public/images/2020/09/2020090421492124.jpg new file mode 100644 index 0000000..d27fac2 Binary files /dev/null and b/public/images/2020/09/2020090421492124.jpg differ diff --git a/public/images/2020/09/2020090421522439.jpg b/public/images/2020/09/2020090421522439.jpg new file mode 100644 index 0000000..de4f946 Binary files /dev/null and b/public/images/2020/09/2020090421522439.jpg differ diff --git a/public/images/2020/09/2020090422023879.jpg b/public/images/2020/09/2020090422023879.jpg new file mode 100644 index 0000000..c81ab92 Binary files /dev/null and b/public/images/2020/09/2020090422023879.jpg differ diff --git a/public/images/2020/09/2020090422024176.jpg b/public/images/2020/09/2020090422024176.jpg new file mode 100644 index 0000000..736d772 Binary files /dev/null and b/public/images/2020/09/2020090422024176.jpg differ diff --git a/public/images/2020/09/2020090422091233.jpg b/public/images/2020/09/2020090422091233.jpg new file mode 100644 index 0000000..7624e26 Binary files /dev/null and b/public/images/2020/09/2020090422091233.jpg differ diff --git a/public/images/2020/09/2020090422164876.jpg b/public/images/2020/09/2020090422164876.jpg new file mode 100644 index 0000000..625b47d Binary files /dev/null and b/public/images/2020/09/2020090422164876.jpg differ diff --git a/public/images/2020/09/2020090422185883.jpg b/public/images/2020/09/2020090422185883.jpg new file mode 100644 index 0000000..8997481 Binary files /dev/null and b/public/images/2020/09/2020090422185883.jpg differ diff --git a/public/images/2020/09/2020090422270141.jpg b/public/images/2020/09/2020090422270141.jpg new file mode 100644 index 0000000..0c61022 Binary files /dev/null and b/public/images/2020/09/2020090422270141.jpg differ diff --git a/public/images/2020/09/2020090422290185.jpg b/public/images/2020/09/2020090422290185.jpg new file mode 100644 index 0000000..e9cdeed Binary files /dev/null and b/public/images/2020/09/2020090422290185.jpg differ diff --git a/public/images/2020/09/2020090422293440.jpg b/public/images/2020/09/2020090422293440.jpg new file mode 100644 index 0000000..35a3edd Binary files /dev/null and b/public/images/2020/09/2020090422293440.jpg differ diff --git a/public/images/2020/09/2020090422361856.jpg b/public/images/2020/09/2020090422361856.jpg new file mode 100644 index 0000000..9ffc640 Binary files /dev/null and b/public/images/2020/09/2020090422361856.jpg differ diff --git a/public/images/2020/09/2020090422395473.jpg b/public/images/2020/09/2020090422395473.jpg new file mode 100644 index 0000000..13b634d Binary files /dev/null and b/public/images/2020/09/2020090422395473.jpg differ diff --git a/public/images/2020/09/2020090422454021.jpg b/public/images/2020/09/2020090422454021.jpg new file mode 100644 index 0000000..d261f3a Binary files /dev/null and b/public/images/2020/09/2020090422454021.jpg differ diff --git a/public/images/2020/09/2020090423034580.jpg b/public/images/2020/09/2020090423034580.jpg new file mode 100644 index 0000000..749e9b8 Binary files /dev/null and b/public/images/2020/09/2020090423034580.jpg differ diff --git a/public/images/2020/09/2020090423035126.jpg b/public/images/2020/09/2020090423035126.jpg new file mode 100644 index 0000000..80421f6 Binary files /dev/null and b/public/images/2020/09/2020090423035126.jpg differ diff --git a/public/images/2020/09/2020092003563700.jpg b/public/images/2020/09/2020092003563700.jpg new file mode 100644 index 0000000..1280da3 Binary files /dev/null and b/public/images/2020/09/2020092003563700.jpg differ diff --git a/public/images/2020/11/2020111616102568.jpg b/public/images/2020/11/2020111616102568.jpg new file mode 100644 index 0000000..ec6426d Binary files /dev/null and b/public/images/2020/11/2020111616102568.jpg differ diff --git a/public/images/2020/11/2020111616303232.jpg b/public/images/2020/11/2020111616303232.jpg new file mode 100644 index 0000000..7a5be6f Binary files /dev/null and b/public/images/2020/11/2020111616303232.jpg differ diff --git a/public/images/2020/11/2020111616333446.jpg b/public/images/2020/11/2020111616333446.jpg new file mode 100644 index 0000000..02a7193 Binary files /dev/null and b/public/images/2020/11/2020111616333446.jpg differ diff --git a/public/images/2020/11/2020111617164786.jpg b/public/images/2020/11/2020111617164786.jpg new file mode 100644 index 0000000..925d0d1 Binary files /dev/null and b/public/images/2020/11/2020111617164786.jpg differ diff --git a/public/images/2020/11/2020111617250726.jpg b/public/images/2020/11/2020111617250726.jpg new file mode 100644 index 0000000..fa42ffc Binary files /dev/null and b/public/images/2020/11/2020111617250726.jpg differ diff --git a/public/images/2020/11/2020111617282542.jpg b/public/images/2020/11/2020111617282542.jpg new file mode 100644 index 0000000..f206991 Binary files /dev/null and b/public/images/2020/11/2020111617282542.jpg differ diff --git a/public/images/2020/11/2020111816301059.jpg b/public/images/2020/11/2020111816301059.jpg new file mode 100644 index 0000000..b00355e Binary files /dev/null and b/public/images/2020/11/2020111816301059.jpg differ diff --git a/public/images/2020/11/2020111816314240.jpg b/public/images/2020/11/2020111816314240.jpg new file mode 100644 index 0000000..7f60bfd Binary files /dev/null and b/public/images/2020/11/2020111816314240.jpg differ diff --git a/public/images/2020/11/2020111917590021.jpg b/public/images/2020/11/2020111917590021.jpg new file mode 100644 index 0000000..c38a1d1 Binary files /dev/null and b/public/images/2020/11/2020111917590021.jpg differ diff --git a/public/images/2020/11/2020111918020680.jpg b/public/images/2020/11/2020111918020680.jpg new file mode 100644 index 0000000..adab524 Binary files /dev/null and b/public/images/2020/11/2020111918020680.jpg differ diff --git a/public/images/2020/11/2020111918021296.jpg b/public/images/2020/11/2020111918021296.jpg new file mode 100644 index 0000000..46fd0ec Binary files /dev/null and b/public/images/2020/11/2020111918021296.jpg differ diff --git a/public/images/2020/11/2020111918234988.jpg b/public/images/2020/11/2020111918234988.jpg new file mode 100644 index 0000000..69757fe Binary files /dev/null and b/public/images/2020/11/2020111918234988.jpg differ diff --git a/public/images/2020/11/2020111918235219.jpg b/public/images/2020/11/2020111918235219.jpg new file mode 100644 index 0000000..3778623 Binary files /dev/null and b/public/images/2020/11/2020111918235219.jpg differ diff --git a/public/images/2020/11/2020111918235837.jpg b/public/images/2020/11/2020111918235837.jpg new file mode 100644 index 0000000..677e268 Binary files /dev/null and b/public/images/2020/11/2020111918235837.jpg differ diff --git a/public/images/2020/11/2020111918513387.jpg b/public/images/2020/11/2020111918513387.jpg new file mode 100644 index 0000000..ed81089 Binary files /dev/null and b/public/images/2020/11/2020111918513387.jpg differ diff --git a/public/images/2020/11/2020111918513562.jpg b/public/images/2020/11/2020111918513562.jpg new file mode 100644 index 0000000..4a5f7ff Binary files /dev/null and b/public/images/2020/11/2020111918513562.jpg differ diff --git a/public/images/2020/11/2020111918513875.jpg b/public/images/2020/11/2020111918513875.jpg new file mode 100644 index 0000000..b756ad2 Binary files /dev/null and b/public/images/2020/11/2020111918513875.jpg differ diff --git a/public/images/2020/11/2020111919141549.jpg b/public/images/2020/11/2020111919141549.jpg new file mode 100644 index 0000000..2afc00e Binary files /dev/null and b/public/images/2020/11/2020111919141549.jpg differ diff --git a/public/images/2020/11/2020111919163265.jpg b/public/images/2020/11/2020111919163265.jpg new file mode 100644 index 0000000..ee9148a Binary files /dev/null and b/public/images/2020/11/2020111919163265.jpg differ diff --git a/public/images/2020/11/2020111919171012.jpg b/public/images/2020/11/2020111919171012.jpg new file mode 100644 index 0000000..9f4ef7f Binary files /dev/null and b/public/images/2020/11/2020111919171012.jpg differ diff --git a/public/images/2020/12/2020121415154130.jpg b/public/images/2020/12/2020121415154130.jpg new file mode 100644 index 0000000..503a0b5 Binary files /dev/null and b/public/images/2020/12/2020121415154130.jpg differ diff --git a/public/images/2020/12/2020121415163788.jpg b/public/images/2020/12/2020121415163788.jpg new file mode 100644 index 0000000..ddc9b94 Binary files /dev/null and b/public/images/2020/12/2020121415163788.jpg differ diff --git a/public/images/2020/12/2020121415193370.jpg b/public/images/2020/12/2020121415193370.jpg new file mode 100644 index 0000000..ddc9b94 Binary files /dev/null and b/public/images/2020/12/2020121415193370.jpg differ diff --git a/public/images/2020/12/2020121415223435.jpg b/public/images/2020/12/2020121415223435.jpg new file mode 100644 index 0000000..a14bf17 Binary files /dev/null and b/public/images/2020/12/2020121415223435.jpg differ diff --git a/public/images/2022/02/2022022821353669.jpg b/public/images/2022/02/2022022821353669.jpg new file mode 100644 index 0000000..728fbf1 Binary files /dev/null and b/public/images/2022/02/2022022821353669.jpg differ diff --git a/public/images/2022/02/2022022821361976.jpg b/public/images/2022/02/2022022821361976.jpg new file mode 100644 index 0000000..b9bdf9a Binary files /dev/null and b/public/images/2022/02/2022022821361976.jpg differ diff --git a/public/images/2022/02/2022022821371261.jpg b/public/images/2022/02/2022022821371261.jpg new file mode 100644 index 0000000..ceca7b5 Binary files /dev/null and b/public/images/2022/02/2022022821371261.jpg differ diff --git a/public/images/2022/02/2022022821542418.jpg b/public/images/2022/02/2022022821542418.jpg new file mode 100644 index 0000000..4e84845 Binary files /dev/null and b/public/images/2022/02/2022022821542418.jpg differ diff --git a/public/images/2022/04/2022041519522100.jpg b/public/images/2022/04/2022041519522100.jpg new file mode 100644 index 0000000..ac3146b Binary files /dev/null and b/public/images/2022/04/2022041519522100.jpg differ diff --git a/public/images/2022/04/2022041519595100.jpg b/public/images/2022/04/2022041519595100.jpg new file mode 100644 index 0000000..fe3e21f Binary files /dev/null and b/public/images/2022/04/2022041519595100.jpg differ diff --git a/public/images/2022/04/2022042003433200.jpg b/public/images/2022/04/2022042003433200.jpg new file mode 100644 index 0000000..105d861 Binary files /dev/null and b/public/images/2022/04/2022042003433200.jpg differ diff --git a/public/images/2023/11/2023112805413770.jpg b/public/images/2023/11/2023112805413770.jpg new file mode 100644 index 0000000..3af37d2 Binary files /dev/null and b/public/images/2023/11/2023112805413770.jpg differ diff --git a/public/images/2023/11/2023112805465597.jpg b/public/images/2023/11/2023112805465597.jpg new file mode 100644 index 0000000..c9bbd1d Binary files /dev/null and b/public/images/2023/11/2023112805465597.jpg differ diff --git a/public/images/2023/11/2023112805523272.jpg b/public/images/2023/11/2023112805523272.jpg new file mode 100644 index 0000000..e03147f Binary files /dev/null and b/public/images/2023/11/2023112805523272.jpg differ diff --git a/public/images/2023/11/2023112806031098.jpg b/public/images/2023/11/2023112806031098.jpg new file mode 100644 index 0000000..fa96bab Binary files /dev/null and b/public/images/2023/11/2023112806031098.jpg differ diff --git a/public/images/2023/11/2023112806104737.jpg b/public/images/2023/11/2023112806104737.jpg new file mode 100644 index 0000000..64ded79 Binary files /dev/null and b/public/images/2023/11/2023112806104737.jpg differ diff --git a/public/images/2023/11/2023112806153845.jpg b/public/images/2023/11/2023112806153845.jpg new file mode 100644 index 0000000..602d0a9 Binary files /dev/null and b/public/images/2023/11/2023112806153845.jpg differ diff --git a/public/images/2023/11/2023112806215481.jpg b/public/images/2023/11/2023112806215481.jpg new file mode 100644 index 0000000..c2d5580 Binary files /dev/null and b/public/images/2023/11/2023112806215481.jpg differ diff --git a/public/images/2023/11/2023112806262013.jpg b/public/images/2023/11/2023112806262013.jpg new file mode 100644 index 0000000..6d634c2 Binary files /dev/null and b/public/images/2023/11/2023112806262013.jpg differ diff --git a/public/images/2023/12/2023120116264095.jpg b/public/images/2023/12/2023120116264095.jpg new file mode 100644 index 0000000..4016043 Binary files /dev/null and b/public/images/2023/12/2023120116264095.jpg differ diff --git a/public/images/2023/12/2023120116301766.jpg b/public/images/2023/12/2023120116301766.jpg new file mode 100644 index 0000000..6251fd6 Binary files /dev/null and b/public/images/2023/12/2023120116301766.jpg differ diff --git a/public/images/2023/12/2023120213055451.jpg b/public/images/2023/12/2023120213055451.jpg new file mode 100644 index 0000000..365c6d1 Binary files /dev/null and b/public/images/2023/12/2023120213055451.jpg differ diff --git a/public/images/2023/12/2023120213252111.jpg b/public/images/2023/12/2023120213252111.jpg new file mode 100644 index 0000000..8582ab9 Binary files /dev/null and b/public/images/2023/12/2023120213252111.jpg differ diff --git a/public/images/2023/12/2023120213392110.jpg b/public/images/2023/12/2023120213392110.jpg new file mode 100644 index 0000000..26d0f5a Binary files /dev/null and b/public/images/2023/12/2023120213392110.jpg differ diff --git a/public/images/2023/12/2023120213404421.jpg b/public/images/2023/12/2023120213404421.jpg new file mode 100644 index 0000000..9ebb93c Binary files /dev/null and b/public/images/2023/12/2023120213404421.jpg differ diff --git a/public/images/2023/12/2023120213463189.png b/public/images/2023/12/2023120213463189.png new file mode 100644 index 0000000..17c307b Binary files /dev/null and b/public/images/2023/12/2023120213463189.png differ diff --git a/public/images/2023/12/2023120214030421.jpg b/public/images/2023/12/2023120214030421.jpg new file mode 100644 index 0000000..6a348ad Binary files /dev/null and b/public/images/2023/12/2023120214030421.jpg differ diff --git a/public/images/2023/12/2023120214134645.png b/public/images/2023/12/2023120214134645.png new file mode 100644 index 0000000..ab816c0 Binary files /dev/null and b/public/images/2023/12/2023120214134645.png differ diff --git a/public/images/2023/12/2023120214181317.jpg b/public/images/2023/12/2023120214181317.jpg new file mode 100644 index 0000000..403977f Binary files /dev/null and b/public/images/2023/12/2023120214181317.jpg differ diff --git a/public/images/2023/12/2023120214201152.jpg b/public/images/2023/12/2023120214201152.jpg new file mode 100644 index 0000000..304b5f9 Binary files /dev/null and b/public/images/2023/12/2023120214201152.jpg differ diff --git a/public/images/2023/12/2023120214235774.jpg b/public/images/2023/12/2023120214235774.jpg new file mode 100644 index 0000000..7642f9e Binary files /dev/null and b/public/images/2023/12/2023120214235774.jpg differ diff --git a/public/images/2023/12/2023120214271365.jpg b/public/images/2023/12/2023120214271365.jpg new file mode 100644 index 0000000..8c1702e Binary files /dev/null and b/public/images/2023/12/2023120214271365.jpg differ diff --git a/public/images/2023/12/2023120214292360.jpg b/public/images/2023/12/2023120214292360.jpg new file mode 100644 index 0000000..f62cd7b Binary files /dev/null and b/public/images/2023/12/2023120214292360.jpg differ diff --git a/public/images/2023/12/2023120215051513.jpg b/public/images/2023/12/2023120215051513.jpg new file mode 100644 index 0000000..30b6f84 Binary files /dev/null and b/public/images/2023/12/2023120215051513.jpg differ diff --git a/public/images/2023/12/2023120215075156.jpg b/public/images/2023/12/2023120215075156.jpg new file mode 100644 index 0000000..0844bf1 Binary files /dev/null and b/public/images/2023/12/2023120215075156.jpg differ diff --git a/public/images/2023/12/2023120215112245.jpg b/public/images/2023/12/2023120215112245.jpg new file mode 100644 index 0000000..cd4aa44 Binary files /dev/null and b/public/images/2023/12/2023120215112245.jpg differ diff --git a/public/images/2023/12/2023120215124283.jpg b/public/images/2023/12/2023120215124283.jpg new file mode 100644 index 0000000..b430684 Binary files /dev/null and b/public/images/2023/12/2023120215124283.jpg differ diff --git a/public/images/2023/12/2023120215143345.jpg b/public/images/2023/12/2023120215143345.jpg new file mode 100644 index 0000000..cc26abb Binary files /dev/null and b/public/images/2023/12/2023120215143345.jpg differ diff --git a/public/images/2023/12/2023120305291357.jpg b/public/images/2023/12/2023120305291357.jpg new file mode 100644 index 0000000..90a40e7 Binary files /dev/null and b/public/images/2023/12/2023120305291357.jpg differ diff --git a/public/images/2023/12/2023120306242912.jpg b/public/images/2023/12/2023120306242912.jpg new file mode 100644 index 0000000..c63b6e5 Binary files /dev/null and b/public/images/2023/12/2023120306242912.jpg differ diff --git a/public/images/2023/12/2023120306243223.jpg b/public/images/2023/12/2023120306243223.jpg new file mode 100644 index 0000000..d2ae183 Binary files /dev/null and b/public/images/2023/12/2023120306243223.jpg differ diff --git a/public/images/2023/12/2023120306305570.jpg b/public/images/2023/12/2023120306305570.jpg new file mode 100644 index 0000000..6766cdd Binary files /dev/null and b/public/images/2023/12/2023120306305570.jpg differ diff --git a/public/images/2023/12/2023120306341521.jpg b/public/images/2023/12/2023120306341521.jpg new file mode 100644 index 0000000..5b4aab5 Binary files /dev/null and b/public/images/2023/12/2023120306341521.jpg differ diff --git a/public/images/2023/12/2023120306382895.jpg b/public/images/2023/12/2023120306382895.jpg new file mode 100644 index 0000000..1479b1e Binary files /dev/null and b/public/images/2023/12/2023120306382895.jpg differ diff --git a/public/images/2023/12/2023120306435871.jpg b/public/images/2023/12/2023120306435871.jpg new file mode 100644 index 0000000..971e3d0 Binary files /dev/null and b/public/images/2023/12/2023120306435871.jpg differ diff --git a/public/images/2023/12/2023120306565488.jpg b/public/images/2023/12/2023120306565488.jpg new file mode 100644 index 0000000..c4936e7 Binary files /dev/null and b/public/images/2023/12/2023120306565488.jpg differ diff --git a/public/images/2023/12/2023120307003245.jpg b/public/images/2023/12/2023120307003245.jpg new file mode 100644 index 0000000..fbf41ac Binary files /dev/null and b/public/images/2023/12/2023120307003245.jpg differ diff --git a/public/images/2023/12/2023120310270529.jpg b/public/images/2023/12/2023120310270529.jpg new file mode 100644 index 0000000..15ab601 Binary files /dev/null and b/public/images/2023/12/2023120310270529.jpg differ diff --git a/public/images/2023/12/2023120310325235.jpg b/public/images/2023/12/2023120310325235.jpg new file mode 100644 index 0000000..5036e82 Binary files /dev/null and b/public/images/2023/12/2023120310325235.jpg differ diff --git a/public/images/2023/12/2023120310341644.jpg b/public/images/2023/12/2023120310341644.jpg new file mode 100644 index 0000000..65bee82 Binary files /dev/null and b/public/images/2023/12/2023120310341644.jpg differ diff --git a/public/images/2024/01/2024012605013787.jpg b/public/images/2024/01/2024012605013787.jpg new file mode 100644 index 0000000..8f6d834 Binary files /dev/null and b/public/images/2024/01/2024012605013787.jpg differ diff --git a/public/images/2024/04/2024040719182210.jpg b/public/images/2024/04/2024040719182210.jpg new file mode 100644 index 0000000..1be7416 Binary files /dev/null and b/public/images/2024/04/2024040719182210.jpg differ diff --git a/public/images/2024/04/2024040719182310.jpg b/public/images/2024/04/2024040719182310.jpg new file mode 100644 index 0000000..0b91e3f Binary files /dev/null and b/public/images/2024/04/2024040719182310.jpg differ diff --git a/public/images/2024/04/2024040719182344.jpg b/public/images/2024/04/2024040719182344.jpg new file mode 100644 index 0000000..155df53 Binary files /dev/null and b/public/images/2024/04/2024040719182344.jpg differ diff --git a/public/images/2024/04/2024040719234718.jpg b/public/images/2024/04/2024040719234718.jpg new file mode 100644 index 0000000..8255875 Binary files /dev/null and b/public/images/2024/04/2024040719234718.jpg differ diff --git a/public/images/2024/04/2024040719244778.jpg b/public/images/2024/04/2024040719244778.jpg new file mode 100644 index 0000000..2d8f269 Binary files /dev/null and b/public/images/2024/04/2024040719244778.jpg differ diff --git a/public/images/2024/04/2024040719297778.jpg b/public/images/2024/04/2024040719297778.jpg new file mode 100644 index 0000000..e0bc11f Binary files /dev/null and b/public/images/2024/04/2024040719297778.jpg differ diff --git a/public/images/2024/04/2024041123031132.jpg b/public/images/2024/04/2024041123031132.jpg new file mode 100644 index 0000000..5608da4 Binary files /dev/null and b/public/images/2024/04/2024041123031132.jpg differ diff --git a/public/images/2024/04/2024041123031192.jpg b/public/images/2024/04/2024041123031192.jpg new file mode 100644 index 0000000..68aaae3 Binary files /dev/null and b/public/images/2024/04/2024041123031192.jpg differ diff --git a/public/images/2024/04/2024041123031232.jpg b/public/images/2024/04/2024041123031232.jpg new file mode 100644 index 0000000..5a29615 Binary files /dev/null and b/public/images/2024/04/2024041123031232.jpg differ diff --git a/public/images/2024/04/2024041405050511.png b/public/images/2024/04/2024041405050511.png new file mode 100644 index 0000000..9ef21fe Binary files /dev/null and b/public/images/2024/04/2024041405050511.png differ diff --git a/public/images/2024/04/2024041510373084.jpg b/public/images/2024/04/2024041510373084.jpg new file mode 100644 index 0000000..5ec2c45 Binary files /dev/null and b/public/images/2024/04/2024041510373084.jpg differ diff --git a/public/images/2024/04/2024041513050511.jpg b/public/images/2024/04/2024041513050511.jpg new file mode 100644 index 0000000..264a0e5 Binary files /dev/null and b/public/images/2024/04/2024041513050511.jpg differ diff --git a/public/images/2024/04/2024041519194400.jpg b/public/images/2024/04/2024041519194400.jpg new file mode 100644 index 0000000..86c497f Binary files /dev/null and b/public/images/2024/04/2024041519194400.jpg differ diff --git a/public/images/2024/04/2024041519203200.jpg b/public/images/2024/04/2024041519203200.jpg new file mode 100644 index 0000000..9d944dc Binary files /dev/null and b/public/images/2024/04/2024041519203200.jpg differ diff --git a/public/images/2024/04/2024041519283300.jpg b/public/images/2024/04/2024041519283300.jpg new file mode 100644 index 0000000..975f1d5 Binary files /dev/null and b/public/images/2024/04/2024041519283300.jpg differ diff --git a/public/images/2024/04/2024041519325100.jpg b/public/images/2024/04/2024041519325100.jpg new file mode 100644 index 0000000..0f1db69 Binary files /dev/null and b/public/images/2024/04/2024041519325100.jpg differ diff --git a/public/images/2024/04/2024041519344400.jpg b/public/images/2024/04/2024041519344400.jpg new file mode 100644 index 0000000..c452256 Binary files /dev/null and b/public/images/2024/04/2024041519344400.jpg differ diff --git a/public/images/2024/04/2024041519362100.jpg b/public/images/2024/04/2024041519362100.jpg new file mode 100644 index 0000000..afb9a18 Binary files /dev/null and b/public/images/2024/04/2024041519362100.jpg differ diff --git a/public/images/2024/04/2024041519424200.jpg b/public/images/2024/04/2024041519424200.jpg new file mode 100644 index 0000000..1d627e7 Binary files /dev/null and b/public/images/2024/04/2024041519424200.jpg differ diff --git a/public/images/2024/04/2024041519434100.jpg b/public/images/2024/04/2024041519434100.jpg new file mode 100644 index 0000000..80e0244 Binary files /dev/null and b/public/images/2024/04/2024041519434100.jpg differ diff --git a/public/images/2024/04/2024041519445600.jpg b/public/images/2024/04/2024041519445600.jpg new file mode 100644 index 0000000..f9cc769 Binary files /dev/null and b/public/images/2024/04/2024041519445600.jpg differ diff --git a/public/images/2024/04/2024041519462300.jpg b/public/images/2024/04/2024041519462300.jpg new file mode 100644 index 0000000..5d92173 Binary files /dev/null and b/public/images/2024/04/2024041519462300.jpg differ diff --git a/public/images/2024/04/2024041519475300.jpg b/public/images/2024/04/2024041519475300.jpg new file mode 100644 index 0000000..8c1c63c Binary files /dev/null and b/public/images/2024/04/2024041519475300.jpg differ diff --git a/public/images/2024/04/2024041520022600.jpg b/public/images/2024/04/2024041520022600.jpg new file mode 100644 index 0000000..f1c8509 Binary files /dev/null and b/public/images/2024/04/2024041520022600.jpg differ diff --git a/public/images/2024/04/2024041520054100.jpg b/public/images/2024/04/2024041520054100.jpg new file mode 100644 index 0000000..5c41fb3 Binary files /dev/null and b/public/images/2024/04/2024041520054100.jpg differ diff --git a/public/images/2024/04/2024041520111500.jpg b/public/images/2024/04/2024041520111500.jpg new file mode 100644 index 0000000..36a5560 Binary files /dev/null and b/public/images/2024/04/2024041520111500.jpg differ diff --git a/public/images/2024/04/2024041520204000.jpg b/public/images/2024/04/2024041520204000.jpg new file mode 100644 index 0000000..c32eedd Binary files /dev/null and b/public/images/2024/04/2024041520204000.jpg differ diff --git a/public/images/2024/04/2024041520232700.jpg b/public/images/2024/04/2024041520232700.jpg new file mode 100644 index 0000000..21f19c0 Binary files /dev/null and b/public/images/2024/04/2024041520232700.jpg differ diff --git a/public/images/2024/04/2024041520255800.jpg b/public/images/2024/04/2024041520255800.jpg new file mode 100644 index 0000000..bfbf72b Binary files /dev/null and b/public/images/2024/04/2024041520255800.jpg differ diff --git a/public/images/2024/04/2024041520433700.jpg b/public/images/2024/04/2024041520433700.jpg new file mode 100644 index 0000000..dd83128 Binary files /dev/null and b/public/images/2024/04/2024041520433700.jpg differ diff --git a/public/images/2024/04/2024041520451500.jpg b/public/images/2024/04/2024041520451500.jpg new file mode 100644 index 0000000..c2821e3 Binary files /dev/null and b/public/images/2024/04/2024041520451500.jpg differ diff --git a/public/images/2024/04/2024041520472600.jpg b/public/images/2024/04/2024041520472600.jpg new file mode 100644 index 0000000..c6d45cb Binary files /dev/null and b/public/images/2024/04/2024041520472600.jpg differ diff --git a/public/images/2024/04/2024041520494100.jpg b/public/images/2024/04/2024041520494100.jpg new file mode 100644 index 0000000..9ce56e9 Binary files /dev/null and b/public/images/2024/04/2024041520494100.jpg differ diff --git a/public/images/2024/04/2024041520520400.jpg b/public/images/2024/04/2024041520520400.jpg new file mode 100644 index 0000000..2c4c368 Binary files /dev/null and b/public/images/2024/04/2024041520520400.jpg differ diff --git a/public/images/2024/04/2024041520534000.jpg b/public/images/2024/04/2024041520534000.jpg new file mode 100644 index 0000000..72d87e2 Binary files /dev/null and b/public/images/2024/04/2024041520534000.jpg differ diff --git a/public/images/2024/04/2024041620281800.jpg b/public/images/2024/04/2024041620281800.jpg new file mode 100644 index 0000000..dc9ba01 Binary files /dev/null and b/public/images/2024/04/2024041620281800.jpg differ diff --git a/public/images/2024/04/2024041620334700.jpg b/public/images/2024/04/2024041620334700.jpg new file mode 100644 index 0000000..79aca22 Binary files /dev/null and b/public/images/2024/04/2024041620334700.jpg differ diff --git a/public/images/2024/04/2024041620352400.jpg b/public/images/2024/04/2024041620352400.jpg new file mode 100644 index 0000000..d2a659d Binary files /dev/null and b/public/images/2024/04/2024041620352400.jpg differ diff --git a/public/images/2024/04/2024041620355700.jpg b/public/images/2024/04/2024041620355700.jpg new file mode 100644 index 0000000..a802710 Binary files /dev/null and b/public/images/2024/04/2024041620355700.jpg differ diff --git a/public/images/2024/04/2024041620364900.jpg b/public/images/2024/04/2024041620364900.jpg new file mode 100644 index 0000000..429ed81 Binary files /dev/null and b/public/images/2024/04/2024041620364900.jpg differ diff --git a/public/images/2024/04/2024041620373800.jpg b/public/images/2024/04/2024041620373800.jpg new file mode 100644 index 0000000..a681fff Binary files /dev/null and b/public/images/2024/04/2024041620373800.jpg differ diff --git a/public/images/2024/04/2024041620384100.jpg b/public/images/2024/04/2024041620384100.jpg new file mode 100644 index 0000000..3fdf278 Binary files /dev/null and b/public/images/2024/04/2024041620384100.jpg differ diff --git a/public/images/2024/04/2024041620404500.jpg b/public/images/2024/04/2024041620404500.jpg new file mode 100644 index 0000000..5167285 Binary files /dev/null and b/public/images/2024/04/2024041620404500.jpg differ diff --git a/public/images/2024/04/2024041620434200.jpg b/public/images/2024/04/2024041620434200.jpg new file mode 100644 index 0000000..a2fd4e1 Binary files /dev/null and b/public/images/2024/04/2024041620434200.jpg differ diff --git a/public/images/2024/04/2024041620445700.jpg b/public/images/2024/04/2024041620445700.jpg new file mode 100644 index 0000000..41da9e4 Binary files /dev/null and b/public/images/2024/04/2024041620445700.jpg differ diff --git a/public/images/2024/04/2024041620473400.jpg b/public/images/2024/04/2024041620473400.jpg new file mode 100644 index 0000000..41c2dc5 Binary files /dev/null and b/public/images/2024/04/2024041620473400.jpg differ diff --git a/public/images/2024/05/2024052911583500.jpg b/public/images/2024/05/2024052911583500.jpg new file mode 100644 index 0000000..1a65bce Binary files /dev/null and b/public/images/2024/05/2024052911583500.jpg differ diff --git a/public/images/2024/05/2024052912154100.jpg b/public/images/2024/05/2024052912154100.jpg new file mode 100644 index 0000000..60a6225 Binary files /dev/null and b/public/images/2024/05/2024052912154100.jpg differ diff --git a/public/images/2024/05/2024052912190600.jpg b/public/images/2024/05/2024052912190600.jpg new file mode 100644 index 0000000..cd5fa04 Binary files /dev/null and b/public/images/2024/05/2024052912190600.jpg differ diff --git a/public/images/categories/article.jpg b/public/images/categories/article.jpg new file mode 100644 index 0000000..aca9ecf Binary files /dev/null and b/public/images/categories/article.jpg differ diff --git a/public/images/categories/coding.jpg b/public/images/categories/coding.jpg new file mode 100644 index 0000000..4fae5a7 Binary files /dev/null and b/public/images/categories/coding.jpg differ diff --git a/public/images/categories/gossip.jpg b/public/images/categories/gossip.jpg new file mode 100644 index 0000000..bc6fa23 Binary files /dev/null and b/public/images/categories/gossip.jpg differ diff --git a/public/images/categories/novel.jpg b/public/images/categories/novel.jpg new file mode 100644 index 0000000..b0890d0 Binary files /dev/null and b/public/images/categories/novel.jpg differ diff --git a/public/images/categories/think.jpg b/public/images/categories/think.jpg new file mode 100644 index 0000000..a749968 Binary files /dev/null and b/public/images/categories/think.jpg differ diff --git a/public/images/default-cover.jpg b/public/images/default-cover.jpg new file mode 100644 index 0000000..2f8dad4 Binary files /dev/null and b/public/images/default-cover.jpg differ diff --git a/public/images/links/80-go.com.jpg b/public/images/links/80-go.com.jpg new file mode 100644 index 0000000..2b2af37 Binary files /dev/null and b/public/images/links/80-go.com.jpg differ diff --git a/public/images/links/alexinea.com.jpg b/public/images/links/alexinea.com.jpg new file mode 100644 index 0000000..00164ac Binary files /dev/null and b/public/images/links/alexinea.com.jpg differ diff --git a/public/images/links/captainofphb.me.jpg b/public/images/links/captainofphb.me.jpg new file mode 100644 index 0000000..bcab74a Binary files /dev/null and b/public/images/links/captainofphb.me.jpg differ diff --git a/public/images/links/cynosura.one.jpg b/public/images/links/cynosura.one.jpg new file mode 100644 index 0000000..2df7909 Binary files /dev/null and b/public/images/links/cynosura.one.jpg differ diff --git a/public/images/links/eee.me.jpg b/public/images/links/eee.me.jpg new file mode 100644 index 0000000..e1919ca Binary files /dev/null and b/public/images/links/eee.me.jpg differ diff --git a/public/images/links/fmoran.me.jpg b/public/images/links/fmoran.me.jpg new file mode 100644 index 0000000..fdbc62f Binary files /dev/null and b/public/images/links/fmoran.me.jpg differ diff --git a/public/images/links/jiasm.github.io.jpg b/public/images/links/jiasm.github.io.jpg new file mode 100644 index 0000000..5ef3768 Binary files /dev/null and b/public/images/links/jiasm.github.io.jpg differ diff --git a/public/images/links/kn007.net.jpg b/public/images/links/kn007.net.jpg new file mode 100644 index 0000000..864e013 Binary files /dev/null and b/public/images/links/kn007.net.jpg differ diff --git a/public/images/links/luoli.net.jpg b/public/images/links/luoli.net.jpg new file mode 100644 index 0000000..247f01e Binary files /dev/null and b/public/images/links/luoli.net.jpg differ diff --git a/public/images/links/mboker.cn.jpg b/public/images/links/mboker.cn.jpg new file mode 100644 index 0000000..653438e Binary files /dev/null and b/public/images/links/mboker.cn.jpg differ diff --git a/public/images/links/minagi.me.jpg b/public/images/links/minagi.me.jpg new file mode 100644 index 0000000..c324d26 Binary files /dev/null and b/public/images/links/minagi.me.jpg differ diff --git a/public/images/links/pwsz.com.jpg b/public/images/links/pwsz.com.jpg new file mode 100644 index 0000000..1acebbd Binary files /dev/null and b/public/images/links/pwsz.com.jpg differ diff --git a/public/images/links/xinsenz.com.jpg b/public/images/links/xinsenz.com.jpg new file mode 100644 index 0000000..d5b4ac7 Binary files /dev/null and b/public/images/links/xinsenz.com.jpg differ diff --git a/public/images/links/yefengs.com.jpg b/public/images/links/yefengs.com.jpg new file mode 100644 index 0000000..642b482 Binary files /dev/null and b/public/images/links/yefengs.com.jpg differ diff --git a/public/images/links/yyjn.org.jpg b/public/images/links/yyjn.org.jpg new file mode 100644 index 0000000..c49292e Binary files /dev/null and b/public/images/links/yyjn.org.jpg differ diff --git a/public/images/open-graph.png b/public/images/open-graph.png new file mode 100644 index 0000000..1a1ee64 Binary files /dev/null and b/public/images/open-graph.png differ diff --git a/public/images/recaps/algo-minimal-costs/step1.svg b/public/images/recaps/algo-minimal-costs/step1.svg new file mode 100644 index 0000000..080aca1 --- /dev/null +++ b/public/images/recaps/algo-minimal-costs/step1.svg @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="UTF-8"?> +<svg width="1203px" height="1201px" viewBox="0 0 1203 1201" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <title>64x64</title> + <g id="64x64" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> + <g id="Group" transform="translate(94, 96.5)" stroke="#979797" stroke-linecap="square"> + <line x1="0.5" y1="103" x2="1006.5" y2="103" id="Line"></line> + <line x1="6" y1="303.5" x2="1012" y2="303.5" id="Line"></line> + <line x1="6" y1="504.5" x2="1012" y2="504.5" id="Line"></line> + <line x1="1" y1="705.5" x2="1007" y2="705.5" id="Line"></line> + <line x1="6" y1="906.5" x2="1012" y2="906.5" id="Line"></line> + <line x1="110.5" y1="6" x2="110.5" y2="1005" id="Line-2"></line> + <line x1="311" y1="6.5" x2="311" y2="1005.5" id="Line-2"></line> + <line x1="504" y1="0.5" x2="504" y2="999.5" id="Line-2"></line> + <line x1="706" y1="4.5" x2="706" y2="1003.5" id="Line-2"></line> + <line x1="908" y1="4.5" x2="908" y2="1003.5" id="Line-2"></line> + </g> + <line x1="203" y1="400.5" x2="202.5" y2="601" id="y" stroke="#003DFF" stroke-width="5" stroke-linecap="square"></line> + <circle id="Oval" stroke="#79A3F8" fill="#9BD0FD" cx="205" cy="600" r="19.5"></circle> + <circle id="Oval" stroke="#FF8D8D" fill="#FD9B9B" cx="205" cy="397" r="19.5"></circle> + </g> +</svg> \ No newline at end of file diff --git a/public/images/recaps/algo-minimal-costs/step2.svg b/public/images/recaps/algo-minimal-costs/step2.svg new file mode 100644 index 0000000..7275f05 --- /dev/null +++ b/public/images/recaps/algo-minimal-costs/step2.svg @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<svg width="1203px" height="1201px" viewBox="0 0 1203 1201" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <title>64x64</title> + <g id="64x64" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> + <g id="Group" transform="translate(94, 96.5)" stroke="#979797" stroke-linecap="square"> + <line x1="0.5" y1="103" x2="1006.5" y2="103" id="Line"></line> + <line x1="6" y1="303.5" x2="1012" y2="303.5" id="Line"></line> + <line x1="6" y1="504.5" x2="1012" y2="504.5" id="Line"></line> + <line x1="1" y1="705.5" x2="1007" y2="705.5" id="Line"></line> + <line x1="6" y1="906.5" x2="1012" y2="906.5" id="Line"></line> + <line x1="110.5" y1="6" x2="110.5" y2="1005" id="Line-2"></line> + <line x1="311" y1="6.5" x2="311" y2="1005.5" id="Line-2"></line> + <line x1="504" y1="0.5" x2="504" y2="999.5" id="Line-2"></line> + <line x1="706" y1="4.5" x2="706" y2="1003.5" id="Line-2"></line> + <line x1="908" y1="4.5" x2="908" y2="1003.5" id="Line-2"></line> + </g> + <line x1="406" y1="400" x2="405.5" y2="600.5" id="y" stroke="#FF0000" stroke-width="5" stroke-linecap="square"></line> + <line x1="203" y1="400.5" x2="202.5" y2="601" id="y" stroke="#003DFF" stroke-width="5" stroke-linecap="square"></line> + <line x1="203.5" y1="398.5" x2="404.5" y2="398.5" id="x" stroke="#FF0000" stroke-width="5" stroke-linecap="square"></line> + <line x1="204" y1="601" x2="405" y2="601" id="x" stroke="#003DFF" stroke-width="5" stroke-linecap="square"></line> + <circle id="Oval" stroke="#79A3F8" fill="#9BD0FD" cx="407" cy="601" r="19.5"></circle> + <circle id="Oval" stroke="#FF8D8D" fill="#FD9B9B" cx="205" cy="397" r="19.5"></circle> + </g> +</svg> \ No newline at end of file diff --git a/public/images/recaps/algo-minimal-costs/step3.svg b/public/images/recaps/algo-minimal-costs/step3.svg new file mode 100644 index 0000000..c99e5f4 --- /dev/null +++ b/public/images/recaps/algo-minimal-costs/step3.svg @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<svg width="1203px" height="1201px" viewBox="0 0 1203 1201" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <title>64x64</title> + <g id="64x64" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> + <g id="Group" transform="translate(94, 96.5)" stroke="#979797" stroke-linecap="square"> + <line x1="0.5" y1="103" x2="1006.5" y2="103" id="Line"></line> + <line x1="6" y1="303.5" x2="1012" y2="303.5" id="Line"></line> + <line x1="6" y1="504.5" x2="1012" y2="504.5" id="Line"></line> + <line x1="1" y1="705.5" x2="1007" y2="705.5" id="Line"></line> + <line x1="6" y1="906.5" x2="1012" y2="906.5" id="Line"></line> + <line x1="110.5" y1="6" x2="110.5" y2="1005" id="Line-2"></line> + <line x1="311" y1="6.5" x2="311" y2="1005.5" id="Line-2"></line> + <line x1="504" y1="0.5" x2="504" y2="999.5" id="Line-2"></line> + <line x1="706" y1="4.5" x2="706" y2="1003.5" id="Line-2"></line> + <line x1="908" y1="4.5" x2="908" y2="1003.5" id="Line-2"></line> + </g> + <line x1="205" y1="397" x2="203.5" y2="1005.5" id="y" stroke="#FF0000" stroke-width="5" stroke-linecap="square"></line> + <line x1="203.5" y1="398.5" x2="404.5" y2="398.5" id="x" stroke="#FF0000" stroke-width="5" stroke-linecap="square"></line> + <line x1="205" y1="398" x2="798.5" y2="397.5" id="x" stroke="#003DFF" stroke-width="5" stroke-linecap="square"></line> + <circle id="Oval" stroke="#79A3F8" fill="#9BD0FD" cx="798" cy="398" r="19.5"></circle> + <circle id="Oval" stroke="#46DDB7" fill="#5CDC8C" cx="205" cy="1005" r="19.5"></circle> + <circle id="Oval" stroke="#FF8D8D" fill="#FD9B9B" cx="205" cy="397" r="19.5"></circle> + </g> +</svg> \ No newline at end of file diff --git a/public/images/recaps/algo-minimal-costs/step4.svg b/public/images/recaps/algo-minimal-costs/step4.svg new file mode 100644 index 0000000..6ed22e3 --- /dev/null +++ b/public/images/recaps/algo-minimal-costs/step4.svg @@ -0,0 +1,41 @@ +<?xml version="1.0" encoding="UTF-8"?> +<svg width="2402px" height="1201px" viewBox="0 0 2402 1201" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <title>128x128</title> + <g id="128x128" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> + <g id="Group" transform="translate(1296, 97.5)" stroke="#979797" stroke-linecap="square"> + <line x1="0.5" y1="103" x2="1006.5" y2="103" id="Line"></line> + <line x1="6" y1="303.5" x2="1012" y2="303.5" id="Line"></line> + <line x1="6" y1="504.5" x2="1012" y2="504.5" id="Line"></line> + <line x1="1" y1="705.5" x2="1007" y2="705.5" id="Line"></line> + <line x1="6" y1="906.5" x2="1012" y2="906.5" id="Line"></line> + <line x1="110.5" y1="6" x2="110.5" y2="1005" id="Line-2"></line> + <line x1="311" y1="6.5" x2="311" y2="1005.5" id="Line-2"></line> + <line x1="504" y1="0.5" x2="504" y2="999.5" id="Line-2"></line> + <line x1="706" y1="4.5" x2="706" y2="1003.5" id="Line-2"></line> + <line x1="908" y1="4.5" x2="908" y2="1003.5" id="Line-2"></line> + </g> + <g id="Group" transform="translate(94, 96.5)" stroke="#979797" stroke-linecap="square"> + <line x1="0.5" y1="103" x2="1006.5" y2="103" id="Line"></line> + <line x1="6" y1="303.5" x2="1012" y2="303.5" id="Line"></line> + <line x1="6" y1="504.5" x2="1012" y2="504.5" id="Line"></line> + <line x1="1" y1="705.5" x2="1007" y2="705.5" id="Line"></line> + <line x1="6" y1="906.5" x2="1012" y2="906.5" id="Line"></line> + <line x1="110.5" y1="6" x2="110.5" y2="1005" id="Line-2"></line> + <line x1="311" y1="6.5" x2="311" y2="1005.5" id="Line-2"></line> + <line x1="504" y1="0.5" x2="504" y2="999.5" id="Line-2"></line> + <line x1="706" y1="4.5" x2="706" y2="1003.5" id="Line-2"></line> + <line x1="908" y1="4.5" x2="908" y2="1003.5" id="Line-2"></line> + </g> + <line x1="600" y1="400" x2="600.5" y2="599.5" id="y" stroke="#FF0000" stroke-width="5" stroke-linecap="square"></line> + <line x1="203" y1="400.5" x2="202.5" y2="601" id="y" stroke="#003DFF" stroke-width="5" stroke-linecap="square"></line> + <line x1="203.5" y1="398.5" x2="600.5" y2="399.5" id="x" stroke="#FF0000" stroke-width="5" stroke-linecap="square"></line> + <line x1="205" y1="601" x2="600.5" y2="601.5" id="x" stroke="#003DFF" stroke-width="5" stroke-linecap="square"></line> + <line x1="1608.5" y1="602.5" x2="1808" y2="602" id="x" stroke="#003DFF" stroke-width="5" stroke-linecap="square"></line> + <line x1="1402" y1="399.5" x2="1608.5" y2="399" id="x" stroke="#003DFF" stroke-width="5" stroke-linecap="square"></line> + <line x1="1608.5" y1="398.5" x2="1608.5" y2="602.5" id="x" stroke="#003DFF" stroke-width="5" stroke-linecap="square"></line> + <circle id="Oval" stroke="#79A3F8" fill="#9BD0FD" cx="600" cy="601" r="19.5"></circle> + <circle id="Oval" stroke="#79A3F8" fill="#9BD0FD" cx="1812" cy="601" r="19.5"></circle> + <circle id="Oval" stroke="#FF8D8D" fill="#FD9B9B" cx="205" cy="397" r="19.5"></circle> + <circle id="Oval" stroke="#FF8D8D" fill="#FD9B9B" cx="1412" cy="399" r="19.5"></circle> + </g> +</svg> \ No newline at end of file diff --git a/public/images/recaps/algo-minimal-costs/step5.svg b/public/images/recaps/algo-minimal-costs/step5.svg new file mode 100644 index 0000000..cc02119 --- /dev/null +++ b/public/images/recaps/algo-minimal-costs/step5.svg @@ -0,0 +1,50 @@ +<?xml version="1.0" encoding="UTF-8"?> +<svg width="2402px" height="1201px" viewBox="0 0 2402 1201" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <title>128x128</title> + <g id="128x128" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> + <g id="Group" transform="translate(1296, 97.5)" stroke="#979797" stroke-linecap="square"> + <line x1="0.5" y1="103" x2="1006.5" y2="103" id="Line"></line> + <line x1="6" y1="303.5" x2="1012" y2="303.5" id="Line"></line> + <line x1="6" y1="504.5" x2="1012" y2="504.5" id="Line"></line> + <line x1="1" y1="705.5" x2="1007" y2="705.5" id="Line"></line> + <line x1="6" y1="906.5" x2="1012" y2="906.5" id="Line"></line> + <line x1="110.5" y1="6" x2="110.5" y2="1005" id="Line-2"></line> + <line x1="311" y1="6.5" x2="311" y2="1005.5" id="Line-2"></line> + <line x1="504" y1="0.5" x2="504" y2="999.5" id="Line-2"></line> + <line x1="706" y1="4.5" x2="706" y2="1003.5" id="Line-2"></line> + <line x1="908" y1="4.5" x2="908" y2="1003.5" id="Line-2"></line> + </g> + <g id="Group" transform="translate(94, 96.5)" stroke="#979797" stroke-linecap="square"> + <line x1="0.5" y1="103" x2="1006.5" y2="103" id="Line"></line> + <line x1="6" y1="303.5" x2="1012" y2="303.5" id="Line"></line> + <line x1="6" y1="504.5" x2="1012" y2="504.5" id="Line"></line> + <line x1="1" y1="705.5" x2="1007" y2="705.5" id="Line"></line> + <line x1="6" y1="906.5" x2="1012" y2="906.5" id="Line"></line> + <line x1="110.5" y1="6" x2="110.5" y2="1005" id="Line-2"></line> + <line x1="311" y1="6.5" x2="311" y2="1005.5" id="Line-2"></line> + <line x1="504" y1="0.5" x2="504" y2="999.5" id="Line-2"></line> + <line x1="706" y1="4.5" x2="706" y2="1003.5" id="Line-2"></line> + <line x1="908" y1="4.5" x2="908" y2="1003.5" id="Line-2"></line> + </g> + <path id="Line-3" d="M1409,603 L1409,771 L1423,771 L1406,805 L1389,771 L1403,771 L1403,603 L1409,603 Z" fill="#718EE5" fill-rule="nonzero"></path> + <circle id="Oval" stroke="#79A3F8" fill="#9BD0FD" cx="1801.5" cy="804.5" r="19.5"></circle> + <path id="Line-3" d="M1573.41584,383.669363 L1607.5,400.5 L1573.585,417.668942 L1573.514,403.669 L1406.51493,404.499963 L1403.51496,404.514888 L1403.48511,398.514962 L1406.48507,398.500037 L1573.485,397.669 L1573.41584,383.669363 Z" fill="#5FB88F" fill-rule="nonzero"></path> + <path id="Line-3" d="M1410,401 L1410,569 L1424,569 L1407,603 L1390,569 L1404,569 L1404,401 L1410,401 Z" fill="#718EE5" fill-rule="nonzero"></path> + <path id="Line-3" d="M1610.5,401.5 L1610.5,569.5 L1624.5,569.5 L1607.5,603.5 L1590.5,569.5 L1604.5,569.5 L1604.5,401.5 L1610.5,401.5 Z" fill="#718EE5" fill-rule="nonzero"></path> + <path id="Line-3" d="M1805.5,399.5 L1805.5,567.5 L1819.5,567.5 L1802.5,601.5 L1785.5,567.5 L1799.5,567.5 L1799.5,399.5 L1805.5,399.5 Z" fill="#718EE5" fill-rule="nonzero"></path> + <path id="Line-3" d="M1573.91584,584.169363 L1608,601 L1574.085,618.168942 L1574.014,604.169 L1407.01493,604.999963 L1404.01496,605.014888 L1403.98511,599.014962 L1406.98507,599.000037 L1573.985,598.169 L1573.91584,584.169363 Z" fill="#5FB88F" fill-rule="nonzero"></path> + <path id="Line-3" d="M1774.91584,584.169363 L1809,601 L1775.085,618.168942 L1775.014,604.169 L1608.01493,604.999963 L1605.01496,605.014888 L1604.98511,599.014962 L1607.98507,599.000037 L1774.985,598.169 L1774.91584,584.169363 Z" fill="#5FB88F" fill-rule="nonzero"></path> + <path id="Line-3" d="M1774.91584,786.169363 L1809,803 L1775.085,820.168942 L1775.014,806.169 L1608.01493,806.999963 L1605.01496,807.014888 L1604.98511,801.014962 L1607.98507,801.000037 L1774.985,800.169 L1774.91584,786.169363 Z" fill="#5FB88F" fill-rule="nonzero"></path> + <path id="Line-3" d="M1573.91584,786.169363 L1608,803 L1574.085,820.168942 L1574.014,806.169 L1407.01493,806.999963 L1404.01496,807.014888 L1403.98511,801.014962 L1406.98507,801.000037 L1573.985,800.169 L1573.91584,786.169363 Z" fill="#5FB88F" fill-rule="nonzero"></path> + <path id="Line-3" d="M1777.91584,385.169363 L1812,402 L1778.085,419.168942 L1778.014,405.169 L1611.01493,405.999963 L1608.01496,406.014888 L1607.98511,400.014962 L1610.98507,400.000037 L1777.985,399.169 L1777.91584,385.169363 Z" fill="#5FB88F" fill-rule="nonzero"></path> + <line x1="600.25" y1="400.75" x2="600.75" y2="804.25" id="y" stroke="#FF0000" stroke-width="5" stroke-linecap="square"></line> + <line x1="202.75" y1="400.5" x2="204.25" y2="804.5" id="y" stroke="#003DFF" stroke-width="5" stroke-linecap="square"></line> + <line x1="203.5" y1="398.5" x2="600.5" y2="396.5" id="x" stroke="#FF0000" stroke-width="5" stroke-linecap="square"></line> + <path id="Line-3" d="M1610,603 L1610,771 L1624,771 L1607,805 L1590,771 L1604,771 L1604,603 L1610,603 Z" fill="#718EE5" fill-rule="nonzero"></path> + <path id="Line-3" d="M1805,601 L1805,769 L1819,769 L1802,803 L1785,769 L1799,769 L1799,601 L1805,601 Z" fill="#718EE5" fill-rule="nonzero"></path> + <line x1="204.75" y1="804.75" x2="602.25" y2="804.25" id="x" stroke="#003DFF" stroke-width="5" stroke-linecap="square"></line> + <circle id="Oval" stroke="#79A3F8" fill="#9BD0FD" cx="602" cy="805" r="19.5"></circle> + <circle id="Oval" stroke="#FF8D8D" fill="#FD9B9B" cx="205" cy="397" r="19.5"></circle> + <circle id="Oval" stroke="#FF8D8D" fill="#FD9B9B" cx="1412" cy="399" r="19.5"></circle> + </g> +</svg> \ No newline at end of file diff --git a/public/images/recaps/algo-minimal-costs/step6.svg b/public/images/recaps/algo-minimal-costs/step6.svg new file mode 100644 index 0000000..0201f8d --- /dev/null +++ b/public/images/recaps/algo-minimal-costs/step6.svg @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="UTF-8"?> +<svg width="2215px" height="1008px" viewBox="0 0 2215 1008" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <title>Untitled</title> + <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> + <g id="step6" transform="translate(0.5, 1)"> + <g id="Group" stroke-linecap="square" transform="translate(1202, 1)" stroke="#979797"> + <line x1="0" y1="102.5" x2="1006" y2="102.5" id="Line"></line> + <line x1="5.5" y1="303" x2="1011.5" y2="303" id="Line"></line> + <line x1="5.5" y1="504" x2="1011.5" y2="504" id="Line"></line> + <line x1="0.5" y1="705" x2="1006.5" y2="705" id="Line"></line> + <line x1="5.5" y1="906" x2="1011.5" y2="906" id="Line"></line> + <line x1="110" y1="5.5" x2="110" y2="1004.5" id="Line-2"></line> + <line x1="310.5" y1="6" x2="310.5" y2="1005" id="Line-2"></line> + <line x1="503.5" y1="0" x2="503.5" y2="999" id="Line-2"></line> + <line x1="705.5" y1="4" x2="705.5" y2="1003" id="Line-2"></line> + <line x1="907.5" y1="4" x2="907.5" y2="1003" id="Line-2"></line> + </g> + <g id="Group" stroke-linecap="square" stroke="#979797"> + <line x1="0" y1="102.5" x2="1006" y2="102.5" id="Line"></line> + <line x1="5.5" y1="303" x2="1011.5" y2="303" id="Line"></line> + <line x1="5.5" y1="504" x2="1011.5" y2="504" id="Line"></line> + <line x1="0.5" y1="705" x2="1006.5" y2="705" id="Line"></line> + <line x1="5.5" y1="906" x2="1011.5" y2="906" id="Line"></line> + <line x1="110" y1="5.5" x2="110" y2="1004.5" id="Line-2"></line> + <line x1="310.5" y1="6" x2="310.5" y2="1005" id="Line-2"></line> + <line x1="503.5" y1="0" x2="503.5" y2="999" id="Line-2"></line> + <line x1="705.5" y1="4" x2="705.5" y2="1003" id="Line-2"></line> + <line x1="907.5" y1="4" x2="907.5" y2="1003" id="Line-2"></line> + </g> + <line x1="905.498111" y1="108.802083" x2="906.50189" y2="707.129289" id="y" stroke="#FF0000" stroke-width="5" stroke-linecap="square"></line> + <line x1="2109.49433" y1="103.060662" x2="2109" y2="909.5" id="y" stroke="#FF0000" stroke-width="5" stroke-linecap="square"></line> + <line x1="1309" y1="506.5" x2="1309.49055" y2="908.75858" id="y" stroke="#FF0000" stroke-width="5" stroke-linecap="square"></line> + <line x1="109" y1="105.465686" x2="906" y2="102.5" id="x" stroke="#FF0000" stroke-width="5" stroke-linecap="square"></line> + <line x1="1308.99622" y1="106.724265" x2="2105.99622" y2="103.758578" id="x" stroke="#FF0000" stroke-width="5" stroke-linecap="square"></line> + <line x1="1308.99244" y1="504.982843" x2="1710" y2="506.5" id="x" stroke="#FF0000" stroke-width="5" stroke-linecap="square"></line> + <line x1="1311.99244" y1="909.98284" x2="2108.99244" y2="907.01716" id="x" stroke="#FF0000" stroke-width="5" stroke-linecap="square"></line> + <line x1="708.25" y1="705.25" x2="902.75" y2="704.75" id="x" stroke="#FF0000" stroke-width="5" stroke-linecap="square"></line> + <circle id="Oval" stroke="#79A3F8" fill="#9BD0FD" fill-rule="nonzero" cx="707.5" cy="707" r="19.5"></circle> + <circle id="Oval" stroke="#79A3F8" fill="#9BD0FD" fill-rule="nonzero" cx="1707.5" cy="503" r="19.5"></circle> + <circle id="Oval" stroke="#FF8D8D" fill="#FD9B9B" fill-rule="nonzero" cx="110.5" cy="103" r="19.5"></circle> + <polygon id="Star" fill="#3FC0FD" fill-rule="nonzero" points="110 315.75 94.423691 323.93895 97.398501 306.594475 84.797002 294.31105 102.211845 291.780525 110 276 117.788155 291.780525 135.202998 294.31105 122.601499 306.594475 125.576309 323.93895"></polygon> + <polygon id="Star" fill="#3FC0FD" fill-rule="nonzero" points="309 315.75 293.423691 323.93895 296.398501 306.594475 283.797002 294.31105 301.211845 291.780525 309 276 316.788155 291.780525 334.202998 294.31105 321.601499 306.594475 324.576309 323.93895"></polygon> + <polygon id="Star" fill="#3FC0FD" fill-rule="nonzero" points="708 515.75 692.423691 523.93895 695.398501 506.594475 682.797002 494.31105 700.211845 491.780525 708 476 715.788155 491.780525 733.202998 494.31105 720.601499 506.594475 723.576309 523.93895"></polygon> + <polygon id="Star" fill="#3FC0FD" fill-rule="nonzero" points="1905 519.75 1889.42369 527.93895 1892.3985 510.594475 1879.797 498.31105 1897.21185 495.780525 1905 480 1912.78815 495.780525 1930.203 498.31105 1917.6015 510.594475 1920.57631 527.93895"></polygon> + <polygon id="Star" fill="#3FC0FD" fill-rule="nonzero" points="1905 720.75 1889.42369 728.93895 1892.3985 711.594475 1879.797 699.31105 1897.21185 696.780525 1905 681 1912.78815 696.780525 1930.203 699.31105 1917.6015 711.594475 1920.57631 728.93895"></polygon> + <polygon id="Star" fill="#3FC0FD" fill-rule="nonzero" points="1706 717.75 1690.42369 725.93895 1693.3985 708.594475 1680.797 696.31105 1698.21185 693.780525 1706 678 1713.78815 693.780525 1731.203 696.31105 1718.6015 708.594475 1721.57631 725.93895"></polygon> + <polygon id="Star" fill="#3FC0FD" fill-rule="nonzero" points="1513 720.75 1497.42369 728.93895 1500.3985 711.594475 1487.797 699.31105 1505.21185 696.780525 1513 681 1520.78815 696.780525 1538.203 699.31105 1525.6015 711.594475 1528.57631 728.93895"></polygon> + <polygon id="Star" fill="#3FC0FD" fill-rule="nonzero" points="506 315.75 490.423691 323.93895 493.398501 306.594475 480.797002 294.31105 498.211845 291.780525 506 276 513.788155 291.780525 531.202998 294.31105 518.601499 306.594475 521.576309 323.93895"></polygon> + <polygon id="Star" fill="#3FC0FD" fill-rule="nonzero" points="705 315.75 689.423691 323.93895 692.398501 306.594475 679.797002 294.31105 697.211845 291.780525 705 276 712.788155 291.780525 730.202998 294.31105 717.601499 306.594475 720.576309 323.93895"></polygon> + <polygon id="Star" fill="#3FC0FD" fill-rule="nonzero" points="1509 315.75 1493.42369 323.93895 1496.3985 306.594475 1483.797 294.31105 1501.21185 291.780525 1509 276 1516.78815 291.780525 1534.203 294.31105 1521.6015 306.594475 1524.57631 323.93895"></polygon> + <polygon id="Star" fill="#3FC0FD" fill-rule="nonzero" points="1317 315.75 1301.42369 323.93895 1304.3985 306.594475 1291.797 294.31105 1309.21185 291.780525 1317 276 1324.78815 291.780525 1342.203 294.31105 1329.6015 306.594475 1332.57631 323.93895"></polygon> + <polygon id="Star" fill="#3FC0FD" fill-rule="nonzero" points="1706 315.75 1690.42369 323.93895 1693.3985 306.594475 1680.797 294.31105 1698.21185 291.780525 1706 276 1713.78815 291.780525 1731.203 294.31105 1718.6015 306.594475 1721.57631 323.93895"></polygon> + <polygon id="Star" fill="#3FC0FD" fill-rule="nonzero" points="1905 315.75 1889.42369 323.93895 1892.3985 306.594475 1879.797 294.31105 1897.21185 291.780525 1905 276 1912.78815 291.780525 1930.203 294.31105 1917.6015 306.594475 1920.57631 323.93895"></polygon> + <circle id="Oval" stroke="#FF8D8D" fill="#FD9B9B" fill-rule="nonzero" cx="1311.5" cy="109" r="19.5"></circle> + </g> + </g> +</svg> \ No newline at end of file diff --git a/public/images/recaps/algo-minimal-costs/step7.svg b/public/images/recaps/algo-minimal-costs/step7.svg new file mode 100644 index 0000000..eab12ef --- /dev/null +++ b/public/images/recaps/algo-minimal-costs/step7.svg @@ -0,0 +1,50 @@ +<?xml version="1.0" encoding="UTF-8"?> +<svg width="2402px" height="1201px" viewBox="0 0 2402 1201" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <title>128x128</title> + <g id="128x128" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> + <g id="Group" transform="translate(1296, 97.5)" stroke="#979797" stroke-linecap="square"> + <line x1="0.5" y1="103" x2="1006.5" y2="103" id="Line"></line> + <line x1="6" y1="303.5" x2="1012" y2="303.5" id="Line"></line> + <line x1="6" y1="504.5" x2="1012" y2="504.5" id="Line"></line> + <line x1="1" y1="705.5" x2="1007" y2="705.5" id="Line"></line> + <line x1="6" y1="906.5" x2="1012" y2="906.5" id="Line"></line> + <line x1="110.5" y1="6" x2="110.5" y2="1005" id="Line-2"></line> + <line x1="311" y1="6.5" x2="311" y2="1005.5" id="Line-2"></line> + <line x1="504" y1="0.5" x2="504" y2="999.5" id="Line-2"></line> + <line x1="706" y1="4.5" x2="706" y2="1003.5" id="Line-2"></line> + <line x1="908" y1="4.5" x2="908" y2="1003.5" id="Line-2"></line> + </g> + <g id="Group" transform="translate(94, 96.5)" stroke="#979797" stroke-linecap="square"> + <line x1="0.5" y1="103" x2="1006.5" y2="103" id="Line"></line> + <line x1="6" y1="303.5" x2="1012" y2="303.5" id="Line"></line> + <line x1="6" y1="504.5" x2="1012" y2="504.5" id="Line"></line> + <line x1="1" y1="705.5" x2="1007" y2="705.5" id="Line"></line> + <line x1="6" y1="906.5" x2="1012" y2="906.5" id="Line"></line> + <line x1="110.5" y1="6" x2="110.5" y2="1005" id="Line-2"></line> + <line x1="311" y1="6.5" x2="311" y2="1005.5" id="Line-2"></line> + <line x1="504" y1="0.5" x2="504" y2="999.5" id="Line-2"></line> + <line x1="706" y1="4.5" x2="706" y2="1003.5" id="Line-2"></line> + <line x1="908" y1="4.5" x2="908" y2="1003.5" id="Line-2"></line> + </g> + <circle id="Oval" stroke="#79A3F8" fill="#9BD0FD" cx="600" cy="798" r="19.5"></circle> + <circle id="Oval" stroke="#79A3F8" fill="#9BD0FD" cx="802" cy="600" r="19.5"></circle> + <circle id="Oval" stroke="#79A3F8" fill="#9BD0FD" cx="600" cy="401" r="19.5"></circle> + <circle id="Oval" stroke="#79A3F8" fill="#9BD0FD" cx="402" cy="599" r="19.5"></circle> + <circle id="Oval" stroke="#FF8D8D" fill="#FD9B9B" cx="602" cy="599" r="19.5"></circle> + <circle id="Oval" stroke="#79A3F8" fill="#9BD0FD" cx="1800" cy="799" r="19.5"></circle> + <circle id="Oval" stroke="#79A3F8" fill="#60E382" cx="1802" cy="1008" r="19.5"></circle> + <circle id="Oval" stroke="#79A3F8" fill="#60E382" cx="1602" cy="799" r="19.5"></circle> + <circle id="Oval" stroke="#79A3F8" fill="#60E382" cx="1404" cy="599" r="19.5"></circle> + <circle id="Oval" stroke="#79A3F8" fill="#60E382" cx="1611" cy="401" r="19.5"></circle> + <circle id="Oval" stroke="#79A3F8" fill="#60E382" cx="1800" cy="204" r="19.5"></circle> + <circle id="Oval" stroke="#79A3F8" fill="#60E382" cx="2002" cy="799" r="19.5"></circle> + <circle id="Oval" stroke="#79A3F8" fill="#60E382" cx="2208" cy="606" r="19.5"></circle> + <circle id="Oval" stroke="#79A3F8" fill="#60E382" cx="2002" cy="401" r="19.5"></circle> + <circle id="Oval" stroke="#79A3F8" fill="#9BD0FD" cx="2002" cy="601" r="19.5"></circle> + <circle id="Oval" stroke="#79A3F8" fill="#9BD0FD" cx="1800" cy="402" r="19.5"></circle> + <circle id="Oval" stroke="#79A3F8" fill="#9BD0FD" cx="1602" cy="600" r="19.5"></circle> + <circle id="Oval" stroke="#FF8D8D" fill="#FD9B9B" cx="1802" cy="600" r="19.5"></circle> + <polygon id="Star" fill="#FF0B0B" points="1002.5 1027.25 980.458053 1038.83814 984.66769 1014.29407 966.835381 996.911863 991.479027 993.330931 1002.5 971 1013.52097 993.330931 1038.16462 996.911863 1020.33231 1014.29407 1024.54195 1038.83814"></polygon> + <polygon id="Star" fill="#FF0B0B" points="2208.5 1027.25 2186.45805 1038.83814 2190.66769 1014.29407 2172.83538 996.911863 2197.47903 993.330931 2208.5 971 2219.52097 993.330931 2244.16462 996.911863 2226.33231 1014.29407 2230.54195 1038.83814"></polygon> + </g> +</svg> \ No newline at end of file diff --git a/public/images/recaps/algo-minimal-costs/step8.svg b/public/images/recaps/algo-minimal-costs/step8.svg new file mode 100644 index 0000000..f20f998 --- /dev/null +++ b/public/images/recaps/algo-minimal-costs/step8.svg @@ -0,0 +1,80 @@ +<?xml version="1.0" encoding="UTF-8"?> +<svg width="2402px" height="1201px" viewBox="0 0 2402 1201" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <title>128x128</title> + <g id="128x128" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> + <g id="Group" transform="translate(1296, 97.5)" stroke="#979797" stroke-linecap="square"> + <line x1="0.5" y1="103" x2="1006.5" y2="103" id="Line"></line> + <line x1="6" y1="303.5" x2="1012" y2="303.5" id="Line"></line> + <line x1="6" y1="504.5" x2="1012" y2="504.5" id="Line"></line> + <line x1="1" y1="705.5" x2="1007" y2="705.5" id="Line"></line> + <line x1="6" y1="906.5" x2="1012" y2="906.5" id="Line"></line> + <line x1="110.5" y1="6" x2="110.5" y2="1005" id="Line-2"></line> + <line x1="311" y1="6.5" x2="311" y2="1005.5" id="Line-2"></line> + <line x1="504" y1="0.5" x2="504" y2="999.5" id="Line-2"></line> + <line x1="706" y1="4.5" x2="706" y2="1003.5" id="Line-2"></line> + <line x1="908" y1="4.5" x2="908" y2="1003.5" id="Line-2"></line> + </g> + <g id="Group" transform="translate(94, 96.5)" stroke="#979797" stroke-linecap="square"> + <line x1="0.5" y1="103" x2="1006.5" y2="103" id="Line"></line> + <line x1="6" y1="303.5" x2="1012" y2="303.5" id="Line"></line> + <line x1="6" y1="504.5" x2="1012" y2="504.5" id="Line"></line> + <line x1="1" y1="705.5" x2="1007" y2="705.5" id="Line"></line> + <line x1="6" y1="906.5" x2="1012" y2="906.5" id="Line"></line> + <line x1="110.5" y1="6" x2="110.5" y2="1005" id="Line-2"></line> + <line x1="311" y1="6.5" x2="311" y2="1005.5" id="Line-2"></line> + <line x1="504" y1="0.5" x2="504" y2="999.5" id="Line-2"></line> + <line x1="706" y1="4.5" x2="706" y2="1003.5" id="Line-2"></line> + <line x1="908" y1="4.5" x2="908" y2="1003.5" id="Line-2"></line> + </g> + <circle id="Oval" stroke="#79A3F8" fill="#9BD0FD" cx="599" cy="797" r="19.5"></circle> + <circle id="Oval" stroke="#79A3F8" fill="#60E382" cx="601" cy="1006" r="19.5"></circle> + <circle id="Oval" stroke="#79A3F8" fill="#60E382" cx="401" cy="797" r="19.5"></circle> + <circle id="Oval" stroke="#79A3F8" fill="#60E382" cx="203" cy="597" r="19.5"></circle> + <circle id="Oval" stroke="#79A3F8" fill="#60E382" cx="410" cy="399" r="19.5"></circle> + <circle id="Oval" stroke="#79A3F8" fill="#60E382" cx="599" cy="202" r="19.5"></circle> + <circle id="Oval" stroke="#79A3F8" fill="#60E382" cx="801" cy="797" r="19.5"></circle> + <circle id="Oval" stroke="#79A3F8" fill="#60E382" cx="1007" cy="604" r="19.5"></circle> + <circle id="Oval" stroke="#79A3F8" fill="#60E382" cx="801" cy="399" r="19.5"></circle> + <circle id="Oval" stroke="#79A3F8" fill="#9BD0FD" cx="801" cy="599" r="19.5"></circle> + <circle id="Oval" stroke="#79A3F8" fill="#9BD0FD" cx="599" cy="400" r="19.5"></circle> + <circle id="Oval" stroke="#79A3F8" fill="#9BD0FD" cx="401" cy="598" r="19.5"></circle> + <circle id="Oval" stroke="#FF8D8D" fill="#FD9B9B" cx="601" cy="598" r="19.5"></circle> + <circle id="Oval" fill="#FFD31C" cx="801" cy="202" r="20"></circle> + <circle id="Oval" fill="#FFD31C" cx="1001" cy="400" r="20"></circle> + <circle id="Oval" fill="#FFD31C" cx="401" cy="202" r="20"></circle> + <circle id="Oval" fill="#FFD31C" cx="203" cy="399" r="20"></circle> + <circle id="Oval" fill="#FFD31C" cx="1007" cy="803" r="20"></circle> + <circle id="Oval" fill="#FFD31C" cx="801" cy="1006" r="20"></circle> + <circle id="Oval" fill="#FFD31C" cx="203" cy="803" r="20"></circle> + <circle id="Oval" fill="#FFD31C" cx="401" cy="1007" r="20"></circle> + <polygon id="Star" fill="#FF0B0B" points="1007.5 1025.25 985.458053 1036.83814 989.66769 1012.29407 971.835381 994.911863 996.479027 991.330931 1007.5 969 1018.52097 991.330931 1043.16462 994.911863 1025.33231 1012.29407 1029.54195 1036.83814"></polygon> + <circle id="Oval" stroke="#79A3F8" fill="#9BD0FD" cx="1800" cy="797" r="19.5"></circle> + <circle id="Oval" stroke="#79A3F8" fill="#60E382" cx="1802" cy="1006" r="19.5"></circle> + <circle id="Oval" stroke="#79A3F8" fill="#60E382" cx="1602" cy="797" r="19.5"></circle> + <circle id="Oval" stroke="#79A3F8" fill="#60E382" cx="1404" cy="597" r="19.5"></circle> + <circle id="Oval" stroke="#79A3F8" fill="#60E382" cx="1611" cy="399" r="19.5"></circle> + <circle id="Oval" stroke="#79A3F8" fill="#60E382" cx="1800" cy="202" r="19.5"></circle> + <circle id="Oval" stroke="#79A3F8" fill="#60E382" cx="2002" cy="797" r="19.5"></circle> + <circle id="Oval" stroke="#79A3F8" fill="#60E382" cx="2208" cy="604" r="19.5"></circle> + <circle id="Oval" stroke="#79A3F8" fill="#60E382" cx="2002" cy="399" r="19.5"></circle> + <circle id="Oval" stroke="#79A3F8" fill="#9BD0FD" cx="2002" cy="599" r="19.5"></circle> + <circle id="Oval" stroke="#79A3F8" fill="#9BD0FD" cx="1800" cy="400" r="19.5"></circle> + <circle id="Oval" stroke="#79A3F8" fill="#9BD0FD" cx="1602" cy="598" r="19.5"></circle> + <circle id="Oval" stroke="#FF8D8D" fill="#FD9B9B" cx="1802" cy="598" r="19.5"></circle> + <circle id="Oval" fill="#FFD31C" cx="2002" cy="202" r="20"></circle> + <circle id="Oval" fill="#FFD31C" cx="2202" cy="400" r="20"></circle> + <circle id="Oval" fill="#FFD31C" cx="1602" cy="202" r="20"></circle> + <circle id="Oval" fill="#FFD31C" cx="1404" cy="399" r="20"></circle> + <circle id="Oval" fill="#FFD31C" cx="2208" cy="803" r="20"></circle> + <circle id="Oval" fill="#FFD31C" cx="2002" cy="1006" r="20"></circle> + <circle id="Oval" fill="#FFD31C" cx="1404" cy="803" r="20"></circle> + <circle id="Oval" fill="#FFD31C" cx="1602" cy="1007" r="20"></circle> + <polygon id="Star" fill="#FF0B0B" points="2208.5 1025.25 2186.45805 1036.83814 2190.66769 1012.29407 2172.83538 994.911863 2197.47903 991.330931 2208.5 969 2219.52097 991.330931 2244.16462 994.911863 2226.33231 1012.29407 2230.54195 1036.83814"></polygon> + <circle id="Oval" fill="#FFD31C" cx="2208" cy="803" r="20"></circle> + <path id="Line-3" d="M1972.28782,584.924819 L2001.49994,598.992575 L1972.71847,613.921622 L1972.54,601.923 L1799.03712,604.499724 L1796.5374,604.536849 L1796.46315,599.5374 L1798.96288,599.500276 L1972.465,596.923 L1972.28782,584.924819 Z" fill="#979797" fill-rule="nonzero"></path> + <path id="Line-3" d="M1971.78782,584.424819 L2000.99994,598.492575 L1972.21847,613.421622 L1972.04,601.423 L1798.53712,603.999724 L1796.0374,604.036849 L1795.96315,599.0374 L1798.46288,599.000276 L1971.965,596.423 L1971.78782,584.424819 Z" fill="#979797" fill-rule="nonzero"></path> + <path id="Line-3" d="M2174.78782,584.424819 L2203.99994,598.492575 L2175.21847,613.421622 L2175.04,601.423 L2001.53712,603.999724 L1999.0374,604.036849 L1998.96315,599.0374 L2001.46288,599.000276 L2174.965,596.423 L2174.78782,584.424819 Z" fill="#979797" fill-rule="nonzero"></path> + <path id="Line-3" d="M2205.9943,594.994312 L2205.99999,597.494305 L2206.434,788.494 L2218.43504,788.467044 L2204.00114,817.499999 L2189.43512,788.533103 L2201.434,788.506 L2201.00001,597.505695 L2200.99431,595.005701 L2205.9943,594.994312 Z" fill="#979797" fill-rule="nonzero"></path> + <path id="Line-3" d="M2209.4943,804.494312 L2209.49999,806.994305 L2209.934,997.994 L2221.93504,997.967044 L2207.50114,1027 L2192.93512,998.033103 L2204.934,998.006 L2204.50001,807.005695 L2204.49431,804.505701 L2209.4943,804.494312 Z" fill="#979797" fill-rule="nonzero"></path> + </g> +</svg> \ No newline at end of file diff --git a/public/images/recaps/atelier-firis/01.jpg b/public/images/recaps/atelier-firis/01.jpg new file mode 100644 index 0000000..5f2486f Binary files /dev/null and b/public/images/recaps/atelier-firis/01.jpg differ diff --git a/public/images/recaps/atelier-firis/02.jpg b/public/images/recaps/atelier-firis/02.jpg new file mode 100644 index 0000000..e519c49 Binary files /dev/null and b/public/images/recaps/atelier-firis/02.jpg differ diff --git a/public/images/recaps/atelier-firis/03.jpg b/public/images/recaps/atelier-firis/03.jpg new file mode 100644 index 0000000..4c93660 Binary files /dev/null and b/public/images/recaps/atelier-firis/03.jpg differ diff --git a/public/images/recaps/atelier-firis/04.jpg b/public/images/recaps/atelier-firis/04.jpg new file mode 100644 index 0000000..9fc840d Binary files /dev/null and b/public/images/recaps/atelier-firis/04.jpg differ diff --git a/public/images/recaps/atelier-firis/05.jpg b/public/images/recaps/atelier-firis/05.jpg new file mode 100644 index 0000000..5395f1d Binary files /dev/null and b/public/images/recaps/atelier-firis/05.jpg differ diff --git a/public/images/recaps/atelier-firis/06.jpg b/public/images/recaps/atelier-firis/06.jpg new file mode 100644 index 0000000..6a890c7 Binary files /dev/null and b/public/images/recaps/atelier-firis/06.jpg differ diff --git a/public/images/recaps/atelier-firis/07.jpg b/public/images/recaps/atelier-firis/07.jpg new file mode 100644 index 0000000..e3074d9 Binary files /dev/null and b/public/images/recaps/atelier-firis/07.jpg differ diff --git a/public/images/recaps/atelier-firis/08.jpg b/public/images/recaps/atelier-firis/08.jpg new file mode 100644 index 0000000..c67b324 Binary files /dev/null and b/public/images/recaps/atelier-firis/08.jpg differ diff --git a/public/images/recaps/atelier-firis/09.jpg b/public/images/recaps/atelier-firis/09.jpg new file mode 100644 index 0000000..1cd11b7 Binary files /dev/null and b/public/images/recaps/atelier-firis/09.jpg differ diff --git a/public/images/recaps/atelier-firis/10.jpg b/public/images/recaps/atelier-firis/10.jpg new file mode 100644 index 0000000..5ac27af Binary files /dev/null and b/public/images/recaps/atelier-firis/10.jpg differ diff --git a/public/images/recaps/atelier-firis/11.jpg b/public/images/recaps/atelier-firis/11.jpg new file mode 100644 index 0000000..c702729 Binary files /dev/null and b/public/images/recaps/atelier-firis/11.jpg differ diff --git a/public/images/recaps/atelier-firis/12.jpg b/public/images/recaps/atelier-firis/12.jpg new file mode 100644 index 0000000..0dce700 Binary files /dev/null and b/public/images/recaps/atelier-firis/12.jpg differ diff --git a/public/images/recaps/atelier-firis/13.jpg b/public/images/recaps/atelier-firis/13.jpg new file mode 100644 index 0000000..07ce01a Binary files /dev/null and b/public/images/recaps/atelier-firis/13.jpg differ diff --git a/public/images/recaps/atelier-firis/14.jpg b/public/images/recaps/atelier-firis/14.jpg new file mode 100644 index 0000000..6244b9c Binary files /dev/null and b/public/images/recaps/atelier-firis/14.jpg differ diff --git a/public/images/recaps/atelier-firis/15.jpg b/public/images/recaps/atelier-firis/15.jpg new file mode 100644 index 0000000..e4351c6 Binary files /dev/null and b/public/images/recaps/atelier-firis/15.jpg differ diff --git a/public/images/recaps/atelier-firis/16.jpg b/public/images/recaps/atelier-firis/16.jpg new file mode 100644 index 0000000..e799624 Binary files /dev/null and b/public/images/recaps/atelier-firis/16.jpg differ diff --git a/public/images/recaps/atelier-firis/17.jpg b/public/images/recaps/atelier-firis/17.jpg new file mode 100644 index 0000000..a9e0eac Binary files /dev/null and b/public/images/recaps/atelier-firis/17.jpg differ diff --git a/public/images/recaps/atelier-firis/18.jpg b/public/images/recaps/atelier-firis/18.jpg new file mode 100644 index 0000000..c1ea640 Binary files /dev/null and b/public/images/recaps/atelier-firis/18.jpg differ diff --git a/public/images/recaps/atelier-firis/19.jpg b/public/images/recaps/atelier-firis/19.jpg new file mode 100644 index 0000000..9b5b3c6 Binary files /dev/null and b/public/images/recaps/atelier-firis/19.jpg differ diff --git a/public/images/recaps/atelier-firis/20.jpg b/public/images/recaps/atelier-firis/20.jpg new file mode 100644 index 0000000..782979d Binary files /dev/null and b/public/images/recaps/atelier-firis/20.jpg differ diff --git a/public/images/recaps/atelier-firis/21.jpg b/public/images/recaps/atelier-firis/21.jpg new file mode 100644 index 0000000..6d1f0cf Binary files /dev/null and b/public/images/recaps/atelier-firis/21.jpg differ diff --git a/public/images/recaps/atelier-firis/22.jpg b/public/images/recaps/atelier-firis/22.jpg new file mode 100644 index 0000000..dabe3ff Binary files /dev/null and b/public/images/recaps/atelier-firis/22.jpg differ diff --git a/public/images/recaps/atelier-firis/23.jpg b/public/images/recaps/atelier-firis/23.jpg new file mode 100644 index 0000000..8c93d71 Binary files /dev/null and b/public/images/recaps/atelier-firis/23.jpg differ diff --git a/public/images/recaps/atelier-firis/24.jpg b/public/images/recaps/atelier-firis/24.jpg new file mode 100644 index 0000000..746d742 Binary files /dev/null and b/public/images/recaps/atelier-firis/24.jpg differ diff --git a/public/images/recaps/atelier-firis/25.jpg b/public/images/recaps/atelier-firis/25.jpg new file mode 100644 index 0000000..997da6e Binary files /dev/null and b/public/images/recaps/atelier-firis/25.jpg differ diff --git a/public/images/recaps/atelier-firis/26.jpg b/public/images/recaps/atelier-firis/26.jpg new file mode 100644 index 0000000..2e2eadc Binary files /dev/null and b/public/images/recaps/atelier-firis/26.jpg differ diff --git a/public/images/recaps/atelier-firis/27.jpg b/public/images/recaps/atelier-firis/27.jpg new file mode 100644 index 0000000..69739cc Binary files /dev/null and b/public/images/recaps/atelier-firis/27.jpg differ diff --git a/public/images/recaps/atelier-firis/28.jpg b/public/images/recaps/atelier-firis/28.jpg new file mode 100644 index 0000000..507ad0f Binary files /dev/null and b/public/images/recaps/atelier-firis/28.jpg differ diff --git a/public/images/recaps/atelier-firis/29.jpg b/public/images/recaps/atelier-firis/29.jpg new file mode 100644 index 0000000..15b0ff5 Binary files /dev/null and b/public/images/recaps/atelier-firis/29.jpg differ diff --git a/public/images/recaps/atelier-firis/30.jpg b/public/images/recaps/atelier-firis/30.jpg new file mode 100644 index 0000000..bf09667 Binary files /dev/null and b/public/images/recaps/atelier-firis/30.jpg differ diff --git a/public/images/recaps/atelier-firis/31.jpg b/public/images/recaps/atelier-firis/31.jpg new file mode 100644 index 0000000..2d911e9 Binary files /dev/null and b/public/images/recaps/atelier-firis/31.jpg differ diff --git a/public/images/recaps/atelier-firis/32.jpg b/public/images/recaps/atelier-firis/32.jpg new file mode 100644 index 0000000..f2600ac Binary files /dev/null and b/public/images/recaps/atelier-firis/32.jpg differ diff --git a/public/images/recaps/atelier-firis/33.jpg b/public/images/recaps/atelier-firis/33.jpg new file mode 100644 index 0000000..e6da89e Binary files /dev/null and b/public/images/recaps/atelier-firis/33.jpg differ diff --git a/public/images/recaps/atelier-firis/34.jpg b/public/images/recaps/atelier-firis/34.jpg new file mode 100644 index 0000000..67b9496 Binary files /dev/null and b/public/images/recaps/atelier-firis/34.jpg differ diff --git a/public/images/recaps/atelier-firis/35.jpg b/public/images/recaps/atelier-firis/35.jpg new file mode 100644 index 0000000..fd3a939 Binary files /dev/null and b/public/images/recaps/atelier-firis/35.jpg differ diff --git a/public/images/recaps/atelier-firis/36.jpg b/public/images/recaps/atelier-firis/36.jpg new file mode 100644 index 0000000..2bf4b80 Binary files /dev/null and b/public/images/recaps/atelier-firis/36.jpg differ diff --git a/public/images/recaps/atelier-firis/37.jpg b/public/images/recaps/atelier-firis/37.jpg new file mode 100644 index 0000000..5511ad5 Binary files /dev/null and b/public/images/recaps/atelier-firis/37.jpg differ diff --git a/public/images/recaps/atelier-firis/38.jpg b/public/images/recaps/atelier-firis/38.jpg new file mode 100644 index 0000000..720250c Binary files /dev/null and b/public/images/recaps/atelier-firis/38.jpg differ diff --git a/public/images/recaps/atelier-firis/39.jpg b/public/images/recaps/atelier-firis/39.jpg new file mode 100644 index 0000000..27e1b6d Binary files /dev/null and b/public/images/recaps/atelier-firis/39.jpg differ diff --git a/public/images/recaps/atelier-firis/40.jpg b/public/images/recaps/atelier-firis/40.jpg new file mode 100644 index 0000000..97ff04f Binary files /dev/null and b/public/images/recaps/atelier-firis/40.jpg differ diff --git a/public/images/recaps/atelier-firis/41.jpg b/public/images/recaps/atelier-firis/41.jpg new file mode 100644 index 0000000..d8e6514 Binary files /dev/null and b/public/images/recaps/atelier-firis/41.jpg differ diff --git a/public/images/recaps/atelier-firis/42.jpg b/public/images/recaps/atelier-firis/42.jpg new file mode 100644 index 0000000..3fe0372 Binary files /dev/null and b/public/images/recaps/atelier-firis/42.jpg differ diff --git a/public/images/recaps/atelier-firis/43.jpg b/public/images/recaps/atelier-firis/43.jpg new file mode 100644 index 0000000..3cc92b3 Binary files /dev/null and b/public/images/recaps/atelier-firis/43.jpg differ diff --git a/public/images/recaps/atelier-firis/44.jpg b/public/images/recaps/atelier-firis/44.jpg new file mode 100644 index 0000000..463eb71 Binary files /dev/null and b/public/images/recaps/atelier-firis/44.jpg differ diff --git a/public/images/recaps/atelier-firis/45.jpg b/public/images/recaps/atelier-firis/45.jpg new file mode 100644 index 0000000..8ea4794 Binary files /dev/null and b/public/images/recaps/atelier-firis/45.jpg differ diff --git a/public/images/recaps/atelier-firis/46.jpg b/public/images/recaps/atelier-firis/46.jpg new file mode 100644 index 0000000..438f95d Binary files /dev/null and b/public/images/recaps/atelier-firis/46.jpg differ diff --git a/public/images/recaps/atelier-firis/47.jpg b/public/images/recaps/atelier-firis/47.jpg new file mode 100644 index 0000000..09418b3 Binary files /dev/null and b/public/images/recaps/atelier-firis/47.jpg differ diff --git a/public/images/recaps/atelier-firis/48.jpg b/public/images/recaps/atelier-firis/48.jpg new file mode 100644 index 0000000..30e1893 Binary files /dev/null and b/public/images/recaps/atelier-firis/48.jpg differ diff --git a/public/images/recaps/atelier-firis/49.jpg b/public/images/recaps/atelier-firis/49.jpg new file mode 100644 index 0000000..83b8427 Binary files /dev/null and b/public/images/recaps/atelier-firis/49.jpg differ diff --git a/public/images/recaps/atelier-firis/50.jpg b/public/images/recaps/atelier-firis/50.jpg new file mode 100644 index 0000000..3c91926 Binary files /dev/null and b/public/images/recaps/atelier-firis/50.jpg differ diff --git a/public/images/recaps/atelier-firis/51.jpg b/public/images/recaps/atelier-firis/51.jpg new file mode 100644 index 0000000..52cda94 Binary files /dev/null and b/public/images/recaps/atelier-firis/51.jpg differ diff --git a/public/images/recaps/atelier-firis/52.jpg b/public/images/recaps/atelier-firis/52.jpg new file mode 100644 index 0000000..bd7568f Binary files /dev/null and b/public/images/recaps/atelier-firis/52.jpg differ diff --git a/public/images/recaps/atelier-firis/53.jpg b/public/images/recaps/atelier-firis/53.jpg new file mode 100644 index 0000000..47cb1cf Binary files /dev/null and b/public/images/recaps/atelier-firis/53.jpg differ diff --git a/public/images/recaps/atelier-firis/54.jpg b/public/images/recaps/atelier-firis/54.jpg new file mode 100644 index 0000000..9744ff0 Binary files /dev/null and b/public/images/recaps/atelier-firis/54.jpg differ diff --git a/public/images/recaps/atelier-firis/55.jpg b/public/images/recaps/atelier-firis/55.jpg new file mode 100644 index 0000000..46d0738 Binary files /dev/null and b/public/images/recaps/atelier-firis/55.jpg differ diff --git a/public/images/recaps/atelier-firis/56.jpg b/public/images/recaps/atelier-firis/56.jpg new file mode 100644 index 0000000..2fa2ca4 Binary files /dev/null and b/public/images/recaps/atelier-firis/56.jpg differ diff --git a/public/images/recaps/atelier-firis/57.jpg b/public/images/recaps/atelier-firis/57.jpg new file mode 100644 index 0000000..32874b4 Binary files /dev/null and b/public/images/recaps/atelier-firis/57.jpg differ diff --git a/public/images/recaps/atelier-firis/58.jpg b/public/images/recaps/atelier-firis/58.jpg new file mode 100644 index 0000000..551d4d7 Binary files /dev/null and b/public/images/recaps/atelier-firis/58.jpg differ diff --git a/public/images/recaps/atelier-firis/59.jpg b/public/images/recaps/atelier-firis/59.jpg new file mode 100644 index 0000000..797e3ae Binary files /dev/null and b/public/images/recaps/atelier-firis/59.jpg differ diff --git a/public/images/recaps/atelier-firis/60.jpg b/public/images/recaps/atelier-firis/60.jpg new file mode 100644 index 0000000..f389dd4 Binary files /dev/null and b/public/images/recaps/atelier-firis/60.jpg differ diff --git a/public/images/recaps/atelier-firis/61.jpg b/public/images/recaps/atelier-firis/61.jpg new file mode 100644 index 0000000..6b86bb1 Binary files /dev/null and b/public/images/recaps/atelier-firis/61.jpg differ diff --git a/public/images/recaps/atelier-firis/62.jpg b/public/images/recaps/atelier-firis/62.jpg new file mode 100644 index 0000000..fb28691 Binary files /dev/null and b/public/images/recaps/atelier-firis/62.jpg differ diff --git a/public/images/recaps/atelier-firis/63.jpg b/public/images/recaps/atelier-firis/63.jpg new file mode 100644 index 0000000..ad93243 Binary files /dev/null and b/public/images/recaps/atelier-firis/63.jpg differ diff --git a/public/images/recaps/atelier-firis/64.jpg b/public/images/recaps/atelier-firis/64.jpg new file mode 100644 index 0000000..b6fbd6e Binary files /dev/null and b/public/images/recaps/atelier-firis/64.jpg differ diff --git a/public/images/recaps/atelier-firis/65.jpg b/public/images/recaps/atelier-firis/65.jpg new file mode 100644 index 0000000..785e6ac Binary files /dev/null and b/public/images/recaps/atelier-firis/65.jpg differ diff --git a/public/images/recaps/atelier-firis/66.jpg b/public/images/recaps/atelier-firis/66.jpg new file mode 100644 index 0000000..65285e2 Binary files /dev/null and b/public/images/recaps/atelier-firis/66.jpg differ diff --git a/public/images/recaps/atelier-firis/67.jpg b/public/images/recaps/atelier-firis/67.jpg new file mode 100644 index 0000000..d839ea8 Binary files /dev/null and b/public/images/recaps/atelier-firis/67.jpg differ diff --git a/public/images/recaps/atelier-firis/68.jpg b/public/images/recaps/atelier-firis/68.jpg new file mode 100644 index 0000000..a18ac17 Binary files /dev/null and b/public/images/recaps/atelier-firis/68.jpg differ diff --git a/public/images/recaps/atelier-firis/69.jpg b/public/images/recaps/atelier-firis/69.jpg new file mode 100644 index 0000000..f9c6677 Binary files /dev/null and b/public/images/recaps/atelier-firis/69.jpg differ diff --git a/public/images/recaps/atelier-firis/70.jpg b/public/images/recaps/atelier-firis/70.jpg new file mode 100644 index 0000000..ad3cb66 Binary files /dev/null and b/public/images/recaps/atelier-firis/70.jpg differ diff --git a/public/images/recaps/atelier-firis/71.jpg b/public/images/recaps/atelier-firis/71.jpg new file mode 100644 index 0000000..1352f94 Binary files /dev/null and b/public/images/recaps/atelier-firis/71.jpg differ diff --git a/public/images/recaps/atelier-firis/72.jpg b/public/images/recaps/atelier-firis/72.jpg new file mode 100644 index 0000000..59f05cb Binary files /dev/null and b/public/images/recaps/atelier-firis/72.jpg differ diff --git a/public/images/recaps/atelier-firis/73.jpg b/public/images/recaps/atelier-firis/73.jpg new file mode 100644 index 0000000..58180a8 Binary files /dev/null and b/public/images/recaps/atelier-firis/73.jpg differ diff --git a/public/images/recaps/atelier-firis/74.jpg b/public/images/recaps/atelier-firis/74.jpg new file mode 100644 index 0000000..0276713 Binary files /dev/null and b/public/images/recaps/atelier-firis/74.jpg differ diff --git a/public/images/recaps/atelier-firis/75.jpg b/public/images/recaps/atelier-firis/75.jpg new file mode 100644 index 0000000..e218c55 Binary files /dev/null and b/public/images/recaps/atelier-firis/75.jpg differ diff --git a/public/images/recaps/atelier-firis/76.jpg b/public/images/recaps/atelier-firis/76.jpg new file mode 100644 index 0000000..c00ff26 Binary files /dev/null and b/public/images/recaps/atelier-firis/76.jpg differ diff --git a/public/images/recaps/atelier-firis/77.jpg b/public/images/recaps/atelier-firis/77.jpg new file mode 100644 index 0000000..3b212b4 Binary files /dev/null and b/public/images/recaps/atelier-firis/77.jpg differ diff --git a/public/images/recaps/atelier-firis/78.jpg b/public/images/recaps/atelier-firis/78.jpg new file mode 100644 index 0000000..dbbbbdb Binary files /dev/null and b/public/images/recaps/atelier-firis/78.jpg differ diff --git a/public/images/recaps/atelier-firis/79.jpg b/public/images/recaps/atelier-firis/79.jpg new file mode 100644 index 0000000..85d180b Binary files /dev/null and b/public/images/recaps/atelier-firis/79.jpg differ diff --git a/public/images/recaps/atelier-firis/80.jpg b/public/images/recaps/atelier-firis/80.jpg new file mode 100644 index 0000000..420ee1c Binary files /dev/null and b/public/images/recaps/atelier-firis/80.jpg differ diff --git a/public/images/recaps/atelier-firis/81.jpg b/public/images/recaps/atelier-firis/81.jpg new file mode 100644 index 0000000..fe67c58 Binary files /dev/null and b/public/images/recaps/atelier-firis/81.jpg differ diff --git a/public/images/recaps/atelier-firis/82.jpg b/public/images/recaps/atelier-firis/82.jpg new file mode 100644 index 0000000..7c31ac2 Binary files /dev/null and b/public/images/recaps/atelier-firis/82.jpg differ diff --git a/public/images/recaps/atelier-firis/83.jpg b/public/images/recaps/atelier-firis/83.jpg new file mode 100644 index 0000000..6250c59 Binary files /dev/null and b/public/images/recaps/atelier-firis/83.jpg differ diff --git a/public/images/recaps/atelier-firis/84.jpg b/public/images/recaps/atelier-firis/84.jpg new file mode 100644 index 0000000..b3cbc33 Binary files /dev/null and b/public/images/recaps/atelier-firis/84.jpg differ diff --git a/public/images/recaps/atelier-firis/85.jpg b/public/images/recaps/atelier-firis/85.jpg new file mode 100644 index 0000000..9ce63dd Binary files /dev/null and b/public/images/recaps/atelier-firis/85.jpg differ diff --git a/public/images/recaps/atelier-firis/86.jpg b/public/images/recaps/atelier-firis/86.jpg new file mode 100644 index 0000000..1548864 Binary files /dev/null and b/public/images/recaps/atelier-firis/86.jpg differ diff --git a/public/images/recaps/atelier-firis/87.jpg b/public/images/recaps/atelier-firis/87.jpg new file mode 100644 index 0000000..45826a2 Binary files /dev/null and b/public/images/recaps/atelier-firis/87.jpg differ diff --git a/public/images/recaps/atelier-firis/88.jpg b/public/images/recaps/atelier-firis/88.jpg new file mode 100644 index 0000000..c2d6763 Binary files /dev/null and b/public/images/recaps/atelier-firis/88.jpg differ diff --git a/public/images/recaps/atelier-firis/89.jpg b/public/images/recaps/atelier-firis/89.jpg new file mode 100644 index 0000000..9decf1f Binary files /dev/null and b/public/images/recaps/atelier-firis/89.jpg differ diff --git a/public/images/recaps/atelier-firis/90.jpg b/public/images/recaps/atelier-firis/90.jpg new file mode 100644 index 0000000..c01e4df Binary files /dev/null and b/public/images/recaps/atelier-firis/90.jpg differ diff --git a/public/images/recaps/atelier-firis/91.jpg b/public/images/recaps/atelier-firis/91.jpg new file mode 100644 index 0000000..7d0323a Binary files /dev/null and b/public/images/recaps/atelier-firis/91.jpg differ diff --git a/public/images/recaps/atelier-firis/92.jpg b/public/images/recaps/atelier-firis/92.jpg new file mode 100644 index 0000000..020ac62 Binary files /dev/null and b/public/images/recaps/atelier-firis/92.jpg differ diff --git a/public/images/recaps/atelier-firis/93.jpg b/public/images/recaps/atelier-firis/93.jpg new file mode 100644 index 0000000..7f36606 Binary files /dev/null and b/public/images/recaps/atelier-firis/93.jpg differ diff --git a/public/images/recaps/the-best-way-to-learn-css/css-best-browser.png b/public/images/recaps/the-best-way-to-learn-css/css-best-browser.png new file mode 100644 index 0000000..3177963 Binary files /dev/null and b/public/images/recaps/the-best-way-to-learn-css/css-best-browser.png differ diff --git a/public/images/recaps/the-best-way-to-learn-css/css-best-class-selector-markup.png b/public/images/recaps/the-best-way-to-learn-css/css-best-class-selector-markup.png new file mode 100644 index 0000000..5aa2d9d Binary files /dev/null and b/public/images/recaps/the-best-way-to-learn-css/css-best-class-selector-markup.png differ diff --git a/public/images/recaps/the-best-way-to-learn-css/css-best-class-selector.png b/public/images/recaps/the-best-way-to-learn-css/css-best-class-selector.png new file mode 100644 index 0000000..f526581 Binary files /dev/null and b/public/images/recaps/the-best-way-to-learn-css/css-best-class-selector.png differ diff --git a/public/images/recaps/the-best-way-to-learn-css/css-best-codeacademy.png b/public/images/recaps/the-best-way-to-learn-css/css-best-codeacademy.png new file mode 100644 index 0000000..6f83bc4 Binary files /dev/null and b/public/images/recaps/the-best-way-to-learn-css/css-best-codeacademy.png differ diff --git a/public/images/recaps/the-best-way-to-learn-css/css-best-codepen.png b/public/images/recaps/the-best-way-to-learn-css/css-best-codepen.png new file mode 100644 index 0000000..2e145c9 Binary files /dev/null and b/public/images/recaps/the-best-way-to-learn-css/css-best-codepen.png differ diff --git a/public/images/recaps/the-best-way-to-learn-css/css-best-css-book.png b/public/images/recaps/the-best-way-to-learn-css/css-best-css-book.png new file mode 100644 index 0000000..ffd4110 Binary files /dev/null and b/public/images/recaps/the-best-way-to-learn-css/css-best-css-book.png differ diff --git a/public/images/recaps/the-best-way-to-learn-css/css-best-font-size.png b/public/images/recaps/the-best-way-to-learn-css/css-best-font-size.png new file mode 100644 index 0000000..efdf09c Binary files /dev/null and b/public/images/recaps/the-best-way-to-learn-css/css-best-font-size.png differ diff --git a/public/images/recaps/the-best-way-to-learn-css/css-best-property-value.png b/public/images/recaps/the-best-way-to-learn-css/css-best-property-value.png new file mode 100644 index 0000000..a8c8bcb Binary files /dev/null and b/public/images/recaps/the-best-way-to-learn-css/css-best-property-value.png differ diff --git a/public/images/recaps/the-best-way-to-learn-css/css-best-rule.png b/public/images/recaps/the-best-way-to-learn-css/css-best-rule.png new file mode 100644 index 0000000..e7bd812 Binary files /dev/null and b/public/images/recaps/the-best-way-to-learn-css/css-best-rule.png differ diff --git a/public/images/recaps/the-best-way-to-learn-css/css-best-selector-declaration.png b/public/images/recaps/the-best-way-to-learn-css/css-best-selector-declaration.png new file mode 100644 index 0000000..6b0ce31 Binary files /dev/null and b/public/images/recaps/the-best-way-to-learn-css/css-best-selector-declaration.png differ diff --git a/public/images/recaps/the-best-way-to-learn-css/css-best-stormtrooper.png b/public/images/recaps/the-best-way-to-learn-css/css-best-stormtrooper.png new file mode 100644 index 0000000..331e519 Binary files /dev/null and b/public/images/recaps/the-best-way-to-learn-css/css-best-stormtrooper.png differ diff --git a/public/images/recaps/the-best-way-to-learn-css/css-best-type-selector.png b/public/images/recaps/the-best-way-to-learn-css/css-best-type-selector.png new file mode 100644 index 0000000..1d1bf40 Binary files /dev/null and b/public/images/recaps/the-best-way-to-learn-css/css-best-type-selector.png differ diff --git a/public/images/recaps/the-best-way-to-learn-css/css-best-zen.png b/public/images/recaps/the-best-way-to-learn-css/css-best-zen.png new file mode 100644 index 0000000..dfac6a4 Binary files /dev/null and b/public/images/recaps/the-best-way-to-learn-css/css-best-zen.png differ diff --git a/public/images/recaps/the-best-way-to-learn-css/secret.png b/public/images/recaps/the-best-way-to-learn-css/secret.png new file mode 100644 index 0000000..689b1d4 Binary files /dev/null and b/public/images/recaps/the-best-way-to-learn-css/secret.png differ diff --git a/public/images/recaps/the-best-way-to-learn-css/tutsplus.png b/public/images/recaps/the-best-way-to-learn-css/tutsplus.png new file mode 100644 index 0000000..b857bc6 Binary files /dev/null and b/public/images/recaps/the-best-way-to-learn-css/tutsplus.png differ diff --git a/public/images/slide/first-three-month-in-oneapm/01.jpg b/public/images/slide/first-three-month-in-oneapm/01.jpg new file mode 100644 index 0000000..198274d Binary files /dev/null and b/public/images/slide/first-three-month-in-oneapm/01.jpg differ diff --git a/public/images/slide/first-three-month-in-oneapm/02.jpg b/public/images/slide/first-three-month-in-oneapm/02.jpg new file mode 100644 index 0000000..281cf6f Binary files /dev/null and b/public/images/slide/first-three-month-in-oneapm/02.jpg differ diff --git a/public/images/slide/first-three-month-in-oneapm/03.jpg b/public/images/slide/first-three-month-in-oneapm/03.jpg new file mode 100644 index 0000000..e297684 Binary files /dev/null and b/public/images/slide/first-three-month-in-oneapm/03.jpg differ diff --git a/public/images/slide/first-three-month-in-oneapm/04.jpg b/public/images/slide/first-three-month-in-oneapm/04.jpg new file mode 100644 index 0000000..21f543f Binary files /dev/null and b/public/images/slide/first-three-month-in-oneapm/04.jpg differ diff --git a/public/images/slide/first-three-month-in-oneapm/05.jpg b/public/images/slide/first-three-month-in-oneapm/05.jpg new file mode 100644 index 0000000..54672ab Binary files /dev/null and b/public/images/slide/first-three-month-in-oneapm/05.jpg differ diff --git a/public/images/slide/first-three-month-in-oneapm/06.jpg b/public/images/slide/first-three-month-in-oneapm/06.jpg new file mode 100644 index 0000000..693bfa1 Binary files /dev/null and b/public/images/slide/first-three-month-in-oneapm/06.jpg differ diff --git a/public/images/slide/first-three-month-in-oneapm/07.jpg b/public/images/slide/first-three-month-in-oneapm/07.jpg new file mode 100644 index 0000000..363931e Binary files /dev/null and b/public/images/slide/first-three-month-in-oneapm/07.jpg differ diff --git a/public/images/slide/first-three-month-in-oneapm/08.jpg b/public/images/slide/first-three-month-in-oneapm/08.jpg new file mode 100644 index 0000000..f4f8d74 Binary files /dev/null and b/public/images/slide/first-three-month-in-oneapm/08.jpg differ diff --git a/public/images/slide/first-three-month-in-oneapm/09.jpg b/public/images/slide/first-three-month-in-oneapm/09.jpg new file mode 100644 index 0000000..b11c8d4 Binary files /dev/null and b/public/images/slide/first-three-month-in-oneapm/09.jpg differ diff --git a/public/images/slide/first-three-month-in-oneapm/10.jpg b/public/images/slide/first-three-month-in-oneapm/10.jpg new file mode 100644 index 0000000..cdba4aa Binary files /dev/null and b/public/images/slide/first-three-month-in-oneapm/10.jpg differ diff --git a/public/images/slide/first-three-month-in-oneapm/11.jpg b/public/images/slide/first-three-month-in-oneapm/11.jpg new file mode 100644 index 0000000..fbfd262 Binary files /dev/null and b/public/images/slide/first-three-month-in-oneapm/11.jpg differ diff --git a/public/images/slide/first-three-month-in-oneapm/12.jpg b/public/images/slide/first-three-month-in-oneapm/12.jpg new file mode 100644 index 0000000..bc019d7 Binary files /dev/null and b/public/images/slide/first-three-month-in-oneapm/12.jpg differ diff --git a/public/images/slide/first-three-month-in-oneapm/13.jpg b/public/images/slide/first-three-month-in-oneapm/13.jpg new file mode 100644 index 0000000..dcd4132 Binary files /dev/null and b/public/images/slide/first-three-month-in-oneapm/13.jpg differ diff --git a/public/images/slide/first-three-month-in-oneapm/14.jpg b/public/images/slide/first-three-month-in-oneapm/14.jpg new file mode 100644 index 0000000..d2bea29 Binary files /dev/null and b/public/images/slide/first-three-month-in-oneapm/14.jpg differ diff --git a/public/images/slide/first-three-month-in-oneapm/15.jpg b/public/images/slide/first-three-month-in-oneapm/15.jpg new file mode 100644 index 0000000..41d4cef Binary files /dev/null and b/public/images/slide/first-three-month-in-oneapm/15.jpg differ diff --git a/public/images/slide/first-three-month-in-oneapm/16.jpg b/public/images/slide/first-three-month-in-oneapm/16.jpg new file mode 100644 index 0000000..a3b06e0 Binary files /dev/null and b/public/images/slide/first-three-month-in-oneapm/16.jpg differ diff --git a/public/images/slide/first-three-month-in-oneapm/17.jpg b/public/images/slide/first-three-month-in-oneapm/17.jpg new file mode 100644 index 0000000..9e13a77 Binary files /dev/null and b/public/images/slide/first-three-month-in-oneapm/17.jpg differ diff --git a/public/images/slide/first-three-month-in-oneapm/18.jpg b/public/images/slide/first-three-month-in-oneapm/18.jpg new file mode 100644 index 0000000..e5a956b Binary files /dev/null and b/public/images/slide/first-three-month-in-oneapm/18.jpg differ diff --git a/public/images/slide/first-three-month-in-oneapm/19.jpg b/public/images/slide/first-three-month-in-oneapm/19.jpg new file mode 100644 index 0000000..ba1ab14 Binary files /dev/null and b/public/images/slide/first-three-month-in-oneapm/19.jpg differ diff --git a/public/images/slide/spring-boot-intro/01.jpg b/public/images/slide/spring-boot-intro/01.jpg new file mode 100644 index 0000000..c34b292 Binary files /dev/null and b/public/images/slide/spring-boot-intro/01.jpg differ diff --git a/public/images/slide/spring-boot-intro/02.jpg b/public/images/slide/spring-boot-intro/02.jpg new file mode 100644 index 0000000..aa70d84 Binary files /dev/null and b/public/images/slide/spring-boot-intro/02.jpg differ diff --git a/public/images/slide/spring-boot-intro/03.jpg b/public/images/slide/spring-boot-intro/03.jpg new file mode 100644 index 0000000..2911b43 Binary files /dev/null and b/public/images/slide/spring-boot-intro/03.jpg differ diff --git a/public/images/slide/spring-boot-intro/04.jpg b/public/images/slide/spring-boot-intro/04.jpg new file mode 100644 index 0000000..da52579 Binary files /dev/null and b/public/images/slide/spring-boot-intro/04.jpg differ diff --git a/public/images/slide/spring-boot-intro/05.jpg b/public/images/slide/spring-boot-intro/05.jpg new file mode 100644 index 0000000..4ee05f1 Binary files /dev/null and b/public/images/slide/spring-boot-intro/05.jpg differ diff --git a/public/images/slide/spring-boot-intro/06.jpg b/public/images/slide/spring-boot-intro/06.jpg new file mode 100644 index 0000000..792ee06 Binary files /dev/null and b/public/images/slide/spring-boot-intro/06.jpg differ diff --git a/public/images/slide/spring-boot-intro/07.jpg b/public/images/slide/spring-boot-intro/07.jpg new file mode 100644 index 0000000..c713633 Binary files /dev/null and b/public/images/slide/spring-boot-intro/07.jpg differ diff --git a/public/images/slide/spring-boot-intro/08.jpg b/public/images/slide/spring-boot-intro/08.jpg new file mode 100644 index 0000000..7a94cb6 Binary files /dev/null and b/public/images/slide/spring-boot-intro/08.jpg differ diff --git a/public/images/slide/spring-boot-intro/09.jpg b/public/images/slide/spring-boot-intro/09.jpg new file mode 100644 index 0000000..efb8f16 Binary files /dev/null and b/public/images/slide/spring-boot-intro/09.jpg differ diff --git a/public/images/slide/spring-boot-intro/10.jpg b/public/images/slide/spring-boot-intro/10.jpg new file mode 100644 index 0000000..f32eb96 Binary files /dev/null and b/public/images/slide/spring-boot-intro/10.jpg differ diff --git a/public/images/slide/spring-boot-intro/11.jpg b/public/images/slide/spring-boot-intro/11.jpg new file mode 100644 index 0000000..4c8f170 Binary files /dev/null and b/public/images/slide/spring-boot-intro/11.jpg differ diff --git a/public/images/slide/spring-boot-intro/12.jpg b/public/images/slide/spring-boot-intro/12.jpg new file mode 100644 index 0000000..3478bfc Binary files /dev/null and b/public/images/slide/spring-boot-intro/12.jpg differ diff --git a/public/images/slide/spring-boot-intro/13.jpg b/public/images/slide/spring-boot-intro/13.jpg new file mode 100644 index 0000000..3785c55 Binary files /dev/null and b/public/images/slide/spring-boot-intro/13.jpg differ diff --git a/public/images/slide/spring-boot-intro/14.jpg b/public/images/slide/spring-boot-intro/14.jpg new file mode 100644 index 0000000..ff09aa8 Binary files /dev/null and b/public/images/slide/spring-boot-intro/14.jpg differ diff --git a/public/images/slide/spring-boot-intro/15.jpg b/public/images/slide/spring-boot-intro/15.jpg new file mode 100644 index 0000000..a99b18a Binary files /dev/null and b/public/images/slide/spring-boot-intro/15.jpg differ diff --git a/public/images/slide/spring-boot-intro/16.jpg b/public/images/slide/spring-boot-intro/16.jpg new file mode 100644 index 0000000..d7603e8 Binary files /dev/null and b/public/images/slide/spring-boot-intro/16.jpg differ diff --git a/public/images/slide/spring-boot-intro/17.jpg b/public/images/slide/spring-boot-intro/17.jpg new file mode 100644 index 0000000..8b74844 Binary files /dev/null and b/public/images/slide/spring-boot-intro/17.jpg differ diff --git a/public/images/slide/spring-boot-intro/18.jpg b/public/images/slide/spring-boot-intro/18.jpg new file mode 100644 index 0000000..d4bd8df Binary files /dev/null and b/public/images/slide/spring-boot-intro/18.jpg differ diff --git a/public/images/slide/spring-boot-intro/19.jpg b/public/images/slide/spring-boot-intro/19.jpg new file mode 100644 index 0000000..6af3d73 Binary files /dev/null and b/public/images/slide/spring-boot-intro/19.jpg differ diff --git a/public/images/slide/spring-boot-intro/20.jpg b/public/images/slide/spring-boot-intro/20.jpg new file mode 100644 index 0000000..797afba Binary files /dev/null and b/public/images/slide/spring-boot-intro/20.jpg differ diff --git a/public/images/slide/spring-boot-intro/21.jpg b/public/images/slide/spring-boot-intro/21.jpg new file mode 100644 index 0000000..172175a Binary files /dev/null and b/public/images/slide/spring-boot-intro/21.jpg differ diff --git a/public/images/slide/spring-boot-intro/22.jpg b/public/images/slide/spring-boot-intro/22.jpg new file mode 100644 index 0000000..24e675a Binary files /dev/null and b/public/images/slide/spring-boot-intro/22.jpg differ diff --git a/public/images/slide/spring-boot-intro/23.jpg b/public/images/slide/spring-boot-intro/23.jpg new file mode 100644 index 0000000..76d597a Binary files /dev/null and b/public/images/slide/spring-boot-intro/23.jpg differ diff --git a/public/images/slide/spring-boot-intro/24.jpg b/public/images/slide/spring-boot-intro/24.jpg new file mode 100644 index 0000000..093b87b Binary files /dev/null and b/public/images/slide/spring-boot-intro/24.jpg differ diff --git a/public/images/slide/spring-boot-intro/25.jpg b/public/images/slide/spring-boot-intro/25.jpg new file mode 100644 index 0000000..0bbf72e Binary files /dev/null and b/public/images/slide/spring-boot-intro/25.jpg differ diff --git a/public/images/slide/spring-boot-intro/26.jpg b/public/images/slide/spring-boot-intro/26.jpg new file mode 100644 index 0000000..7cd6f82 Binary files /dev/null and b/public/images/slide/spring-boot-intro/26.jpg differ diff --git a/public/images/slide/spring-boot-intro/27.jpg b/public/images/slide/spring-boot-intro/27.jpg new file mode 100644 index 0000000..921ce1b Binary files /dev/null and b/public/images/slide/spring-boot-intro/27.jpg differ diff --git a/public/images/slide/spring-boot-intro/28.jpg b/public/images/slide/spring-boot-intro/28.jpg new file mode 100644 index 0000000..abc1c91 Binary files /dev/null and b/public/images/slide/spring-boot-intro/28.jpg differ diff --git a/public/images/slide/spring-boot-intro/29.jpg b/public/images/slide/spring-boot-intro/29.jpg new file mode 100644 index 0000000..9e26353 Binary files /dev/null and b/public/images/slide/spring-boot-intro/29.jpg differ diff --git a/public/images/slide/spring-boot-intro/30.jpg b/public/images/slide/spring-boot-intro/30.jpg new file mode 100644 index 0000000..e902595 Binary files /dev/null and b/public/images/slide/spring-boot-intro/30.jpg differ diff --git a/public/images/slide/spring-boot-intro/31.jpg b/public/images/slide/spring-boot-intro/31.jpg new file mode 100644 index 0000000..4668e35 Binary files /dev/null and b/public/images/slide/spring-boot-intro/31.jpg differ diff --git a/public/images/slide/spring-boot-intro/32.jpg b/public/images/slide/spring-boot-intro/32.jpg new file mode 100644 index 0000000..0d8ad13 Binary files /dev/null and b/public/images/slide/spring-boot-intro/32.jpg differ diff --git a/public/images/slide/spring-boot-intro/33.jpg b/public/images/slide/spring-boot-intro/33.jpg new file mode 100644 index 0000000..f0007c9 Binary files /dev/null and b/public/images/slide/spring-boot-intro/33.jpg differ diff --git a/public/images/slide/two-year-in-oneapm/01.jpg b/public/images/slide/two-year-in-oneapm/01.jpg new file mode 100644 index 0000000..48202f6 Binary files /dev/null and b/public/images/slide/two-year-in-oneapm/01.jpg differ diff --git a/public/images/slide/two-year-in-oneapm/02.jpg b/public/images/slide/two-year-in-oneapm/02.jpg new file mode 100644 index 0000000..78084a0 Binary files /dev/null and b/public/images/slide/two-year-in-oneapm/02.jpg differ diff --git a/public/images/slide/two-year-in-oneapm/03.jpg b/public/images/slide/two-year-in-oneapm/03.jpg new file mode 100644 index 0000000..c838e8c Binary files /dev/null and b/public/images/slide/two-year-in-oneapm/03.jpg differ diff --git a/public/images/slide/two-year-in-oneapm/04.jpg b/public/images/slide/two-year-in-oneapm/04.jpg new file mode 100644 index 0000000..5d31a55 Binary files /dev/null and b/public/images/slide/two-year-in-oneapm/04.jpg differ diff --git a/public/images/slide/two-year-in-oneapm/05.jpg b/public/images/slide/two-year-in-oneapm/05.jpg new file mode 100644 index 0000000..d6f49e3 Binary files /dev/null and b/public/images/slide/two-year-in-oneapm/05.jpg differ diff --git a/public/images/slide/two-year-in-oneapm/06.jpg b/public/images/slide/two-year-in-oneapm/06.jpg new file mode 100644 index 0000000..b0b3969 Binary files /dev/null and b/public/images/slide/two-year-in-oneapm/06.jpg differ diff --git a/public/images/slide/two-year-in-oneapm/07.jpg b/public/images/slide/two-year-in-oneapm/07.jpg new file mode 100644 index 0000000..d1208de Binary files /dev/null and b/public/images/slide/two-year-in-oneapm/07.jpg differ diff --git a/public/images/slide/two-year-in-oneapm/08.jpg b/public/images/slide/two-year-in-oneapm/08.jpg new file mode 100644 index 0000000..41ef518 Binary files /dev/null and b/public/images/slide/two-year-in-oneapm/08.jpg differ diff --git a/public/images/slide/two-year-in-oneapm/09.jpg b/public/images/slide/two-year-in-oneapm/09.jpg new file mode 100644 index 0000000..99f57d5 Binary files /dev/null and b/public/images/slide/two-year-in-oneapm/09.jpg differ diff --git a/public/images/slide/two-year-in-oneapm/10.jpg b/public/images/slide/two-year-in-oneapm/10.jpg new file mode 100644 index 0000000..9019867 Binary files /dev/null and b/public/images/slide/two-year-in-oneapm/10.jpg differ diff --git a/public/images/slide/two-year-in-oneapm/11.jpg b/public/images/slide/two-year-in-oneapm/11.jpg new file mode 100644 index 0000000..2da6420 Binary files /dev/null and b/public/images/slide/two-year-in-oneapm/11.jpg differ diff --git a/public/images/slide/two-year-in-oneapm/12.jpg b/public/images/slide/two-year-in-oneapm/12.jpg new file mode 100644 index 0000000..3eb1488 Binary files /dev/null and b/public/images/slide/two-year-in-oneapm/12.jpg differ diff --git a/public/images/slide/two-year-in-oneapm/13.jpg b/public/images/slide/two-year-in-oneapm/13.jpg new file mode 100644 index 0000000..8f7b043 Binary files /dev/null and b/public/images/slide/two-year-in-oneapm/13.jpg differ diff --git a/public/images/slide/two-year-in-oneapm/14.jpg b/public/images/slide/two-year-in-oneapm/14.jpg new file mode 100644 index 0000000..784aed3 Binary files /dev/null and b/public/images/slide/two-year-in-oneapm/14.jpg differ diff --git a/public/images/slide/two-year-in-oneapm/15.jpg b/public/images/slide/two-year-in-oneapm/15.jpg new file mode 100644 index 0000000..788d8e3 Binary files /dev/null and b/public/images/slide/two-year-in-oneapm/15.jpg differ diff --git a/public/images/slide/two-year-in-oneapm/16.jpg b/public/images/slide/two-year-in-oneapm/16.jpg new file mode 100644 index 0000000..6b8adf4 Binary files /dev/null and b/public/images/slide/two-year-in-oneapm/16.jpg differ diff --git a/public/images/slide/two-year-in-oneapm/17.jpg b/public/images/slide/two-year-in-oneapm/17.jpg new file mode 100644 index 0000000..dd4f6a1 Binary files /dev/null and b/public/images/slide/two-year-in-oneapm/17.jpg differ diff --git a/public/images/slide/two-year-in-oneapm/18.jpg b/public/images/slide/two-year-in-oneapm/18.jpg new file mode 100644 index 0000000..a7a6ea6 Binary files /dev/null and b/public/images/slide/two-year-in-oneapm/18.jpg differ diff --git a/public/images/slide/two-year-in-oneapm/19.jpg b/public/images/slide/two-year-in-oneapm/19.jpg new file mode 100644 index 0000000..5e60ef8 Binary files /dev/null and b/public/images/slide/two-year-in-oneapm/19.jpg differ diff --git a/public/images/slide/two-year-in-oneapm/20.jpg b/public/images/slide/two-year-in-oneapm/20.jpg new file mode 100644 index 0000000..47c787f Binary files /dev/null and b/public/images/slide/two-year-in-oneapm/20.jpg differ diff --git a/public/images/slide/two-year-in-oneapm/21.jpg b/public/images/slide/two-year-in-oneapm/21.jpg new file mode 100644 index 0000000..a3340ce Binary files /dev/null and b/public/images/slide/two-year-in-oneapm/21.jpg differ diff --git a/public/images/slide/two-year-in-oneapm/22.jpg b/public/images/slide/two-year-in-oneapm/22.jpg new file mode 100644 index 0000000..c510378 Binary files /dev/null and b/public/images/slide/two-year-in-oneapm/22.jpg differ diff --git a/public/images/slide/two-year-in-oneapm/23.jpg b/public/images/slide/two-year-in-oneapm/23.jpg new file mode 100644 index 0000000..9255e92 Binary files /dev/null and b/public/images/slide/two-year-in-oneapm/23.jpg differ diff --git a/public/images/slide/two-year-in-oneapm/24.jpg b/public/images/slide/two-year-in-oneapm/24.jpg new file mode 100644 index 0000000..4e81201 Binary files /dev/null and b/public/images/slide/two-year-in-oneapm/24.jpg differ diff --git a/public/images/slide/two-year-in-oneapm/25.jpg b/public/images/slide/two-year-in-oneapm/25.jpg new file mode 100644 index 0000000..088a7f4 Binary files /dev/null and b/public/images/slide/two-year-in-oneapm/25.jpg differ diff --git a/public/images/slide/two-year-in-oneapm/26.jpg b/public/images/slide/two-year-in-oneapm/26.jpg new file mode 100644 index 0000000..8fb5338 Binary files /dev/null and b/public/images/slide/two-year-in-oneapm/26.jpg differ diff --git a/public/images/slide/two-year-in-oneapm/27.jpg b/public/images/slide/two-year-in-oneapm/27.jpg new file mode 100644 index 0000000..c3652bb Binary files /dev/null and b/public/images/slide/two-year-in-oneapm/27.jpg differ diff --git a/public/images/slide/two-year-in-oneapm/28.jpg b/public/images/slide/two-year-in-oneapm/28.jpg new file mode 100644 index 0000000..6c14dd9 Binary files /dev/null and b/public/images/slide/two-year-in-oneapm/28.jpg differ diff --git a/public/images/slide/two-year-in-oneapm/29.jpg b/public/images/slide/two-year-in-oneapm/29.jpg new file mode 100644 index 0000000..0d45a15 Binary files /dev/null and b/public/images/slide/two-year-in-oneapm/29.jpg differ diff --git a/public/images/slide/two-year-in-oneapm/30.jpg b/public/images/slide/two-year-in-oneapm/30.jpg new file mode 100644 index 0000000..2159686 Binary files /dev/null and b/public/images/slide/two-year-in-oneapm/30.jpg differ diff --git a/public/images/slide/two-year-in-oneapm/31.jpg b/public/images/slide/two-year-in-oneapm/31.jpg new file mode 100644 index 0000000..7f0b834 Binary files /dev/null and b/public/images/slide/two-year-in-oneapm/31.jpg differ diff --git a/public/images/slide/two-year-in-oneapm/32.jpg b/public/images/slide/two-year-in-oneapm/32.jpg new file mode 100644 index 0000000..44325dc Binary files /dev/null and b/public/images/slide/two-year-in-oneapm/32.jpg differ diff --git a/public/images/slide/two-year-in-oneapm/33.jpg b/public/images/slide/two-year-in-oneapm/33.jpg new file mode 100644 index 0000000..f55ad01 Binary files /dev/null and b/public/images/slide/two-year-in-oneapm/33.jpg differ diff --git a/public/images/slide/two-year-in-oneapm/34.jpg b/public/images/slide/two-year-in-oneapm/34.jpg new file mode 100644 index 0000000..ff8caa4 Binary files /dev/null and b/public/images/slide/two-year-in-oneapm/34.jpg differ diff --git a/public/images/slide/two-year-in-oneapm/35.jpg b/public/images/slide/two-year-in-oneapm/35.jpg new file mode 100644 index 0000000..88ff566 Binary files /dev/null and b/public/images/slide/two-year-in-oneapm/35.jpg differ diff --git a/public/images/slide/two-year-in-oneapm/36.jpg b/public/images/slide/two-year-in-oneapm/36.jpg new file mode 100644 index 0000000..f79b70b Binary files /dev/null and b/public/images/slide/two-year-in-oneapm/36.jpg differ diff --git a/public/images/slide/two-year-in-oneapm/37.jpg b/public/images/slide/two-year-in-oneapm/37.jpg new file mode 100644 index 0000000..26d8245 Binary files /dev/null and b/public/images/slide/two-year-in-oneapm/37.jpg differ diff --git a/public/images/slide/two-year-in-oneapm/38.jpg b/public/images/slide/two-year-in-oneapm/38.jpg new file mode 100644 index 0000000..523cc16 Binary files /dev/null and b/public/images/slide/two-year-in-oneapm/38.jpg differ diff --git a/public/images/slide/two-year-in-oneapm/39.jpg b/public/images/slide/two-year-in-oneapm/39.jpg new file mode 100644 index 0000000..870cbc6 Binary files /dev/null and b/public/images/slide/two-year-in-oneapm/39.jpg differ diff --git a/public/images/slide/two-year-in-oneapm/40.jpg b/public/images/slide/two-year-in-oneapm/40.jpg new file mode 100644 index 0000000..8fe0867 Binary files /dev/null and b/public/images/slide/two-year-in-oneapm/40.jpg differ diff --git a/public/images/slide/two-year-in-oneapm/41.jpg b/public/images/slide/two-year-in-oneapm/41.jpg new file mode 100644 index 0000000..7f8ccfb Binary files /dev/null and b/public/images/slide/two-year-in-oneapm/41.jpg differ diff --git a/public/images/slide/two-year-in-oneapm/42.jpg b/public/images/slide/two-year-in-oneapm/42.jpg new file mode 100644 index 0000000..2ce1e08 Binary files /dev/null and b/public/images/slide/two-year-in-oneapm/42.jpg differ diff --git a/public/images/slide/two-year-in-oneapm/43.jpg b/public/images/slide/two-year-in-oneapm/43.jpg new file mode 100644 index 0000000..edce57f Binary files /dev/null and b/public/images/slide/two-year-in-oneapm/43.jpg differ diff --git a/public/images/slide/two-year-in-oneapm/44.jpg b/public/images/slide/two-year-in-oneapm/44.jpg new file mode 100644 index 0000000..90d25d2 Binary files /dev/null and b/public/images/slide/two-year-in-oneapm/44.jpg differ diff --git a/public/images/slide/two-year-in-oneapm/45.jpg b/public/images/slide/two-year-in-oneapm/45.jpg new file mode 100644 index 0000000..7b81745 Binary files /dev/null and b/public/images/slide/two-year-in-oneapm/45.jpg differ diff --git a/public/images/slide/two-year-in-oneapm/46.jpg b/public/images/slide/two-year-in-oneapm/46.jpg new file mode 100644 index 0000000..b6f2d76 Binary files /dev/null and b/public/images/slide/two-year-in-oneapm/46.jpg differ diff --git a/public/images/slide/two-year-in-oneapm/47.jpg b/public/images/slide/two-year-in-oneapm/47.jpg new file mode 100644 index 0000000..618b133 Binary files /dev/null and b/public/images/slide/two-year-in-oneapm/47.jpg differ diff --git a/public/images/slide/two-year-in-oneapm/48.jpg b/public/images/slide/two-year-in-oneapm/48.jpg new file mode 100644 index 0000000..85c6754 Binary files /dev/null and b/public/images/slide/two-year-in-oneapm/48.jpg differ diff --git a/public/images/slide/two-year-in-oneapm/49.jpg b/public/images/slide/two-year-in-oneapm/49.jpg new file mode 100644 index 0000000..2a60b46 Binary files /dev/null and b/public/images/slide/two-year-in-oneapm/49.jpg differ diff --git a/public/images/slide/two-year-in-oneapm/50.jpg b/public/images/slide/two-year-in-oneapm/50.jpg new file mode 100644 index 0000000..1fd55dd Binary files /dev/null and b/public/images/slide/two-year-in-oneapm/50.jpg differ diff --git a/public/images/slide/two-year-in-oneapm/51.jpg b/public/images/slide/two-year-in-oneapm/51.jpg new file mode 100644 index 0000000..f21e066 Binary files /dev/null and b/public/images/slide/two-year-in-oneapm/51.jpg differ diff --git a/public/images/slide/two-year-in-oneapm/52.jpg b/public/images/slide/two-year-in-oneapm/52.jpg new file mode 100644 index 0000000..4b1c685 Binary files /dev/null and b/public/images/slide/two-year-in-oneapm/52.jpg differ diff --git a/public/images/slide/two-year-in-oneapm/53.jpg b/public/images/slide/two-year-in-oneapm/53.jpg new file mode 100644 index 0000000..1630c71 Binary files /dev/null and b/public/images/slide/two-year-in-oneapm/53.jpg differ diff --git a/public/images/slide/two-year-in-oneapm/54.jpg b/public/images/slide/two-year-in-oneapm/54.jpg new file mode 100644 index 0000000..65e1538 Binary files /dev/null and b/public/images/slide/two-year-in-oneapm/54.jpg differ diff --git a/public/images/slide/two-year-in-oneapm/55.jpg b/public/images/slide/two-year-in-oneapm/55.jpg new file mode 100644 index 0000000..0b86ca3 Binary files /dev/null and b/public/images/slide/two-year-in-oneapm/55.jpg differ diff --git a/public/images/slide/two-year-in-oneapm/56.jpg b/public/images/slide/two-year-in-oneapm/56.jpg new file mode 100644 index 0000000..4080d4f Binary files /dev/null and b/public/images/slide/two-year-in-oneapm/56.jpg differ diff --git a/public/images/slide/two-year-in-oneapm/57.jpg b/public/images/slide/two-year-in-oneapm/57.jpg new file mode 100644 index 0000000..fbb8565 Binary files /dev/null and b/public/images/slide/two-year-in-oneapm/57.jpg differ diff --git a/public/images/slide/two-year-in-oneapm/58.jpg b/public/images/slide/two-year-in-oneapm/58.jpg new file mode 100644 index 0000000..32db9de Binary files /dev/null and b/public/images/slide/two-year-in-oneapm/58.jpg differ diff --git a/public/images/slide/two-year-in-oneapm/59.jpg b/public/images/slide/two-year-in-oneapm/59.jpg new file mode 100644 index 0000000..94a2d2f Binary files /dev/null and b/public/images/slide/two-year-in-oneapm/59.jpg differ diff --git a/public/images/slide/two-year-in-oneapm/60.jpg b/public/images/slide/two-year-in-oneapm/60.jpg new file mode 100644 index 0000000..468568a Binary files /dev/null and b/public/images/slide/two-year-in-oneapm/60.jpg differ diff --git a/public/images/slide/two-year-in-oneapm/61.jpg b/public/images/slide/two-year-in-oneapm/61.jpg new file mode 100644 index 0000000..80d1d4c Binary files /dev/null and b/public/images/slide/two-year-in-oneapm/61.jpg differ diff --git a/public/images/slide/two-year-in-oneapm/62.jpg b/public/images/slide/two-year-in-oneapm/62.jpg new file mode 100644 index 0000000..fdbdebd Binary files /dev/null and b/public/images/slide/two-year-in-oneapm/62.jpg differ diff --git a/public/images/slide/two-year-in-oneapm/63.jpg b/public/images/slide/two-year-in-oneapm/63.jpg new file mode 100644 index 0000000..112d85e Binary files /dev/null and b/public/images/slide/two-year-in-oneapm/63.jpg differ diff --git a/public/images/slide/two-year-in-oneapm/64.jpg b/public/images/slide/two-year-in-oneapm/64.jpg new file mode 100644 index 0000000..e75509a Binary files /dev/null and b/public/images/slide/two-year-in-oneapm/64.jpg differ diff --git a/public/images/slide/two-year-in-oneapm/65.jpg b/public/images/slide/two-year-in-oneapm/65.jpg new file mode 100644 index 0000000..424e586 Binary files /dev/null and b/public/images/slide/two-year-in-oneapm/65.jpg differ diff --git a/public/images/slide/two-year-in-oneapm/66.jpg b/public/images/slide/two-year-in-oneapm/66.jpg new file mode 100644 index 0000000..bd14013 Binary files /dev/null and b/public/images/slide/two-year-in-oneapm/66.jpg differ diff --git a/public/images/slide/two-year-in-oneapm/67.jpg b/public/images/slide/two-year-in-oneapm/67.jpg new file mode 100644 index 0000000..eaaf2b0 Binary files /dev/null and b/public/images/slide/two-year-in-oneapm/67.jpg differ diff --git a/public/images/slide/two-year-in-oneapm/68.jpg b/public/images/slide/two-year-in-oneapm/68.jpg new file mode 100644 index 0000000..e5bdaca Binary files /dev/null and b/public/images/slide/two-year-in-oneapm/68.jpg differ diff --git a/public/logo.svg b/public/logo.svg new file mode 100644 index 0000000..6dc0bd9 --- /dev/null +++ b/public/logo.svg @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<svg width="300px" height="300px" viewBox="0 0 300 300" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <title>logo</title> + <g id="logo" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> + <g id="logo-white" transform="translate(8, 15)"> + <path d="M95.5479774,135.486962 C100.290716,134.547617 104.46066,134.627395 108.053294,135.772127 C113.966407,137.656241 116.468525,139.552508 119.527601,143.942864 C121.544778,146.837896 123.197824,151.954965 124.547977,159.269051 C121.480628,160.074879 118.922174,160.051421 116.898234,159.066848 C113.281243,157.307314 109.930013,154.854322 105.030874,149.36204 C101.920908,145.875547 98.7620867,141.249025 95.5479774,135.486962 Z" id="font1-dot" fill="#E87777"></path> + <path d="M47.5587025,42.6413499 L59.4150545,57.2519576 C58.8684637,57.9832966 58.3430156,58.6485661 57.8388914,59.2870617 C55.7842658,61.889336 54.0749685,64.0703301 52.6932724,68.234464 C52.3972743,69.1265385 52.1127855,69.9469062 51.8354808,70.7466353 C51.7762919,70.9173323 51.7174272,71.0870945 51.6583785,71.2577622 L51.4080304,71.9847059 L51.2428469,72.4700919 C51.2170703,72.5463221 51.1913289,72.6226961 51.1656192,72.6992573 L51.0117106,73.1612194 C49.9365927,76.4155491 48.9042374,80.1534684 47.6422403,87.5937801 C47.5786111,87.9689161 47.5175344,88.3349742 47.4594861,88.6914196 C47.8205566,88.7052825 48.1824457,88.7272292 48.5448346,88.7575303 C53.2985413,89.1550102 57.7287004,90.9558044 61.2274422,93.4383815 C64.9191616,96.0578882 67.5904277,99.4358643 68.421524,102.73783 C70.6242525,111.489322 68.0433783,128.18177 66.7604391,136.604682 C66.5760113,137.81551 66.4172222,138.858235 66.3012834,139.686204 C66.2016412,140.397791 66.0872369,141.256287 65.9581638,142.224941 C65.5876098,145.005838 65.0955267,148.699702 64.4838444,152.424745 L64.3361424,153.310702 C64.2920666,153.57103 64.247405,153.831182 64.202602,154.088327 L64.0647364,154.867719 C63.0203572,160.682068 61.8345775,166.290495 60.1402991,167.372933 C59.1659482,167.995425 58.1852887,168.319837 57.1912629,168.319837 C56.356509,168.319837 55.5191232,168.092016 54.6748194,167.653082 L56.5363189,133.786424 L56.5363189,118.952805 C56.5363189,115.701061 55.1263855,110.807176 52.875941,107.070037 C50.9302372,103.838957 48.3629758,101.576275 45.6552368,101.494204 C45.3655232,101.485423 45.0759031,101.501657 44.7872246,101.541493 C44.7393205,101.794983 44.6910298,102.05047 44.6423463,102.307982 C44.2216556,104.533231 43.8288356,106.607074 43.4615123,108.546312 C40.7188824,123.025681 39.3957424,130.014727 38.5058473,136.482186 L38.3992705,137.269874 L38.2472267,138.442822 C37.7369337,142.485349 37.3583969,146.599603 36.8681523,152.512401 L36.7720733,153.676454 C36.6744698,154.863818 36.5720959,156.122519 36.4631876,157.465038 C34.6411838,179.924984 34.6459097,194.343019 36.4678788,208.691721 C36.9300999,209.475926 37.2387054,209.829551 37.5996095,210.243082 C38.0153708,210.719468 38.5000146,211.274777 38.9984015,211.840487 L39.5091338,212.418163 C40.4663724,213.496594 41.4011441,214.52083 41.9316193,215.02291 C58.6803665,230.87513 77.107296,242.87339 106.916185,247.4201 C110.425997,247.955447 116.366501,248.499928 122.462612,248.892117 L123.720445,248.97074 L124.224982,249.000986 L125.229948,249.059012 C132.313319,249.457494 139.137562,249.613103 142.147095,249.290113 C159.931881,247.381405 179.547613,239.71767 191.550191,231.205553 L199.563204,246.267087 C183.184311,263.364504 153.471394,270.406826 128.459093,268.783502 C92.7267899,266.464438 59.6570672,251.504543 36.0192817,227.08072 C13.8613092,204.185919 -1.42108547e-14,172.974912 -1.42108547e-14,136.084268 C-1.42108547e-14,95.8042617 5.20678585,78.8281994 17.4643391,60.9623736 L23.615165,67.669314 C24.2300789,71.5053875 24.0908298,75.4888077 23.8819173,79.4637156 L23.7920604,81.122829 C23.6513999,83.6931991 23.5176088,86.2524312 23.5617746,88.7610078 L35.2808135,88.7610078 C36.8707631,80.2385778 37.7272242,75.6393315 38.3392315,72.595871 C38.7070171,70.7831879 38.9434241,69.7044519 39.1828249,68.7008499 L39.4717463,67.5274334 C39.7538699,66.424868 39.9912408,65.5392748 40.2842693,64.4459443 C41.7014155,59.1583721 44.9207598,48.8335215 47.5587025,42.6413499 Z M33.1933892,101.258656 C32.6602145,101.302832 32.1499254,101.393947 31.6649787,101.531912 C26.5554184,102.98556 21.7915951,110.342352 18.2185718,120.795944 C17.9620284,121.546513 17.7255344,122.215274 17.4910581,122.878375 C16.9981658,124.272281 16.5141151,125.64148 15.8650618,127.709854 L15.829353,127.840121 L15.7588677,128.104027 C15.736272,128.190143 15.7138608,128.277058 15.691622,128.364886 L15.6254108,128.631218 C14.5739206,132.939882 13.8917852,139.607142 12.2397013,160.97199 C14.3429123,170.17238 17.5150377,179.006857 21.9971411,187.751028 C23.4199733,190.526842 25.2281179,193.798969 26.9600704,196.708551 C27.6847124,197.925909 28.4587844,199.185248 29.243105,200.426866 C29.0940719,198.99637 28.9512035,197.555095 28.8149806,196.103615 C27.1419104,178.276741 26.7401892,161.775833 27.6116912,146.600868 C28.4832942,131.424144 30.2529663,116.783711 32.9211878,102.679629 C33.0107582,102.206164 33.101492,101.732507 33.1933892,101.258656 Z M89.6136343,57.8915456 C92.5207218,59.8413435 95.757162,62.0490497 99.322968,64.5146446 C99.5757265,64.6894158 99.8290763,64.86371 100.083123,65.0376999 L100.586746,65.3816115 C103.270392,67.2089793 105.82809,68.8691087 107.023588,69.638714 L107.12174,69.7013171 L106.622439,71.7174649 L102.10112,89.9462065 C109.509279,81.503201 116.693566,77.5133458 123.724983,78.2561059 C124.775931,78.3671222 125.818198,78.4848018 126.844767,78.6301404 C127.171633,78.6764172 127.501638,78.7221424 127.834197,78.76822 C128.609894,78.8756963 129.399629,78.9850773 130.192229,79.1076101 L130.71623,79.1905763 C134.779202,79.8501476 138.995024,80.9126593 142.243229,84.1358564 C144.698067,86.5717944 146.577854,90.2342165 147.474776,95.8124796 C148.609211,102.867923 146.177747,114.685842 143.514658,127.830297 C143.105273,129.850941 142.690629,131.902058 142.28185,133.971759 L142.010322,135.354182 C138.404784,153.81972 135.457943,173.544833 140.981739,186.178845 C144.591197,194.434389 147.644971,199.21786 150.179853,201.954525 C151.861791,203.77035 153.346236,204.723374 154.628922,205.205997 C156.612445,205.952316 158.163845,205.610158 159.338985,205.331228 C159.673711,205.251778 159.963177,205.170695 160.212486,205.170695 C161.760061,205.170695 164.889188,204.145311 169.591406,202.006587 C170.203583,207.704116 169.937427,212.441799 168.762515,216.215654 C168.325303,217.619989 168.08318,218.291265 167.229562,218.749075 C164.759118,220.074016 161.33865,219.491314 158.035932,218.660292 C152.718798,217.328664 145.375426,215.520784 139.125653,207.930129 C138.533436,207.210851 137.964535,206.526006 137.417377,205.867339 C131.943189,199.277525 128.676537,195.366456 126.006663,185.516627 C124.153503,178.679862 123.524735,173.686814 123.497999,165.346832 L123.497287,164.50688 C123.504188,159.678426 123.694904,153.744251 123.960932,145.795011 C124.422298,132.008836 126.466077,122.921303 127.986504,116.155919 C128.981823,111.727089 129.748333,108.266902 129.748333,105.145054 C129.748333,103.873678 129.916089,102.094153 130.093165,100.223439 L130.153565,99.584772 C130.378609,97.1966866 130.590493,94.7398056 130.509114,92.9955736 C130.473414,92.2303984 130.378088,91.5878183 130.223402,91.114477 C129.978656,90.3655563 129.565766,89.9621099 129.122071,89.7833286 C126.960478,88.912343 123.797914,89.6984588 120.45971,91.4684019 C116.277113,93.6860491 111.839157,97.3179607 109.143171,100.024299 C102.702707,106.489496 101.650463,108.11278 98.9103631,122.097683 C97.1454746,131.105308 95.1275565,157.925005 92.8695504,202.554835 C88.7417121,200.249882 85.8091381,197.388161 84.1031585,193.940877 C81.1874766,188.049141 80.173945,185.916077 78.5912785,175.473769 C77.3777356,167.466909 78.0187398,156.486894 78.390954,150.030858 C78.5104167,147.958784 78.60257,146.343082 78.60257,145.421556 C78.60257,141.632745 79.2111322,131.682372 80.9746846,117.107659 C81.813388,110.176274 82.2916314,106.235131 82.8703415,102.454843 L82.9960414,101.646264 C83.6128469,97.7387114 84.3731033,93.7843163 85.7879622,86.638173 C87.6146854,77.4117928 88.8900495,67.8290721 89.6136343,57.8915456 Z" id="Down-circle-and-font1" fill="#263148"></path> + <path d="M126.96931,5.68434189e-14 C166.552949,5.68434189e-14 200.771355,18.8335538 224.335488,47.1455462 C243.947772,70.709445 257.478475,99.8259352 258.985217,133.803264 C259.663652,149.102117 254.884757,168.318925 251.00421,182.757848 L241.723032,161.357573 C242.093055,160.04666 242.618858,158.294937 243.215109,156.308153 C245.15965,149.828693 247.837278,140.878045 248.380331,136.427538 C249.191142,129.782654 250.230593,110.529648 235.615894,80.2093501 C229.18805,66.8738608 212.590335,48.7092842 199.019677,38.2407285 C185.446312,27.7700842 159.021567,20.5570019 132.111557,19.4473082 C106.501884,18.3912368 80.9927614,24.4350512 61.2580024,37.4410355 L56.6964273,21.7259635 C76.9325749,7.67716119 101.149514,5.68434189e-14 126.96931,5.68434189e-14 Z" id="Upper-circle" fill="#263148"></path> + <path d="M154.78974,159.482317 C155.90974,165.962317 161.10974,170.762317 167.82974,170.362317 C182.38974,169.642317 187.74974,149.642317 187.34974,137.962317 C191.34974,138.522317 195.10974,140.202317 197.02974,143.962317 C199.50974,148.762317 199.10974,154.842317 196.46974,159.402317 C193.02974,165.002317 187.50974,167.482317 182.54974,171.242317 C180.78974,172.602317 180.54974,175.482317 182.86974,176.602317 C185.10974,177.562317 188.30974,175.882317 190.30974,174.922317 C201.10974,169.882317 209.02974,159.882317 207.82974,147.642317 C206.70974,136.682317 198.70974,129.642317 188.14974,127.962317 C178.62974,126.442317 168.06974,128.842317 161.34974,135.962317 C155.66974,142.122317 153.18974,151.242317 154.78974,159.482317 Z M163.18974,154.522317 C163.50974,145.162317 170.70974,138.682317 180.22974,137.722317 C179.34974,143.962317 177.66974,150.442317 174.22974,155.802317 C172.86974,157.882317 171.02974,160.282317 168.54974,160.842317 C164.70974,161.642317 163.10974,157.482317 163.18974,154.522317 Z" id="font2" fill="#263148" fill-rule="nonzero"></path> + <path d="M210.72574,196.794317 C210.96574,195.786317 210.53374,195.258317 209.47774,195.258317 L204.82174,195.258317 C203.71774,195.258317 203.28574,195.786317 203.57374,196.842317 C204.00574,198.522317 204.43774,200.106317 204.77374,201.594317 C204.96574,202.554317 205.54174,203.034317 206.50174,203.034317 L207.60574,203.034317 C208.56574,203.034317 209.18974,202.602317 209.47774,201.690317 C209.95774,200.106317 210.38974,198.474317 210.72574,196.794317 Z M204.19774,227.754317 C203.71774,227.706317 203.33374,227.850317 203.09374,228.090317 C202.18174,229.002317 201.60574,229.482317 201.36574,229.482317 L198.10174,229.482317 C197.09374,229.482317 196.61374,229.002317 196.61374,227.994317 L196.61374,212.490317 C196.61374,211.578317 197.09374,211.098317 198.05374,211.098317 L216.14974,211.098317 C217.06174,211.098317 217.54174,211.578317 217.54174,212.490317 L217.54174,228.042317 C217.54174,229.002317 217.06174,229.482317 216.10174,229.482317 L213.17374,229.482317 C212.74174,229.434317 212.35774,229.338317 212.11774,229.146317 C211.01374,228.234317 210.38974,227.754317 210.24574,227.754317 L204.19774,227.754317 Z M237.36574,210.330317 C238.27774,212.346317 238.70974,214.410317 238.70974,216.522317 C238.70974,219.450317 238.13374,221.562317 236.98174,222.810317 C235.82974,224.058317 234.00574,224.682317 231.46174,224.682317 L229.92574,224.682317 C228.96574,224.682317 228.38974,224.250317 228.19774,223.338317 L227.71774,220.938317 C227.47774,219.930317 227.90974,219.450317 228.96574,219.402317 C230.40574,219.354317 231.36574,219.162317 231.89374,218.730317 C232.42174,218.298317 232.70974,217.434317 232.70974,216.138317 C232.70974,213.114317 231.17374,209.898317 228.10174,206.394317 C227.47774,205.674317 227.33374,204.906317 227.76574,204.042317 C229.25374,201.210317 230.59774,198.042317 231.74974,194.586317 C232.08574,193.530317 231.65374,193.002317 230.50174,193.002317 L228.00574,193.002317 C227.04574,193.002317 226.56574,193.482317 226.56574,194.394317 L226.56574,228.042317 C226.56574,229.002317 226.08574,229.482317 225.12574,229.482317 L222.10174,229.482317 C221.09374,229.482317 220.61374,229.002317 220.61374,227.994317 L220.61374,189.594317 C220.61374,188.634317 221.09374,188.154317 222.05374,188.154317 L236.88574,188.154317 C237.84574,188.154317 238.32574,188.634317 238.32574,189.546317 L238.32574,191.562317 C238.32574,192.570317 238.18174,193.482317 237.89374,194.394317 C236.83774,197.706317 235.58974,200.874317 234.14974,203.802317 C233.71774,204.618317 233.86174,205.386317 234.53374,206.106317 C235.68574,207.354317 236.64574,208.746317 237.36574,210.330317 Z M197.81374,196.650317 C197.62174,195.930317 197.18974,195.450317 196.56574,195.306317 C195.60574,195.066317 195.12574,194.586317 195.12574,193.818317 L195.12574,191.706317 C195.12574,190.746317 195.60574,190.266317 196.56574,190.266317 L202.18174,190.266317 C203.14174,190.266317 203.62174,189.786317 203.62174,188.826317 L203.62174,187.626317 C203.62174,186.666317 204.10174,186.186317 205.06174,186.186317 L208.46974,186.186317 C209.38174,186.186317 209.86174,186.666317 209.86174,187.626317 L209.86174,188.826317 C209.86174,189.786317 210.34174,190.266317 211.30174,190.266317 L217.30174,190.266317 C218.26174,190.266317 218.74174,190.746317 218.74174,191.706317 L218.74174,193.818317 C218.74174,194.490317 218.50174,194.922317 218.02174,195.114317 C217.01374,195.546317 216.43774,196.074317 216.29374,196.650317 C215.95774,198.234317 215.52574,199.818317 215.04574,201.402317 C214.70974,202.506317 215.14174,203.034317 216.29374,203.034317 L217.78174,203.034317 C218.74174,203.034317 219.22174,203.514317 219.22174,204.474317 L219.22174,206.778317 C219.22174,207.738317 218.74174,208.218317 217.78174,208.218317 L196.08574,208.218317 C195.17374,208.218317 194.69374,207.738317 194.69374,206.778317 L194.69374,204.474317 C194.69374,203.514317 195.17374,203.034317 196.08574,203.034317 L197.81374,203.034317 C198.91774,203.034317 199.30174,202.506317 199.06174,201.450317 C198.67774,199.914317 198.24574,198.330317 197.81374,196.650317 Z M210.24574,222.954317 C211.20574,222.954317 211.68574,222.474317 211.68574,221.514317 L211.68574,217.530317 C211.68574,216.618317 211.20574,216.138317 210.24574,216.138317 L204.19774,216.138317 C203.23774,216.138317 202.75774,216.618317 202.75774,217.578317 L202.75774,221.562317 C202.75774,222.474317 203.23774,222.954317 204.19774,222.954317 L210.24574,222.954317 Z" id="font3" fill="#263148" fill-rule="nonzero"></path> + <path d="M269.68574,209.658317 C271.36574,209.514317 271.65374,208.794317 270.54974,207.498317 C258.88574,193.914317 258.11774,193.098317 268.34174,204.954317 C269.20574,205.962317 268.67774,206.442317 266.80574,206.442317 L263.87774,206.442317 C262.91774,206.442317 262.19774,206.874317 261.76574,207.690317 C260.90174,209.370317 260.80574,209.562317 261.47774,208.266317 C260.75774,209.658317 261.18974,210.282317 262.72574,210.186317 C265.17374,209.994317 267.52574,209.802317 269.68574,209.658317 Z M252.02174,215.274317 C251.06174,215.322317 250.53374,214.842317 250.48574,213.882317 L250.38974,212.202317 C250.34174,211.290317 250.77374,210.762317 251.73374,210.714317 C251.82974,210.714317 251.92574,210.714317 252.02174,210.714317 C253.17374,210.666317 253.22174,210.666317 252.21374,210.714317 C253.17374,210.666317 253.89374,210.234317 254.37374,209.418317 C254.51774,209.226317 254.70974,208.842317 255.04574,208.266317 C255.71774,207.066317 255.33374,206.442317 253.94174,206.442317 L251.06174,206.442317 C250.10174,206.442317 249.62174,206.922317 249.62174,207.882317 C249.52574,213.306317 248.80574,218.154317 247.41374,222.330317 C247.02974,223.482317 247.46174,224.058317 248.66174,224.058317 L260.46974,224.058317 C261.38174,224.058317 261.86174,223.674317 261.90974,222.858317 C261.95774,221.898317 261.47774,221.418317 260.46974,221.418317 L251.58974,221.418317 C250.62974,221.418317 250.14974,220.938317 250.14974,219.978317 L250.14974,218.490317 C250.14974,217.530317 250.62974,217.050317 251.58974,217.050317 L260.46974,217.050317 C261.18974,217.050317 261.66974,216.762317 261.81374,216.234317 C262.14974,215.226317 261.66974,214.794317 260.42174,214.842317 C257.58974,215.034317 254.75774,215.178317 252.02174,215.274317 Z M251.06174,195.402317 L273.76574,195.402317 C274.58174,195.402317 275.06174,195.018317 275.15774,194.250317 C275.25374,193.290317 274.77374,192.810317 273.71774,192.810317 L251.01374,192.810317 C250.00574,192.810317 249.52574,193.290317 249.62174,194.250317 C249.71774,195.018317 250.19774,195.402317 251.06174,195.402317 Z M281.49374,212.346317 C282.11774,213.162317 281.97374,213.786317 281.06174,214.314317 L278.85374,215.562317 C277.98974,216.042317 277.26974,215.898317 276.69374,215.130317 C276.93374,215.466317 276.83774,215.274317 276.35774,214.650317 C275.78174,213.882317 275.01374,213.546317 274.00574,213.642317 C272.51774,213.786317 271.07774,213.930317 269.63774,214.074317 C268.72574,214.170317 268.24574,214.698317 268.19774,215.610317 C268.14974,216.570317 268.62974,217.050317 269.58974,217.050317 L279.04574,217.050317 C279.95774,217.050317 280.43774,217.530317 280.43774,218.490317 L280.43774,219.978317 C280.43774,220.938317 279.95774,221.418317 279.04574,221.418317 L269.58974,221.418317 C268.72574,221.418317 268.24574,221.802317 268.19774,222.618317 C268.14974,223.578317 268.62974,224.058317 269.63774,224.058317 L281.58974,224.058317 C282.54974,224.058317 283.02974,224.538317 283.02974,225.450317 L283.02974,227.418317 C283.02974,228.378317 282.54974,228.858317 281.63774,228.858317 L249.42974,228.810317 C246.11774,228.810317 244.34174,228.954317 244.19774,229.242317 C244.29374,229.050317 244.38974,228.906317 244.43774,228.810317 C244.19774,229.194317 243.71774,228.906317 242.99774,227.994317 L240.74174,225.306317 C240.16574,224.586317 240.06974,223.818317 240.45374,222.906317 C241.50974,220.506317 242.27774,217.914317 242.80574,215.178317 C243.38174,211.914317 243.66974,207.642317 243.66974,202.410317 L243.66974,189.594317 C243.66974,188.634317 244.14974,188.154317 245.06174,188.154317 L279.95774,188.154317 C280.86974,188.154317 281.34974,188.634317 281.34974,189.594317 L281.34974,198.282317 C281.34974,199.242317 280.86974,199.722317 279.90974,199.722317 L251.01374,199.722317 C250.34174,199.722317 249.90974,199.962317 249.71774,200.490317 C249.38174,201.450317 249.81374,201.930317 251.06174,201.930317 L280.91774,201.930317 C281.87774,201.930317 282.35774,202.410317 282.35774,203.370317 L282.35774,205.050317 C282.35774,205.962317 281.87774,206.442317 280.96574,206.442317 L279.52574,206.442317 C277.65374,206.442317 277.31774,207.162317 278.51774,208.602317 C279.57374,209.898317 280.58174,211.146317 281.49374,212.346317 Z" id="font4" fill="#263148" fill-rule="nonzero"></path> + </g> + </g> +</svg> \ No newline at end of file diff --git a/public/manifest.webmanifest b/public/manifest.webmanifest new file mode 100644 index 0000000..d3fc690 --- /dev/null +++ b/public/manifest.webmanifest @@ -0,0 +1,7 @@ +{ + "name": "且听书吟", + "icons": [ + { "src": "/icon-192.png", "type": "image/png", "sizes": "192x192" }, + { "src": "/icon-512.png", "type": "image/png", "sizes": "512x512" } + ] +} diff --git a/public/robots.txt b/public/robots.txt new file mode 100644 index 0000000..ac230b4 --- /dev/null +++ b/public/robots.txt @@ -0,0 +1,3 @@ +User-agent: * +Allow: / +Sitemap: https://yufan.me/sitemap.xml diff --git a/public/safari-pinned-tab.svg b/public/safari-pinned-tab.svg new file mode 100644 index 0000000..b6bf593 --- /dev/null +++ b/public/safari-pinned-tab.svg @@ -0,0 +1,40 @@ +<?xml version="1.0" standalone="no"?> +<svg version="1.0" xmlns="http://www.w3.org/2000/svg" + width="700.000000pt" height="700.000000pt" viewBox="0 0 700.000000 700.000000" + preserveAspectRatio="xMidYMid meet"> +<g transform="translate(0.000000,700.000000) scale(0.100000,-0.100000)" +fill="#000000" stroke="none"> +<path d="M0 3500 l0 -3500 3500 0 3500 0 0 3500 0 3500 -3500 0 -3500 0 0 +-3500z m2242 3173 c101 -126 188 -234 192 -241 5 -8 -21 -50 -68 -115 -99 +-133 -134 -205 -206 -420 -83 -246 -129 -436 -175 -723 l-6 -41 93 -6 c158 +-10 338 -75 471 -171 91 -64 199 -183 236 -258 76 -154 88 -458 35 -918 -24 +-209 -151 -1092 -185 -1278 -64 -358 -97 -422 -218 -422 l-41 0 0 42 c0 23 16 +330 36 683 30 551 35 685 31 965 -3 300 -5 331 -26 405 -70 248 -201 450 -334 +514 -61 29 -157 39 -178 19 -10 -10 -47 -190 -107 -509 -150 -805 -173 -958 +-216 -1474 -94 -1110 -98 -1583 -21 -2313 15 -147 14 -218 -6 -207 -19 12 -83 +140 -116 233 -87 244 -112 419 -155 1067 -20 302 -17 1235 5 1525 23 303 60 +664 92 910 23 168 100 647 121 749 l7 34 -63 -6 c-172 -15 -340 -177 -484 +-465 -57 -114 -91 -199 -167 -417 -94 -269 -119 -423 -174 -1090 -14 -170 -26 +-318 -28 -328 -2 -16 -14 -10 -72 34 -98 74 -180 161 -210 224 -79 169 -109 +555 -86 1135 43 1090 185 1661 569 2283 l67 108 92 -98 c58 -61 96 -111 103 +-133 11 -38 12 -342 2 -595 -4 -88 -5 -179 -3 -203 l3 -42 271 2 270 3 58 308 +c81 434 103 533 174 782 87 303 213 675 229 675 2 0 87 -102 188 -227z m1726 +-516 c114 -79 244 -168 288 -198 l82 -54 -63 -260 c-35 -143 -88 -359 -119 +-480 -30 -121 -54 -221 -52 -222 1 -1 22 23 46 55 220 281 464 470 681 527 +107 29 389 7 604 -45 322 -79 487 -314 502 -713 9 -224 -16 -398 -157 -1111 +-175 -889 -220 -1217 -220 -1616 0 -419 51 -625 251 -1009 94 -182 168 -291 +258 -382 122 -123 222 -161 360 -139 112 18 185 38 285 76 48 19 90 34 92 34 +8 0 3 -278 -6 -340 -6 -36 -20 -96 -31 -133 -18 -62 -23 -70 -57 -84 -107 -45 +-465 35 -695 155 -164 86 -248 165 -466 437 -178 222 -253 348 -320 539 -130 +368 -161 662 -142 1341 20 730 46 979 151 1460 65 298 80 389 90 550 5 83 14 +209 21 280 26 298 -17 375 -200 362 -207 -14 -529 -223 -798 -517 -103 -114 +-162 -201 -202 -302 -35 -89 -90 -308 -125 -499 -23 -126 -66 -462 -66 -519 +l0 -25 187 0 188 0 110 -38 c134 -46 216 -91 289 -158 71 -64 149 -170 185 +-250 66 -147 154 -485 129 -500 -20 -13 -135 -22 -190 -16 -219 26 -580 364 +-835 780 -37 59 -68 105 -70 103 -15 -15 -86 -1063 -143 -2106 -12 -206 -23 +-376 -25 -378 -7 -7 -100 65 -141 110 -61 66 -102 130 -156 246 -86 183 -123 +321 -169 622 -26 178 -35 520 -20 800 6 118 16 323 22 455 13 338 37 601 100 +1130 54 455 76 597 159 1023 75 382 123 708 151 1015 7 75 16 137 21 137 4 0 +101 -65 216 -143z"/> +</g> +</svg> diff --git a/remark-plugins/images.ts b/remark-plugins/images.ts new file mode 100644 index 0000000..ba0ff11 --- /dev/null +++ b/remark-plugins/images.ts @@ -0,0 +1,53 @@ +import type { Literal, Node, Parent } from 'unist'; +import { visit } from 'unist-util-visit'; +import { imageMetadata } from '../src/helpers/images'; + +export type ImageNode = Parent & { + url: string; + alt: string; + name: string; + width?: number; + height?: number; + attributes: (Literal & { name: string })[]; +}; + +export const astroImage = () => { + return async (tree: Node) => { + const images: ImageNode[] = []; + + // Find all the local image node. + visit(tree, 'image', (node: Node, _, __: Parent) => { + const imageNode = node as ImageNode; + // Skip remote images. + if (imageNode.url.startsWith('http')) { + return; + } + + images.push(imageNode); + }); + + // Process images. + await Promise.all(images.map(transformAstroImage)); + return tree; + }; +}; + +const transformAstroImage = async (imageNode: ImageNode) => { + const metadata = await imageMetadata(imageNode.url); + if (metadata == null) { + throw new Error(`Failed to get image metadata: ${imageNode.url}`); + } + + // Convert original node to next/image + imageNode.type = 'mdxJsxFlowElement'; + imageNode.name = 'Image'; + imageNode.attributes = [ + { type: 'mdxJsxAttribute', name: 'alt', value: imageNode.alt }, + { type: 'mdxJsxAttribute', name: 'src', value: imageNode.url }, + { type: 'mdxJsxAttribute', name: 'width', value: imageNode.width ?? metadata.width }, + { type: 'mdxJsxAttribute', name: 'height', value: imageNode.height ?? metadata.height }, + { type: 'mdxJsxAttribute', name: 'blurDataURL', value: metadata.blurDataURL }, + { type: 'mdxJsxAttribute', name: 'blurWidth', value: metadata.blurWidth }, + { type: 'mdxJsxAttribute', name: 'blurHeight', value: metadata.blurHeight }, + ]; +}; diff --git a/renovate.json b/renovate.json new file mode 100644 index 0000000..22a9943 --- /dev/null +++ b/renovate.json @@ -0,0 +1,4 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": ["config:recommended"] +} diff --git a/src/asserts/og/NotoSansSC-Bold.ttf b/src/asserts/og/NotoSansSC-Bold.ttf new file mode 100644 index 0000000..b9010df Binary files /dev/null and b/src/asserts/og/NotoSansSC-Bold.ttf differ diff --git a/src/asserts/og/logo-dark.png b/src/asserts/og/logo-dark.png new file mode 100644 index 0000000..cff93b5 Binary files /dev/null and b/src/asserts/og/logo-dark.png differ diff --git a/src/asserts/og/open-graph.png b/src/asserts/og/open-graph.png new file mode 100644 index 0000000..1a1ee64 Binary files /dev/null and b/src/asserts/og/open-graph.png differ diff --git a/src/asserts/scripts/sticky-sidebar.js b/src/asserts/scripts/sticky-sidebar.js new file mode 100644 index 0000000..fd52244 --- /dev/null +++ b/src/asserts/scripts/sticky-sidebar.js @@ -0,0 +1,429 @@ +import resizeSensor from 'resize-sensor'; + +class stickySidebarEventHandler { + constructor() { + this.functionMap = {}; + } + + addEventListener(target, event, func) { + this.functionMap[event] = func; + target.addEventListener(event.split('.')[0], this.functionMap[event]); + } + + removeEventListener(target, event) { + target.removeEventListener(event.split('.')[0], this.functionMap[event]); + delete this.functionMap[event]; + } +} + +const stickySidebarStickySidebar = (target, opts) => { + const defaults = { + containerSelector: '', + additionalMarginTop: 0, + additionalMarginBottom: 0, + updateSidebarHeight: true, + minWidth: 0, + disableOnResponsiveLayouts: true, + sidebarBehavior: 'modern', + defaultPosition: 'relative', + namespace: 'TSS', + }; + + const options = Object.assign(defaults, opts); + + // Validate options + options.additionalMarginTop = Number.parseInt(options.additionalMarginTop) || 0; + options.additionalMarginBottom = Number.parseInt(options.additionalMarginBottom) || 0; + + tryInitOrHookIntoEvents(options, target); + + // Try doing init, otherwise hook into window.resize and document.scroll and try again then. + function tryInitOrHookIntoEvents(options, $that) { + const success = tryInit(options, $that); + + if (!success) { + console.log('TSS: Body width smaller than options.minWidth. Init is delayed.'); + + stickySidebarEventHandler.addEventListener( + document, + `scroll.${options.namespace}`, + ((options, $that) => () => { + const success = tryInit(options, $that); + + if (success) { + stickySidebarEventHandler.removeEventListener(document, `scroll.${options.namespace}`); + } + })(options, $that), + ); + + stickySidebarEventHandler.addEventListener( + window, + `resize.${options.namespace}`, + ((options, $that) => () => { + const success = tryInit(options, $that); + + if (success) { + stickySidebarEventHandler.removeEventListener(window, `resize.${options.namespace}`); + } + })(options, $that), + ); + } + } + + // Try doing init if proper conditions are met. + function tryInit(options, $that) { + if (options.initialized === true) { + return true; + } + + if (document.querySelector('body').getBoundingClientRect().width < options.minWidth) { + return false; + } + + init(options, $that); + + return true; + } + + // Init the sticky sidebar(s). + function init(options, $that) { + options.initialized = true; + + // Add CSS + const existingStylesheet = document.querySelectorAll( + `#stickySidebar-sticky-sidebar-stylesheet-${options.namespace}`, + ); + + if (existingStylesheet.length === 0) { + document + .querySelector('head') + .insertAdjacentHTML( + 'beforeend', + `<style id="stickySidebar-sticky-sidebar-stylesheet-${options.namespace}">.stickySidebarStickySidebar:after {content: ""; display: table; clear: both;}</style>`, + ); + } + + for (const element of $that) { + const o = {}; + + o.sidebar = element; + + // Save options + o.options = options || {}; + + // Get container + o.container = o.options.containerSelector === '' ? [] : document.querySelectorAll(o.options.containerSelector); + if (o.container.length === 0) { + o.container = o.sidebar.parentNode; + } + + // Create sticky sidebar + let parentNode = o.sidebar.parentNode; + while (parentNode && parentNode !== document) { + parentNode.style.setProperty('-webkit-transform', 'none'); // Fix for WebKit bug - https://code.google.com/p/chromium/issues/detail?id=20574 + parentNode = parentNode.parentNode; + } + + for (const [key, value] of Object.entries({ + position: o.options.defaultPosition, + overflow: 'visible', + // The "box-sizing" must be set to "content-box" because we set a fixed height to this element when the sticky sidebar has a fixed position. + '-webkit-box-sizing': 'border-box', + '-moz-box-sizing': 'border-box', + 'box-sizing': 'border-box', + })) { + o.sidebar.style.setProperty(key, value); + } + + // Get the sticky sidebar element. If none has been found, then create one. + o.stickySidebar = o.sidebar.querySelector('.stickySidebarStickySidebar'); + if (o.stickySidebar === null) { + // Remove <script> tags, otherwise they will be run again when added to the stickySidebar. + const javaScriptMIMETypes = /(?:text|application)\/(?:x-)?(?:javascript|ecmascript)/i; + + for (const script of Array.from(o.sidebar.querySelectorAll('script'))) { + if (script.type.length === 0 || script.type.match(javaScriptMIMETypes)) { + script.remove(); + } + } + + o.stickySidebar = document.createElement('div'); + o.stickySidebar.classList.add('stickySidebarStickySidebar'); + for (const child of Array.from(o.sidebar.children)) { + o.stickySidebar.appendChild(child); + } + o.sidebar.appendChild(o.stickySidebar); + } + + // Get existing top and bottom margins and paddings + const computedStyle = window.getComputedStyle(o.sidebar); + o.marginBottom = Number.parseInt(computedStyle.getPropertyValue('margin-bottom')); + o.paddingTop = Number.parseInt(computedStyle.getPropertyValue('padding-top')); + o.paddingBottom = Number.parseInt(computedStyle.getPropertyValue('padding-bottom')); + + // Add a temporary padding rule to check for collapsable margins. + let collapsedTopHeight = o.stickySidebar.getBoundingClientRect().top + window.scrollY; + let collapsedBottomHeight = o.stickySidebar.getBoundingClientRect().height; + o.stickySidebar.style.setProperty('padding-top', '1px'); + o.stickySidebar.style.setProperty('padding-bottom', '1px'); + collapsedTopHeight -= o.stickySidebar.getBoundingClientRect().top + window.scrollY; + collapsedBottomHeight = + o.stickySidebar.getBoundingClientRect().height - collapsedBottomHeight - collapsedTopHeight; + if (collapsedTopHeight === 0) { + o.stickySidebar.style.setProperty('padding-top', '0'); + o.stickySidebarPaddingTop = 0; + } else { + o.stickySidebarPaddingTop = 1; + } + + if (collapsedBottomHeight === 0) { + o.stickySidebar.style.setProperty('padding-bottom', '0'); + o.stickySidebarPaddingBottom = 0; + } else { + o.stickySidebarPaddingBottom = 1; + } + + // We use this to know whether the user is scrolling up or down. + o.previousScrollTop = null; + + // Scroll top (value) when the sidebar has fixed position. + o.fixedScrollTop = 0; + + // Set sidebar to default values. + resetSidebar(); + + o.onScroll = (o) => { + // Stop if the sidebar isn't visible. + if (getComputedStyle(o.stickySidebar).display === 'none') { + return; + } + + // Stop if the window is too small. + if (document.querySelector('body').getBoundingClientRect().width < o.options.minWidth) { + resetSidebar(); + return; + } + + // Stop if the sidebar width is larger than the container width (e.g. the theme is responsive and the sidebar is now below the content) + if (o.options.disableOnResponsiveLayouts) { + const sidebarStyles = getComputedStyle(o.sidebar); + const margins = + sidebarStyles.float === 'none' + ? Number.parseInt(sidebarStyles.marginLeft) + Number.parseInt(sidebarStyles.marginRight) + : 0; + const sidebarWidth = o.sidebar.getBoundingClientRect().width + margins; + + if (sidebarWidth + 50 > o.container.getBoundingClientRect().width) { + resetSidebar(); + return; + } + } + + const scrollTop = window.scrollY; + let position = 'static'; + let top = 0; + + // Position of element relative to document = position of element relative to screen + window scrolling position + const sidebarOffset = o.sidebar.getBoundingClientRect().top + window.scrollY; + + // If the user has scrolled down enough for the sidebar to be clipped at the top, then we can consider changing its position. + if (scrollTop >= sidebarOffset + (o.paddingTop - o.options.additionalMarginTop)) { + // The top and bottom offsets, used in various calculations. + const offsetTop = o.paddingTop + options.additionalMarginTop; + const offsetBottom = o.paddingBottom + o.marginBottom + options.additionalMarginBottom; + + // All top and bottom positions are relative to the window, not to the parent elements. + const containerTop = o.sidebar.getBoundingClientRect().top + window.scrollY; + const containerBottom = + o.sidebar.getBoundingClientRect().top + window.scrollY + getClearedHeight(o.container); + + // The top and bottom offsets relative to the window screen top (zero) and bottom (window height). + const windowOffsetTop = 0 + options.additionalMarginTop; + let windowOffsetBottom; + + const sidebarSmallerThanWindow = + o.stickySidebar.getBoundingClientRect().height + offsetTop + offsetBottom < window.innerHeight; + if (sidebarSmallerThanWindow) { + windowOffsetBottom = windowOffsetTop + o.stickySidebar.getBoundingClientRect().height; + } else { + windowOffsetBottom = window.innerHeight - o.marginBottom - o.paddingBottom - options.additionalMarginBottom; + } + + const staticLimitTop = containerTop - scrollTop + o.paddingTop; + const staticLimitBottom = containerBottom - scrollTop - o.paddingBottom - o.marginBottom; + + top = o.stickySidebar.getBoundingClientRect().top + window.scrollY - scrollTop; + const scrollTopDiff = o.previousScrollTop - scrollTop; + + // If the sidebar position is fixed, then it won't move up or down by itself. So, we manually adjust the top coordinate. + if (getComputedStyle(o.stickySidebar).position === 'fixed') { + if (o.options.sidebarBehavior === 'modern') { + top += scrollTopDiff; + } + } + + if (o.options.sidebarBehavior === 'stick-to-top') { + top = options.additionalMarginTop; + } + + if (o.options.sidebarBehavior === 'stick-to-bottom') { + top = windowOffsetBottom - o.stickySidebar.getBoundingClientRect().height; + } + + if (scrollTopDiff > 0) { + // If the user is scrolling up. + top = Math.min(top, windowOffsetTop); + } else { + // If the user is scrolling down. + top = Math.max(top, windowOffsetBottom - o.stickySidebar.getBoundingClientRect().height); + } + + top = Math.max(top, staticLimitTop); + + top = Math.min(top, staticLimitBottom - o.stickySidebar.getBoundingClientRect().height); + + // If the sidebar is the same height as the container, we won't use fixed positioning. + const sidebarSameHeightAsContainer = + o.container.getBoundingClientRect().height === o.stickySidebar.getBoundingClientRect().height; + + if (!sidebarSameHeightAsContainer && top === windowOffsetTop) { + position = 'fixed'; + } else if ( + !sidebarSameHeightAsContainer && + top === windowOffsetBottom - o.stickySidebar.getBoundingClientRect().height + ) { + position = 'fixed'; + } else if ( + scrollTop + top - (o.sidebar.getBoundingClientRect().top + window.scrollY) - o.paddingTop <= + options.additionalMarginTop + ) { + // Stuck to the top of the page. No special behavior. + position = 'static'; + } else { + // Stuck to the bottom of the page. + position = 'absolute'; + } + } + + /* + * Performance notice: It's OK to set these CSS values at each resize/scroll, even if they don't change. + * It's way slower to first check if the values have changed. + */ + if (position === 'fixed') { + const scrollLeft = window.scrollX; + + for (const [key, value] of Object.entries({ + position: 'fixed', + width: `${getWidthForObject(o.stickySidebar)}px`, + transform: `translateY(${top}px)`, + left: `${o.sidebar.getBoundingClientRect().left + Number.parseInt(getComputedStyle(o.sidebar).paddingLeft) - scrollLeft}px`, + top: '0', + })) { + o.stickySidebar.style.setProperty(key, value); + } + } else if (position === 'absolute') { + const css = {}; + + if (getComputedStyle(o.stickySidebar).position !== 'absolute') { + css.position = 'absolute'; + css.transform = `translateY(${scrollTop + top - (o.sidebar.getBoundingClientRect().top + window.scrollY) - o.stickySidebarPaddingTop - o.stickySidebarPaddingBottom}px)`; + css.top = '0px'; + } + + css.width = `${getWidthForObject(o.stickySidebar)}px`; + css.left = ''; + + for (const [key, value] of Object.entries(css)) { + o.stickySidebar.style.setProperty(key, value); + } + } else if (position === 'static') { + resetSidebar(); + } + + if (position !== 'static') { + if (o.options.updateSidebarHeight === true) { + `${o.sidebar.style.setProperty( + 'min-height', + o.stickySidebar.outerHeight + + (o.stickySidebar.getBoundingClientRect().top + window.scrollY) - + (o.sidebar.getBoundingClientRect().top + window.scrollY) + + o.paddingBottom, + )}px`; + } + } + + o.previousScrollTop = scrollTop; + }; + + // Initialize the sidebar's position. + o.onScroll(o); + + // Recalculate the sidebar's position on every scroll and resize. + document.addEventListener( + 'scroll', + ((o) => () => { + o.onScroll(o); + })(o), + ); + window.addEventListener( + 'resize', + ((o) => () => { + o.stickySidebar.style.setProperty('position', 'static'); + o.onScroll(o); + })(o), + ); + + // Recalculate the sidebar's position every time the sidebar changes its size. + if (typeof resizeSensor !== 'undefined') { + new resizeSensor( + o.stickySidebar, + ((o) => () => { + o.onScroll(o); + })(o), + ); + } + + // Reset the sidebar to its default state + function resetSidebar() { + o.fixedScrollTop = 0; + o.sidebar.style.setProperty('min-height', '1px'); + for (const [key, value] of Object.entries({ + position: 'static', + width: '', + transform: 'none', + })) { + o.stickySidebar.style.setProperty(key, value); + } + } + + // Get the height of a div as if its floated children were cleared. Note that this function fails if the floats are more than one level deep. + function getClearedHeight(e) { + let height = e.getBoundingClientRect().height; + + for (const child of Array.from(e.children)) { + height = Math.max(height, child.getBoundingClientRect().height); + } + + return height; + } + } + } + + function getWidthForObject(object) { + let width; + + try { + width = object[0].getBoundingClientRect().width; + } catch (err) {} + + if (typeof width === 'undefined') { + width = object.getBoundingClientRect().width; + } + + return width; + } + + return this; +}; + +export default stickySidebarStickySidebar; diff --git a/src/asserts/scripts/yufan.me.js b/src/asserts/scripts/yufan.me.js new file mode 100644 index 0000000..94a3fbb --- /dev/null +++ b/src/asserts/scripts/yufan.me.js @@ -0,0 +1,171 @@ +import Aplayer from 'aplayer/dist/APlayer.min.js'; +import Artalk from 'artalk/dist/ArtalkLite'; +import stickySidebar from './sticky-sidebar.js'; + +// Menu toggle. +const menuBody = document.querySelector('.site-aside'); +document.addEventListener('keydown', (event) => { + if (event.key === 'Escape') { + event.preventDefault(); + event.stopPropagation(); + menuBody.classList.toggle('in', false); + } +}); +document.querySelector('.menu-toggler').addEventListener('click', () => menuBody.classList.toggle('in', true)); +document.querySelector('.site-menu').addEventListener('click', () => menuBody.classList.toggle('in', false)); +document.querySelector('.aside-overlay').addEventListener('click', () => menuBody.classList.toggle('in', false)); + +// Go to top. +const goTop = document.querySelector('.fixed-gotop'); +const handleScrollUp = () => { + window.requestAnimationFrame(() => { + goTop.classList.toggle('current', window.scrollY > 300); + }); +}; + +goTop.addEventListener('click', () => window.scrollTo({ left: 0, top: 0, behavior: 'smooth' })); +window.addEventListener('scroll', handleScrollUp); +window.addEventListener('resize', handleScrollUp); + +// Dialog popup. +for (const dialog of document.querySelectorAll('.nice-dialog')) { + const popup = dialog.querySelector('.nice-popup'); + dialog.addEventListener('click', (event) => { + event.stopPropagation(); + popup.classList.toggle('nice-popup-open', true); + }); + + const close = dialog.querySelector('.nice-popup-close'); + close.addEventListener('click', (event) => { + event.stopPropagation(); + popup.classList.toggle('nice-popup-open', false); + }); +} + +// Netease music player. +const ps = document.querySelectorAll('.aplayer'); +for (const p of ps) { + new Aplayer({ + container: p, + audio: [ + { + name: p.dataset.name, + artist: p.dataset.artist, + url: p.dataset.url, + cover: p.dataset.cover, + theme: '#ebd0c2', + }, + ], + }); +} + +// Search Bar. +const searchSidebar = document.querySelector('.search-sidebar'); +if (typeof searchSidebar !== 'undefined' && searchSidebar !== null) { + searchSidebar.addEventListener('keydown', (event) => { + if (event.key === 'Enter') { + event.preventDefault(); + event.stopPropagation(); + + const query = event.target.value; + event.target.value = ''; + location.href = `/search?q=${encodeURIComponent(query)}`; + } + }); +} + +// Search dialog. +const searchPopup = document.querySelector('.global-search-popup'); +document.querySelector('.global-search').addEventListener('click', (event) => { + event.stopPropagation(); + searchPopup.classList.toggle('nice-popup-open', true); +}); + +document.querySelector('.global-search-close').addEventListener('click', (event) => { + event.stopPropagation(); + searchPopup.classList.toggle('nice-popup-open', false); +}); + +// Loading the comments. +const comment = document.querySelector('#comments'); +if (typeof comment !== 'undefined' && comment !== null) { + const { key, title, server, site } = comment.dataset; + Artalk.init({ + el: '#comments', + pageKey: key, + pageTitle: title, + server: server, + site: site, + }); +} + +// Add like button for updating likes. +const likeButton = document.querySelector('button.post-like'); + +const increaseLikes = (count) => { + count.textContent = Number.parseInt(count.textContent) + 1; + fetch(`${window.location.href}/likes`, { + method: 'POST', + headers: { + 'Content-type': 'application/json; charset=UTF-8', + }, + body: JSON.stringify({ action: 'increase' }), + }) + .then((res) => res.json()) + .then(({ likes, token }) => { + count.textContent = likes; + localStorage.setItem(window.location.href, token); + }); +}; + +const decreaseLikes = (count) => { + const token = localStorage.getItem(window.location.href); + if (token === null || token === '') { + return; + } + + count.textContent = Number.parseInt(count.textContent) - 1; + fetch(`${window.location.href}/likes`, { + method: 'POST', + headers: { + 'Content-type': 'application/json; charset=UTF-8', + }, + body: JSON.stringify({ action: 'decrease', token: token }), + }) + .then((res) => res.json()) + .then(({ likes }) => { + count.textContent = likes; + localStorage.removeItem(window.location.href); + }); +}; + +if (typeof likeButton !== 'undefined' && likeButton !== null) { + // Change the like state if it has been liked. + const token = localStorage.getItem(window.location.href); + if (token !== null && token !== '') { + likeButton.classList.add('current'); + } + + // Add the click action. + likeButton.addEventListener('click', (event) => { + event.preventDefault(); + event.stopPropagation(); + + const count = likeButton.querySelector('.like-count'); + if (typeof count === 'undefined') { + return; + } + + // Increase the likes and set liked before submitting. + if (likeButton.classList.contains('current')) { + likeButton.classList.remove('current'); + decreaseLikes(count); + } else { + likeButton.classList.add('current'); + increaseLikes(count); + } + }); +} + +// Sticky Sidebar +stickySidebar(document.querySelectorAll('.sidebar')); diff --git a/src/asserts/styles/globals.css b/src/asserts/styles/globals.css new file mode 100644 index 0000000..61978f8 --- /dev/null +++ b/src/asserts/styles/globals.css @@ -0,0 +1,3584 @@ +@media (min-width: 1200px) { + .content-wrapper { + width: 71%; + } + + .sidebar { + width: 29%; + max-width: 370px; + margin-left: auto; + } +} + +/*-------------------------------------------------------------- + title Font color style +--------------------------------------------------------------*/ + +.text-primary { + color: var(--color-primary) !important; +} + +.text-dark { + color: var(--color-dark) !important; +} + +.text-secondary { + color: var(--color-secondary) !important; +} + +.text-muted { + color: var(--color-muted) !important; +} + +.text-light { + color: var(--color-light) !important; +} + +.text-danger { + color: var(--color-danger) !important; +} + +.text-disabled { + pointer-events: none; + opacity: 0.65; +} + +/*-------------------------------------------------------------- +Buttons +--------------------------------------------------------------*/ + +.btn { + border-radius: var(--radius-xs); + white-space: normal; + font-size: 0.875rem; + padding: 0.5rem 1.625rem; +} + +.btn:hover, +.btn:focus, +.btn.disabled, +.btn:disabled, +.btn:not(:disabled):not(.disabled):active:focus, +.btn:not(:disabled):not(.disabled).active:focus { + -webkit-box-shadow: none !important; + box-shadow: none !important; +} + +@media (max-width: 767.98px) { + .btn { + padding: 0.375rem 1.625rem; + } +} + +/*-------------------------------------------------------------- + btn style +--------------------------------------------------------------*/ + +.btn-primary { + color: #fff; + background-color: var(--btn-primary); + border-color: var(--btn-primary); +} + +.btn-primary:hover, +.btn-primary:focus, +.btn-primary.focus, +.btn-primary:not(:disabled):not(.disabled):active, +.btn-primary:not(:disabled):not(.disabled).active, +.btn-primary:not(:disabled):not(.disabled):active:focus, +.btn-primary:not(:disabled):not(.disabled).active:focus { + color: #fff; + background-color: var(--btn-dark); + border-color: var(--btn-dark); +} + +.btn-primary.disabled, +.btn-primary:disabled { + color: #fff; + background-color: var(--btn-dark); + border-color: var(--btn-dark); + opacity: 0.4; +} + +/*-------------------------------------------------------------- + btn secondary style +--------------------------------------------------------------*/ + +.btn-secondary { + color: var(--color-light); + background-color: var(--btn-secondary); + border-color: var(--btn-secondary); +} + +.btn-secondary:hover, +.btn-secondary:focus, +.btn-secondary.focus, +.btn-secondary.disabled, +.btn-secondary:disabled, +.btn-secondary:not(:disabled):not(.disabled):active, +.btn-secondary:not(:disabled):not(.disabled).active, +.btn-secondary:not(:disabled):not(.disabled):active:focus, +.btn-secondary:not(:disabled):not(.disabled).active:focus { + color: #fff; + background-color: var(--btn-secondary); + border-color: var(--btn-secondary); +} + +/*-------------------------------------------------------------- + btn light style +--------------------------------------------------------------*/ + +.btn-light { + color: var(--color-muted); + background-color: var(--btn-light); + border-color: var(--btn-light); +} + +.btn-light:hover, +.btn-light:focus, +.btn-light.focus, +.btn-light.disabled, +.btn-light:disabled, +.btn-light:not(:disabled):not(.disabled):active, +.btn-light:not(:disabled):not(.disabled).active, +.btn-light:not(:disabled):not(.disabled):active:focus, +.btn-light:not(:disabled):not(.disabled).active:focus { + color: var(--color-dark); + background-color: var(--btn-light); + border-color: var(--btn-light); +} + +/*-------------------------------------------------------------- + btn dark style +--------------------------------------------------------------*/ + +.btn-dark { + color: var(--color-light); + background-color: var(--btn-dark); + border-color: var(--btn-dark); +} + +.btn-dark:hover, +.btn-dark:focus, +.btn-dark.focus, +.btn-dark.disabled, +.btn-dark:disabled, +.btn-dark:not(:disabled):not(.disabled):active, +.btn-dark:not(:disabled):not(.disabled).active, +.btn-dark:not(:disabled):not(.disabled):active:focus, +.btn-dark:not(:disabled):not(.disabled).active:focus { + color: #fff; + background-color: var(--btn-secondary); + border-color: var(--btn-secondary); +} + +/*-------------------------------------------------------------- + btn danger style +--------------------------------------------------------------*/ + +.btn-danger { + color: var(--color-light); + background-color: var(--btn-danger); + border-color: var(--btn-danger); +} + +.btn-danger:hover, +.btn-danger:focus, +.btn-danger.focus, +.btn-danger.disabled, +.btn-danger:disabled, +.btn-danger:not(:disabled):not(.disabled):active, +.btn-danger:not(:disabled):not(.disabled).active, +.btn-danger:not(:disabled):not(.disabled):active:focus, +.btn-danger:not(:disabled):not(.disabled).active:focus { + color: #fff; + background-color: var(--btn-danger); + border-color: var(--btn-danger); +} + +/*-------------------------------------------------------------- + btn link style +--------------------------------------------------------------*/ + +.btn-link { + color: var(--color-muted); + text-decoration: none; +} + +.btn-link:hover, +.btn-link:focus, +.btn-link.focus, +.btn-link.disabled, +.btn-link:disabled, +.btn-link:not(:disabled):not(.disabled):active, +.btn-link:not(:disabled):not(.disabled).active, +.btn-link:not(:disabled):not(.disabled):active:focus, +.btn-link:not(:disabled):not(.disabled).active:focus { + color: var(--color-dark); + background-color: var(--btn-light); + border-color: var(--btn-light); + text-decoration: none; +} + +/*-------------------------------------------------------------- + btn link style +--------------------------------------------------------------*/ + +.btn-text { + color: var(--color-muted); +} + +.btn-text:hover, +.btn-text:focus, +.btn-text.focus, +.btn-text.disabled, +.btn-text:disabled, +.btn-text:not(:disabled):not(.disabled):active, +.btn-text:not(:disabled):not(.disabled).active, +.btn-text:not(:disabled):not(.disabled):active:focus, +.btn-text:not(:disabled):not(.disabled).active:focus { + color: var(--color-secondary); + background-color: transparent; + border-color: transparent; + text-decoration: none; +} + +/*-------------------------------------------------------------- + btn link style +--------------------------------------------------------------*/ + +.btn-success { + color: #fff; + background-color: var(--btn-success); + border-color: var(--btn-success); +} + +.btn-success:hover, +.btn-success:focus, +.btn-success.focus, +.btn-success.disabled, +.btn-success:disabled, +.btn-success:not(:disabled):not(.disabled):active, +.btn-success:not(:disabled):not(.disabled).active, +.btn-success:not(:disabled):not(.disabled):active:focus, +.btn-success:not(:disabled):not(.disabled).active:focus { + color: #fff; + background-color: var(--btn-success); + border-color: var(--btn-success); + opacity: 0.8; +} + +/*-------------------------------------------------------------- + btn outline style +--------------------------------------------------------------*/ + +.btn-outline-primary { + color: var(--color-primary); + background-color: var(--btn-outline-primary); + border-color: var(--border-outline-primary); +} + +.btn-outline-primary:hover, +.btn-outline-primary:focus, +.btn-outline-primary.focus, +.btn-outline-primary.disabled, +.btn-outline-primary:disabled, +.btn-outline-primary:not(:disabled):not(.disabled):active, +.btn-outline-primary:not(:disabled):not(.disabled).active, +.btn-outline-primary:not(:disabled):not(.disabled):active:focus, +.btn-outline-primary:not(:disabled):not(.disabled).active:focus { + color: #fff; + background-color: var(--btn-primary); + border-color: var(--btn-primary); +} + +/*-------------------------------------------------------------- + btn outline secondary style +--------------------------------------------------------------*/ + +.btn-outline-secondary { + color: var(--color-secondary); + border-color: var(--btn-secondary); +} + +.btn-outline-secondary:hover, +.btn-outline-secondary:focus, +.btn-outline-secondary.focus, +.btn-outline-secondary.disabled, +.btn-outline-secondary:disabled, +.btn-outline-secondary:not(:disabled):not(.disabled):active, +.btn-outline-secondary:not(:disabled):not(.disabled).active, +.btn-outline-secondary:not(:disabled):not(.disabled):active:focus, +.btn-outline-secondary:not(:disabled):not(.disabled).active:focus { + color: #fff; + background-color: var(--btn-secondary); + border-color: var(--btn-secondary); +} + +/*-------------------------------------------------------------- + btn outline light style +--------------------------------------------------------------*/ + +.btn-outline-light { + color: var(--color-muted); + border-color: var(--btn-light); +} + +.btn-outline-light:hover, +.btn-outline-light:focus, +.btn-outline-light.focus, +.btn-outline-light.disabled, +.btn-outline-light:disabled, +.btn-outline-light:not(:disabled):not(.disabled):active, +.btn-outline-light:not(:disabled):not(.disabled).active, +.btn-outline-light:not(:disabled):not(.disabled):active:focus, +.btn-outline-light:not(:disabled):not(.disabled).active:focus { + color: var(--color-secondary); + border-color: var(--btn-light); +} + +/*-------------------------------------------------------------- + btn outline secondary style +--------------------------------------------------------------*/ + +.btn-outline-dark { + color: var(--color-dark); + border-color: var(--btn-secondary); +} + +.btn-outline-dark:hover, +.btn-outline-dark:focus, +.btn-outline-dark.focus, +.btn-outline-dark.disabled, +.btn-outline-dark:disabled, +.btn-outline-dark:not(:disabled):not(.disabled):active, +.btn-outline-dark:not(:disabled):not(.disabled).active, +.btn-outline-dark:not(:disabled):not(.disabled):active:focus, +.btn-outline-dark:not(:disabled):not(.disabled).active:focus { + color: #fff; + background-color: var(--btn-dark); + border-color: var(--btn-dark); +} + +/*-------------------------------------------------------------- + btn style +--------------------------------------------------------------*/ + +.btn-pointer { + position: relative; + overflow: hidden; + color: #fff; + background: #ff1d1d; + /* fallback for old browsers */ + /* Chrome 10-25, Safari 5.1-6 */ + background: -o-linear-gradient(left, #fa7a46, #ff1d1d); + background: -webkit-gradient(linear, left top, right top, from(#fa7a46), to(#ff1d1d)); + background: linear-gradient(to right, #fa7a46, #ff1d1d); + /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */ + -webkit-box-shadow: 0 15px 20px rgb(254 89 43 / 20%); + box-shadow: 0 15px 20px rgb(254 89 43 / 20%); + border: 0; + padding: 0.6875rem 1.75rem; +} + +.btn-pointer:hover, +.btn-pointer:focus { + color: #fff; +} + +.btn-pointer:after { + position: absolute; + content: ''; + top: 0; + left: 0; + width: 100%; + height: 100%; + border-radius: 0.3em; + background: #ff1d1d; + background: -o-linear-gradient(left, #ff1d1d, #fa7a46); + background: -webkit-gradient(linear, left top, right top, from(#ff1d1d), to(#fa7a46)); + background: linear-gradient(to right, #ff1d1d, #fa7a46); + -webkit-transition: opacity 0.5s ease-out; + -o-transition: opacity 0.5s ease-out; + transition: opacity 0.5s ease-out; + z-index: 2; + opacity: 0; +} + +.btn-pointer:hover:after { + opacity: 1; +} + +.btn-pointer span { + position: relative; + z-index: 3; +} + +@media (max-width: 767.98px) { + .btn-pointer.btn-lg { + padding: 0.6875rem 1.75rem; + } +} + +/*-------------------------------------------------------------- + btn radius style +--------------------------------------------------------------*/ + +.btn-circle { + border-radius: 50%; + padding-left: 1rem; + padding-right: 1rem; +} + +.btn-rounded { + border-radius: 5rem; + padding-left: 1.75rem; + padding-right: 1.75rem; +} + +.btn-rounded-sm { + border-radius: var(--radius-sm); +} + +.btn-rounded-md { + border-radius: var(--radius-md); +} + +.btn-rounded-lg { + border-radius: var(--radius-lg); +} + +.btn-rounded.btn-xs { + padding-left: 0.8125rem; + padding-right: 0.8125rem; +} + +.btn-rounded.btn-sm { + padding-left: 1.25rem; + padding-right: 1.25rem; +} + +.btn-rounded.btn-lg { + border-radius: 4rem; + padding-left: 2.5rem; + padding-right: 2.5rem; +} + +@media (max-width: 767.98px) { + .btn-rounded.btn-sm { + padding-left: 1rem; + padding-right: 1rem; + } +} + +/*-------------------------------------------------------------- + btn size style +--------------------------------------------------------------*/ + +.btn-xs { + font-size: 0.75rem; + padding: 0.25rem 0.75rem; +} + +.btn-sm { + font-size: 0.8125rem; + padding: 0.3125rem 0.875rem; +} + +.btn-lg { + font-size: 0.9375rem; + padding: 0.625rem 2rem; +} + +.btn-block { + width: 100%; + display: block; + padding-left: 0.5rem; + padding-right: 0.5rem; +} + +@media (min-width: 768px) and (max-width: 991.98px) { + .btn-sm { + font-size: 0.75rem; + } + + .btn-lg { + font-size: 0.9375rem; + } +} + +@media (max-width: 767.98px) { + .btn-sm { + font-size: 0.75rem; + padding: 0.25rem 0.5rem; + } + + .btn-lg { + font-size: 0.875rem; + padding: 0.5rem 1.75rem; + } +} + +/*-------------------------------------------------------------- + btn icon style +--------------------------------------------------------------*/ + +.btn-icon { + position: relative; + width: 2rem; + height: 2rem; + font-size: 1.0625rem; + text-align: center; + padding: 0 !important; +} + +.btn-icon span { + position: absolute; + width: 100%; + height: 100%; + top: 0; + display: -ms-flexbox; + display: -webkit-box; + display: flex; + -ms-flex-align: center; + -webkit-box-align: center; + align-items: center; + -ms-flex-pack: center; + -webkit-box-pack: center; + justify-content: center; +} + +.btn-icon:hover, +.btn-icon:active, +.btn-icon:focus { + -webkit-box-shadow: none; + box-shadow: none; +} + +.btn-icon.btn-xs { + width: 1.5rem; + height: 1.5rem; + font-size: 0.875rem; +} + +.btn-icon.btn-sm { + width: 1.875rem; + height: 1.875rem; + font-size: 1.125rem; +} + +.btn-icon.btn-md { + width: 2.625rem; + height: 2.625rem; + font-size: 1.25rem; +} + +.btn-icon.btn-lg { + width: 2.75rem; + height: 2.75rem; + font-size: 1.325rem; +} + +.btn-icon .icon-status { + position: absolute; + left: 0; + top: 0; + z-index: 1; +} + +.icon-status { + display: block; + font-size: 11px; + line-height: 1; + min-width: 20px; + margin: 1px; + padding: 2px 3px; + border-radius: var(--radius-lg); + color: #fff; + background-color: var(--bg-danger); +} + +.icon-status.status-top { + left: 0; + top: 0; +} + +.icon-status.status-right { + left: auto; + top: 0; + right: 0; + -webkit-transform: translate(50%, -50%); + -ms-transform: translate(50%, -50%); + transform: translate(50%, -50%); +} + +@media (max-width: 767.98px) { + .btn-icon.btn-md { + width: 2.125rem; + height: 2.125rem; + font-size: 1.125rem; + } + + .btn-icon.btn-lg { + width: 3.125rem; + height: 3.125rem; + font-size: 1.125rem; + } +} + +@media (min-width: 768px) and (max-width: 991.98px) { + .btn-icon.btn-md { + width: 2.125rem; + height: 2.125rem; + font-size: 1.125rem; + } + + .btn-icon.btn-lg { + width: 2.75rem; + height: 2.75rem; + font-size: 1.25rem; + } +} + +/*-------------------------------------------------------------- + btn width style +--------------------------------------------------------------*/ + +.btn-w-xs { + min-width: 65px; + padding-left: 0.375rem; + padding-right: 0.375rem; +} + +.btn-w-sm { + min-width: 75px; + padding-left: 0.375rem; + padding-right: 0.375rem; +} + +.btn-w-md { + min-width: 95px; + padding-left: 0.75rem; + padding-right: 0.75rem; +} + +.btn-w-lg { + min-width: 150px; + padding-left: 0.75rem; + padding-right: 0.75rem; +} + +.btn-w-lg.btn-lg { + padding-left: 0.75rem; + padding-right: 0.75rem; +} + +@media (max-width: 767.98px) { + .btn-sm.btn-w-md { + min-width: 80px; + } + + .btn-lg { + font-size: 0.875rem; + padding: 0.5rem 1.75rem; + } + + .btn-lg.btn-w-lg { + min-width: 135px; + padding-left: 0.75rem; + padding-right: 0.75rem; + } +} + +@media (min-width: 768px) and (max-width: 991.98px) { + .btn-w-lg { + min-width: 135px; + } +} + +@media (min-width: 768px) { + .btn-sm.btn-w-md { + min-width: 85px; + } + + .btn-sm.btn-w-sm { + min-width: 70px; + } +} + +/*-------------------------------------------------------------- + rounded style +--------------------------------------------------------------*/ + +.rounded { + border-radius: var(--radius-sm) !important; +} + +.rounded-md { + border-radius: var(--radius-md) !important; +} + +.rounded-lg { + border-radius: var(--radius-lg) !important; +} + +/*-------------------------------------------------------------- + title Font Size style +--------------------------------------------------------------*/ + +.bg-primary { + background-color: var(--bg-primary) !important; +} + +.bg-dark { + background-color: var(--bg-dark) !important; +} + +.bg-secondary { + background-color: var(--bg-secondary) !important; +} + +.bg-muted { + background-color: var(--bg-muted) !important; +} + +.bg-light { + background-color: var(--bg-light) !important; +} + +.bg-dark-gradient { + background: -o-linear-gradient(top, #000613, #343f48); + background: -webkit-gradient(linear, left top, left bottom, from(#000613), to(#343f48)); + background: linear-gradient(to bottom, #000613, #343f48); +} + +.bg-color { + position: relative; + overflow: hidden; +} + +.bg-white-overlay { + color: #fff; + background-color: rgb(40 49 73 / 60%); +} + +.bg-nocolor { + background-color: transparent !important; +} + +.bg-dark-overlay { + color: #fff; + background-color: rgba(44, 56, 83, 0.2); +} + +.bg-img { + background-size: cover; + background-position: 50% 50%; + background-repeat: no-repeat; +} + +.bg-wrapper-80 { + position: absolute; + left: 0; + top: 0; + bottom: 0; + width: 80%; + z-index: -1; +} + +.bg-overlay { + position: fixed; + height: 100%; + right: -99%; + top: 0; + left: -99%; + opacity: 0; + background: rgba(120, 129, 147, 0.22); + visibility: hidden; + -webkit-transform: translate3d(0px, 0px, 0px); + transform: translate3d(0px, 0px, 0px); + -webkit-transition: 0.3s ease-in-out; + -o-transition: 0.3s ease-in-out; + transition: 0.3s ease-in-out; + z-index: 998; +} + +.bg-effect { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; +} + +.bg-poster { + -ms-background-size: cover; + background-size: cover; + background-repeat: no-repeat; + background-position: center; +} + +.bg-fixed { + background-attachment: fixed; +} + +/*-------------------------------------------------------------- + title Font Size style +--------------------------------------------------------------*/ + +.shadow { + -ms-box-shadow: 0px 10px 30px 0px rgba(17, 58, 93, 0.1) !important; + -webkit-box-shadow: 0px 10px 30px 0px rgba(17, 58, 93, 0.1) !important; + box-shadow: 0px 10px 30px 0px rgba(17, 58, 93, 0.1) !important; +} + +.shadow-2x { + -ms-box-shadow: 0px 10px 50px -15px rgba(17, 58, 93, 0.13) !important; + -webkit-box-shadow: 0px 10px 50px -15px rgba(17, 58, 93, 0.13) !important; + box-shadow: 0px 10px 50px -15px rgba(17, 58, 93, 0.13) !important; +} + +.no-shadow { + -webkit-box-shadow: none !important; + box-shadow: none !important; +} + +@media (max-width: 767.98px) { +} + +.blur { + -webkit-filter: blur(3px); + filter: blur(3px); +} + +/*-------------------------------------------------------------- +badge +--------------------------------------------------------------*/ + +.badge { + font-size: 0.625rem; + font-weight: 400; + padding: 0.125rem 0.625rem 0.125rem; + border-radius: 0; + vertical-align: middle; + -webkit-box-shadow: none !important; + box-shadow: none !important; + outline: none !important; +} + +.badge-sm { + padding: 0.25rem 0.35rem; +} + +.badge-md { + padding: 0.4375rem 0.625rem; +} + +.badge-primary { + color: #fff; + background-color: var(--btn-primary); +} + +.badge-dark { + color: #fff; + background-color: var(--btn-dark); +} + +.badge-secondary { + color: #fff; + background-color: var(--btn-secondary); +} + +.badge-warning { + color: var(--color-warning); + background-color: var(--bg-warning); +} + +.badge-light { + color: var(--color-secondary); + background-color: var(--btn-light); +} + +.badge-cat:hover, +.badge-cat:focus { + color: inherit; +} + +.badge-sticky { + color: #fff; + border-width: 0; + background-color: var(--bg-primary); +} + +.badge-danger { + color: var(--color-danger); + background: var(--btn-outline-danger); +} + +.badge-pill { + border-radius: 10rem; + padding: 0.375rem 0.75rem; +} + +.badge-w-sm { + min-width: 50px; +} + +.badge-w-md { + min-width: 68px; +} + +@media (max-width: 1199.98px) { + .badge { + font-size: 9px; + padding: 0.3125rem 0.5rem; + } +} + +/*-------------------------------------------------------------- +border +--------------------------------------------------------------*/ + +.border-secondary { + border-color: var(--border-secondary) !important; +} + +.border-muted { + border-color: var(--border-muted) !important; +} + +.border-primary { + border-color: var(--border-primary) !important; +} + +.border-light { + border-color: var(--border-light) !important; +} + +.border-1 { + border-width: 1px !important; +} + +.border-2 { + border-width: 2px !important; +} + +.border-3 { + border-width: 3px !important; +} + +/*-------------------------------------------------------------- + form-control style +--------------------------------------------------------------*/ + +.form-control { + font-size: 0.875rem; + height: calc(37px + 2px); + padding: 0.375rem 0.75rem; + border-color: var(--border-light); + color: var(--color-muted); + border-radius: var(--radius-sm); +} + +.form-control:focus { + color: var(--color-secondary); + border-color: var(--border-muted); + -webkit-box-shadow: none; + box-shadow: none; +} + +.form-control::-webkit-input-placeholder { + color: var(--color-secondary); + opacity: 1; +} + +.form-control::-moz-placeholder { + color: var(--color-secondary); + opacity: 1; +} + +.form-control:-ms-input-placeholder { + color: var(--color-secondary); + opacity: 1; +} + +.form-control::-ms-input-placeholder { + color: var(--color-secondary); + opacity: 1; +} + +.form-control::placeholder { + color: var(--color-secondary); + opacity: 1; +} + +.form-control:disabled, +.form-control[readonly] { + background-color: var(--bg-light); + opacity: 1; + color: color; +} + +textarea.form-control { + height: auto; + padding: 0.625rem 0.75rem; +} + +.form-control-lg { + height: calc(42px + 2px); + padding: 0.5rem 1rem; + font-size: 0.9375rem; +} + +@media (min-width: 768px) and (max-width: 991.98px) { + .form-control-lg { + height: calc(42px + 2px); + padding: 0.5rem 1rem; + font-size: 0.9375rem; + } +} + +@media (max-width: 767.98px) { + .form-control { + height: calc(33px + 2px); + padding: 0.375rem 0.75rem; + } + + .form-control-lg { + height: calc(37px + 2px); + padding: 0.5rem 0.875rem; + font-size: 0.875rem; + } +} + +/*-------------------------------------------------------------- + avatar style +--------------------------------------------------------------*/ + +.flex-avatar { + position: relative; + line-height: 1; + white-space: nowrap; + font-weight: bold; + display: -ms-flexbox; + display: -webkit-box; + display: flex; + -ms-flex-pack: center; + -webkit-box-pack: center; + justify-content: center; + -ms-flex-align: center; + -webkit-box-align: center; + align-items: center; + -ms-flex-negative: 0; + flex-shrink: 0; + border-radius: 50px; +} + +.flex-avatar img { + border-radius: inherit; + width: 100%; +} + +/*-------------------------------------------------------------- + media style +--------------------------------------------------------------*/ + +.media { + position: relative; + display: block; + overflow: hidden; + padding: 0; + -ms-flex-negative: 0; + flex-shrink: 0; +} + +.media:after { + content: ''; + display: block; + padding-top: 100%; +} + +.media:not(:first-child):not(:last-child):not(:only-child) { + border-radius: 0; +} + +.media-overlay { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + z-index: 2; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + color: #fff; +} + +.media-overlay.overlay-top { + bottom: auto; +} + +.media-overlay.overlay-bottom { + top: auto; +} + +.media-content { + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + border: 0; + border-radius: inherit; + background-size: cover; + background-repeat: no-repeat; + background-position: 50% 50%; + background-color: rgba(120, 120, 120, 0.1); +} + +.media-content img { + width: 100%; + height: 100%; + object-fit: cover; + display: block; +} + +.media-36x17:after { + padding-top: 47.222222%; +} + +.media-21x9:after { + padding-top: 42.857143%; +} + +.media-16x9:after { + padding-top: 56.25%; +} + +.media-4x3:after { + padding-top: 75%; +} + +.media-2x3:after { + padding-top: 150%; +} + +.media-3x2:after { + padding-top: 66.66666%; +} + +.media-3x4:after { + padding-top: 133.33333%; +} + +.media-1x2:after { + padding-top: 200%; +} + +.media-2x1:after { + padding-top: 50%; +} + +.media-3x1:after { + padding-top: 33%; +} + +.media-4x1:after { + padding-top: 25%; +} + +.media-1-4:after { + padding-top: 25vh; + min-height: 10rem; +} + +.media-1-3:after { + padding-top: 33vh; + min-height: 12.5rem; +} + +.media-1-2:after { + padding-top: 50vh; + min-height: 15rem; +} + +.media-action { + position: absolute; + left: 50%; + top: 50%; + -webkit-transform: translate(-50%, -50%); + -ms-transform: translate(-50%, -50%); + transform: translate(-50%, -50%); + pointer-events: none; + -webkit-transition: opacity 0.3s; + -o-transition: opacity 0.3s; + transition: opacity 0.3s; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; +} + +.media-action .btn { + background-color: rgb(40 49 73 / 50%); + border-color: transparent; + color: #fff; +} + +@media (max-width: 767.98px) { + .media-action .btn-icon.btn-lg { + width: 2.375rem; + height: 2.375rem; + } +} + +@media (min-width: 768px) and (max-width: 991.98px) { + .media-action .btn-icon.btn-lg { + width: 2.5rem; + height: 2.5rem; + } +} + +/*Pagination +-------------------------------------------------------------- */ + +.nav-links { + display: block; + text-align: center; +} + +.nav-links .page-numbers, +.nav-links .post-page-numbers, +.nav-links .current, +.nav-links .next, +.nav-links .prev { + position: relative; + display: inline-block; + margin: 0.25rem; + padding: 0; + text-align: center; + width: 2.5rem; + color: #fff; + width: 2.5rem; + height: 2.5rem; + line-height: 2.5rem; + border-radius: 100px; + background-color: #283248; +} + +.nav-links .page-numbers.dots:hover { + color: #fff; + background-color: #283248; +} + +.nav-links .page-numbers:hover, +.nav-links .page-numbers.current, +.nav-links .post-page-numbers:hover, +.nav-links .next:hover, +.nav-links .prev:hover, +.nav-links .current { + background-color: #008c95; +} + +/*-------------------------------------------------------------- + card style +--------------------------------------------------------------*/ + +.card, +.block { + margin-bottom: 1.75rem; + border: 0; + border-radius: 0; + background-color: #fff; + -webkit-box-shadow: 0 0 30px 0 rgb(40 49 73 / 2%); + box-shadow: 0 0 30px 0 rgb(40 49 73 / 2%); +} + +.card-header, +.card-footer { + background-color: transparent; + border-color: transparent; + background-clip: padding-box; + border: 0; + padding: 1.5rem 1.25rem; +} + +.card-header:first-child { + padding: 1.25rem 1rem 0; + border-radius: 0; +} + +.card-md .card-body { + padding: 2rem; +} + +@media (max-width: 767.98px) { + .card, + .block { + margin-bottom: 0.75rem; + } + + .card-md .card-body { + padding: 1rem; + } +} + +@media (min-width: 768px) and (max-width: 991.98px) { + .card, + .block { + margin-bottom: 1.25rem; + } +} + +@media (min-width: 992px) and (max-width: 1199.98px) { + .card, + .block { + margin-bottom: 1.25rem; + } +} + +@media (min-width: 1200px) and (max-width: 1399.98px) { + .card, + .block { + margin-bottom: 1.25rem; + } +} + +/*-------------------------------------------------------------- + list style +--------------------------------------------------------------*/ + +.list { + padding-left: 0; + padding-right: 0; +} + +.list-item { + position: relative; + display: -ms-flexbox; + display: -webkit-box; + display: flex; + -ms-flex-direction: column; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + flex-direction: column; + min-width: 0; + word-wrap: break-word; +} + +.list-content { + display: -ms-flexbox; + display: -webkit-box; + display: flex; + -ms-flex-direction: column; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + flex-direction: column; + -ms-flex: 1 1 auto; + -webkit-box-flex: 1; + flex: 1 1 auto; + -ms-flex-pack: center; + -webkit-box-pack: center; + justify-content: center; +} + +.list-body { + -ms-flex: 1 1 auto; + -webkit-box-flex: 1; + flex: 1 1 auto; +} + +.list-title { + display: block; + color: inherit; +} + +@media (min-width: 1200px) and (max-width: 1399.98px) { + .list-desc .h-2x { + -webkit-line-clamp: 1; + } +} + +/*-------------------------------------------------------------- + list grouped style +--------------------------------------------------------------*/ + +.list-grouped > div { + display: -webkit-box; + display: -ms-flexbox; + display: flex; +} + +.list-grouped .list-item { + -webkit-box-flex: 1; + -ms-flex: 1 1 auto; + flex: 1 1 auto; + margin: 0; +} + +.list-grouped .list-content { + padding: 1rem 1.25rem; +} + +/*-------------------------------------------------------------- + list padding style +--------------------------------------------------------------*/ + +.list-grid-padding.list-bordered { + padding: 0 1rem; +} + +.list-grid-padding.list-bordered .list-item { + border-top: 1px solid rgba(135, 150, 165, 0.075); + margin-top: -1px; + margin-bottom: 0; + padding: 1rem 0; +} + +.list-grid-padding.list-bordered .list-item:first-child { + border-top: none; +} + +/*-------------------------------------------------------------- + list overlay style +--------------------------------------------------------------*/ + +.list-overlay .media:before { + content: ''; + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + padding: 0; + background-color: rgba(39, 49, 73, 0.19); + z-index: 1; +} + +.list-overlay .list-content { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + border-radius: inherit; +} + +.list-overlay .list-content { + padding: 1rem; + z-index: 1; +} + +.list-overlay .list-body { + display: -ms-flexbox; + display: -webkit-box; + display: flex; + -ms-flex-direction: column; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + flex-direction: column; +} + +.list-overlay .list-body .list-title { + margin-top: auto; +} + +.list-hover-overlay .media { + display: none; +} + +.list-overlay { + color: #fff; + margin-bottom: 0; +} + +.list-overlay a:hover, +.list-overlay a:active, +.list-overlay .list-title { + color: #fff; +} + +.list-overlay .text-muted:not(i) { + color: rgba(255, 255, 255, 0.5) !important; +} + +#recent_posts, +#tag_cloud, +#recent-comments { + a:hover { + color: var(--color-primary); + } +} + +a.list-title:hover { + color: var(--color-primary); +} + +/*-------------------------------------------------------------- + list overlay style +--------------------------------------------------------------*/ + +.list-nice-overlay { + margin-bottom: 0; + -ms-flex: 1 1 auto; + -webkit-box-flex: 1; + flex: 1 1 auto; +} + +.list-nice-overlay .media { + -ms-flex: 1 1 auto; + -webkit-box-flex: 1; + flex: 1 1 auto; +} + +.list-nice-overlay .list-content { + position: absolute; + right: 0; + bottom: 0; + left: 0; +} + +.list-nice-overlay .list-content { + padding: 0.75rem 1rem; + z-index: 1; +} + +.list-nice-overlay .list-body { + display: -ms-flexbox; + display: -webkit-box; + display: flex; + -ms-flex-direction: column; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + flex-direction: column; + -ms-flex: none; + -webkit-box-flex: 0; + flex: none; +} + +.list-nice-overlay .list-title { + margin-bottom: 0.5rem; + color: #fff; +} + +.list-nice-overlay .text-muted:not(i) { + color: #eaecf3 !important; +} + +@media (max-width: 767.98px) { + .list-nice-overlay .list-content { + padding: 0.5rem; + z-index: 1; + } +} + +/*-------------------------------------------------------------- + custom style +--------------------------------------------------------------*/ + +.custom-hover { + position: relative; + overflow: hidden; +} + +.custom-hover img, +.custom-hover-img { + max-width: 100%; + -webkit-transition: all 444ms ease-in-out; + -o-transition: all 444ms ease-in-out; + transition: all 444ms ease-in-out; +} + +.custom-hover:hover img, +.custom-hover:hover .custom-hover-img { + -webkit-transform: scale(1.05); + -ms-transform: scale(1.05); + transform: scale(1.05); +} + +.custom-hover .custom-hover-icon { + position: absolute; + left: 0; + right: 0; + text-align: center; + top: 50%; + opacity: 0; + -webkit-transform: translateY(-50%); + -ms-transform: translateY(-50%); + transform: translateY(-50%); + visibility: visible; + z-index: 9; + -webkit-transition: 0.3s; + -o-transition: 0.3s; + transition: 0.3s; +} + +.custom-hover .custom-hover-icon span { + width: 40px; + height: 40px; + line-height: 40px; + border-radius: 40px; + display: inline-block; + background-color: rgba(255, 255, 255, 0.68); +} + +.custom-hover:hover .custom-hover-icon { + opacity: 1; +} + +/*-------------------------------------------------------------- + overlay style +--------------------------------------------------------------*/ + +.overlay { + width: 100%; + height: 100%; + background-color: rgb(40 49 73 / 66%); + position: absolute; + opacity: 0.6; + top: 0; + left: 0; + -webkit-transition: opacity 0.3s ease-in-out; + -o-transition: opacity 0.3s ease-in-out; + transition: opacity 0.3s ease-in-out; +} + +.overlay-hover:hover .overlay, +a:hover .overlay { + opacity: 0.22; +} + +/*-------------------------------------------------------------- + line-clamp style +--------------------------------------------------------------*/ + +.h-1x { + overflow: hidden; + display: -webkit-box; + -webkit-line-clamp: 1; + -webkit-box-orient: vertical; +} + +.h-2x { + overflow: hidden; + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; +} + +.h-3x { + overflow: hidden; + display: -webkit-box; + -webkit-line-clamp: 3; + -webkit-box-orient: vertical; +} + +.h-4x { + overflow: hidden; + display: -webkit-box; + -webkit-line-clamp: 4; + -webkit-box-orient: vertical; +} + +/*-------------------------------------------------------------- + data-null style +--------------------------------------------------------------*/ + +.data-null { + display: -ms-flexbox; + display: -webkit-box; + display: flex; + -ms-flex-direction: column; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + flex-direction: column; + -webkit-box-flex: 1; + -ms-flex: 1 1 auto; + flex: 1 1 auto; + text-align: center; + height: 50vh; +} + +.data-null h1 { + font-size: 6rem; +} + +/*-------------------------------------------------------------- + headere style +--------------------------------------------------------------*/ + +.site-layout { + display: -ms-flexbox; + display: -webkit-box; + display: flex; + -ms-flex-direction: row; + -webkit-box-orient: horizontal; + -webkit-box-direction: normal; + flex-direction: row; +} + +@media (max-width: 991.98px) { + .site-layout { + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; + } +} + +.site-aside { + position: -webkit-sticky; + position: sticky; + display: block; + width: 280px; + opacity: 1; + top: 0; + height: 100vh; + z-index: 1020; + -ms-flex-negative: 0; + flex-shrink: 0; +} + +@media (min-width: 1200px) and (max-width: 1919.98px) { + .site-aside { + width: 260px; + } +} + +@media (min-width: 992px) and (max-width: 1199.98px) { + .site-aside { + width: 220px; + } +} + +@media (min-width: 768px) and (max-width: 991.98px) { + .site-aside { + width: 240px; + } +} + +.site-main { + display: -ms-flexbox; + display: -webkit-box; + display: flex; + -ms-flex-direction: column; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + flex-direction: column; + -webkit-box-flex: 1; + -ms-flex: 1 1 auto; + flex: 1 1 auto; +} + +.aside-inner { + pointer-events: inherit; + display: -ms-flexbox; + display: -webkit-box; + display: flex; + -ms-flex-direction: column; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + flex-direction: column; + height: 100%; +} + +@media (max-width: 991.98px) { + .site-aside { + position: fixed; + width: 100%; + height: 100%; + opacity: 0; + visibility: hidden; + pointer-events: none; + -webkit-transition: all 0.5s ease; + -o-transition: all 0.5s ease; + transition: all 0.5s ease; + } + + .site-aside.in { + opacity: 1; + visibility: visible; + pointer-events: auto; + z-index: 10; + } + + .site-aside .aside-inner { + position: fixed; + width: 240px; + -webkit-transition: 0.4s ease-in-out; + -o-transition: 0.4s ease-in-out; + transition: 0.4s ease-in-out; + -webkit-transform: translate3d(-100%, 0, 0); + transform: translate3d(-100%, 0, 0); + } + + .site-aside.in .aside-inner { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } + + .site-aside .aside-overlay { + visibility: hidden; + pointer-events: none; + } + + .site-aside.in .aside-overlay { + position: fixed; + left: 0; + right: 0; + top: 0; + bottom: 0; + background-color: rgba(8, 15, 25, 0.3); + visibility: visible; + pointer-events: initial; + } +} + +@media (max-width: 767.98px) { + .site-aside .aside-inner { + width: 75%; + } +} + +/*-------------------------------------------------------------- + header style +--------------------------------------------------------------*/ + +.navbar-brand { + display: block; + margin: 0; + padding: 20px 25px 15px 25px; + -ms-flex-negative: 0; + flex-shrink: 0; +} + +.navbar-brand svg { + max-height: 60px; +} + +@media (max-width: 767.98px) { + .navbar-brand { + display: none; + padding: 10px 20px; + } + + .navbar-brand svg { + max-height: 50px; + } +} + +@media (min-width: 768px) and (max-width: 991.98px) { + .navbar-brand { + display: none; + padding: 15px 20px; + } + + .navbar-brand svg { + max-height: 55px; + } +} + +@media (min-width: 992px) and (max-width: 1199.98px) { + .navbar-brand { + padding: 15px 20px; + } +} + +.mobile-brand { + display: none; + padding: 1rem 0; + background-color: #fff; + border-bottom: 1px solid #ebf1f6; +} + +.mobile-brand svg { + height: 50px; +} + +.mobile-brand .menu-toggler { + cursor: pointer; +} + +@media (min-width: 768px) and (max-width: 991.98px) { + .mobile-brand { + display: block; + } + + .mobile-brand svg { + max-height: 40px; + } +} + +@media (max-width: 767.98px) { + .mobile-brand { + display: block; + } + + .mobile-brand svg { + max-height: 35px; + } +} + +/*-------------------------------------------------------------- + site-menu style +--------------------------------------------------------------*/ + +.site-menu { + -webkit-box-flex: 1; + -ms-flex: 1 1 auto; + flex: 1 1 auto; + overflow-x: hidden; + overflow-y: auto; + -webkit-overflow-scrolling: touch; +} + +.site-menu > ul { + padding: 0.625rem 0.75rem; +} + +@media (max-width: 767.98px) { + .site-menu > ul { + padding: 0.625rem 0.75rem; + } +} + +@media (min-width: 768px) and (max-width: 991.98px) { + .site-menu > ul { + padding: 0.625rem 0.5rem; + } +} + +.site-menu li { + position: relative; + display: block; + padding: 0.75rem 0.75rem; +} + +.site-menu li a, +.site-menu li a:not([href]):not([tabindex]) { + position: relative; + display: block; + color: #fff; + font-size: 0.9375rem; + cursor: pointer; + opacity: 0.6; + text-decoration: none; +} + +.site-menu li:last-child a { + margin: 0; +} + +.site-menu li.current-menu-item > a, +.site-menu li:hover > a { + opacity: 1; +} + +.site-menu li.in { + background: rgb(235 239 246 / 0.1); + padding: 0.75rem; + border-radius: 2px; +} + +/*-------------------------------------------------------------- + menu icon style +--------------------------------------------------------------*/ + +.menu-icon { + position: absolute; + top: 50%; + right: 0; + font-size: 0.75rem; + opacity: 0.6; + -webkit-transform: translate(0%, -50%); + -ms-transform: translate(0%, -50%); + transform: translate(0%, -50%); +} + +.menu-icon .iconfont { + display: block; + -webkit-transition: all 0.3s ease; + -o-transition: all 0.3s ease; + transition: all 0.3s ease; +} + +.site-menu li.menu-item-has-children.in .menu-icon .iconfont { + -ms-transform: rotate(90deg); + transform: rotate(90deg); + -webkit-transform: rotate(90deg); +} + +/*-------------------------------------------------------------- + sub-menu style +--------------------------------------------------------------*/ + +.site-menu .sub-menu { + display: none; + position: relative; + margin: 10px 0 0; +} + +.site-menu li.in .sub-menu { + border-top: 1px solid rgb(108 114 136 / 30%); +} + +.site-menu .sub-menu li { + padding: 0; + margin: 0.75rem 0 0; + background: transparent; +} + +.site-menu .sub-menu li .sub-menu { + border-bottom: 1px solid rgb(108 114 136 / 30%); + margin: 0; + padding: 0; + border-top: 0; +} + +.site-menu .sub-menu li .sub-menu li { + margin: 0.75rem 0; +} + +.site-menu .sub-menu li:first-child { + border: 0; +} + +.site-menu .sub-menu li.current-menu-item { + position: relative; +} + +.site-menu .sub-menu li.current-menu-item a, +.site-menu .sub-menu > li .sub-memu > li:hover > a, +.site-menu .sub-menu > li:hover > a, +.site-menu > li > ul > li > ul > li:hover > a, +.site-menu > li > ul > li:hover > a, +.site-menu > li:hover > a { + color: #00818a; +} + +@media (max-width: 991.98px) { + .site-menu li.menu-item-has-children > .menu-icon { + top: 8px; + right: 0; + } +} + +.site-submenu { + -ms-flex-negative: 0; + flex-shrink: 0; + padding: 25px; +} + +.site-submenu .button-social { + margin-right: 8px; +} + +@media (max-width: 767.98px) { + .site-submenu { + padding: 20px 25px; + } +} + +@media (min-width: 992px) and (max-width: 1199.98px) { + .site-submenu { + padding: 20px 15px; + } +} + +/*-------------------------------------------------------------- + popup css +--------------------------------------------------------------*/ +.nice-tips, +.nice-popup { + position: fixed; + display: flex; + align-items: center; + justify-content: center; + left: 0; + top: 0; + height: 100%; + width: 100%; + opacity: 0; + visibility: hidden; + z-index: 999; + overflow-x: hidden; + overflow-y: auto; +} + +.nice-tips-open, +.nice-popup-open { + opacity: 1; + visibility: visible; +} + +.nice-tips-overlay, +.nice-popup-overlay { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100vh; + background-color: rgba(0, 0, 0, 0.3); + opacity: 0; + visibility: hidden; +} + +.nice-tips-open .nice-tips-overlay, +.nice-popup-open .nice-popup-overlay { + opacity: 1; + visibility: visible; + pointer-events: auto; +} + +/*-------------------------------------------------------------- + popup size +--------------------------------------------------------------*/ + +.nice-tips-body, +.nice-popup-body { + position: relative; + width: 100%; + max-width: 450px; + padding-top: 2rem; + padding-bottom: 2rem; + transform: translateY(-40px); + opacity: 0; + visibility: hidden; + transition: all 0.3s ease-in-out; +} + +.nice-tips-open .nice-tips-body, +.nice-popup-open .nice-popup-body { + transform: translateY(0); + pointer-events: auto; + opacity: 1; + visibility: visible; +} + +.nice-tips-xl .nice-tips-body, +.nice-popup-xl .nice-popup-body { + max-width: 790px; +} + +.nice-tips-lg .nice-tips-body, +.nice-popup-lg .nice-popup-body { + max-width: 750px; +} + +.nice-tips-md .nice-tips-body, +.nice-popup-md .nice-popup-body { + max-width: 540px; +} + +.nice-tips-sm .nice-tips-body, +.nice-popup-sm .nice-popup-body { + max-width: 300px; + width: auto; +} + +.nice-tips-nopd .nice-tips-body, +.nice-popup-nopd .nice-popup-body { + max-width: 340px; +} + +@media (min-width: 768px) and (max-width: 991.98px) { + .nice-tips-xl .nice-tips-body, + .nice-popup-xl .nice-popup-body { + max-width: 670px; + } +} + +@media (max-width: 767.98px) { + .nice-tips-body, + .nice-popup-body { + width: 95%; + } + + .nice-tips-xl .nice-tips-body, + .nice-popup-xl .nice-popup-body { + height: 100vh; + } + + .nice-tips-nopd .nice-tips-body, + .nice-popup-nopd .nice-popup-body { + width: 75%; + } +} + +/*-------------------------------------------------------------- + popup content +--------------------------------------------------------------*/ + +.nice-tips-content, +.nice-popup-content { + position: relative; + background: #fff; + padding: 1.75rem; + border-radius: 9px; + border-radius: var(--border-radius-md, 9px); + color: var(--color-dark); +} + +.nice-tips-xl .nice-tips-content, +.nice-popup-xl .nice-popup-content { + width: 100%; + height: auto; + overflow: hidden; +} + +.nice-tips-sm .nice-tips-content, +.nice-popup-sm .nice-popup-content { + padding: 1.75rem 2.5rem; +} + +.nice-tips-nopd .nice-tips-content, +.nice-popup-nopd .nice-popup-content { + padding: 0; +} + +@media (max-width: 767.98px) { + .nice-tips-xl .nice-tips-body .nice-tips-content, + .nice-popup-xl .nice-popup-body .nice-popup-content { + box-shadow: none; + border-radius: 0; + height: 100vh; + } + + .nice-tips-xl .nice-tips-close .svg-white, + .nice-popup-xl .nice-popup-close .svg-white { + width: 20px; + height: 20px; + } + + .nice-tips-xl .nice-tips-close .svg-dark, + .nice-popup-xl .nice-popup-close .svg-dark { + display: none; + width: 20px; + height: 20px; + } +} + +/*-------------------------------------------------------------- + error content +--------------------------------------------------------------*/ +.nice-popup-error { + align-items: flex-start; +} + +.nice-popup-error .nice-popup-content { + display: flex; + align-items: center; + text-align: center; + padding: 0.5rem 1.5rem; + border: 0; + color: #fff; + white-space: nowrap; + border-radius: 50px !important; + background-color: rgba(0, 0, 0, 0.9); + transition: all 0.2s ease-in-out; + transform: scale(0.8); +} + +.nice-popup-error.error .icon { + display: block; + width: 24px; + height: 24px; + background-position: center; + background-repeat: no-repeat; + background-size: contain; + background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbDpzcGFjZT0icHJlc2VydmUiIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDM5IDM5IiB2aWV3Qm94PSIwIDAgMzkgMzkiPjxwYXRoIGQ9Im0xMSAyOCA4LjUtOC41TTI4IDExbC04LjUgOC41bTAgMEwxMSAxMW04LjUgOC41TDI4IDI4IiBzdHlsZT0iZmlsbDpub25lO3N0cm9rZTojZWEzMDE0O3N0cm9rZS13aWR0aDozLjI1O3N0cm9rZS1saW5lY2FwOnJvdW5kO3N0cm9rZS1saW5lam9pbjpyb3VuZDtzdHJva2UtbWl0ZXJsaW1pdDo2LjUiLz48L3N2Zz4='); +} + +.nice-popup-error.success .icon { + display: block; + width: 24px; + height: 24px; + background-position: center; + background-repeat: no-repeat; + background-size: contain; + background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbDpzcGFjZT0icHJlc2VydmUiIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDM5IDM5IiB2aWV3Qm94PSIwIDAgMzkgMzkiPjxwYXRoIGQ9Im04LjEgMjEuMSA2LjUgNi41IDE2LjItMTYuMiIgc3R5bGU9ImZpbGw6bm9uZTtzdHJva2U6IzM0YjI4ZTtzdHJva2Utd2lkdGg6My4yNTtzdHJva2UtbGluZWNhcDpyb3VuZDtzdHJva2UtbGluZWpvaW46cm91bmQ7c3Ryb2tlLW1pdGVybGltaXQ6Ni41Ii8+PC9zdmc+'); +} + +.nice-popup-error.nice-popup-open .nice-popup-content { + padding: 1rem 2.5rem 1rem 2rem; + transform: scale(1); +} + +@media (max-width: 991.98px) { + .nice-popup-error .nice-popup-content { + font-size: 0.75rem; + } + + .nice-popup-error.nice-popup-open .nice-popup-content { + padding: 0.75rem 2.5rem 0.75rem 2rem; + } +} + +/*-------------------------------------------------------------- + hidden body +--------------------------------------------------------------*/ + +.nice-popup-hidden { + overflow: hidden; +} + +/*-------------------------------------------------------------- + tips close btn +--------------------------------------------------------------*/ + +.nice-tips-close, +.nice-popup-close { + position: absolute; + bottom: 0; + left: 0; + width: 100%; + z-index: 99; + cursor: pointer; + text-align: center; + transform: translateY(25%); +} + +.nice-tips-close .svg-white, +.nice-popup-close .svg-white { + display: inline-block; + background-image: url('data:image/svg+xml;base64,PHN2ZyBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB3aWR0aD0iMTI4IiBoZWlnaHQ9IjEyOCI+PGRlZnM+PHN0eWxlLz48L2RlZnM+PHBhdGggZD0iTTUxMiAwQzIyOS4yIDAgMCAyMjkuMTk5OTk5IDAgNTEyYzAgMjgyLjggMjI5LjIgNTEyIDUxMiA1MTIgMjgyLjgwMDAwMSAwIDUxMi0yMjkuMiA1MTItNTEyQzEwMjQgMjI5LjE5OTk5OSA3OTQuODAwMDAxIDAgNTEyIDB6bTIxMy40NjA1MjIgNzI1Ljk3NTY1OWMtNi4wNzcyNDkgNi4wNzcyNDgtMTQuMDY0NDg4IDkuMTE1ODcyLTIyLjA1MTcyNyA5LjExNTg3Mi03Ljk4NzI0MiAwLTE2LjA2MTI5OC0zLjAzODYyNC0yMi4xMzg1NDgtOS4yMDI2OUw1MTIgNTU2LjI3MTMyMyAzNDIuNzI5NzUyIDcyNS44ODg4NDFjLTYuMDc3MjQ4IDYuMTY0MDY2LTE0LjE1MTMwNiA5LjIwMjY5LTIyLjEzODU0NiA5LjIwMjY5LTcuOTg3MjQgMC0xNS45NzQ0NzktMy4wMzg2MjQtMjIuMDUxNzI3LTkuMTE1ODcyLTEyLjI0MTMxMy0xMi4xNTQ0OTYtMTIuMjQxMzEzLTMxLjk0ODk2LS4wODY4MTgtNDQuMTkwMjczTDQ2Ny44OTY1NDYgNTExLjk5NDIzIDI5OC40NTI2NjEgMzQyLjIwMzA3NGMtMTIuMTU0NDk1LTEyLjI0MTMxMi0xMi4xNTQ0OTUtMzIuMDM1Nzc2LjA4NjgxOC00NC4xOTAyNzEgMTIuMjQxMzEzLTEyLjE1NDQ5NSAzMi4wMzU3NzctMTIuMTU0NDk1IDQ0LjE5MDI3My4wODY4MTdMNTEyIDQ2Ny43MTcxNDFsMTY5LjI3MDI0Ny0xNjkuNzA0MzM4YzEyLjE1NDQ5NS0xMi4yNDEzMTMgMzEuOTQ4OTU5LTEyLjI0MTMxMyA0NC4xOTAyNzUtLjA4NjgxOCAxMi4yNDEzMTMgMTIuMTU0NDk1IDEyLjI0MTMxMyAzMS45NDg5NTkuMDg2ODE4IDQ0LjE5MDI3Mkw1NTYuMTAzNDU0IDUxMS45OTQyMyA3MjUuNTQ3MzQgNjgxLjc4NTM4NmMxMi4xNTQ0OTUgMTIuMjQxMzEzIDEyLjE1NDQ5NSAzMi4wMzU3NzctLjA4NjgxOCA0NC4xOTAyNzN6IiBmaWxsPSIjZmZmIi8+PC9zdmc+'); + background-size: contain; + background-position: center; + background-repeat: no-repeat; + vertical-align: middle; + width: 28px; + height: 28px; +} + +.nice-tips-close .svg-dark, +.nice-popup-close .svg-dark { + display: none; + background-image: url('data:image/svg+xml;base64,PHN2ZyBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB3aWR0aD0iMTI4IiBoZWlnaHQ9IjEyOCI+PGRlZnM+PHN0eWxlLz48L2RlZnM+PHBhdGggZD0iTTUxMiAwQzIyOS4yIDAgMCAyMjkuMTk5OTk5IDAgNTEyYzAgMjgyLjggMjI5LjIgNTEyIDUxMiA1MTIgMjgyLjgwMDAwMSAwIDUxMi0yMjkuMiA1MTItNTEyQzEwMjQgMjI5LjE5OTk5OSA3OTQuODAwMDAxIDAgNTEyIDB6bTIxMy40NjA1MjIgNzI1Ljk3NTY1OWMtNi4wNzcyNDkgNi4wNzcyNDgtMTQuMDY0NDg4IDkuMTE1ODcyLTIyLjA1MTcyNyA5LjExNTg3Mi03Ljk4NzI0MiAwLTE2LjA2MTI5OC0zLjAzODYyNC0yMi4xMzg1NDgtOS4yMDI2OUw1MTIgNTU2LjI3MTMyMyAzNDIuNzI5NzUyIDcyNS44ODg4NDFjLTYuMDc3MjQ4IDYuMTY0MDY2LTE0LjE1MTMwNiA5LjIwMjY5LTIyLjEzODU0NiA5LjIwMjY5LTcuOTg3MjQgMC0xNS45NzQ0NzktMy4wMzg2MjQtMjIuMDUxNzI3LTkuMTE1ODcyLTEyLjI0MTMxMy0xMi4xNTQ0OTYtMTIuMjQxMzEzLTMxLjk0ODk2LS4wODY4MTgtNDQuMTkwMjczTDQ2Ny44OTY1NDYgNTExLjk5NDIzIDI5OC40NTI2NjEgMzQyLjIwMzA3NGMtMTIuMTU0NDk1LTEyLjI0MTMxMi0xMi4xNTQ0OTUtMzIuMDM1Nzc2LjA4NjgxOC00NC4xOTAyNzEgMTIuMjQxMzEzLTEyLjE1NDQ5NSAzMi4wMzU3NzctMTIuMTU0NDk1IDQ0LjE5MDI3My4wODY4MTdMNTEyIDQ2Ny43MTcxNDFsMTY5LjI3MDI0Ny0xNjkuNzA0MzM4YzEyLjE1NDQ5NS0xMi4yNDEzMTMgMzEuOTQ4OTU5LTEyLjI0MTMxMyA0NC4xOTAyNzUtLjA4NjgxOCAxMi4yNDEzMTMgMTIuMTU0NDk1IDEyLjI0MTMxMyAzMS45NDg5NTkuMDg2ODE4IDQ0LjE5MDI3Mkw1NTYuMTAzNDU0IDUxMS45OTQyMyA3MjUuNTQ3MzQgNjgxLjc4NTM4NmMxMi4xNTQ0OTUgMTIuMjQxMzEzIDEyLjE1NDQ5NSAzMi4wMzU3NzctLjA4NjgxOCA0NC4xOTAyNzN6Ii8+PC9zdmc+'); + background-size: contain; + background-position: center; + background-repeat: no-repeat; + vertical-align: middle; + width: 28px; + height: 28px; +} + +@media (max-width: 767.98px) { + .nice-tips-xl .nice-tips-close, + .nice-popup-xl .nice-popup-close { + bottom: auto; + left: auto; + top: 10px; + right: 10px; + width: auto; + } +} + +/*-------------------------------------------------------------- + list grid style +--------------------------------------------------------------*/ + +.list-grid .list-item { + -ms-flex-direction: row; + -webkit-box-orient: horizontal; + -webkit-box-direction: normal; + flex-direction: row; + -ms-flex: 1 1 auto; + -webkit-box-flex: 1; + flex: 1 1 auto; +} + +.list-grid .list-content { + background-color: #fff; + padding: 1.5rem; +} + +@media (min-width: 768px) and (max-width: 991.98px) { + .list-grid .list-content { + padding: 1.25rem 1.25rem 1rem; + } +} + +@media (min-width: 992px) and (max-width: 1199.98px) { + .list-grid .list-content { + padding: 1.25rem 1.25rem 1rem; + } +} + +@media (min-width: 1200px) and (max-width: 1399.98px) { + .list-grid .list-content { + padding: 1.25rem 1.25rem 1rem; + } +} + +@media (max-width: 767.98px) { + .list-grid .media { + width: 45%; + } + + .list-grid .list-content { + padding: 0.75rem 0.75rem 0.5rem; + } +} + +/*-------------------------------------------------------------- + pushes style02 +--------------------------------------------------------------*/ + +.list-pushes-style02 .list-item { + margin-bottom: 0; +} + +.list-pushes-style02 .list-item.block .list-content { + padding: 0.75rem; +} + +.list-pushes-style02 .card-body { + /* margin-top: -5rem; */ +} + +/* Entry Content ----------------------------- */ + +.post-content { + font-size: 0.9375rem; + color: inherit; + text-align: justify; + line-height: 1.875; + margin: 0 0 1.5rem; +} + +.post-content p, +.post-content center { + margin: 0 0 1.25rem; + font-size: 1rem; +} + +.post-content h1, +.post-content h2, +.post-content h3 { + line-height: 1.5; + margin: 2rem 0 1rem; + color: var(--color-dark); +} + +.post-content h4, +.post-content h5, +.post-content h6 { + margin: 2rem 0 2rem; +} + +.post-content h2 { + position: relative; + padding: 0 0 0 1.5rem; +} + +.post-content h2:before { + content: ''; + position: absolute; + left: 0; + top: 7px; + width: 6px; + height: 22px; + background: var(--bg-danger); +} + +.post-content h3 { + position: relative; + padding: 0 0 0 1.5rem; +} + +.post-content h3:before { + content: ''; + position: absolute; + left: 0; + top: 11px; + width: 5px; + height: 5px; + background-color: var(--bg-primary); +} + +.post-content hr { + margin: 2rem auto; +} + +.post-inner .post-content > .wp-block-cover.alignwide:first-child, +.post-inner .post-content > .wp-block-cover.alignfull:first-child { + margin-top: 0; +} + +.post-content ol { + list-style-type: decimal; + margin: 0 0 1rem 1rem; +} + +.post-content ul { + list-style-type: circle; + margin: 0 0 1rem 1rem; +} + +@media (max-width: 767.98px) { + .post-content h1, + .post-content h2, + .post-content h3 { + margin: 2rem 0 1.25rem; + } + + .post-content h4, + .post-content h5 .post-content h6 { + margin: 2.5rem 0 1.75rem; + } + + .post-content h2:before { + top: 5px; + height: 18px; + } + + .post-content h3:before { + top: 9px; + } +} + +@media (min-width: 768px) and (max-width: 991.98px) { + .post-content h3:before { + top: 9px; + } +} + +/* Font Families ----------------------------- */ + +.post-content p > a, +.post-content li > a, +.post-content dd > a, +.post-content td a, +.post-content th a, +.post-content h1 a, +.post-content h2 a, +.post-content h3 a, +.post-content h4 a, +.post-content h5 a, +.post-content h6 a, +.post-content em a, +.post-content strong a { + -webkit-box-shadow: 0 -1px 0 0 var(--color-primary) inset; + box-shadow: 0 -1px 0 0 var(--color-primary) inset; + -webkit-transition: 0.3s ease-in; + -o-transition: 0.3s ease-in; + transition: 0.3s ease-in; +} + +.post-content p > a:hover, +.post-content li > a:hover, +.post-content dd > a:hover, +.post-content td a:hover, +.post-content th a:hover, +.post-content h1 a:hover, +.post-content h2 a:hover, +.post-content h3 a:hover, +.post-content h4 a:hover, +.post-content h5 a:hover, +.post-content h6 a:hover, +.post-content em a:hover, +.post-content strong a:hover { + opacity: 1; + -webkit-box-shadow: 0 -1px 0 0 currentColor inset; + box-shadow: 0 -1px 0 0 currentColor inset; +} + +.post-content a:hover, +.post-content a:focus { + text-decoration: none; +} + +/* Post table style ----------------------------- */ + +.post-content > table, +.post-content div > table { + max-width: 100%; + width: 100%; + overflow: hidden; + margin: 0; + border: 1px solid var(--border-light); + border-collapse: collapse; + border-spacing: 0; + empty-cells: show; +} + +.post-content > table th, +.post-content div > table th { + font-weight: 500; +} + +.post-content > table th, +.post-content > table td, +.post-content div > table th, +.post-content div > table td { + border: 1px solid var(--border-light); + padding: 0.75rem 1.125rem; + margin: 0; + overflow: visible; +} + +.post-content > table thead, +.post-content div > table thead { + vertical-align: bottom; + white-space: nowrap; +} + +.post-content > table tbody tr:nth-child(odd), +.post-content div > table tbody tr:nth-child(odd) { + background: var(--bg-light); +} + +.post-content > .alignleft > table, +.post-content > .alignright > table, +.post-content div > .alignleft > table, +.post-content div > .alignright > table { + margin: 0; +} + +.post-content caption { + background: var(--bg-light); + font-weight: 500; + padding: 0.5em; + text-align: center; +} + +.post-content img { + display: flex; + margin: auto; + justify-content: center; +} + +/*-------------------------------------------------------------- + top thumbnail style +--------------------------------------------------------------*/ + +.post-thumbnail img { + width: 100%; + height: auto; +} + +/*-------------------------------------------------------------- + post like style +--------------------------------------------------------------*/ + +.post-like .like-count { + display: inline-block; + vertical-align: middle; +} + +.post-like.current { + background: #ff4053; + border-color: #ff4053; + color: #fff; + -webkit-box-shadow: 0px 5px 20px 0px rgba(228, 93, 106, 0.35) !important; + box-shadow: 0px 5px 20px 0px rgba(228, 93, 106, 0.35) !important; +} + +.post-like:hover { + animation: shake 0.82s cubic-bezier(0.36, 0.07, 0.19, 0.97) both; + transform: translate3d(0, 0, 0); +} + +@keyframes shake { + 10%, + 90% { + transform: translate3d(-1px, 0, 0); + } + 20%, + 80% { + transform: translate3d(2px, 0, 0); + } + + 30%, + 50%, + 70% { + transform: translate3d(-2px, 0, 0); + } + 40%, + 60% { + transform: translate3d(2px, 0, 0); + } +} + +/*-------------------------------------------------------------- + tag style +--------------------------------------------------------------*/ + +.post-tags a { + background-color: #f7f8fa; + padding: 0.25rem 0.5rem; + font-size: 0.75rem; + margin: 0 0.5rem 0.5rem 0; + border-radius: 0.15rem; + display: inline-block; +} + +/*-------------------------------------------------------------- + comment style +--------------------------------------------------------------*/ + +/*-------------------------------------------------------------- + footer style +--------------------------------------------------------------*/ + +.footer, +.footer a { + color: #e8e9ea; +} + +.footer a:hover { + color: #fff; +} + +/*-------------------------------------------------------------- + widget style +--------------------------------------------------------------*/ + +.sidebar-inner { + padding: 2rem 1.75rem; + background-color: var(--bg-white); +} + +.widget { + margin-bottom: 2.5rem; +} + +.widget-title { + color: #008c95; + font-size: 1rem; + padding: 1.25rem 0; + position: relative; + border-top: 2px solid #d2e3e4; +} + +.widget-title span { + position: relative; +} + +.widget-title:before { + content: ''; + position: absolute; + top: -2px; + left: 0; + width: 30px; + height: 2px; + background-color: #008c95; +} + +/*-------------------------------------------------------------- + search style +--------------------------------------------------------------*/ + +.widget_search label { + display: block; +} + +.widget_search .search-field { + position: relative; + display: block; + width: 100%; + padding: 0.5rem 1rem; + border: 0; + border-radius: var(--radius-sm); + background-color: var(--bg-light); + -webkit-box-shadow: none; + box-shadow: none; + -webkit-transition: + background-color 0.15s ease-in-out, + -webkit-box-shadow 0.15s ease-in-out; + transition: + background-color 0.15s ease-in-out, + -webkit-box-shadow 0.15s ease-in-out; + -o-transition: + background-color 0.15s ease-in-out, + box-shadow 0.15s ease-in-out; + transition: + background-color 0.15s ease-in-out, + box-shadow 0.15s ease-in-out; + transition: + background-color 0.15s ease-in-out, + box-shadow 0.15s ease-in-out, + -webkit-box-shadow 0.15s ease-in-out; +} + +.widget_search .search-field:hover, +.widget_search .search-field:focus { + border-color: var(--border-muted); + -webkit-box-shadow: none; + box-shadow: none; + outline: 0; +} + +.widget_search .screen-reader-text, +.widget_search .search-submit { + display: none; +} + +/*-------------------------------------------------------------- + widget_recent_comments style + widget_recent_entries style +--------------------------------------------------------------*/ + +.widget_recent_entries ul, +.widget_recent_comments ul { + padding-left: 1.25rem; +} + +.widget_recent_entries ul li, +.widget_recent_comments ul li { + margin-bottom: 0.75rem; + list-style-type: circle; + font-size: inherit; +} + +.widget_recent_entries ul li a { + display: block; +} + +.widget_recent_entries ul li span { + color: var(--color-muted); + font-size: inherit; +} + +.widget_recent_comments ul li span { + font-weight: 500; + color: var(--color-dark); + margin-right: 5px; +} + +/*-------------------------------------------------------------- + widget_categories style +--------------------------------------------------------------*/ + +.blogroll li, +.widget_meta li, +.widget_archive li, +.widget_categories li { + position: relative; + display: -ms-flexbox; + display: -webkit-box; + display: flex; + -ms-flex-direction: row; + -webkit-box-orient: horizontal; + -webkit-box-direction: normal; + flex-direction: row; + -ms-flex-align: center; + -webkit-box-align: center; + align-items: center; + text-align: justify; + -ms-flex-pack: justify; + -webkit-box-pack: justify; + justify-content: space-between; + font-size: inherit; + color: var(--color-muted); + padding: 0.75rem 0 0.5rem 0; + text-transform: uppercase; + border-top: 1px solid var(--border-light); +} + +.blogroll li { + -ms-flex-direction: column; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + flex-direction: column; + -ms-flex-pack: normal; + -webkit-box-pack: normal; + justify-content: normal; + -ms-flex-align: normal; + -webkit-box-align: normal; + align-items: normal; +} + +.widget_meta li a, +.blogroll li a, +.widget_archive li a, +.widget_categories li a { + font-size: 0.875rem; +} + +.blogroll li a { + display: -ms-flexbox; + display: -webkit-box; + display: flex; + -ms-flex-direction: row; + -webkit-box-orient: horizontal; + -webkit-box-direction: normal; + flex-direction: row; + -ms-flex-align: center; + -webkit-box-align: center; + align-items: center; +} + +.blogroll li a img { + width: 26px; + height: 26px; + border-radius: 100%; + margin-right: 10px; +} + +.blogroll li:last-child, +.widget_archive li:last-child, +.widget_categories li:last-child { + padding: 0.75rem 0 0; +} + +.widget_meta li:first-child, +.blogroll li:first-child, +.widget_archive li:first-child, +.widget_categories li:first-child { + border: none; + padding: 0 0 0.75rem 0; +} + +.widget_categories select, +.widget_archive select { + width: 100%; + font-size: inherit; + border: 1px solid var(--border-light); + border-radius: 0; + height: 35px; +} + +/*-------------------------------------------------------------- + tagcloud style +--------------------------------------------------------------*/ + +.tagcloud { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -ms-flex-wrap: wrap; + flex-wrap: wrap; +} + +.tagcloud a { + position: relative; + display: inline-block; + font-size: 0.875rem !important; + line-height: 1; + padding: 0.5rem 0.9375rem; + margin: 0 0.375rem 0.375rem 0; + border-radius: var(--radius-xs); + border: 1px solid var(--border-light); +} + +.tags a:before, +.tagcloud > a:before { + content: '#'; + font-size: inherit; + display: inline-block; + color: var(--color-primary); + margin-right: 5px; +} + +/*-------------------------------------------------------------- + searchform style +--------------------------------------------------------------*/ + +.searchform { + position: relative; +} + +.searchform label { + display: none; +} + +.searchform input[type='submit'] { + position: absolute; + bottom: 0; + right: 0; + top: 0; + border: 0; + border-radius: 0; + padding: 0 20px; + color: #fff; + background-color: var(--bg-dark); + -webkit-transition: all 0.3s ease; + -o-transition: all 0.3s ease; + transition: all 0.3s ease; +} + +.searchform input[type='submit']:hover { + background-color: var(--bg-dark); +} + +.searchform input[type='text'] { + width: 100%; +} + +/*-------------------------------------------------------------- + widget_media_image style +--------------------------------------------------------------*/ + +.widget_media_image img { + max-width: 100%; + height: auto; +} + +/*-------------------------------------------------------------- + widget_recent_comments style +--------------------------------------------------------------*/ + +.widget_nav_menu ul li { + font-size: inherit; + letter-spacing: 0.12em; + text-align: left; + padding-top: 12px; + text-transform: uppercase; + margin-bottom: 10px; + border-top: 1px solid var(--border-light); +} + +.widget_nav_menu ul li:first-child { + border: none; + padding-top: 0; +} + +/*-------------------------------------------------------------- + widget_calendar style +--------------------------------------------------------------*/ + +.widget_calendar table { + border-collapse: collapse; + margin: 0 0 0.5rem; + width: 100%; + caption-side: top; +} + +.widget_calendar caption { + border: 0; + border-bottom: 0; + padding: 10px 0; +} + +.widget_calendar caption { + padding: 0.25rem 0; +} + +.widget_calendar th, +.widget_calendar td { + text-align: center; + padding: 0.25rem 0.5rem; +} + +@media (min-width: 992px) and (max-width: 1399.98px) { + .widget_calendar th, + .widget_calendar td { + text-align: center; + padding: 0.125rem 0.125rem; + } +} + +.widget_calendar tbody td a { + position: relative; +} + +.widget_calendar tbody td a::after { + content: ''; + position: absolute; + width: 6px; + height: 6px; + background: var(--bg-dark); + border-radius: var(--radius-lg); + bottom: -6px; + left: 50%; + margin-left: -3px; +} + +.widget_calendar td#today { + font-weight: bold; + color: var(--color-primary); +} + +.widget_calendar tfoot { + border: 1px solid var(--border-light); + border-top: 0; +} + +.widget_calendar tfoot td { + border: 0; +} + +.widget_calendar .wp-calendar-nav { + font-size: 0.75rem; +} + +/*-------------------------------------------------------------- + widget_rss style +--------------------------------------------------------------*/ + +.widget_rss .widget-title .rsswidget:first-child { + float: right; +} + +.widget_rss ul li { + text-transform: uppercase; + margin-bottom: 10px; + padding-top: 12px; + border-top: 1px solid var(--border-light); +} + +.widget_rss ul li:first-child { + border: none; + padding-top: 0; +} + +.widget_rss ul li .rsswidget { + font-size: inherit; + display: block; +} + +.widget_rss ul li .rss-date { + font-size: inherit; + color: var(--color-muted); +} + +.widget_rss ul li .rssSummary { + font-size: inherit; + margin-top: 5px; + color: var(--color-secondary); +} + +.widget_rss ul li cite { + font-size: inherit; + font-style: normal; + color: var(--color-muted); +} + +/*-------------------------------------------------------------- +## Pagination (WordPress CSS classes) +--------------------------------------------------------------*/ + +.screen-reader-text { + clip: rect(1px, 1px, 1px, 1px); + width: 1px; + height: 1px; + overflow: hidden; + position: absolute !important; + word-wrap: normal !important; +} + +.pagination { + position: relative; + margin: 2.5rem 0 0; +} + +.pagination .nav-links { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + -webkit-box-pack: center; + -ms-flex-pack: center; + justify-content: center; + width: 100%; +} + +.page-numbers { + display: inline-block; + min-width: 40px; + height: 40px; + text-align: center; + line-height: 40px; + margin: 0.25rem; + background-color: transparent; + color: var(--color-muted); +} + +.page-numbers:hover, +.page-numbers.current { + color: #fff; + background-color: var(--btn-primary); +} + +@media (max-width: 767.98px) { + .pagination { + margin: 1.25rem 0 0; + } + + .page-numbers { + display: inline-block; + min-width: 30px; + height: 30px; + font-size: 0.75rem; + text-align: center; + line-height: 30px; + margin: 0.25rem; + background-color: transparent; + color: var(--color-muted); + } +} + +@media (min-width: 768px) and (max-width: 991.98px) { + .pagination { + margin: 2rem 0 0; + } +} + +@media (min-width: 992px) and (max-width: 1199.98px) { + .pagination { + margin: 2rem 0 0; + } +} + +/*-------------------------------------------------------------- + dialog +--------------------------------------------------------------*/ + +#nice-back-to-top { + position: fixed; + width: 48px; + height: 48px; + right: 25px; + bottom: 25px; + z-index: 10000; + opacity: 0; + visibility: hidden; +} + +#nice-back-to-top.active { + opacity: 1; + visibility: visible; +} + +#nice-back-to-top .icon-stack { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; + -webkit-box-pack: center; + -ms-flex-pack: center; + justify-content: center; + width: 100%; + height: 100%; + font-size: 1rem; + text-align: center; + color: #fff; + background-color: #252c41; + overflow: hidden; + -webkit-transition: + color 0.2s ease-in-out, + background-color 0.2s ease-in-out, + border-color 0.2s ease-in-out; + -o-transition: + color 0.2s ease-in-out, + background-color 0.2s ease-in-out, + border-color 0.2s ease-in-out; + transition: + color 0.2s ease-in-out, + background-color 0.2s ease-in-out, + border-color 0.2s ease-in-out; + border-radius: 0.2rem; +} + +#nice-back-to-top .icon-stack:hover { + background-color: #00818a; +} + +#nice-back-to-top .icon-stack i { + position: absolute; + top: 9px; + left: 50%; + -webkit-transform: translateX(-50%); + -ms-transform: translateX(-50%); + transform: translateX(-50%); + -webkit-transition: 0.15s ease 50ms; + -o-transition: 0.15s ease 50ms; + transition: 0.15s ease 50ms; +} + +#nice-back-to-top .icon-stack .back-to-top-text { + display: inline-block; + -webkit-transform: translateY(5px); + -ms-transform: translateY(5px); + transform: translateY(5px); + font-size: 11px; + text-transform: uppercase; + letter-spacing: 0.05em; + line-height: 1em; + -webkit-transition: -webkit-transform 0.35s cubic-bezier(0.165, 0.84, 0.44, 1); + transition: -webkit-transform 0.35s cubic-bezier(0.165, 0.84, 0.44, 1); + -o-transition: transform 0.35s cubic-bezier(0.165, 0.84, 0.44, 1); + transition: transform 0.35s cubic-bezier(0.165, 0.84, 0.44, 1); + transition: + transform 0.35s cubic-bezier(0.165, 0.84, 0.44, 1), + -webkit-transform 0.35s cubic-bezier(0.165, 0.84, 0.44, 1); +} + +#nice-back-to-top .icon-stack:hover i { + opacity: 0; + -webkit-transform: translateX(-50%) translateY(-10px); + -ms-transform: translateX(-50%) translateY(-10px); + transform: translateX(-50%) translateY(-10px); + -webkit-transition: all 0.45s cubic-bezier(0.165, 0.84, 0.44, 1); + -o-transition: all 0.45s cubic-bezier(0.165, 0.84, 0.44, 1); + transition: all 0.45s cubic-bezier(0.165, 0.84, 0.44, 1); +} + +#nice-back-to-top .icon-stack:hover .back-to-top-text { + -webkit-transform: translateY(0); + -ms-transform: translateY(0); + transform: translateY(0); + -webkit-transition: -webkit-transform 0.25s cubic-bezier(0.165, 0.84, 0.44, 1) 50ms; + transition: -webkit-transform 0.25s cubic-bezier(0.165, 0.84, 0.44, 1) 50ms; + -o-transition: transform 0.25s cubic-bezier(0.165, 0.84, 0.44, 1) 50ms; + transition: transform 0.25s cubic-bezier(0.165, 0.84, 0.44, 1) 50ms; + transition: + transform 0.25s cubic-bezier(0.165, 0.84, 0.44, 1) 50ms, + -webkit-transform 0.25s cubic-bezier(0.165, 0.84, 0.44, 1) 50ms; +} + +/*-------------------------------------------------------------- + Like style in blog post +--------------------------------------------------------------*/ + +.list-like { + margin-left: 10px; + color: var(--color-dark); + background-color: transparent; +} + +.list-like .like-count { + padding-left: 3px; +} + +/*-------------------------------------------------------------- + top search style +--------------------------------------------------------------*/ + +.site-search-popup { + position: fixed; + width: 100%; + left: 0; + right: 0; + top: 0; + bottom: 0; + background-color: #283149; + z-index: 9999; + visibility: hidden; + opacity: 0; + -webkit-transform: translateY(10px); + -ms-transform: translateY(10px); + transform: translateY(10px); + -webkit-transition: all 0.3s; + -o-transition: all 0.3s; + transition: all 0.3s; +} + +.site-search-popup.show-popup { + visibility: visible; + opacity: 1; + -webkit-transform: translateY(0); + -ms-transform: translateY(0); + transform: translateY(0); +} + +.site-search-body { + position: absolute; + display: -ms-flexbox; + display: -webkit-box; + display: flex; + -ms-flex-pack: center; + -webkit-box-pack: center; + justify-content: center; + left: 0; + right: 0; + top: 50%; + -webkit-transform: translate(0, -50%); + -ms-transform: translate(0, -50%); + transform: translate(0, -50%); + -webkit-transition: all 400ms cubic-bezier(0.17, 0.67, 0.39, 1.09); + -o-transition: all 400ms cubic-bezier(0.17, 0.67, 0.39, 1.09); + transition: all 400ms cubic-bezier(0.17, 0.67, 0.39, 1.09); + /* easeOutSine */ +} + +.search-popup-close { + padding: 1rem 0; + text-align: right; + color: #bbbbbb; +} + +.popup-close-btn { + display: inline-block; + cursor: pointer; + line-height: 1; +} + +.popup-close-btn i { + display: block; +} + +.popup-close-btn:hover i { + -webkit-transform: rotate(90deg); + -ms-transform: rotate(90deg); + transform: rotate(90deg); +} + +/*-------------------------------------------------------------- + svg style +--------------------------------------------------------------*/ + +.svg-404 { + display: block; + width: 64px; + height: 64px; + background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJAAAACQCAYAAADnRuK4AAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAB3RJTUUH4wkGCCcYs8WFqgAAAAZiS0dEAP8A/wD/oL2nkwAAY/hJREFUeNrt/XecJOd1341+n1BVnSduTlgswiIDBEkwgiAoBpEKJE0qWulV4GtlW/bVlaxAmkq2P7IsXfnVtS1btK1IXipTFEUSABNIggkgiJyBzTt5pkNVPeH+8VR1V/fO7C7ALKHxafTMbE9Pd9Wvzvmdc37nHMGzt2dvz+DmQQB7xbOH4tnbMwQQBBA9e3v29uzt2duzt2dvz96evf2Tu/2TJEGf/e2bsah6j1Y7ItveEeuzSri2Rbdjkbe1yOsKmwjhNSAB55HGepnlLurlROuRz9ZzpzbWaC9ZEZ9q+bW10252AN6/6l+9+1kAfb3e/vI/fR996nRYZYZlOSuXhUEnXRo7GwwOxjK7sCazA3XV3xcrs0tLs11J35HSaSF9hPQa6RV4iUAWh8jjvQccTlicMM5J463InRfrudWnMhud6Nvakczpx1MfP5pSf7RG/4RwJl1zHbdCx+co/83/+l3PAuhr8fYff/Xn8Ahxnb5b7dBLsVBsk8JfXheDq2uyf01D9y9JdL5LR6YptI+EJkKhhEIKJUCKYGtkeWTEEDshbhXgffg2QAnvPFiPtzgM1ltvfC4zY3Qvy/Xxnq0/2LfJXX1Xu9t5ca909uRJM5/90fEb7JTu+//0m//+WQB9tW9/++tvIveR3qOPNdpqfbeSXF9T2Quaqvu8RjQ4FEV5S8ZOEwslIiHQErQAJUFRAMcXjwVohuCpAKj80geHNvzaAjYACefAeMg9Pvfe596SS5NlUbefx492Tf3TfZvcvpFFnxEiPnqfvaT3nT/3DnPN2+7h82+94lkAfaVuv/cb/5KnOCBe4D5av0A9saMRpdfGKnt5U/de3IwGl8Y1UxOxl8QFYKICNBrQBXCUCHdZgEhUAVS5VzHk/cgSOQ+u+JmrgMj6AKLynnvIHeTe+xSfpbq/kdUeGpj67amNbt2wzc89Zg+ceMrv6U2x5r/35//nswD6svGbX/tn9H1dzIilmX3q2MVt3XtZTQ9ubsSD59Vr2axMHCQKYglRAZgheMQINEoU1gdQLjwKRo/Chy+qR8cz7sI84EQAjxPBEnkRQFMFUu7AMPo6c5A63EAwGMTLG3njs31Tu61v4g+cyucezHy0/MpffL9/FkBf4tsHfvVVKGG37VYnrmnp3utqevDyVjI4HNdNQk1AUliaEjwRBXBKlwUoD8qGRylAaVAKZAKyFh5FDDICIhBlEFb4Km/AZeBzcCm4AdgBuBysAesKMEmwItxzPwJVXrkXQKLvSAfa9NLa/Vke3bJqO3/3SH7gc+BPvfYX3vssgL7Y2y2/8g1Y1OwedeSG2Xj1DfUofVk9yS6K6lZSkwE4sYRYFMApQBMVgNEWtA+cRyegO6DnQG8DvRPkdlCzIKdBtEG0gPoIPEIGyxP8FPgUfA/8OvgVsEvF/QSYk2AWIV8G0wOTB+tjJRgJRowsUe4hqwBp4DF9aXtp8lgvq992Op/5y+N2x8c1ZukVv3DLswB6urf3/MY306XZuNA//Pzd+uS3t+LeK2q17GBUd3oInEQUwCkANOQ5FrQDHUE8BfFeiC+E6CDoAyD3gJwF2QbRCNZmGIKJSig2eSs9ixuFYhjwA/BdcKvgToJ5CsxjkD0K6eOQnYa8W7gyHcCUezAugCgtwWSh7zEDmff78VPdtPb+k2bbO4+z+xN1+r2bfv7WZwF0rts//PorWRKz6gL3+CU75Onvmk1W31CvpRfpuk9EQ4ysTQmeId/xoA1ECuI5qF0MtSsgugyiC4OlEU0grgClSmiqIBHnANDkIawy7iqoVgKY8ocg/QL074P0CGQ9yAVYBRnBCuXFY1oAauDIezIdDOLHFtPpv3p4sOsP7+tvv297tGG/41fe/yyAJm9//avfhPaZmBUrrabov3FndOr7p2rd5+qma4m6GLc41XvkgrVJWlC/COrPgdpzQF8Eag5IAmD8ViARFcIsz/Pd+uL1quCbfCwiO3wBqI0Apuwe6H0aunfD4GThzmQAVOnSMgogOXzPYXpyY6XfuOu42fmODTrvXvXtFYPy3/Jv3/MsgADe+yuvQWOiabF8+ZxcfMvOZPHbkkY+LRtSUZcEklzwm1gEIxJ5iD0kc9C8BpovgeRa0LsCaPzkyR0LszaxHuJpHBa/ifUaC8/OtFZDgDpwa5A/AN2Pw8YnoPsYZBmY0iIxcm0F0XZ979KeXjo1mP3r427n7+VW3AXkN/7SJ7+q5059Vf/6L3n8lW/jIT3X2hMvvWG3Pv72XY3F18Zt3xYtKWkKqEuoCwLvAWouPDa2wfRNMPfPof1GiK8OnKa84kNcXZzMzVzQVgDYDCB+C4Ccz/du5NYwIZITMajdUL8WGtdAMg+iB34VRF5EiFQeQSghIm0aLdG9om77N+B9t+caj3zotbfl/+qmJrfe8tF/WgD63//u27lU3iPbrfULtuuFn9hfO/7zM63upbItNA0JjQp4EgGxg8RBfQ5mXgrz3w2db4H4YgJzzouTVJw8sRVI2IL3nC+I3CaA8RPEevK5bjySwxbvlxAB1q6AxtUQzwIbgYwLW/B6OeL3SiAVqiEGu+qu/yLpXfvV9r1P3O5vXPkXr9jm/+qWu/5puLB3/srrOcre6Eb3oefu0Kd/ar6++s1JwzZoKKgRgJMUZDn2EFuotaF9DUy9EhrPBTUFrjwZYpO7HNW0znBf5ceWE4dBPA33xflZLL8Z0DYBt4jCBZA9Cqu3wspHoPtUQbAVpMCgINkDDz1LuqH6C+n03x03O/7zo+7AHTNiNXvVL932j9sC3fq2F2KdrF/Hna/bHZ385fnG6ivjtktoqmBt6rIAEJDYAKTWxbDtjTD7ZqhfEd62zwrwcBa3NPFvgi0I79ms0bncmNvEKjnwbuI5dnPLNLzn4VHPQ+NyqB0EacGdBtcrSi1ydC1IgZY2qvv+4ZrrX9XyGwtdmzz2ozfPmd+/7eQ/TgDd8daryL1uXqCe+q7d8clfmml0r9MdIWmU4Cm5jofYQH0a5m6C7d8JrReBbIQMMGYCDJuBxm9xpW/2fHcegGGTk86ZYPJuC1fnznIvf9eEC0MIiHdD43Bwa24F7CJIF0BUGkspUNKLOoM9sUuvwYvBE+LCB//slgfT/9TY4H0f+Pg/DgD959/4cd57+A4+17p6ap889pY98cl/024OLlQtCQ1ZAY8IPCdx0D4EO94Es98Eyd5whfrszChHuAkQnC0iOl9iXJxYUfnZGRblfO52i68nrVT138uwPwdZh9qFwRqJHPLjIRMu5UgxIAVCChKy+ZobXJvYnvqmD//1vTmq/9e3fP4fB4C+++ZDnGzMzR7k8Z/eF5/4yVYr2yNbagSeMkyPLSQRzL4gWJ3Oc0N9yqcVF7BVKO02sTD+LCG3O4/oym9uKc4gzFUXZc8OKu/Owxr5kVsTHqJ5qF8CUQfMiZAGEEWeSYTPJJQgEXmn7vpXRWbQEN7f/R0vv7j7R7c+9vVLov/Xr383Fs1+88jcHnfkZ/Ynx3+k0bJztFRwVXXCY0wAT70Nc98As6+GZFuIRDZL+m1FmMfIsagk8zYj0ZsR5y81iS5A7d0mZZDNXCebE20PeAXWwvqdcOovYe1+yASkYkSs+x66lv66Wj6abnvHk+KCf39ldtfJj9Vu5I2/8J6vMwvkPT9662/T9msze+2TP3MgOfZ/11tuTrQqfGeYWTbQ3AHb3wAzrwLdAlGQZOHPk6NMPm/iBIlz/Z47Czl2Z7FEZ7M09jxe42yWq1rENeEjRTuhdgDcOuQnClcrK4GCJBK2Xnf9y6TJ6/fqKz93Vfap3r7X/iT/8IGPff0A6O95P30ftQ/y5E8ciI//WKNlR+CpTVie1oHAd6ZuKPx7HviHmLjKxWbhsDtLDoazENrixAl3Fnc1+XO7yXMsePs0+JDd4rUmgOm3AKS3oKcDL/IDyI4W+a+KGA5BhKsldnBYmox75ZV3XdP71OC//toC/MHbvvYBdOsvP5e+b9YvFI//4L7oxL9qtc120SxdVhFpxT7UsdoXBvC0rw4nU9oQbYjNrMbEiRVb5VjceXCbTQAiCrIstjjp3k0kA58JsZ4A3xkW6yyv6yvWSLWgfkGROzoWdEpCFtebByGIvanHNj2sbNZ/Irro7rc89l+yd9x25GsbQH/3K6/igeT66Fpzx5v3RSd+vt3M9spmkSAcA4+HqYtg++uhdSkIEzhPaXmEqwDkPEJi4c9iPc4VSvvzDLe3iqzsFvfNfre4e3cWS7TJ86sA9raI0hJI9odjlR0NPxsrCEtin7cimx7WNj35mN17/4/fNG3f8aFjX5sA+q1/+Rq+977Xy1+a/dNX7I9O/PJ0vXdYtVQBnKKiHhMA1LkItn0zNC4KLgtTAU1pgc7lmiY5yyTvcTzt0P2sXMV9cXf/Rb6GK0BUWiJX1NXiveH77GiR6hgFFQJB4vIpZfOLFfbh9ybf+tjP3FTzf3rrI19bAPqvb/0OfuzJv+SlFz155QX62C9vq2+8WFfrWbVKTat9ALa9FhqHCvDYCZe1mQtz5452zhWOi80smT8LaPxZLMn5hOrnskZnSyr60fv1VeCUX5fPywsQ7QoXYXqsINxF1Fkk4GObbce43dvcqbt+f+pfn3zbS/q885YHvjYA9Fu//W955cZf8PntV24/oE787K5k+Y1J06thWWIox7DQ3AnbXgPNi0ZuS/qRxak+nstqCHfuksKm0ZU/Tw5jz4MQ2/MAi6sUejd5XX8e7qua5faVAq0vQRRBvDOUPdJjBRcqUhJeIIHEpfuxrnGod9cnX5fcurHrRW/ibz907xd17vWXAkDXLf0996vL6gfdE9+1LVr8jlrDRaEkURF+KQfJNMzcGCxPWfvZUp+z1feVn/uJvI7Y7Lnn0gCJZ5Ae26p2dras98TPPGcvrp5NSSAqvy8qlkjXYeYlkG/Ayj2h9cgSzoOTJNaqbWbpDaumfv/71q7/refzqfSrboFu+YXrOab2q33+yRv3yONvm230d4t6wXvqFQFYUoO5l8DUtcHiYEaWB1/8zI0OyjCMd2cpT5wthN/KBU5e5f4ZEOnNyLQ9y7/7TayMPUdENxHSezvuzkoiXr07E8of0Vyhw14CXyHVXhJ5E0cmvaQnp+5f1LseecPLr/TvvO2hr54FWoj3ss8+sXs7p356Ju5dKBIdEF8qCHXQsdC5CjpXF1dPUTD0xV2IihK08nNsxapsYYUQFZBNPNdXM9BUrNSktdlMSC/Ow/JsYSH8uayJO0shl4l/m8xI+1F/2hmvV1iieBZmXwj5GtgFcKqwRB5hlZjKB3t39Y/+dJfmfQ145Ktmgf74V9/ElFuuzbuTP7pXnfzn9RbJkDDHRWtNVBRG514CUXNU3yk5zGa8pxqS+8mcz7lC9adjSSZJ9tPI5/jNOM9WPMhvwZnO8X7GrI4/kwe5SUtkR4+6E6xPehxsEd4XnbTSIbTNtudG5CfV7o9+502H7J/d9shXHkA/9tImdd+/cT9P/sJUI98ph1oeORK8N+Zg/sVQ216Q5uJEjRFnt0m0VAXZFmG3OIcKcFM3t1UUZs8jr2MZyWW3Ir1Vkm7PPwXgt8h4j7kou3lEVgKqGv15AohsD9LTxdsSRcArUM7FymR7BjZ+4FWrH3to6g0/zfs+8ImvnAv7q7e9gjXE/OXm7h+ZSgYHZG2yuc9DlMDUlZDsqEgxJghs2SIsK+7FFT3rVXckNil4erZwUVu5u63E9U+3tryZYM1xpv56C7Lt3bndIBNt1H5S5ciEy3TDGmQY/uBBRdC5HPqnwRwLfXOxAOtRNUkrzw7s6h/5gb+auulzl/c++Yyyi/KZ/NL//o3v41t/8QPsyp/81jm5cnOc+EhEFc5TanibB6BxcOSbfZGGL++l0Jzqz4ur3FdE6D4vsqxVK1Dec0Z66Hz89cvXG75G+br5JndTedzqOfkWz8kmPkf5WTf5237yvZsJy1b93JW72+yzVY+THd3L1/EpxNPQuQySZtHaXTRgRoI48Wpabbxsr338DW+Z+RP5v976+q+MBdq2cR9/+YsvuXiHOPkd9dhsk4ms9KKXIfsMtC4BlYQDPEaYC8vjqyRYVHIXhaWoRhDl88RWMozy0Z5DolEN/ys/E5zFIm0hkfVVKyLOYVE4i4WqfO0r8o+q9fF+k5+VHthVrJIf5Ycg1Meae6F/ANL7i3bvMDtAxoJGnM/P2+U3/bel7/xQwuALX3YO9Ds/dTO/evp16vsaH/j+HfHKtzcarq6GOR8ZalxRBFOXQOuCgueUlW9GhdIxsuwrhcyzJA79ZmTTTnAoyzk7JM5ZezrfkNuyterwXK9tNy9veFuJtCYyz35CzTgW3vvK8+x4aI8OicZ0AUw/XEBl/OI83vh5YfNTH6y//lM/eWPd/ultj375APRvXtHhFe2HrrxAHf2pqdrgsrguEEPSXACosQ2mLguJLVGWKRjJT4U7M7ISE4AaA8JExVycRylC2C3qWFvpm/1Zoqank6nehIx7e466WgVMzm2S77ETwKmQ5mp9rAoe/Pi/iSS4wWyx+LkYzjiS1sYml7VWtvDpOXvqxM2vvJF33/rAl96F/cG/vpHfWb8x+sX6/3xVs54+J4qZmLvjwwSMxj7QzUCch+6qeNPlY0mWhRg2bKJEhRhzpgsSFddX0b5s2lXqt+g4FWfrQn2mJHoT8rup29qKXFfcUTXfU7ojV3GRY8/bJDdUEmg/kTtCQH031I5Bfmo4ZEtoiY4trax3/Xx++tUfbrz2/gvMQ/0vuQX6w195E5fwBNfWj1y6W5388am4e3lck8hy2EE55KCxLeR9dFTJ8fjxr4d1LMbrWVXXJjabhLGJOxL+HCH7uVSB/hzuayur48/DjdmzZK19hfBOhOuTVoSt3NeERXKTFsqPrJqzYWSNs5AWVqh0YU4gjNGpjaKaWbt9pztx+oaXvpC//MjDX7oorGVX+b35t6t5e+xFdTF4bhSBGJLm4pV0BLWdgTj7SmRCJUJwZVRRRCdu4t+GPMBUfs+E57ni96hGWPYceZvJqM1MRF2bRVZmi9+bfI1sk9eyE6+5mUbIj3Oe8nMN75WotCppLT+zK46bqx4fMzq21eM3lMMW39fmIZ4JF17hOaQS6FjQVt3ntezKje/qvyypmbUvXRj/gic8M/kpvmPpt3bXGby6rgYzIpKI6oxBCUTTkMyOA4ZqmFkNN904OIYHoRqu5hWiaSZC4spBdbYS6lfDarPJSTRbgCs/B8jMFmCZfE1zFtAW79GVd1MBQuWzlZV770YhPJULD7tFOG/Hj7Mz4xeYz0HGIamromG7tChcWUNljRqD175A3rnjQPogf/brb/7ScKCffcerednb7+RT//bCKxuy/8IoguFo3OG0UxUmZaioOBBluF7ILEUl+efleP2rDK0FlTpYGGbpxeh3h/93lfmFvjqOd3JOD5uE+mxSX+MsFXl/Fv4jJniMPwtPqiT6ypTFJH/xbkR1Sj6DKP5K5fX9JP9hPIyHCQ7kxr+PpyFuh0lqMnBXoQUqgpm8+8KBHlz7ge0/dPTKwR32SwKgZr7Mu37p1dMx2c0N2dsrooDa4ZRTQahzxVMV/60Kpl/keKSoAKmYbCrFmDEsD5ozDm8dWIP3rphOoRBKIyMNWiKkHAfA8LXlhBh/M4J9FvJ93gOmxMTfcFtkniv/7t0oCPDiDCLsncPnFmdyfJ7jrUMIiVAaoWS4C1V8vApwSuLMxCxr70c5ourXKgqeor8WcnZKIKQHLanL/nxk01det37bbQ3fW/uiAfSnb/tmrlv+G+6rX7arJgY3xtqHkylBlCNIhAyolnFhfWRB2iqVdVecFFmxIIX18B58ZrA2x2UpWbfPYCOlt5Ey6Buch7gR0Zlr0J5ro9sNVC1GCFnJO4rxSGVIyNnaEp1R4pgEkNgigpq0TmKicj6RbCyjTu8nKhgjq+Cdx/QHZMsbLJ1YY22xi8sdUSxpNCOanRr1Tg1dr6PiBKkUQojxaG04gngiwTh2t+F50VRIs2RdhCzcmBJoDU2zflPLb+z7D4f+8J6/evvP8a2/+N5nDqC2XeEvZr83unbwseubdK+QWoyAU951DFG70O1SaHsmwCPl6EOWmV8PznhMZrC9Hr21LqeObfDU4+scO5qytJjR7VqM88SJYtfeJte+cDuXXL+LZiTDhNUxg1HkA0TVpItxayE2c1NPJ3wX5ycuG7MwciIk92f+qjWkaxt8/vajfPKjp1g8leKdI44lnY5m546EfQdq7LmgzeyODvV2A5UkSF0CifEh6M6Ph/TV5KT3oIpzJrvD8ygUSC1osnFI+fzFP/DYzzzY8Ov5F2WB2maZC8ygGfvspTWVNlGy8JsCL0W48HWziLwK2cDwaqiWL6o5jFDQs8aQDwb0ljZ48tFV7rt3jYce6nHyVE6/77DGj9IbDu65u8/ikmfXxXM05xsFZ6hchbiJHNEEgEqLCJtYpkmLIs6jgOrH3ZmfzAUxftUPuYgYBxkeoRy9nuVDty5w1x0rSCXCaKDCyEZRl05HsXfPCocPt7j08g7bd3dIOk1ULUEpWcm5bZIHGpZHKl/HreDORB4sUHFeY2WSutl42aw/9ScvPX73MwfQu9/6am78pr/nI39+xY6633i+LiffjhXUVQAQlQPk/KhHaejvXeHawHmPzTLStS6nnlrhc59d4XN3rXPyVI61oDUkMchEhuqW9aSpwzjo7GhT39ZCKA/GVHiNHyUWS75VgkZMJBfFxPO3AojY4t/O4NViwqpUXVX1wnHj9b5q4lBLajva7Lp0G08+0iMfpGgtkMVnsc6zumpZWenxyKMD7r13g2uvWeeyK6aZ2TlF3KyjYh2skZsg2VQ40PBCA1QNVB2kKSQ2AUBKIVr5+nOX9Y6D777gm++Gv/HPCEAN3+NP/+71WgqurdO7CEV4g6XrQgRTqJPRm3JydILGXFiIBpz15P2U7tIaD9yzzMc+tspDj/YxxpPE0KoHPxw8nsfmHisF87s7XPGyA9z4zw7R2aGh1y+upBIUfnRyvKxEPYxaf4UYb74bGhC/xW4MsXXU5auF2UmS7iaUg1XAViOpystbT3uuxmt/4AqmZht85v2PsHZqAykdupC6GBeumTR33Ht/jyNPDXji0T7Pf0HK/oumqE83iZIonKNqtOYqlsdV5SQSdB0vNwrxpgi/q4Wo0dutXHZ9Oz99D2cOYjq/TPSPvbhO5NKk6df/+axYeomuSSljiYokUkuEloikCUmnyCj5ivX3E5lnsNZhen2Wj69wx8dP8b4PLPPEUwOiCFoNQb0uqCUCrUDi0Eoyu7fNNa84xCu+92pe8I0XMDsvEL1emAw/DG3txPn14wMNJjXFVaXjsBBZWAi3hRx1eCIY5xTVf58UfZ0xpYzx7HH5786Dswjvac7V2H/Fdrbvm0YIyPs5Ljdo4dFaEGmItEBJwWDgeOp4xumFAY3EMd0UKC0DKWaiXubcOLF2xWe1BvIu3jq89Tjri7SUFwObnHIq/od/9prr7Z988KGnb4HumXs5lyx/vF23G9ep2MtyGcnQK0kZuiOhiLpk5QCHTgCQID02d5heyulja3z0o4vc/slVen1HuyWpxRBFYS+Ktw4hBTN7pjn03D0cfuk+9l48Q1LziGwDVgdhSsWQqlROzFgXxjjHGKlG/LgPrqZSvd+a7pwRtk/8nvcTv78Fj/JuQtVRsURpqJ436zWuu2kbF147y2N3LfDAx47w1D2n2FjqYa1FKxHGYUeSfgqPPjqg112k37Vcc51lar6NrkVIxCZEeqLUITTIGE+OF4HXEriXrpv1a4+73TvSXv/JZ+TC5tcfFdbLQ4nvXSxkeD+jdUgCLxVCRsWbqboNMZbcsrkl76csHlvn1g8tcvsd61jrmWpLakm4oiQeZx3NmToXP28PV3/Dhey7bJo49tBfheU07KLwdlQUPaM7x48AJCZOuq+G+RUgOL9FKshvnVz0YpOk3Vm4NlUOVAGVq+RuytdJDWQpIuoy3ahz3cvmOXTtLE/ctcg9H32Kxz9/gv7KIGxu0AKtPAMlOHEy4x/ev0Q+sDzv+Y7OtiZREhcR2ibh/LCWKPBCF0VtPzy/QjlRY7A/z9JLnXfPDEBJtiqlyy6LSWfDeSmAM7RCqhi5VjJ8OQpbi6jDGY8ZpCwf3+C2Ajx4z3RbkCTBJHvrkFKw+8ptXPfqC7nkhl202xIG67A4gDwPrytl5cRWQFINmUtr48V4bmizKo7wZyms+7PkE/1ZxGWbRfaTf6fCQ4aL7PzownMejIVBDnGXTrPOVS+ZZc/hNg/cPsPnb32cEw+vgPHUYoFSHqkEK6uGWz68jABueL6nPd9AxXEl8TihrSoz31IPz2vVSCiRt6Zk7zKLev/T5kB/+7abaZplXfO975iWyy9SiVQyEshIIKJQgBNRDRnXKnu2fMUyCJx3mEHG+kKXD390iY98YgPwdNqCegke40gaEVfctJ+XftdlXHLdHDXfh5U16A2KSKtada+4rjFZw4T78GKLrgs/HomcoS2eVAeyuTLwjIGak+I3xhN8Y+Tanfme/SaiOVdEmv0U0ox6S7Pr4mnm93cwmWP1VBebGXQk0WEEMOtdx8lTOe2aYNusDpxIgKhqiLwbLchzDm8NzgzwxhUlNI8tSmepi5/6yNr+973mefvc+z/95PlboL6L0LLZmDILl0qNqkppwgUuQCo8HjFM0cviAEi8t7jcMljr8+lPr3L7Hes45+i0C6IswRnL1PYmz/nGg1x9816mOhKxvAyDbKROrG4PdJWwvBpRTbobv1n/V9UyVKQigjNrZKX18WfjQROv5TcplwjGe7g2zURPhv5+E8sE5MEi6UaNg5e06MwdZmZHgzv/4QnWlwdESiISgUCyvGq47ROrtFqCy68QJM0EpeU42S8evbfhXArFcHZ1MTpPSB9Fee/QgWk5KxCnnpYLizA4qbfHfrAP4aUXIvyhSsuwFxLvHaLsqqhc2d44TD/nwQc2+Ogn1+inlk5LksQCLTwud8zva/PiN13EZS/YQYKBhW5hcSqliGrxVIjxq1q6CUGBn0jrbKKbFn5zHnNG+M548XPsd88hQJsUfI1lqCdrYZXc0BngcRVKULi1tRwxSJnvNHnhtxygPZPwib96lOUTG2glqScC5+DE6YyPfGKN6Y5m/0GBJCqyGRM9ZlXttBB44SuuzMuayPfO6/5egX96AGrYdZTL92qfbR8WhId6+MoikZLUDomzxJtgfU4e63P7HessrhhaDUktFmjpsdaz/UCHl337RVx6/Sw67UJ3UERym50XP1G1F0Gy6gpeNFwK5yvVeTGRJ9rComxKgP05vj8HY/abJR8nMvFDl8Z4MnSzqG6Yhinc2sBBntNs1bnuxu0kNclH3/0wC0e6aCWo1wTOeR55MuVTd64zPR0xM0coe/jxHjKPxXsXIjAxyomV30tMW/lsp3i6JFo4g/B2p/Sm5sV4zswXf6A8CN67sCHbuyA78TBYz/j83Rs8+mRKHAtqMSjpsSaA5+bvvIhLrplCbnShl1XciagQ4aCW894X94pBECCEK9LvoTof7n4iVPdnGhpxtvqXmACB2KS2dhaJx2b/JCpRqSOcsIKDeOvxrtgqPowBfMjliIK/iEoPHYSLNrOwYohbda68YRYpL+JD73yEhaMbRErQqAnWup677+9zcG+Xa5uSuJ4U1/1ETioQkSLhWlkVIQQSV4tcbxd43vOLL+F1b//ouQH0u7/5MzRO/DlWxrskPvLV5r1qX5/3QW7hXYFs8Dh87jh2rM/dD3TJrKPTFCgZShLb9rS4+U0XcumVU4i1LvQHo/SNDyfeAy5zuNxgMovNHCY3mDyE+t4XB1iG4p+KJDpWqFgjE4mKFVJr0KIAlZigMf7cuZ3NwHfWWtjWMiDvHc46XG5xmcFlFpe54WdzJtx9YY2UBBkpdKwCQY41MlYoqRCla/cyuPvVDXTDcsW10/jsAm591yMsneyjtaBeg5U1w11f6HJgd8KO3QqvRMEOXJCPOIv3dnMplACBr8V5d/eBpSf53N6XnZ8Fumj5Y6zU9omZ/mO7EF4jJzRLVF1EtR1Fg3P0uzn3PtjnxIIJSUItsNYxv7PJTW84yKVXthFr6zBIw2tIUSSKHcZYzMCQdnPWlzMWT2csLRvW1y3rXUeauqJeFkoeUSRotiStlqLVlkzNaNozEY1OTNyM0Y2oAJQKGqYxSuTP7Y6eVo/YeJTujcVmlryfk3dz+usZ3XVDd9WwvmZYX3OsrzsGA1dcHOHKj7Sg1ZRMT2lmZhUzczHt6Zh6KyJKNCpWCFW8I+tgrYdqOK64bpqsu59b3v0Y6ysZsRakyvPIUxkPPdpnZiYiaRSBt5uctu83X7/nfSx9vu1vr/6X0Y61e/LzApB3FskgVi6b82I81A9AKtxKhYh5QjreG8/Jkyn3PzrAOE8jEljjaE/FvOgb93D5tR1krxcsjw8FPGccNjeYfsb6UsqpEymPP57y6OM5x04a1jY8We6xzg8rDXJIdUL4msTB93c6gu3zil27I3bvTdixO2FqW0LSidG1qDj4k1FatX3an4eUQ5ypABzqekLi1PUN6VrK6kL4PCeOpJw8kXN6ybGy5uh1PYOBJzeFC6tcoAJQShDHgnZLsGOb4sCeiAv2x+zandCZq5E0Y1Sii2KrhW4f7eHqG2ZZXxnw0fccYdAz1GJBt2+556E+F19YY0eSFBa5dJu2oCGe0X+B5/rwebX0draRnq5boc8PQH3dxiOTOWenUSiPL0K9ydRJwX+Gqn/IBo5HHk85sZAT6yCU0nXF827aydXPm0ENetBNC8R7XO4x/ZyNpT5PPtHnvgcGPPBIzokFyyAt5EYRxBFB4iDGS17Oh8pGnocTsrAEjz5miZOM6ak+e3dHXHxJzKFLamzfW6c+XUM3ImSkRuOVJ6MvcZaw3W/NfVzusAPDYCXl1FM9Hn2ozyMPZzx1NGdpxZIW14yQxQ5gBbUEpBDDbEUJJOvAGM+pRc/J05b7H8yZmx5w4YGIKy5NOHiozvS2GlEjRunCtW30SNp1nnvjdlZPp3zmIyeQ3qMUPHks48jxlPm5CBEVSlFfEOhhHmt0YXlc8emckj6fTgarTWUHa+dngVQEiIbAtcHLkWkTlWNdIri0Ph4hPBtdw6NHUtLc0ygWB152zSzPfek2aj4fRlveg8ktWTfj5JE+n7urx+fuSTmxYLHOk0SCmY4gisKBVioc5OoMhmqwYn3gWM5CZiDLPYuLjtMLKQ88lLH/rj5XXDngiqtb7LigTtxJUIka75Q+Q2Tmz+Q53m0SyQlsasg3MpaO9bnn8xvc+dk+Tzxl6HYdQoRm3VZTEBebxlV5Mcjxz1Smu0KOz2Ms5EaQpp6TS46TSykPPppz+cUZ11+TcuBgg3onQSUapQSsedrtBi94xU6WFwbc//lltIL1nuPxIxmHL7K0lBxe/GOF5tK7FFZoyIO8aUem29BucH4cSLscj6hJb+tejNJ0I3nLJkq3wn4vrxpOLZmgYbGefQfbvOjlO5hqABsBPM46zMDSXUl58IEut3+mx4OP5WS5p1YT1BNJHAUuEJWr3aUY7hiZVJiW4jvngjWyDowV5MaTZtAfeB54KOeJpyyPPJpz48sNF18JtekaKtHBEvlzhOFbic082NyRbeQceWiDj9y2yp13Dlhf80QRtJuCWkIogOriYpDjn6dU5lb/dFlAty7kEE1dkOWefgrLa47bPzvgyWOGFz7HcM2VDaa21fH1CK0NYmPAjm01XvSKnSyeHnDsyR7WwonTOf2eo90QhdUpAqEiChy6r2oKS3gEvh7Zfk35/PwAJJwlDKazSWnahn8oCAUK61NEYTgEIQHVG3h6vRBVdLbXeMHLd7F7bw3R64OxWOuwg5zVhZTPfK7LRz7V48SiJYlgZioUV2NdWB4dMtZKDvNcZySYfQVE3ong0kqVgoV6Ao0E+pmg2/fcedeAlTXLa3K48npBfUYgIlVRNrJJ9+omtbCCL3nrML2cY492ed97VrjzrgF46LRCFBTHhQSj0BuXn0WKiaT6RBku3ENS0IT+AjIDtTh8pl4fnjpuWLmtx9KS5UXP92zbXUc0YpTPkUJw8KIm1794OwsLR9jo56z3HIPMgVDD83fm3EaG9qeST42VzZLzBpB0BiAW3sdD0lwAZ/yaHG8hEZFE1WOiumYu0bzkG3Zx5bXTRCaHNPhbmzpWFzJuv2ODD32yx1rX0WoImnVBEkEcM7xSpfRIIYbaNXGWaFuWlRQ82oPXgsgKjPVEWqCj8Lq9HjzxWM773rtKq6O55BqN1HKcKPvzaGsuLyDj2FjJuP0j63z+rgFaBldVTwRJTHEhhBxYqQYuP4yYSEmJifymp+ia8h6rwuvkReQZRwFE3b7jI58ZkOVw84sF83skoaCRkzQ1192wjdOnDB/74El0opGNCLQMA1P8ZKvQmRP0wvdeSptqsYmubItEogOE8h45mY0f/U1/RvgqpGTXwRav/JY6cTPm8GUtWsqGRGFB+NNuzl139/jQJ3us90KOqFEPBzvWxcEWIITHOzCuUroQEyLBqmy1dC6ySLyJcMJE2X0kIBxajxCCp57IuOtzPfYfbhM12KTbYjJXJLasf504brj3CwPA02qEckKwpAzVlYE++aKG6SuK2pG8dfwv+uJjiaGLU1IgCisWRKECpWCj6/nk5wckieTmVsxMrJHSQzdjplXn5tftYXZ7k0QaZrZHhP2ZYyagcJsFr0VUorGh7kWeyf/Od7jCWKuRH96HHTTlz61jdkry4htaoBXSmBBxWVdccYLlZcdn7hmwum5pNwsxmfIhV+B8aNgUIJUkqinq7YRaK6Y5U6M5FSr/vtD2jjRSnv56Rn8tI9vISbsZ2SDD5R5XZLDxwZJFCpLIk6WO1Q1wUoezYf0WHRtbRV1F0jNWrGeC/sARKdDShwug4DEm80XCUxLFEUkzImnF1FsxjZkacUOPjuXwQhFk/Yzu0oDeWspgPSPrmZAeKGhE+VlcBLYu2Oh6Pn3PgIsuzpjdXgvv31hYHzDfqPHym2YhzVCDHr7nRtan+LvOn1mQDrxoE/XKOQEkBB5hfdC/TxArUeSBSgNQXE3e441F9lJUXtSoyq5IWZiGSJIJRT8vrAMhanJOIBJFfSqiM1dnZleTub0tZnY3mZqv05yKSZqaOJYjrlJGgUUaPs9g0A/EvLuUs7bQY+VEj9WTXdYX+nSXU7pdg/EO7T3b99e59PnbaMw2wqISJhIxm+aAqn1YwSLKKGL3xdMcvGKDJ+9bRcgg0pKRpNGJ6Mw3mNrVZGZXg5mdDTrzdZrTEbWWJk4ilCplIJWBWj7UC9Oeo7uWsb48YPXEgIUn11g4ss7qyR4bq1nIaFsf2txx9AeSvtNhaZ8twzmDWOuhRZEvSjOc3WwgVSXHV7Gwfpjekm4z3643d2AaL0TuEbnfLOAaZlsd3stQxihCB28suAxRXtnKF73aEULFbD/Q4fk3wp2fWSHrZUzPJ+w80Gb3oQ47DraZ3VGnM6VJajIUEY0Fk0Lah54dVY5LDTZhj2isI5ptxdy0hotqIKaDJqvv6K4YVk4NWDjeY+VEH6Fg9yVtLrmsTuQH0BPj1Xy/VRaacXWjA+EEew61+dYfvYQH71pj/WSfKJLM7q4zv7fJ7M4GrZmYWiKQslDFGwt2AP2NwJCrUtzCumopSZSiM6/ZtbMJV0xh8h2srRmWjvc58egaRx9a4fSRLgunBsQtz+Gr5rj4uu3IKAdThNxeh9B0qP2xY50afuw+crVlcjM8TTivEuPPl0SjNSAyh0wZszYT+q2xNzKqGQ57uYVlNU84YWfZpnrMSEtnus7LXrObQ9dup9e3zOxqMLejRrMhkMJBbqC3DivFgXZuvCN0ONa5rM/ZSvuOKiZOhDYZHUW0kpjWzogde9pc8pwO1oZslhIGNrqwYTap9m/S87UVmHKLUhkXXNhg/8W7yfLgqqNYICk+T7YByyZ8bdxQRD9sdaI6Q4kzJSNCgNboSDObxMxe1ODCi5p0X7yd5VMpp471kcDBgw2m4pylpZgnuvuZE6c5EC8N28yHgfqwgFomE/2EEKB47sgC5VbG2XgHylkAZESERwwsul+4QXGGJnv4fZGN9gwTUxKPx/JAdye32lexNPMC9nU/w+vW3sWcGtBsCi69KAkhivCQ9eB0BlleIcZuTH16Bp/1djy2dy6MEXYCjAjVapGDGFB26IlYoFWhrclssAbej8tkq1qisbBoi/4w76CfQWaRkaKmi27ZteL1S8CMdar6catTBY6blH8Uv5uVo2QGIAUyUrSTmPauiP27p8Ln76d0Fwa8r/8GHpl7LWLhfp6/8m5e3LqPpszD0I8y31O1OmcESKNylfMCL0Tf6PoAe54AWljP8cjevJPrTuC8R411tbhSZiGGIHLeIhFoUnKr+dDKFfyR+272X/pqXnTBPB++ezeHT72f2eYJhJfhoJdVcmfHW4KkHLUDi2reRY74whnaZDmh6qv0f7li3EomNmkaZJPsJON9ZmeTagxbk13oqiCrlOGrXSJVdaLYRC8tK3mZLfZ3lIC1PiSFusWSOSnBebzJObHa4s7oxbz68udwdOFK/sdnD3LfqT/ke2ZvZVb1QjWhGORQtvoMrU5FMlMFmPNqPdf13nlzoNh08YjUC7XqvHDOoYLlERN8yA8BJJxBK8N61uSdKy/mD9z3cNWVN/HGy5p0Ys97XY3FvIl3HnIXRhiWs4WG24crV2lZqKrqaUr+U034eT+h8RHBepViMiEmJK7uTBlHtWOjKsofm746OZ96s6ELE6L9sfKHH2+zHgNTpbcdeWZX62R/f7Wz1YY5QL5YDdEzMadMjRbwDfsSVu0N/NEdHY4en+bHZ9/LvuTEmfxnbOCZHzUYO3BeWCuilSye2pD+PPNA8y2FkzpjNV7yFus90QiRRVKxKuxXDuEs963t478tv44/12/mhVddw/dfXmO+Dsf68NSGJc0ErpdjS4FjLENFWaswrkX48QMoqtM2KpbljKzx5EADsUmnaQkiNTqpgs1lrV5sMXxhYkhDVVc05pY4c1zvWBS3ifjf+wkiPbmZaNzXeCdC8TYz+NwhvEBHDozlRGo42vXsawpes0/RM5fzB5/+ER4/tpOfmn4Xz2vdjxb5GR3QvloWGs5oEMYJtWyT1kANTp5nKaM9R/uR25zp7DrucpE752q+yCP5Yd4gFMkiHNZKblm7lv+89l3cnrySF126n5+4MmF7HXIHp/twbMPg05yVoxs8eQrqiWR2Puh2dCNIE1QsQserrKSdq1ZGTojmy08tNpnAUR1YdUZisCDcYyuTxNYF1M3qYa6qVpQTSdXJoU9iE0MlxwdgVl3uEDBybOZA6JgIGiObOrKNjO5qxsJChjGCg/s0Xk+z1Ms5sgF2PrzEGw9KVtP9/MFn3szDJ3fzw90/5zumb6Uj1rBeFYApa2IVK2QBL3IrooXXv/u/Zbfd9JLzA9DrfvZveO//+zqkM8esF7l3fji/0VmPtQIlPVoZltMWf9V9Kb+bfQ8Pt1/ACy6a52euStjXhnULUwqOrsPyICPvpvz959b58OcNsx3JRQciLt4Xs3tnzNRMRK0Vo+tBMKViFSQXqiDAYiKHMJzyUPn50O2VC3TlWQRgYsJdTbjBs6oN/ZmdF2dIWP0W4vwKIR/bJlTJ7JchtANnDC632NyGin8vp7+es7SQ89TRjIeezHj0aE5v4HnNC2rsf66hl+U8tl4EiS6sqf3uQ5LVbDt/fM/L+bcLe3mwv4t/MfXnHNAncF5i/Kht3vlq948YmLh57JMvvLSwjOeZifZe4pEnLSr1zlQIlkA5i/Keh3q7eUfvm/hT9WYWZi7j6r0dfvLymCvnYM2MGike60IvDyq8+x/KWFiHjYHj2KLhzgdSds4p9m7X7N0eMT+vmZqOaLY1STMiqmlUEgVJpy5GkMjQRSmGpWw/7uqqIvtJziDGai+VKExMAORsmmmxhVxoszG/nNlyXYJbiELyGs5e6E+3xahIh0lz8l7OoGfYWM9ZWco5eSrnyMmco6csJ5cd3YHDeUgz+Oz9Kc1DOa6W8/i6Y2AlkYS+hU4N/q9LFEtph7+Wl/L/XfxBHjm5hx9v/QkvTO4h8hbj5dCtjRQOYmB1/RjAt/z67ecPIFObQpnBESvjBWfTna7QjWlnMFZz+9oV/L75dj7Y+EbSuX0c3t7kJw7HPH+7oFdUkOs6NFc+uuYZ5J6B0ygJU41QVcYHieojRwyPHs2oJ4pOUzI3Jdk+q9g+HzE7o5ma1jTbmnozIqlpVCxHMlWtEDqcDCErhgk5wXHEJjJmf26uc9Zxd34LWetEJ0hhoULKg2GW2DuLM+FuU4tJLVnf0O85uusZK8sZi8uGk4uG04uWpRXHas+RZcHCRgo6jXARDTJPP7UcX1EM5hWPrxuW+prdLUg9dC3saMG/uDSia1u8T+7l75beyOMrO/lh/ad8S+2jdPwaxqshmXbOY4XecCI6sVU9Y0sAuShB294JI5Mnrdu4XDuvImdZzRv8/eDF/E/53dw78xLc3ByHZ+r82MUxr9gjMCK0d4dyPpwawOPrOf1cs+EaQzlCs91EtufBWWx3lay/QZYZTi3BiUW49zFJLUlp1gVTTcnslGRuWjM7pZme0jQ7imZL0WhqoroeaoVlpJDF/EZRjiuRlb6yIb0qc00FoZ+Qs272lajqEDZbmDPsYxsNt/Ru1H3hrC+IryVPLWk/p9+19LqGtVXDyqpledWwtGJZXrWsbjg2+o4sB+cdWngiDZ2mIKq3kPUW3qS4/nox79QzMArnJEt9y8keHGiHj2889B0cmoUfuyQitZ4Pqznujl7O2xd38NDKbr4n/lv2cRxRyEicE96K+GieTB952gASaQ+Zrvdy3XhIpIuvjJ1TT2bb+NP8dfx5/U0cn7sKpttcNVfnRw/FvHJ/yAAPCh9aLIThRB9O9Q3WC4yXxVQJaO2+kNlrX49UMf3Tj9FbfJxs+RjZ+gKmt0o+SMlzx/IKLCzDI0clWmbUIkGjLmk2BFMtydSUZKqtmO4oOu0ogKqlqTUUOpboSKIUYUClDGXssmI/DOCkHGuzF1v101dc01g2fphgLcJjG+YgWeMwmSPPLIOeC5ala1hbM6yuW1bWLCurlrWuY6Pr6KWeLPPYcjGc9ETS04whigW61iJqzZHM7aG+/WKimT30Fx5n45734ewS9ZqknkAkPaup5amu4wYkWkJadAJJAVfMw09cEqOF5BYJp9WV/MFih0e7e/h+8S6e4+5DeYuzMje68YiN6kvC26cHoG99+4f4+597jpWY+2Rf5HflF8b/S34bt059K+vb9kOrzuUzDd5yKOYVewU6hr4pitoiSE4EcKTr6GYOgUMKH8YTC0dndjuHn3MjtdY0vfVlNtaXWV8+xfrCk/RPPsFg6Qjp6klMdxnTXyPPMkwe8mf9VTi9EtyElGGeUKwFjZqkURd02pKplqTRVNRroZU6iQVaS3QUHpUO8ogglS3GyRVj5TZrwBhLshVT1pwFazzGhuKnMaFjJMsdaepJ0yCu2+g61ruObs/R6xdAyYNc1RWglNKjpSdWYeSk1qDimKjWIWrPk8zupbH9QlrbL6A5v49WZ55ae4qlp+7jwSOfob+6yFRHMtVR4Dx963hsw5FbiRYhvel8AJJUcNU2eAsaIep8ENjQB/j7pTdzZGUX35v+Ea8wH0PjBl3RuH/p3/5Vtuftr3j60zmIGm7VyDvvFM9f/uP4zc275l9JNjcHzQaXdOr834ciXrlXECcwsAyZvCwAZCw80fX0rUc4RxJ5anVgBdxgg0Q52q0GzZpi+/YdGHcJaTqgu7FBd2WRjaUTdJeP0V08QrZynHT1VABUuo4ddDGZwZgiCZxCry/wy6HpUYogGxUiAKXUVWsV5KVSjgbMCsL3So3LZqtBxxBAFVm0sz6oBa0vxP3he1fIal0RvbpKrVDgw4UkoB4FPY9UEGmJSuqopIVuzZFM7SCZ3UN9dh+tub20ZnfS6sxQqzfQWgaxfFwjbyTDlrqZtqbTUrh1R2YdR3qejQya9ZCstoVEdgDUFFy9PYDIUueDpwS5FNylb+Y3F7dzdGWGN/pb1r3Qd2//l1fxjb/4wacJoB9+F99+qq87Or04a0/p09uuwM3OIpoNLpmq88MHNd+wV5AkgaTlbjRqRxYbELoZHOl5MuvRzlJPBO22hmMZvcXTbCweozm3G2ctSkGsNfWkw+zMDGLffnJjSAd9ut0NuutrdFdO01tdpLd2knTlONnGEtnaEnl3CZt2MYMuedoLuhlTkEDvsQZMfiajGWsU8GfvTh4Vin2FM42+L1uChfeIwgkKEURlQf8c2o+U1ui4hq410UkT3Zgmas0Rteaozeyg1tlGY2o7zentNNod6vUmcZygVZhDYI3BWhOqjdaycfoIg/VlhICZ6YhmImDFYTwsDGAthU6jkDwVeXhTdEcnEq7cBj+CxlPnQ6clAyk4pq7hHf4tPLG6f32HHJz6fxa/D37oJPz+G84TQD/8R+BTvSo7b1przf6y37Z9O9MdRKPJ4ek6bzmkedW+QIZTH8yjLTqbyxlFEugaWMnAeoe2nlosmZmJkCqnv7bA6vFH2HbouuJqDzshvPdo79FaUa/HtBo15ubmhs8xuWGQpfR6XQb9Ht21Zfrry6TddfrrC6Trp8m7q+S9NUxvhby/hsv62GyAM2m451mIgsqkGVV1QZmy8RPBuxiK4kpEBQVkEf0JgVQKGSVInSCjBBXVUFENXe+gm1PopE3c6BC3Z6l1tpE0OtSaHeqtaWqNFvVGnThKiJIIpRR4jzMWYwzW5DhnsNbinENKhUl7rB65n7y7TBwrts1HRDrU/pxzrBtPNw/npJrYsJU5QHEE1+6EH1UKJWrcekrQd54lfzF/raZ2u6XV7yY5fhxdO833/y94x/edHUDih/4QBj3pW9PfylT7l/38zMVMt1HNNlfONPjBQ5Kb90KcQB/Ixfgbwo7KW90M1nKPtaFdItKendtiavWUdLDC0hP3kl+/QVxvFC22ocjnhMA4EYY0CBekm1IRaUW9VmNaT4WWZR+iE2MsxlrSNGUwGJBmA7J+n353nUG/Szbokfc3yAcb5P11zGADm/VxWYo1GdZmeGvwxa4OZwze2lGLnVTBqiiNkLqYHK9BRuiohopryChCRXWiepuo1kLXWsS1JnFSI641qDVbxHGdWi0mqdWI4wQpFVoppBTDNnFrHdYajDVYY7HGYIzBWTuu7hOS3uoCy0cewGQ5nemEHdsT1oUf7t9YMY7lQuAwbB2S4FVx3oqMQizh8m3wFiSxrPH+E4IughzXwfsfYikdiP7ybxLHa/6sFuiH/jfRhS/GPPWpF/rW1P+LmblLRWca1Whz2XSDH7pQ8rK9YXfZBsOVIEMTL4tSkyxqo6sZLOVuKEEVOLZv03TampM9w8qRB1hfOMLc/sN4b4IVkgJRTHYVQiBUmEHkKoMbrHMoLVFSIoWmXo9RKnwvKjIM6xzGhk4Q58LJyHNLnhvyLMNaU5wsi3PFSSruvpRYVETwUkqkVEipg7VROrgkqVBR0OtoHRFrhdYKITVKhmFcSqihCtkVOSFrLbYAv7UBtNY5rHO4QiZTNv2VF9dQs+w9K8ceYuP046F+ORszPatZG7ghUevmjoVB0XRQJOmdGK3QA8h9EClEEi6eh+/3AuMSbjkBfWfx1sxi8x/CmyNyY/kP/Fv+2Lj/+l2bA0jVGtgjnzxIY+onxfTMc+hMIetNDrQafNd+yQ07Q1dA1xUDR4o3Vbot5YtSZXECl3JYy0fDjJw1tKYVO+YTTp8a0F14nIXH7mJ690XDmo/3MgBJCKQQOBGmVHjph1epd6GX3iLwwuBzi7WyOMECKcKjUoo40kWUJYvKx0Rra6XbxFddWLX8UCQdBWK8O6RSDSmHQpS/57wvSLSbuHvscLCBL8BiQ+KurEn58HsB+KFGVdUvCykxaY+Fhz9LunYSFUl27apRa0tcNx9OYB0Yz0LqMS6kWDwhSjYTM9YoqIcG9k3Ddx4QrGYJn7QtjDW4PN+NyX8cwWOuc8EHoh/7E/L/8p3jAGr8zN+gvW30Rf27XHvqG31nWutGi3a9ycu3K547D6mAtFiFUSZ6y9mMqghvVXGOjIelzJOWUp+i66+WePbvTXjoUUXWX+fEfZ9g9xU30pzZTlkycc4hCvCEDPNICyN8ENWXu1q8VCNttnNBKSCDztp7cMIG91O+lhjlgERROxMVVIhKG9GZy3oZ74kbyj79mADdl73mw9B/BKhqI58bAilYGlf+3nDsy+jnjpHwXQjF2sknWXj0Trx1NDsx+/fXSHSoxpdgS51nIfNkJkxetT6cF1PQjuF4hXJdrQPtYG8HXr1TcKRX46htYdoG8uwq6d0PJN0nH/C11lN5VXsw+9bb2L1zVohm5ybdmfpu0e60Vb1BFDc41Iq4fhasglUbZMl9F1h8mZzKbNE9WYSJ3ofvlzNIizk4wnukNcTCsn9fzMxsjBCw8tjnOPXgp4ptPCqYbje6CkemvBA3ueKAeju6qn15oIsBDK68ct1oQc6YfqkIr4vnjayDHfKPklcZa8PXxgZeYk3xvMrvVoBSnfMzpptyFQtaZKgDoFwBJkYc0I3ANPYevQvHyFuO3/dxeqcfQUrBzh019uyJ0d6GDsSiEppbz3IWUizDfvviXGU26N9SF2plfRfO7bqFDQ+HOnDVtKKWNNC1BrLdEbo99RrdmfmWmbl2Mv/vPjSyQLVmjYFwu+N2+zt9VL/MNdqopEEjTrigKahpWHMjLVaZ9S+3PanKDhElwBTLelZST14IupW3RC5D5pZt85q9u2ssLWaY/hKPfOzPaW3bx85Lr0cmKhBYZ7HOhtbhsZqkLCxR4eqKmM/jUEWpwkEYNAUIwgg+IcQww+zLr87QcYvzGxo1LGX4sW7SkVx0ZJWGwGASPOXXIzflJ92dDa5NSIFWCUKF1ZDH77+DY3d9EGxKUtMcOthkuiNhkCNtjvYmjMpxltXM0zfBsuSm4DyV4Gc40rO6RsOGf9tbh6lE40wDYw3a+9nExN8myD8UefWFvb/9cfRF73ic6Z27xOKTj1/vnXyFUQlRXCOK67RjRSuCXtEUWDbqlUJCW35dqCzLDlEjwpK95cyRFyYpchmxTfGpodV2XHSoxiOP9ej3POtH7+az7/qP7L76G9h+yXOY3rmfxtQsUdwMYHV2eLUGEy4DLygoaZgfLkG6MD3WB4lnuXWhXAPhhR9NcR9qjUpIiE16b6tqjfH09Igv+fEJO+UEsqG7cxXLU/apVXlP+b0bWjOEQEUxSic458iyAd3VJVZPHmHpyfs4dtc/MFh8GKUks7MJF16YkEiLzwzSZMQuRRRkfDlzbKSKehwk55mHTBb7FotOorIdvFQhlurcSEEnFvSyBBnXkHgiGz0/ku7mOJIPW+sHWkaK9cUTU6rReqnyepf2IZceR5paFKzJkoOOhaTS9FBuuZQ+7CxzZYdNoWnvDmAh9WTFO4psSs33MbkjtoYLDsTs31vjoYctjdiRLtzDA//wOA99ZJrWtv3M7j3MtoNXMLf/EqZ37KHe7qB02AMh/KgxzjlXZJLLSC0ASQiP9MWEstDnFial2/DmywERUshNesLEeIF9k7yQL7YpDnvT/GSvfmF1SheEG1oZa92QMwkRXHekg/icPGPQ7bKxfJq1U0dZOvIYi0ceZvnYQ/QWj8BglVhtEMcC5yUHL2ywY4eGPMVnDu1y6q5XpsJZyRwrA5iuFVNLfLA+eekpXGWlcDHHM7OwbqBHSIRGWkKUIIRHEde0MDcLYf9caXFEqyhGCD8L+rnSRUgHWkZEKvReLTo4lYHV0JSQABEj1yV9sEBRoeHSMgBoqQ8n+6FPTFhLw27QcD1M7pADy2wn5vLLGhw/npLlhqmOwpoBWXaE/pFjPP74Z3n84zVqne1M7bmI+QsOM7f3EqZ3X0Bn207qzSmiqFi8NtEA6Crye1mpIhcDiMOW4gIoTrrqUslNCqliovpeGUJQ6Sen2rlb/lek5oUUSHTQjymBisE5S57npL0u3ZVFVhdOsHTsCZaOPMrSscdZO/kY/ZWT2H4XQUakc2qJI2kptJZkmWd2Juayww0akcWt5hjjqdkBc34ZYQzeGlZSw/F+zO6mwJjgvkoQORWuN1e4stwGvtTLYTmHkzaALFYSrzQOXZSG1HVK2IO12ZNHdDS/LNzazr3ey4uxMtRqpEQVUzoXLSQZGA0zEhoeEhekGppiY2JR/4FQwsg8PLHhONU3xZgMw7xbpOV75EYgM4u2hgsPxjx0oMZDD22gpaDREnii0BJsDGm2RjpYZeG+RzlxzweRUY2kPU9r/gAzOw8wtesAUzv3MzW/k9b0PPXWNFG9SaRrqEgjCxclhChajcankInK0CxRGa50JobEmCsTw/VjokgDjGuwg2Y8cBhrLCZLGfQ36K2t0l1eYH3hBMunjrB8/ClWThxhY+kI3ZUTZBur4CxaWqLY0Yg9yYwkiiWx1qhCzp1lDqUkF1/aYu8eDWmKNY7MCmp+wHZ3GpFnYC2LA8NDa47L2grjCw7kIVfFFBNZrAQuyhs9E4KfUymcNuHfwmwBCRSbKrXaJYQ5nK1vu0PTn1NCqZ3CqSlR+KHqkp2BhRM5pIOQeZ6OgiWqSYgLaxSVFqjQAC1n8Jlly6k0B2sQWcZ+d4S275Fbicodpm+Y7kRcfWWTkydS0n4eBpBHMiS9vMc4GaaPWY/JLXm+TtpfZ+2Rx1l6UOClRMZ14uYM9dY2mjM7ac/voj23i/b8ThpTc9RaUySNFvVGkzhpoOI6OgpTvaSSRX5Ijnf5TI67q4xC8c5hfeAX3lqsyckHGXnaJx30GHQ36K0v011eYGNlifWVBdYXT7CxeJre6gKD9dOk3RVcHsaVaenRsacew9QsRJEM00SUKgq/hASpCC4uyz3GwLZtCVdd2aCmHG7dhDGBxqOdYY87jsi6YDqs54bPruQ8Z0rSiAWpD6MVMgu5DJYoJXCerguWZyENj31bSKYq02MDCVaRkOyRgkgLqRVSdYTVsbCmaIcqQlMbEnZpDouEUG8lghkFbQl1ATUPsQ+uzRRJtQe7nk8u5aRZDsai0nUOuKeIMRgbhyFQmUWlORdeUOPwZS0+99kVMhNWGpUDmOKyduNEEcrKguQFKYQ1AVTZYI3++hOsPwXHfCDZIkqQUQMdN9FJi7jWIqm3iJtTxM02UVJHx0XAEMVIpZFKh7KFGOmaS0viTNjpavKMLE3J0gF5v0/aXyftbpD1e+SDDbLeGnm2jk17WBuSekHeEkbMJBG02hDFYT2BLva2K1kOnioGalXUBOXAqSyHLPMorbjy6ja7tyv8xgBrHNaG9QQ4xyGepJUtsJJthyTnC6s5n1iMuG5K0ZehGp8CqQy5vZ4PUfaKDVLkvgnrSYYbyQvuhvfFEmCFVDSl9FILGViMRCKFRHiH9QZrI4xRqHxEjDd8QOWygJaADtAC6kCN4NqOZPDJVcPj/RxsEPB00hMc5hGEs8U+qjAv2vZykmnNtde2OX4i5fjRHpH2o3WP5U47RdH3VFnb5cB7VXLF4Ug463wx6m6AMX1MvohLob8M3VJ24ca7w4QY7XEQY+6oOjfHjdp93biUWsjCzBdykXos0A1QWiClHo20q4xlCbOPGMpHpBTVRUhjf94VGwuz3JFlnosPN7nyihYyz0KHhiu1SWCc4AJxlAP546ykF0MjYjHLuWXBYI1kuibIS+AU53SN8JiVx9aGKNrmQcVgjMc5g/IOSRQsoiouDGRmJckKiEwpFUsh8NaEqalFaUAUDF0qMCogeNXDSR8sUNNDPQyC4NjAcn8vI8tzpLX4zHGJeYSLOBLyOYUIqxRgyW7OtukGz3veNB9czen181DXEmEWThntVdutVJkVnlgJGnrWqmP4SomJGP7M+2KRyET3ZXU6l9iEB4mhxloMLVSZOyonjnkxAkh1+pisrCYb7RsRY7tHxFlWkBkbZj72+o65bXWe/8IZ2jWHW8lCQtOW8yGD29/BKte4+7grvxFhErCGh3sZuZccqGviSJBJ6BKAZGVlJUnBZ00erFCeh9223uXhQlESqaSTUiyAN3rbJfN26bH8mHDitHaypbUitxZnM/JMIojwRYpbKobCdedho8gZCBcqq6l1LGc5gzxHOwvWo02XG/ydbJPrWCRyaCEKEKWGqJdy0YUJK8+b5vaPLtHvhwp8te1q01mYYnxh8xlzrJncwiSGYBrbR7eJhN5z/ruchZjocZyYPrblHM9zzEErJ9AaA72+I6lH3PCiWfbs0PjVLta4cYtuQ79eXaRcz928xyywbKdQzmJtzpOpZNlLGrqYM124zUhWxiaHnXehrT+HPDdYkyK9Q6soDHSP6EkpH/LWpXrlKZBaH/dePBAhDkZZRJYbcpNjjCh0OBprgyBKFqvASmGSdUFMljlHanKMzYi8RXuwRBz0R7iBz6HJcAUYS/AIG4Ttop8RRZJrrm6zuma5+3PLyNSNyG316t1qTsYmYw3Pe93XFrM4zhdAsPlyoGd6Ky2qtcWwkr7DIbn++XNcemkDsdHHDvLhVNryeLpS24TjGv8w1/EAH5WXEgHGO6wzdPOU3MXEShFJgS4WSw6bjgoAOesxxmBshncGrQRxHBEnChXxiBDqIVmbsjo0QYoFqbldC14d17TIcx1CUJtjcFgXo6xGqtA16sWob8h6j/EG44KeJnKWCNBKgza8yH+Wi/wR3LAH0OMLwicdCOvJc4dYz2hMSV5wwwyDvuOh+1bCeBQhh8uhz3WixJfgZIunCZwv9W3EeYpVYQNHbuDq58xy7XVTJNkA08sK0jy6D+WzgBOKHSxws/0YD6hX0VOzRMKSOlvUCx3GahAKJxWymHhW7vJwzuKswdsc7y1KeOIoJk4iogSk4qPeiWPOFrWwuE7X5rxfRfyzpCGvcSbBWUeWFT7WOZxTIatUjFQpJ8xYb7HehrYTPJEQJErjVcLBwZ28YvAPtP0qTqlycXP4sIXpDYt3PHlmEGsp01OKF79oljxzPPHIerBQNRm4j9rcEn0pbl9N0AwTnW7EeUq3NcjgsitmecELp2mRYdcHWGOHncLDwrBh2E7kpECJnBelH+PT+R18fOoNCJ8jvSFzDmszcmFwQqKEQiALilnWM8L+DOEdWkCsI2r1hFpTomMe856/PvYAi7suBnXsf76N3T/4VpxjWUW0VMwLpZSRtyHP7YeV7lDctM4E8ZXLsS7ILPEO6T2JFNSVRsUN2vT51lP/jZct/y2KHF8o76Qq+t9VkaGVo/Ya7xzSelqdiLmdDVZWDYsLaSGIqhBT/+UB0Vfz5ivgyQ0MBo40g4sOT3PjTfPMxBa7GhoJbHUZc8l/chfuxg8VCG2zQp2UR6evZ6O2k2i4HDAUuINawRQyGoOzOd7mCG/C1mwpiKOIerNGcyoibpILyX93lnd2tjPw5aiKvT/8VmREjuOY0OzRMZcpLSVOF6VahxhuT/DDNyDwKDyRFCRaUdcxUVIjUY6bFt7JG4/+Lh2zgFW60A4LhCpAU7hDIUeDkj3F/lTnaE/HzO1qsLpuWVzI8M6HvRCMLzH8egdSdSpGyXn6fUtmBBdfNsNLb5xnrh7Ak2cmWG9f6fgo24pyF8LtYn2UQyC8Z2d6BCk9j01dR5pMExXuShVgCk0AHundsFtES0GkNbUoptGq0ZyOSFrCCPg7b/lPQnIE4I4XFItUjv7+29jzg29Fapad4WGl2aZr4oBKZCyFQqKCyk8IlJRoJVFKEmtFoiOSKKae1IiShLpIeeGpv+DNj/8GewaPYIqsWNkhGibRBSCVUziGYq+iluSMRzlHZzphfneTjZ5j4VSKta6QrcJY5UF8nYOn1OmYEKobLzl85SwvKcGz0iVPK5bH+2Iqf6UfLffDqKzcgeMQRDZjb/chlHCc7FxEWpsjVhGRCuujIqWIpCJSkkhpYh2RxDG1ekKjU6Mxq0maYkMI3mNzfm1qH5/vLwXwbOr6X3CHx8MhlfB9QvJGbzmc9b3K+548LUxkMeRYFNJRryReCafJj93wxLvX3vSFX7zoQPZwbBM5BM/QXUWhXKETWezDEkHfHMnRMhUp0FIS12PUTJPFvuSTn1jigXuWwVoadRk6NYcZ268vEFWHxBf9BqRZAI9ONFc+Z47nXD/NtMqxKz1MmmNsOS1sxB+tdZg8dL+aLLRMm3TUGVuK57S19JjiY9vfaP/m8M8sHJm6vI0XDZxD2JFkVgiB1BAlkqgu0Qm50tzrLX9hBvyhEDzyieePH+gztjYf+e9vY+8PvnXZGz4jJHdLTVfHIolqohU3ZJzUFFFNkdQUsiYRibQ1PXiqyer7ZsTa7/7I/T/1nvlT9+9LnbxAKV/ISCuup7REQ1msGFstIMoEnQ/7tkRuaTUVOw+00UnEwukwrncoTf0yhtNfbqtTRlqD1NHte9rTNZ734u085/op2i7DLHcxqSlUlqUic5RDsyZY62B9SvdVDAyv1LCsF4h+ys61Bz+V1ad+89jOy++uqVTrRLV8Pa7JhhT1hqLelCQtSdwUq1HCXULwLp/zOybl3cDJT94gnl7w8fyPeSEks6rGYSF5HnC9d+z0Dp15enWzvNzMVx6LrP3kdd2P3/n2137PkcX3PV8/cMtT32xX13+9Rv/SqBa2Clb5j9QCFUtkJFGRQEcKpWWRZ5JFJ0NpXSRRrImmGmRJjYcfH/CZTy5y6tgGsfbU6zLUz9SZ+ye+FoFTdVnGePp9h/WS3Re0ee7zZjmwN0b3+5i1PqYYLF5ynhIcw/DduBF5zoIbc9bhTEiVhHVgDpPCwCWPyVj/3J7Z9C8Wrrgx+v2Zn734dLzj2r6KL3VK71iNdnVy1RCR4DjwOe+4y2Y85B2rd7xIPPPo9Yq/8Tz4Ibj6m4h1jTmhaANyXZJfs/HJ/s8c+4W15yx+oEuCRyH4AfyT/+NQ7al71r7Pb6z/Ul2nu3VS7JlXlccouC0VhZWVAUChV13JoouiLC4KQaQVUbuGbzU4tea587MrPHjvMiY11OphOZuuAO9rBUhjwCmIsrVhiEJ/4Kk1Yy67eparrplivulhrYfpDsjLUN2POI8r8j3WepxxgfuUEVixOtNbP5oEYsFmjoGpnbJx69dqU+r3n/+rx7v+lyVrV+2i0V2Xx/W+5gc7b2780fz/lRyP9tPO6eJYQWA/8aJzH7wv+vD6Pxg1Ngyz99//H93n/8PvdBaPmJ/QveWfrsfpvI4lUocTLIpQXuoRkHTlZ2rYCizLCb0hclCSqJ6gphp0Rcwjj/b5/GcXOXV0AyU99Zos1kNVVil9Fcj25PJlN7Q6HpOHEN1Lwe79Ha5+zhwX7K9RMwPceh/Tz0OfWjGP0rlKkrAU8luC9SnJc+5wedjL6q3HG1+sWXCkebySR63/Up+p/9Z//p2rFv/o//P3cijoNoVE6oe+Cvkz//vDzrIz9+cIAd/r3d3//sDcwpH0Z6P+0o80knxKhTpKyAGV+SAtUFqhCzCVuaKhJSoXzRUTyZSSxHGEbtVwrSZLXc+9X1jjwXuWWVsZhF0YSblaaRxIUn75uFK1POIqFfugDijmjWcO6wQz8w0OXz3DpYfbTCcOsdHDbAzOcFnOjwY9OVt0nAxrX8H6uLxc2usL11UUV3PPIFMbRjf/T3su+rVr/93pI/wfZGU96hkfQXz/VzgB69+x5esEVnwF7v5bdu048ZT9ed1f+b56Yjo6lshyfaUSBYDkyCKpYHmUEsNFc6IAgizm+khZuLRajGw3sPUaJxYs931hhccfWmVjbYCUnjgSBT8Sw4YAcR7ubaufb7V0ZLN1ENYF4ZcxntyEkLozXePQ4Skuu3ya+WmB7PWD1UlzjAkarCFovB9LFg4B5AribEbbnl2xsNcXRNrmjkGmekY33tmZVm+/5leXH62AZ7M+k2CJvtIAqoBIbPq6AmGJ/MPHZ3Yde8r/fDRY/e56kk+V7kwVABqCZwxERStxASQhZcWajERnWmuieg05VcfomJMLhocfWueJR9dYWwppfyV9seVZjK2aFJNSCnHuA3KGpaluTSxOtrF+OHZGacX0fJ39h6a46KImO+cUMs9wqz1sxV25YvxdqWvaDEChW7UAS+4LFWJBmofg8Qwy2bWq/hftafnvrrlm9WHSYrbC5uB5xtbnywmg0ekQXmQ+9o8cm9l54qj7N1G69r31KJsdciItUFGwOkKDKMh06cZEMQSq5ESikvcJOpyQM9KRRjWCRfI6ZmHdceSpHk8+vsHpkz36GxnOhG4NXQyTGlo4UXF1mx0dvxUpDlbB27DXrEz0Ka1otBK27Wyw94IWe/c3mG9LRJbi1nrYfhbGtLhR35hzk8Or/JD/DEnxUArjAmCywnXZYJVM7kiNXjOq8e7OFL9+xaHVR4QUQik/1sL2pQLPlxJAZwFRQbB3CfeFT+3evnA8/wk1WPvBmk53RrFERgWICjBJHaI0VZQ6qpZIqlHtrHRnYujWgnZYaYWuxah2DZKEnpEsLBtOnexz4niPpVMD+t2cPLVY44YFxDFgbtL/Xh0u5YauIOS0lJZEiabRipiZrbFjd4Mdu+rMT2vq2sEgxW30MYNsWAh1Ze9YuXHAj3I91XDdORcqRwVwnK2M0MvD1mtnHHkGqYkWbdz4406H37rgQPeJls6kjisLmM8E0BcFni9ZEfocXGgUpX0v7rO/vneme6L//fS7PxGJ7IIkIURipSXSo3BfyurXhQsbSkMr2W1Z7XcHJUKpRSca1aghGzE+iukZwdqGY2M9Z20tZ20to7uRM+gaBj1DmgVQDTVLxcgZKWSYCqZDuiGpKeJEUW9EtNqazlRCpx3RmtK065K6dkiT43oprpeGAqh1w8EJQ1murwCntEZ2PN/jh8R5NKjTm5JEh3HAWQqZi5+ycfN/tKfE719+4cpxYaxMan6TUbJfPO/5sqgYzsMSBRh9L/Zzb93d6q1mb8y76b+KXf/qWs2KMkIbcaDCIsmyblaE9Kqo5JdzDQsAqTLDTRVMAiWKPFMcIZMYVQvLU71U5EgyF2pQWQ5Z6sgzN6ox2dAMqKQMQqqCRyW1MGsxloJIeWLCqgdyg0tz7CDDpjnOuuDi8OO9+VXw+Iqrqko0SrDYURTmrQtirwI8JnMMUokR8b0yqf12e1r//6655NRquiFkXPdOnAM8X1MAelqWaAfurrsPJ/1Tyy9N1/s/LbP+K2qJSaJEDBOKpTuTJU9RctwyCTGSZRaRWVmYFSWQZKFmFkWdRxS5JSWRWiG1LlIJ5UR8NTYS2A+F9mcsqA8DsYooyBsTZj1XxrGMgYbJ4Q5UhkX40aAFNx62U5H+DqOsQrqaDxz9TGc2anw4atR+qzalb7n+4NG8v46sNXBCjgXrX3LL82XTUZ0PiDwgInxW3yO+8Nns8Pqq/xHf3fiemk5n4loRdkejrLWqWqJJEBU8aVgbq7ozKYbi9VEysdr9UB33UoJQDIE3tuzFj4YmOOfHhicwvpytINu+EIn5YaszFfI9BFFpXcrw3ZaPpctimHl2pthRn0E/T5apN/6sMy1/r71nx72H9Bf8wAiZJN4pvSV4/lEAqIxmwnncn7hPf3h+2vTyb9tYHvxozXUP12ou0pFEalCF+EwVVkmUyUU5wYGGScNSOjIOEikqxdoJlXu1lUds8ebP0Ov7SvdHNcQvQVb8IMgqJlZqu8qMIFfyntHImRFp9mNRVp570oEwqWg8XJ+u/T+NKf1n1zx3adEcTYX3AqW9l2JLt/UldV1fCQCd7fXD0Awfeo9FC/uFR/bGpp8/d+m0/THRX//GWpRPxTFC66o7ExUgMRKpleAprZKgYokq7TMVQA0HZopqJ2o1mTjR1zP5ZakhHtuzPs51xvrmJ62OHwHHD2cVMQrZy7yOAWMcJsP382jF1xofnNmmf9fr+OPXXX3UuMUw00vKsd0LW2yY+dKC58smBT5PEMnyqhVCCKRnLW35pxZacytL7tsGK/3viezgqiSy9Sguw/wif6NLK1SRxVYtUQmSqgy2VDOWPxuzQAynl23+zsUZaeixdqEqSPzE0IUx4Iw/DnM8FeLsi7650BXhyTNPlst+Jhr312fq/3t+m3vnTDs9ua25hndC4MNlWHlbXzHwfNkAdJ6JxgmPIcLYVY3JZEff93Dr6sUT+T9n0P2mmOxAFLkoihjJPiogGnIiOa6zHlogNW6BqD4OtzBV5gZt/klGVqrSuDhZPA3988VzyjYbN259RpodP2517EjjnGeezMg899FRksbfze5M/s/uPfYz25KTFisU5eRNzg88X2rgfMUAdO5s9UTSESGQ3v/ee19vXv/yT7WffNzc2Fvqf7vIs5cp8j2RdioqJCBlhKY0FW40qpeV5YpyzqIc/gUx4siTlqfKizY5F766BbMEU9VlVQE04bbKUsXQ2hRZbOt8IMjGFcBR1hIdczr5cGOm/q7t++UtF/6Lo+v8H6GL0R+buauvOHi+0gA6L3JNtee0gbv9/Ze4+cu7O04eyV+ad/tvECZ/kXT5/lg5GcWgK9nrYcFVFW5MVlzWZm6tAh5ffl8OkxJii1PiGfqMMa5z5tfDDYBjloeh26p2lWaZJzPaOREd8Tq6XTcbfzV/QXzb5T/xxAn+O4IEXbwfd7a8zlcKOF9RAJ1nsnEyCBo9J8aK7/L+8//hgj3LJ/rP9engdSa1NwqTXxQro+LYo3WopalhWD8CVWlphkSbkSUS1f1xZ8x4mTglYtzqjL4ux+X6zfM9rspzwqO1HpMXCUwbeXT0sNTRh0Utee/0rvod1/ybU0f5rz1PPTRQMDGZ9ysZaX3NAOiZW6Mw34FrcMsP7WThqNx24oi93OfZK0xqb7JZfo32WTuJHCVPEpUsdbXcUW7jqbqvao5oMpzf9MxUONAZa5+GstVKXatwV7Zsw8k9qZEY4nUZR1+Iauo2oaMPdnbUv7DnNaun546seE4j8WMbCs4FnK+o5fmqAehpRGqb8KPi/7M4mrv9w/fq1qmj2V6RZ8/LUn9T2rcvIM8OxiKLI+2F1gipZdACVQAkKpZojAeJcojS2d546b3EROjO2ArtskAatnI7jMHnRvrMRxlR/ERSV59IauI2p+I7tu9OjhzYn69HrWOCo4Vu5+z85qtqdb4mAPQM3NqZJZEGnm9Q7uR7t0dP3iea3uYHse65vR4vSnvmWp9nByKR1yPptNZeSiWErIjTIKgjZaVr5JxHZSzbzDjXGa548liLN1Y4Y6UxPkqJoifiur6z0eDjItKf1rF8dPchub7zjYs570klvXJW3lnzOV8zwPmaAdAzsEZnJowl0MYRT/PEw7FeWBS1RNs9aS6u6PX8Nf2uu9Jl+cVYs01jalK4WAmvZbFeY8STKiKzUUaxIM7joGFs+RxYh3VO5NbJ3KIHXkWnZRI9XG+ILzQbfD6KuNs4cXR6WvT3XmxNlC/CepgfsQkg/Dlc1VfFXX3NAmgTED0zIBUCNiRuYOr+9GpNbPSEijWt1Oq9NrMHVzf0BYOBP+izfG+eu53C2TmJbQjvIoHXAqeFKGaoizPWpLowlEaYcJe5R/W9lIs6kidEHB+Na+qxTtM8liTysUSbo3nu1loNZ2enMl/XfXCo4eIxf35h+Nea1fmaBNAzraltDaYyvewdoVU8tFE2IV1rRt2Bbi71mjMmt9tclk+v9ZP2xiDu4GxLONMQ3te89xF4iRAOQQ4y9UL1UHq9VcvXO410XWq1rGN1eq7RXW7UTS+Z7mWsFcG2H9pHWWSzz8fCTGaavqYsztcNgJ4hRzo7b4JyOU+wA1PAS/BEIFpjWWXBk0hWEGRCkHjPPJ5dARaVNFAYMPhhBCtQwFSO1iBuChR/bop+5vO+1oDzdQOgp8GTzvV5NqfI4oyTXTqWzfYejOep/HkR3PMFzNe0pfm6B9BZuNIzBdTT4VrnOunnAxRxvmD6egHP1yWAvghATVqaL9dn92zaz3Fu0H09AWf4nou0mf/HMvBrgjM9HbCILwIwz/g5X4+gqd40sBc4cp4H4usKS2c5geIZAoF/ymDZ7Pb/B7puTXLBapRVAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE5LTA5LTA2VDA4OjM5OjA4KzAwOjAwVds59wAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxOS0wOS0wNlQwODozOTowOCswMDowMCSGgUsAAAAASUVORK5CYII='); + background-repeat: no-repeat; + background-position: center; + background-size: contain; + margin: 0 auto; +} + +.svg-search { + display: block; + width: 64px; + height: 64px; + background-image: url('data:image/svg+xml;base64,PHN2ZyBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB3aWR0aD0iMTI4IiBoZWlnaHQ9IjEyOCI+PGRlZnM+PHN0eWxlLz48L2RlZnM+PHBhdGggZD0iTTg4My42MjY2NjcgODIzLjA0TDczOC41NiA2NzguNGEzMzcuOTIgMzM3LjkyIDAgMDA3Mi4xMDY2NjctMjA5LjA2NjY2NyAzNDEuMzMzMzMzIDM0MS4zMzMzMzMgMCAxMC0zNDEuMzMzMzM0IDM0MS4zMzMzMzRBMzM3LjkyIDMzNy45MiAwIDAwNjc4LjQgNzM4LjU2bDE0NC42NCAxNDUuMDY2NjY3YTQyLjY2NjY2NyA0Mi42NjY2NjcgMCAwMDYwLjU4NjY2NyAwIDQyLjY2NjY2NyA0Mi42NjY2NjcgMCAwMDAtNjAuNTg2NjY3ek0yMTMuMzMzMzMzIDQ2OS4zMzMzMzNhMjU2IDI1NiAwIDExMjU2IDI1NiAyNTYgMjU2IDAgMDEtMjU2LTI1NnoiIGZpbGw9IiMyODMxNDkiLz48L3N2Zz4='); + background-repeat: no-repeat; + background-position: center; + background-size: contain; +} + +/*-------------------------------------------------------------- + fixed widget style +--------------------------------------------------------------*/ + +.site-fixed-widget { + position: fixed; + right: 20px; + display: block; + bottom: 0; + -webkit-transform: translateY(-50%); + -ms-transform: translateY(-50%); + transform: translateY(-50%); + z-index: 9999; +} + +.site-fixed-widget li { + margin: 0 0 1rem; +} + +.site-fixed-widget li .menu-toggler .icon-menu-outline { + display: block; +} + +.site-fixed-widget li .menu-toggler .icon-close-outline { + display: none; +} + +.site-fixed-widget li .menu-toggler.active .icon-menu-outline { + display: none; +} + +.site-fixed-widget li .menu-toggler.active { + color: #fff; + background-color: #283149; + border-color: #283149; +} + +.site-fixed-widget li .menu-toggler.active .icon-close-outline { + display: block; +} + +.site-fixed-widget li.fixed-gotop { + margin: 0; +} + +.site-fixed-widget li.fixed-gotop { + display: none; +} + +.site-fixed-widget li.fixed-gotop.current { + display: block; +} + +@media (min-width: 992px) { + .site-fixed-widget li.fixed-menu { + display: none; + } +} + +@media (max-width: 767.98px) { + .site-fixed-widget li.fixed-menu { + display: none; + } +} + +/*-------------------------------------------------------------- + list bookmarks style +--------------------------------------------------------------*/ + +.list-bookmarks { + margin: 2rem 0 0; +} + +.list-bookmarks .list-gogogo { + position: absolute; + left: 0; + top: 0; + width: 100%; + height: 100%; + z-index: 1; +} + +.list-bookmarks .list-grouped .list-content { + padding: 0.75rem 1rem 1rem; +} + +.list-bookmarks .list-favicon { + background-size: cover; + display: inline-block; + margin-left: 8px; + width: 12px; + height: 12px; +} + +@media (max-width: 767.98px) { + .list-bookmarks { + margin: 2.5rem 0 0; + } +} + +/* Quotes ------------------------------------ */ + +blockquote { + border-color: #008c95; + border-style: solid; + /*rtl:ignore*/ + border-width: 0 0 0 4px; + margin: 1.75rem 0; + /*rtl:ignore*/ + padding: 1rem 2rem 1rem 2rem; +} + +cite { + font-size: 0.875rem; + font-style: normal; + font-weight: 600; + line-height: 1.25; +} + +blockquote cite { + display: block; + margin: 2rem 0 0 0; +} + +blockquote p:last-child { + margin: 0; +} + +.aplayer { + max-width: 350px; + margin: 0 0 1.25rem; +} diff --git a/src/asserts/styles/iconfont/iconfont.css b/src/asserts/styles/iconfont/iconfont.css new file mode 100644 index 0000000..7c38781 --- /dev/null +++ b/src/asserts/styles/iconfont/iconfont.css @@ -0,0 +1,2474 @@ +@font-face { + font-family: 'iconfont'; + src: + url('iconfont.woff2?t=1629473213677') format('woff2'), + url('iconfont.woff?t=1629473213677') format('woff'), + url('iconfont.ttf?t=1629473213677') format('truetype'); +} + +.iconfont { + font-family: 'iconfont' !important; + font-style: normal; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.icon-kefu:before { + content: '\e641'; +} + +.icon-kefu1:before { + content: '\e600'; +} + +.icon-caret-up1:before { + content: '\e721'; +} + +.icon-caret-down1:before { + content: '\e722'; +} + +.icon-dot:before { + content: '\e649'; +} + +.icon-play:before { + content: '\e6d9'; +} + +.icon-zan:before { + content: '\e6d7'; +} + +.icon-ellipsis1:before { + content: '\e65d'; +} + +.icon-jiantou1:before { + content: '\e9d4'; +} + +.icon-night-circle-fill:before { + content: '\e63c'; +} + +.icon-night:before { + content: '\e6d1'; +} + +.icon-share-square:before { + content: '\e642'; +} + +.icon-linkedin2:before { + content: '\e6e7'; +} + +.icon-facebook1:before { + content: '\e60b'; +} + +.icon-instagram-fill1:before { + content: '\e768'; +} + +.icon-arrowdown:before { + content: '\e861'; +} + +.icon-dribbble-circle-fill:before { + content: '\e961'; +} + +.icon-upload:before { + content: '\e862'; +} + +.icon-googleplus-circle-f:before { + content: '\e962'; +} + +.icon-colum-height:before { + content: '\e863'; +} + +.icon-medium-circle-fill:before { + content: '\e963'; +} + +.icon-vertical-align-botto:before { + content: '\e864'; +} + +.icon-QQ-circle-fill:before { + content: '\e964'; +} + +.icon-vertical-align-middl:before { + content: '\e865'; +} + +.icon-IE-circle-fill:before { + content: '\e965'; +} + +.icon-totop:before { + content: '\e866'; +} + +.icon-google-circle-fill:before { + content: '\e966'; +} + +.icon-vertical-align-top:before { + content: '\e867'; +} + +.icon-dingtalk-circle-fill:before { + content: '\e967'; +} + +.icon-download:before { + content: '\e868'; +} + +.icon-sketch-circle-fill:before { + content: '\e968'; +} + +.icon-sort-descending:before { + content: '\e869'; +} + +.icon-slack-circle-fill:before { + content: '\e969'; +} + +.icon-sort-ascending:before { + content: '\e86a'; +} + +.icon-twitter-circle-fill:before { + content: '\e96a'; +} + +.icon-fall:before { + content: '\e86b'; +} + +.icon-taobao-circle-fill:before { + content: '\e96b'; +} + +.icon-swap:before { + content: '\e86c'; +} + +.icon-weibo-circle-fill:before { + content: '\e96c'; +} + +.icon-stock:before { + content: '\e86d'; +} + +.icon-zhihu-circle-fill:before { + content: '\e96d'; +} + +.icon-rise:before { + content: '\e86e'; +} + +.icon-reddit-circle-fill:before { + content: '\e96e'; +} + +.icon-indent:before { + content: '\e86f'; +} + +.icon-alipay-square-fill:before { + content: '\e96f'; +} + +.icon-outdent:before { + content: '\e870'; +} + +.icon-dingtalk-square-fill:before { + content: '\e970'; +} + +.icon-menu:before { + content: '\e871'; +} + +.icon-CodeSandbox-square-f:before { + content: '\e971'; +} + +.icon-unorderedlist:before { + content: '\e872'; +} + +.icon-behance-square-fill:before { + content: '\e972'; +} + +.icon-orderedlist:before { + content: '\e873'; +} + +.icon-amazon-square-fill:before { + content: '\e973'; +} + +.icon-align-right:before { + content: '\e874'; +} + +.icon-codepen-square-fill:before { + content: '\e974'; +} + +.icon-align-center:before { + content: '\e875'; +} + +.icon-dribbble-square-fill:before { + content: '\e975'; +} + +.icon-align-left:before { + content: '\e876'; +} + +.icon-dropbox-square-fill:before { + content: '\e976'; +} + +.icon-pic-right:before { + content: '\e877'; +} + +.icon-facebook-fill:before { + content: '\e977'; +} + +.icon-pic-left:before { + content: '\e878'; +} + +.icon-googleplus-square-f:before { + content: '\e978'; +} + +.icon-bold:before { + content: '\e879'; +} + +.icon-google-square-fill:before { + content: '\e979'; +} + +.icon-font-colors:before { + content: '\e87a'; +} + +.icon-instagram-fill:before { + content: '\e97a'; +} + +.icon-exclaimination:before { + content: '\e87b'; +} + +.icon-IE-square-fill:before { + content: '\e97b'; +} + +.icon-font-size:before { + content: '\e87c'; +} + +.icon-medium-square-fill:before { + content: '\e97c'; +} + +.icon-check-circle:before { + content: '\e77d'; +} + +.icon-infomation:before { + content: '\e87d'; +} + +.icon-linkedin-fill:before { + content: '\e97d'; +} + +.icon-CI:before { + content: '\e77e'; +} + +.icon-line-height:before { + content: '\e87e'; +} + +.icon-QQ-square-fill:before { + content: '\e97e'; +} + +.icon-Dollar:before { + content: '\e77f'; +} + +.icon-strikethrough:before { + content: '\e87f'; +} + +.icon-reddit-square-fill:before { + content: '\e97f'; +} + +.icon-compass:before { + content: '\e780'; +} + +.icon-underline:before { + content: '\e880'; +} + +.icon-twitter-square-fill:before { + content: '\e980'; +} + +.icon-close-circle:before { + content: '\e781'; +} + +.icon-number:before { + content: '\e881'; +} + +.icon-sketch-square-fill:before { + content: '\e981'; +} + +.icon-frown:before { + content: '\e782'; +} + +.icon-italic:before { + content: '\e882'; +} + +.icon-slack-square-fill:before { + content: '\e982'; +} + +.icon-info-circle:before { + content: '\e783'; +} + +.icon-code:before { + content: '\e883'; +} + +.icon-taobao-square-fill:before { + content: '\e983'; +} + +.icon-left-circle:before { + content: '\e784'; +} + +.icon-column-width:before { + content: '\e884'; +} + +.icon-weibo-square-fill:before { + content: '\e984'; +} + +.icon-down-circle:before { + content: '\e785'; +} + +.icon-check:before { + content: '\e885'; +} + +.icon-zhihu-square-fill:before { + content: '\e985'; +} + +.icon-EURO:before { + content: '\e786'; +} + +.icon-ellipsis:before { + content: '\e886'; +} + +.icon-zoomout:before { + content: '\e986'; +} + +.icon-copyright:before { + content: '\e787'; +} + +.icon-dash:before { + content: '\e887'; +} + +.icon-apartment:before { + content: '\e987'; +} + +.icon-minus-circle:before { + content: '\e788'; +} + +.icon-close:before { + content: '\e888'; +} + +.icon-audio:before { + content: '\e988'; +} + +.icon-meh:before { + content: '\e789'; +} + +.icon-enter:before { + content: '\e889'; +} + +.icon-audio-fill:before { + content: '\e989'; +} + +.icon-plus-circle:before { + content: '\e78a'; +} + +.icon-line:before { + content: '\e88a'; +} + +.icon-robot:before { + content: '\e98a'; +} + +.icon-play-circle:before { + content: '\e78b'; +} + +.icon-minus:before { + content: '\e88b'; +} + +.icon-zoomin:before { + content: '\e98b'; +} + +.icon-question-circle:before { + content: '\e78c'; +} + +.icon-question:before { + content: '\e88c'; +} + +.icon-robot-fill:before { + content: '\e98c'; +} + +.icon-Pound:before { + content: '\e78d'; +} + +.icon-rollback:before { + content: '\e88d'; +} + +.icon-bug-fill:before { + content: '\e98d'; +} + +.icon-right-circle:before { + content: '\e78e'; +} + +.icon-small-dash:before { + content: '\e88e'; +} + +.icon-bug:before { + content: '\e98e'; +} + +.icon-smile:before { + content: '\e78f'; +} + +.icon-pause:before { + content: '\e88f'; +} + +.icon-audiostatic:before { + content: '\e98f'; +} + +.icon-trademark:before { + content: '\e790'; +} + +.icon-bg-colors:before { + content: '\e890'; +} + +.icon-comment:before { + content: '\e990'; +} + +.icon-time-circle:before { + content: '\e791'; +} + +.icon-crown:before { + content: '\e891'; +} + +.icon-signal-fill:before { + content: '\e991'; +} + +.icon-timeout:before { + content: '\e792'; +} + +.icon-drag:before { + content: '\e892'; +} + +.icon-verified:before { + content: '\e992'; +} + +.icon-earth:before { + content: '\e793'; +} + +.icon-desktop:before { + content: '\e893'; +} + +.icon-shortcut-fill:before { + content: '\e993'; +} + +.icon-YUAN:before { + content: '\e794'; +} + +.icon-gift:before { + content: '\e894'; +} + +.icon-videocameraadd:before { + content: '\e994'; +} + +.icon-up-circle:before { + content: '\e795'; +} + +.icon-stop:before { + content: '\e895'; +} + +.icon-switchuser:before { + content: '\e995'; +} + +.icon-warning-circle:before { + content: '\e796'; +} + +.icon-fire:before { + content: '\e896'; +} + +.icon-whatsapp:before { + content: '\e996'; +} + +.icon-sync:before { + content: '\e797'; +} + +.icon-thunderbolt:before { + content: '\e897'; +} + +.icon-appstoreadd:before { + content: '\e997'; +} + +.icon-transaction:before { + content: '\e798'; +} + +.icon-check-circle-fill:before { + content: '\e898'; +} + +.icon-caret-down:before { + content: '\e998'; +} + +.icon-undo:before { + content: '\e799'; +} + +.icon-left-circle-fill:before { + content: '\e899'; +} + +.icon-backward:before { + content: '\e999'; +} + +.icon-redo:before { + content: '\e79a'; +} + +.icon-down-circle-fill:before { + content: '\e89a'; +} + +.icon-caret-up:before { + content: '\e99a'; +} + +.icon-reload:before { + content: '\e79b'; +} + +.icon-minus-circle-fill:before { + content: '\e89b'; +} + +.icon-caret-right:before { + content: '\e99b'; +} + +.icon-reloadtime:before { + content: '\e79c'; +} + +.icon-close-circle-fill:before { + content: '\e89c'; +} + +.icon-caret-left:before { + content: '\e99c'; +} + +.icon-message:before { + content: '\e79d'; +} + +.icon-info-circle-fill:before { + content: '\e89d'; +} + +.icon-fast-backward:before { + content: '\e99d'; +} + +.icon-dashboard:before { + content: '\e79e'; +} + +.icon-up-circle-fill:before { + content: '\e89e'; +} + +.icon-forward:before { + content: '\e99e'; +} + +.icon-issuesclose:before { + content: '\e79f'; +} + +.icon-right-circle-fill:before { + content: '\e89f'; +} + +.icon-fast-forward:before { + content: '\e99f'; +} + +.icon-poweroff:before { + content: '\e7a0'; +} + +.icon-plus-circle-fill:before { + content: '\e8a0'; +} + +.icon-search:before { + content: '\e9a0'; +} + +.icon-logout:before { + content: '\e7a1'; +} + +.icon-question-circle-fill:before { + content: '\e8a1'; +} + +.icon-retweet:before { + content: '\e9a1'; +} + +.icon-piechart:before { + content: '\e7a2'; +} + +.icon-EURO-circle-fill:before { + content: '\e8a2'; +} + +.icon-login:before { + content: '\e9a2'; +} + +.icon-setting:before { + content: '\e7a3'; +} + +.icon-frown-fill:before { + content: '\e8a3'; +} + +.icon-step-backward:before { + content: '\e9a3'; +} + +.icon-eye:before { + content: '\e7a4'; +} + +.icon-copyright-circle-fil:before { + content: '\e8a4'; +} + +.icon-step-forward:before { + content: '\e9a4'; +} + +.icon-location:before { + content: '\e7a5'; +} + +.icon-CI-circle-fill:before { + content: '\e8a5'; +} + +.icon-swap-right:before { + content: '\e9a5'; +} + +.icon-edit-square:before { + content: '\e7a6'; +} + +.icon-compass-fill:before { + content: '\e8a6'; +} + +.icon-swap-left:before { + content: '\e9a6'; +} + +.icon-export:before { + content: '\e7a7'; +} + +.icon-Dollar-circle-fill:before { + content: '\e8a7'; +} + +.icon-woman:before { + content: '\e9a7'; +} + +.icon-save:before { + content: '\e7a8'; +} + +.icon-poweroff-circle-fill:before { + content: '\e8a8'; +} + +.icon-plus:before { + content: '\e9a8'; +} + +.icon-Import:before { + content: '\e7a9'; +} + +.icon-meh-fill:before { + content: '\e8a9'; +} + +.icon-eyeclose-fill:before { + content: '\e9a9'; +} + +.icon-appstore:before { + content: '\e7aa'; +} + +.icon-play-circle-fill:before { + content: '\e8aa'; +} + +.icon-eye-close:before { + content: '\e9aa'; +} + +.icon-close-square:before { + content: '\e7ab'; +} + +.icon-Pound-circle-fill:before { + content: '\e8ab'; +} + +.icon-clear:before { + content: '\e9ab'; +} + +.icon-down-square:before { + content: '\e7ac'; +} + +.icon-smile-fill:before { + content: '\e8ac'; +} + +.icon-collapse:before { + content: '\e9ac'; +} + +.icon-layout:before { + content: '\e7ad'; +} + +.icon-stop-fill:before { + content: '\e8ad'; +} + +.icon-expand:before { + content: '\e9ad'; +} + +.icon-left-square:before { + content: '\e7ae'; +} + +.icon-warning-circle-fill:before { + content: '\e8ae'; +} + +.icon-deletecolumn:before { + content: '\e9ae'; +} + +.icon-play-square:before { + content: '\e7af'; +} + +.icon-time-circle-fill:before { + content: '\e8af'; +} + +.icon-merge-cells:before { + content: '\e9af'; +} + +.icon-control:before { + content: '\e7b0'; +} + +.icon-trademark-circle-fil:before { + content: '\e8b0'; +} + +.icon-subnode:before { + content: '\e9b0'; +} + +.icon-codelibrary:before { + content: '\e7b1'; +} + +.icon-YUAN-circle-fill:before { + content: '\e8b1'; +} + +.icon-rotate-left:before { + content: '\e9b1'; +} + +.icon-detail:before { + content: '\e7b2'; +} + +.icon-heart-fill:before { + content: '\e8b2'; +} + +.icon-rotate-right:before { + content: '\e9b2'; +} + +.icon-minus-square:before { + content: '\e7b3'; +} + +.icon-piechart-circle-fil:before { + content: '\e8b3'; +} + +.icon-insertrowbelow:before { + content: '\e9b3'; +} + +.icon-plus-square:before { + content: '\e7b4'; +} + +.icon-dashboard-fill:before { + content: '\e8b4'; +} + +.icon-insertrowabove:before { + content: '\e9b4'; +} + +.icon-right-square:before { + content: '\e7b5'; +} + +.icon-message-fill:before { + content: '\e8b5'; +} + +.icon-table1:before { + content: '\e9b5'; +} + +.icon-project:before { + content: '\e7b6'; +} + +.icon-check-square-fill:before { + content: '\e8b6'; +} + +.icon-solit-cells:before { + content: '\e9b6'; +} + +.icon-wallet:before { + content: '\e7b7'; +} + +.icon-down-square-fill:before { + content: '\e8b7'; +} + +.icon-formatpainter:before { + content: '\e9b7'; +} + +.icon-up-square:before { + content: '\e7b8'; +} + +.icon-minus-square-fill:before { + content: '\e8b8'; +} + +.icon-insertrowright:before { + content: '\e9b8'; +} + +.icon-calculator:before { + content: '\e7b9'; +} + +.icon-close-square-fill:before { + content: '\e8b9'; +} + +.icon-formatpainter-fill:before { + content: '\e9b9'; +} + +.icon-interation:before { + content: '\e7ba'; +} + +.icon-codelibrary-fill:before { + content: '\e8ba'; +} + +.icon-insertrowleft:before { + content: '\e9ba'; +} + +.icon-check-square:before { + content: '\e7bb'; +} + +.icon-left-square-fill:before { + content: '\e8bb'; +} + +.icon-translate:before { + content: '\e9bb'; +} + +.icon-border:before { + content: '\e7bc'; +} + +.icon-play-square-fill:before { + content: '\e8bc'; +} + +.icon-deleterow:before { + content: '\e9bc'; +} + +.icon-border-outer:before { + content: '\e7bd'; +} + +.icon-up-square-fill:before { + content: '\e8bd'; +} + +.icon-sisternode:before { + content: '\e9bd'; +} + +.icon-border-top:before { + content: '\e7be'; +} + +.icon-right-square-fill:before { + content: '\e8be'; +} + +.icon-google-fill:before { + content: '\e767'; +} + +.icon-border-bottom:before { + content: '\e7bf'; +} + +.icon-plus-square-fill:before { + content: '\e8bf'; +} + +.icon-Field-number:before { + content: '\e9be'; +} + +.icon-border-left:before { + content: '\e7c0'; +} + +.icon-accountbook-fill:before { + content: '\e8c0'; +} + +.icon-Field-String:before { + content: '\e9bf'; +} + +.icon-border-right:before { + content: '\e7c1'; +} + +.icon-carryout-fill:before { + content: '\e8c1'; +} + +.icon-Function:before { + content: '\e9c0'; +} + +.icon-border-inner:before { + content: '\e7c2'; +} + +.icon-calendar-fill:before { + content: '\e8c2'; +} + +.icon-Field-time:before { + content: '\e9c1'; +} + +.icon-border-verticle:before { + content: '\e7c3'; +} + +.icon-calculator-fill:before { + content: '\e8c3'; +} + +.icon-GIF:before { + content: '\e9c2'; +} + +.icon-border-horizontal:before { + content: '\e7c4'; +} + +.icon-interation-fill:before { + content: '\e8c4'; +} + +.icon-Partition:before { + content: '\e9c3'; +} + +.icon-radius-bottomleft:before { + content: '\e7c5'; +} + +.icon-project-fill:before { + content: '\e8c5'; +} + +.icon-index:before { + content: '\e9c4'; +} + +.icon-radius-bottomright:before { + content: '\e7c6'; +} + +.icon-detail-fill:before { + content: '\e8c6'; +} + +.icon-Storedprocedure:before { + content: '\e9c5'; +} + +.icon-radius-upleft:before { + content: '\e7c7'; +} + +.icon-save-fill:before { + content: '\e8c7'; +} + +.icon-Field-Binary:before { + content: '\e9c6'; +} + +.icon-radius-upright:before { + content: '\e7c8'; +} + +.icon-wallet-fill:before { + content: '\e8c8'; +} + +.icon-Console-SQL:before { + content: '\e9c7'; +} + +.icon-radius-setting:before { + content: '\e7c9'; +} + +.icon-control-fill:before { + content: '\e8c9'; +} + +.icon-icon-test:before { + content: '\e9c8'; +} + +.icon-adduser:before { + content: '\e7ca'; +} + +.icon-layout-fill:before { + content: '\e8ca'; +} + +.icon-aim:before { + content: '\e9c9'; +} + +.icon-deleteteam:before { + content: '\e7cb'; +} + +.icon-appstore-fill:before { + content: '\e8cb'; +} + +.icon-compress:before { + content: '\e9ca'; +} + +.icon-deleteuser:before { + content: '\e7cc'; +} + +.icon-mobile-fill:before { + content: '\e8cc'; +} + +.icon-expend:before { + content: '\e9cb'; +} + +.icon-addteam:before { + content: '\e7cd'; +} + +.icon-tablet-fill:before { + content: '\e8cd'; +} + +.icon-folder-view:before { + content: '\e9cc'; +} + +.icon-user:before { + content: '\e7ce'; +} + +.icon-book-fill:before { + content: '\e8ce'; +} + +.icon-file-GIF:before { + content: '\e9cd'; +} + +.icon-team:before { + content: '\e7cf'; +} + +.icon-redenvelope-fill:before { + content: '\e8cf'; +} + +.icon-group:before { + content: '\e9ce'; +} + +.icon-areachart:before { + content: '\e7d0'; +} + +.icon-safetycertificate-f:before { + content: '\e8d0'; +} + +.icon-send:before { + content: '\e9cf'; +} + +.icon-linechart:before { + content: '\e7d1'; +} + +.icon-propertysafety-fill:before { + content: '\e8d1'; +} + +.icon-Report:before { + content: '\e9d0'; +} + +.icon-barchart:before { + content: '\e7d2'; +} + +.icon-insurance-fill:before { + content: '\e8d2'; +} + +.icon-View:before { + content: '\e9d1'; +} + +.icon-pointmap:before { + content: '\e7d3'; +} + +.icon-securityscan-fill:before { + content: '\e8d3'; +} + +.icon-shortcut:before { + content: '\e9d2'; +} + +.icon-container:before { + content: '\e7d4'; +} + +.icon-file-exclamation-fil:before { + content: '\e8d4'; +} + +.icon-ungroup:before { + content: '\e9d3'; +} + +.icon-database:before { + content: '\e7d5'; +} + +.icon-file-add-fill:before { + content: '\e8d5'; +} + +.icon-sever:before { + content: '\e7d6'; +} + +.icon-file-fill:before { + content: '\e8d6'; +} + +.icon-mobile:before { + content: '\e7d7'; +} + +.icon-file-excel-fill:before { + content: '\e8d7'; +} + +.icon-tablet:before { + content: '\e7d8'; +} + +.icon-file-markdown-fill:before { + content: '\e8d8'; +} + +.icon-redenvelope:before { + content: '\e7d9'; +} + +.icon-file-text-fill:before { + content: '\e8d9'; +} + +.icon-book:before { + content: '\e7da'; +} + +.icon-file-ppt-fill:before { + content: '\e8da'; +} + +.icon-filedone:before { + content: '\e7db'; +} + +.icon-file-unknown-fill:before { + content: '\e8db'; +} + +.icon-reconciliation:before { + content: '\e7dc'; +} + +.icon-file-word-fill:before { + content: '\e8dc'; +} + +.icon-file-exception:before { + content: '\e7dd'; +} + +.icon-file-zip-fill:before { + content: '\e8dd'; +} + +.icon-filesync:before { + content: '\e7de'; +} + +.icon-file-pdf-fill:before { + content: '\e8de'; +} + +.icon-filesearch:before { + content: '\e7df'; +} + +.icon-file-image-fill:before { + content: '\e8df'; +} + +.icon-solution:before { + content: '\e7e0'; +} + +.icon-diff-fill:before { + content: '\e8e0'; +} + +.icon-fileprotect:before { + content: '\e7e1'; +} + +.icon-file-copy-fill:before { + content: '\e8e1'; +} + +.icon-file-add:before { + content: '\e7e2'; +} + +.icon-snippets-fill:before { + content: '\e8e2'; +} + +.icon-file-excel:before { + content: '\e7e3'; +} + +.icon-batchfolding-fill:before { + content: '\e8e3'; +} + +.icon-file-exclamation:before { + content: '\e7e4'; +} + +.icon-reconciliation-fill:before { + content: '\e8e4'; +} + +.icon-file-pdf:before { + content: '\e7e5'; +} + +.icon-folder-add-fill:before { + content: '\e8e5'; +} + +.icon-file-image:before { + content: '\e7e6'; +} + +.icon-folder-fill:before { + content: '\e8e6'; +} + +.icon-file-markdown:before { + content: '\e7e7'; +} + +.icon-folder-open-fill:before { + content: '\e8e7'; +} + +.icon-file-unknown:before { + content: '\e7e8'; +} + +.icon-database-fill:before { + content: '\e8e8'; +} + +.icon-file-ppt:before { + content: '\e7e9'; +} + +.icon-container-fill:before { + content: '\e8e9'; +} + +.icon-file-word:before { + content: '\e7ea'; +} + +.icon-sever-fill:before { + content: '\e8ea'; +} + +.icon-file:before { + content: '\e7eb'; +} + +.icon-calendar-check-fill:before { + content: '\e8eb'; +} + +.icon-file-zip:before { + content: '\e7ec'; +} + +.icon-image-fill:before { + content: '\e8ec'; +} + +.icon-file-text:before { + content: '\e7ed'; +} + +.icon-idcard-fill:before { + content: '\e8ed'; +} + +.icon-file-copy:before { + content: '\e7ee'; +} + +.icon-creditcard-fill:before { + content: '\e8ee'; +} + +.icon-snippets:before { + content: '\e7ef'; +} + +.icon-fund-fill:before { + content: '\e8ef'; +} + +.icon-audit:before { + content: '\e7f0'; +} + +.icon-read-fill:before { + content: '\e8f0'; +} + +.icon-diff:before { + content: '\e7f1'; +} + +.icon-contacts-fill:before { + content: '\e8f1'; +} + +.icon-Batchfolding:before { + content: '\e7f2'; +} + +.icon-delete-fill:before { + content: '\e8f2'; +} + +.icon-securityscan:before { + content: '\e7f3'; +} + +.icon-notification-fill:before { + content: '\e8f3'; +} + +.icon-propertysafety:before { + content: '\e7f4'; +} + +.icon-flag-fill:before { + content: '\e8f4'; +} + +.icon-safetycertificate:before { + content: '\e7f5'; +} + +.icon-moneycollect-fill:before { + content: '\e8f5'; +} + +.icon-insurance:before { + content: '\e7f6'; +} + +.icon-medicinebox-fill:before { + content: '\e8f6'; +} + +.icon-alert:before { + content: '\e7f7'; +} + +.icon-rest-fill:before { + content: '\e8f7'; +} + +.icon-delete:before { + content: '\e7f8'; +} + +.icon-shopping-fill:before { + content: '\e8f8'; +} + +.icon-hourglass:before { + content: '\e7f9'; +} + +.icon-skin-fill:before { + content: '\e8f9'; +} + +.icon-bulb:before { + content: '\e7fa'; +} + +.icon-video-fill:before { + content: '\e8fa'; +} + +.icon-experiment:before { + content: '\e7fb'; +} + +.icon-sound-fill:before { + content: '\e8fb'; +} + +.icon-bell:before { + content: '\e7fc'; +} + +.icon-bulb-fill:before { + content: '\e8fc'; +} + +.icon-trophy:before { + content: '\e7fd'; +} + +.icon-bell-fill:before { + content: '\e8fd'; +} + +.icon-rest:before { + content: '\e7fe'; +} + +.icon-filter-fill:before { + content: '\e8fe'; +} + +.icon-USB:before { + content: '\e7ff'; +} + +.icon-fire-fill:before { + content: '\e8ff'; +} + +.icon-skin:before { + content: '\e800'; +} + +.icon-funnelplot-fill:before { + content: '\e900'; +} + +.icon-home:before { + content: '\e801'; +} + +.icon-gift-fill:before { + content: '\e901'; +} + +.icon-bank:before { + content: '\e802'; +} + +.icon-hourglass-fill:before { + content: '\e902'; +} + +.icon-filter:before { + content: '\e803'; +} + +.icon-home-fill:before { + content: '\e903'; +} + +.icon-funnelplot:before { + content: '\e804'; +} + +.icon-trophy-fill:before { + content: '\e904'; +} + +.icon-like:before { + content: '\e805'; +} + +.icon-location-fill:before { + content: '\e905'; +} + +.icon-unlike:before { + content: '\e806'; +} + +.icon-cloud-fill:before { + content: '\e906'; +} + +.icon-unlock:before { + content: '\e807'; +} + +.icon-customerservice-fill:before { + content: '\e907'; +} + +.icon-lock:before { + content: '\e808'; +} + +.icon-experiment-fill:before { + content: '\e908'; +} + +.icon-customerservice:before { + content: '\e809'; +} + +.icon-eye-fill:before { + content: '\e909'; +} + +.icon-flag:before { + content: '\e80a'; +} + +.icon-like-fill:before { + content: '\e90a'; +} + +.icon-moneycollect:before { + content: '\e80b'; +} + +.icon-lock-fill:before { + content: '\e90b'; +} + +.icon-medicinebox:before { + content: '\e80c'; +} + +.icon-unlike-fill:before { + content: '\e90c'; +} + +.icon-shop:before { + content: '\e80d'; +} + +.icon-star-fill:before { + content: '\e90d'; +} + +.icon-rocket:before { + content: '\e80e'; +} + +.icon-unlock-fill:before { + content: '\e90e'; +} + +.icon-shopping:before { + content: '\e80f'; +} + +.icon-alert-fill:before { + content: '\e90f'; +} + +.icon-folder:before { + content: '\e810'; +} + +.icon-api-fill:before { + content: '\e910'; +} + +.icon-folder-open:before { + content: '\e811'; +} + +.icon-highlight-fill:before { + content: '\e911'; +} + +.icon-folder-add:before { + content: '\e812'; +} + +.icon-phone-fill:before { + content: '\e912'; +} + +.icon-deploymentunit:before { + content: '\e813'; +} + +.icon-edit-fill:before { + content: '\e913'; +} + +.icon-accountbook:before { + content: '\e814'; +} + +.icon-pushpin-fill:before { + content: '\e914'; +} + +.icon-contacts:before { + content: '\e815'; +} + +.icon-rocket-fill:before { + content: '\e915'; +} + +.icon-carryout:before { + content: '\e816'; +} + +.icon-thunderbolt-fill:before { + content: '\e916'; +} + +.icon-calendar-check:before { + content: '\e817'; +} + +.icon-tag-fill:before { + content: '\e917'; +} + +.icon-calendar:before { + content: '\e818'; +} + +.icon-wrench-fill:before { + content: '\e918'; +} + +.icon-scan:before { + content: '\e819'; +} + +.icon-tags-fill:before { + content: '\e919'; +} + +.icon-select:before { + content: '\e81a'; +} + +.icon-bank-fill:before { + content: '\e91a'; +} + +.icon-boxplot:before { + content: '\e81b'; +} + +.icon-camera-fill:before { + content: '\e91b'; +} + +.icon-build:before { + content: '\e81c'; +} + +.icon-error-fill:before { + content: '\e91c'; +} + +.icon-sliders:before { + content: '\e81d'; +} + +.icon-crown-fill:before { + content: '\e91d'; +} + +.icon-laptop:before { + content: '\e81e'; +} + +.icon-mail-fill:before { + content: '\e91e'; +} + +.icon-barcode:before { + content: '\e81f'; +} + +.icon-car-fill:before { + content: '\e91f'; +} + +.icon-camera:before { + content: '\e820'; +} + +.icon-printer-fill:before { + content: '\e920'; +} + +.icon-cluster:before { + content: '\e821'; +} + +.icon-shop-fill:before { + content: '\e921'; +} + +.icon-gateway:before { + content: '\e822'; +} + +.icon-setting-fill:before { + content: '\e922'; +} + +.icon-car:before { + content: '\e823'; +} + +.icon-USB-fill:before { + content: '\e923'; +} + +.icon-printer:before { + content: '\e824'; +} + +.icon-golden-fill:before { + content: '\e924'; +} + +.icon-read:before { + content: '\e825'; +} + +.icon-build-fill:before { + content: '\e925'; +} + +.icon-cloud-server:before { + content: '\e826'; +} + +.icon-boxplot-fill:before { + content: '\e926'; +} + +.icon-cloud-upload:before { + content: '\e827'; +} + +.icon-sliders-fill:before { + content: '\e927'; +} + +.icon-cloud:before { + content: '\e828'; +} + +.icon-alibaba:before { + content: '\e928'; +} + +.icon-cloud-download:before { + content: '\e829'; +} + +.icon-alibabacloud:before { + content: '\e929'; +} + +.icon-cloud-sync:before { + content: '\e82a'; +} + +.icon-antdesign:before { + content: '\e92a'; +} + +.icon-video:before { + content: '\e82b'; +} + +.icon-ant-cloud:before { + content: '\e92b'; +} + +.icon-notification:before { + content: '\e82c'; +} + +.icon-behance:before { + content: '\e92c'; +} + +.icon-sound:before { + content: '\e82d'; +} + +.icon-googleplus:before { + content: '\e92d'; +} + +.icon-radarchart:before { + content: '\e82e'; +} + +.icon-medium:before { + content: '\e92e'; +} + +.icon-qrcode:before { + content: '\e82f'; +} + +.icon-google:before { + content: '\e92f'; +} + +.icon-fund:before { + content: '\e830'; +} + +.icon-IE:before { + content: '\e930'; +} + +.icon-image:before { + content: '\e831'; +} + +.icon-amazon:before { + content: '\e931'; +} + +.icon-mail:before { + content: '\e832'; +} + +.icon-slack:before { + content: '\e932'; +} + +.icon-table:before { + content: '\e833'; +} + +.icon-alipay:before { + content: '\e933'; +} + +.icon-idcard:before { + content: '\e834'; +} + +.icon-taobao:before { + content: '\e934'; +} + +.icon-creditcard:before { + content: '\e835'; +} + +.icon-zhihu:before { + content: '\e935'; +} + +.icon-heart:before { + content: '\e836'; +} + +.icon-HTML:before { + content: '\e936'; +} + +.icon-block:before { + content: '\e837'; +} + +.icon-linkedin:before { + content: '\e937'; +} + +.icon-error:before { + content: '\e838'; +} + +.icon-yahoo:before { + content: '\e938'; +} + +.icon-star:before { + content: '\e839'; +} + +.icon-facebook:before { + content: '\e939'; +} + +.icon-gold:before { + content: '\e83a'; +} + +.icon-skype:before { + content: '\e93a'; +} + +.icon-heatmap:before { + content: '\e83b'; +} + +.icon-CodeSandbox:before { + content: '\e93b'; +} + +.icon-wifi:before { + content: '\e83c'; +} + +.icon-chrome:before { + content: '\e93c'; +} + +.icon-attachment:before { + content: '\e83d'; +} + +.icon-codepen:before { + content: '\e93d'; +} + +.icon-edit:before { + content: '\e83e'; +} + +.icon-aliwangwang:before { + content: '\e93e'; +} + +.icon-key:before { + content: '\e83f'; +} + +.icon-apple:before { + content: '\e93f'; +} + +.icon-api:before { + content: '\e840'; +} + +.icon-android:before { + content: '\e940'; +} + +.icon-disconnect:before { + content: '\e841'; +} + +.icon-sketch:before { + content: '\e941'; +} + +.icon-highlight:before { + content: '\e842'; +} + +.icon-Gitlab:before { + content: '\e942'; +} + +.icon-monitor:before { + content: '\e843'; +} + +.icon-dribbble:before { + content: '\e943'; +} + +.icon-link:before { + content: '\e844'; +} + +.icon-instagram:before { + content: '\e944'; +} + +.icon-man:before { + content: '\e845'; +} + +.icon-reddit:before { + content: '\e945'; +} + +.icon-percentage:before { + content: '\e846'; +} + +.icon-windows:before { + content: '\e946'; +} + +.icon-pushpin:before { + content: '\e847'; +} + +.icon-yuque:before { + content: '\e947'; +} + +.icon-phone:before { + content: '\e848'; +} + +.icon-Youtube:before { + content: '\e948'; +} + +.icon-shake:before { + content: '\e849'; +} + +.icon-Gitlab-fill:before { + content: '\e949'; +} + +.icon-tag:before { + content: '\e84a'; +} + +.icon-dropbox:before { + content: '\e94a'; +} + +.icon-wrench:before { + content: '\e84b'; +} + +.icon-dingtalk:before { + content: '\e94b'; +} + +.icon-tags:before { + content: '\e84c'; +} + +.icon-android-fill:before { + content: '\e94c'; +} + +.icon-scissor:before { + content: '\e84d'; +} + +.icon-apple-fill:before { + content: '\e94d'; +} + +.icon-mr:before { + content: '\e84e'; +} + +.icon-HTML-fill:before { + content: '\e94e'; +} + +.icon-share:before { + content: '\e84f'; +} + +.icon-windows-fill:before { + content: '\e94f'; +} + +.icon-branches:before { + content: '\e850'; +} + +.icon-QQ:before { + content: '\e950'; +} + +.icon-fork:before { + content: '\e851'; +} + +.icon-twitter:before { + content: '\e951'; +} + +.icon-shrink:before { + content: '\e852'; +} + +.icon-skype-fill:before { + content: '\e952'; +} + +.icon-arrawsalt:before { + content: '\e853'; +} + +.icon-weibo:before { + content: '\e953'; +} + +.icon-verticalright:before { + content: '\e854'; +} + +.icon-yuque-fill:before { + content: '\e954'; +} + +.icon-verticalleft:before { + content: '\e855'; +} + +.icon-Youtube-fill:before { + content: '\e955'; +} + +.icon-right:before { + content: '\e856'; +} + +.icon-yahoo-fill:before { + content: '\e956'; +} + +.icon-left:before { + content: '\e857'; +} + +.icon-wechat:before { + content: '\e957'; +} + +.icon-up:before { + content: '\e858'; +} + +.icon-chrome-fill:before { + content: '\e958'; +} + +.icon-down:before { + content: '\e859'; +} + +.icon-alipay-circle-fill:before { + content: '\e959'; +} + +.icon-fullscreen:before { + content: '\e85a'; +} + +.icon-aliwangwang-fill:before { + content: '\e95a'; +} + +.icon-fullscreen-exit:before { + content: '\e85b'; +} + +.icon-behance-circle-fill:before { + content: '\e95b'; +} + +.icon-doubleleft:before { + content: '\e85c'; +} + +.icon-amazon-circle-fill:before { + content: '\e95c'; +} + +.icon-doubleright:before { + content: '\e85d'; +} + +.icon-codepen-circle-fill:before { + content: '\e95d'; +} + +.icon-arrowright:before { + content: '\e85e'; +} + +.icon-CodeSandbox-circle-f:before { + content: '\e95e'; +} + +.icon-arrowup:before { + content: '\e85f'; +} + +.icon-dropbox-circle-fill:before { + content: '\e95f'; +} + +.icon-arrowleft:before { + content: '\e860'; +} + +.icon-github-fill:before { + content: '\e960'; +} diff --git a/src/asserts/styles/iconfont/iconfont.ttf b/src/asserts/styles/iconfont/iconfont.ttf new file mode 100644 index 0000000..721b31a Binary files /dev/null and b/src/asserts/styles/iconfont/iconfont.ttf differ diff --git a/src/asserts/styles/iconfont/iconfont.woff b/src/asserts/styles/iconfont/iconfont.woff new file mode 100644 index 0000000..df5f049 Binary files /dev/null and b/src/asserts/styles/iconfont/iconfont.woff differ diff --git a/src/asserts/styles/iconfont/iconfont.woff2 b/src/asserts/styles/iconfont/iconfont.woff2 new file mode 100644 index 0000000..5e83db1 Binary files /dev/null and b/src/asserts/styles/iconfont/iconfont.woff2 differ diff --git a/src/asserts/styles/opposans/OPPOSans-Bold.ttf b/src/asserts/styles/opposans/OPPOSans-Bold.ttf new file mode 100644 index 0000000..b764e98 Binary files /dev/null and b/src/asserts/styles/opposans/OPPOSans-Bold.ttf differ diff --git a/src/asserts/styles/opposans/OPPOSans-Bold.woff2 b/src/asserts/styles/opposans/OPPOSans-Bold.woff2 new file mode 100644 index 0000000..989ed90 Binary files /dev/null and b/src/asserts/styles/opposans/OPPOSans-Bold.woff2 differ diff --git a/src/asserts/styles/opposans/OPPOSans-Medium.ttf b/src/asserts/styles/opposans/OPPOSans-Medium.ttf new file mode 100644 index 0000000..c60c3c7 Binary files /dev/null and b/src/asserts/styles/opposans/OPPOSans-Medium.ttf differ diff --git a/src/asserts/styles/opposans/OPPOSans-Medium.woff2 b/src/asserts/styles/opposans/OPPOSans-Medium.woff2 new file mode 100644 index 0000000..cda829c Binary files /dev/null and b/src/asserts/styles/opposans/OPPOSans-Medium.woff2 differ diff --git a/src/asserts/styles/opposans/OPPOSans-Regular.ttf b/src/asserts/styles/opposans/OPPOSans-Regular.ttf new file mode 100644 index 0000000..d41b703 Binary files /dev/null and b/src/asserts/styles/opposans/OPPOSans-Regular.ttf differ diff --git a/src/asserts/styles/opposans/OPPOSans-Regular.woff2 b/src/asserts/styles/opposans/OPPOSans-Regular.woff2 new file mode 100644 index 0000000..d4f89da Binary files /dev/null and b/src/asserts/styles/opposans/OPPOSans-Regular.woff2 differ diff --git a/src/asserts/styles/opposans/opposans.css b/src/asserts/styles/opposans/opposans.css new file mode 100644 index 0000000..b162b55 --- /dev/null +++ b/src/asserts/styles/opposans/opposans.css @@ -0,0 +1,27 @@ +/** + * OPPO Sans Fonts + */ +@font-face { + font-family: 'OPPOSans'; + src: + url(OPPOSans-Regular.woff2) format('woff2'), + url(OPPOSans-Regular.ttf) format('truetype'); + font-weight: 400; + font-style: normal; +} +@font-face { + font-family: 'OPPOSans'; + src: + url(OPPOSans-Medium.woff2) format('woff2'), + url(OPPOSans-Medium.ttf) format('truetype'); + font-weight: 600; + font-style: normal; +} +@font-face { + font-family: 'OPPOSans'; + src: + url(OPPOSans-Bold.woff2) format('woff2'), + url(OPPOSans-Bold.ttf) format('truetype'); + font-weight: 800; + font-style: normal; +} diff --git a/src/asserts/styles/reset.css b/src/asserts/styles/reset.css new file mode 100644 index 0000000..844808f --- /dev/null +++ b/src/asserts/styles/reset.css @@ -0,0 +1,1079 @@ +:root { + --color-primary: #008c95; + --color-dark: #151b2b; + --color-secondary: #404b69; + --color-muted: #8a92a9; + --color-light: #e8e9ea; + --color-danger: #f7094c; + --color-warning: #ff8338; + --color-body: #151924; + --btn-primary: #008c95; + --btn-dark: #151b2b; + --btn-secondary: #20283b; + --btn-danger: #f7094c; + --btn-light: #eceef1; + --btn-success: #41d589; + --bg-primary: #008c95; + --bg-dark: #151b2b; + --bg-secondary: #283149; + --bg-danger: #ff625e; + --bg-warning: #ffe9d5; + --bg-light: #f6f6f7; + --bg-muted: #ededf1; + --bg-white: #fff; + --bg-body: #fbfbfd; + --border-primary: #008c95; + --border-dark: #2b2a2a; + --border-secondary: #283149; + --border-danger: #f7094c; + --border-muted: #d4ddec; + --border-light: #eff3fa; + --border-white: #fff; + --btn-outline-primary: #fff0f0; + --btn-outline-danger: #ffe8e8; + --border-outline-primary: #ffd1d1; + --border-outline-danger: #ffe8e8; + --night-color-primary: #008c95; + --night-color-dark: #d7d7d7; + --night-color-secondary: #8c8c91; + --night-color-muted: #8a8a8a; + --night-color-light: #6a6a6a; + --night-color-danger: #f7094c; + --night-color-body: #e4e4e5; + --night-btn-primary: #008c95; + --night-btn-outline-primary: #ffd1d1; + --night-btn-dark: #1e1e21; + --night-btn-secondary: #252628; + --night-btn-light: #414147; + --night-btn-danger: #f7094c; + --night-btn-success: #41d589; + --night-bg-primary: #008c95; + --night-bg-dark: #141417; + --night-bg-secondary: #2f3035; + --night-bg-light: #232327; + --night-bg-muted: #202023; + --night-bg-body: #19191d; + --night-bg-danger: #f7094c; + --night-bg-warning: #f6d365; + --night-bg-white: #101012; + --night-border-primary: #008c95; + --night-border-outline-primary: #ffd1d1; + --night-border-dark: #141417; + --night-border-secondary: #2f3035; + --night-border-muted: #37373c; + --night-border-light: #3f4041; + --night-border-danger: #f7094c; + --night-border-white: #101012; + --radius-xs: 3px; + --radius-sm: 4px; + --radius-md: 6px; + --radius-lg: 10px; + --shadow-xs: 0 10px 40px 5px rgb(62 61 80 / 2%); + --shadow-sm: 0 5px 30px 5px rgb(62 61 80 / 5%); + --shadow-md: 0 10px 40px 5px rgb(62 61 80 / 6%); + --shadow-lg: 0 10px 40px 5px rgb(62 61 80 / 10%); + --text-dark: #000; +} + +/* -------------------------------------------------------------------------- */ + +/* 0. CSS Reset +/* -------------------------------------------------------------------------- */ + +*, +*::before, +*::after { + -webkit-box-sizing: border-box; + box-sizing: border-box; +} + +html, +body { + border: none; + margin: 0; + padding: 0; +} + +h1, +h2, +h3, +h4, +h5, +h6, +p, +blockquote, +address, +big, +cite, +code, +em, +font, +img, +small, +strike, +sub, +sup, +li, +ol, +ul, +fieldset, +form, +label, +legend, +button, +table, +caption, +tr, +th, +td { + border: none; + font-size: inherit; + line-height: inherit; + text-align: inherit; + margin: 0; + padding: 0; +} + +/* code -------------------------- */ + +code { + font-size: 90%; + color: inherit; + word-wrap: break-word; + word-break: break-all; + background-color: rgb(253, 246, 227); + counter-reset: step; + counter-increment: step 0; +} + +code .line::before { + content: counter(step); + counter-increment: step; + width: 1rem; + margin-right: 1.5rem; + display: inline-block; + text-align: right; + color: rgba(115, 138, 148, 0.4); +} + +pre { + padding: 14px; + margin-bottom: 24px; + display: block; + overflow: auto; + word-wrap: normal; + overflow-wrap: normal; +} + +/* Table -------------------------- */ + +table { + max-width: 100%; + background-color: transparent; +} + +th, +td { + background: transparent; + padding: 6px 12px; + border: 0.0625rem solid var(--border-light); + text-align: initial; +} + +th { + background: rgba(var(--bg-light), 0.05); +} + +table caption { + padding: 0 0 8px 0; + width: auto; +} + +/* -------------------------------------------------------------------------- */ + +/* 1. Document Setup +/* -------------------------------------------------------------------------- */ + +body { + font-family: + OPPOSans, + OPPOSans2, + OPlusSans3, + PingFang SC, + Lantinghei SC, + Microsoft YaHei, + Source Han Sans CN, + -apple-system, + BlinkMacSystemFont, + HanHei SC, + Helvetica Neue, + Open Sans, + Arial, + Hiragino Sans GB, + STHeiti, + WenQuanYi Micro Hei, + SimSun, + sans-serif, + Apple Color Emoji, + Segoe UI Emoji, + Segoe UI Symbol; + font-size: 0.9375rem; + background-color: var(--bg-body); + color: var(--color-body); + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + -webkit-box-sizing: border-box; + box-sizing: border-box; +} + +/* Base Transitions -------------------------- */ + +p { + line-height: inherit; +} + +/*-------------------------------------------------------------- +## Reboot +--------------------------------------------------------------*/ + +a { + color: var(--color-body); + text-decoration: none; + -webkit-transition: all 0.25s; + transition: all 0.25s; +} + +a:hover, +a:active, +a:focus, +a:not([href]), +a:not([href]):hover { + color: inherit; + text-decoration: none; +} + +svg { + overflow: hidden; + vertical-align: middle; +} + +template { + display: none; +} + +[hidden] { + display: none !important; +} + +.screen-reader-text, +.sr-only { + display: none; +} + +i { + font-style: normal; +} + +/* -------------------------------------------------------------------------- */ + +/* 2. Element Base +/* ---------------------------------------------*---------------------------- */ + +.h1, +.h2, +.h3, +.h4, +.h5, +.h6, +h1, +h2, +h3, +h4, +h5, +h6 { + font-weight: 500; + margin: 0; +} + +/*-------------------------------------------------------------- +/* 3. title Font Size style +--------------------------------------------------------------*/ + +h1, +.h1, +.heading-size-1 { + font-size: 2rem; + line-height: 1.4; +} + +h2, +.h2, +.heading-size-2 { + font-size: 1.5rem; +} + +h3, +.h3, +.heading-size-3 { + font-size: 1.3125rem; +} + +h4, +.h4, +.heading-size-4 { + font-size: 1.25rem; + line-height: 1.4; +} + +h5, +.h5, +.heading-size-5 { + font-size: 1.25rem; + line-height: 1.4; +} + +h6, +.h6, +.heading-size-6 { + line-height: 1.4; +} + +@media (max-width: 767.98px) { + h1, + .h1, + .heading-size-1 { + font-size: 1.5rem; + } + + h2, + .h2, + .heading-size-2 { + font-size: 1.25rem; + } + + h3, + .h3, + .heading-size-3 { + font-size: 1.125rem; + } + + h4, + .h4, + .heading-size-4 { + font-size: 1rem; + } + + h5, + .h5, + .heading-size-5 { + font-size: 0.9375rem; + } + + h6, + .h6, + .heading-size-6 { + font-size: 0.9375rem; + } +} + +@media (min-width: 768px) and (max-width: 991.98px) { + h1, + .h1, + .heading-size-1 { + font-size: 1.625rem; + } + + h2, + .h2, + .heading-size-2 { + font-size: 1.375rem; + } + + h3, + .h3, + .heading-size-3 { + font-size: 1.125rem; + } + + h4, + .h4, + .heading-size-4 { + font-size: 1rem; + line-height: 1.5; + } + + h5, + .h5, + .heading-size-5 { + font-size: 1rem; + } + + h6, + .h6, + .heading-size-6 { + font-size: 1rem; + } +} + +@media (min-width: 992px) and (max-width: 1199.98px) { + h1, + .h1, + .heading-size-1 { + font-size: 1.75rem; + } + + h2, + .h2, + .heading-size-2 { + font-size: 1.5rem; + } + + h3, + .h3, + .heading-size-3 { + font-size: 1.375rem; + } + + h4, + .h4, + .heading-size-4 { + font-size: 1.25rem; + } + + h5, + .h5, + .heading-size-5 { + font-size: 1.125rem; + } + + h6, + .h6, + .heading-size-6 { + font-size: 1rem; + } +} + +@media (min-width: 1200px) and (max-width: 1399.98px) { + h1, + .h1, + .heading-size-1 { + font-size: 1.75rem; + } + + h2, + .h2, + .heading-size-2 { + font-size: 1.5rem; + } + + h3, + .h3, + .heading-size-3 { + font-size: 1.375rem; + } + + h4, + .h4, + .heading-size-4 { + font-size: 1.25rem; + } + + h5, + .h5, + .heading-size-5 { + font-size: 1.125rem; + } + + h6, + .h6, + .heading-size-6 { + font-size: 1rem; + } +} + +.h4 .small, +.h4 small, +.h5 .small, +.h5 small, +.h6 .small, +.h6 small, +h4 .small, +h4 small, +h5 .small, +h5 small, +h6 .small, +h6 small { + font-size: 85%; +} + +/* Inputs ------------------------------------ */ + +input, +textarea { + border-color: var(--border-light); + color: var(--text-dark); +} + +code, +input[type='url'], +input[type='email'], +input[type='tel'] { + /*rtl:ignore*/ + direction: ltr; +} + +input[type='text'], +input[type='password'], +input[type='email'], +input[type='url'] { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + -webkit-box-shadow: none; + box-shadow: none; + outline: 0; +} + +input[type='date'], +input[type='month'], +input[type='time'], +input[type='datetime'], +input[type='datetime-local'], +input[type='week'], +input[type='number'], +input[type='search'], +input[type='tel'], +input[type='color'], +textarea { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; +} + +input[type='number']::-webkit-outer-spin-button, +input[type='number']::-webkit-inner-spin-button { + -webkit-appearance: none; +} + +textarea { + line-height: 1.5; + width: 100%; +} + +input::-webkit-input-placeholder { + line-height: normal; +} + +input:-ms-input-placeholder { + line-height: normal; +} + +input::-moz-placeholder { + line-height: revert; + /* Reset to the value from the user-agent stylesheets. */ +} + +input[type='search']::-webkit-search-decoration, +input[type='search']::-webkit-search-cancel-button, +input[type='search']::-webkit-search-results-button, +input[type='search']::-webkit-search-results-decoration { + display: none; +} + +button, +button:focus, +button:hover, +.button:focus, +.button:hover { + -webkit-appearance: none; + appearance: none; + outline: none !important; + -webkit-box-shadow: none !important; + box-shadow: none !important; +} + +input[type='button'], +input[type='reset'], +input[type='submit'] { + -webkit-transition: all 0.15s linear; + transition: all 0.15s linear; +} + +button:focus, +button:hover, +.button:focus, +.button:hover, +input[type='button']:focus, +input[type='button']:hover, +input[type='reset']:focus, +input[type='reset']:hover, +input[type='submit']:focus, +input[type='submit']:hover { + text-decoration: none; +} + +input[type='text']:focus, +input[type='email']:focus, +input[type='url']:focus, +input[type='password']:focus, +input[type='number']:focus, +input[type='tel']:focus, +input[type='range']:focus, +input[type='date']:focus, +input[type='month']:focus, +input[type='week']:focus, +input[type='time']:focus, +input[type='datetime']:focus, +input[type='datetime-local']:focus, +input[type='color']:focus, +textarea:focus { + outline: 0; +} + +select { + -webkit-box-shadow: none; + box-shadow: none; + -webkit-transition: opacity 0.15s linear; + transition: opacity 0.15s linear; +} + +textarea { + height: auto; + resize: none; +} + +/* Lists ------------------------------------- */ + +menu, +ul, +ol { + list-style: none; + margin: 0; + padding: 0; +} + +dt, +dd { + line-height: 1.5; +} + +dt { + font-weight: 500; +} + +dt + dd { + margin-top: 0.5rem; +} + +dd + dt { + margin-top: 1.5rem; +} + +/* Quotes ------------------------------------ */ + +blockquote { + padding: 16px 20px; + margin: 24px 0; + background-color: var(--bg-light); + border-radius: var(--radius-sm); +} + +blockquote::before, +blockquote::after { + content: ''; +} + +cite { + color: inherit; + font-size: 85%; + font-style: normal; + font-weight: 500; + line-height: 1.25; +} + +blockquote cite { + display: block; + margin: 32px 0 0 0; +} + +blockquote p, +blockquote > p:last-child { + margin-bottom: 32px; +} + +blockquote p:last-child { + margin: 0; +} + +blockquote em, +blockquote i, +blockquote cite { + font-style: normal; +} + +/* Media ------------------------------------- */ + +figure { + margin: 0; +} + +img, +embed, +iframe, +object, +video { + max-width: 100%; +} + +img { + height: auto; + max-width: 100%; + vertical-align: middle; +} + +/*-------------------------------------------------------------- +/* 5. Size style +--------------------------------------------------------------*/ + +.w-8 { + width: 8px !important; + height: 8px !important; +} + +.w-12 { + width: 12px !important; + height: 12px !important; +} + +.w-16 { + width: 16px !important; + height: 16px !important; +} + +.w-20 { + width: 20px !important; + height: 20px !important; + font-size: 0.6em; +} + +.w-24 { + width: 24px !important; + height: 24px !important; + font-size: 0.7em; +} + +.w-28 { + width: 28px !important; + height: 28px !important; + font-size: 0.8em; +} + +.w-32 { + width: 32px !important; + height: 32px !important; + font-size: 0.85em; +} + +.w-36 { + width: 36px !important; + height: 36px !important; + font-size: 0.875em; +} + +.w-40 { + width: 40px !important; + height: 40px !important; +} + +.w-48 { + width: 48px !important; + height: 48px !important; +} + +.w-56 { + width: 56px !important; + height: 56px !important; +} + +.w-64 { + width: 64px !important; + height: 64px !important; +} + +.w-72 { + width: 72px !important; + height: 72px !important; +} + +.w-80 { + width: 80px; + height: 80px; +} + +.w-96 { + width: 96px; + height: 96px; +} + +.w-128 { + width: 128px; + height: 128px; +} + +.w-168 { + width: 168px; + height: 168px; +} + +.w-192 { + width: 192px; +} + +.w-xs { + width: 90px; +} + +.w-auto { + width: auto; +} + +.h-auto { + height: auto; +} + +.hv { + height: 100vh; +} + +.h-v { + min-height: 100vh; +} + +.h-v-30 { + min-height: 30vh; +} + +.h-v-33 { + min-height: 33vh; +} + +.h-v-50 { + min-height: 50vh; +} + +.h-v-66 { + min-height: 66vh; +} + +.h-v-75 { + min-height: 75vh; +} + +@media (max-width: 1199.98px) { + .w-auto-lg { + width: auto !important; + } + + .w-100-lg { + width: 100% !important; + } +} + +@media (max-width: 991.98px) { + .w-auto-md { + width: auto !important; + } + + .w-100-md { + width: 100% !important; + } +} + +@media (max-width: 767.98px) { + .w-auto-sm { + width: auto !important; + } + + .w-100-sm { + width: 100% !important; + } +} + +@media (max-width: 575.98px) { + .w-auto-xs { + width: auto !important; + } + + .w-100-xs { + width: 100% !important; + } +} + +@media (min-width: 768px) { + .h-v-25 { + min-height: 25vh; + } +} + +.overflow-y { + overflow-x: hidden; + overflow-y: auto; +} + +/*-------------------------------------------------------------- +/* 7. title Font Size style +--------------------------------------------------------------*/ + +.text-xx { + font-size: 0.6875rem !important; +} + +.text-xs { + font-size: 0.75rem !important; +} + +.text-sm { + font-size: 0.875rem !important; +} + +.text-md { + font-size: 0.9375rem !important; +} + +.text-lg { + font-size: 1.125rem !important; +} + +.text-xl { + font-size: 1.625rem !important; +} + +.text-xxl { + font-size: 2.625rem !important; +} + +.text-40 { + font-size: 2.5rem !important; +} + +.text-50 { + font-size: 3.125rem !important; +} + +.text-64 { + font-size: 4rem !important; +} + +@media (max-width: 767.98px) { + .text-xl { + font-size: 1.5rem !important; + } + + .text-lg { + font-size: 1.125rem !important; + } + + .text-md { + font-size: 0.9375rem !important; + } + + .text-sm { + font-size: 0.8125rem !important; + } + + .text-xs { + font-size: 0.6875rem !important; + } + + .text-xx { + font-size: 0.625rem !important; + } +} + +@media (min-width: 768px) and (max-width: 991.98px) { + .text-xl { + font-size: 1.5rem !important; + } + + .text-lg { + font-size: 1.0625rem !important; + } + + .text-md { + font-size: 0.9375rem !important; + } + + .text-sm { + font-size: 0.8125rem !important; + } + + .text-xx { + font-size: 0.6875rem !important; + } +} + +/*-------------------------------------------------------------- +/* 8. title Font Size style +--------------------------------------------------------------*/ + +.text-height-xs { + line-height: 1 !important; +} + +.text-height-sm { + line-height: 1.2 !important; +} + +.text-height-md { + line-height: 1.75 !important; +} + +.text-height-lg { + line-height: 1.85 !important; +} + +.text-height-xl { + line-height: 2 !important; +} + +/* text space style ----------------------------- */ + +.text-space-md { + letter-spacing: 5px; +} + +.text-space-lg { + letter-spacing: 15px; +} + +/* Icon style ----------------------------- */ + +.iconfont { + display: inline-block; + vertical-align: middle; + line-height: normal; +} + +.text-sm .iconfont.text-md, +.text-xs .iconfont.text-md, +.text-xs .iconfont.text-sm, +.text-xx .iconfont.text-sm { + position: relative; + top: -1px; +} + +/*-------------------------------------------------------------- +/* 6. nice-dark-mode style +--------------------------------------------------------------*/ + +.nice-dark-mode code, +.nice-dark-mode pre { + background: var(--night-bg-light); +} + +/* Quotes ------------------------------------ */ + +.nice-dark-mode blockquote { + background-color: var(--night-bg-light); +} diff --git a/src/components/comment/Artalk.astro b/src/components/comment/Artalk.astro new file mode 100644 index 0000000..18d7b85 --- /dev/null +++ b/src/components/comment/Artalk.astro @@ -0,0 +1,22 @@ +--- +import { options } from '@/helpers/schema'; +import 'artalk/dist/ArtalkLite.css'; + +interface Props { + commentKey: string; + title: string; +} + +const { commentKey, title } = Astro.props; +--- + +<div + id="comments" + class="comments py-5" + data-key={commentKey} + data-title={title} + data-server={options.settings.comments.server} + data-site={options.title} +> + 评论正在加载中 ... +</div> diff --git a/src/components/footer/Footer.astro b/src/components/footer/Footer.astro new file mode 100644 index 0000000..c465936 --- /dev/null +++ b/src/components/footer/Footer.astro @@ -0,0 +1,24 @@ +--- +import { DateTime } from 'luxon'; + +import { options } from '@/helpers/schema'; + +function currentYear(): number { + return DateTime.now().setZone(options.settings.timeZone).year; +} +--- + +<footer class="border-top border-light text-xs text-center py-4 py-xl-5"> + Copyright © {options.settings.initialYear}-{currentYear()}{' '} + <a href={import.meta.env.SITE} title={options.title} rel="home"> + {options.title} + </a> + <br /> + { + options.settings.icpNo && ( + <a href="https://beian.miit.gov.cn" rel="nofollow" target="_blank" title={'良民证'}> + {options.settings.icpNo} + </a> + ) + } +</footer> diff --git a/src/components/footer/GoTop.astro b/src/components/footer/GoTop.astro new file mode 100644 index 0000000..d84ee13 --- /dev/null +++ b/src/components/footer/GoTop.astro @@ -0,0 +1,9 @@ +<ul class="site-fixed-widget"> + <li class="fixed-gotop"> + <div class="btn btn-light btn-icon btn-lg btn-rounded btn-gotop"> + <span> + <i class="iconfont icon-arrowup"></i> + </span> + </div> + </li> +</ul> diff --git a/src/components/header/Header.astro b/src/components/header/Header.astro new file mode 100644 index 0000000..7b5dfc1 --- /dev/null +++ b/src/components/header/Header.astro @@ -0,0 +1,69 @@ +--- +import Logo from '@/components/header/Logo.astro'; +import LogoLarge from '@/components/header/LogoLarge.astro'; +import QRDialog from '@/components/image/QRDialog.astro'; +import SearchDialog from '@/components/search/SearchDialog.astro'; +import { options } from '@/helpers/schema'; +--- + +<header class="site-aside"> + <div class="aside-overlay"></div> + <div class="aside-inner bg-secondary"> + <h1 class="navbar-brand"> + <a href={'/'} title={options.title} class="d-block"> + <Logo /> + </a> + </h1> + <div class="site-menu"> + <ul> + { + options.navigation.map((menu, i) => ( + <li id={`menu-item-${i}`} class={`menu-item ${i === 0 ? 'menu-item-home}' : ''}`}> + <a href={menu.link} target={menu.target}> + {menu.text} + </a> + </li> + )) + } + </ul> + </div> + <div class="site-submenu"> + { + options.socials.map((social) => { + if (social.type === 'qrcode') { + return ( + <QRDialog url={social.link} name={social.name} title={social.title ?? social.name} icon={social.icon} /> + ); + } else { + return ( + <a + href={social.link} + target={'_blank'} + title={social.title ?? social.name} + class="btn btn-dark btn-icon btn-circle button-social" + > + <span> + <i class={`iconfont ${social.icon}`} /> + </span> + </a> + ); + } + }) + } + <SearchDialog /> + </div> + </div> +</header> +<div class="mobile-brand"> + <div class="container"> + <div class="d-flex flex-flex align-items-center"> + <a href="/" title={options.title} class="d-block"> + <LogoLarge /> + </a> + <div class="flex-fill"></div> + <div class="menu-toggler text-xl"> + <i class="d-block iconfont icon-menu"></i> + </div> + </div> + </div> +</div> diff --git a/src/components/header/Logo.astro b/src/components/header/Logo.astro new file mode 100644 index 0000000..15da34b --- /dev/null +++ b/src/components/header/Logo.astro @@ -0,0 +1,38 @@ +--- +import { options } from '@/helpers/schema'; +--- + +<svg viewBox="0 0 300 300" xmlns="http://www.w3.org/2000/svg"> + <title>{options.title}</title> + <g id="logo-dark" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> + <g transform="translate(9, 16)"> + <path + d="M94.5479774,134.486962 C99.2907157,133.547617 103.46066,133.627395 107.053294,134.772127 C112.966407,136.656241 115.468525,138.552508 118.527601,142.942864 C120.544778,145.837896 122.197824,150.954965 123.547977,158.269051 C120.480628,159.074879 117.922174,159.051421 115.898234,158.066848 C112.281243,156.307314 108.930013,153.854322 104.030874,148.36204 C100.920908,144.875547 97.7620867,140.249025 94.5479774,134.486962 Z" + id="font1-dot" + fill="#E87777"></path> + <path + d="M46.8422869,43.5778113 L57.1443602,56.2730781 C56.7735605,56.7561572 56.4130622,57.2126612 56.0629838,57.65605 C53.9299254,60.3576629 52.1719261,62.6165475 50.7441559,66.9195388 C50.4502647,67.8052636 50.1677524,68.619931 49.8923919,69.4140528 C49.8314037,69.5899391 49.7724657,69.7599129 49.7128765,69.9321459 L49.4613482,70.662537 L49.2935232,71.1557917 C47.9745439,75.1396843 46.9306321,78.9136477 45.656322,86.4265524 C45.5923165,86.803907 45.5308802,87.1721303 45.4724886,87.5306837 L45.2906471,88.64728 L46.4211204,88.6906833 C46.7672343,88.703972 47.114133,88.7250069 47.4615106,88.7540528 C52.0299366,89.1360406 56.2866289,90.8682914 59.6487574,93.2539327 C63.1178814,95.7154941 65.6686718,98.8706462 66.4517701,101.981914 C68.60611,110.541158 66.0929237,126.783437 64.8127236,135.185752 C64.5866135,136.670182 64.4272962,137.716618 64.3109454,138.547528 C64.2110444,139.260964 64.0963334,140.121689 63.9669251,141.092859 C63.5964104,143.873461 63.1062925,147.552582 62.4974582,151.2603 L62.3501742,152.143769 C62.3063655,152.402519 62.2619748,152.661094 62.2178889,152.914142 L62.0804882,153.690928 C62.0374659,153.930444 61.9945544,154.170039 61.9516883,154.409322 L61.8231614,155.125846 C60.9449348,160.010357 60.0584182,164.599705 58.601916,165.530233 C57.805445,166.039081 57.006599,166.319837 56.1912629,166.319837 C55.6983618,166.319837 55.2058376,166.218051 54.7107569,166.026725 L56.5363189,132.813886 L56.5363189,117.952805 C56.5363189,114.562057 55.0807514,109.453547 52.7326075,105.554166 C50.565461,101.955353 47.6610156,99.5848491 44.6855326,99.494663 C44.0984373,99.4768683 43.5116237,99.5447372 42.930147,99.691674 L42.6597517,101.122219 C42.2390935,103.347296 41.8463033,105.420982 41.4790073,107.360075 C38.7314734,121.865335 37.4066585,128.866917 36.514877,135.348104 L36.4075675,136.141324 L36.2550999,137.317585 C35.7432607,141.37236 35.3633024,145.499053 34.8715413,151.430142 L34.7754348,152.594528 C34.6778039,153.782228 34.5754009,155.041283 34.4664618,156.384181 C32.6370807,178.935067 32.6465327,193.41116 34.4758443,207.817687 C35.1130431,209.059087 35.4505578,209.4473 35.8461893,209.900621 C36.2628642,210.378055 36.7485755,210.934581 37.2492196,211.502852 L37.761254,212.081997 C38.7419113,213.186811 39.7007875,214.234846 40.2442178,214.749187 C57.1310783,230.732128 75.7119052,242.824647 105.765401,247.408667 C109.294776,247.946998 115.268279,248.495676 121.400226,248.890169 L122.660606,248.968948 L123.167339,248.999323 L124.173781,249.057433 C128.498158,249.300705 132.7267,249.451989 136.06598,249.461499 L136.820436,249.461154 C138.665307,249.453887 140.193882,249.398156 141.253804,249.284403 C158.756452,247.405975 178.012994,240.001867 190.196691,231.670191 L197.337908,245.093068 C181.039287,261.625357 151.989795,268.373466 127.523858,266.785601 C92.0463247,264.483072 59.2083357,249.636224 35.737857,225.385271 C13.7492289,202.665446 0,171.691228 0,135.084268 C0,95.9047997 4.92480232,78.9292586 16.5817116,61.5698853 L21.6734002,67.1219286 C22.224218,70.7987853 22.0831216,74.6092097 21.8833807,78.4096352 L21.7935543,80.068187 C21.6331516,82.9993195 21.4826699,85.9161104 21.5886642,88.7610078 L35.1115099,88.7610078 L35.4226052,87.0934405 C36.910092,79.119959 37.7288197,74.7309457 38.3192627,71.7947151 C38.6839117,69.9974911 38.9181738,68.9279254 39.1538244,67.9399317 L39.4405339,66.775326 C39.7212508,65.6782577 39.9575194,64.7967777 40.2489296,63.7094853 C41.5463253,58.868719 44.3586413,49.7909628 46.8422869,43.5778113 Z M33.4110834,99.2447984 C32.9875317,99.2197029 32.5537361,99.2253734 32.1108175,99.2620712 C31.510935,99.3117743 30.9369263,99.4148625 30.3913414,99.5700791 C25.0958359,101.076628 20.0066053,108.547117 16.272319,119.472516 C16.0174749,120.218113 15.7824956,120.88259 15.5482645,121.544999 L15.4289242,121.882749 C14.9704194,123.182325 14.4903225,124.576387 13.6539215,127.394135 C12.5972078,131.724203 11.9030411,138.422974 10.2648489,160.194842 C12.386381,169.475376 15.5860883,178.386831 20.1072374,187.207176 C21.5388579,190.000136 23.3581345,193.292493 25.1007851,196.220048 C25.8298233,197.444791 26.6085805,198.711777 27.3976596,199.960927 C28.1550483,201.15991 28.9313605,202.357364 29.6935857,203.499008 C29.5337319,202.098916 29.3818575,200.706731 29.2377218,199.323244 C29.0890396,197.896117 28.9465076,196.458236 28.8106055,195.010174 C27.142633,177.237618 26.7411971,160.786976 27.6100462,145.658204 C28.4790972,130.525914 30.2433482,115.92831 32.9037595,101.865512 C32.9930459,101.393549 33.083492,100.921394 33.1750978,100.449046 C33.2530331,100.047187 33.331695,99.6457716 33.4110834,99.2447984 Z M89.4808642,58.6801565 C92.0068614,60.3843231 94.7646457,62.2699999 97.7542322,64.3371648 C98.0082141,64.512782 98.2627902,64.6879201 98.5191904,64.8635207 L99.0239121,65.2081815 C101.346591,66.789757 103.575234,68.2464848 104.913699,69.1125503 L104.645529,70.5022078 L99.0735581,92.9668955 C107.177099,82.6114474 114.957818,77.4411893 122.619933,78.2505728 C123.659042,78.3603385 124.689583,78.4765651 125.704588,78.6202666 C126.032424,78.6666807 126.363407,78.712543 126.696954,78.7587574 C127.472499,78.8662125 128.254562,78.9745299 129.035845,79.0953064 L129.55599,79.1776545 C133.416424,79.8043464 137.445859,80.7765026 140.53886,83.8456905 C142.876704,86.1655353 144.634788,89.6681904 145.487457,94.9712293 C146.593454,101.849804 144.235271,113.304222 141.647049,126.076635 L141.534571,126.63173 C141.124865,128.653954 140.7099,130.706676 140.300599,132.779026 L140.028856,134.162543 C136.378889,152.855625 133.478955,172.801947 139.065486,185.579446 C142.741515,193.98725 145.865395,198.847806 148.446217,201.634068 C150.269872,203.60289 151.887994,204.619399 153.276765,205.141938 C155.503681,205.979836 157.247306,205.618131 158.574524,205.303093 C158.881949,205.228586 159.056948,205.170695 159.212486,205.170695 C160.681127,205.170695 163.524778,204.324138 167.729101,202.486963 C168.144678,207.413204 167.853549,211.559155 166.807717,214.918397 C166.490764,215.93646 166.402402,216.521637 165.756928,216.867816 C163.472619,218.09293 160.306731,217.452113 157.278843,216.690243 C152.044493,215.379504 144.939023,213.632045 138.897651,206.294504 C138.304468,205.574054 137.734642,204.888089 137.186589,204.228344 C131.79243,197.734936 128.584983,193.895563 125.971834,184.25501 C124.142417,177.505838 123.524386,172.576467 123.497998,164.345985 L123.497286,163.50831 C123.504175,158.688115 123.6948,152.764096 123.960373,144.828458 C124.418593,131.136286 126.448981,122.108357 127.95961,115.386576 C128.977339,110.858026 129.748333,107.328344 129.748333,104.145054 C129.748333,102.897969 129.91503,101.152569 130.088723,99.3175902 L130.149154,98.6785927 C130.379001,96.2395414 130.591136,93.7302671 130.508028,91.9489684 C130.467268,91.0753466 130.350362,90.3437209 130.173932,89.8038461 C129.805841,88.6774852 129.150822,88.1197233 128.495809,87.8557942 C126.138427,86.9059184 122.674207,87.6321829 118.991273,89.5849052 C114.720749,91.8491721 110.187542,95.5551461 107.434711,98.3185491 C100.842602,104.935973 99.7358106,106.580141 96.9290224,120.905406 C95.1829229,129.817136 93.1830672,156.132114 90.9546315,199.846258 C87.7558456,197.811765 85.423412,195.374821 83.9994149,192.497341 C81.1302113,186.699524 80.1373069,184.598991 78.579987,174.323917 C77.3820022,166.419708 78.014172,155.594277 78.3840357,149.179652 C78.510286,146.989852 78.60257,145.354355 78.60257,144.421556 C78.60257,140.648774 79.211373,130.740662 80.9674434,116.227783 C81.804359,109.311174 82.2813491,105.378398 82.8584727,101.608456 L82.9838112,100.802183 C83.5990451,96.9045868 84.3576676,92.9603216 85.7689204,85.832392 C87.4981236,77.0985643 88.7355384,68.0467944 89.4808642,58.6801565 Z" + id="Down-circle-and-font1" + fill="#FFFFFF"></path> + <path + d="M125.96931,0 C165.244145,0 199.188759,18.6967659 222.566877,46.7852627 C242.044483,70.1873477 255.489726,99.1018141 256.986198,132.847566 C257.617886,147.092255 253.475262,164.752089 249.778592,178.724344 L241.782581,160.287368 C242.142102,159.030178 242.624586,157.42267 243.165601,155.619938 C243.757109,153.648959 244.40736,151.47963 245.046597,149.274558 L245.36469,148.170767 C246.750719,143.330945 248.015661,138.476921 248.372968,135.54866 C249.191574,128.839897 250.276891,109.397269 235.51671,78.7751477 C229.036129,65.330249 212.314365,47.0048462 198.630472,36.4489395 C184.941164,25.8888558 158.303936,18.5677961 131.15276,17.4481574 C105.814941,16.4032964 80.5800412,22.2630952 60.8430882,34.8694163 L56.8577885,21.1396695 C76.8094612,7.46418563 100.610421,0 125.96931,0 Z" + id="Upper-circle" + fill="#FFFFFF"></path> + <path + d="M186.992625,127.949897 C192.185797,128.776084 196.740749,130.94293 200.085937,134.288118 C203.244467,137.446649 205.314771,141.65394 205.834511,146.739889 C206.384415,152.348905 204.936064,157.466847 202.146389,161.810588 C199.064207,166.609784 194.352759,170.465378 188.886854,173.016134 C186.790972,174.030354 184.17215,175.484367 182.282377,174.690964 C181.93939,174.521434 181.676586,174.298397 181.495225,174.036154 C181.301426,173.755924 181.20287,173.434686 181.183291,173.10673 C181.137511,172.339912 181.506314,171.539641 182.153845,171.039222 C183.468941,170.042294 184.824211,169.13691 186.16858,168.238124 C189.99904,165.677246 193.725348,163.152543 196.321816,158.925735 C199.140385,154.057975 199.551295,147.599676 196.920345,142.50754 C194.849421,138.451981 190.824509,136.579032 186.488388,135.971975 C186.089287,135.916101 185.689776,135.871263 185.291244,135.83899 C185.317716,136.232667 185.337391,136.618847 185.350326,136.996544 C185.573874,143.52416 183.96246,152.717552 179.867892,159.513863 C176.918756,164.408946 172.662059,168.072684 166.78035,168.363538 C163.750107,168.543859 161.062809,167.582154 158.987636,165.850722 C156.807138,164.031411 155.303845,161.371002 154.77513,158.312003 C153.230699,150.357067 155.614437,141.572966 161.076979,135.648701 C167.576646,128.762149 177.79698,126.481685 186.992625,127.949897 Z M180.383135,135.633276 C179.968245,135.653552 179.549932,135.684957 179.129408,135.727363 C174.040881,136.240492 169.591248,138.267306 166.39797,141.415608 C163.286957,144.482803 161.356895,148.615929 161.190324,153.488149 C161.138763,155.394962 161.72196,157.715934 162.997962,159.220474 C163.574847,159.900683 164.288243,160.422401 165.136865,160.706532 C165.893594,160.959895 166.763196,161.027651 167.770001,160.817758 C170.485546,160.20457 172.564408,157.647204 174.066709,155.349566 C177.587926,149.863086 179.320045,143.243049 180.219942,136.861961 C180.277448,136.454185 180.331959,136.044532 180.383135,135.633276 Z" + id="font2" + fill="#FFFFFF" + fill-rule="nonzero"></path> + <path + d="M211.943573,193.818182 C212.16928,192.606061 211.717867,192 210.589333,192 L203.411857,192 C202.193041,192 201.786768,192.656566 202.102758,193.919192 C202.599313,195.737374 203.095868,197.858586 203.637564,200.282828 C203.863271,201.444444 204.540391,202 205.578642,202 L208.151699,202 C209.189951,202 209.912212,201.444444 210.228202,200.383838 C210.905322,198.262626 211.447018,196.090909 211.943573,193.818182 Z M202.085158,224.116095 C201.530414,224.07124 201.114355,224.205805 200.883212,224.474934 C199.819951,225.506596 199.172749,226 198.849148,226 L198.664234,225.955145 C197.554745,226 197,225.461741 197,224.430079 L197,210.525066 C197,209.493404 197.554745,209 198.618005,209 L214.428224,209 C215.491484,209 216,209.538259 216,210.569921 L216,224.430079 C216,225.461741 215.445255,226 214.381995,226 L214.289538,225.955145 C213.781022,225.91029 213.364964,225.82058 213.087591,225.596306 C211.839416,224.609499 211.145985,224.116095 211.007299,224.116095 L202.085158,224.116095 Z M235.413994,208.657957 C236.48688,210.695962 237,212.826603 237,215.0962 C237,217.551069 236.393586,219.357482 235.227405,220.515439 C234.014577,221.673397 232.148688,222.229216 229.676385,222.229216 L228.370262,222.229216 C227.344023,222.229216 226.737609,221.766033 226.504373,220.793349 C226.271137,219.68171 226.784257,219.125891 227.950437,219.125891 L228.090379,219.125891 C230.142857,219.125891 231.542274,218.847981 232.335277,218.245843 C233.12828,217.643705 233.501458,216.578385 233.501458,215.049881 C233.501458,211.390736 231.728863,207.916865 228.230321,204.628266 C227.437318,203.840855 227.297376,203.007126 227.810496,202.127078 C229.489796,199.209026 231.029155,196.013064 232.381924,192.631829 C232.848397,191.473872 232.475219,190.871734 231.215743,190.871734 L226.037901,190.871734 C224.965015,190.871734 224.405248,191.381235 224.405248,192.446556 L224.405248,225.425178 C224.405248,226.490499 223.845481,227 222.772595,227 L222.6793,226.953682 C221.559767,227 221,226.444181 221,225.332542 L221,189.62114 C221,188.555819 221.559767,188 222.632653,188 L235.040816,188 C236.020408,188 236.533528,188.416865 236.673469,189.250594 C236.766764,190.130641 236.580175,191.149644 236.113703,192.400238 C234.854227,195.688836 233.408163,198.83848 231.728863,201.849169 C231.215743,202.775534 231.402332,203.609264 232.195335,204.350356 C233.548105,205.647268 234.620991,207.083135 235.413994,208.657957 Z M198.772083,194.713948 C198.496287,193.770686 197.944695,193.276596 197.071341,193.186761 C196.106054,193.096927 195.600428,192.647754 195.46253,191.884161 C195.324632,190.851064 195.876224,190.312057 197.071341,190.312057 L203.414652,190.312057 C204.47187,190.312057 204.977497,189.77305 204.977497,188.739953 L204.977497,187.572104 C204.977497,186.539007 205.529089,186 206.586307,186 L206.90807,186 C207.965288,186 208.51688,186.539007 208.51688,187.572104 L208.51688,188.739953 C208.51688,189.77305 209.068473,190.312057 210.125691,190.312057 L216.974629,190.312057 C217.939915,190.312057 218.491507,190.761229 218.58344,191.614657 C218.675372,192.55792 218.261677,193.096927 217.296391,193.186761 C216.239172,193.276596 215.595648,193.770686 215.365818,194.713948 C214.860192,196.690307 214.308599,198.576832 213.711041,200.328605 C213.343313,201.496454 213.757007,202.080378 214.99809,202.080378 L217.388323,202.080378 C218.399575,202.080378 218.951168,202.529551 218.997134,203.427896 C219.0431,204.460993 218.537474,205 217.388323,205 L196.61168,205 C195.600428,205 195.048836,204.550827 195.00287,203.652482 C194.956904,202.619385 195.46253,202.080378 196.565714,202.080378 L199.04788,202.080378 C200.19703,202.080378 200.65669,201.541371 200.380894,200.463357 C199.875268,198.44208 199.369642,196.510638 198.772083,194.713948 Z M211.403042,222 C212.452471,222 213,221.43662 213,220.356808 L213,213.643192 C213,212.56338 212.452471,212 211.403042,212 L202.596958,212 C201.547529,212 201,212.56338 201,213.643192 L201,220.356808 C201,221.43662 201.547529,222 202.596958,222 L211.403042,222 Z" + id="font3" + fill="#FFFFFF" + fill-rule="nonzero"></path> + <path + d="M257.384704,207.041597 C256.606856,208.420495 257.018658,209.086169 258.528597,208.991073 C261.685741,208.753332 265.025909,208.468043 268.549099,208.135205 C270.013282,207.992561 270.379328,207.421983 269.601481,206.42347 C267.862764,204.141157 266.764626,203 266.261313,203 L260.999406,203 C259.947024,203 259.169177,203.52303 258.665864,204.521542 C258.254062,205.424958 257.796505,206.233278 257.384704,207.041597 Z M247,193.409091 C247,194.454545 247.559068,195 248.630616,195 L273.369384,195 C274.440932,195 275,194.454545 275,193.409091 L275,192.545455 C275,191.5 274.440932,191 273.369384,191 L248.630616,191 C247.559068,191 247,191.5 247,192.545455 L247,193.409091 Z M243.985144,224.66586 C243.477744,225.815981 242.785835,225.90799 241.909417,225.033898 L241.724908,224.803874 C240.986872,224.113801 240.802363,223.239709 241.217509,222.273608 C243.385489,216.845036 244.446416,210.082324 244.446416,201.939467 L244.446416,189.610169 C244.446416,188.552058 244.999943,188 246.06087,188 L277.56578,188 C278.626707,188 279.180234,188.552058 279.180234,189.610169 L279.180234,195.912833 C279.180234,196.970944 278.672834,197.476998 277.611907,197.476998 L249.520413,197.476998 C248.459487,197.476998 247.90596,198.029056 247.90596,199.087167 L247.90596,199.179177 C247.90596,200.237288 248.459487,200.789346 249.520413,200.789346 L278.626707,200.789346 C279.503124,200.789346 280.056651,201.157385 280.195033,201.939467 C280.425669,202.997579 279.872142,203.549637 278.626707,203.549637 L274.198491,203.549637 C272.353401,203.549637 272.076638,204.193705 273.3682,205.527845 C275.259418,207.506053 277.150635,209.484262 278.949597,211.46247 C279.687633,212.290557 279.595379,213.026634 278.718961,213.670702 L278.672834,213.716707 C277.796416,214.31477 277.012253,214.176755 276.320344,213.348668 C275.905199,212.88862 275.490054,212.428571 275.074909,211.968523 C274.336873,211.186441 273.414328,210.818402 272.353401,210.956416 C270.18542,211.186441 268.34033,211.37046 266.910386,211.508475 C265.849459,211.600484 265.295932,212.198547 265.295932,213.256659 L265.295932,214.130751 C265.295932,215.188862 265.849459,215.74092 266.910386,215.74092 L276.689362,215.74092 C277.56578,215.74092 278.07318,216.108959 278.211562,216.845036 C278.442198,217.903148 277.888671,218.455206 276.643235,218.455206 L266.864259,218.455206 C265.803332,218.455206 265.295932,219.007264 265.295932,220.065375 L265.295932,221.583535 C265.295932,222.641646 265.803332,223.193705 266.864259,223.193705 L279.364743,223.193705 C280.333415,223.193705 280.840815,223.561743 280.979196,224.343826 C281.117578,225.447942 280.564051,226 279.364743,226 L247.39856,226 C246.476015,225.953995 245.968615,225.539952 245.830233,224.757869 C245.645724,223.699758 246.153124,223.193705 247.39856,223.193705 L260.175808,223.193705 C261.236734,223.193705 261.790261,222.641646 261.790261,221.583535 L261.790261,220.065375 C261.790261,219.007264 261.236734,218.455206 260.175808,218.455206 L250.396831,218.455206 C249.520413,218.455206 249.013014,218.087167 248.874632,217.35109 C248.643996,216.292978 249.197523,215.74092 250.442958,215.74092 L260.221935,215.74092 C261.282862,215.74092 261.790261,215.188862 261.790261,214.130751 L261.790261,213.532688 C261.790261,212.474576 261.236734,211.968523 260.175808,212.014528 C256.762391,212.244552 253.579611,212.428571 250.627467,212.520581 C249.75105,212.566586 249.197523,212.198547 248.966886,211.416465 C248.73625,210.358354 249.24365,209.806295 250.489085,209.760291 C250.350704,209.760291 250.535213,209.760291 251.042612,209.714286 C252.195794,209.668281 253.026084,209.208232 253.533484,208.288136 C254.087011,207.368039 254.640538,206.401937 255.194065,205.389831 C255.885974,204.1477 255.516956,203.549637 254.133138,203.549637 L249.520413,203.549637 C248.459487,203.549637 247.952087,204.193705 247.90596,205.48184 C247.767578,212.88862 246.429888,219.283293 243.985144,224.66586 Z" + id="font4" + fill="#FFFFFF" + fill-rule="nonzero"></path> + </g> + </g> +</svg> diff --git a/src/components/header/LogoLarge.astro b/src/components/header/LogoLarge.astro new file mode 100644 index 0000000..de60066 --- /dev/null +++ b/src/components/header/LogoLarge.astro @@ -0,0 +1,52 @@ +--- +import { options } from '@/helpers/schema'; +--- + +<svg viewBox="0 0 1237 300" xmlns="http://www.w3.org/2000/svg"> + <title>{options.title}</title> + <g id="logo-large" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> + <g id="logo-white" transform="translate(20, 15)"> + <path + d="M95.5479774,135.486962 C100.290716,134.547617 104.46066,134.627395 108.053294,135.772127 C113.966407,137.656241 116.468525,139.552508 119.527601,143.942864 C121.544778,146.837896 123.197824,151.954965 124.547977,159.269051 C121.480628,160.074879 118.922174,160.051421 116.898234,159.066848 C113.281243,157.307314 109.930013,154.854322 105.030874,149.36204 C101.920908,145.875547 98.7620867,141.249025 95.5479774,135.486962 Z" + id="font1-dot" + fill="#E87777"></path> + <path + d="M47.5587025,42.6413499 L59.4150545,57.2519576 C58.8684637,57.9832966 58.3430156,58.6485661 57.8388914,59.2870617 C55.7842658,61.889336 54.0749685,64.0703301 52.6932724,68.234464 C52.3972743,69.1265385 52.1127855,69.9469062 51.8354808,70.7466353 C51.7762919,70.9173323 51.7174272,71.0870945 51.6583785,71.2577622 L51.4080304,71.9847059 L51.2428469,72.4700919 C51.2170703,72.5463221 51.1913289,72.6226961 51.1656192,72.6992573 L51.0117106,73.1612194 C49.9365927,76.4155491 48.9042374,80.1534684 47.6422403,87.5937801 C47.5786111,87.9689161 47.5175344,88.3349742 47.4594861,88.6914196 C47.8205566,88.7052825 48.1824457,88.7272292 48.5448346,88.7575303 C53.2985413,89.1550102 57.7287004,90.9558044 61.2274422,93.4383815 C64.9191616,96.0578882 67.5904277,99.4358643 68.421524,102.73783 C70.6242525,111.489322 68.0433783,128.18177 66.7604391,136.604682 C66.5760113,137.81551 66.4172222,138.858235 66.3012834,139.686204 C66.2016412,140.397791 66.0872369,141.256287 65.9581638,142.224941 C65.5876098,145.005838 65.0955267,148.699702 64.4838444,152.424745 L64.3361424,153.310702 C64.2920666,153.57103 64.247405,153.831182 64.202602,154.088327 L64.0647364,154.867719 C63.0203572,160.682068 61.8345775,166.290495 60.1402991,167.372933 C59.1659482,167.995425 58.1852887,168.319837 57.1912629,168.319837 C56.356509,168.319837 55.5191232,168.092016 54.6748194,167.653082 L56.5363189,133.786424 L56.5363189,118.952805 C56.5363189,115.701061 55.1263855,110.807176 52.875941,107.070037 C50.9302372,103.838957 48.3629758,101.576275 45.6552368,101.494204 C45.3655232,101.485423 45.0759031,101.501657 44.7872246,101.541493 C44.7393205,101.794983 44.6910298,102.05047 44.6423463,102.307982 C44.2216556,104.533231 43.8288356,106.607074 43.4615123,108.546312 C40.7188824,123.025681 39.3957424,130.014727 38.5058473,136.482186 L38.3992705,137.269874 L38.2472267,138.442822 C37.7369337,142.485349 37.3583969,146.599603 36.8681523,152.512401 L36.7720733,153.676454 C36.6744698,154.863818 36.5720959,156.122519 36.4631876,157.465038 C34.6411838,179.924984 34.6459097,194.343019 36.4678788,208.691721 C36.9300999,209.475926 37.2387054,209.829551 37.5996095,210.243082 C38.0153708,210.719468 38.5000146,211.274777 38.9984015,211.840487 L39.5091338,212.418163 C40.4663724,213.496594 41.4011441,214.52083 41.9316193,215.02291 C58.6803665,230.87513 77.107296,242.87339 106.916185,247.4201 C110.425997,247.955447 116.366501,248.499928 122.462612,248.892117 L123.720445,248.97074 L124.224982,249.000986 L125.229948,249.059012 C132.313319,249.457494 139.137562,249.613103 142.147095,249.290113 C159.931881,247.381405 179.547613,239.71767 191.550191,231.205553 L199.563204,246.267087 C183.184311,263.364504 153.471394,270.406826 128.459093,268.783502 C92.7267899,266.464438 59.6570672,251.504543 36.0192817,227.08072 C13.8613092,204.185919 0,172.974912 0,136.084268 C0,95.8042617 5.20678585,78.8281994 17.4643391,60.9623736 L23.615165,67.669314 C24.2300789,71.5053875 24.0908298,75.4888077 23.8819173,79.4637156 L23.7920604,81.122829 C23.6513999,83.6931991 23.5176088,86.2524312 23.5617746,88.7610078 L35.2808135,88.7610078 C36.8707631,80.2385778 37.7272242,75.6393315 38.3392315,72.595871 C38.7070171,70.7831879 38.9434241,69.7044519 39.1828249,68.7008499 L39.4717463,67.5274334 C39.7538699,66.424868 39.9912408,65.5392748 40.2842693,64.4459443 C41.7014155,59.1583721 44.9207598,48.8335215 47.5587025,42.6413499 Z M33.1933892,101.258656 C32.6602145,101.302832 32.1499254,101.393947 31.6649787,101.531912 C26.5554184,102.98556 21.7915951,110.342352 18.2185718,120.795944 C17.9620284,121.546513 17.7255344,122.215274 17.4910581,122.878375 C16.9981658,124.272281 16.5141151,125.64148 15.8650618,127.709854 L15.829353,127.840121 L15.7588677,128.104027 C15.736272,128.190143 15.7138608,128.277058 15.691622,128.364886 L15.6254108,128.631218 C14.5739206,132.939882 13.8917852,139.607142 12.2397013,160.97199 C14.3429123,170.17238 17.5150377,179.006857 21.9971411,187.751028 C23.4199733,190.526842 25.2281179,193.798969 26.9600704,196.708551 C27.6847124,197.925909 28.4587844,199.185248 29.243105,200.426866 C29.0940719,198.99637 28.9512035,197.555095 28.8149806,196.103615 C27.1419104,178.276741 26.7401892,161.775833 27.6116912,146.600868 C28.4832942,131.424144 30.2529663,116.783711 32.9211878,102.679629 C33.0107582,102.206164 33.101492,101.732507 33.1933892,101.258656 Z M89.6136343,57.8915456 C92.5207218,59.8413435 95.757162,62.0490497 99.322968,64.5146446 C99.5757265,64.6894158 99.8290763,64.86371 100.083123,65.0376999 L100.586746,65.3816115 C103.270392,67.2089793 105.82809,68.8691087 107.023588,69.638714 L107.12174,69.7013171 L106.622439,71.7174649 L102.10112,89.9462065 C109.509279,81.503201 116.693566,77.5133458 123.724983,78.2561059 C124.775931,78.3671222 125.818198,78.4848018 126.844767,78.6301404 C127.171633,78.6764172 127.501638,78.7221424 127.834197,78.76822 C128.609894,78.8756963 129.399629,78.9850773 130.192229,79.1076101 L130.71623,79.1905763 C134.779202,79.8501476 138.995024,80.9126593 142.243229,84.1358564 C144.698067,86.5717944 146.577854,90.2342165 147.474776,95.8124796 C148.609211,102.867923 146.177747,114.685842 143.514658,127.830297 C143.105273,129.850941 142.690629,131.902058 142.28185,133.971759 L142.010322,135.354182 C138.404784,153.81972 135.457943,173.544833 140.981739,186.178845 C144.591197,194.434389 147.644971,199.21786 150.179853,201.954525 C151.861791,203.77035 153.346236,204.723374 154.628922,205.205997 C156.612445,205.952316 158.163845,205.610158 159.338985,205.331228 C159.673711,205.251778 159.963177,205.170695 160.212486,205.170695 C161.760061,205.170695 164.889188,204.145311 169.591406,202.006587 C170.203583,207.704116 169.937427,212.441799 168.762515,216.215654 C168.325303,217.619989 168.08318,218.291265 167.229562,218.749075 C164.759118,220.074016 161.33865,219.491314 158.035932,218.660292 C152.718798,217.328664 145.375426,215.520784 139.125653,207.930129 C138.533436,207.210851 137.964535,206.526006 137.417377,205.867339 C131.943189,199.277525 128.676537,195.366456 126.006663,185.516627 C124.153503,178.679862 123.524735,173.686814 123.497999,165.346832 L123.497287,164.50688 C123.504188,159.678426 123.694904,153.744251 123.960932,145.795011 C124.422298,132.008836 126.466077,122.921303 127.986504,116.155919 C128.981823,111.727089 129.748333,108.266902 129.748333,105.145054 C129.748333,103.873678 129.916089,102.094153 130.093165,100.223439 L130.153565,99.584772 C130.378609,97.1966866 130.590493,94.7398056 130.509114,92.9955736 C130.473414,92.2303984 130.378088,91.5878183 130.223402,91.114477 C129.978656,90.3655563 129.565766,89.9621099 129.122071,89.7833286 C126.960478,88.912343 123.797914,89.6984588 120.45971,91.4684019 C116.277113,93.6860491 111.839157,97.3179607 109.143171,100.024299 C102.702707,106.489496 101.650463,108.11278 98.9103631,122.097683 C97.1454746,131.105308 95.1275565,157.925005 92.8695504,202.554835 C88.7417121,200.249882 85.8091381,197.388161 84.1031585,193.940877 C81.1874766,188.049141 80.173945,185.916077 78.5912785,175.473769 C77.3777356,167.466909 78.0187398,156.486894 78.390954,150.030858 C78.5104167,147.958784 78.60257,146.343082 78.60257,145.421556 C78.60257,141.632745 79.2111322,131.682372 80.9746846,117.107659 C81.813388,110.176274 82.2916314,106.235131 82.8703415,102.454843 L82.9960414,101.646264 C83.6128469,97.7387114 84.3731033,93.7843163 85.7879622,86.638173 C87.6146854,77.4117928 88.8900495,67.8290721 89.6136343,57.8915456 Z" + id="Down-circle-and-font1" + fill="#263148"></path> + <path + d="M126.96931,0 C166.552949,0 200.771355,18.8335538 224.335488,47.1455462 C243.947772,70.709445 257.478475,99.8259352 258.985217,133.803264 C259.663652,149.102117 254.884757,168.318925 251.00421,182.757848 L241.723032,161.357573 C242.093055,160.04666 242.618858,158.294937 243.215109,156.308153 C245.15965,149.828693 247.837278,140.878045 248.380331,136.427538 C249.191142,129.782654 250.230593,110.529648 235.615894,80.2093501 C229.18805,66.8738608 212.590335,48.7092842 199.019677,38.2407285 C185.446312,27.7700842 159.021567,20.5570019 132.111557,19.4473082 C106.501884,18.3912368 80.9927614,24.4350512 61.2580024,37.4410355 L56.6964273,21.7259635 C76.9325749,7.67716119 101.149514,0 126.96931,0 Z" + id="Upper-circle" + fill="#263148"></path> + <path + d="M154.78974,159.482317 C155.90974,165.962317 161.10974,170.762317 167.82974,170.362317 C182.38974,169.642317 187.74974,149.642317 187.34974,137.962317 C191.34974,138.522317 195.10974,140.202317 197.02974,143.962317 C199.50974,148.762317 199.10974,154.842317 196.46974,159.402317 C193.02974,165.002317 187.50974,167.482317 182.54974,171.242317 C180.78974,172.602317 180.54974,175.482317 182.86974,176.602317 C185.10974,177.562317 188.30974,175.882317 190.30974,174.922317 C201.10974,169.882317 209.02974,159.882317 207.82974,147.642317 C206.70974,136.682317 198.70974,129.642317 188.14974,127.962317 C178.62974,126.442317 168.06974,128.842317 161.34974,135.962317 C155.66974,142.122317 153.18974,151.242317 154.78974,159.482317 Z M163.18974,154.522317 C163.50974,145.162317 170.70974,138.682317 180.22974,137.722317 C179.34974,143.962317 177.66974,150.442317 174.22974,155.802317 C172.86974,157.882317 171.02974,160.282317 168.54974,160.842317 C164.70974,161.642317 163.10974,157.482317 163.18974,154.522317 Z" + id="font2" + fill="#263148" + fill-rule="nonzero"></path> + <path + d="M210.72574,196.794317 C210.96574,195.786317 210.53374,195.258317 209.47774,195.258317 L204.82174,195.258317 C203.71774,195.258317 203.28574,195.786317 203.57374,196.842317 C204.00574,198.522317 204.43774,200.106317 204.77374,201.594317 C204.96574,202.554317 205.54174,203.034317 206.50174,203.034317 L207.60574,203.034317 C208.56574,203.034317 209.18974,202.602317 209.47774,201.690317 C209.95774,200.106317 210.38974,198.474317 210.72574,196.794317 Z M204.19774,227.754317 C203.71774,227.706317 203.33374,227.850317 203.09374,228.090317 C202.18174,229.002317 201.60574,229.482317 201.36574,229.482317 L198.10174,229.482317 C197.09374,229.482317 196.61374,229.002317 196.61374,227.994317 L196.61374,212.490317 C196.61374,211.578317 197.09374,211.098317 198.05374,211.098317 L216.14974,211.098317 C217.06174,211.098317 217.54174,211.578317 217.54174,212.490317 L217.54174,228.042317 C217.54174,229.002317 217.06174,229.482317 216.10174,229.482317 L213.17374,229.482317 C212.74174,229.434317 212.35774,229.338317 212.11774,229.146317 C211.01374,228.234317 210.38974,227.754317 210.24574,227.754317 L204.19774,227.754317 Z M237.36574,210.330317 C238.27774,212.346317 238.70974,214.410317 238.70974,216.522317 C238.70974,219.450317 238.13374,221.562317 236.98174,222.810317 C235.82974,224.058317 234.00574,224.682317 231.46174,224.682317 L229.92574,224.682317 C228.96574,224.682317 228.38974,224.250317 228.19774,223.338317 L227.71774,220.938317 C227.47774,219.930317 227.90974,219.450317 228.96574,219.402317 C230.40574,219.354317 231.36574,219.162317 231.89374,218.730317 C232.42174,218.298317 232.70974,217.434317 232.70974,216.138317 C232.70974,213.114317 231.17374,209.898317 228.10174,206.394317 C227.47774,205.674317 227.33374,204.906317 227.76574,204.042317 C229.25374,201.210317 230.59774,198.042317 231.74974,194.586317 C232.08574,193.530317 231.65374,193.002317 230.50174,193.002317 L228.00574,193.002317 C227.04574,193.002317 226.56574,193.482317 226.56574,194.394317 L226.56574,228.042317 C226.56574,229.002317 226.08574,229.482317 225.12574,229.482317 L222.10174,229.482317 C221.09374,229.482317 220.61374,229.002317 220.61374,227.994317 L220.61374,189.594317 C220.61374,188.634317 221.09374,188.154317 222.05374,188.154317 L236.88574,188.154317 C237.84574,188.154317 238.32574,188.634317 238.32574,189.546317 L238.32574,191.562317 C238.32574,192.570317 238.18174,193.482317 237.89374,194.394317 C236.83774,197.706317 235.58974,200.874317 234.14974,203.802317 C233.71774,204.618317 233.86174,205.386317 234.53374,206.106317 C235.68574,207.354317 236.64574,208.746317 237.36574,210.330317 Z M197.81374,196.650317 C197.62174,195.930317 197.18974,195.450317 196.56574,195.306317 C195.60574,195.066317 195.12574,194.586317 195.12574,193.818317 L195.12574,191.706317 C195.12574,190.746317 195.60574,190.266317 196.56574,190.266317 L202.18174,190.266317 C203.14174,190.266317 203.62174,189.786317 203.62174,188.826317 L203.62174,187.626317 C203.62174,186.666317 204.10174,186.186317 205.06174,186.186317 L208.46974,186.186317 C209.38174,186.186317 209.86174,186.666317 209.86174,187.626317 L209.86174,188.826317 C209.86174,189.786317 210.34174,190.266317 211.30174,190.266317 L217.30174,190.266317 C218.26174,190.266317 218.74174,190.746317 218.74174,191.706317 L218.74174,193.818317 C218.74174,194.490317 218.50174,194.922317 218.02174,195.114317 C217.01374,195.546317 216.43774,196.074317 216.29374,196.650317 C215.95774,198.234317 215.52574,199.818317 215.04574,201.402317 C214.70974,202.506317 215.14174,203.034317 216.29374,203.034317 L217.78174,203.034317 C218.74174,203.034317 219.22174,203.514317 219.22174,204.474317 L219.22174,206.778317 C219.22174,207.738317 218.74174,208.218317 217.78174,208.218317 L196.08574,208.218317 C195.17374,208.218317 194.69374,207.738317 194.69374,206.778317 L194.69374,204.474317 C194.69374,203.514317 195.17374,203.034317 196.08574,203.034317 L197.81374,203.034317 C198.91774,203.034317 199.30174,202.506317 199.06174,201.450317 C198.67774,199.914317 198.24574,198.330317 197.81374,196.650317 Z M210.24574,222.954317 C211.20574,222.954317 211.68574,222.474317 211.68574,221.514317 L211.68574,217.530317 C211.68574,216.618317 211.20574,216.138317 210.24574,216.138317 L204.19774,216.138317 C203.23774,216.138317 202.75774,216.618317 202.75774,217.578317 L202.75774,221.562317 C202.75774,222.474317 203.23774,222.954317 204.19774,222.954317 L210.24574,222.954317 Z" + id="font3" + fill="#263148" + fill-rule="nonzero"></path> + <path + d="M269.68574,209.658317 C271.36574,209.514317 271.65374,208.794317 270.54974,207.498317 C258.88574,193.914317 258.11774,193.098317 268.34174,204.954317 C269.20574,205.962317 268.67774,206.442317 266.80574,206.442317 L263.87774,206.442317 C262.91774,206.442317 262.19774,206.874317 261.76574,207.690317 C260.90174,209.370317 260.80574,209.562317 261.47774,208.266317 C260.75774,209.658317 261.18974,210.282317 262.72574,210.186317 C265.17374,209.994317 267.52574,209.802317 269.68574,209.658317 Z M252.02174,215.274317 C251.06174,215.322317 250.53374,214.842317 250.48574,213.882317 L250.38974,212.202317 C250.34174,211.290317 250.77374,210.762317 251.73374,210.714317 C251.82974,210.714317 251.92574,210.714317 252.02174,210.714317 C253.17374,210.666317 253.22174,210.666317 252.21374,210.714317 C253.17374,210.666317 253.89374,210.234317 254.37374,209.418317 C254.51774,209.226317 254.70974,208.842317 255.04574,208.266317 C255.71774,207.066317 255.33374,206.442317 253.94174,206.442317 L251.06174,206.442317 C250.10174,206.442317 249.62174,206.922317 249.62174,207.882317 C249.52574,213.306317 248.80574,218.154317 247.41374,222.330317 C247.02974,223.482317 247.46174,224.058317 248.66174,224.058317 L260.46974,224.058317 C261.38174,224.058317 261.86174,223.674317 261.90974,222.858317 C261.95774,221.898317 261.47774,221.418317 260.46974,221.418317 L251.58974,221.418317 C250.62974,221.418317 250.14974,220.938317 250.14974,219.978317 L250.14974,218.490317 C250.14974,217.530317 250.62974,217.050317 251.58974,217.050317 L260.46974,217.050317 C261.18974,217.050317 261.66974,216.762317 261.81374,216.234317 C262.14974,215.226317 261.66974,214.794317 260.42174,214.842317 C257.58974,215.034317 254.75774,215.178317 252.02174,215.274317 Z M251.06174,195.402317 L273.76574,195.402317 C274.58174,195.402317 275.06174,195.018317 275.15774,194.250317 C275.25374,193.290317 274.77374,192.810317 273.71774,192.810317 L251.01374,192.810317 C250.00574,192.810317 249.52574,193.290317 249.62174,194.250317 C249.71774,195.018317 250.19774,195.402317 251.06174,195.402317 Z M281.49374,212.346317 C282.11774,213.162317 281.97374,213.786317 281.06174,214.314317 L278.85374,215.562317 C277.98974,216.042317 277.26974,215.898317 276.69374,215.130317 C276.93374,215.466317 276.83774,215.274317 276.35774,214.650317 C275.78174,213.882317 275.01374,213.546317 274.00574,213.642317 C272.51774,213.786317 271.07774,213.930317 269.63774,214.074317 C268.72574,214.170317 268.24574,214.698317 268.19774,215.610317 C268.14974,216.570317 268.62974,217.050317 269.58974,217.050317 L279.04574,217.050317 C279.95774,217.050317 280.43774,217.530317 280.43774,218.490317 L280.43774,219.978317 C280.43774,220.938317 279.95774,221.418317 279.04574,221.418317 L269.58974,221.418317 C268.72574,221.418317 268.24574,221.802317 268.19774,222.618317 C268.14974,223.578317 268.62974,224.058317 269.63774,224.058317 L281.58974,224.058317 C282.54974,224.058317 283.02974,224.538317 283.02974,225.450317 L283.02974,227.418317 C283.02974,228.378317 282.54974,228.858317 281.63774,228.858317 L249.42974,228.810317 C246.11774,228.810317 244.34174,228.954317 244.19774,229.242317 C244.29374,229.050317 244.38974,228.906317 244.43774,228.810317 C244.19774,229.194317 243.71774,228.906317 242.99774,227.994317 L240.74174,225.306317 C240.16574,224.586317 240.06974,223.818317 240.45374,222.906317 C241.50974,220.506317 242.27774,217.914317 242.80574,215.178317 C243.38174,211.914317 243.66974,207.642317 243.66974,202.410317 L243.66974,189.594317 C243.66974,188.634317 244.14974,188.154317 245.06174,188.154317 L279.95774,188.154317 C280.86974,188.154317 281.34974,188.634317 281.34974,189.594317 L281.34974,198.282317 C281.34974,199.242317 280.86974,199.722317 279.90974,199.722317 L251.01374,199.722317 C250.34174,199.722317 249.90974,199.962317 249.71774,200.490317 C249.38174,201.450317 249.81374,201.930317 251.06174,201.930317 L280.91774,201.930317 C281.87774,201.930317 282.35774,202.410317 282.35774,203.370317 L282.35774,205.050317 C282.35774,205.962317 281.87774,206.442317 280.96574,206.442317 L279.52574,206.442317 C277.65374,206.442317 277.31774,207.162317 278.51774,208.602317 C279.57374,209.898317 280.58174,211.146317 281.49374,212.346317 Z" + id="font4" + fill="#263148" + fill-rule="nonzero"></path> + </g> + <g id="title" transform="translate(365, 40)" fill="#263148" fill-rule="nonzero"> + <path + d="M49.7786196,143.857143 C44.7400831,143.857143 42.3303482,146.274725 42.3303482,151.32967 L42.3303482,179.241758 C42.3303482,184.296703 44.7400831,186.934066 49.7786196,186.934066 L142.005745,186.934066 C147.044282,186.934066 149.673083,184.516484 149.673083,179.461538 L149.673083,151.549451 C149.673083,146.494505 147.044282,143.857143 142.005745,143.857143 L49.7786196,143.857143 Z M49.7786196,89.1318681 C44.7400831,89.1318681 42.3303482,91.5494505 42.3303482,96.6043956 L42.3303482,122.098901 C42.3303482,127.153846 44.7400831,129.791209 49.7786196,129.791209 L142.005745,129.791209 C147.044282,129.791209 149.673083,127.373626 149.673083,122.318681 L149.673083,96.8241758 C149.673083,91.7692308 147.044282,89.1318681 142.005745,89.1318681 L49.7786196,89.1318681 Z M42.3303482,67.5934066 C42.3303482,72.6483516 44.7400831,75.2857143 49.7786196,75.2857143 L142.005745,75.2857143 C147.044282,75.2857143 149.673083,72.6483516 149.673083,67.5934066 L149.673083,42.978022 C149.673083,37.9230769 147.263348,35.2857143 142.224812,35.2857143 L49.9976865,35.2857143 C44.9591499,35.2857143 42.3303482,37.9230769 42.3303482,42.978022 L42.3303482,67.5934066 Z M184.285639,201 L7.49872602,201 C2.89832309,200.78022 0.488588219,198.582418 0.0504546065,194.406593 C-0.387679006,189.351648 2.02205586,186.934066 7.49872602,186.934066 L17.7948659,186.934066 C22.8334025,186.934066 25.4622041,184.296703 25.4622041,179.241758 L25.4622041,28.6923077 C25.4622041,23.6373626 28.0910058,21 33.1295424,21 L158.873889,21 C163.912426,21 166.541227,23.6373626 166.541227,28.6923077 L166.541227,179.241758 C166.541227,184.296703 168.950962,186.934066 173.989499,186.934066 L184.285639,186.934066 C189.762309,186.934066 192.391111,189.351648 191.952977,194.406593 C191.514843,198.582418 188.886042,200.78022 184.285639,201 Z" + id="Shape"></path> + <path + d="M240.493056,151.997823 C240.493056,157.067415 243.131944,159.712419 248.189815,159.712419 L260.724537,159.712419 C265.782407,159.712419 268.421296,157.067415 268.421296,151.997823 L268.421296,49.06306 C268.421296,43.9934679 265.782407,41.5688803 260.724537,41.5688803 L248.189815,41.5688803 C243.131944,41.5688803 240.493056,43.9934679 240.493056,49.06306 L240.493056,151.997823 Z M302.287037,118.494431 C305.585648,98.8773135 307.344907,72.4272674 307.564815,38.9238757 C307.564815,33.8542836 310.203704,30.9888619 315.261574,30.5480278 C345.388889,28.1234402 371.118056,24.1559333 392.449074,18.42509 C397.506944,17.1025877 400.585648,18.8659241 402.125,23.7150992 L402.125,23.9355163 C403.664352,29.0051084 401.905093,32.0909472 396.847222,33.4134495 C378.375,38.4830416 356.384259,42.0097144 331.094907,44.434302 C326.037037,44.8751361 323.398148,47.7405577 323.178241,52.8101499 C322.958333,60.9655808 322.958333,67.5780923 322.738426,73.0885185 C322.518519,78.1581107 324.9375,80.8031153 330.215278,80.8031153 L406.303241,80.8031153 C411.361111,80.8031153 414,83.2277029 414,88.297295 C414,93.3668872 411.361111,96.0118918 406.303241,96.0118918 L392.888889,96.0118918 C387.831019,96.0118918 385.19213,98.4364794 385.19213,103.506072 L385.19213,198.50582 C385.19213,203.575412 382.553241,206 377.49537,206 L376.175926,205.779583 C370.898148,206 368.259259,203.354995 368.259259,198.064986 L368.259259,103.506072 C368.259259,98.4364794 365.62037,96.0118918 360.5625,96.0118918 L328.895833,96.0118918 C323.837963,96.0118918 320.979167,98.6568964 320.539352,103.726489 C318.12037,126.429445 314.162037,144.72406 308.664352,159.051168 C303.386574,172.717025 295.689815,185.280797 285.574074,196.962901 C282.275463,200.930408 278.756944,201.150825 274.798611,197.403735 L274.358796,196.742484 C270.62037,193.436228 270.180556,189.909555 273.479167,186.162465 C275.018519,184.178712 275.898148,183.076627 275.898148,183.076627 C280.516204,177.125366 278.976852,174.039528 271.280093,174.039528 L248.189815,174.039528 C243.131944,174.039528 240.493056,176.684532 240.493056,181.754124 L240.493056,183.076627 C240.493056,188.146219 237.854167,190.791224 232.796296,190.791224 L231.476852,190.791224 C226.418981,190.791224 224,188.366636 224,183.297044 L224,34.5155347 C224,29.4459426 226.638889,26.8009379 231.696759,26.8009379 L276.997685,26.8009379 C282.055556,26.8009379 284.694444,29.4459426 284.694444,34.5155347 L284.694444,153.320325 C284.694444,166.986182 287.333333,167.647433 292.391204,155.304078 C296.569444,144.503643 299.868056,132.380705 302.287037,118.494431 Z" + id="Shape"></path> + <path + d="M524.749145,47.6933333 C522.32041,48.3422222 517.5439,49.3966667 510.419612,50.8566667 C503.295325,52.3166667 498.842645,53.0466667 497.061574,53.0466667 C495.118586,53.0466667 491.880274,51.9922222 487.346636,49.8833333 C482.812999,47.7744444 480.54618,45.9088889 480.54618,44.2866667 C480.54618,42.6644444 483.217788,41.8533333 488.561003,41.8533333 C499.40935,41.6911111 511.067275,40.7988889 523.534778,39.1766667 C524.020525,38.8522222 524.263398,35.2833333 524.263398,28.47 C524.263398,24.4144444 522.7252,19.345 519.648803,13.2616667 C516.572406,7.17833333 515.034208,3.89333333 515.034208,3.40666667 C515.034208,1.13555556 517.5439,0 522.563284,0 C527.906499,0 533.330673,1.90611111 538.835804,5.71833333 C544.340935,9.53055556 547.093501,13.9511111 547.093501,18.98 C547.093501,20.9266667 546.769669,23.9277778 546.122007,27.9833333 C545.474344,32.0388889 545.150513,35.04 545.150513,36.9866667 C556.808438,35.8511111 564.094641,34.7155556 567.009122,33.58 C567.656784,33.4177778 569.437856,32.5255556 572.352338,30.9033333 C575.266819,29.2811111 577.371722,28.47 578.667047,28.47 C581.581528,28.47 586.31756,31.1061111 592.875143,36.3783333 C599.432725,41.6505556 602.711517,45.6655556 602.711517,48.4233333 C602.711517,50.0455556 600.849487,52.7222222 597.125428,56.4533333 C610.564424,53.8577778 618.49829,52.56 620.927024,52.56 C624.651083,52.56 629.427594,54.2633333 635.256556,57.67 C641.085519,61.0766667 644,64.4022222 644,67.6466667 C644,69.9177778 642.623717,71.0533333 639.871152,71.0533333 C638.413911,71.0533333 636.875713,70.8911111 635.256556,70.5666667 C633.6374,70.2422222 631.815849,69.7961111 629.791904,69.2283333 C627.767959,68.6605556 626.270239,68.2955556 625.298746,68.1333333 C615.259977,66.1866667 604.81642,65.2133333 593.968073,65.2133333 C592.510832,65.2133333 590.608324,66.7138889 588.260547,69.715 C585.912771,72.7161111 583.645952,76.0416667 581.460091,79.6916667 C579.27423,83.3416667 576.481186,86.6672222 573.080958,89.6683333 C569.68073,92.6694444 566.199544,94.17 562.6374,94.17 C561.503991,94.17 559.884835,93.9266667 557.779932,93.44 C555.675029,92.9533333 554.217788,92.71 553.40821,92.71 L545.63626,92.71 C543.855188,92.71 542.883694,94.6161111 542.721779,98.4283333 C542.559863,102.240556 542.640821,105.201111 542.964652,107.31 C551.54618,106.012222 556.484607,105.201111 557.779932,104.876667 C558.913341,104.552222 560.653934,103.984444 563.00171,103.173333 C565.349487,102.362222 567.494869,101.713333 569.437856,101.226667 C571.380844,100.74 573.161916,100.496667 574.781072,100.496667 C577.695553,100.496667 581.379133,101.429444 585.831813,103.295 C590.284493,105.160556 592.510832,107.31 592.510832,109.743333 C592.510832,111.203333 591.660775,112.095556 589.960661,112.42 C588.260547,112.744444 586.843786,112.825556 585.710376,112.663333 L569.923603,113.636667 L542.964652,115.096667 L542.721779,128.723333 C556.970353,128.398889 567.656784,127.993333 574.781072,127.506667 C576.238312,127.506667 578.667047,127.182222 582.067275,126.533333 C585.467503,125.884444 588.058153,125.56 589.839225,125.56 C593.401368,125.56 598.056442,126.695556 603.804447,128.966667 C609.552452,131.237778 612.426454,133.833333 612.426454,136.753333 C612.426454,139.348889 610.240593,140.646667 605.868871,140.646667 C605.221209,140.646667 602.630559,140.241111 598.096921,139.43 C582.876853,136.834444 571.542759,135.536667 564.094641,135.536667 C542.397948,135.536667 521.915621,138.132222 502.647662,143.323333 C502,143.485556 499.895097,144.093889 496.332953,145.148333 C492.77081,146.202778 489.330103,147.176111 486.010832,148.068333 C482.691562,148.960556 480.384265,149.406667 479.08894,149.406667 C476.49829,149.406667 472.126568,148.068333 465.973774,145.391667 C459.820981,142.715 456.744584,140.322222 456.744584,138.213333 C456.744584,136.591111 458.039909,135.78 460.630559,135.78 C462.735462,135.78 465.933295,135.942222 470.224059,136.266667 C474.514823,136.591111 477.712657,136.753333 479.81756,136.753333 C484.351197,136.753333 489.006271,136.469444 493.782782,135.901667 C498.559293,135.333889 504.550171,134.441667 511.755416,133.225 C518.960661,132.008333 523.534778,131.237778 525.477765,130.913333 L525.477765,118.016667 L508.233751,120.936667 C506.938426,121.098889 504.631129,121.747778 501.311859,122.883333 C497.992588,124.018889 495.523375,124.586667 493.904219,124.586667 C491.475485,124.586667 487.994299,123.086111 483.460661,120.085 C478.927024,117.083889 476.660205,114.61 476.660205,112.663333 L477.145952,111.446667 C477.793615,110.96 479.007982,110.716667 480.789054,110.716667 C482.40821,110.716667 484.836944,110.919444 488.075257,111.325 C491.313569,111.730556 493.661345,111.933333 495.118586,111.933333 C498.033067,111.933333 503.538198,111.649444 511.633979,111.081667 C519.729761,110.513889 524.020525,109.905556 524.506271,109.256667 C524.992018,108.607778 525.234892,103.741111 525.234892,94.6566667 C522.968073,94.6566667 519.527366,95.265 514.912771,96.4816667 C510.298176,97.6983333 506.776511,98.3066667 504.347777,98.3066667 C501.919042,98.3066667 498.802166,97.6983333 494.997149,96.4816667 C491.192132,95.265 489.289624,93.7644444 489.289624,91.98 C489.289624,90.52 490.584949,89.79 493.175599,89.79 C506.776511,88.1677778 517.381984,86.7888889 524.992018,85.6533333 L525.234892,69.1066667 C522.968073,69.4311111 518.596351,69.9177778 512.119726,70.5666667 C505.643101,71.2155556 500.218928,71.9455556 495.847206,72.7566667 C491.475485,73.5677778 487.265678,74.6222222 483.217788,75.92 C483.055872,75.92 478.724629,77.4205556 470.224059,80.4216667 C461.723489,83.4227778 456.906499,84.9233333 455.77309,84.9233333 C452.858609,84.9233333 448.00114,83.3416667 441.200684,80.1783333 C434.400228,77.015 431,74.2166667 431,71.7833333 C431,70.1611111 433.104903,69.35 437.314709,69.35 C438.124287,69.35 439.622007,69.4716667 441.807868,69.715 C443.993729,69.9583333 445.653364,69.9988889 446.786773,69.8366667 C471.236032,67.5655556 497.223489,64.24 524.749145,59.86 L524.749145,47.6933333 Z M570.652223,56.4533333 C570.814139,55.6422222 571.340365,53.9388889 572.230901,51.3433333 C573.121437,48.7477778 573.566705,46.72 573.566705,45.26 C573.566705,42.8266667 571.866591,41.61 568.466363,41.61 C565.713797,41.61 561.706385,42.0966667 556.444128,43.07 C551.18187,44.0433333 547.255416,44.53 544.664766,44.53 L544.179019,58.1566667 C546.445838,57.9944444 550.615165,57.7511111 556.687001,57.4266667 C562.758837,57.1022222 567.413911,56.7777778 570.652223,56.4533333 Z M566.766249,65.2133333 L543.693273,66.6733333 L543.450399,83.4633333 C547.984036,83.4633333 551.222349,83.3416667 553.165336,83.0983333 C555.108324,82.855 557.09179,81.9222222 559.115735,80.3 C561.139681,78.6777778 562.880274,76.1633333 564.337514,72.7566667 C565.794755,69.0255556 566.604333,66.5111111 566.766249,65.2133333 Z M581.824401,144.783333 C584.576967,144.783333 588.948689,147.865556 594.939567,154.03 C600.930445,160.194444 603.925884,164.655556 603.925884,167.413333 L603.925884,167.9 C603.602052,169.197778 602.22577,170.860556 599.797035,172.888333 C597.368301,174.916111 595.91106,176.335556 595.425314,177.146667 L582.310148,197.586667 C581.176739,199.371111 580.124287,201.196111 579.152794,203.061667 C578.1813,204.927222 576.805017,206.630556 575.023945,208.171667 C573.242873,209.712778 571.299886,210.483333 569.194983,210.483333 C567.09008,210.483333 563.77081,209.793889 559.237172,208.415 C554.703535,207.036111 551.141391,206.508889 548.550741,206.833333 C543.207526,207.157778 536.649943,207.725556 528.877993,208.536667 C521.106043,209.347778 514.629418,210.483333 509.448119,211.943333 C507.828962,212.43 506.128848,213.727778 504.347777,215.836667 C502.566705,217.945556 501.028506,219 499.733181,219 C499.247434,219 498.68073,218.837778 498.033067,218.513333 C495.766249,217.377778 493.661345,212.835556 491.718358,204.886667 C489.775371,196.937778 488.641961,191.584444 488.31813,188.826667 C486.698974,181.526667 483.86545,173.577778 479.81756,164.98 C479.81756,164.817778 479.331813,164.047222 478.360319,162.668333 C477.388826,161.289444 476.903079,160.194444 476.903079,159.383333 C476.903079,159.221111 476.984036,158.977778 477.145952,158.653333 L477.388826,158.166667 C478.036488,157.517778 478.927024,157.193333 480.060433,157.193333 C482.003421,157.193333 484.836944,157.882778 488.561003,159.261667 C492.285063,160.640556 495.199544,161.33 497.304447,161.33 C500.380844,161.33 503.740593,161.046111 507.383694,160.478333 C511.026796,159.910556 515.115165,159.14 519.648803,158.166667 C524.18244,157.193333 527.420753,156.544444 529.36374,156.22 L569.68073,149.163333 C570.976055,149.001111 572.919042,148.230556 575.509692,146.851667 C578.100342,145.472778 580.205245,144.783333 581.824401,144.783333 Z M506.776511,204.4 C514.224629,202.615556 523.575257,201.115 534.828392,199.898333 C546.081528,198.681667 555.432155,197.748889 562.880274,197.1 C564.661345,195.802222 567.09008,190.611111 570.166477,181.526667 C573.242873,172.442222 574.781072,166.521111 574.781072,163.763333 C574.781072,159.87 572.352338,157.923333 567.494869,157.923333 C566.199544,157.923333 562.961231,158.328889 557.779932,159.14 C529.282782,164.006667 510.581528,167.413333 501.676169,169.36 L503.619156,181.526667 C506.047891,181.04 510.379133,179.904444 516.612885,178.12 C522.846636,176.335556 528.554162,174.875556 533.735462,173.74 C538.916762,172.604444 543.288483,172.036667 546.850627,172.036667 C549.603193,172.036667 552.639111,172.523333 555.958381,173.496667 C559.277651,174.47 560.937286,175.93 560.937286,177.876667 C560.937286,179.985556 551.789054,182.175556 533.492588,184.446667 C515.196123,186.717778 505.724059,188.34 505.076397,189.313333 L506.776511,204.4 Z" + id="Shape"></path> + <path + d="M677.021778,161.388886 C677.021778,166.440162 679.436018,169.07561 684.483976,169.07561 L696.555178,169.07561 C701.603136,169.07561 704.236853,166.440162 704.236853,161.388886 L704.236853,49.6019631 C704.236853,44.5506876 701.822612,41.9152395 696.774655,41.9152395 L684.703452,41.9152395 C679.655495,41.9152395 677.021778,44.5506876 677.021778,49.6019631 L677.021778,161.388886 Z M788.954747,34.4481366 C785.662601,30.2753438 782.150978,30.2753438 778.858832,34.4481366 C770.299252,44.7703083 761.739672,54.433618 752.741139,63.4380656 C746.156847,69.8070652 747.473706,73.1013753 756.472238,73.1013753 L811.560817,73.1013753 C820.55935,73.1013753 821.656732,69.8070652 815.07244,63.4380656 C806.073907,54.433618 797.514327,44.7703083 788.954747,34.4481366 Z M851.286048,73.1013753 C855.456099,76.1760647 856.114529,79.9096162 853.261335,84.3020297 L852.602906,85.400133 C849.749713,89.7925465 846.457567,90.4514085 842.287515,87.3767191 C839.653798,85.400133 837.897987,83.8627883 837.020081,83.2039263 C840.312227,86.058995 836.581128,87.3767191 825.387831,87.3767191 L747.912658,87.3767191 C746.376324,87.3767191 745.059465,87.1570984 743.962083,86.7178571 C736.280409,83.2039263 732.110357,81.8862022 731.012975,82.7646849 C731.232451,82.5450643 729.47664,83.8627883 726.184494,86.4982364 C722.014442,89.7925465 720.039154,93.7457186 720.039154,98.7969941 L720.039154,176.103471 C720.039154,181.154747 717.624914,183.570574 712.576956,183.570574 L684.703452,183.570574 C680.094448,183.570574 677.680207,185.54716 677.021778,189.280712 C676.363349,194.331987 673.949108,196.967435 669.340104,196.967435 L668.901151,196.747815 C663.633717,196.967435 661,194.331987 661,189.280712 L661,34.6677573 C661,29.6164818 663.633717,27.2006544 668.681674,27.2006544 L712.576956,27.2006544 C717.624914,27.2006544 720.039154,29.6164818 720.039154,34.6677573 L720.039154,58.1671694 C720.039154,66.2931344 723.111824,67.8304791 729.257164,62.5595829 C743.084177,50.4804458 756.033286,36.863964 768.104488,22.1493789 C771.396634,17.9765861 775.566686,16 780.614644,16 L787.198936,16 C792.246893,16 796.416945,17.9765861 799.709091,22.1493789 C814.633487,40.8171362 831.752647,57.7279281 851.286048,73.1013753 Z M787.198936,203.336435 C783.467837,206.850366 779.517261,206.850366 775.786163,203.556056 L774.908257,202.677573 C770.957681,199.163642 770.957681,195.649711 774.908257,192.135781 C793.563752,175.005368 809.146577,156.337611 821.876209,136.352129 C825.607308,130.422371 823.851496,127.567302 816.828251,127.567302 L734.96355,127.567302 C729.915593,127.567302 727.501352,125.151475 727.281876,120.539441 C727.062399,115.488165 729.696116,112.852717 734.96355,112.852717 L838.556416,112.852717 C843.604373,112.852717 846.018614,115.268545 846.23809,119.880579 C846.457567,124.931854 845.140708,129.763509 842.506991,134.375543 C827.363119,160.510404 808.9271,183.350954 787.198936,203.336435 Z" + id="Shape"></path> + </g> + </g> +</svg> diff --git a/src/components/image/Image.astro b/src/components/image/Image.astro new file mode 100644 index 0000000..2d977a7 --- /dev/null +++ b/src/components/image/Image.astro @@ -0,0 +1,11 @@ +--- +import { blurStyle, type Image } from '@/helpers/images'; + +interface Props extends Image { + alt: string; +} + +const { alt, ...meta } = Astro.props; +--- + +<img src={meta.src} {alt} loading="lazy" width={meta.width} height={meta.height} style={blurStyle(meta)} /> diff --git a/src/components/image/QRDialog.astro b/src/components/image/QRDialog.astro new file mode 100644 index 0000000..9b05879 --- /dev/null +++ b/src/components/image/QRDialog.astro @@ -0,0 +1,47 @@ +--- +import QRCode from 'qrcode-svg'; + +interface Props { + url: string; + name: string; + title: string; + icon: string; + className?: string; +} + +const { url, name, title, icon, className } = Astro.props; +const svg = new QRCode({ + width: 196, + height: 196, + content: url, + join: true, + xmlDeclaration: false, + container: 'svg-viewbox', +}).svg(); +--- + +<div + class={className + ? `nice-dialog ${className}` + : 'nice-dialog btn btn-dark btn-icon btn-circle single-popup button-social'} +> + <span> + <i class={`iconfont ${icon}`}></i> + </span> + <div class="nice-popup nice-popup-center nice-popup-sm"> + <div class="nice-popup-overlay"></div> + <div class="nice-popup-body"> + <div class="nice-popup-close"> + <span class="svg-white"></span> + <span class="svg-dark"></span> + </div> + <div class="nice-popup-content"> + <div class="text-center"> + <h6>{title}</h6> + <p class="mt-1 mb-2">{name}</p> + <Fragment set:html={svg} /> + </div> + </div> + </div> + </div> +</div> diff --git a/src/components/like/LikeButton.astro b/src/components/like/LikeButton.astro new file mode 100644 index 0000000..be05c19 --- /dev/null +++ b/src/components/like/LikeButton.astro @@ -0,0 +1,18 @@ +--- +import { queryLikes } from '@/helpers/db/query'; +import type { Post } from '@/helpers/schema'; + +interface Props { + post: Post; +} + +const { post } = Astro.props; +const likes = await queryLikes(post.slug); +--- + +<div class="post-action text-center mt-5"> + <button class="post-like btn btn-secondary btn-lg btn-rounded" title="Do you like me?" type="button"> + <i class="text-lg iconfont icon-heart-fill me-1"></i> + <span class="like-count">{likes}</span> + </button> +</div> diff --git a/src/components/like/LikeIcon.astro b/src/components/like/LikeIcon.astro new file mode 100644 index 0000000..a98e20c --- /dev/null +++ b/src/components/like/LikeIcon.astro @@ -0,0 +1,20 @@ +--- +import { queryLikesAndViews } from '@/helpers/db/query'; +import type { Post } from '@/helpers/schema'; + +interface Props { + post: Post; +} + +const { post } = Astro.props; +const [likes, view] = await queryLikesAndViews(post.slug); +--- + +<div class="list-like d-inline-block"> + <i class="text-md iconfont icon-eye"></i> + <span class="like-count">{view}</span> +</div> +<div class="list-like d-inline-block"> + <i class="text-md iconfont icon-heart-fill"></i> + <span class="like-count">{likes}</span> +</div> diff --git a/src/components/like/LikeIconSmall.astro b/src/components/like/LikeIconSmall.astro new file mode 100644 index 0000000..0170e38 --- /dev/null +++ b/src/components/like/LikeIconSmall.astro @@ -0,0 +1,16 @@ +--- +import { queryLikes } from '@/helpers/db/query'; +import type { Post } from '@/helpers/schema'; + +interface Props { + post: Post; +} + +const { post } = Astro.props; +const likes = await queryLikes(post.slug); +--- + +<div> + <i class="text-md iconfont icon-heart-fill"></i> + <span class="like-count">{likes}</span> +</div> diff --git a/src/components/like/Share.astro b/src/components/like/Share.astro new file mode 100644 index 0000000..e3ca5e1 --- /dev/null +++ b/src/components/like/Share.astro @@ -0,0 +1,45 @@ +--- +import QRDialog from '@/components/image/QRDialog.astro'; +import { options, type Post } from '@/helpers/schema'; +import { urlJoin } from '@/helpers/tools'; +import * as querystring from 'node:querystring'; + +interface Props { + post: Post; +} + +const { post } = Astro.props; +const postURL = urlJoin(options.website, post.permalink); +const qq = querystring.stringify({ + query: `url=${postURL}&pics=${urlJoin(options.website, post.cover.src)}&summary=${post.summary}`, +}); +const weibo = querystring.stringify({ + query: `url=${postURL}&type=button&language=zh_cn&pic=${urlJoin(options.website, post.cover.src)}&searchPic=true&title=【${post.title}】${post.summary}`, +}); +--- + +<div class="post-share text-center mt-4"> + <a + href={`https://connect.qq.com/widget/shareqq/index.html?${qq}`} + class="btn btn-light btn-icon btn-md btn-circle mx-1 qq" + > + <span> + <i class="iconfont icon-QQ"></i> + </span> + </a> + <QRDialog + url={postURL} + name={'在微信中请长按二维码'} + title={'微信扫一扫 分享朋友圈'} + icon={'icon-wechat'} + className={'btn btn-light btn-icon btn-circle btn-md single-popup mx-1 weixin'} + /> + <a + href={`https://service.weibo.com/share/share.php?${weibo}`} + class="btn btn-light btn-icon btn-circle btn-md mx-1 weibo" + > + <span> + <i class="iconfont icon-weibo"></i> + </span> + </a> +</div> diff --git a/src/components/meta/PageMeta.astro b/src/components/meta/PageMeta.astro new file mode 100644 index 0000000..35215d9 --- /dev/null +++ b/src/components/meta/PageMeta.astro @@ -0,0 +1,49 @@ +--- +import { openGraphHeight, openGraphWidth } from '@/helpers/images'; +import { options } from '@/helpers/schema'; +import { getPageMeta } from '@/helpers/seo'; +import { urlJoin } from '@/helpers/tools'; + +export interface Props { + title?: string; + description?: string; + ogImageUrl?: string; +} + +const { title, description, ogImageUrl } = Astro.props; + +const { og, twitter } = getPageMeta({ + title: title || options.title, + description: description || options.description, + baseUrl: import.meta.env.SITE, + ogImageAbsoluteUrl: + ogImageUrl === undefined + ? urlJoin(import.meta.env.SITE, '/images/open-graph.png') + : ogImageUrl.startsWith('/') + ? urlJoin(import.meta.env.SITE, ogImageUrl) + : ogImageUrl, + ogImageAltText: title || options.title, + ogImageWidth: openGraphWidth, + ogImageHeight: openGraphHeight, + siteOwnerTwitterHandle: options.settings.twitter, + contentAuthorTwitterHandle: options.settings.twitter, +}); +--- + +<Fragment> + {og.title && <meta property="og:title" content={og.title} />} + {og.description && <meta property="og:description" content={og.description} />} + {og.type && <meta property="og:type" content={og.type} />} + {og.url && <meta property="og:url" content={og.url} />} + {og.image && <meta property="og:image" content={og.image} />} + {og.imageAlt && <meta property="og:image:alt" content={og.imageAlt} />} + {og.imageWidth && <meta property="og:image:width" content={og.imageWidth} />} + {og.imageHeight && <meta property="og:image:height" content={og.imageHeight} />} + {twitter.title && <meta property="twitter:title" content={twitter.title} />} + {twitter.description && <meta property="twitter:description" content={twitter.description} />} + {twitter.site && <meta property="twitter:site" content={twitter.site} />} + {twitter.creator && <meta property="twitter:creator" content={twitter.creator} />} + <meta property="twitter:card" content="summary_large_image" /> + {twitter.image && <meta property="twitter:image" content={twitter.image} />} + {twitter.imageAlt && <meta property="twitter:image:alt" content={twitter.imageAlt} />} +</Fragment> diff --git a/src/components/meta/PostMeta.astro b/src/components/meta/PostMeta.astro new file mode 100644 index 0000000..f653d52 --- /dev/null +++ b/src/components/meta/PostMeta.astro @@ -0,0 +1,57 @@ +--- +import { openGraphHeight, openGraphWidth } from '@/helpers/images'; +import { options } from '@/helpers/schema'; +import { getBlogPostMeta } from '@/helpers/seo'; +import { urlJoin } from '@/helpers/tools'; + +export interface Props { + title?: string; + description?: string; + publishDate: string; + requestPath: string; + ogImageUrl?: string; + ogImageAltText?: string; +} + +const { requestPath, title, description, publishDate, ogImageUrl, ogImageAltText } = Astro.props; + +const { og, twitter } = getBlogPostMeta({ + title: title || options.title, + description: description || options.description, + pageUrl: requestPath.startsWith('http') ? requestPath : import.meta.env.SITE + requestPath, + authorName: options.author.name, + publishDate, + ogImageAbsoluteUrl: + typeof ogImageUrl === 'undefined' + ? urlJoin(import.meta.env.SITE, '/images/open-graph.png') + : ogImageUrl.startsWith('/') + ? urlJoin(import.meta.env.SITE, ogImageUrl) + : ogImageUrl, + ogImageAltText, + ogImageWidth: openGraphWidth, + ogImageHeight: openGraphHeight, + siteOwnerTwitterHandle: options.settings.twitter, + contentAuthorTwitterHandle: options.settings.twitter, +}); +--- + +<Fragment> + {og.url && <link rel="canonical" href={og.url} />} + {og.title && <meta property="og:title" content={og.title} />} + {og.description && <meta property="og:description" content={og.description} />} + {og.type && <meta property="og:type" content={og.type} />} + {og.url && <meta property="og:url" content={og.url} />} + {og.author && <meta property="article:author" content={og.author} />} + {og.publishDate && <meta property="article:published_time" content={og.publishDate} />} + {og.image && <meta property="og:image" content={og.image} />} + {og.imageAlt && <meta property="og:image:alt" content={og.imageAlt} />} + {og.imageWidth && <meta property="og:image:width" content={og.imageWidth} />} + {og.imageHeight && <meta property="og:image:height" content={og.imageHeight} />} + {twitter.title && <meta property="twitter:title" content={twitter.title} />} + {twitter.description && <meta property="twitter:description" content={twitter.description} />} + {twitter.site && <meta property="twitter:site" content={twitter.site} />} + {twitter.creator && <meta property="twitter:creator" content={twitter.creator} />} + <meta property="twitter:card" content="summary_large_image" /> + {twitter.image && <meta property="twitter:image" content={twitter.image} />} + {twitter.imageAlt && <meta property="twitter:image:alt" content={twitter.imageAlt} />} +</Fragment> diff --git a/src/components/page/category/PinnedCategories.astro b/src/components/page/category/PinnedCategories.astro new file mode 100644 index 0000000..f63fd4a --- /dev/null +++ b/src/components/page/category/PinnedCategories.astro @@ -0,0 +1,13 @@ +--- +import PinnedCategory from '@/components/page/category/PinnedCategory.astro'; +import { getCategory, options } from '@/helpers/schema'; + +const pinnedSlug = options.settings.post.category ?? []; +const pinnedCategories = pinnedSlug + .map((slug) => getCategory(undefined, slug)) + .flatMap((category) => (category !== undefined ? [category] : [])); +--- + +<div class="row g-2 g-md-4 list-grouped mt-3 mt-md-4"> + {pinnedCategories.map((category) => <PinnedCategory category={category} />)} +</div> diff --git a/src/components/page/category/PinnedCategory.astro b/src/components/page/category/PinnedCategory.astro new file mode 100644 index 0000000..eb9f117 --- /dev/null +++ b/src/components/page/category/PinnedCategory.astro @@ -0,0 +1,35 @@ +--- +import Image from '@/components/image/Image.astro'; +import type { Category } from '@/helpers/schema'; + +interface Props { + category: Category; +} + +const { category } = Astro.props; +--- + +<div class="col-md-6"> + <div class="list-item block"> + <div class="media media-3x1"> + <a href={category.permalink} class="media-content"> + <Image {...category.cover} alt={category.name} /> + </a> + </div> + <div class="list-content"> + <div class="list-body"> + <a href={category.permalink} class="list-title h5"> + {category.name} + </a> + <div class="list-subtitle d-none d-md-block text-md text-secondary mt-2"> + <div class="h-1x">{category.description}</div> + </div> + </div> + <div class="list-footer mt-2"> + <div class="text-muted text-sm"> + <span class="d-inline-block">{`${category.counts} 篇文章`}</span> + </div> + </div> + </div> + </div> +</div> diff --git a/src/components/page/friend/FriendCard.astro b/src/components/page/friend/FriendCard.astro new file mode 100644 index 0000000..1f11c89 --- /dev/null +++ b/src/components/page/friend/FriendCard.astro @@ -0,0 +1,38 @@ +--- +import type { Friend } from '@/helpers/schema'; + +interface Props extends Friend {} + +const { website, description, homepage, poster, favicon } = Astro.props; +--- + +<div class="col-12 col-md-4"> + <div class="list-item block"> + <div class="media media-3x1"> + <div + class="media-content" + style={{ + backgroundImage: `url('${poster}')`, + backgroundSize: 'cover', + }} + > + </div> + </div> + <div class="list-content"> + <div class="list-body"> + <div class="list-title h6 h-1x"> + {website} + <div + class="list-favicon" + style={{ + backgroundImage: `url('${favicon}')`, + }} + > + </div> + </div> + <div class="text-sm text-secondary h-2x mt-1">{description ? description : ' '}</div> + </div> + </div> + <a href={homepage} target="_blank" class="list-gogogo"></a> + </div> +</div> diff --git a/src/components/page/friend/FriendLinks.astro b/src/components/page/friend/FriendLinks.astro new file mode 100644 index 0000000..319afab --- /dev/null +++ b/src/components/page/friend/FriendLinks.astro @@ -0,0 +1,28 @@ +--- +import FriendCard from '@/components/page/friend/FriendCard.astro'; +import { friends } from '@/helpers/schema'; +import _ from 'lodash'; + +const list = _.shuffle(friends); +--- + +{ + list.length > 0 ? ( + <div class="list-bookmarks px-3 px-md-0"> + <h2 class="text-muted mb-4 mb-md-3"> + 左邻右舍 <span class="text-primary text-sm mb-4 mb-md-3">排名不分前后</span> + </h2> + <div class="row g-md-4 list-grouped"> + {list.map((friend) => ( + <FriendCard {...friend} /> + ))} + </div> + </div> + ) : ( + <div class="data-null"> + <div class="my-auto"> + <div>还没有友链呢...😭</div> + </div> + </div> + ) +} diff --git a/src/components/page/pagination/LargePagination.astro b/src/components/page/pagination/LargePagination.astro new file mode 100644 index 0000000..e601786 --- /dev/null +++ b/src/components/page/pagination/LargePagination.astro @@ -0,0 +1,55 @@ +--- +import PaginationItem from '@/components/page/pagination/PaginationItem.astro'; + +interface Props { + current: number; + total: number; + rootPath: string; +} + +const { current, total, rootPath } = Astro.props; +const pages = + current < 5 + ? [1, 2, 3, 4, 5] + : current > total - 4 + ? [total - 4, total - 3, total - 2, total - 1, total] + : [current - 1, current, current + 1]; +--- + +{ + current < 5 ? ( + <> + {pages.map((page) => ( + <PaginationItem pageNum={page} current={current} rootPath={rootPath} /> + ))} + <span class="page-numbers dots"> + <i class="iconfont icon-ellipsis" /> + </span> + <PaginationItem pageNum={total} current={current} rootPath={rootPath} /> + </> + ) : current > total - 4 ? ( + <> + <PaginationItem pageNum={1} current={current} rootPath={rootPath} /> + <span class="page-numbers dots"> + <i class="iconfont icon-ellipsis" /> + </span> + {pages.map((page) => ( + <PaginationItem pageNum={page} current={current} rootPath={rootPath} /> + ))} + </> + ) : ( + <> + <PaginationItem pageNum={1} current={current} rootPath={rootPath} /> + <span class="page-numbers dots"> + <i class="iconfont icon-ellipsis" /> + </span> + {pages.map((page) => ( + <PaginationItem pageNum={page} current={current} rootPath={rootPath} /> + ))} + <span class="page-numbers dots"> + <i class="iconfont icon-ellipsis" /> + </span> + <PaginationItem pageNum={total} current={current} rootPath={rootPath} /> + </> + ) +} diff --git a/src/components/page/pagination/Pagination.astro b/src/components/page/pagination/Pagination.astro new file mode 100644 index 0000000..b0e1c6a --- /dev/null +++ b/src/components/page/pagination/Pagination.astro @@ -0,0 +1,27 @@ +--- +import LargePagination from '@/components/page/pagination/LargePagination.astro'; +import SmallPagination from '@/components/page/pagination/SmallPagination.astro'; + +interface Props { + current: number; + total: number; + rootPath: string; +} + +const { current, total, rootPath } = Astro.props; +--- + +{ + total !== 1 && ( + <nav class="navigation pagination" aria-label="文章"> + <h2 class="screen-reader-text">文章导航</h2> + <div class="nav-links"> + {total <= 6 ? ( + <SmallPagination current={current} total={total} rootPath={rootPath} /> + ) : ( + <LargePagination current={current} total={total} rootPath={rootPath} /> + )} + </div> + </nav> + ) +} diff --git a/src/components/page/pagination/PaginationItem.astro b/src/components/page/pagination/PaginationItem.astro new file mode 100644 index 0000000..c16dda2 --- /dev/null +++ b/src/components/page/pagination/PaginationItem.astro @@ -0,0 +1,23 @@ +--- +import { join } from 'node:path'; + +interface Props { + current: number; + pageNum: number; + rootPath: string; +} + +const { current, pageNum, rootPath } = Astro.props; +--- + +{ + current !== pageNum ? ( + <a class="page-numbers" href={pageNum === 1 ? rootPath : join(rootPath, `/page/${pageNum}`)}> + {pageNum} + </a> + ) : ( + <span aria-current="page" class="page-numbers current"> + {pageNum} + </span> + ) +} diff --git a/src/components/page/pagination/SmallPagination.astro b/src/components/page/pagination/SmallPagination.astro new file mode 100644 index 0000000..4692177 --- /dev/null +++ b/src/components/page/pagination/SmallPagination.astro @@ -0,0 +1,14 @@ +--- +import PaginationItem from '@/components/page/pagination/PaginationItem.astro'; + +interface Props { + current: number; + total: number; + rootPath: string; +} + +const { current, total, rootPath } = Astro.props; +const pages = Array.from({ length: total }, (_, i) => i + 1); +--- + +{pages.map((page) => <PaginationItem pageNum={page} current={current} rootPath={rootPath} />)} diff --git a/src/components/page/post/FeaturePost.astro b/src/components/page/post/FeaturePost.astro new file mode 100644 index 0000000..ceeacd6 --- /dev/null +++ b/src/components/page/post/FeaturePost.astro @@ -0,0 +1,26 @@ +--- +import Image from '@/components/image/Image.astro'; +import type { Post } from '@/helpers/schema'; + +interface Props { + post: Post; +} + +const { post } = Astro.props; +--- + +<div class="list-item list-nice-overlay"> + <div class="media media-3x2"> + <a href={post.permalink} class="media-content"> + <Image {...post.cover} alt={post.title} /> + <div class="overlay"></div> + </a> + </div> + <div class="list-content p-2 p-md-3"> + <div class="list-body"> + <a href={post.permalink} class="list-title h5 h-2x m-0"> + {post.title} + </a> + </div> + </div> +</div> diff --git a/src/components/page/post/FeaturePosts.astro b/src/components/page/post/FeaturePosts.astro new file mode 100644 index 0000000..2ef57a3 --- /dev/null +++ b/src/components/page/post/FeaturePosts.astro @@ -0,0 +1,35 @@ +--- +import FeaturePost from '@/components/page/post/FeaturePost.astro'; +import { options, type Post } from '@/helpers/schema'; + +interface Props { + posts: Post[]; +} + +const { posts } = Astro.props; +const featurePosts = options.settings.post.feature ?? []; +const metas: Post[] = featurePosts + .map((slug) => posts.find((post) => post.slug === slug)) + .flatMap((post) => (post == null ? [] : [post])) + .slice(0, 3); +--- + +<div class="list-top-pushes mb-3 mb-md-4 mb-lg-5"> + <div class="container"> + <div class="row gx-2 gx-md-3 list-grouped"> + <div class="col-lg-8"> + <FeaturePost post={metas[0]} /> + </div> + <div class="col-lg-4 d-flex flex-column mt-2 mt-md-3 mt-lg-0"> + <div class="row g-2 g-md-3"> + <div class="col-6 col-lg-12"> + <FeaturePost post={metas[1]} /> + </div> + <div class="col-6 col-lg-12"> + <FeaturePost post={metas[2]} /> + </div> + </div> + </div> + </div> + </div> +</div> diff --git a/src/components/page/post/PostCard.astro b/src/components/page/post/PostCard.astro new file mode 100644 index 0000000..39ae31c --- /dev/null +++ b/src/components/page/post/PostCard.astro @@ -0,0 +1,42 @@ +--- +import Image from '@/components/image/Image.astro'; +import LikeIcon from '@/components/like/LikeIcon.astro'; +import { formatShowDate } from '@/helpers/formatter'; +import { getCategory, type Post } from '@/helpers/schema'; + +interface Props { + post: Post; +} + +const { post } = Astro.props; +const category = getCategory(post.category, undefined); +--- + +<div class="list-item block"> + <div class="media media-3x2 col-6 col-md-5"> + <a href={post.permalink} class="media-content"> + <Image {...post.cover} alt={post.title} /> + </a> + <div class="media-overlay overlay-top"> + <a class="d-none d-md-inline-block badge badge-md bg-white-overlay" href={category ? category.permalink : ''}> + {post.category} + </a> + </div> + </div> + <div class="list-content"> + <div class="list-body"> + <a href={post.permalink} class="list-title h5"> + <div class="h-2x">{post.title}</div> + </a> + <div class="d-none d-md-block list-desc text-secondary text-md mt-3"> + <div class="h-2x">{post.summary ?? ''}</div> + </div> + </div> + <div class="list-footer"> + <div class="d-flex flex-fill align-items-center text-muted text-sm"> + <div class="flex-fill d-none d-md-block">{formatShowDate(post.date)}</div> + <LikeIcon {post} /> + </div> + </div> + </div> +</div> diff --git a/src/components/page/post/PostCards.astro b/src/components/page/post/PostCards.astro new file mode 100644 index 0000000..bd1cdbb --- /dev/null +++ b/src/components/page/post/PostCards.astro @@ -0,0 +1,12 @@ +--- +import PostCard from '@/components/page/post/PostCard.astro'; +import type { Post } from '@/helpers/schema'; + +interface Props { + posts: Post[]; +} + +const { posts } = Astro.props; +--- + +<div class="list-grid">{posts.map((post) => <PostCard post={post} />)}</div> diff --git a/src/components/page/post/PostContent.astro b/src/components/page/post/PostContent.astro new file mode 100644 index 0000000..fd216e1 --- /dev/null +++ b/src/components/page/post/PostContent.astro @@ -0,0 +1,15 @@ +--- +import Image from '@/components/image/Image.astro'; +import UnstyledMusicPlayer from '@/components/player/UnstyledMusicPlayer.astro'; +import { posts } from '@/helpers/schema'; + +const { slug } = Astro.params; +const post = posts.find((post) => post.slug === slug); +if (!post) { + return Astro.redirect('/404'); +} + +const { Content } = await post.render(); +--- + +<Content components={{ MusicPlayer: UnstyledMusicPlayer, Image: Image }} /> diff --git a/src/components/page/post/PostPagination.astro b/src/components/page/post/PostPagination.astro new file mode 100644 index 0000000..cf9bdcc --- /dev/null +++ b/src/components/page/post/PostPagination.astro @@ -0,0 +1,24 @@ +--- +import Pagination from '@/components/page/pagination/Pagination.astro'; +import PostCards from '@/components/page/post/PostCards.astro'; +import { slicePosts } from '@/helpers/formatter'; +import { options, type Post } from '@/helpers/schema'; + +interface Props { + posts: Post[]; + pageNum: number; +} + +const { pageNum, posts } = Astro.props; +const results = slicePosts(posts, pageNum, options.settings.pagination.posts); +if (!results) { + return Astro.redirect('/404'); +} + +const { currentPosts, totalPage } = results; +--- + +<div class="content-wrapper content-wrapper col-12 col-xl-9"> + <PostCards posts={currentPosts} /> + <Pagination current={pageNum} total={totalPage} rootPath={'/'} /> +</div> diff --git a/src/components/page/post/PostSquare.astro b/src/components/page/post/PostSquare.astro new file mode 100644 index 0000000..0471ed6 --- /dev/null +++ b/src/components/page/post/PostSquare.astro @@ -0,0 +1,34 @@ +--- +import Image from '@/components/image/Image.astro'; +import LikeIconSmall from '@/components/like/LikeIconSmall.astro'; +import { formatShowDate } from '@/helpers/formatter'; +import type { Post } from '@/helpers/schema'; + +interface Props { + post: Post; + first: boolean; +} + +const { post, first } = Astro.props; +--- + +<div class={first ? 'col-12 col-md-8 col-xl-6' : 'col-6 col-md-4 col-xl-3'}> + <div class="list-item list-nice-overlay"> + <div class={`media ${first ? 'media-36x17' : ''}`}> + <a href={post.permalink} class="media-content"> + <Image {...post.cover} alt={post.title} /> + <div class="overlay"></div> + </a> + </div> + <div class="list-content"> + <a href={post.permalink} class="list-body"> + <div class="list-title h6 h-2x">{post.title}</div> + <div class="list-meta font-number d-flex flex-fill text-muted text-sm"> + <span class="d-inline-block">{formatShowDate(post.date)}</span> + <div class="flex-fill"></div> + <LikeIconSmall {post} /> + </div> + </a> + </div> + </div> +</div> diff --git a/src/components/player/MusicPlayer.astro b/src/components/player/MusicPlayer.astro new file mode 100644 index 0000000..b75cf0b --- /dev/null +++ b/src/components/player/MusicPlayer.astro @@ -0,0 +1,18 @@ +--- +import { resolveSong, type MusicPlayerProps } from '@/components/player/resolver'; +import 'aplayer/dist/APlayer.min.css'; + +interface Props extends MusicPlayerProps {} + +const { name, artist, url, pic } = await resolveSong(Astro.props); +--- + +{ + url === '' ? ( + <p>歌曲加载失败</p> + ) : ( + <div class="aplayer" data-name={name} data-artist={artist} data-url={url} data-cover={pic}> + 音乐正在加载中 ... + </div> + ) +} diff --git a/src/components/player/UnstyledMusicPlayer.astro b/src/components/player/UnstyledMusicPlayer.astro new file mode 100644 index 0000000..c438d3e --- /dev/null +++ b/src/components/player/UnstyledMusicPlayer.astro @@ -0,0 +1,9 @@ +--- +import { resolveSong, type MusicPlayerProps } from '@/components/player/resolver'; + +interface Props extends MusicPlayerProps {} + +const { url } = await resolveSong(Astro.props); +--- + +{url !== '' && <audio controls src={url} />} diff --git a/src/components/player/resolver.ts b/src/components/player/resolver.ts new file mode 100644 index 0000000..99add89 --- /dev/null +++ b/src/components/player/resolver.ts @@ -0,0 +1,51 @@ +export type Song = { + name: string; + artist: string; + url: string; + pic: string; +}; + +// The props for music player. We support both netease music and direct linked music. +export interface MusicPlayerProps { + netease?: string; + song?: Song; +} + +const emptySong = { name: '', artist: '', url: '', pic: '' }; + +const song = async (props: MusicPlayerProps): Promise<Song> => { + const { netease, song } = props; + + if (import.meta.env.DEV) { + // Fix the UNABLE_TO_GET_ISSUER_CERT_LOCALLY issue. + process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'; + } + + if (netease) { + // https://github.com/injahow/meting-api + const data = await fetch(`https://api.injahow.cn/meting/?type=song&id=${netease}`) + .then((response) => response.json()) + .catch((e) => { + console.log(e); + return [emptySong]; + }); + + return data[0] as Song; + } + + if (song) { + return song; + } + + console.error('No song information is provided, check your code.'); + return emptySong; +}; + +export const resolveSong = async (props: MusicPlayerProps): Promise<Song> => { + // Try-catch for avoiding the unexpected errors. + try { + return await song(props); + } catch (e) { + return emptySong; + } +}; diff --git a/src/components/search/SearchBar.astro b/src/components/search/SearchBar.astro new file mode 100644 index 0000000..606dc7b --- /dev/null +++ b/src/components/search/SearchBar.astro @@ -0,0 +1,12 @@ +--- +import { options } from '@/helpers/schema'; +--- + +<div id="search" class="widget widget_search" hidden={!options.settings.sidebar.search}> + <div class="search-form"> + <label> + <span class="screen-reader-text">搜索:</span> + <input type="search" class="search-field search-sidebar" placeholder="输入然后回车…" name="q" /> + </label> + </div> +</div> diff --git a/src/components/search/SearchDialog.astro b/src/components/search/SearchDialog.astro new file mode 100644 index 0000000..c89ac68 --- /dev/null +++ b/src/components/search/SearchDialog.astro @@ -0,0 +1,33 @@ +--- + +--- + +<div class="global-search btn btn-dark btn-icon btn-circle site-search-toggler button-social"> + <span> + <i class="iconfont icon-search"></i> + </span> +</div> + +<div class="global-search-popup nice-popup nice-popup-center nice-popup-md"> + <div class="nice-popup-overlay"></div> + <div class="nice-popup-body"> + <div class="global-search-close nice-popup-close"> + <span class="svg-white"></span> + <span class="svg-dark"></span> + </div> + <div class="nice-popup-content"> + <form class="text-center p-3 p-md-5" action={'/search'}> + <div class="mb-3 mb-md-4"> + <input + class="form-control form-control-lg text-center" + type="text" + name="q" + placeholder="搜索并回车" + required + /> + </div> + <button type="submit" class="btn btn-primary btn-block btn-lg">搜索</button> + </form> + </div> + </div> +</div> diff --git a/src/components/sidebar/RandomPosts.astro b/src/components/sidebar/RandomPosts.astro new file mode 100644 index 0000000..35233fe --- /dev/null +++ b/src/components/sidebar/RandomPosts.astro @@ -0,0 +1,29 @@ +--- +import _ from 'lodash'; + +import { options, type Post } from '@/helpers/schema'; + +interface Props { + posts: Post[]; +} + +const { posts } = Astro.props; +const randomSize = options.settings.sidebar.post; +--- + +{ + randomSize > 0 && ( + <div id="recent_posts" class="widget widget_recent_entries"> + <div class="widget-title">随机文章</div> + <ul class="line"> + {_.sampleSize(posts, randomSize).map((post) => ( + <li> + <a href={post.permalink} title={post.title}> + {post.title} + </a> + </li> + ))} + </ul> + </div> + ) +} diff --git a/src/components/sidebar/RandomTags.astro b/src/components/sidebar/RandomTags.astro new file mode 100644 index 0000000..0fe216a --- /dev/null +++ b/src/components/sidebar/RandomTags.astro @@ -0,0 +1,25 @@ +--- +import _ from 'lodash'; + +import { options, type Tag } from '@/helpers/schema'; + +interface Props { + tags: Tag[]; +} + +const { tags } = Astro.props; +const randomSize = options.settings.sidebar.tag; +--- + +<div id="tag_cloud" class="widget widget_tag_cloud"> + <div class="widget-title">文章标签</div> + <div class="tagcloud"> + { + _.sampleSize(tags, randomSize).map((tag) => ( + <a href={tag.permalink} class="tag-cloud-link" title={`${tag.name} (${tag.counts} 篇文章)`}> + {tag.name} + </a> + )) + } + </div> +</div> diff --git a/src/components/sidebar/RecentComments.astro b/src/components/sidebar/RecentComments.astro new file mode 100644 index 0000000..cf8c6dc --- /dev/null +++ b/src/components/sidebar/RecentComments.astro @@ -0,0 +1,32 @@ +--- +import { latestComments } from '@/helpers/db/query'; +import { options } from '@/helpers/schema'; + +const comments = await latestComments(); +--- + +{ + options.settings.sidebar.comment > 0 && ( + <div id="recent-comments" class="widget widget_recent_comments"> + <div class="widget-title">近期评论</div> + <ul id="recentcomments"> + {comments.map((comment) => ( + <li class="recentcomments"> + <span class="comment-author-link"> + {comment.authorLink === '' ? ( + comment.author + ) : ( + <a href={comment.authorLink} target="_blank" rel="nofollow"> + {comment.author} + </a> + )} + </span> + {'发表在《'} + <a href={comment.permalink}>{comment.title}</a> + {'》'} + </li> + ))} + </ul> + </div> + ) +} diff --git a/src/components/sidebar/Sidebar.astro b/src/components/sidebar/Sidebar.astro new file mode 100644 index 0000000..a883a2c --- /dev/null +++ b/src/components/sidebar/Sidebar.astro @@ -0,0 +1,23 @@ +--- +import SearchBar from '@/components/search/SearchBar.astro'; +import RandomPosts from '@/components/sidebar/RandomPosts.astro'; +import RandomTags from '@/components/sidebar/RandomTags.astro'; +import RecentComments from '@/components/sidebar/RecentComments.astro'; +import type { Post, Tag } from '@/helpers/schema'; + +interface Props { + posts: Post[]; + tags: Tag[]; +} + +const { posts, tags } = Astro.props; +--- + +<aside class="sidebar col-12 col-xl-3 d-none d-xl-block"> + <div class="sidebar-inner block"> + <SearchBar /> + <RandomPosts {posts} /> + <RecentComments /> + <RandomTags {tags} /> + </div> +</aside> diff --git a/src/content/categories/article.yml b/src/content/categories/article.yml new file mode 100644 index 0000000..3345a1c --- /dev/null +++ b/src/content/categories/article.yml @@ -0,0 +1,6 @@ +name: 文章 +slug: article +description: |- + 我在寻找一个声音,期待着它把书影里的音符唱给你们听。 + 记录一本书、一个作者、一部电影及其与生活之间丝丝缕缕的情。我热爱书和电影,更热爱生活,希望我们都有着走不完的似水流年,说不完的逝水年华。 +cover: /images/categories/article.jpg diff --git a/src/content/categories/coding.yml b/src/content/categories/coding.yml new file mode 100644 index 0000000..f3c9b06 --- /dev/null +++ b/src/content/categories/coding.yml @@ -0,0 +1,7 @@ +name: 编程 +slug: coding +description: |- + 冒泡排序,选择排序,插入排序,快速排序,堆排序,归并排序,希尔排序,桶排序,基数排序。 + 有向图,无向图,有环图,无环图,完全图,稠密图,稀疏图,拓扑图。 + 二叉树,红黑树,van Emde Boas树,最小生成树。 +cover: /images/categories/coding.jpg diff --git a/src/content/categories/gossip.yml b/src/content/categories/gossip.yml new file mode 100644 index 0000000..d5ae928 --- /dev/null +++ b/src/content/categories/gossip.yml @@ -0,0 +1,5 @@ +name: 杂谈 +slug: gossip +description: |- + 我读书不过为消遣,偶至有趣处,便欣然记下。不敢说集腋成裘,但聊作敝帚自珍。有伟人说,科学的世界像是海洋,他像在海边玩耍的孩子,偶尔捡拾到几只贝壳,他就很高兴。海洋的比喻也可用作浩瀚的文史,行走在文史的典籍里,偶尔捡到一些边角料,也同样令人兴奋。 +cover: /images/categories/gossip.jpg diff --git a/src/content/categories/novel.yml b/src/content/categories/novel.yml new file mode 100644 index 0000000..d58b3b0 --- /dev/null +++ b/src/content/categories/novel.yml @@ -0,0 +1,5 @@ +name: 小说 +slug: novel +description: |- + 在这个世界里没有朝霞的红,没有苔藓的绿,没有夜来香的黄,没有橡木的棕,也没有深海的蓝。有的只是孩子们张惶不安的丈量世界,换来一声叹息。 +cover: /images/categories/novel.jpg diff --git a/src/content/categories/think.yml b/src/content/categories/think.yml new file mode 100644 index 0000000..5763b25 --- /dev/null +++ b/src/content/categories/think.yml @@ -0,0 +1,7 @@ +name: 杂思 +slug: think +description: |- + 听一听素乐,品一品素茶,读一读素书,写一写素心。即使是清贫过一生,也安之若素。 + 只想在这滚滚红尘深处,留一抹清淡。只愿在这茫茫人海之中,寻一个会心。 + 爱读几句书,常听几支曲,闲品几盏茶,偶插几朵花。此生无所求,闲看花开落。 +cover: /images/categories/think.jpg diff --git a/src/content/config.ts b/src/content/config.ts new file mode 100644 index 0000000..779bf66 --- /dev/null +++ b/src/content/config.ts @@ -0,0 +1,158 @@ +import { imageMetadata } from '@/helpers/images'; +import { defineCollection, z } from 'astro:content'; + +export const defaultCover = '/images/default-cover.jpg'; + +// Copied and modified from https://github.com/zce/velite/blob/main/src/schemas/slug.ts +// The slug is internally supported by Astro with 'content' type. +// We add the slug here for validating the YAML configuration. +const slug = () => + z + .string() + .min(3) + .max(200) + .regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/i, 'Invalid slug'); + +const image = (fallbackImage: string) => + z + .string() + .optional() + .default(fallbackImage) + .transform(async (arg) => await imageMetadata(arg)); + +// Categories Collection +const categoriesCollection = defineCollection({ + type: 'data', + schema: z.object({ + name: z.string().max(20), + slug: slug(), + cover: image(defaultCover), + description: z.string().max(999).optional(), + }), +}); + +// Friends Collection +const friendsCollection = defineCollection({ + type: 'data', + schema: z.array( + z + .object({ + website: z.string().max(40), + description: z.string().optional(), + homepage: z.string().url(), + poster: z.string(), + favicon: z.string().optional(), + }) + .transform((data) => { + if (data.favicon === undefined) { + data.favicon = `${data.homepage}/favicon.ico`; + } + return data; + }), + ), +}); + +// Options Collection +const optionsCollection = defineCollection({ + type: 'data', + schema: z.object({ + title: z.string().max(40), + website: z.string().url(), + description: z.string().max(100), + keywords: z.array(z.string()), + author: z.object({ name: z.string(), email: z.string().email(), url: z.string().url() }), + navigation: z.array(z.object({ text: z.string(), link: z.string(), target: z.string().optional() })), + socials: z.array( + z.object({ + name: z.string(), + icon: z.string(), + type: z.enum(['link', 'qrcode']), + title: z.string().optional(), + link: z.string().url(), + }), + ), + settings: z.object({ + initialYear: z.number().max(2024), + icpNo: z.string().optional(), + locale: z.string().optional().default('zh-CN'), + timeZone: z.string().optional().default('Asia/Shanghai'), + timeFormat: z.string().optional().default('yyyy-MM-dd HH:mm:ss'), + twitter: z.string(), + post: z.object({ + sort: z.enum(['asc', 'desc']), + feature: z.array(z.string()).optional(), + category: z.array(z.string()).optional(), + }), + pagination: z.object({ + posts: z.number().optional().default(5), + category: z.number().optional().default(7), + tags: z.number().optional().default(7), + search: z.number().optional().default(7), + }), + feed: z.object({ + full: z.boolean().optional().default(true), + size: z.number().optional().default(20), + }), + sidebar: z.object({ + search: z.boolean().default(false), + post: z.number().default(6), + comment: z.number().default(0), + tag: z.number().default(20), + }), + comments: z.object({ + server: z.string().url().readonly(), + admins: z.array(z.number()), + }), + }), + }), +}); + +// Posts Collection +const postsCollection = defineCollection({ + type: 'content', + schema: z.object({ + title: z.string().max(99), + date: z.date(), + updated: z.date().optional(), + comments: z.boolean().optional().default(true), + tags: z.array(z.string()).optional().default([]), + category: z.string(), + summary: z.string().optional().default(''), + cover: image(defaultCover), + published: z.boolean().optional().default(true), + }), +}); + +// Pages Collection +const pagesCollection = defineCollection({ + type: 'content', + schema: z.object({ + title: z.string().max(99), + date: z.date(), + updated: z.date().optional(), + comments: z.boolean().optional().default(true), + cover: image(defaultCover), + published: z.boolean().optional().default(true), + friend: z.boolean().optional().default(false), + }), +}); + +// Tags Collection +const tagsCollection = defineCollection({ + type: 'data', + schema: z.array( + z.object({ + name: z.string().max(20), + slug: slug(), + }), + ), +}); + +export const collections = { + categories: categoriesCollection, + friends: friendsCollection, + options: optionsCollection, + pages: pagesCollection, + posts: postsCollection, + tags: tagsCollection, +}; diff --git a/src/content/friends/index.yml b/src/content/friends/index.yml new file mode 100644 index 0000000..85fa221 --- /dev/null +++ b/src/content/friends/index.yml @@ -0,0 +1,63 @@ +- website: 80后向前冲 + description: 松鼠哥哥 + homepage: https://www.80-go.com + poster: /images/links/80-go.com.jpg +- website: Cynosura + description: Trying to light up the dark + homepage: https://cynosura.one + poster: /images/links/cynosura.one.jpg + favicon: https://cynosura.one/img/favicon.ico +- website: EEE.ME + description: 途方に暮れて + homepage: https://eee.me + poster: /images/links/eee.me.jpg +- website: kn007的个人博客 + homepage: https://kn007.net + poster: /images/links/kn007.net.jpg +- website: Xinsenz茶话 + description: 树下呷茶,酒好花新。 + homepage: https://xinsenz.com + poster: /images/links/xinsenz.com.jpg +- website: 刀客 + description: 这世界需要更多英雄 + homepage: https://blog.mboker.cn + poster: /images/links/mboker.cn.jpg + favicon: data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text x=%22-0.125em%22 y=%22.9em%22 font-size=%2290%22>🌻</text></svg> +- website: 品味苏州 + description: 吴侬软语、小桥流水的生活点滴 + homepage: https://pwsz.com + poster: /images/links/pwsz.com.jpg +- website: 夜枫 + homepage: https://yefengs.com + poster: /images/links/yefengs.com.jpg +- website: 樱花烂漫 + description: 樱花烂漫 + homepage: https://minagi.me + poster: /images/links/minagi.me.jpg +- website: 羽忆江南 + description: 烟雨红尘的寻觅,诗画江南的惦记。 + homepage: https://yyjn.org + poster: /images/links/yyjn.org.jpg +- website: 行者自若 + description: 茶盐观瑟丶行者自若 + homepage: https://alexinea.com + poster: /images/links/alexinea.com.jpg + favicon: https://alexinea.com/wp-content/uploads/2016/09/cropped-20160812.2-32x32.png +- website: 贾顺名 + description: 全沾码农的一些笔记 + homepage: https://jiasm.github.io + poster: /images/links/jiasm.github.io.jpg +- website: 白丁轶事 - FMoran的自留地 + description: Everything should be hurry. + homepage: https://fmoran.me + poster: /images/links/fmoran.me.jpg +- website: 船长の部落格 + description: 船长の部落格,记录有趣的事,分享技术经验。 + homepage: https://captainofphb.me + poster: /images/links/captainofphb.me.jpg + favicon: https://captainofphb.me/favicon.svg +- website: 小萌博客 + description: 互联网分享笔记 + homepage: https://blog.luoli.net + poster: /images/links/luoli.net.jpg + favicon: https://blog.luoli.net/usr/themes/MUltraMoe/images/favicon.png diff --git a/src/content/options/index.yml b/src/content/options/index.yml new file mode 100644 index 0000000..439657a --- /dev/null +++ b/src/content/options/index.yml @@ -0,0 +1,92 @@ +title: 且听书吟 +website: https://yufan.me +description: 诗与梦想的远方 +keywords: + - 雨帆 + - 且听书吟 + - syhily + - amehochan + - yufan +author: + name: 雨帆 + email: syhily@gmail.com + url: https://yufan.me +navigation: + - text: 首页 + link: / + - text: 关于 + link: /about + - text: 留言 + link: /guestbook + - text: 友链 + link: /links + - text: 笔记 + link: https://note.yufan.me + target: _blank +socials: + - name: GitHub + icon: icon-github-fill + type: link + link: https://github.com/syhily + - name: Twitter + icon: icon-twitter + type: link + link: https://twitter.com/amehochan + - name: Wechat + icon: icon-wechat + type: qrcode + title: 扫码加我微信好友 + link: https://u.wechat.com/EBpmuKmrVz4YVFnoCJdnruA +settings: + initialYear: 2011 + icpNo: 皖ICP备2021002315号-2 + locale: zh-CN + timeZone: Asia/Shanghai + timeFormat: yyyy年MM月dd日 + twitter: amehochan + post: + # asc or desc + sort: desc + # This is the PINGED posts on top of your homepage. + # You can add the posts id here. + # We only show the first three feature posts. + feature: + - secret-of-boys-mind + - my-darling + - happiness-caprice + # The pinned category slugs. + category: + - article + - think + - gossip + - coding + pagination: + # Number of posts per home page. + posts: 5 + # Number of posts per category page. + category: 7 + # Number of posts per tag page. + tags: 7 + # Number of posts in search results. + search: 7 + feed: + # Whether to show the post's content. + full: true + # The counts of the latest post to show. + size: 10 + sidebar: + # Display search bar. + search: true + # Display the number of random posts. Set 0 or a negation number to disable it. + post: 6 + # Display recent blog comments. Set 0 or a negative number to disable it. + comment: 6 + # Display the tag cloud. Set 0 or a negative number to disable it. + tag: 20 + # Artalk configuration + comments: + # The artalk server endpoint + server: https://comment.yufan.me + # The administrator user id. + admins: + - 3 diff --git a/src/content/pages/about.mdx b/src/content/pages/about.mdx new file mode 100644 index 0000000..4a2c350 --- /dev/null +++ b/src/content/pages/about.mdx @@ -0,0 +1,39 @@ +--- +title: 关于我 +slug: about +date: 2010-03-25 02:20:11 +updated: 2024-04-08 19:27:27 +cover: /images/2019/05/2019051406433394.jpg +published: true +--- + + +<MusicPlayer netease={22705492} /> + +2007 年,我开始写 Blog,第一个 Blog 名字叫做“雨帆”。 + +2011 年,我开始用 WordPress 写博客,起的第一个名字也叫“雨帆”。 + +“雨帆”在我的字典里并没有特别的意义,它只代表着我真实的名字,我亲爱的父母为我起的乳名。 + +2012 年 5 月,在间隔了八个月后,我在博客发布了只有一张 404 的照片。同时,我将那个 Blog 的简介改成了“暂时离开”。自那之后,便准备放弃更新。 + +我累了,因为我已不再年轻。 + +当我抱怨没有人在自己的 Blog 上留言的时候,并没有想到使自己写作陷入停滞状态的并不是那些不留言的访客们。原因仅仅只是,在我心里,自己已经不再年轻。日复一日地思考,日复一日地剖析着内心的情感,久了,也就累了。做完一天的实验,写完长长的代码串后,便是漫长的发呆,望着空荡荡的后台不知如何下笔。写了、删除,然后重新是一样的动作。 + +许巍在《那一年》唱道:“这么多年你还在不停奔跑,眼看着明天依然虚无缥缈,在生存面前那纯洁的理想,原来是那么脆弱不堪。” + +真是这样吗?对于我而言,情况似乎还没有那么糟糕。 + +我仍然热爱着写作,热爱着那些相似的博主,我也正试图让自己重燃对进步的渴望。 + +“你曾拥有一些英雄的梦想,好像黑夜里面温暖的灯光;怎能没有了希望的力量,只能够挺胸勇往直前。” + +且听书吟是关于雨帆的生活态度,雨帆的故事将在这里书写。 + +不再有迷茫、无奈,我愿意重新亲近这个自留地,让自己的名字带上我的每一天。 + +雨帆就是我,一直很年轻的孩子。 + + diff --git a/src/content/pages/guestbook.mdx b/src/content/pages/guestbook.mdx new file mode 100644 index 0000000..570c726 --- /dev/null +++ b/src/content/pages/guestbook.mdx @@ -0,0 +1,23 @@ +--- +title: 留言簿 +slug: guestbook +date: 2012-01-25 02:20:11 +updated: 2024-04-08 12:27:27 +cover: /images/2019/05/2019051406592297.jpg +published: true +--- + + +<MusicPlayer netease={2109088527} /> + +耳机里面单曲循环着《水中花》。曾经,很长的一段时间我喜欢听这首歌。 + +“凄冷风雨中,多少繁华如梦”,一句道出了人生的真谛。淡淡的愁绪如这淡淡的花片,淡雅而平淡。繁华如梦,往昔如何的绚烂,到头来,都如昨夜的轻梦。曾经的万紫千红,却已随风吹落,似水年华流走,不留踪影。以花比人,人似飞花一样绚烂,奈何韶光易逝,丝毫不给你时间挽留。 + +那水中的花朵,强要留一抹红,奈何已经辗转在风尘,不再有往日的娇艳。就像博客里的文字,写了又删,删了又写,反复咀嚼的只是那些无人问津的日常。飞花想留住逝去的韶华,但时光却不容飞花的叹求。就像是满留疮痍的留言板,空余丝丝惆怅与寂寥。 + +纷纷飞花已坠落,往日写博客的深情早已成空。访客匆匆而过,谁又能在此片刻停留?我感怀飘零的花朵,尘世中无从寄托,任那风吹雨打也沉默,仿若我内心真实的写照。 + +草木无情,有时飘零,人生易老天难老。飞花易逝,岁月无情,有些博客就这么消失了,而又有着新的博主到来…… + +人生似飞花匆匆,飞花也有过绚丽。只是,当多年后的你再次看到这些留言时,是否能像飞花一样泰然。 diff --git a/src/content/pages/links.mdx b/src/content/pages/links.mdx new file mode 100644 index 0000000..ff3ebef --- /dev/null +++ b/src/content/pages/links.mdx @@ -0,0 +1,35 @@ +--- +title: 友人帐 +slug: links +date: 2012-01-25 02:20:11 +updated: 2024-04-08 12:27:27 +cover: /images/2019/05/2019051407200569.jpg +friend: true +published: true +--- + + + +<MusicPlayer netease={26192704} /> + +生活有很多面。经历、遭遇、过去、未来。正发生的、曾经发生的、或即将发生的。感情的迁移、心态的改变、外貌的成熟。这些都是。 + +而其中,最经常发生、时刻发生的,是相遇与分离。 + +有些人一辈子只能见一次,有些人见过很多次,却不知道彼此的名字。有些人记住了彼此的名字,而后相忘。有些人无法忘记对方,所以对回忆与过去留下了遗憾。 + +而其实,博客亦是如此。 + +对朋友的定义,字面上就已解释得一清二楚。两个“月”字,朋字何解?不必朝夕相处,而是时常想念。朋友,是一个永远被人不断提起的话题。因为人们的相遇不断。因为我们不断遇到对的人,并愿与之交好。 + +而其实,友链亦是如此。 + +写了七年多的博客,重谈友链,感触颇丰。 + +时至今日,我还能想起第一次去别人博客留言要链接的紧张感。记得当时才写博客,忐忑不安地四处留言求连接。依稀记得小白姐姐很好说话,虽然彼此并不熟悉,但还是和我换了链接。写博的日子长了,链接也就慢慢丰富起来了,也就有了专门的链接页面,专门的分类美化…… + +倘若要让我给博客一个形象的比喻,我想,应该是月台吧。在古代建筑里,月台原本是指正房、正殿前没有遮拦的平台,因为视野开阔,正适合凭栏赏月,所以得名。月即思念,登台守望。我相信,彼此交换的链接,就像是这茫茫“网络铁轨”上的一间小站,目睹着来来往往的访客,在此遥望着远方等候博友归来。 + +无论过了多久,无论白天与黑夜,博客是永恒的长亭,任你来来去去,悲欢离合,它只在那里。不悲,不喜。 + +我说,我只想做个博客里面的守望者,我会陪你们一起,我们一起守望幸福,等待下一次遇见…… diff --git a/src/content/posts/2009/2009-10-29-phoenix-flowers.mdx b/src/content/posts/2009/2009-10-29-phoenix-flowers.mdx new file mode 100644 index 0000000..a8cb116 --- /dev/null +++ b/src/content/posts/2009/2009-10-29-phoenix-flowers.mdx @@ -0,0 +1,37 @@ +--- +title: 凤凰花开 +slug: phoenix-flowers +date: 2009-10-29 04:56:30 +updated: 2020-10-28 18:51:55 +tags: + - 高考 + - 厦门 + - 凤凰花 + - 成功 +category: 文章 +cover: /images/2019/05/2019051817144382.jpg +summary: 凤凰木,被誉为厦门的市树。当你漫步于厦门街头时,除了亚热带常见的棕榈,看得最多的树,怕就是它了。人行道上,放眼望去,一行行的都是凤凰树。 +--- + + +<MusicPlayer netease={109734} /> + +凤凰木,被誉为厦门的市树。当你漫步于厦门街头时,除了亚热带常见的棕榈,看得最多的树,怕就是它了。人行道上,放眼望去,一行行的都是凤凰树。虽已是金秋十月,对于亚热带的厦门,只算是夏至未至。 + +故那原本在盛夏开得烂漫的凤凰花儿,此刻依旧开了大半。火红的花儿挤着、簇拥着,占了大半个树儿,远远望去像薄雾一般看不真切,只感觉似火在树丛中跃动。只有走到近处,眯起眼睛时,才可以看到那点点的花瓣、细蕊。比起故乡的枫叶,这凤凰花儿多了一番迷人,少了一番萧瑟。 + +穿行于漫天的火红之中,忽地心里一紧,抬头望这凤凰木,这情境似在哪见过。有时觉得自己像《麦田里的守望者》中的那只羔羊一样。一次次地向前走,却总是逃不出命运安排的怪圈,总是一次次地回到起点。 + +哦,对了。这相似的情形曾发生在三年前…… + +那时该还是盛夏时节,知了依旧在树上不知疲倦地鸣唱。午后的阳光,照得人发倦,一切事物倍感朦胧。也就在那个午后,在那火红的凤凰花的簇拥底下,我同其他同学一起对着主席台的老师进行中考百日誓师。一切都是那么不真切,那么朦胧。时光的流逝到了这里,仿佛静止了一般。而记忆之中的画面,也似乎定格在了这一瞬间。只记得宣誓的最后,语文老师动情地说道:“你们看那凤凰花儿都盛开了,那我们离成功还会远吗?” + +是啊!花开象征着收获,象征着挥洒汗水之后的成功,亦如人生之中拼搏的种种。起初,在最开始的几年里,凤凰树是不开花的。就像一棵普普通通的树,你天天从它下面走过,却从未抬头驻足,甚至探寻它的来历,只当它是一棵普普通通的树。但是,在饱尝了几载的风风雨雨之后,终有一天,如同这个午后,凤凰树会对着阳光,绽开最美、最火红的花朵。也就是在这时,你才会驻足,才会惊讶:这究竟是一棵怎样的树? + +也还记得在那一年,经过无数个日日夜夜的苦读,最终,在凤凰花的映衬下进入考场,也最终在这花的映衬下拿到了重点中学的录取通知书。毕业联欢晚会上,我是最闪亮的那一个。青春中最美丽的花朵也由此绽放在那个夏季…… + +静心回想,其实人生就是这样一棵树:一开始就是不断的积累与拼搏,并不显眼、并不出众。只有披荆斩棘,闯过生命中种种关卡之后,你才能像树一样开放出人生中动人的一枝奇葩! + +抬头看这凤凰花,三年前的情境依旧让我感动。凤凰花开,生命经过默默拼搏后创造的最动人之景。而现在,身处高三的我,不也同样经受着人生中的又一次蜕变吗?想到这,我的脚步不觉在这火红的花海中加快了…… + + diff --git a/src/content/posts/2010/2010-03-25-swan-of-thought.mdx b/src/content/posts/2010/2010-03-25-swan-of-thought.mdx new file mode 100644 index 0000000..2956655 --- /dev/null +++ b/src/content/posts/2010/2010-03-25-swan-of-thought.mdx @@ -0,0 +1,21 @@ +--- +title: 思想的天鹅 +slug: swan-of-thought +date: 2010-03-25 02:20:11 +updated: 2019-05-18 19:27:27 +tags: + - 思想 + - 天鹅 + - 文字 + - 时间 +category: 文章 +cover: /images/2019/05/2019051819264475.jpg +summary: 天行健君子以自强不息。而对于思想,我则将它比做天鹅。不为其它,只因这思想太轻盈,有着一种如同天鹅翱翔般柔美。 +--- + + +<MusicPlayer netease={268154} /> + +天行健,君子以自强不息。而对于思想,我则将它比作天鹅。不为其它,只因这思想太轻盈,有着一种如同天鹅翱翔般的柔美。看似很近,却又是很远,是那么的不可触及。 + +思想如同天鹅般轻舞、飞翔,最终融汇于字里行间。文字、书本只是它的承载体,只是将它收集归纳。时光的流逝也许会将那一本本日记本刻上道道伤痕,让这白皙的纸张变黄变碎。但承载于其中的思想却不朽。它们将始终像天鹅般洁白,在我心头飞翔。 diff --git a/src/content/posts/2010/2010-09-17-cherry-blossoms-withered.mdx b/src/content/posts/2010/2010-09-17-cherry-blossoms-withered.mdx new file mode 100644 index 0000000..8a0acd2 --- /dev/null +++ b/src/content/posts/2010/2010-09-17-cherry-blossoms-withered.mdx @@ -0,0 +1,38 @@ +--- +title: 樱花谢了 +slug: cherry-blossoms-withered +date: 2010-09-17 10:50:41 +updated: 2019-05-18 19:23:01 +tags: + - 高考 + - 青春 + - 樱花 + - 小四 + - 花谢 + - 结束 + - 美丽 +category: 文章 +cover: /images/2019/05/2019051819204032.jpg +summary: 三月,该是樱花开放的季节。而三月之际开放的鲜花,却不止樱花一种。但凭心而论,真正能触动心弦的词,该是樱花。 +--- + + +<MusicPlayer netease={1331313370} /> + +三月,该是樱花开放的季节。而三月之际开放的鲜花,却不止樱花一种。但凭心而论,真正能触动心弦的,还是樱花。 + +第一次接触樱花,是从小学的音乐课本中得来的。那首极具日本风格的歌曲也由此铭记于心。真正见到樱花时,应该是初一了。初春的午后,和同学们一同去大明湖看樱花。远远望去,湖边树上全是粉红的一片,似淡纱,似粉彩,似迷雾。走近了才发现,它们全是由一朵朵的樱花构成的。低头拾起一朵樱花,它是多么细小、纤弱、惹人怜爱。一阵风吹过,下起一阵花雨。无数朵樱花随着风纷纷扬扬地撒下,空中的世界分明变成了花的海洋,也许神话中的天女散花不过如此吧!樱花点点,缀在行人的头上,肩上,夹在了我怀中的笔记本里,也落在我的心头…… + +遐想相隔不远处的岛国,是否也发生着这相似的一幕呢? + +不由得想起了《悠久之翼》里的那个午后,男女主人公在樱花雨下的漫步。粉红的基调配上朦胧的爱情、小心的试探和交织的羁绊,让一切变得美好,似不褪色的童话般动人。又想起川端康成,他是否依旧步行在伊豆泥泞的路上,踩着碎花,去追寻自己的舞女呢? + +总觉得樱花很美,美到极致,美到忧伤。似乎生来就有为悲剧做配角的资质。不因其他,只因为它的柔弱与易逝。查阅了《大英百科全书》,上面说它的花期只有3~5天。可是真正挺过的又有多少?它们中的绝大多数,都在开得最美最艳时离开枝头,恣意地在空中飞舞,旋转,飞散。以自己的一生,来完成这最美的场景。故说:樱花之美,是死亡之美,是充满激情并令人哀伤的美。一如《恋空》中的男女主角,在樱花下相爱,又在樱花下生死分离。 + +而人生是否也曾有过一场这样的美丽呢?我想,我们每个人都曾有过,那便是青春。也许如小四所言:“青春是一道明媚的忧伤。”但这忧伤的来源便是它的消逝。青春的我们、朝气、阳光、充满活力。如花的笑靥、粉面、丹唇、桃膝是我们的标志。我们笑过、哭过、努力过、奋斗过、贪玩过,一起走过青春,绽放出这一生一次的最动人的光彩。一如这三月的樱花的绽放。 + +但,这忧伤终究要来,青春终究要结束。高考完的那一刻,也许就是青春旋律的休止符。我们终究要长大,跨向社会,迎来另一个开始。 + +而此时,樱花谢了。 + + diff --git a/src/content/posts/2011/2011-01-04-old-train-site.mdx b/src/content/posts/2011/2011-01-04-old-train-site.mdx new file mode 100644 index 0000000..6a516c9 --- /dev/null +++ b/src/content/posts/2011/2011-01-04-old-train-site.mdx @@ -0,0 +1,42 @@ +--- +title: 旧月台 +slug: old-train-site +date: 2011-01-04 05:22:43 +updated: 2019-05-18 19:07:52 +tags: + - 记忆 + - 月台 + - 离别 + - 重聚 + - 相逢 +category: 文章 +cover: /images/2019/05/2019051819045868.jpg +summary: 夏日傍晚的太阳已收敛了它一天的炎热,仅洒下点点余辉,投射在路面上。在这个略觉清爽的午后,我沿着屋后早已废弃的铁轨开始了随意的散步。 +--- + + +<MusicPlayer netease={287035} /> + +夏日傍晚的太阳已收敛了一天的炎热,仅洒下点点余辉,投射在路面上。在这个略觉清爽的午后,我沿着屋后早已废弃的铁轨开始了随意的散步。 + +也许是因为将之废弃不用,更或许是时间的漫长,棕红色的铁锈将其覆盖,斑驳的马齿苋、狗尾巴草将之团团包围。它,快被人忘记了吧。 + +双脚踏在其中一根旧铁轨上,玩起了儿时最喜欢的 Stand by Me(注:出自 1986 年的一部美国电影)。哎,就是在铁路上走啦。张开双手尝试着向前走,一次次地滑下来,又一次次地重新站起…… + +不觉临近了这座老月台。其那早已被青苔覆盖的站牌上的站名早已被时间磨洗干净,无从辨认。白瓷砖拼成的安全警示线不知从何时起已被来来往往的行人踩得支离破碎。斑驳的地面不知经历了几代的风风雨雨,记述着多少时光中的点点滴滴。曾经谁的谁在这里离别,又是谁的谁在这里等待、遇见…… + +远处的铁路闸道口又响起了叮咚叮咚的警笛声。在呜咽的汽笛声与铿锵的车轮撞击声中,一辆列车呼啸而过,驶向远方…… + + + +声音渐远渐消,思绪不觉恍惚起来。对于列车,我总有一种特殊的情怀。小时候的学校旁边就是火车道,每天不知何时,就会有一辆列车从上呼啸而过,驶向未知的尽头。也曾想过去探寻那遥远的未知之地,可每每走了许久,便放弃追寻。在儿时的联想中,铁轨永远是无穷无尽的,而其上的列车也是终究不会停的。 + +然而,列车终会停留,鸟儿终会停歇,马儿总会停下。对于火车而言,这停留之地便是月台。 + +是起点也是终点,是开始也是结束;是欢聚也是离散,是出发也是归宿。 + +有多少次,我也曾被卸在月台,又有多少次,我也曾从月台离去,我不知道自己终究要去往何方?回想近些年来的生活,别离总多于团聚,失望总多于获得。寂寞、惆怅,和一份深沉的苍凉,常是我密切的旅伴。离去不是离去,心仍萦留于亲情,归来不是归来,浮土又焉能扎根? + +静心想想,其实人生的聚散往往并不像徐志摩写的那样:轻轻的我走了,正如我轻轻的来,挥一挥衣袖,不带走一片云彩。就像这古老的月台曾经上演过多少聚散离合?它记载过多少悲欢离合、喜怒哀乐,又承载了多少依依惜别、迎来送往?聚也依依,散也依依,聚散两相依!不知古老的月台是否会为人们伤感的离别动容?是否为人们流露的真情打动?月台上的人流不断地更换着,送走一批又迎来一批,最后只归于寂寥,唯一仅存的是依然矗立在那的旧月台,记录下那些曾经的喜悦与哀愁。而那些真挚情谊与真情实感依旧会在新的月台上继续记录着……续写着…… + + diff --git a/src/content/posts/2011/2011-07-09-19-year-old.mdx b/src/content/posts/2011/2011-07-09-19-year-old.mdx new file mode 100644 index 0000000..9c046b2 --- /dev/null +++ b/src/content/posts/2011/2011-07-09-19-year-old.mdx @@ -0,0 +1,73 @@ +--- +title: 19岁的“雨季” +slug: 19-year-old +date: 2011-07-09 13:01:20 +updated: 2019-05-18 19:40:45 +tags: + - 花季 + - 雨季 + - 青春期 + - 烦躁 + - 思考 + - 告别 +category: 文章 +cover: /images/2019/05/2019051819385367.jpg +summary: 这样的雨,实在是让人烦恼,接连数日,没有停的时候。这样的雨里,想做的事情实在很少。天空灰蒙蒙的,心情也仿佛蒙了灰尘,让人感觉整个世界变得忧郁而烦闷。 +--- + + +<MusicPlayer netease={114852} /> + +这样的雨,实在是让人烦恼,接连数日,没有停的时候。 + +这样的雨里,想做的事情实在很少。天空灰蒙蒙的,心情也仿佛蒙了灰尘,让人感觉整个世界变得忧郁而烦闷。 + +对于雨天,从小就是心怀不平的。 + +只那么一夜,树叶洒落一地,不由得惊叹秋雨竟如此冰冷无情,想起曾经读过的许多雨天的文章,总是不了解作家的心境,不了解他们怎么会有那样美妙、美好的感觉,自己始终无法体味。 + +就在深秋的一个黄昏,那拍落了叶的街头树与自己相对而立,默默无语地看着一如既往的街景和匆匆的行人,偶尔有一片叶悠悠落下,就这样悄然而立,接受暮里落叶飘零的情意。 + +难道花季来过,雨季已悄然来临? + +花季……风和日丽的港湾…… + +虽然是在措手不及间踏上这样一条未知的路,虽然花季初至也曾经彷徨,但永远无法忘却的是美丽的心情;永远不放弃的是成长的意义,没有任何感伤,只有如期而至的平静与欣慰。 + +没有显赫的身世,没有令人瞩目的才能,却很早就学会用神的笔画着:“我爱祖国”…… + +没有英俊的外表,没有名牌的衣裳,但这并不重要,阳光、闲适不就是一种自然舒适的心情? + +没有人注意自己,也不期待有人为自己鼓掌。毕竟花季不是一路鲜花,一路喝彩…… + +因为花季中也有无数飘雨的日子…… + +常常被一些真挚的情意感动而流泪,是在花季里呢? + +喜欢在黑夜里孤灯下遥望繁星,聆听“吱吱”的昆虫声,是在花季里呢? + +那些被伤害的日子里,学会去思考,去面对,去品悟,是在花季里吧? + +我的花季,不是浪漫的粉红色。 + +以为 19 岁时开满鲜花的,19 岁的字典里也没有“忧伤”这个词,但走进花季,才明白自己和别人不同,也没有资格拥有他们拥有的一切欢笑,自己保留的是一种真诚,不断地使自己完整,不断地寻求自知,体验生活自己拥有的,也只是心底纯净的蔚蓝色的天空。 + +那一切缤纷的往日在脑中一遍遍重复,像一部黑白的老电影,亲切至极而依然毫无厌倦,是不是他也曾注意,那时的许多美丽的黄昏? + +花季是一条路,注定每人都要走过,都要面对,站在这个路口,会想起失败和失败者,想起跋涉和跋涉者……但别无选择,我们属于这条路。 + +总是想起年少时有过的许多幻想,都在岁月积累的颠簸中碰撞坍塌了,伤心、感慨,昔时难再的悲伤,但谁不是这样?谁的心不是在这样的坎坷中成长起来的,庆幸的是有失去就有得到,就在这些磨难之后,才会进入一种境界,才会拥有一种面对现实的决心,一种明了生命的镇定,就算付出了生命中最宝贵的年华,也无需太在意,不是么?我们所追求的一切,在自己看来却是美丽令人心悸,但最终要得到它还要经过岁月的洗礼,这难道不是一种无可奈何的安排吗? + +那么,就让自己忘记得与失。 + +走了,花季终于永远地走了,而自己永远也无法再抓住那纯好梦幻时光,可是,如果在走出花季后,能得到一种原本无法认知的感悟,那么又何不笑着面对命运呢? + +让自己向花季道别吧!如果心真的已不再年轻,再也想不起回忆,那么,就像花季道别吧。 + +如果走出花季以后,每一件伤心的往事都能让自己深深地醒悟,每一次感悟都能让自己成长许多,每一次成长都能让自己正视过去与现在,每一次回顾中,每个有雨的日子,都能在心底抽出一张浅浅淡淡的风景……那么走出花季又有什么不好呢? + +于是,就在雨季中道别花季…… + +然而,夕阳里,风景依旧迷人。 + + diff --git a/src/content/posts/2011/2011-08-23-drip-records.mdx b/src/content/posts/2011/2011-08-23-drip-records.mdx new file mode 100644 index 0000000..3203826 --- /dev/null +++ b/src/content/posts/2011/2011-08-23-drip-records.mdx @@ -0,0 +1,36 @@ +--- +title: 杂思——点滴记录 +slug: drip-records +date: 2011-08-23 00:12:31 +updated: 2019-05-18 19:45:35 +tags: + - 琐碎 + - 杂思 + - 雨夜 + - 随感 + - 点滴 +category: 文章 +cover: /images/2019/05/2019051819444155.jpg +summary: 今天下午的厦门下起了雨,闷热而又纷乱,似乎与闷热的午后不相协调。一切显得是那么的突兀,就像那杂乱不堪的思绪纷纷扰扰洒落。 +--- + + +<MusicPlayer netease={1426112587} /> + +**(一)雨来** + +今天下午的厦门突然下起了雨,闷热的午后与纷乱的雨水形成了不协调的对比。一切显得格外突兀,仿佛与那杂乱不堪的思绪相呼应。豆大的雨珠不断洒落,不一会儿地面上便形成了一条条小溪。匆匆跑过的行人,没有带伞的他们,雨中匆忙行走。楼下的小孩在屋檐下唱着:「两只老虎,两只老虎,谈恋爱,谈恋爱。一只是公的,另一只也是公的。真变态,真变态。」。 + +**(二)心乱** + +安静的午后突然下起了雨,我原本专心阅读的心情却被打乱了。一直以来的烦躁在心头涌动,我望向窗外,心中不禁涌起无数思绪,却又无法抓住其中的任何一点,让人苦苦追寻…… + +**(三)来电** + +雨依旧在下着,嘈杂的雨声渐渐让人感觉到宁静。就像是一种独奏曲,掩盖了周围的一切,只有雨声在耳边回荡。然而,手机突然响起,范玮琪的《那些花儿》在单曲循环中轻声哼唱,如同一场扰乱阵雨的旋律。 + +不远处的手机持续震动,闪烁的来电提示灯与单曲循环的铃声交织在一起,不断扰乱我的思绪。我拿起电话,又放下,失神地望着窗外,一丝苦涩涌上心头。对方终究失去了耐心,挂断了电话。 + +终究只是一场突如其来的阵雨,来得快,去得也快。不过 20 分钟,雨停了,阳光重新露面。楼下的小孩开始在雨后的街道上奔跑嬉戏,溅起一片片小水洼。我走出门去,穿梭在厦门少见的小巷中,踩着泥泞的小路,渐行渐远…… + +嗯,又是一个难得的凉爽下午! diff --git a/src/content/posts/2011/2011-09-06-the-beginning-of-blog.mdx b/src/content/posts/2011/2011-09-06-the-beginning-of-blog.mdx new file mode 100644 index 0000000..de31fb2 --- /dev/null +++ b/src/content/posts/2011/2011-09-06-the-beginning-of-blog.mdx @@ -0,0 +1,36 @@ +--- +title: 开始 · 起点 · 轮回 +slug: the-beginning-of-blog +date: 2011-09-05 16:04:27 +updated: 2019-05-18 20:02:33 +tags: + - 起点 + - 开始 + - 迷茫 + - 轮回 + - 梦想 +category: 文章 +cover: /images/2019/05/2019051820015162.jpg +summary: 经历了无数次的选择无数次的徘徊,最终还是选择了独立博客,这亦或是起点亦或是轮回。 +--- + + +<MusicPlayer netease={1899950648} /> + +经历了无数次选择与徘徊,最终还是决定创建独立博客,这或许是一个新的起点,也或许是一次轮回。 + +——题记 + +我爱上文学大概是在小学六年级,第一次作文获奖,被老师在班里朗读。我依稀记得同学们投来的羡慕眼光和自己内心的自豪。从那以后,我对语文的兴趣一发不可收拾,《读者》、《青年文摘》、《散文》等阅览室里的杂志都被我读遍了,里面的好词好句都被我收录在自己的笔记本里,而我的喜怒哀乐则记录在私密的日记本里。这一切都随着一次次搬家和奔波,渐渐消逝了…… + +曾经幻想过,如果还能记得当年的那些童言稚语和豪情壮志,会是怎样的一番景象。然而,时间最能冲刷一切,再痛彻心扉的记忆、再刻骨铭心的海誓山盟,也只是曾经。一切都会过去,就像当年的那个小小的文学梦想。 + +自从进入初中,一切梦想不得不被搁置一旁。那些发黄的摘抄本,如同一地的瓜子壳,人已走,只留下狼藉供人参赏…… + +再次重新拾笔是在高二,一次偶然的发现让我接触到了博客这个新生的网络产物,并由此再次点燃了我的写作热情。然而,高三的升学压力又一次让我放弃,曾经的梦想不得不再次搁浅。写作、停笔,写作、停笔,一次又一次的轮回,一次又一次的努力。想起希腊神话里的西西弗斯,一次又一次推着石头到山顶,又看着石头一次次滚落。这是宿命,或许也是无奈。 + +木木木木木空间里的那个广告让我再次产生了写博客的冲动,纠结了很久后,最终选择了 WordPress。昔日的 QQ 空间、网易博客已经好久没有更新。重拾博客,这是我自己的选择,或许也是一个新的开始…… + +仅以此文纪念自己再次写博,也作为再次踏上梦想旅程的一声呼喊。 + + diff --git a/src/content/posts/2011/2011-09-11-association-of-old-books.mdx b/src/content/posts/2011/2011-09-11-association-of-old-books.mdx new file mode 100644 index 0000000..77a6e6e --- /dev/null +++ b/src/content/posts/2011/2011-09-11-association-of-old-books.mdx @@ -0,0 +1,35 @@ +--- +title: 旧书之联想 +slug: association-of-old-books +date: 2011-09-11 08:07:38 +updated: 2019-05-18 20:08:42 +tags: + - 回忆 + - 旧书 + - 联想 + - 文化 + - 碎片 + - 余秋雨 + - 文化苦旅 + - 灵魂 +category: 文章 +cover: /images/2019/05/2019051820064669.jpg +summary: 每本书都有属于自己的思想,亦可称之为灵魂。而这灵魂的载体便是纸张和文字。时间的流逝,可以令书本原本白皙的直面发黄、生霉。就像是少男少女的洁白的双手、粉嫩的面颊,在光阴的长河的洗涤下变得暗淡、起皱。 +--- + + +<MusicPlayer netease={4879351} /> + +每本书都有属于自己的思想,亦可称之为灵魂。而这灵魂的载体便是纸张和文字。时间的流逝,可以使书本原本白皙的纸张发黄、生霉。就像少男少女的洁白双手、粉嫩面颊,在光阴的洗涤下变得暗淡、起皱。但纵使一本书再破再旧,其中的灵魂却不朽。 + +儿时最喜欢在外婆家待的地方,便是那个装满旧书的小书柜。一打开柜门,扑鼻而来的是一股霉味。书架上,一列列花花绿绿的旧书排得整整齐齐。许多书的纸张已经泛黄,不少书的表面蒙上了淡淡的薄尘。而暴露在外的书脊,大多因年久而褪色,时间的久远可见一斑。随手抽出一本线装的《石头记》翻阅,早已不再使用的竖排文字、从右至左的阅读顺序、略显生硬粗糙的插图、外公和母亲在上面的批注,无一不让人联想回味那段消逝的过去。忽地想起《阿长与〈山海经〉》中的那本《山海经》,是否也是这样一本旧书呢? + +一本旧书,或许是另一种价值的体现吧!想起那些埋藏于莫高窟内的经书,由此引发了一股延绵至今的敦煌热。《文化苦旅》中曾这样记述:众多外国学者不远千里来到此处“取经”,以极低的价格从王道士那里购买经书。而同时代的官员对此却充耳不闻,甚至加入强盗的行列,收缴经书并作为仕途的“垫脚石”。这是时代的悲哀,亦是时代的必然,民族的悲痛。我们无法评论早已化为一抔黄土的王道士,而我所痛心的是在这场野蛮人的“掠夺战争”中那些被人损毁的书籍。还未曾见天日,公诸于世,却早早零落成碎片。这些经书承载着不为人知的历史与文化,纵使它们支离破碎,文字模糊不清,它们的存在亦是永恒。 + +可以说,一本旧书,同时也承载着一段过去。 + +漫步于山大的校图书馆中,我最喜欢驻足的地方便是那些有着久远年代书籍的书架。随手抽出一本《梦溪笔谈》,吹去表面的灰尘,手抚泛黄的纸张与那斑驳的前人注释,心中顿生一种历史的沧桑感与虚无感。想起余秋雨在《文化苦旅》自序中提到:每个人都有极其矛盾的心理年龄。年少时的张狂、好奇与年老时的沉稳,有时可以集中于一人身上。而那厚重的文化,或许便是让人萌发苍老之感的缘由。这或许是我对旧书喜爱的另一种解释吧! + +时间的流逝,必将带走不可计数的旧书归于尘世。就像人,纵使你是红粉骷髅,也终将化为天地间的元素。然而,人和书是不同的。有人说:“少了一位老人,便少了一座图书馆。”我说:“少了一本旧书,便少了一段可以延续的已逝过去。” + + diff --git a/src/content/posts/2011/2011-09-14-hear-the-wind-sing.mdx b/src/content/posts/2011/2011-09-14-hear-the-wind-sing.mdx new file mode 100644 index 0000000..933514d --- /dev/null +++ b/src/content/posts/2011/2011-09-14-hear-the-wind-sing.mdx @@ -0,0 +1,38 @@ +--- +title: 且听风吟 +slug: hear-the-wind-sing +date: 2011-09-14 03:43:50 +updated: 2019-05-18 20:25:18 +tags: + - 回忆 + - 青春 + - 且听风吟 + - 恋爱 + - 懵懂 +category: 文章 +cover: /images/2019/05/2019051820203620.jpg +summary: 午后的时光,阳光明媚,气温尚好。我喜欢于此时在学校教学楼后的树荫下面读书,看天上风云变幻。而今天,却有人先来了。那是一段长达45秒的爱恋。 +--- + + +<MusicPlayer netease={22705507} /> + +午后的时光,阳光明媚,气温尚好。我喜欢在此时于学校教学楼后的树荫下读书,看天上风云变幻。而今天,却有人先来了。那是一段长达45秒的爱恋。 + +——题记 + +第一次听到“且听书吟”这个词,是在《格言》上的一篇小说中。故事中的女主人公携带一本《且听书吟》去见男朋友,只为寻找共同话题。“且听书吟”,这是一个令人遐想的词。去倾听风的吟唱,那么风是否会吟唱?它又在吟唱什么?它在为谁而唱?光是这个故事就令人浮想联翩。我也曾想像故事中的女主角一样,来一场刻骨铭心的爱,只是不敢爱,也没时间去爱。 + +常怀恋高一的那个午后,我和她在一起的时光。午后的晴空下,我一如既往地来到那树荫下,手执一本“大砖头”——《基础有机化学》,准备阅读。忽然如心灵感应般,一转头,身形一震,竟是她!此刻,她正在专注地啃着语文课本,不断记忆着,眉峰微皱,嘴唇微咬,脸色由红转白。阳光透过树叶的缝隙洒在她的发丝间,一粒一粒地,折射出迷人的光彩,让人如痴如醉。佛曰:“十年修得同船渡,百年修得同枕眠。”如果有前世今生,那么究竟多少次的回眸凝视,多少次的擦肩而过,才修得你我今世今日的相遇。时光依旧静静流淌,起了风。似那调皮的精灵,一次次把她额前的刘海弄乱,又一次次被她的玉手撩起…… + +真希望时光就这样静止,好留下这一刻的静谧与安详。远处篮球场上的呼喊声、耳畔的风声似乎都渐行渐远,愈发朦胧。天地间似乎只存在我们两人。而美好的时光总是短暂的。像那昙花,准备多日后的开放,虽开得动人,却转眼即逝,像火星,像烟花,像火柴。 + + + +大概是感受到了我灼热的目光,她最终注意到了我。起身,像蝴蝶一般掠过,带起一阵清风,消失在眼前。所留下的,只有那隐约萦绕在鼻翼间的一抹暗香…… + +曾看过一部名为《悠久之翼》的动漫,剧中的男主角在常去的废弃火车月台上遇到一个女孩。两个人相识、相知并最终恋爱。生活中的类似情境无时无刻不在发生,亦如这个午后。有时感慨,世界很小,两个人无处不相逢。也许这就是缘吧。 + +缘尽了,情散了。也许多年后的某个午后,我还会想起她。那是,一场长达45秒的爱恋。 + + diff --git a/src/content/posts/2011/2011-09-15-the-pain-of-lonely.mdx b/src/content/posts/2011/2011-09-15-the-pain-of-lonely.mdx new file mode 100644 index 0000000..a94e02b --- /dev/null +++ b/src/content/posts/2011/2011-09-15-the-pain-of-lonely.mdx @@ -0,0 +1,39 @@ +--- +title: 寂寞的疼痛 +slug: the-pain-of-lonely +date: 2011-09-15 08:42:13 +updated: 2019-05-18 20:30:43 +tags: + - 疼痛 + - 寂寞 + - 无奈 + - 安静 +category: 文章 +cover: /images/2019/05/2019051820293355.jpg +summary: 某个月明风高的深夜,我无意中打开学校的学生论坛。出奇的是,竟有2000多人在线,无聊的话题,纯表情的回复,似乎都在折射出一个词——“寂寞”。 +--- + + +<MusicPlayer netease={1867107328} /> + +某个月明风高的深夜,我无意中打开学校的学生论坛。出奇的是,竟有2000多人在线。无聊的话题,纯表情的回复,似乎都在折射出一个词——“寂寞”。 + +——题记 + +也不知道最近是怎么回事,莫名其妙地容易伤感,可能是受季节感染的缘故,也或许是自己本来就是个忧郁多愁善感的人。 + +开学已经近一个星期了,却依然感觉不到任何改变。或者是很多东西在不知不觉中变化了,只是自己太过茫然的眼睛没有发现而已。 + +写下这段文字,我抬起头回望四周。教室里,讲台上的老师依旧在那里讲着中国传统文化的历史渊源。而我们,似乎没有人真正在意课程的内容。讲台下,是一张张略显呆滞的面孔。有人拿起手机看起了小说,玩起了游戏;迟到的几位还在呼哧呼哧地啃着馒头;昨夜挑灯夜战的几位同学,现在已经安然入梦。而一切的一切,竟是那样和谐、生动,仿佛一场现场直播的舞台剧,其中的演员便是我们。一切的解释似乎只因寂寞。 + +很久之前就想写下这篇文章,关于自己、关于大学、关于生活。感觉有很多话想要说出口,可每每张口欲言时,却不知从何谈起。记事本上密密麻麻地记录着各种计划,又不断地“胎死腹中”。或许人的天性便是这样——想得很好,但在真正要实践时才发现,很多时候我们无法真正左右自己的…… + +每天,抬望眼,看窗前日出日落,感觉青春的年华正无可挽回地消逝。心里面满是空荡,似有潮水在心中涌起,又在某个不经意的瞬间悄然而逝。心绪总在无可无不可,无意不无意之间,一切都像是软绵绵的。我这是怎么了?不禁扪心自问。 + +大一的日子已经远去,大半个班的同学都选择了转专业,而那些昔日动人的故事和略显鲜明的面孔此刻正在我的记忆深处慢慢褪去颜色。宛如一张张破旧的黑白照片,铺满墙面,像那丢弃的瓜子壳般支离破碎、面目全非。对于未来大三的实习,我不敢想象。曾听人说过:工作就像一面镜子,我们要撞碎它,然后擦着锋利的碎片走过,血肉模糊,迎来新生。也许,这抑或是另一种传说般的将来…… + +夜色洒满大地,星幕挂上天穹。舍友早已入睡,鼾声、虫声、键盘的敲击声让这夜愈发静谧、安详。我荷起寂寞的锄,刨开相思的土,种下满院的荒芜。寂寞,是一只小小的舟,停泊在无人的野渡;寂寞,是一杯销魂的酒,让人不由自主,魂销骨瘦;寂寞,是一双深情的眸,怅望千里,凭空添出一段愁。某刻再回首,确是,陈柯断斧,几度苍凉。 + +寂寞,那道不忍触及的痛。 + + diff --git a/src/content/posts/2011/2011-09-16-bathe.mdx b/src/content/posts/2011/2011-09-16-bathe.mdx new file mode 100644 index 0000000..cd09253 --- /dev/null +++ b/src/content/posts/2011/2011-09-16-bathe.mdx @@ -0,0 +1,39 @@ +--- +title: 记忆 · 洗澡 +slug: bathe +date: 2011-09-16 12:33:50 +updated: 2019-05-18 21:01:17 +tags: + - 记忆 + - 洗澡 + - 过去 + - 澡堂 + - 新旧交替 + - 展望 +category: 文章 +cover: /images/2019/05/2019051820583532.jpg +summary: 不知什么时候起,澡堂这个词离我们越来越远了;也不知又是什么时候起,热水器步入大街小巷。而澡堂,只能成为记忆中的点滴碎片,点缀成串,交织成一幅幅似曾相识的画面。 +--- + + +<MusicPlayer netease={4879333} /> + +不知从什么时候起,澡堂这个词离我们越来越远了;也不知又是什么时候起,热水器走进了大街小巷。而澡堂,只能成为记忆中的点滴碎片,点缀成串,交织成一幅幅似曾相识的画面。 + +——楔子 + +记得小时候,我是怕洗澡的。不是因为洗澡不舒服,也不是因为洗澡麻烦,而是因为我是在女澡堂洗的。从小到能依稀记事知道男女有别时,我一直是被妈妈带到女澡堂洗澡。然而,这终究不是长久之计,大概在我四岁那年,我便开始跟随老爸在男澡堂洗澡。于是,我最初的澡堂记忆便从那时开始…… + +那时,大约是九几年的某个年代,改革开放的大潮如火如荼地进行着,农村集体合作制变成公有制的国企。国营食堂、国企员工宿舍、国营澡堂便是这一环境下的产物。而乡下人一般并不是天天洗澡的,即便在炎热的夏天,也是一周去一次澡堂。所以每到周末,一家人要去澡堂时,便显得像过节一般隆重。每到这个时候,工作了一天的老爸一手提着装着换洗衣服的手提袋,一手牵着我,走上很远去澡堂。于是,每到冬天寒风凛冽时,洗澡成为一种质朴的等待。 + +进了澡堂大门,交了钱,跨过弄堂口,经过女浴室,便到达我们的目的地。门口,照例是用棉绳撩起的厚重破棉布。进了门,扑鼻而来的便是一股澡堂特有的湿漉漉的味道。劣质的香皂、发霉的木头和刚洗完澡的人身上热腾腾的热气构成了这难忘的气味。洗发水、沐浴露一类的东西在那个时候还没有人用得起,上海牌的洗发膏和一元一块的廉价肥皂便是家家户户都爱用的洗浴用品。 + +放衣服的地方,是用水泥砌成的几条长条形石台,上面简陋地铺着一条草席。每次,照例是老爸把我抱上草席,然后不知从哪里用脚踢过来一双别人刚用完的、带着水汽的、永远不合脚的塑料拖鞋。长年的使用,使它的表面处处开裂,走起路来一深一浅。然而没有人在意这些,因为此时大家已经进入了浴室深处。掀开帘子,充斥耳边的便是各种各样的怪叫和大人们的呵斥声。早到的人,还可以看到精彩的“弄潮”表演。因为条件简陋,一开始,浴池里的水并没有混匀,往往是几个青年扑通跳下去,又被烫得哇哇怪叫地跳上来。照例是有几个青壮年会拿着盆,在池子里搅和一通,等水温上下均匀了才可以下脚。可是,水依旧很热。下了池子,不一会儿,便浑身通红似的像煮熟的大龙虾般跳上来,如此反复。而老人们,却是不怕烫的,一个个半躺在池沿上,或是哼着小曲,或是隔着老远地大声聊天。 + +记忆中的池水,永远是黄几几的。来得晚了,池底还会沉积起一层黄褐色的泥浆。也许就像《红楼梦》中宝玉所言:女人是水做的,男人是泥做的。然而,依旧没有人在意,也没有人会有所厌恶。大人们更多关注的是,池水够不够热,泡得舒不舒服。泡完澡,照例是要去冲淋浴。哪几个淋浴头水大,哪几个淋浴是坏的,每个人心里都有一本账。而往返于水池与淋浴室之间,看准时机的争抢,便是另一种不可或缺的技能。大厅里,那些泡完澡的老人们,一个个浑身冒着热气,靠在墙上幸福地打着小盹。时间对于他们而言,是极其缓慢的…… + +这样的记忆一直延续到千禧时节,单位盖了新楼分了新房。从那时起,各家各户开始安装起燃气热水器。而澡堂,也去得越来越少了。随着生活条件的不断改善,澡堂最终成为一段逝去的历史,沉淀于记忆之中。无意中在图书馆看到杨绛大师的《洗澡》,那些似曾相识的情形在某个瞬间唤醒了尘封已久的记忆。深夜又去下载了同名电影,殊不知最后竟然看得热泪盈眶…… + +时代的发展,总会带走许许多多的东西,楼宇替代了一砖一瓦的平房;新式五颜六色的时装抛弃了颜色土得掉渣的中山装、布拉吉;各色新时代的“三大件”叫嚣着自行车、缝纫机、手表的逝去……我,立身于时代发展的滚滚洪流之中,回视那些被人遗忘的过去。殊不知,一滴泪水,早已打湿了我的衣襟。 + + diff --git a/src/content/posts/2011/2011-09-18-ignorant-age.mdx b/src/content/posts/2011/2011-09-18-ignorant-age.mdx new file mode 100644 index 0000000..e25f440 --- /dev/null +++ b/src/content/posts/2011/2011-09-18-ignorant-age.mdx @@ -0,0 +1,41 @@ +--- +title: 懵懂的年华 +slug: ignorant-age +date: 2011-09-18 14:39:10 +updated: 2019-05-18 21:18:49 +tags: + - 流年 + - 青春 + - 年华 + - 懵懂 + - 爱恋 + - 记录 +category: 文章 +cover: /images/2019/05/2019051821092623.jpg +summary: 记得当时年纪小,你爱谈天我爱笑。有一回我们并肩坐在桃树下,风在林梢鸟在叫。后来不知怎么我们睡着了,梦里花落知多少。 +--- + + +<MusicPlayer netease={454182} /> + +记得当时年纪小,你爱谈天我爱笑。有一回我们并肩坐在桃树下,风在林梢鸟在叫。后来不知怎么我们睡着了,梦里花落知多少。 + +——是为题 + +现在已经是凌晨,放下手中握得发烫的笔,理清发胀的思绪,我开始想念你。窗外响起了夜虫的鸣叫,隔屋传来了老爸均匀的呼吸声。我想,你应该早就睡了吧。轻手轻脚地拿出一本装饰精美的本子,我开始埋藏对你的不尽思念。 + +拿起笔,又轻放下。在身上擦了又擦才落笔,生怕不小心弄脏了那只属于你我的本子。不经意间,眼前的本子似与你的面孔重合。那白皙的纸面恰如你那青春无痕的微笑,边角的几个小黑点正像那几个浅褐色的小雀斑。让人怜惜,不忍落笔。但,我还是写下一段文字,将一个不为人知的秘密藏在里面。哦,当然,你也是可以看的。只是,只是我还没准备好,怎么面对你。 + + + +还记得某个夏日的午后。阳光洋洋洒洒地占据了每个角落。暖暖的阳光,安静的教室,让人不由地从心底萌发出一分倦意。讲台上,物理老师还在那里忘我的讲着动量定理。对于早已听过竞赛的我,不听也罢。遂张望一番后,我开始观察你的一举一动、一颦一笑。金色的阳光,挥洒在你的身上,给坐在后方的我蒙上一层阴影。从我的视角来看,阳光在你的黛青色的发丝间跃动,粉白色的发卡上波光连动,似因阳光的照射而散发出一层绮丽的光彩,顿生朦胧之感。而身着的一袭白衫,令原本皮肤白皙的你更加迷人。 + +喜欢看你光亮的下巴和那微蹙的眉峰;喜欢看你咬着下嘴唇又松开,那下唇如何又沁红转白又变得更红;更喜欢看你额前的刘海,如何被风一次次地缭乱,又一次次被你的素手撩起……而这样的观察不知有过多少回。 + +在我的记忆里,起初,你是不那么起眼的。噢,对不起,我一直生活在“他们”的世界,用“他们”的语言同你交流。用我的话说,起初,你那内敛的美丽并未被我察觉。不知是何时你的回眸一笑,亦或是某一刻你那恬静的安详,我开始喜欢上了你。只是这喜欢,来得太突然,来得让我自己也无法相信。 + +遂不谈及这些,还记得你我初次见面的情形吗?新学伊始,我风风火火跑进才分好的理科班,却差一点把迎面走来的你撞个满怀。你满脸通红,低头从我旁边绕过。红扑扑的脸蛋,让人有一种上前咬一口的冲动。而那一低头的温柔,却恰似水莲花不胜凉风的娇羞。古人云:一笑倾城,再笑倾国。而你的娇柔却让我记住了你。随时间不断沉淀,演变为此刻的暗恋。 + +低头看表,1:00了。遂搁笔,轻合上那本只属于你我的本子。哦对了,也祝你做一个好梦。 + + diff --git a/src/content/posts/2011/2011-09-20-floral-sarong.mdx b/src/content/posts/2011/2011-09-20-floral-sarong.mdx new file mode 100644 index 0000000..ab3541e --- /dev/null +++ b/src/content/posts/2011/2011-09-20-floral-sarong.mdx @@ -0,0 +1,44 @@ +--- +title: 碎花布裙 +slug: floral-sarong +date: 2011-09-20 08:33:58 +updated: 2019-05-18 21:24:18 +tags: + - 时间 + - 回忆 + - 过去 + - 碎花 + - 布裙 +category: 文章 +cover: /images/2019/05/2019051821195094.jpg +summary: 儿时最喜欢做的事,就是傍晚同老妈的散步。漫步于夏日的傍晚,走过田野、小河,嗅着扑鼻的油菜花香,感受着迎面而来的略带凉爽的风。 +--- + + +<MusicPlayer netease={420693} /> + +时间的流逝总会带走些许旧事物,仅遗留下些许影子,投射于记忆之中。 + +——题记 + +儿时最喜欢做的事,就是傍晚同老妈的散步。漫步于夏日的傍晚,走过田野、小河,嗅着扑鼻的油菜花香,感受着迎面而来的略带凉爽的风。这大概是一天之中最惬意、最悠闲的时刻了。 + +每到这时,妈妈便会脱去穿了一天的化验室白大褂,换上一身的小碎花布裙。白皙的布面上点缀着细碎的靛青色的无名小花图案。一袭碎花布裙却将妈妈内敛的气质完全烘托出来。远远望去,是那样的美丽、动人。 + +曾读过张爱玲的小说,故事里的女子,无一不是身着旗袍。也曾在某本书上读过这样一句话:“每个女人都有属于自己的一身旗袍”。而妈妈却从未拥有过旗袍,那件布裙便是她的最爱。每次穿完,妈妈都要将它细心地洗净、晾干、小心地叠放于衣柜之中。也许这简单的碎花布裙,便是属于妈妈的“旗袍”吧。 + +我至今记得,那夏日傍晚的微风如何拂动着妈妈的裙摆,阳光透过树叶在她的裙子上投下斑驳的影子。妈妈低头对我微笑的样子,那样温暖而安详,仿佛整个世界都安静下来,只剩下我们母子俩的脚步声和不远处小河的潺潺水声。 + +时代一直在向前迈步,总有许多东西消逝或者改变,仅仅存留于记忆之中…… + +儿时常走的白马路,现在早已被灰尘覆盖,汽车一过,便扬起一阵沙暴;记忆之中的黄油油的田野,现在早已荒芜,无人耕种;而那袭碎花布裙,也不知被妈妈藏于某个角落,不再穿起…… + +穿行于都市的大街上,迎面走来一群群年轻貌美的少女。她们穿着百样,T恤、衬衫、泡泡纱、超短裙……但,竟无一人再穿起昔日流行的碎花布裙。也许,它同昔日上海滩的旗袍一样,定格于过去的某个画面碎片之中了吧。 + +每个时代都有每个时代的潮流。回想过去五六十年代的布拉吉、中山装,七八十年代的旗袍,新时代的多元化服饰。也许,这布裙在其中根本不算什么。就像大海之中的点点浪花,而它就是其中不为人注意的一朵,一闪而过,就此消逝。 + +曾幻想过这样的情形:梅雨时节,一妙龄女子身着一袭小碎花布裙,漫步于雨后的小巷。黛青色的布料,靛紫的碎花,同这同样深灰色的环境交融。一如穿越千年的青花瓷般,在这雨后的小巷中渐行渐远。 + +那是,一个永远不会褪色的梦。 + + diff --git a/src/content/posts/2011/2011-09-24-harry-potter.mdx b/src/content/posts/2011/2011-09-24-harry-potter.mdx new file mode 100644 index 0000000..d6eece3 --- /dev/null +++ b/src/content/posts/2011/2011-09-24-harry-potter.mdx @@ -0,0 +1,42 @@ +--- +title: 当青春不再魔法散场 +slug: harry-potter +date: 2011-09-24 05:07:26 +updated: 2019-05-27 06:56:38 +tags: + - 回忆 + - 青春 + - 花季 + - 梦想 + - 魔法 + - 哈利波特 + - 散场 +category: 文章 +cover: /images/2019/05/2019051821474615.png +summary: 对于今年的7月7日来说,是个值得纪念的日子,伴随着我们童年长大的《哈利波特》系列终于落下了帷幕。那些美好,柔柔消散,竟让人忍不住落笔想念。 +--- + + +<MusicPlayer netease={379785} /> + +对于今年的7月7日来说,是个值得纪念的日子,伴随着我们童年长大的《哈利波特》系列终于落下了帷幕。那些美好,柔柔消散,竟让人忍不住落笔想念。 + +曾记否,那部《哈利波特与魔法石》从童年时光进入你我的生活。奇妙的魔法,飞天的扫帚,激动人心的魁地奇比赛,还有那繁华多彩的对角巷,不为人瞩目的 9¾ 站台,丰富奇特的霍格沃茨魔法学校。无一不吸引着你我的眼球,挑动着我们的好奇心,去追寻、去探索。而这,便是我们青春与梦,记下我们最纯真的回忆。一次经历,一次纪念;你的夕阳,我的童年,谁的三分之一年? + +这些潮湿而又略带些温暖的记忆,不断于眼前浮动、破碎。回想起那些已逝的年华,我的思念化为细碎的雨,飘摇不定,醉倒于来时的路上。那些记得的忘记的,那些似水流年,时间总像细沙滑落于指间,记忆总像满地的碎玻璃,明媚中露着忧伤,让人心里面不由得的发胀。 + +感谢 J.K. 罗琳,是她,写下了这精彩的文字并搬上了荧幕。也由此,哈利、罗恩、赫敏这三个主人公同我们一起成长。从他们身上,我们总能找到些许自己的影子:友情、亲情、爱情;努力地学习、青春的懵懂、吵架与和解。他们就像我们一样慢慢地长大,慢慢地蜕变,慢慢地成熟。 + +每个同时代的儿童心底,几乎都藏着一个相似的魔法梦。记得当年的我,就一直梦想着是否会有一天,会有一只同样的猫头鹰落在我的肩头,给我一张来自霍格沃茨的入学通知书。也曾想拥有一把同哈利一样的“光轮2000”,骑着它自由飞翔于天际…… + +儿时的思维总是那么的天马行空,而以自己现在的成人眼光来审视,却是那么的幼稚好笑。对于已被埋葬的八度芳华,我所相信的真是就是绝大多数的同学奔波于月与月的三点一线,最大的悲剧就是父母的期待与失望,唯一的支撑就是未来。不知什么时候起开始忙于学习了,也未知从何时起我们放下了幻想。魔咒、神奇生物、魔法,这些昔日闪光的点滴记忆碎片早已被深埋于某个不知名的角落,不再提及。 + +突然想起高三毕业时,同桌那个爱笑的女孩一直小声地哼唱一首歌:“成长是一扇树叶的门/童年有一群亲爱的人/春天是一段路程/沧海桑田的拥有……我们都曾有过一张天真而忧伤的脸/手握阳光我们望着遥远/轻轻的一天天一年又一年/长大间我们是否还会再唱起心愿。” + +谁的谁从你的花季里走过,留下笑颜;谁的谁曾在你的青春里停留,温暖了想念;谁的谁又从你的雨季里消逝,溢满了泪水…… + +我们终究还是要长大,要放弃做梦开始忙碌。昔日的同学录上曾有这样一段话:“青春就是一场奢华的电影,我们煞有其事的忙碌,只为最终礼貌的下台。” + +而此时,青春不再,魔法散场。 + + diff --git a/src/content/posts/2011/2011-09-29-shallow-lonely-faint-miss.mdx b/src/content/posts/2011/2011-09-29-shallow-lonely-faint-miss.mdx new file mode 100644 index 0000000..2df3478 --- /dev/null +++ b/src/content/posts/2011/2011-09-29-shallow-lonely-faint-miss.mdx @@ -0,0 +1,39 @@ +--- +title: 浅浅寂寞,淡淡想念 +slug: shallow-lonely-faint-miss +date: 2011-09-29 04:44:28 +updated: 2019-05-27 09:34:50 +tags: + - 寂寞 + - 浅浅 + - 想念 + - 黑夜 +category: 文章 +cover: /images/2019/05/2019052708550328.jpg +summary: 夜 11:30,宿舍熄灯的瞬间,床头漆黑的夜色像某刻恬静的安详,心绪中无边无际的想念不觉纠缠。此刻,我想你了,好像此刻的孤单能有你相陪。将你们搂入怀中,轻嗅发丝间薰衣草的清香,心玄跟着挥舞懵懂。 +--- + + +<MusicPlayer netease={527799} /> + +夜晚11:30,宿舍熄灯的瞬间,床头漆黑的夜色仿佛是某刻恬静的安详,心绪中无尽的想念纠缠着我。此刻,我想你了,好像这份孤单可以有你来陪伴。想象着将你搂入怀中,轻嗅发丝间薰衣草的清香,心跟着挥舞着懵懂。 + +花季的末班车,上演了一场琴弦的离别,天真地以为游荡的音符的我找到的是五线谱般的舒适,所以安静地只想走好高三的最后一段路途。那些欢笑、泪水、某刻的甜言蜜语,一切的一切,就此定格。就像孩童信手涂鸦般,复写于人生的第一个身份转角的路牌。 + +一年过去了,三百多个日子,三百多种想法,三百多种心情,三百多次想念,三百多次回忆。 + +时间总会改变许多,不只是昔日素面朝天的笑颜,还有那言语中、故事里,悄然而逝的那份埋藏在彼此内心深处的真实。 + +刚上大学时,接到你的电话,跳动不安的激动,不停地询问各种故事,惊讶于听到的许多事情。而一年后的今天,再次接到你的电话,却只是淡然安静,无话可说,只能沦为一个倾听者。对于你的一切,不再惊讶。或许天生爱笑爱闹的你,到了哪儿都可以把它变成自己的小舞台。这些都是你该有的生活方式。一路相随,你好像从未孤单寂寞过。回顾过往的青春尾巴,想起了昔日的你我…… + +此刻的自己,静静地坐在杳无人迹的自习室,不知从何时起,习惯了这样的孤单,喜欢了这种静谧的想念。心跳的声音,呼吸的味道,手握浓茶的热度,敲击键盘的吧嗒,都像极了某刻内心的独白,抒写着一个沉思者最为深刻的内心沉淀。 + +查看人人网上大家的签名状态,仿佛每个人都在向前看,有些人已经开始了新一轮的奔波。而我,却不忍回首那唯一的美好,那段昔日的青葱年华,白衣飘飘的时代。此刻的我,只想放纵自己的悲伤、回忆、落泪,仅此于记述这段文字的时间里。 + +我们都曾有一张天真而忧伤的脸,长大间我们是否还会想起那些记忆? + +不想述说,却依旧书写;不想回忆,却依旧想念;不想落寞,却依旧悲伤。 + +记,第一次分手。 + + diff --git a/src/content/posts/2011/2011-10-02-the-losted-beautiful.mdx b/src/content/posts/2011/2011-10-02-the-losted-beautiful.mdx new file mode 100644 index 0000000..e4188dc --- /dev/null +++ b/src/content/posts/2011/2011-10-02-the-losted-beautiful.mdx @@ -0,0 +1,39 @@ +--- +title: 遗失的美好 +slug: the-losted-beautiful +date: 2011-10-02 14:19:35 +updated: 2019-06-05 12:10:07 +tags: + - 记忆 + - 美好 + - 遗失 + - 童年 +category: 文章 +cover: /images/2019/06/2019060512093940.jpg +summary: 如果海会说话/如果风爱上沙/如果有些想念/遗忘在漫长的长假/我会聆听浪花/任记忆里的爱情/在时间潮汐里喧哗,我会试着把那一年的故事/再接下去说完。 +--- + + +<MusicPlayer netease={1866489121} /> + +如果海会说话/如果风爱上沙/如果有些想念/遗忘在漫长的长假/我会聆听浪花/让记忆里的爱情/在时间潮汐里喧哗,我会试着把那一年的故事/再接着说完。 + +——题记 + +不知什么时候起,我睡着了。此刻,我猜,该是某个秋风乍起的午后。我蜷缩在外婆家门口的大藤椅上,头枕着小棉垫,身披着阳光,就这样定定地入睡了。那倾洒于身的光线已然没有了夏日的灼热,略显温和的温度辐射于这个清冷的初秋,让人不由得从心底萌发出阵阵温暖。 + +在这样一个温暖而舒适的午后,我坐在外婆家的门口同外婆一起晒太阳。调皮的光线透过门前大榕树上枯黄的树叶间隙,在地上投射出斑驳的亮斑。也同时投射在窗前、门上,随着轻风的吹拂不断地跃动着、追逐着。树梢上那只不知名的鸟儿偶尔也会叽叽喳喳地叫上几声,是在自言自语?还是在述说沐浴阳光的喜悦? + +渐渐地、渐渐地,四周开始安静起来。不断刮起的微风颓然离去,枝头那只扰人的雀儿也似入定般消了声迹。偌大的天地间仿佛只剩下了阳光和我,一切的其他都好似消散了踪迹。不知何时起,我也睡着了。四周静悄悄的,只剩下光线依旧温柔地拨动着我的眼皮,试图挑开我的双眼。 + +可是我的感官却依旧清醒着,整个人似梦似醒,灵魂好似脱离了躯壳,俯视四周。远处街头马路上,一辆辆老式拖拉机哒哒而过。隔壁的黄奶奶正坐在门口,咔嚓地修剪着前些日子才摘的老南瓜藤,准备晾晒。一直四处觅食的野猫从我跟前走过,擦过我的裤管,轻声地哼着“喵”,见无人理会便又渐行渐远…… + +而这一切的美好终究似梦一般破碎,那方记忆之中的阳光此刻也离我远去。那年年末,随父母离家去厦门谋生。都市的生活永远是喧闹的,白天的车水马龙,夜晚的灯红酒绿,没有了昔日小山村中的那份宁静与安详。而一座座拔地而起的楼宇,已然将阳光挡住,仅仅留下片片阴冷。突然想起自己很久没有像儿时那样毫无心绪地安然入梦了。一次次地从梦中惊醒,想起未完成的学业、计划,我的身后总是有一根温柔的鞭子,在鞭挞着我、激励着我,要为来日的生活奔波、奋斗。 + +有些故事,有些情思,终究只能发生在我们童年的时光中。那时,我们可以有大把大把的时光来坐在草地上,数天上飘过的云朵,唱着最为童稚的儿歌。困倦的午后时光,喧闹的庭前树梢,外婆在那里慢慢地讲述久远的传说。时间流逝,那些大把挥霍掉的日子,已然成为此时最为珍贵的记忆、瑰宝。飞扬的岁月、两小无猜的豆蔻年华,那些存在于头脑中的不尽故事,或属当时,或为过去。就像是那缕阳光,穿越了光与影的距离却终究只能在衣襟上留下一抹倒影。 + +那方小天地,早已远去了。国庆时日的返乡,却发现昔日的院子早已拆迁。我哭诉、我追寻、我叩问,回应我的仅有天地间的那一道风声。 + +童年,那段消逝的美好。 + + diff --git a/src/content/posts/2011/2011-10-04-countercurrent-river.mdx b/src/content/posts/2011/2011-10-04-countercurrent-river.mdx new file mode 100644 index 0000000..aa494c2 --- /dev/null +++ b/src/content/posts/2011/2011-10-04-countercurrent-river.mdx @@ -0,0 +1,42 @@ +--- +title: 梦断逆流河 +slug: countercurrent-river +date: 2011-10-04 12:39:00 +updated: 2019-06-05 12:17:11 +tags: + - 美好 + - 梦断 + - 逆流河 + - 幸福 + - 李献计 +category: 文章 +cover: /images/2019/06/2019060512164612.jpg +summary: 也许这个世界上本身真的存在一条逆流河。起源于大海、终于巨峰之顶。传说中,如果有人能够达到它的尽头,便会获得幸福。而你我便是用一生来追寻幸福的青鸟。 +--- + + +<MusicPlayer netease={1295704234} /> + +也许这个世界上本身真的存在一条逆流河。起源于大海、终于巨峰之顶。传说中,如果有人能够达到它的尽头,便会获得幸福。而你我便是用一生来追寻幸福的青鸟。 + +——题记 + +究竟是一条怎样的河流,竟会使得无数人为之追寻,甚至耗尽一生的光阴、年华只为一个子虚乌有的传说? + +也许从它诞生那一天起便注定了它一生的不平凡。因为它的与众不同,因为它的踪迹难寻,更或者,因为它的美丽传说。试曾想这样一条河流,波光潋滟,水声潺潺。有鱼儿在其中游荡,有大树在其旁相映成荫。看似普通的一条河流,可是它的水流却是从低处往高处流淌的,它便是逆流河。可是它又在哪里呢? + +突然想起昨晚在虾子酱的博客上看到的动画片《李献计历险记》,这是一部好坏参半的片子,有人捧也有人骂。但是当中的某些场景却深深地触动了我的心弦:故事中的李献计费尽心思地想打穿一部游戏,为此不惜卖肾、买毒品、走私国宝、和恐怖分子搏斗、将自己的手变成铁质的。因为,传说中打穿游戏后就能出现一扇门,借此可以通往任何时间。而李献计是为了回到当年和女友李倩相遇的那一刻,因为未来的女友不再爱他。可是当他真正打穿游戏回到过去时,却颓然发现通往过去的有无数扇门,于是他便一次次地打穿游戏,一次次地穿过各种各样的门。直到有一天在昔日的人民公园,那个美好而又淡然的午后,李献计又看到了昔日初见的情形。可是,他却再也无法迈出那一步了。此时的他已是蹉跎老人,而李倩依旧活在她的时间内,两人间已是两条平行线,再无相交的可能。 + +你我其实就像李献计一样一直苦苦地找寻着世上唯一的“逆流河”,但是那些美好仅仅是存在于童话里,就像可以实现人们任何愿望的基拉祈、可以穿越时空的帕路奇犽和帝牙卢卡。那些奇妙的幻想只有童话里才能成真。 + +其实,这个世界上本无逆流河,它只存于心间,是人们主观的一种幻想。而幸福,却是要用心感受的。就像欣赏宇宙星空一样,在沉默中感受它的博大精深。幸福,只存于心间,无需找寻,无需发掘。只要用心感受,定能发现其中那股灼人的力量。 + +一直以来的找寻算是白费了,可是这世上同我一样的找寻者还有不少吧。曾看过一则寓言:有一个人用了一生来寻找美,他急匆匆地赶路,从不向四周多张望一眼,从不驻足留恋。于是他错过了绚丽的晚霞、色彩鲜艳的花朵……而这些便是他在找寻的美丽啊! + +身处美中,不知美。身怀幸福,却苦苦找寻幸福。这是不幸,还是悲哀?我想我还是不幸的好。因为这样就多了一份追求、一种渴望。 + +我想这个世上还是存在一条逆流河的吧。只是它与幸福无关,同所有的河流一样,只是一条略显不同的河流。而它,便藏在世界的某个不为人知的角落里。也许,终有一天我会找到它并于其旁定居。 + +那时,该是陈珂断斧,几度苍凉。 + + diff --git a/src/content/posts/2011/2011-10-06-the-story-of-time.mdx b/src/content/posts/2011/2011-10-06-the-story-of-time.mdx new file mode 100644 index 0000000..6169f1d --- /dev/null +++ b/src/content/posts/2011/2011-10-06-the-story-of-time.mdx @@ -0,0 +1,44 @@ +--- +title: 光阴的故事 +slug: the-story-of-time +date: 2011-10-05 19:03:48 +updated: 2019-06-06 07:15:29 +tags: + - 记忆 + - 光阴 + - 故事 + - 方大同 + - 我与狗狗的十个约定 + - 感伤 + - 十年 +category: 文章 +cover: /images/2019/06/2019060607035266.jpg +summary: “流水它带走光阴的故事,改变了两个人……”,耳机里一直重复地放着罗大佑的“光阴的故事”。沙哑的嗓音配上那忧伤歌词令人不觉心萌伤感。 +--- + + +<MusicPlayer netease={26361010} /> + +“流水它带走光阴的故事,改变了两个人……”,耳机里一直重复地放着罗大佑的“光阴的故事”。沙哑的嗓音配上那忧伤歌词令人不觉心萌伤感。对于罗大佑写的歌,不但别的女子唱,他自己也唱。而唱得最为打动人心的,便是这首了。 + +想想一首歌曲最为动人的地方又是什么呢?是歌词?是曲调?亦或是歌手的嗓音?不是,都不是。真正触动心扉的并不是那些表面上的“花饰”,而是歌曲之中所蕴含的点滴情思。换句话说,于细微之中现真情便是对此的最好诠释。 + +时光匆匆而过,光阴的故事也在一直上演,不断回映。有些故事会就此忘却,再也找寻不回。而有些却又会铭刻于心,永不褪色。 + +一直忘不了那部叫做《我与狗狗的十个约定》的影片,它是对光阴与情感的另一种诠释。主人公“我”一直想养一只小狗,并有幸在自家的院子里见到一只走失的小狗。而此时的“妈妈”身患绝症,将不久于人世。为了日后的“我”不会孤单,“妈妈”便同意了让“我”养小狗的请求,并让我和小狗许下了10条约定,以期小狗能在没有妈妈的日子里同“我”相依相随。整个故事的情节也就此展开。 + +十条约定,大部分都记不清了。但印象最深的便是最后一条:“记住,我的寿命只有十年。当我老去,即将死去时,请陪伴在我的身边。”十年的光阴,对于我们大多数人而言,不长不短,只算得上生命的 1/6 左右。而这对于狗而言,便几乎是一生。岁月流逝,狗总是比人先老去、离世,仅仅留下不尽的悲伤和对于往昔欢乐时光的点滴回忆。正如作家塞缪尔曾说过的那样:“当你把一只狗带回家时,也就把一颗悲伤的种子种在了你身边,十五年或者更短的岁月之后,悲伤之花绽放,给你满身伤痛后盘踞在你的心中……” + +细数人生,又有几个十年呢?有时可能会觉得这有限的时间不够用,而有时也会觉得活这么久太无聊。然而时间却是十分奇妙的。痛苦时会觉得一个小时比半天还长。高兴时,又会觉得一天比一个小时还短。十载岁月,像做梦一样长,又似梦后初醒一般渺茫。 + +不觉在时光的流逝中感伤。可任你怎样哭泣、落泪,它总是一刻不停地流逝。这一秒过去了,下一秒接着来了。 + +记起十年前的我,还是一个乳臭未干的小孩,对于一切诸事不知。而现在,恍如一瞬,十年的岁月就这样消逝,我已长大,就像是在做梦一般。只是,这梦就像《盗梦空间》里的梦的最深层,永远不会有醒来的那一天啊!儿时门前的那棵与我齐高的小梧桐树,现在俨然成材。就像《十年如昔》中说的那样,一个人的老去只要十年,一棵树的成长也只需要十年。 + +十年的时间,可以发生很多事情,写下很多故事。恰如陈奕迅的《十年》中唱的那样,情人最终沦为朋友。就像《我与狗狗的十个约定》中的“我”最终长大成人,懂得感恩父亲。也就像《再见可鲁》中的小Q,最终结束了导盲犬的使命。 + +光阴似箭,岁月如梭。会想多年前的种种,许多至今还历历在目。但不知不觉又将度过一个十年。那就让这记忆中的点滴深埋于昔日的光阴长河之中吧。 + +只为,留予他年说梦痕。 + + diff --git a/src/content/posts/2011/2011-10-07-those-words-my-love.mdx b/src/content/posts/2011/2011-10-07-those-words-my-love.mdx new file mode 100644 index 0000000..c2792c3 --- /dev/null +++ b/src/content/posts/2011/2011-10-07-those-words-my-love.mdx @@ -0,0 +1,45 @@ +--- +title: 那些文字,那段情 +slug: those-words-my-love +date: 2011-10-06 21:36:39 +updated: 2019-06-06 07:22:10 +tags: + - 文字 + - 回忆 + - 情感 + - 手写 +category: 文章 +cover: /images/2019/06/2019060607210889.jpg +summary: 又一次整理桌上散乱的纸张,无意中竟发现昔日尝试写的第一本同人小说的草稿,不禁有些淡淡的感触。那些文字,那些情感原来一直都存在着,只是我们未曾去发掘,便一次次地错失某些回忆。 +--- + + +<MusicPlayer netease={287319} /> + +又一次整理桌上散乱的纸张,无意中竟发现昔日尝试写的第一本同人小说的草稿,不禁有些淡淡的感触。那些文字,那些情感原来一直都存在着,只是我们未曾去发掘,便一次次地错失某些回忆。 + +突然惊恐地发现自己距上次手写文章已经相隔6个月了。自从有了电脑以后,习惯了坐在电脑前,一边打字一边冥想。就像现在,我写下这篇日志,而耳机里一直在单曲循环着孙燕姿的《遇见》。只为述说一个早已褪色的故事…… + +相遇便是一种缘分。就像电影《向左走向右走》中的男女主角:一次次地错过,却最终因为地震而走到了一起。 + +曾几何时,你我还是小孩,对一切懵懂无知。旋转木马不停地摇曳,而你我,或许只该是两条本不该相交的平行线。而旋转的木马带动了时光齿轮飞转,种种交织、纠葛就像看不见的丝线连成串,最终将我们牵在了一起。这也许便是说不清、道不明的缘分。 + +厦门的87路在还未改道前几乎横穿小半个城市。高二的新学期伊始,我独自一人从始发站上车。依旧熟悉的街景,依旧冷清的车厢,依旧令人聒噪的汽车发动机的轰响。我蜷缩在某个不引人注意的角落,静静地看着窗外两个月不见却依稀改变的街道。87路走走停停,似老爷车般缓慢而令人心烦意乱。每到一站,车门打开,便有一群叽叽喳喳的中学生和几位急着上班的白领挤上车,接着又迎来新的一批学生和白领。车厢内人头攒动,原本宁静的环境不知从何时起变得喧闹起来。环顾四周,我一下子便注意到了同样静静的“她”。背着一个亮橙色的双肩背包,扎着两条垂及肩部的发辫,穿着同样略显单薄的衬衫的她一下子便吸引了我的目光,再也移不开来…… + +想起纳兰性德的“人生若只如初见”,初见的那般美好,往往最令人陶醉。就像是我,仅仅淡淡的惊鸿一瞥,却早已喜欢上了这个女孩。也许,就像琼瑶小说中的一见钟情吧。只是,这一份相恋,仅仅只敢埋藏于心中,不敢说出口。 + +“听见冬天的离开,我在某年某月醒过来。我想我等我期待,未来却不能理智安排……” + +一次次地早起等车,一次次的翘首以待,只为遇见那个心中的喜爱。多少次的注目远视,多少次的心怀想念,只因喜欢上了她。而作为另一主角的“她”,却对这一切毫无半分察觉。 + +也许,她终究只是当我是一个常见的乘客罢了。也许她早已注意,却从心中将我否定。但也许,我们终究只是过客…… + +半年后,厦门钟鼓山隧道开始通车了,87路就此改道。从那以后,我就再也没见过她。 + +一直以来的单相思算是告一段落。可是,又有谁能说是真的结束呢?心底的那颗暗恋种子,早已生根,等待下一次的遇见。 + +我想我等我期待,爱要拐几个弯才来…… + +>后记:相逢是缘。看过《向左走向右走》后,不觉为男女主角的曲折爱恋所动容。我们都是一个残缺的圆,在茫茫人海中找寻另一半。一次次的遇见,一次次的等待再见。 + + diff --git a/src/content/posts/2011/2011-10-11-past-memory.mdx b/src/content/posts/2011/2011-10-11-past-memory.mdx new file mode 100644 index 0000000..a80663e --- /dev/null +++ b/src/content/posts/2011/2011-10-11-past-memory.mdx @@ -0,0 +1,31 @@ +--- +title: 回首的瞬间 +slug: past-memory +date: 2011-10-11 02:15:37 +updated: 2019-06-06 07:29:35 +tags: + - 回首 + - 瞬间 + - 美好 + - 亲情 + - 父母 + - 点滴,情感 +category: 文章 +cover: /images/2019/06/2019060607290148.jpg +summary: 喜欢一个人默默地伫立在窗口任清风袭来,带走心底的疲惫,仰望苍穹。闲看庭前花开花落,漫步窗外,静看云卷云舒。 +--- + + +<MusicPlayer netease={488388715} /> + +喜欢一个人默默地伫立在窗口,任清风袭来,带走心底的疲惫,仰望苍穹。闲看庭前花开花落,漫步窗外,静看云卷云舒。在这种种神神秘秘、没有时间、没有怀疑的宁静中,闭目宁神,扇动你的鼻翼,带着点点滴滴泥土的神韵,飞往记忆的国度。在这种静得可以感受到心脏搏动的时刻,静得简直让人窒息的瞬间,使你的血液沸腾,心灵燃烧,任你生命之火尽情地奔涌、蔓延,直到生命危殆,直到心灵垂老。那时你会发现,回首的瞬间,很美。 + +也许是偶然,其实是必然。当你饱经沧桑,历尽生命铅华,蓦然回首,端视那一一留下的行走的足迹,你的心也会随之变得超然。过去的将会变成永远过去,在你转身默默行走中随风而逝,但消逝的终究是生命的容颜,保留的却是回忆的真谛。 + +思绪纷纷攘攘:是谁陪我栉风沐雨,静看春华秋实?是谁用那轻轻的叮咛为我驱寒散热,却独自忍受着坎坷?又是谁忙里忙外,脚步匆匆,殊不知年轻的头上早生华发?哦,那是我的父母——我慷慨的父母,慷慨到用他们博大精深的无私的爱为我编织一双双坚硬、勇敢的翅膀,伴我飞翔;我吝啬的父母,吝啬到只愿独自咀嚼生活的艰辛,却把幸福的甘露任我挥洒。 + +闲云潭影日悠悠,物转星移几度秋。岁月的每一痕迹,都在你经意或不经意时悄悄溜走,于是思念便成为唯一方式。回首的瞬间,从眼角流下多少感动,从眼角想起几分幸福?一颗感恩的心在胸膛里默默低诉,低诉多年的恩情,待话到嘴边时,却又不知从何说起。回首的瞬间,心中装满愧怍,汇集了吐不尽的懊恼,一颗坎坷的心最终逃不过良心的谴责。父母不辞辛劳,无悔地用辛劳和汗水编织的幸福却在冥冥之中被我肆意地挥霍。记忆中父亲的手是那样的光滑细腻而温柔,而如今那双温柔的大手上却布满辛劳与岁月的迹痕,有时候我甚至不敢相信那就是昔日握着我的小手的大手。在回首的瞬间,我们感怀亲情,感悟亲情,亲情就像一条线,随我们不停地步行到天边。沉默的唇有千言万语,温馨的叮嘱有千万遍,总在午夜梦回时,扣响我们的心扉。 + +回首的瞬间,无限短暂而又无限悠长,因其时间短暂易被忘却,因其凝聚了生命的真实历程而无限悠长。瞬间的回首是历史的眼睛,遥看尘世悲喜故事;瞬间的回首是时光的脚步,踏过多少历程;瞬间的回首是岁月的镜框,框住多少难忘的景象。所以我愿意采撷瞬间——因为那时花开。瞬间很美。 + + diff --git a/src/content/posts/2011/2011-10-13-memories-of-blossom.mdx b/src/content/posts/2011/2011-10-13-memories-of-blossom.mdx new file mode 100644 index 0000000..68a1568 --- /dev/null +++ b/src/content/posts/2011/2011-10-13-memories-of-blossom.mdx @@ -0,0 +1,41 @@ +--- +title: 花开的回忆 +slug: memories-of-blossom +date: 2011-10-12 17:56:23 +updated: 2019-06-06 08:10:15 +tags: + - 回忆 + - 流年 + - 花开 + - 拼搏 + - 初中 +category: 文章 +cover: /images/2019/06/2019060608094516.jpg +summary: 一些事物,总能给我无边的联想,这些联想似无逻辑,但我总是喜欢记下它们,也许是因为它们只属于我。 +--- + + + +<MusicPlayer netease={1840344776} /> + +一些事物,总能给我无边的联想。这些联想似无逻辑,但我总是喜欢记下它们,也许是因为它们只属于我。 + +——题记 + +傍晚时分,云淡风轻,天气有些阴冷。走在通往食堂的道路上,我无意于过往的行人,目光在周围熟悉的景物间游离。猛然间,我的目光停留在草坪间的一朵迟开的野菊花。在这个寒风凛冽的下午,别的花儿都已经凋谢的季节,它却以自己的那份坚强坦然面对那份孤独。对于自己的内心而言,我是一个喜欢寂寞的人。因为有时,一个人的思考,往往可以想得很多、很久。就像现在看着眼前这朵随手拍下的野菊花图片,而我的思绪却飘飞得很远、很远…… + +我曾经在厦门的大同中学度过两载初中时代,并在那毕业。所以,你可以很明显地发现:我是一名转校生。可是,与绝大多数人不同的是,我是从济南转学到厦门的。对于一个 12 岁的小孩来说,你可以想象这是多么大的挑战。独自一人孤零零地坐在教室最后面的那个无光的角落,周遭的一切都是那么地陌生。新的环境,新的同学,不一样版本的课本,与别人相差很远的成绩……没有人和你说话,没有老师会注意到你的存在,仿佛一个透明人般被孤独所覆盖。 + +而这,便是我内心对于初二生活的真实写照。在那段可以称之为暗淡无光的日子,每天的作息便是 5:00 起床到 23:30 睡觉。每天都是独自一人上学、独自一人回家,总是经过校外的一片荒芜花坛,一遍又一遍麻木地重复着这些相同的动作。有时真的很想找父母或他人倾诉,可是双亲的操劳让我不忍心再令他们添负担。于是便一次又一次地从梦中醒来,担心将来的测验;一次又一次被同学孤立,以泪洗面;一次又一次看着卷面上刺眼的红叉,心灰意冷。忧郁彷徨的时候,思考着自己的无奈,或者是一种命运的注定,注定我一直向左走,向右走,最后竟又回到起点。站在原点,我不知何去何从,只能蜷缩在教室一角,学习着独自承受面对这一切。 + +依旧是独自一人上学,依旧孤单孤单。直到有一天,当我再次经过那个大花坛时,昔日那些一直被我忽视的小草,此刻竟然都变成了朵朵白花。白色略透鹅黄的六翼花瓣让人不由得打心底喜爱,而挥散的清香更是让人驻足观赏。花开的烂漫是那般美好,让我心底有些许慰藉。想想一朵花开的过程是漫长的,或许它的一生都在默默积累,不为人所关注,就像那片被我忽视了一年的“小草”。只有到了积累足够的那一刻,它才会开放,组成这天地间最为动人的光景。而人生,亦是如此。 + +也就是在那年年末,经过无数个日日夜夜的努力,我的期末考试成绩进了年级前十,终于赢得了老师和同学们的认可,青春之花又一次在我的脸上绽放…… + +感谢这些记忆,这些光阴中的片段,它们让我知道,每一个成功的背后,都有无数为之奋斗而默默挥洒的汗水。那些掉落一地的花瓣,瓣瓣不相同。每一瓣,都是一道闪光的记忆。我记得这些光阴中的刹那,那些无法忘记的真实与疼痛。而人生中最美的一刻,便是拿到成绩单时的那份笑脸,便是我那些拼搏的日子吧。 + +花坛里,那朵野菊花依旧绽放,纯白的花瓣纯白了记忆。但是,我不能停留,还得继续前进。我的前方,还有无数“关卡”要去超越;我的那朵生命之花,还在等待另一次的绽放。 + +吉他、钢琴,平静地演奏着《栀子花开》,没有过多的起伏,这里只有淡淡的回忆,还有一份不舍,一份陶醉。 + + diff --git a/src/content/posts/2011/2011-10-14-im-a-male-not-female.mdx b/src/content/posts/2011/2011-10-14-im-a-male-not-female.mdx new file mode 100644 index 0000000..b25ab15 --- /dev/null +++ b/src/content/posts/2011/2011-10-14-im-a-male-not-female.mdx @@ -0,0 +1,35 @@ +--- +title: 我是男生,不是女生 +slug: im-a-male-not-female +date: 2011-10-13 16:19:57 +updated: 2019-06-10 04:40:15 +tags: + - 思想 + - 情感 + - 人性 + - 男女 + - 性别 +category: 文章 +cover: /images/2019/06/2019061004393184.jpg +summary: 也许是我的博客的名字太秀气,也许是我之前用的主题太婉约,更或许是那个留言的小女孩头像惹的祸,总是有人把我当做女孩子。 +--- + + + +<MusicPlayer netease={1299981609} /> + +也许是我的博客名字太秀气,也许是我之前用的主题太婉约,更或许是那个留言的小女孩头像惹的祸,总是有人把我当做女孩子。甚至,有人说我的真实姓名“雨帆”就是一个女孩子的名字。好吧,为了不再被别人误解,我的博客改名叫“且听书吟”,模板也换成了 Deve。可是令人郁闷的是,还是有人叫我女生。 + +昨夜整理博客留言,看到小白姐姐对我文章的评价,最终发现了缘由:我的文字实在是太女性化了。这或许也是一个令人哭笑不得的结论。 + +文字,是思想的载体,很多时候,我的内心观,都是通过你眼前的文字来表达的。所以,你从我的文章中发掘出的那些细腻的思想,便是人性中女性的一面。而人性中所蕴含的男性与女性两方面,恰如哲学中的两个相互矛盾的事物间的关系。以辩证的眼光来看,它们相互依存却又不相互分离,在每一个人的身上都能完美体现。就像猛虎与蔷薇,一切的和谐之美便存在于矛盾之中。 + +其实,每个人内心的思想都含有两方面;其一是男性化的,苍鹰、怒马、瀑布便是他的代言词;而另一方面,却是婉约的女性化的,像夜莺、像静池、像莲花。就像余光中曾经提到的那样:所谓的外向与内向,所谓的雄伟与秀美,所谓的金刚怒目,菩萨低眉,所谓的“静如处子动如脱兔”,所谓“骏马秋风冀北,杏花春雨江南”,所谓的“杨柳岸,晓风残月”和“大江东去”。一句话,《姚姬传》中所谓的阳刚和阴柔,都无非是这两种气质的注脚。而对于你我而言,便只是这两种气质的比例不同而已。 + +突然想起那些思想家对于人与之有关的一切的不断探索。从“人啊,认识你自己”的那一声呐喊到卡夫卡的那句“人是一株会思想的芦苇”,我们从未停止过对于自身的思考。正是因为我们懂得思考,所以每个人便显得那么的与众不同。也就是这样一根能思考的芦苇,才有了对于人性中刚与柔的讨论。 + +每个人的心灵深处,都有一处花冢,埋藏着那些与自己本身性格相反的那些或坚毅、或凄美的不为外人所道的情感。这花冢,一直藏在某个不为人知的角落,总有一天会被情感所激发,使人觉醒。“天行健,君子以自强不息。”“花非花,雾非雾;夜半来,天明去,来如春梦几多时,去似朝云无觅处。”而一个完整的人生,便应同时兼具这两种情感。 + +人啊,认识你自己! + + diff --git a/src/content/posts/2011/2011-10-16-the-centenary-of-school-anniversary.mdx b/src/content/posts/2011/2011-10-16-the-centenary-of-school-anniversary.mdx new file mode 100644 index 0000000..3a53d9f --- /dev/null +++ b/src/content/posts/2011/2011-10-16-the-centenary-of-school-anniversary.mdx @@ -0,0 +1,28 @@ +--- +title: 今天校庆 +slug: the-centenary-of-school-anniversary +date: 2011-10-16 07:09:37 +updated: 2019-07-12 13:47:47 +tags: + - 回忆 + - 山大 + - 杂思 + - 校庆 + - 无聊 +category: 杂思 +cover: /images/2019/07/2019071213470131.jpg +summary: 今天是山大的110周年的校庆,作为一个山大人来说,应该是一个高兴的日子。可是,我却没有丝毫的欣喜,一个人坐在依旧空荡荡的自习室,耳机里听着“How to be alone”。 +--- + + +<MusicPlayer netease={1810227452} /> + +今天是山大的 110 周年校庆,作为一个山大人来说,应该是一个高兴的日子。可是,我却没有丝毫的欣喜,一个人坐在依旧空荡荡的自习室,耳机里听着“How to be alone”。有些无聊,甚至还有些烦躁。 + +傍晚时分,教室外的大功率喇叭依旧在那里一遍遍单曲循环着老校歌。萧瑟的秋风,稀少的路人,感觉像是突然回到了上学期的毕业季。大家都在忙碌、奔波,时候一到,便各奔东西。总有一些突然烦躁的静不下心来,走出校门漫无边际地散步。那些熟悉到可以烂在心底的景物一一在眼前晃过。来来往往的行人脚步匆匆,他们每个人都有自己的事,都在忙碌。而山大的校庆,对于他们而言,只是饭后谈资罢了。 + +想想这次校庆,我们的“崔牛司”校长可谓是呕心沥血啊!在我们才入学时,便提出了力争 120 周年时建设世界一流大学的口号。为此不惜耗重金打造一系列大型土木工程:中心校区的新体育馆,山大的新的花园式喷泉校门……新的校歌、新的校训,一切都是新的。似乎只有一切换成新的才能更加体现“世界一流大学”的风范,笑。而谈及钱学森爷爷的三问,对比眼前大张旗鼓开展的各种活动的校庆。我以一种局外人的眼光审视,却突然地失了所有的言语,不禁怀疑起大学的存在与定位。 + +而我们总会在某个时间某个地点,亦如此刻随意漫步的我,会在某片风画成线的地方,回想起曾经那般熟悉的场景、面容,同时也在那一瞬间,天昏地暗。在那些单纯的岁月里,流淌的是那青春与激情,求知和拼搏。至今那些高中的场景还历历在目。没有大张旗鼓的宣传,没有奢华的重建,没有盛大而壮观的汇报演出。有的,只是校长那一声寄语,老师的一段鼓励,同学们的一番展望,仅此而已…… + +思绪拉回现在,天依旧灰蒙蒙的,空气依旧阴冷。今天校庆,仅此而已。 diff --git a/src/content/posts/2011/2011-10-20-loving-notebook.mdx b/src/content/posts/2011/2011-10-20-loving-notebook.mdx new file mode 100644 index 0000000..b967b7a --- /dev/null +++ b/src/content/posts/2011/2011-10-20-loving-notebook.mdx @@ -0,0 +1,32 @@ +--- +title: 恋恋笔记本 +slug: loving-notebook +date: 2011-10-20 07:14:32 +updated: 2019-07-12 14:01:32 +tags: + - 恋恋 + - 笔记本 + - 前言 + - 记事 +category: 杂思 +cover: /images/2019/07/2019071214005288.jpg +summary: 前天买了一本新的笔记本,拿到手,看着光洁的纸面,总想写点什么。可是拿起笔又放下,脑袋昏沉沉的,感觉就像时喝醉酒了般写不出东西来。 +--- + + + +<MusicPlayer netease={1091476} /> + +前天买了一本新的笔记本,拿到手,看着光洁的纸面,总想写点什么。可是拿起笔又放下,脑袋昏沉沉的,感觉就像时喝醉酒了般写不出东西来。最后就写个类似书本的引语。现在贴出来,大家勿笑哦。 + +一直有收藏笔记本的喜好,一直喜欢记笔记。而时间,却总会将这纸面变黄、弄皱,消减昔日的光洁。所以,一切都会变老、变旧。但是永远不变的,却是我现在写在这纸面上的字。也可以称之为我的思想。 + +本子买了一本又一本,可是却没有一本写完过,一本还没写几页,却又忍不住又买了一本新的。有时候老妈总是抱怨我买那么多的本子。可是这也许就是我的另一份爱好吧。 + +突然想起前面一本蓝色皮套烙有喜羊羊图案的笔记本,它的纸张背景和它的封面一样可爱。每一张,都是一个与众不同的卡通图案,让人不忍心落笔留痕。可是,这样也失去了它作为笔记本的功能。在纠结于保留可爱和使用它之间很久后,最终决定再买一本,也就是现在我在写的这本。这也许是一种两全其美的办法吧。 + +我是一个**男生**,最喜欢的颜色便是淡淡的天蓝色。也许是因为它们的读音都一样吧,笑。所以在挑选时在超市翻箱倒柜一番后最终选择了“你”。天蓝略泛白的封面,时尚而又个性的数字花案,传说中的不伤眼的黄色纸面。这一切都是我的最爱,我有什么理由不选你呢?就像那些墙角边的不为人注意的花饰,总有什么可以挑动你的心弦。 + +最后为了防止我的笔记本弄丢,当然是要写上我的联系方式了哦。希望如果有哪位大大捡到它的话一定要联系我哦,雨帆在此感激不尽了。 + + diff --git a/src/content/posts/2011/2011-10-21-the-streets-where-wind-lives.mdx b/src/content/posts/2011/2011-10-21-the-streets-where-wind-lives.mdx new file mode 100644 index 0000000..750793b --- /dev/null +++ b/src/content/posts/2011/2011-10-21-the-streets-where-wind-lives.mdx @@ -0,0 +1,35 @@ +--- +title: 风居住的街道 +slug: the-streets-where-wind-lives +date: 2011-10-20 16:00:16 +updated: 2021-02-27 18:14:08 +tags: + - 记忆 + - 童年 + - 风 + - 街道 +category: 文章 +cover: /images/2019/07/2019071214170923.jpg +summary: 傍晚时分,走出昏暗的教室,秋风乍起,阵阵寒风袭来,不禁打了一个寒战。看到路面上随风而起的梧桐叶,一如疲倦了的蝴蝶。 +--- + + +<MusicPlayer netease={29539350} /> + +是风,拨动记忆的琴弦;是风,挑起心中的涟漪;是风,唤醒久违的思绪。 + +——题记 + +傍晚时分,走出昏暗的教室,秋风乍起,阵阵寒风袭来,不禁打了一个寒战。看到路面上随风而起的梧桐叶,一如疲倦了的蝴蝶。不知何时,北方的深秋,已然悄然而至。满目的萧瑟,却不颓废,充溢着诗情。抬头仰望 45° 的天空,依旧是黄昏暗淡,校园小道上行色匆匆的路人和校门口飞奔的车辆,一切无不体现着这灯红酒绿的城市机器的那让人窒息的快节奏。除了悠然慢行的我和道旁无言的树。可是,沉默的树儿,你懂我吗? + +伸出双手,让风儿从指缝间划过,刺骨的寒冷,铭心的疼痛,真实的记忆。身处繁华的都市,我却措手不及,在人群中踌躇,思念远方的小城,狭窄的小道,浓重的乡音,亲切的面孔,让我魂牵梦系。那座记忆之中的小城,那些风儿居住过的街道,一切的故事便是从这里开始…… + +时光流走,阔别故土,已然有十载有余。露从今夜白,月是故乡明。梦中每迷还乡路,欲知晚途念桑梓。此刻的风儿,就像故乡的信使,呼唤着我的归去,也在我的心底漾起层层涟漪。一年又一年花开花落,而风儿年年依旧。它从未死去,又从不变老,引异着此刻周身的黄绿交织,维系着外行游子的浓浓情思。 + +此刻闭上双眼,我的思绪仿佛随着身边的风儿一起掠过故乡的街道、田野。我仿佛听到了风拂麦田的声音,那动态又轻盈的美的旋律。这是风的动情,也是麦的韵律。风推着麦,麦打着风,一次又一次地拂过。我好像看到了傍晚晚归时的家家户户屋檐上的炊烟,那靛青色的烟尘在风中轻抚变形。无论怎么看都像是一幅悬腕挥就的狂草,风影乱舞。该虚的地方虚,该实的地方实。那是我们在纸上无法辨别的,真可谓天书了。风夹着炊烟,掺杂着人的欢声笑语,构成了那幅乡村傍晚图景…… + +可是,为什么美好的时光总是消散的那么快呢?一眨眼,我已离它远去。而自己,也忙于学习之中,再也没有昔日的那份闲情去回忆。 + +睁开双眼,依旧是满目的萧瑟。我继续向着自习室迈步。而那些记忆,那些思念,已然随着风儿,渐行渐远…… + + diff --git a/src/content/posts/2011/2011-10-23-show-the-sword.mdx b/src/content/posts/2011/2011-10-23-show-the-sword.mdx new file mode 100644 index 0000000..425a557 --- /dev/null +++ b/src/content/posts/2011/2011-10-23-show-the-sword.mdx @@ -0,0 +1,42 @@ +--- +title: 亮剑 +slug: show-the-sword +date: 2011-10-22 17:31:34 +updated: 2019-07-13 10:59:53 +tags: + - 高考 + - 拼搏 + - 亮剑 + - 剑客 + - 学习 + - 江湖 +category: 文章 +cover: /images/2019/07/2019071310585310.jpg +summary: 两位剑客狭路相逢。对方身怀绝技、早已是风动江湖、举世皆知的青年才俊。而你,只是一个名不见经传、只有一本下品武学的小卒子。是该退避其芒,还是挺身向前?我答:“亮剑。” +--- + + + +<MusicPlayer netease={26124988} /> + +两位剑客狭路相逢。对方身怀绝技、早已是风动江湖、举世皆知的青年才俊。而你,只是一个名不见经传、只有一本下品武学的小卒子。是该退避其锋,还是挺身向前?我答:“亮剑。” + +——题记 + +我们都是一名剑客,仗剑游行于江湖之中。只是这里的江湖不似小说里面的那样充溢着刀光箭雨、血肉纷飞。没有侠客魂、柔女情,有的只是无声的较量,没有硝烟的斗争,不屈的追赶。而这,便是你的江湖,我的战场。 + +我们都是一名侠士,耗尽几乎全部的青春年华与心血打造那把只属于你我的剑。“宝剑自从磨砺出,梅花香自苦寒来。”为了勤练剑术,我们三更眠,五更起;为了赶超他人,我们寒来暑往,风雨未停;为了这把剑,我们付出了太多太多。 + +我们铸剑做啥?我们为何勤练剑技?我们身处何方?哪里是江湖?何处才是我们可以为之挥洒血泪的地方? + +看过《碧血剑》,便为其中的金蛇郎君所折服;看过《诛仙》,便为陆雪琪所叹惋。这里是剑客的江湖,亦是江湖的剑士,我们亦是其中之一。人在江湖,身不由己。为了成名,为了成为众英杰中敢执牛耳者。我们亦是身怀这样的信念,日日闻鸡起舞,不断寻觅新的对手,一次次的失败跌倒,又一次次的重新站起。这一切的宿命与无奈,从我们踏进江湖的那一天开始,便就此注定。 + +我无门无派,只是一介底层小散修。没有精妙的武功心法,没有旷古的武器,有的,只有自身的不懈努力。而那些宗派的精英,个个身负绝世功法,神兵利器,在他们眼里,我是蝼蚁一般的存在。但是,我亦有梦,当我面对他们时,唯一能让我坦然的便是最初的梦想。那就是,打败江湖中的所有剑客,置身于武道的最顶峰,俯笑终生…… + +一年一度的武林精英宴于华山峰顶举行。这是为江湖豪杰所瞩目的、全武林的盛事。常言道:“十年磨一剑”。而为了这天的到来,我苦战了十多年。可是纵使我自创神技,自铸好剑,我还是不如那些青年才俊、天之骄子。是逃避、还是向前?我答:“亮剑。” + +狭路相逢,勇者胜。 + +> 我把自己想象成为一名剑客,江湖便是由莘莘学子所组成。每次的比试,就是一场考试。学习的过程便是铸剑,练习剑术。而高考便是亮剑之时! + + diff --git a/src/content/posts/2011/2011-10-26-face-the-fact.mdx b/src/content/posts/2011/2011-10-26-face-the-fact.mdx new file mode 100644 index 0000000..250ade5 --- /dev/null +++ b/src/content/posts/2011/2011-10-26-face-the-fact.mdx @@ -0,0 +1,35 @@ +--- +title: 坦然面对 +slug: face-the-fact +date: 2011-10-26 05:19:21 +updated: 2020-09-04 21:16:30 +tags: + - 坦然 + - 面对 + - 人生 + - 挫折 + - 平淡 +category: 文章 +cover: /images/2020/09/2020090421160773.jpg +summary: 生活中,我们要面对很多,有好的,有坏的,但无论好坏,都无需埋怨,人生的路途就是这样。抱怨没有用,逃避不可能,人生是现实的,现实的人生还需要现实的方法处理。 +--- + + + +<MusicPlayer netease={276709} /> + +无论你愿不愿意,我们必须面对生活呈现给我们的一切。 + +——题记 + +生活中,我们要面对很多,有好的,有坏的,但无论好坏,都无需埋怨,人生的路途就是这样。抱怨没有用,逃避不可能,人生是现实的,现实的人生还需要现实的方法处理。无论什么困难,除了坦然面对,我们别无选择。 + +野草的生存环境可谓恶劣,光照不足,营养不良,被人随便拔去,锄去,被人随意践踏。可是,它仍然在人们不知不觉中壮大起来,仍然活得精神奋发。它的微弱正衬托出它的骄傲,它的不受宠正显出它的坚强。那么作为万物之灵的我们,有什么理由不坦然面对人生旅途中的一切呢? + +能够直面人生的不幸,说明你是镇定的,只有镇定才能自若,只有自若才能从容,从容了也就坦然面对了。而不敢面对,只会使自己陷入到一种不幸的重重包围之中,茫然四顾不能自拔。生活是豁达的,只要你真诚地面对,都会得到它的宽容的回报,上帝给我们的这个世界是要我们用乐观的态度去诠释的,因为当我们看它好的时候,一切都会好。假如我们处处想要揭穿生活的假象,那么我们只会失望。而失望的生活并不可怕,可怕的是我们面对它的态度。 + +面对善良,我们回报以真诚的微笑,我们渲染以刚毅的色彩。面对沉默,我们装点以宁静的氛围。而面对失望,我们要坚强乐观。面对失败,我们要积极进取。当面对你自己的初衷,面对你的灵魂,面对你的良心,你可坦然地说句无怨无悔,那么你已学会了坦然面对。 + +坚强的人对挫折总是轻描淡写,因为他不怕面对失败;胆小的人谈起失败总是谈虎色变,因为他害怕面对。其实,人与世界的永恒画面是:征服与被征服,只要我们敢于面对现实的人生,就没有什么可以打败我们。 + +然而我们每天拥抱阳光,不回避阴影,坦然面对人生的喜悦和成功,坦然面对人生的挫折和失败,就会看见那条充满阳光的彩虹。 diff --git a/src/content/posts/2011/2011-10-28-south-or-north.mdx b/src/content/posts/2011/2011-10-28-south-or-north.mdx new file mode 100644 index 0000000..e7dce40 --- /dev/null +++ b/src/content/posts/2011/2011-10-28-south-or-north.mdx @@ -0,0 +1,47 @@ +--- +title: 黄梅细雨 +slug: south-or-north +date: 2011-10-27 16:11:03 +updated: 2020-09-04 22:09:29 +tags: + - 记忆 + - 情感 + - 梅雨 +category: 文章 +cover: /images/2020/09/2020090422091233.jpg +summary: 白马秋风塞上,杏花春雨江南。塞上是空旷的、粗犷的,能与之相配的,只有那萧瑟的秋风,疾奔的白马。 +--- + + + +<MusicPlayer netease={1964055957} /> + +## Part 1 + +白马秋风塞上,杏花春雨江南。塞上是空旷的、粗犷的,能与之相配的,只有那萧瑟的秋风,疾奔的白马。而与之相对的江南,则是婉约的、柔美的,如同多情的女子。正如诗人所言,只有杏花、细雨才村的出、配得上这美。也正如此,从而更显得江南的雨别有一番韵味了。 + +在曾经的记忆里,雨,应该是匆忙的。急急的来、急急的去,不给人以半分准备与留恋。到头来,看到了地上的潮湿和水洼,才知道这儿曾经下过一场雨。来得快、去得快,这恰是厦门午后的暴雨的特点。在厦门一住就是七年,对于这种雨早已习惯了。而潜意识之中的雨,也应是如此。 + +可是这江南的雨,却彻底颠覆了我以往的观点。初回老家时,还是夏至未至。而这雨,却早已与我不期而至了。天空明亮,细雨婆娑,似有似无。不像轻纱,笼罩在心头。烟柳画桥,如梦如幻。不像大陆东海沿岸的雨,来去无意,不带半分留恋。也不似北方济南周边的雨,夹杂着灰尘、落叶,铺天盖地向你袭来,无处可藏。而此时,半边烟雨半映山。一股久违的熟悉感充溢于心头,儿时故乡的雨就是这样啊!故乡我回来了…… + +## Part 2 + +漫步于乡间的天田埂上,头顶上依旧在下着小雨。小雨沾衣,却浑然不觉。这雨,竟不再似雨,到成了天地间的另一种装饰。雨滴彼此串连着,组成一幅水帘挡在了眼前。四周之景看不真切,模糊又迷离。这迷蒙的小雨怎能不令人满心欢喜?远处郁郁葱葱的树木,身旁潺潺的流淌的水,还有那翠绿的稻田。都在这细绢般的雨下无声的浣洗。洗去一身的灰蒙,更添一分别样的艳丽。一切周身之景就像一幅挥毫泼墨而就的水墨画,又似一个难以企及的梦,触动了我心中的某处柔软,绽开了朵朵涟漪。真可谓“细雨湿衣看不见,闲花落地听无声。” + +## Part 3 + +一连几天,这雨竟一直未绝,时断时续。下时,也不过两三丝。才将地润湿,竟又没了踪影,无处可觅。黄梅时节,最常见的便是这种雨。小时候,每到这个时节晴天时,老妈总会把许多压箱底的被褥、衣服拿出来晾晒,以防发霉。而此时的空气,也极为湿润,有时悬挂于屋檐下的大蒜籽,竟会发芽。故梅雨,霉雨也。 + +穿行于故乡的小巷之中,踩着水洼,扣着青苔,历数墙壁上的斑驳,无处不见梅雨的影子。地理书上曾经说过,淮河沿岸的梅雨是由江南准静止锋形成的。可我总觉得,如果将如此一个灵动的事物用条条框框将之定义、束缚,那将会失去多少活泼与自然啊! + +## Part 4 + +不管大人们对于梅雨有多么的不满,我偏爱这梅雨,不为它的朦胧,不为它的轻盈,只为偶然相遇时的惊喜。就像是一种等待,可另一方迟迟未来。当你心灰意冷、失去耐心之时,对方却突然到来。本来明明有所准备,此刻却像失了魂般慌乱。正如稼轩所言:“众里寻他千百度,蓦然回首,那人却在,灯火阑珊处。”下课了,看看窗外。原来是风烟俱净,此刻却纷纷扬扬地下起了雨。低着头,踏着积水。一路小跑地向着宿舍赶去,青春、活泼。记得儿时的下雨天,我没带伞举着书包向家赶,最后一身烂泥的滑稽样。又想起语文课上老师说过的:“下雨天,留客天。天留我不?留!”的精妙断句。雨中的奔跑,总令人遐思甚远。 + +也许每个人心中总有这样一处地方,埋葬着磅礴凄美却不为外道的情感。而故乡的梅雨,却像一把钥匙,解开了心头那把厚重的大锁,释放出那些久违的思绪。 + +雨,带给我簌簌的微思。似看不见的手指,在我的心头上不断奏着潺潺的乐曲。看看窗外,天黑了,雨停了,心底浮现出一行字来:记忆即为温暖,至美就是永恒。 + +——写于:2010年 5月 梅雨时节 + + diff --git a/src/content/posts/2011/2011-10-31-explorer-keyboard.mdx b/src/content/posts/2011/2011-10-31-explorer-keyboard.mdx new file mode 100644 index 0000000..660baa7 --- /dev/null +++ b/src/content/posts/2011/2011-10-31-explorer-keyboard.mdx @@ -0,0 +1,60 @@ +--- +title: 键盘的随想 +slug: explorer-keyboard +date: 2011-10-31 11:13:45 +updated: 2020-09-04 22:19:16 +tags: + - 文化 + - 手写 + - 键盘 + - 随想 + - 网络 + - 平板 +category: 杂思 +cover: /images/2020/09/2020090422185883.jpg +summary: 数字时代已经到来。伴随着网络的普及,人们的工作、学习、交流方式逐渐转移到了电子设备上。与之相伴而生的键盘输入方式也逐渐为大家所接受,成了一种格局,或者说是一种文化。 +--- + + + +<MusicPlayer netease={5101896} /> + +数字时代已经到来。伴随着网络的普及,人们的工作、学习、交流方式逐渐转移到了电子设备上。与之相伴而生的键盘输入方式也逐渐为大家所接受,成了一种格局,或者说是一种文化。没有人可以确切地说触摸屏将能替代键盘,原因便是这份割舍不了的键盘情结。 + +## 一、键盘的历史简述 + +查阅维基百科便可知,最早的键盘可能出现在 17 世纪初,那时的打字机上配备了键盘。有记录的是在 1868 年,被称作“打字机之父”的美国人克里斯托夫·拉森·肖尔斯,获得了打字机模型专利并取得打字机的经营权。随后几年,人们设计出实用形式的现代打字机并首次规范了键盘基本格局,即出现了现在的“QWERTY”键盘。但目前使用更广泛的电脑键盘,人们通常称为“keyboard”。 + +到了 20 世纪中叶,键盘又多了一个用武之地——作为电脑的基本输入设备。可以说,无论时代如何发展,键盘无论如何改变,它的基本功能却从未变过,那便是作为输入设备进行数据录入。 + +## 二、键盘与手写 + +就像我之前的那篇[《那段文字,那些情》](/posts/those-words-my-love/)中说的那样。在这个信息爆发的时代,我们手写的次数越来越少。聊天、上网、游戏,2.0 的网络普及带来了更多的交流。而作为网络言论的接收者和创造者的我们,录入信息的最主要途径便是——键盘。 + +对于手写,很多时候我们只有在签字时才会想到。有时,我们会提笔忘字。每当想写较长的文章时,我更喜欢在电脑上写。因为很多时候,我的思想不是连续的,而是一个又一个支离破碎的片段。而使用键盘的好处在于我可以快速地将思维中的灵感记录下来,再进行编辑。 + +键盘打字更加轻松自由,很多时候更像是一种无意识的条件反射,你只需要快速地敲击几下便好。而与之相对的手写,则更像是一种既费体力又费脑力的事情。用笔的力度、字的好看与否、段落的布局,你要关注到方方面面。 + +所以,写字更像是一种艺术化的行为。而在今天信息高速传递的背景下,我们所关注的更多的是文字本身所传达的思想而不是字体本身的美丑。就像钢笔代替了毛笔,键盘取代了手写,字的本身不断在被弱化。但是,我们不可否认的是,那些千篇一律的铅字从一定程度上抹杀了书法所独有的魅力。 + +## 三、键盘文化 + +美国社会科学家 David Popenoe 说过:文化,是一个群体或社会所共同具有的价值观和意义体系。而作为已经被大家广泛认知的键盘,也带来了另一类的文化冲击。以下列举的便是几种相关的表现。 + +### 1、提笔忘字,写错别字。 + +由于长时间的打字,对于一些字,很多时候我们只记得大致形状却不会写。往往要用时,就得查手机、查电脑。而写错别字也是同样的情况。我至今还记忆深刻的便是在某节语文课上,我们的老师将“老师”写成“老帅”。 + +### 2、另类的流行语 + +提到打字,不由得说的是 80% 的人用的是拼音输入法。而搜狗等智能拼音输入软件的流行也造成了一种奇怪的流行语。就像说“压力”叫做“鸭梨”,“怎么了”变成“肿么了”,“泪流满面”成了“内牛满面”。这些错别字的诞生一开始并不是有意为之,但因为蛮好玩的,所以也就流传开了哦。 + +### 3、看不懂的火星文、象形字 + +“火星文”的火爆甚至一度出现了专用的火星文输入法。“囧”等字的广泛使用也体现了古汉字的魅力。但这些无不是键盘文化的另一种冲击。在人们更多关注思想而不是汉字时,作为媒介的汉字便被大家弱化了。对于那些使用火星文的人士而言,他们关注的是你是否理解,而非是否正确。 + +## 四、键盘是否会被淘汰 + +在我看来,在目前的 20 年内键盘的地位还无法被撼动。对于目前已经在用的手写输入和声控输入而言,其识别率不高、麻烦的外接第三方设备并不能使它们普及,充其量也只能为某些残障人士服务。 + +而目前势头正火的平板能否取代键盘呢?我想不能。键盘文化是 PC 永远无法被平板取代的原因。正是因为平板没有键盘,所以平板的定位是娱乐而不是创作。你不会用触控式输入法来写大量的文档,同样也不会用平板和别人聊得不亦乐乎。键盘是生产设备,是信息时代很多人生存的必备工具。 diff --git a/src/content/posts/2011/2011-11-23-sunny-day-after-rain.mdx b/src/content/posts/2011/2011-11-23-sunny-day-after-rain.mdx new file mode 100644 index 0000000..abc20b5 --- /dev/null +++ b/src/content/posts/2011/2011-11-23-sunny-day-after-rain.mdx @@ -0,0 +1,34 @@ +--- +title: 雨后便是晴天 +slug: sunny-day-after-rain +date: 2011-11-23 11:56:07 +updated: 2020-09-04 21:53:12 +tags: + - 回忆 + - 情感 + - 雨后 + - 晴天 +category: 文章 +cover: /images/2020/09/2020090421472732.jpg +summary: 最近一段时间济南阴雨连绵,窗外的天空中的雾气与那迷蒙的小雨掺杂在一起,到有一种不真切的烟雨江南之感。 +--- + + + +<MusicPlayer netease={441809} /> + +最近一段时间济南阴雨连绵,窗外的天空中雾气与那迷蒙的小雨掺杂在一起,倒有一种不真切的烟雨江南之感。但是这里是北国,时至深秋,济南的天气却如书中所说的那样,一层秋雨一层凉。 + +瑟瑟秋风刺痛着人的面庞,校园道路上的行人日渐稀少、行色匆匆,地上堆积着厚重的落叶,夹杂着树枝、泥沙与雨水的混合物。我在雨中一边行走,一边小心翼翼地避开一个又一个的水洼。不经意间,雨水从伞的缝隙间落下,打在额头上。冰凉的感觉让人心里一突,自己也仿佛变得清醒了许多。突然想起昔日某刻姣好的面容,是放不下,还是相忘于江湖? + +灰蒙蒙的天空,承载着些许思念,幻化成了雨,散落在都市的每个角落。想起三毛的浪漫:我每爱你一次,天上落下一粒沙,从此便有了撒哈拉。我每想你一次,天上落下一滴水,从此有了太平洋。此时落下的雨滴,每一滴都装载了无尽的思念与牵挂。静静地走进楼内的那一刹那,从门口的玻璃门中看见此时的自己。雨珠,伴随着我的泪水,悄然落下,一切,都是忍不住的想念与回忆。 + +也许在某一天会再次相见,所以不停地狂奔,竭尽全力,直到一切都消失不见。望着自己的影子被路灯拉得长长的,看着我的眼泪慢慢地落下,失落与难过顿时充满四周,挤压着自己。无尽的悲伤与寂寞源源不断地将整颗空虚的心填满…… + +前天早上,一直连绵多日的雨终于停了,暖暖的阳光洒向依旧寒冷的空气,让人突然觉得这短暂的温暖是那么的来之不易。搬出被子到阳台上晾晒,换一换略带“发霉”的心情。 + +傍晚的阳光柔情蜜意地抚慰着阳台,透过走廊尽头西向的窗台,刚好照在门前,它毫不吝啬。找任何存在的缝隙给我们更多的光亮,那是一段金黄,更加让人想到可贵的阳光,让人惜之倍分。而我们无法阻止它失去的脚步,好的时光总是短暂,而只能静静地感叹和享受它的存在。正像有些人,注定只能陪你走一段路,而不会伴你一生,拥有时懂得珍惜,失去时请不要哭泣。 + +虽然我无法做到,但我想:在阳光的照射下,应该把心情拿出来晒一晒,忘掉悲伤,去寻找短暂的快乐。这,不是很好吗?在充满阳光的道路上,也许只有孩子明白:雨后便是晴天。 + + diff --git a/src/content/posts/2011/2011-11-25-the-amber-in-november.mdx b/src/content/posts/2011/2011-11-25-the-amber-in-november.mdx new file mode 100644 index 0000000..df6d9cc --- /dev/null +++ b/src/content/posts/2011/2011-11-25-the-amber-in-november.mdx @@ -0,0 +1,40 @@ +--- +title: 十一月的琥珀 +slug: the-amber-in-november +date: 2011-11-25 04:28:08 +updated: 2020-09-04 21:45:42 +tags: + - 琥珀 + - 薰衣草 + - 感触 + - 生日石 +category: 杂思 +cover: /images/2020/09/2020090421241938.jpg +summary: 琥珀,十一月的生日石之一。此时谈起,正当其时。 +--- + + + +<MusicPlayer netease={1697643} /> + +琥珀,十一月的生日石之一。此时谈起,正当其时。 + +相信我们小学的时候都学习过这样一篇课文,名为《奇异的琥珀》。讲的就是一万年前的某个夏天,一滴松脂将两只小虫包裹起来,历经沧海桑田的变迁,变成了化石。而后的某一天,被人发现了,于是它便有了一个新的名字——琥珀。 + +或许这个故事就是我们对于琥珀最早的印象吧,一个神奇的故事,一段凄美的传说。 + +研究上说,琥珀的年龄在 200 万年到 3.6 亿年之间,但大多数宝石级的琥珀的年龄在 500 万年到 5000 万年之间。在漫长的历史长河中,它也被人类冠以各种各样的含义。如:在拉丁文中指“精髓”,在阿拉伯文中是指“胶”,而在中国古代,我们叫它“虎魄”。就在今天,琥珀也依然有许多不同的用途。因为美丽以及拥有能够保持史前生物有机组织的奇异能力,它同时赢得了宝石收藏家和科学家的青睐,成为一扇探索久远过去的窗户。也因其奇特神秘,人们还赋予它许多象征的字眼,如爱、力量、幸运、魔力、保护以及安神等…… + +正是由于琥珀有如此多的非凡魔力,才使无数人与之结下了不解之缘。缘生情,情更浓。不知从何时起,这个可爱的精灵便于人世间最伟大的情藕断丝连,斩之不断。 + +此时,耳畔又响起水木年华的那首《琥珀》:为你守候一扇窗/不管黄昏或黎明/生命每一次跋涉/付出每一分情/为你守住一分缘/翻开风雨不在乎/生命每一次等待/换回每一寸心/我只想感谢上天/让我与你相识/一生不悔的执着/只因这世界有你/给你琥珀的心,琥珀的情/你是我一生的风景/给你琥珀的泪,琥珀的痛/你是我千年不陨星…… + +无论是水木年华深沉又有力的《琥珀》,还是孟京辉的音乐剧《琥珀》,亦或是大提琴家郭虔哲的《凝结在琥珀里的爱情》,无一不是在向人昭示着一种浪漫唯美的爱情。至于凯瑟琳·温莎的小说《琥珀》,更是将这种琥珀之情在 17 世纪的英国传颂了个遍,怎能不令俗世间的男女动容? + +琥珀,古朴含蓄、深沉典雅,给人们一种安详恬静的心灵享受。精致的外观、丰富的色彩,轻巧和美感的手感,将含蓄的智慧传递给人间。由此,我想到了薰衣草。一种原本只生长于法国的普罗旺斯的浪漫植物,相传有一个美丽的传说。“我是你远行的心”便是关于见证薰衣草见证爱情传说中的一句话。那个久远的爱情故事还说:薰衣草的香气可以使不洁之物现形,可以慰藉受伤的心灵,一束美丽的薰衣草能叫人等待爱情的到来。热烈、坚定、浪漫的薰衣草抚慰着人的心灵。 + +一样温暖的名字,一样温馨的表达。瞧,它和琥珀是多么地相似。 + +琥珀,时光的固化,瞬间的永恒,凝结着千百年的生物能量,在蕴含无数神奇传说中,以其浑然天成的古朴庄重之美,温润中透出古典之气,散发出独特的迷人魅力。它,不仅是一个美丽的传说,更是 11 月份出生的一种缘,起于千万年之前,留下了最后的缠绵…… + + diff --git a/src/content/posts/2011/2011-11-29-restart-the-blog.mdx b/src/content/posts/2011/2011-11-29-restart-the-blog.mdx new file mode 100644 index 0000000..835011d --- /dev/null +++ b/src/content/posts/2011/2011-11-29-restart-the-blog.mdx @@ -0,0 +1,34 @@ +--- +title: 写在今天——记重开始写博 +slug: restart-the-blog +date: 2011-11-29 05:16:29 +updated: 2020-09-04 22:29:54 +tags: + - 起点 + - 开始 + - 未来 + - 更新 +category: 杂思 +cover: /images/2020/09/2020090422270141.jpg +summary: Today is the first day of the rest of my life, I wake as a child to see the world begin. +--- + + + +<MusicPlayer netease={1345084315} /> + +> Today is the first day of the rest of my life, I wake as a child to see the world begin. On monarch wings and birthday wondering, want to put on faces, walk in the wet and cold. And look forward to my growing old, to grow is to change, to change is to be new, to be new is to be young again, I barely remember when. + +花了半个多月的时间备案,最后实在是忍受不了缓慢的备案审核,在这个寒冷的 11 月底搬回了墙外。唉,又是一段漫长的搬家,忙好七七八八的东西后已经是午后 5 点。初冬的济南天黑的特别早。想起两年前的今天,我应该是高中放学回家的路上,车窗外,光影流年、万家灯火。即使是在经历过两度春秋的今天,我仍可以真切地记起那时的情景,灯火通明的街道,行行色色的路人。那般真实,仿若不食人间烟火…… + +记忆这个东西总有点不可思议。实际身临其境的时候,几乎未曾意识到那片街景,未曾觉得他有什么撩人情怀之处,更没想到两年之后的历历在目。就像不久前看到的一条新闻,说新闻联播要改版了,那首伴随了国人长达 23 年之久的片头曲也会被新曲所代替。有些人为此惋惜不已,因为那首承载了他们多少年的记忆,每天晚上听到短短的 16 秒的音乐,就预示着饭点到了。对于许多人来说,那不只是一段音乐,更是一种精神寄托。如今要改变这已经习惯了的老曲,倒是真的有点舍不得。 + +不过在我看来,有些改变是必要的,或许这一个个的小改变组合在一起,就形成了一个时代、一种文化的终结,也就预示着新的时代的来临。在不同的时间段内,我们需要赋予它不同的意义,为它注入新的血液,才能成为一个跨越。也正是有这些一点一滴的改变,日积月累,才能开启新时代的篇章。唯有不断改变、不断进步,才能有所突破。我们要做的便是顺应这些变化,珍惜现在、时间,以迎接美好的未来。 + +人生莫过于如此。时间的转轮一刻也不停歇,每天,时光都在悄悄地溜走,此刻的你是未来的时光中最年轻的。但是,你不必要为失去的时光留恋惆怅,也不必为即将到来的时光担忧迷茫。珍惜现在,你会发现,人生的道路上其实有很多精彩。朋友说我已经有了初老的迹象,对过去的事情记得很清楚,对近来发生的总是忘记。或许人长大了,总会怀念过去的时光,相比现在的忙碌与压力,许多人宁愿选择活在过去的世界里,沉湎于过去不可自拔。人总有怀旧的时候,我也会,但如果总被过去所束缚,逃不出旧有的圈子,那只能是对于现实的逃避,大好的青春都浪费在迷失里了。换一个角度,倘若在未来的某一天,当你回首往事的时,却发现,那些本该应有青春活力的日子却被回忆所占据,那时候,你又能拿什么去回忆呢? + +《功夫熊猫》中师傅教育阿宝说:“Yesterday is history, tomorrow is mystery, today is God's gift.” 所以让我们一起珍惜今天这个上帝给予我们的礼物。Because today is the first day of the rest of my weblog's life. + +仅以此文纪念我的博客的另一个新的开始。 + + diff --git a/src/content/posts/2011/2011-11-30-the-first-snowing.mdx b/src/content/posts/2011/2011-11-30-the-first-snowing.mdx new file mode 100644 index 0000000..380bc04 --- /dev/null +++ b/src/content/posts/2011/2011-11-30-the-first-snowing.mdx @@ -0,0 +1,52 @@ +--- +title: 2011年的第一场雪 +slug: the-first-snowing +date: 2011-11-30 01:37:31 +updated: 2020-09-04 22:46:05 +tags: + - 济南 + - 杂思 + - 情感 + - 雪 +category: 杂思 +cover: /images/2020/09/2020090422395473.jpg +summary: 角落里有一片暗雪/我猜它会是/一张被雨水冲着/想在那里休息的报纸/它的周身/被不大的印字布满/一天的新闻恰如历史的一粒微尘/曾经存在/却又慢慢的变得微不足道。 +--- + + + +<MusicPlayer netease={31446197} /> + +> 角落里有一片暗雪 +> +> 我猜它会是 +> +> 一张被雨水冲着 +> +> 想在那里休息的报纸 +> +> 它的周身 +> +> 被不大的印字布满 +> +> 一天的新闻恰如历史的一粒微尘 +> +> 曾经存在 +> +> 却又慢慢的变得微不足道。 + +昨日傍晚时分,天上开始由小雨转为小雪。我坐在暖暖的自习室里看着书,却不知,外面早已下起了雪。某刻被女友云儿的推去看雪,才发现,窗外早已是银装素裹。 + +外面的雪下得好欢快呀!喜欢冬天,因为自己喜欢下雪的日子,喜欢雪花洋洋洒洒的飘落。今年的雪来的比去年早了很多,还记得去年那场薄薄的小雪,只把地面刷白。而今年的上天终是不吝啬,在 11 年 11 月的最后两天给大地披上了洁白的衣装。 + +大雪点亮了齐鲁大地,也用无瑕的白色刷新了我们的校园,远望去,红色的教学楼,淡黄色的宿舍楼更显得稳重和温馨。我喜欢雪却没有为什么,只是喜欢。这种白色充满光亮的白色,可以把所有的不光彩的尘埃、垃圾、枯枝烂叶一起盖在下面,而只允许人们去寻找和探索雪下的事物。大雪给本来郁闷几分沮丧的我带来了一点欢快和舒心,真是好雪。 + +夜晚,雪花透过漆黑的苍穹飘落人间,它们在自习楼前的路灯照射下显现点点身影,在风中时而左摆时而右摆快活的活动着。它们很像一群有生命的洁白的小精灵,相互嬉闹着,集体飞向某方,前面的忽然停住了,后面的也跟着回转,似乎听到了前面雪花兄弟姐妹的呼声:再走就撞墙了,撤!于是乎又集体跑开了。偶尔有几个淘气的小精灵前来伏在面前的窗玻璃上,静静的,这才发现它们是那样的娇小,却很快只剩下几点晶莹的水点。想起论坛上有人贴过的雪花的容颜,放大了几十倍的,很是漂亮。简单中透着复杂,丰满和谐,六边形的骨架自然美观。不晓得大自然如何构成如此小巧的规范,更难以想象他在雪花六个枝上做的手艺…… + +雪花飘落,在世界的各个角落找到了自己的位置,有的落在水泥地上,化成了水,是哭了吗?至少为后来的雪花润湿了栖身之地;有的落在草地和松柏上,在黯淡的夜中透着洁白的靓影,想像它们在枝丫上你推我挤的闹得不亦乐乎,这时我想起了日本宫崎骏的“鹿神”,茂密的丛林中小孩样的木精们从树干的罅隙中钻出来晃动着脑袋发出的哒啦啦哒啦啦的弹性的声音,时而又将脑袋转个 360 度,也是你推我挤得,有时背着伙伴在树间走来走去,表情丰富的露出累而调皮的神情。想象着想象着,心底萌生出几分喜悦。 + +想起初一时看过的一部名为[《我的兄弟姐妹》](https://movie.douban.com/subject/1316513/)的老电影,其中的情节,已经非常模糊了。却一直记得其中的一句台词:兄弟姐妹们本是天上的小雪花,落到了地上,结成了冰,化成了水,就彼此再也不分开了。瑞雪寒冬,独在异乡的我是那么孤独。就像是空气中依然在恣意飞舞的雪花,一直流浪、漂泊。但是,落叶归根、老燕识巢,迷途的游子离不开的是远方的亲人。拿出手机,拨通厦门母亲的电话问一声安好?便心安,厦门依旧温暖如春。 + +再次回望窗外的雪景,月亮已经出来,照射在雪地上,伴着浓雾反射出一片银白色的辉光,似是天上的宫阙。真可谓一场好雪! + + diff --git a/src/content/posts/2011/2011-12-07-drink-the-tea.mdx b/src/content/posts/2011/2011-12-07-drink-the-tea.mdx new file mode 100644 index 0000000..447e5a1 --- /dev/null +++ b/src/content/posts/2011/2011-12-07-drink-the-tea.mdx @@ -0,0 +1,33 @@ +--- +title: 茶品 · 茶悟 +slug: drink-the-tea +date: 2011-12-07 01:12:58 +updated: 2020-09-04 23:06:50 +tags: + - 人生 + - 茶 + - 品悟 +category: 杂思 +cover: /images/2020/09/2020090423034580.jpg +summary: 翻开最新一期的山大周刊,页末的一篇关于茶的感悟吸引了我的目光。文章的作者说:其实茶有三次生命。一是茶的自然生命,是茶作为一种植物的自然生命过程。 +--- + + + +<MusicPlayer netease={105734} /> + +翻开最新一期的山大周刊,页末的一篇关于茶的感悟吸引了我的目光。文章的作者说:其实茶有三次生命。一是茶的自然生命,是茶作为一种植物的自然生命过程。而其二便是茶的制作生命,作为一种饮品的商品生命过程。第三,就是茶的人受生命,是在品饮过程中人与茶的互动过程。 + +一杯清茶,从灌木到杯中,经过了三次生命的锤炼过程。故品茶,更像是一种品悟,一种对于茶生命的细碎感悟。就像前文提到的茶的三次生命,只是一种外在的、独立的、缘外的感触。而开始品饮之后,茶水由口入体进心,才有了另外一种芬芳、灿烂、亲密、独具的“生命”。 + +一杯茶,唤醒时光的边缘;一杯茶,还原一个春天。同样一杯茶,喝的人不同,便会有不一样的感受。虽然滋味差不多,但是对于茶水的灵动、质感与生命色彩却是由饮者所赋予的。正可谓千江有水千江月,万人品茗万里香。 + +清晨的我喜欢泡一杯咖啡,听几首欢快的歌曲,是为提神。而傍晚时分的奶茶,更多是一种冬日里的一份温度,融融的投进心底。而对于喝茶,更像是一种品位,需要在午后时分,一天天气最好、精神最好的时分慢慢细品。一杯一杯,缓慢细数时光的流逝。住在厦门时,常常看见家门口的大榕树下,一对老人在树下石凳上慢条斯理地喝着茶。喝茶、嗑瓜子、谈笑风生,而时间对于他们而言,是极其缓慢的……茶座旁的开水壶依旧一天天地冒着哧哧的热气,只是某一天,当我再经过榕树下时,只剩一人。氤氲的水汽弥漫在老人周围,也迷蒙了我的眼睛…… + +此情此景却好似曾经读过的《相忘江湖》里面的开头:“隔一程山水,你是我无法靠近的彼岸,与我坐望于光阴的两岸。彼处桃花盛开,绚烂如漫天凄艳的晚霞,你笑得从容,而我却仍在这里守望,落英如雨,映出我拈花一笑的了然。”而人走,茶亦凉。虽淡然,却多了一份相思。所以有时候很喜欢茶道里面的“一生一会”的说法。就像林清玄曾经说过的那样:我们每次与朋友对坐喝茶,都应该生起很深的珍惜。因为一生里能这样的喝茶可能只有这一回,一旦过了,就再也不可得了。 + +一生只有这一次聚会,一生只有这一次相遇。往往使我们在喝茶的时候,会沉入一种疼惜与深刻,而不至于错失那最美好的因缘。所以有时候,喝茶的感受就是一个人的人生经历的另一种体现,你可以从中看出一个人的心灵。 + +胡适说:“一个人就是他所吃的东西,所以达柯塔的务农者,加利福尼亚的种果者,以及千百万别的粮食供给者的工作,都是生活在他的身上。因此套用胡适先生的话来说,一个人就是他自己所喝的东西,所以福建的铁观音,台湾的高山茶,以及千百万的茶业者的劳作,都是生活在他的身上。说茶悟人生,其实是因为茶进入到我们生命中来,让我们感觉到了它的芬芳与甜香。品茶人中的快乐与感悟,无一不是基于此。 + + diff --git a/src/content/posts/2011/2011-12-09-you-are-the-apple-of-mine.mdx b/src/content/posts/2011/2011-12-09-you-are-the-apple-of-mine.mdx new file mode 100644 index 0000000..fca3003 --- /dev/null +++ b/src/content/posts/2011/2011-12-09-you-are-the-apple-of-mine.mdx @@ -0,0 +1,42 @@ +--- +title: 那些年我们一起追过的女孩 +slug: you-are-the-apple-of-mine +date: 2011-12-09 01:43:49 +updated: 2020-09-06 11:31:29 +tags: + - 青春 + - 影评 + - 成长 + - 那些年 +category: 杂思 +cover: /images/2024/04/2024041519203200.jpg +summary: 夜里12点,耗尽笔记本里面的最后一格电量的我终于将这部电影看完,却怎么也睡不着。抬头看着桌前的墙壁,回想起已逝的青春经历,整个人便有了一种苍老的感觉。 +--- + + + +<MusicPlayer netease={572912887} /> + +夜里12点,耗尽笔记本里面的最后一格电量的我终于将这部电影看完,却怎么也睡不着。抬头看着桌前的墙壁,回想起已逝的青春经历,整个人便有了一种苍老的感觉。对于已逝的过去,突然觉得像梦一般漫长…… + +不得不说导演“九把刀”的才华与浪漫,或者说对于情感的深度刻画。整个电影中的故事情节非常平淡,就像是一份长达十多年的流水账,从头到尾的舒缓读完。但是,就是这一份份简单至极的故事,在影片的最后一一回放,却让人不由得感动、落泪。在我眼中,所谓的打动人心,依靠的往往不是那些惊天动地的故事。有时仅仅是一种简单,一份与你的人生经历类似的故事,便可挑动你记忆最深处的那份柔软,让你潸然落泪。就像一年前的《老男孩》一样是一部简单至极的片子,却应其中的片段和大多数的80后经历呼应,便感动了许多人。 + +对于影片的剧情,我想,我所看到懂的是一段男孩成长为男人的故事。也许是我的阅历不够,更或者是我的感触不深。但仅仅是关于成长,便让人思绪颇多。 + +柯景腾在读国中时成绩不好而且很喜欢调皮捣蛋,在一次上课“打飞机”被老师抓住后校长把他调到了班级成绩最好的女生沈佳仪前面,让她监督景腾的学习。于是便有了校园小说里常有的端子,佳仪很是“爱管闲事”,只要景腾不在读书,便各种督促。两个人的关系,并不是很融洽。直到某天的英语课上,景腾主动把自己的英语课本借给没带书的佳仪,替她出去受罚时,两个人之间的关系开始缓和,我们的故事才算真正展开…… + +从最初的不想读书到被沈佳仪逼着读书,从被逼读书到景腾自己主动读书并乐在其中。我们轻易地看到了男孩的成长。但是景腾的心里却又是极其幼稚的,就像国中毕业大家一起游玩时在桥上谈论的理想一样,希望自己成为一个顶天立地的人。比起周围很多人明确的目标,是那样的幼稚、飘渺。 + +而对于爱情的试探,景腾可以说是一败涂地。说傻,不如说是可爱。从开始的两人朦胧的感觉,到高考佳仪失利后的小心安慰,景腾一直没有发现佳仪对于自己的喜欢,也许恋爱中的男生是麻木的吧。或许是景腾太喜欢,以至于害怕被拒绝后的失望。就像大学寒假,两人一起去游玩时景腾在表白后不想知道佳仪的答案。 + +但是,两人最后没有走到一起的关键在于景腾的不成熟。其实作为旁观者的我们很容易发现,佳仪对于景腾的要求不在于他读书是否好、人是否打架“很厉害”。佳仪所希望看到的是男孩的长大与心理的成熟,不再幼稚。这也是为什么当佳仪看到景腾和别人打架弄一身伤时的失望与心痛;当两个人吵架分手时邵和文可以成功追到沈佳仪的原因。 + +而我想,每一个男孩的成长和成熟,其实有时不需要多久,仅仅是短短的一瞬便好。就像阿景,在经历了时间与社会的磨砺,再次见到即将嫁为人妇的沈佳仪的那一刹那,他便懂了。其实爱情,不分结果,只要默默祝福现在的她(他)幸福,便一切都好。 + +也就像《我与狗狗的十个约定》里面的明莉,在狗狗死去的那一刻,才懂得了关爱与感恩,并对两鬓已经斑白的爸爸说:“谢谢你,爸爸。”而人生中的青葱年华,那些与我们相似的日子里所记述的便是有关成长的故事。也只有经历过,我们才能脱去一份稚气,更添一份成年人的智慧。 + +用影片中的一句话来说:生活不是一张考卷,没有对错答案,你永远不知道下一刻该选什么。所以,我们的故事依旧继续。 + +下一刻,生命起航…… + + diff --git a/src/content/posts/2011/2011-12-11-sauvignon-blanc.mdx b/src/content/posts/2011/2011-12-11-sauvignon-blanc.mdx new file mode 100644 index 0000000..b930fc8 --- /dev/null +++ b/src/content/posts/2011/2011-12-11-sauvignon-blanc.mdx @@ -0,0 +1,57 @@ +--- +title: 最是一番长相思 +slug: sauvignon-blanc +date: 2011-12-11 01:58:34 +updated: 2020-09-06 11:32:00 +tags: + - 回忆 + - 那些年 + - 相思 + - 思念 + - 冷山 +category: 文章 +cover: /images/2024/04/2024041519325100.jpg +summary: 堇色年华,青春的下一个路口,再回首,却是多般支离破碎。毕业,然后各奔东西,聚了又散、离离合合。我们总会遇见一些人,然后在某一刻踏上开往南北的列车,就此不常相见。 +--- + + + +<MusicPlayer netease={496869422} /> + +与你擦肩而过的时候,蓦然回首,那人似曾相识…… + +## 一、青春告别曲 + +堇色年华,青春的下一个路口,再回首,却是多般支离破碎。 + +毕业,然后各奔东西,聚了又散、离离合合。我们总会遇见一些人,然后在某一刻踏上开往南北的列车,就此不常相见。但是,忘不了的还是心中的你那昔日身影…… + +安东尼说:“还会遇见很多人,还要经历许多事,只是那些感动的事还会再记得么,那些喜欢过的人还会再遇见么?”我们彼此南北分隔,和那些互不相识的人做着彼此所不了解的事。 + +你知道吗?在你居住的城市里,有我思念的牵挂。 + +而喜欢上阿狸,是在上了大学以后,因为那只可爱的火红小狐狸总是像你一样笨笨的可爱。怀揣一本《永远站》和阿狸在城市的某个街角踏上了那辆红色巴士,去找寻幸福。我不知现在开往何方,但是在我的心中却有一个终点。就像是一种感觉、一种信赖,就像我一直知道,你永远都爱着我。 + +那个寒假,我们再见,轻轻地挽起彼此的双手,走在废旧的铁轨上。嘴上不语,心中悄悄地无数遍爱你。 + +Dreams, as if you never wake up. + +我悄悄在某个站点下车,去找寻属于我的小小天地。它在我心里,小小的、暖暖的,也与你在一起…… + +## 二、思念回响曲 + +《冷山》里,那位在美国南北战争末期受伤的士兵英曼,在灵魂仿佛燃尽之后,对于家园的渴望使他重新站立起来,踏上了艰辛漫长的归家路途。他的情人艾达在山里的乡间独立忍受孤独,并学会了与艰苦的生活斗争。 + +战争带走了一切,而依旧兀立于天地间的冷山便是他们之间唯一的联系,是他们回忆与向往的地方。就如《思无邪》里面描述的那样:“一个人即使你所信仰的天堂已然破碎,却仍然为你疗伤止痛的美好国度。”从战场重归家乡,回到日夜思念的爱人身边,整个人也从破损重归完整。 + +想起那首《我愿意陪你走》:我耗尽了温柔,我孤独地等候,你却放开了手,我在你的身后只换来一句苍白借口。在汹涌的街头,我寂寞地逗留,有谁能够解救,你从前的笑容那么久,盘旋在我左右。我愿意陪你走,就让我陪你走,多希望陪着你直到老,走过天涯海角。我找啊找啊找啊找,找不到曾经的天荒地老,我逃啊逃啊逃啊逃,逃不出遍体鳞伤的煎熬…… + +一样的寻找与等待,一样的悲伤情感,恰是对《冷山》的真实写照。而英曼在受伤之际能重新站起的源泉便是对于爱人的思念,在遥远的那边有艾达为他庇佑。哪怕是路途遥远、生活粗粝尘锐,英曼都会为了她顽强地去承受,只因最初的承诺。 + +而别离的相思之苦,恰如泰戈尔的诗句中说的那样:“每当我想起你时,你的眼睛就挂满星际。”故不论月亮的圆缺,思念都似一首绵长的诗,让你哭,让你笑。不论你是哭着思念,还是笑着思念,都是生命之中最真实的记录。 + +于是,伴随着思念而来的便是英曼、艾达两人间漫长的等待。正如诗人迪金森说的那样:“等待一万年不长,如果有爱作为补偿。” + +也就有了人海中的徘徊、寻找,于那千万人中遇见你所找寻的她。时间的无际空间里,没有早,没有晚,两个人恰好匆匆遇见。此刻却没有了什么浪漫的画面与对白。千言万语只化尽,唯有轻轻地问一句:“噢,你也在这里吗?” + + diff --git a/src/content/posts/2011/2011-12-16-one-hundred-days.mdx b/src/content/posts/2011/2011-12-16-one-hundred-days.mdx new file mode 100644 index 0000000..d540287 --- /dev/null +++ b/src/content/posts/2011/2011-12-16-one-hundred-days.mdx @@ -0,0 +1,77 @@ +--- +title: 第几个100天——博客百日记录 +slug: one-hundred-days +date: 2011-12-16 11:23:12 +updated: 2020-09-06 11:33:13 +tags: + - 情感 + - 百日 + - 纪念 +category: 杂思 +cover: /images/2024/04/2024041519424200.jpg +summary: 时间终会一点一滴磨平我们青春的印迹,那散在记忆里的片段退去了华丽的色彩,留下的还有什么呢? +--- + + + +<MusicPlayer netease={413961275} /> + +时间终会一点一滴磨平我们青春的印迹,那散在记忆里的片段退去了华丽的色彩,留下的还有什么呢? + +## 一、缘起 + +就像张爱玲说的那样:“于千万人中遇见你所要遇见的人,在千万年之中,时间的无涯的荒野里,没有早一步,也没有晚一步,刚巧赶上了。”缘分便是这般神奇,就像我与 WordPress 的邂逅,也是各种偶然与巧合。 + +那么许下一个写博客的决定,需要多长时间? + +我知道,这个问题是多么的白痴。那么简单的一个计划,往往只是脑海中简单的一瞬。又何必在意,许下一个约定所用的时间? + +时间被缩影成一帧帧光感饱满的电影胶片,带动岁月的齿轮从眼前卷过,勾起往事悠悠回忆无边。那些最初的记忆似乎就发生在昨天。 + +第一次遇见 WordPress,便是与软件街博客的不期而遇。第一次发现,原来博客还可以这么漂亮。所以,这就是缘。而在脑海中常常有许多的想法,一段话,在键盘上流出之前,早已在心中酝酿了很久,也许在写下之前,便忘了大半。于是,那么多记忆的文字,就在心底长久的累积。也在某一刻,促使我做下写博客的约定…… + +于是乎,对于写博客的缘由便是一种思想的表达吧。 + + + +## 二、流年 + +我们总是通过记忆的缺口张望,流失的色彩,消逝的行人。也许是我们陌生的彼此,也许是我们的擦肩而过,也许是蓦然瞥见人潮涌动中匆匆闪过的侧影,但这一刻,便是回忆。 + +100 天,说长不长,说短不短,但是却拥有着无数个第一次。第一次解析域名、第一次用后台、第一次发表一篇文章,这种初试的美好与快乐我想只有那些一样在写博客的主人才能真正体会。留言、回复、友链,当你的博客诱人来访,有人围观时的那份喜悦也便是我写博客至今的动力吧。那就是:将你的思想给别人看。 + +曾经在 16 岁的日记本里写下略显单薄的字迹:孤单时我们总是躲在寂寞的墙角悄悄哭泣,眼泪化成永生不灭的琥珀,让我们在一起的时光进驻里面,就算我们都老了,老到认不出了彼此,认不出了漫天的飞雪是为你而纷纷扬扬……然后做一个大大的梦,在岁月中拾荒,柠檬的色彩,短短的头发,齐眉的刘海,似乎都不够…… + +我们还没有权利伤感,至少对于青春应该是活力与张扬,就像前些日子窗外纷扬的雪花。永不停息的生命旅途中,博客,这个偏安于世的转角驿站,给奔流的岁月投去一道柔光。无处安放的青春在这里偷得浮生半日闲暇,陶然憩息。 + +《穿过流水》中唱到:在船桨起落之间,看流水带走两岸的云烟。在手指交汇之间,看穿过空气的阳光耀眼。在你我之间,在天地之间,谁转过身、遮住脸?不忍看一段青春走远。在回望的视线里,我听见明媚的往昔。 + +生命只能不断地经历春夏秋冬,而我们在热爱世界时,便活在了这个世界上。纵然一切都是瞬息,一切都将会过去。而那过去的,便将成为亲切的怀念,正如这一处可安歇的博客小屋。 + + + +## 三、人事 + +> 当岁月的脚步再移一小步,我忘了你是过客,你是,过客。 + +这样伤感的文字终究只能是纪念,纪念我所经历的长路,回忆那些各色的路人。 + +人生路上的遇见,又需要多少缘分才能做到?不像教科书里面的概率一样可以估测,只是一种偶然与必然的文艺辩论。但是,总有人与你遇见,也总有人离开…… + +遇见了你们,遇见了缘分。平淡的日子因为您们的来访变得闪闪发亮,阴霾的心情因为你们的留言一扫而光。遇见了你们,道一声珍惜。我珍惜,不仅仅是你们出现在我生命最绚烂的时刻;我珍惜,不仅仅是因为你们对于我的文字的欣赏;我珍惜,只是因为你们是我写博客时光中最美的记忆。珍惜那些留言,那些温暖了整个冬季的话语。 + +看见后台控制面板上一个个活生生的面孔,有关记忆的故事和回忆充溢开来。至少在纷乱迷茫之时,“永远陪伴”这样矫揉造作的愿望成了一份写作的动力。所以,纵然前方未知,至少有了你们的鼓励与祝福,才有了一份别样的温馨与感动。 + + + +## 四、明天 + +席慕容的《羊蹄甲》里曾说过:在整个人生的长路上,不是都开着像羊蹄甲一样迷迷潆潆的花树吗?往前看过去的时候,总是看不真切,总是觉得笼罩着一层缥缈的烟雾,等到真的走到树下了,却又只能看到一朵一朵与远看时完全不同的单薄细润的花朵。所以对于未知的明天,并不可怕,遇到时便会知道结果与状况。 + +也就像亨利·米勒说:“一切为了明天,但明天从不到来。”以故明天的不确定性,是珍惜今日的动力。对于看似漫长的博客写作时光中,“今天”便是一粒种子,我们要创造一片土壤,让它成长为“明天”那棵大树。 + +对于文字,我的追求是一种思想的调门不高,却用情至深的写作。“用情”便是最为关键的。只有深情,才有了使用一切词语表达情感的冲动,才有了精耕细作,才有了水平的不断提升——在自我那个思想触及的因素面前,唯有深情促使我们的文章体现与“深情”对应的仪式感。 + +所以我将自由地在这个只属于我的博客平台里书写着我的情感与思想。也许有一天我累了,我会放弃。但是,那些都是难忘的美好记忆。 + +——谨以此文纪念我的博客写作 100 天 diff --git a/src/content/posts/2011/2011-12-20-who-is-singing.mdx b/src/content/posts/2011/2011-12-20-who-is-singing.mdx new file mode 100644 index 0000000..e2d8e94 --- /dev/null +++ b/src/content/posts/2011/2011-12-20-who-is-singing.mdx @@ -0,0 +1,57 @@ +--- +title: 听是谁在唱歌 +slug: who-is-singing +date: 2011-12-20 06:38:49 +updated: 2021-11-23 17:50:23 +tags: + - 回忆 + - 情感 + - 刘若英 + - 听,是谁在唱歌 + - 老歌 +category: 杂思 +cover: /images/2022/04/2022041519522100.jpg +summary: 听着奶茶的甜美的嗓音,便是一种恬静的享受。冬日里的午后,音箱里放着那首“听,是谁在唱歌”,像是有一种魔力般的感染,让人回忆许久。而仔细回想,都是种呼唤…… +--- + + + +<MusicPlayer netease={238964} /> + +听着奶茶的甜美的嗓音,便是一种恬静的享受。冬日里的午后,音箱里放着那首“听,是谁在唱歌”,像是有一种魔力般的感染,让人回忆许久。而仔细回想,都是种呼唤…… + +## 音乐,生活的百味 + +如果说生活是百味的季节,那么音乐便是回味的片片落叶。 + +喜爱音乐,因为音乐如生活中缭绕的云雾,诗化了单调与平凡。看书时让一首轻音乐慢慢地在身边飘起,眼前便铺开章节中的情境。入神了,自己也幻化成书中的角色,在音乐的侵染下演绎童话与传奇。若是生活中有了苦闷,音乐如展开思绪繁节的巧手。倾听不过几分钟,怒热就渐渐的冷却,繁杂渐渐的舒展,于是心平,于是气和,于是一切归于安守。用音乐来点缀生活,虽不可旋转人生,却衬托了生活的美好;营造了温馨,化解了纷繁。音乐的感染是落叶铺满小路的浪漫。 + +喜爱音乐,因为音乐有韵律种种,这韵律是生活的脉搏。兴奋时开启音响,找个激昂的曲调。不自主的随着节拍跳动,幻想自己站在华妆的舞台,在万众的惊慕和呼喊中成为焦点;忧伤时带上耳机,听一曲或钢琴或吉他伴奏的独唱,遐思自己在空无的大厅,边拂动手中的乐器,边让音乐边打心中的哀愁,不知不觉音乐载着心绪流动。回到现实,目明心朗,再加上一种说不出来,唯有自己明白的满足,作为韵律,音乐是夜落至手边的感动。 + +最爱音乐,因为音乐唱出了心中久久不能道明的话语。陪着她徜徉,于耳畔响起。 + +## 那首,循环的单曲 + +已知的老歌里,罗大佑、张艾嘉先后用他们忧伤略带磁性的歌喉唱着《光阴的故事》:“春天的花开秋天的风以及冬天的落阳,忧郁的青春年少的我曾经无知的这么想。风车在四季轮回的歌里它天天地流转,风花雪月的诗句里我在年年的成长。流水它带走光阴的故事改变了一个人,就在那多愁善感而初次等待的青春。”曾经很长一段时间喜欢这首歌曲。而“凄雨冷风中,多少繁华如梦”,人生的真谛便是如此。淡淡地忧郁如同流转的风车,悠久平淡。繁华如梦,往昔的青春年少,到头来,都如昨夜的轻梦…… + +小时候的我很喜欢一整个下午一直听着某首歌曲,一遍又一遍。每当父母上班一个人在家时,便会放着那盘仅有的老磁带,听着蔡琴的“你的眼神”、苏芮的“牵手”、孟庭苇的“野百合也有春天”。而每一首歌曲里,唱不尽、道不完的便是那些思念与深情。久远而又熟悉的旋律中,带着曾经在这片苍穹下吹拂过去的约定,永远的流淌在你我如同钻石一般的记忆银河之中,闪烁成为无数人眼瞳里面心悸和疼痛的故事…… + +常在一边看书时一边听着某段不知名的曲调,就像此刻的我写下这段话时,耳机里重复放着文首的MV。一样伤感的曲调,一样的深情,让人忍不住听了一遍又一遍。想起有人说过:音乐是最为接近神的语言。那么究竟是怎样一段曲调,怎样一种歌喉,怎样一番情思,让你将整整一首歌曲,一遍、一遍地单曲循环了呢? + +谁的歌声,像是塞壬的歌喉,拂拭着人们心灵最脆弱的沙洲,带来天空瞬息万变的风景,奏动了锈迹斑斑的的琴弦…… + +## 那些,消失的声音 + +人总是要走出去很远之后,一回头,才会想起那些消失的声音。 + +歌曲与歌曲的更替,乐坛上新人换了旧颜,有多少曾经让人难以追怀。 + +我曾希望那些优美的曲调能够留存的久远些,但它们大都沉淀在记忆里面。随着一些人的离世,那些相似的声音就此弥散在空气中,再也无从唱起。 + +而那些声音的消失、溃散,是多么的令人伤心欲绝的事情。人生易老天难老,飞花易逝,岁月无情。就像在某种声音中颤动过的空气,一转身,已经默不出声,或者出现在另一端声音里…… + +回不去的地方叫去过,忘不了的东西叫记忆。那些消失的曲调一直被深埋与脑海中,终将在某刻被唤醒,重新浮现。 + +听,是谁在唱歌? + + diff --git a/src/content/posts/2012/2012-01-01-the-stopped-wheelchair.mdx b/src/content/posts/2012/2012-01-01-the-stopped-wheelchair.mdx new file mode 100644 index 0000000..e1d69e2 --- /dev/null +++ b/src/content/posts/2012/2012-01-01-the-stopped-wheelchair.mdx @@ -0,0 +1,51 @@ +--- +title: 停止了一年的轮椅 +slug: the-stopped-wheelchair +date: 2012-01-01 15:20:43 +updated: 2020-09-06 11:36:12 +tags: + - 回忆 + - 史铁生 + - 生与死 +category: 文章 +cover: /images/2024/04/2024041520022600.jpg +summary: 从生到死,这位病人因为瘫痪已经在轮椅上度过了38年,在2010年12月31日凌晨因为突发脑溢血逝世。从那时起,这只摇了38年的轮椅,停了。 +--- + + + +<MusicPlayer netease={28285910} /> + +当时钟指向 2011 年的最后一天时,相信很多人都在庆祝新年的到来。这一天也是剧作家史铁生去世整整一年的时间。从生到死,这位病人因为瘫痪已经在轮椅上度过了 38 年,在 2010 年 12 月 31 日凌晨因为突发脑溢血逝世。从那时起,这只摇了 38 年的轮椅,停了。 + +--- + +了解史铁生,应该是从高中的那篇阅读《我与地坛》。在文章里,作者都摇着吊有用来接尿的黄色塑料瓶的轮椅,前去离大杂院不远的地坛。就在这座荒废的园子里,“一连几个小时,专心致志地思考关于死的故事,也用同样的耐心和方式思考为什么要出生。” + +在作者徐晓的记述中:“黑色的皮肤,厚厚的嘴唇,明显有残疾的双腿,总是‘捧着本厚厚的英文字典’。”也就是这样一个人,带着本子和笔,在园中人少的角落里“偷偷地”写。如果有人无意中闯进这个空间,“他就把本子合上,把笔叼在嘴里”。 + +以这种极其特别的方式,最终诞生了那篇长达 15000 字的《我与地坛》。从这篇文章中我们看到作者最“真实”的写作与思考人生的体悟,并以一种扣动心扉的追问深深地打动了无数读者。就如作家韩少功曾经说过的那样:“这篇文章的发表,对当年的文坛来说,即使没有其它的作品,那一年的文坛也是一个丰年。” + +似乎“疾病”便是与史铁生联系最深刻的词。 + +这位一直自嘲“职业是生病,业余是写作的”男人曾将自己的身体比作一架飞机。从 21 岁开始,就一直没逃脱出疾病的折磨。先是作为“起落架”的两条腿瘫痪了,然后便是像“发动机”一样的两个肾也“一起失灵”——患上了尿毒症。他不得不以每周三次的透析来维持生命…… + +而才开始瘫痪的时候,史铁生是迷茫的,“我没有死,也再不能走,对未来怀着希望也怀着恐惧。在以后的年月里,还将有很多我料想不到的事情发生,我仍旧有时候默念‘上帝保佑’而陷入茫然。” + +经过了茫然、无助,意识到命运已经将他束缚在轮椅上后,史铁生便将所有的精力投身于写作,用思想代替双脚,向着自己的内心深处走去,越行越远…… + +人为什么而活?或者为了什么?这是史铁生在瘫痪后一直要面对的问题,也是作者写作的动机——为活着找充分的理由。 + +在起初的苦难日子里,作者曾想过以自杀的方式结束自己冤案般的生命。但随后便觉得这是最无聊的方法,开始接受身体残疾的事实。他说:“苦难不可避免,看来只好接受苦难。人类的全部剧目需要它。” + +“人生来残缺,人生艰难、充满困境,当人面临的困境没有尽头的时候,会变得焦躁而脆弱,这时候需要一种对于生命的理解。”那么,是什么让作者的精神历经病魔的洗礼而依然健康,备受打击却不会崩溃? + +信仰。是的,信仰。“在命运的混沌之点,人唯有乞灵于自己的精神。不管我们信仰什么,都是我们自己的精神的描述和引导。”于是,在史铁生看来,写作是一种生命存在的方式,一种意义的证明,“只是因为我活着,我才不得不写作。” + +由史铁生的小说《命若琴弦》改编的电影《边走边唱》里,盲人钢琴师的师傅说:“千弦断,天眼开”,意为弹断 1000 根琴弦能带来光明。而盲人对于光明的渴望就像残疾了双腿的渴望行走一样,从未停止。那个永远不曾实现的梦想,谁又会想起? + +《我与地坛》里史铁生这样看待死亡:“死是一件无论怎样耽搁也不会错过的事,一个必然会降临的节日。”注定来的,终究还是来了,没有什么改变,只是昔日地坛里的身影,再也不会出现了。 + +**再见,史铁生。** + + diff --git a/src/content/posts/2012/2012-01-26-visitant.mdx b/src/content/posts/2012/2012-01-26-visitant.mdx new file mode 100644 index 0000000..2ae04c1 --- /dev/null +++ b/src/content/posts/2012/2012-01-26-visitant.mdx @@ -0,0 +1,47 @@ +--- +title: 候鸟 +slug: visitant +date: 2012-01-25 17:08:09 +updated: 2020-09-06 11:37:25 +tags: + - 迷茫 + - 候鸟 + - 回家 +category: 文章 +cover: /images/2012/03/2012030819164800.jpg +summary: 放假回家前收拾了一个下午的东西,现在窗外天已经黑了,我重新坐下来。回身看到放在身旁的行李箱,大大的、满满的。原本杂乱无章的书桌也有些空荡荡的 +--- + + + +<MusicPlayer netease={1938687497} /> + +放假回家前,我收拾了一个下午的东西,现在窗外天已经黑了,我重新坐了下来。 + +回头看到放在身旁的行李箱,大大的、满满的。原本杂乱无章的书桌也显得有些空荡荡的。 + +看来,时间并没有欺骗我,我真的要离开学校回家了。 + +也许是天生缺乏安全感。虽然没有离开这个学习生活的城市,但我还是莫名地感到陌生和恐惧。我像一个恋旧的旅人,矛盾的心理使我尽力去保留家的气息:厚厚的日记本、小小的围巾、睡觉时抱的企鹅点点、蓝色的小熊毛巾……如果可以,我愿意是一只小小的蜗牛,时刻背负我沉重而又甜蜜的家当,不离不弃。 + +到家后的第二天,为了一个急需的证明,我回了一次高中的学校。去之前我还是不情不愿的,走在熟悉的路上,心里总觉得别扭。没有怀旧的心情,更缺乏面对过去的勇气。在我看来那里存在着我的三年,三年的快乐,三年的伤害,我没法把它们放在一起去回忆。 + +当我转过路口,看到那再熟悉不过的学校大门时,原本喧闹的心却突然安静了。原来,这里还是接纳我的,那些过往还是那么根植于心,无法抹去。 + +我走进校门,林荫道上没有了往日的喧闹,校园安静得有些羞涩,只有一棵棵大树依旧碧绿,在风里散发着温暖而甜美的气息。眯起眼睛,仿佛可以看到许多身影向我走来。我的老师、我的同学、我的朋友,仿佛就站在路的尽头对我微笑,一如我那已逝去的美丽年华。 + + + +下午突然下起了雨,一瞬间天色阴沉。从小就喜欢下雨的我,却总是害怕打雷。走在大街上,我尽量放慢脚步去看街边神色匆忙的人群,试着作为一个异类行走在他们中间。已经几天没有见到朋友们了,偶尔想起,多是怀念,稍有不安。或许我已经习惯了没有人陪伴的日子?可是自己还是情不自禁地穿过层层雨雾向对街寻找,希望有熟悉的味道飘散过来,对我伸开双臂,给我一个拥抱。 + +是找谁呢?我不知道。因为爱我的人和我爱的人都有很多。 + +这些天,很多人已经回家了,还有些人正准备要走。在书上读到一句话:“你走了,我还守着一座空城。”说的好像我啊。当昔日的同学四散分开,我却留在了“原地”。 + +冬天来了,这是没有候鸟的季节。我的鸟儿都飞走了,离开了熟悉的城市,离开家,去遥远的地方寻找只属于自己的温暖。我只能用心去浇灌一株植物,布满祝福的叶子,给日夜守护我的家,给我相依相伴的四季花园,给童年,给我亲爱的伙伴,给某次曾经里的某个身影,给我世界尽头的保护人,给像我的你和像你的我…… + +说实话,对未来的某些事,我一点都看不清。别人眼里的世界和我心里的世界差别太大,我无法鉴别真伪。我更不知道凭我现在的能力能不能争取到我要的未来,能不能达到家人的期望……一切都太渺茫,形势严峻得如同泰山压顶,而前途太遥远,我却太脆弱。一整个秋天琐碎的心思,自信连连受挫,日子千疮百孔。也许我真的要在大学的环境里才能远离旁人给我的压力,重拾信心,开始别样的生活。 + +事实上,我也是一只盘旋在自我世界的候鸟。一边逃避寒冷,一边努力飞翔着给自己制造温暖。回家,也许是最好的选择。可以留下一份温暖,给自己,给候鸟般盘旋、起伏不定的未来。 + + diff --git a/src/content/posts/2012/2012-01-28-my-dear-kitty.mdx b/src/content/posts/2012/2012-01-28-my-dear-kitty.mdx new file mode 100644 index 0000000..c7a65c1 --- /dev/null +++ b/src/content/posts/2012/2012-01-28-my-dear-kitty.mdx @@ -0,0 +1,61 @@ +--- +title: 爷爷养过的猫 +slug: my-dear-kitty +date: 2012-01-28 15:41:26 +updated: 2020-09-06 11:38:13 +tags: + - 回忆 + - 爷爷 + - 伤感 +category: 文章 +cover: /images/2012/02/2012020222465000.jpg +summary: 日子一天天过去,时间一天天流淌,故事也一天天的上演。有些记忆早就被忘记,而有些却像伤疤版附着于灵魂上,怎么也消散不去…… +--- + + + +<MusicPlayer netease={2156585059} /> + +日子一天天过去,时间一天天流淌,故事也一天天上演。有些记忆早就被忘记,而有些却像伤疤般附着于灵魂上,怎么也消散不去…… + +那一年,3 月的午后降临了一场小雨,淅淅沥沥地湿润了整个午后。 + +那一年,伴随着突如其来的雨水,我降临到这个世界。 + +那一年,爷爷开始养猫…… + +爷爷是在我出生后开始养猫的。记得小时候和爷爷聊天时,爷爷说猫是从王二婶家抱过来的。那一天,爷爷就从镇上挎个菜篮子回来,猫就放在篮子里,用块布包着眼睛。爷爷说猫通人性,认得回去的路,蒙上了眼睛,就不知道跨过几座桥,走了多少路,就会把这里当家。从这一天家里多了一位新成员,叫“小花”。 + +在曾经的记忆里,爷爷养猫的方式和别人总有些不大一样,他不过多地破费,不额外地操心。别人都是给猫最好的窝,最精心的猫食。爷爷只是给予每天的剩菜剩饭,床底下的一张用旧帽子做的小窝,仅此而已。 + +最初的印象里,猫儿是十分怕生的。一有陌生人来到家时,就缩到床底角落里,闪烁着一双眼睛惊恐地看着外面,死也不肯出来。 + +但是,猫儿唯一不怕的人便是爷爷,它成了爷爷最忠实的伙伴,每天都陪在爷爷身旁,和爷爷一起生活。不像别的猫,成天就在外面玩,到了吃饭时候才会回来。 + +冬日里某个阳光明媚的下午,爷爷与我一起在楼下晒太阳,聊着过去的事情。渐渐地、渐渐地,爷爷睡着了,静静的。某刻专心于折纸的我抬起头,看见爷爷和他的小花。 + +爷爷靠在摇椅上,微闭着双眼,并拢着双腿,随着椅子的微微晃动细微地呼吸着。小花趴在他的膝盖上,也闭着眼睛。爷爷的双手就那样轻微地、温柔地搭在小花背上。爷爷以那样小心的姿势睡着了,他的身体一直保持一个弯曲的弓形,他的双腿并拢得很紧,以那样不舒服的姿势睡着。他刻意地收敛双手搭在猫身上的重量,一动不动…… + +爷爷对猫的关爱,常令我疑惑。比如爷爷不记得我正在上几年级,我多大了等。但是,爷爷却能记住很多关于小花的事情。小花生病了,爷爷的脸上写满了焦急。听奶奶说,爷爷那几天夜里常常爬起来,看看床底下的小花。小花病好了,爷爷脸上也显得精神多了。 + + + +猫就像人一样,也会学坏。没多久,当我上小学时,小花便开始三天两头地在外面跑,直到吃饭时间和夜里睡觉时才会回家。春天夜里,处于发情期的小花便彻夜不归,一直在外面咿呀咿呀地叫着,惊醒了睡不踏实的爷爷,震碎了老人脆弱的梦境。爷爷的脸上开始挂上愁绪,有时我在爷爷家门口玩的时候,常常看到爷爷推开纱门向外张望,喊着猫猫的名字。那种期盼的眼神,让我看着十分难过、心痛。 + +单位拆迁,换了新房后,猫猫再也看不见了身影,它跑了,爷爷找了一天也没找到。 + +从那以后爷爷的脸上很少能瞧见笑容,常常看见爷爷跑到老屋门口,将猫猫最喜欢的鱼放在门口,可是结果往往都是原封不动。 + +又一次看到爷爷在摇椅上晒太阳,膝盖上已经没有了那只小猫咪,可是他的姿势依旧是那样弓着背,并着双膝,一双手微微地搭在膝盖上,似乎猫还在那里。 + +在阳光的照射下,爷爷的背影是那样的孤单、寂寞。 + +在那一刹那,我似乎还看到了那只小猫,可是爷爷的膝盖上依旧空空如也。 + +我一直在身后望着爷爷的背影,希望能同他说话,像猫一样也趴在爷爷的膝盖上同爷爷一起在和煦的阳光下暖暖地睡下,一同呼吸着相同的命运…… + +高考前一个月,爷爷走了,奶奶说,死前爷爷的嘴里还是记挂着小猫,盼望着小猫的回来。 + +摇椅依旧在那里,可是坐在上面的人却早已不在。我望着空荡荡的房间,却再也找不回熟悉的气息,那种熟悉的温柔,仅存于记忆之中…… + + diff --git a/src/content/posts/2012/2012-02-03-blue-turkey.mdx b/src/content/posts/2012/2012-02-03-blue-turkey.mdx new file mode 100644 index 0000000..7509061 --- /dev/null +++ b/src/content/posts/2012/2012-02-03-blue-turkey.mdx @@ -0,0 +1,48 @@ +--- +title: 蓝色土耳其 +slug: blue-turkey +date: 2012-02-03 15:43:29 +updated: 2020-09-06 11:38:47 +tags: + - 回忆 + - 爱情 + - 蓝色土耳其 +category: 文章 +summary: 还贪恋着,你的风情,诱惑着,你的神秘。埋葬了,我的爱情,忧郁蓝色土耳其。紧跟随着,我的稚气;逃避着,我的宿命。徘徊在,你的淡淡哀愁灰色眼眸里。 +cover: /images/2012/03/2012031120464600.jpg +--- + + +<MusicPlayer netease={1389742858} /> + +还贪恋着,你的风情,诱惑着,你的神秘。埋葬了,我的爱情,忧郁蓝色土耳其。紧跟随着,我的稚气;逃避着,我的宿命。徘徊在,你的淡淡哀愁灰色眼眸里——《蓝色土耳其》 + +耳机里面依旧放着《蓝色土耳其》的旋律,在厦门这个难得舒适的午后,我一个人静坐在桌前写字。突然回想起多年前的那个下午,一样的时间,不一样的地点,似乎曾听过相同的旋律…… + +高中伊始,凤凰花开的季节,树梢上弥漫着片片“火焰”,煞是好看。红色的花瓣,瞬间的开放,弥漫了整个记忆。我情不自禁地想起昔日校园里花坛的三角梅,想必那时也是一片火红了。也就是在这红色的喜庆花海中,我如愿以偿地走进了梦想的重点高中。 + +可是,理想与现实的距离,往往就像那朵盛开在彼岸的花朵,怎么也抓不住。 + +开学第一天的班会上,班主任便无情地敲碎了我对于美好高中未来的幻想。老班说:“你们进的是重点高中的重点班级,并不是一件值得高兴的事情,你们的对手是整个福建省。所以,班级的人员安排将实行流动制,每次月考前 50 名便是我们的成员,成绩差的将被无情地踢出我们班。”赤裸裸的威胁,冷酷的安排。只记得当老班说下这个决定后,整个教室的温度瞬间便低至冰点,原本才进入高中的喜悦,刹那间荡然无存。 + +不知什么时候开始,大家开始忙碌起来,每天的生活就像三点一线:教室——食堂——家里的书桌。睡觉的时间也越来越往后延,10 点 → 11 点 → 1 点。同学之间的交流也越来越少,几乎没有。有时抬起头看向四周,映入眼帘的是一排排的后脑勺。可是,偏偏就有这样一个另类! + +在我的印象里,同桌小 C 一直是一个爱笑爱闹的小女孩子,也是班主任眼中的差生,令任课老师头疼不已的坏孩子。似乎班主任的威胁对小 C 无效。课堂上常常看到她在那里偷偷地用手遮挡着耳机听歌;下课时常听到她在那里小声地哼唱;晚自习时,相对于我们课桌上摆放的高高的参考书,她的桌上放的是一本本的小说,看的昏天地暗。有时抬起头,竟会发现她在突然地掉眼泪,一问,才知道“XXX 死了”。那么 XXX 是谁呢?再一问,才哭笑不得地发现原来是小说里面的女主角! + + + +那么,是什么时候开始喜欢上她呢?不知什么时候起,身旁的角落里有了她的倩影。那段日子里,是无忧无虑的,简单而又幸福的。每天早上一起边啃着面包边赶去上学,课下一起结伴去食堂。晚自习后还不愿意回家,在校园花坛的榕树下,尽情地谈天,聊理想,谈属于那个年纪的秘密。周末,我们一起看小说,看得昏天地暗,编织着童话般的梦的衣裳。那时的我们,似乎永远也长不大,快乐,豪放,活得无所畏惧,从来没有恐慌抑或不安,生活里满满的都是明媚的阳光。 + +但是,快乐的时光总是过得很快,浪漫的花季一旦过去,那娇柔的花瓣便会如雪般在风雨中轻轻飘落。那一天,月考来临了,小 C 还是没能进入年级前 50 名,被踢出我们尖子班。随后她的家长决定让她转学,回到莆田读书…… + +走之前,我们又来到昔日的榕树下,地上、石凳上,铺上了一层散发清香的花毯。美得让人惊叹,让人感伤。小 C 轻轻地说:“以后不知道还能不能一起来此聊天。”两人静静地坐着,一阵无言,只有她还在那里小声地唱着这首《蓝色土耳其》:“还贪恋着,你的风情,诱惑着,你的神秘。埋葬了,我的爱情,忧郁蓝色土耳其。紧跟随着,我的稚气;逃避着,我的宿命。徘徊在,你的淡淡哀愁灰色眼眸里……” + +她踏上了开往北方的长途汽车,离开了……走之前,将自己最喜欢的小妮子的《恶魔之吻》送给我。从那以后,我再也没见过她。两人之间的来信也越来越少,终究止于高二的那个弥散着离愁的秋季。 + +夜里又一次看了一遍《秒速 5 厘米》,看着贵树和明理的童贞爱情,竟不知最后看得热泪盈眶。 + +回想起与小 C 分别时自己写在日记本里的一首小诗:下了一夜的雨、下了一夜的情书、那段年少的故事、是一出难忘的戏、想了一夜的你、想了一夜的往昔、我的轻狂你的美、你的离别我的泪。 + +前些日子又一次回到中学,绿树依旧,石凳依旧,花儿依旧,一切还在老地方。只是,小 C 你是否还会想起——我们的那段短暂的中学时代,那段青涩的美好年华? + + diff --git a/src/content/posts/2012/2012-02-17-image-times.mdx b/src/content/posts/2012/2012-02-17-image-times.mdx new file mode 100644 index 0000000..cf726dc --- /dev/null +++ b/src/content/posts/2012/2012-02-17-image-times.mdx @@ -0,0 +1,39 @@ +--- +title: 图片时光 +slug: image-times +date: 2012-02-16 16:31:28 +updated: 2020-09-06 11:40:37 +tags: + - 时间 + - 记忆 + - 图片时光 +category: 文章 +summary: 这些天在看书时偶然读到一句话:林花谢了春红,太匆匆。恍然有轻缓踏歌之声自时光的深处漾起,在读到此句的那一刹那,诗句中交融的时间之美、空间之美犹若一滴年久醇厚的烟墨点入碧清的水中,丝丝缕缕地舒卷散尽。 +cover: /images/2012/05/2012050221032900.jpg +--- + + + +<MusicPlayer netease={730690} /> + +这些天在看书时偶然读到一句话:林花谢了春红,太匆匆。 + +恍然有轻缓踏歌之声自时光的深处漾起,在读到此句的那一刹那,诗句中交融的时间之美、空间之美犹若一滴年久醇厚的烟墨点入碧清的水中,丝丝缕缕地舒卷散尽。 + +美,在于观察,在于记录。而人生如花,花如梦,梦里开,梦里落。一段如诗般的青春岁月,我们曾经走过、哭过、笑过、也爱过。时光安然,沉醉于春色无边,却无法将那些曾经感动过我们的丝丝瞬间一笔一划地写下。只能埋藏于心,成为岁月里的一块碎片,慢慢磨散。 + +常常心惊于最美的光景总是不过多久便落幕收场。人生也一样,青春从不是用来东张西望的时候。好比观赏春日的林花,不知觉中已然错过了太多的精彩,直到花谢了,才开始惋惜。 + +时间的洗刷,有时便是沧海桑田般的变迁。“汩余若将不及今,恐年岁不吾与”。每次翻看自己的手抄本,读到这一句话的时候,突然间就感到一阵茫然……身边的人聚聚散散,熟悉的面孔颠覆在世间的长河里。留下我独自一个人,在荆棘满布的小路上蹒跚而行。 + +往事随风散…… + + + +张爱玲看老照片时曾说道:“照片这东西不过是生命的碎壳,纷纷的岁月已过去,瓜子仁一粒粒咽了下去,滋味各人自己知道,留给大家看的惟有那满地狼藉的黑白的瓜子壳。”光影闪动,凝刻下生命中某一刹那间的年华,却被装裱于厚重的相册中,束之高阁。某刻,再想起,拂去表面的灰尘,拿起泛黄的老照片时,也仅存留回忆…… + +时光就是这样的紧凑、匮乏。每日不过是 24 小时的堆积,一年不过是 365 个单调的重复,而生命里面又有多少个一年呢? + +图片,是已逝时光的影子。对于过去,我们无能为力,但是却不该忽视那些点滴的闪光和感动。图片时光,以图片的方式记录那些生命中的美丽。在时间和空间的舞袖里,完成对那一刻动与静的定格。在多年后的今天,在早春稀疏的碎花之间,我仍能用心感受到当年被凝住的美丽。 + + diff --git a/src/content/posts/2012/2012-02-23-spring-words.mdx b/src/content/posts/2012/2012-02-23-spring-words.mdx new file mode 100644 index 0000000..af948c2 --- /dev/null +++ b/src/content/posts/2012/2012-02-23-spring-words.mdx @@ -0,0 +1,37 @@ +--- +title: 春语 +slug: spring-words +date: 2012-02-23 04:14:05 +updated: 2020-09-06 11:42:04 +tags: + - 杂思 + - 春天 + - 目标 +category: 文章 +summary: 喜欢春天,因为喜欢鸟语花开,欣欣向荣。阳光更暖了,风更暖了,心情也更暖了。期待中的春天就这样悄然而至,原心灵的春天也随之萌发。 +cover: /images/2012/05/2012050521120700.jpg +--- + + + +<MusicPlayer netease={1485319473} /> + +喜欢春天,因为喜欢鸟语花开,欣欣向荣。 + +阳光更暖了,风更暖了,心情也更暖了。期待中的春天就这样悄然而至,原本心灵的春天也随之萌发。 + +二月的早上宁静安详,那份宁静和清新让人精神雀跃,一改往日冬天赖床的习惯,离开温暖的被窝迎接清凉亮丽的朝阳。早上的太阳升起在东南偏北,到了三月校园后的山坡上已是绿意融融。我站在阳台上,寻觅着山上静静的松柏任何微动的哼唧,猜想着那份少有而可爱的寂静。 + +宿舍楼下的花坛里不经意间已经冒出一团团新绿,它们也按捺不住寂寞,想看一看外面的世界。这不正是我们吗?对明天充满渴望,用尽一切努力让世界看到自己!春来了,心灵就更加活跃了,对未来的追求就更加强烈了。 + +乌云,带来一片片小雨,它们是如此的可爱,点点滴滴、缠缠绵绵。有丝丝的清冷,却会让人更加清醒。沉寂了一冬,迎着这样丝丝柔柔的清凉雨,是不是该伸展一下,抖擞起精神,活力十足地去迎接这样一个春天?春来了,心灵就更加清爽了,不会再迷迷糊糊,目标就更加明确了。 + +温柔的风轻轻拂过面颊。呀!如此的令人陶醉。我最喜欢让这微风这样轻轻地吹着,洒脱、自在,一切的烦恼都随之而去,它是春带来的最好的礼物。风儿吹来了温暖的阳光,点点绿的小草,还有清爽的小雨。追着春天的风,是不是该放飞心灵,洒脱地面对人生?春来了,心灵更加洒脱了,我愿意面对所有的一切。 + +春来了,不晓得何时:心灵萌发了,就在此刻。一年之计在于春,此时不奋何时奋。希望就在春中,就在手中,就在心灵中,不要忘记! + +春天到了,女生们脱去厚厚的臃肿的面包服,身材展现。 + +春天到了,带来了我们想要的一切,你准备好了吗? + + diff --git a/src/content/posts/2012/2012-02-24-intimate-in-mind.mdx b/src/content/posts/2012/2012-02-24-intimate-in-mind.mdx new file mode 100644 index 0000000..323bb00 --- /dev/null +++ b/src/content/posts/2012/2012-02-24-intimate-in-mind.mdx @@ -0,0 +1,30 @@ +--- +title: 相视一笑,莫逆于心 +slug: intimate-in-mind +date: 2012-02-24 14:20:13 +updated: 2020-09-06 11:42:55 +tags: + - 杂思 + - 情感 +category: 杂思 +summary: 说话有时候耐人寻味。例如,如果我对一个远方一个朋友说:“我很想你啊”,她会体会到我当下的心情吗?我想很难。 +cover: /images/2012/02/2012020521241800.jpg +--- + + + +<MusicPlayer netease={1430268793} /> + +说话有时候耐人寻味。 + +例如,如果我对一个远方的朋友说:“我很想你啊”,她会体会到我当下的心情吗?我想很难。或许,“想念”在由我那忧戚感伤的心情转变为硬生生的文字(或者话语)时就不再温润,就褪色了,或者遇到了稀释。又或许,此刻我的朋友有她自己的心情,有她自己的事,譬如她正在果园里摘桃子,说不定就会兴冲冲地跟我说:“那么待会我给你送些桃子吃呵”。 + +可是并不是所有的话语都像“我很想你”之类的脉脉温情,有时候我们说话是为了寻求帮助,发泄苦闷,分享喜悦……可惜,结局并不如你所愿,让人遗憾。你的谈话对象可能正戴着帽子听音乐,或者看她喜欢的电影。甚至有时候,语言不是桥梁,而是墙,造成人与人之间的误会、距离乃至隔阂。 + +在一定意义上,我赞成这样一句话:“信念永远不能达到目的地”。 + +于是,我坚持认为王子猷的做法堪称绝对意义上的经典。据说王子猷住在会稽山北面,有一次夜里下了一场大雪。他一觉醒来,打开卧室门,命仆人斟上酒,饮酒赏雪。四下里望去,一片皎然。于是起身,漫步徘徊,吟诵着左思的《招隐诗》。他忽然间想到了戴逵,当时戴逵住在剡县,于是王子猷马上连夜乘小舟前往,经过一夜才到,到了戴逵家门前却又转身返回。有人问他为什么这样呢,王子猷就说:“吾本乘兴而行,兴尽而归,何必见戴?”我想,这不仅仅是魏晋风度。 + +又想起一句话,“相视一笑,莫逆于心”。如此境界,是在可遇不可求。无论朋友,抑或爱人,若能达到此种境界,也算是三生有幸。多多包容之外,还是随缘好了。 + + diff --git a/src/content/posts/2012/2012-02-26-take-the-train.mdx b/src/content/posts/2012/2012-02-26-take-the-train.mdx new file mode 100644 index 0000000..adfa8d8 --- /dev/null +++ b/src/content/posts/2012/2012-02-26-take-the-train.mdx @@ -0,0 +1,50 @@ +--- +title: 爱我就请去搭火车 +slug: take-the-train +date: 2012-02-25 20:00:22 +updated: 2020-09-06 11:43:41 +tags: + - 火车 + - 情感 + - 爱情 + - 金粉世家 + - 读者 +category: 文章 +summary: 也许很少有人还记得1998年由法国电影导演帕特里斯 · 夏洛尔拍摄的电影《爱我就请去搭火车》。这部充溢着罗曼蒂克气息的电影故事取材自导演和他身边朋友的经历。 +cover: /images/2012/02/2012020821400300.jpg +--- + + +<MusicPlayer netease={408328757} /> + +也许很少有人还记得 1998 年由法国电影导演帕特里斯 · 夏洛尔拍摄的电影《爱我就请去搭火车》。这部充满罗曼蒂克气息的电影故事取材自导演和他身边朋友的经历。片名就是他的朋友的原话——当时住在巴黎的他,想死后埋在小镇利马汤的墓地里。 + +但是,利马汤和巴黎之间有 4 个半小时的火车车程。如果那样的话,亲朋好友都要长途跋涉去参加他的葬礼。对于性格散漫、慵懒、喜欢享受的巴黎人来说,无疑是一件不愉快的事。在别人质疑他的观点的时候,那位朋友说:“爱我就请搭火车。” + +夜里我专门下载观看了这部电影,不由得沉浸在了焦黄色胶片背景下映射的复杂交织,那些去吊唁的亲朋好友之间的浅浅回忆。但,最喜欢的还是那个给观众以无限遐想的浪漫片名。 + +也许只有法国人的浪漫,才能有这样的想法——一种看似荒谬,实际却对于爱与生命、死亡之间的深刻思考。爱不怕分离,如果你真的挂念我,真的爱我,又怎会在意这区区距离呢?纵使身处天涯海角,纵使海枯石烂,你依旧会将我去追寻。哪怕这路太过于遥远,太过于艰险,太过于崎岖,你依旧会来找寻我。一切的一切只因为彼此的相爱,如果有爱,距离又算得上什么呢? + +《金粉世家》里面的三少爷,因为爱慕她的容貌、清纯,义无反顾地爱上了她。纵使两个人之间的地位、身份相差甚远,他还是毫不犹豫地跨过种种鸿沟。这算得上是爱吗?非也!当岁月将事物的表面洗刷干净,就像那世家表面的金粉必将消散殆尽。故事的结局出人意料却又在情理之中。两个人最终踏上开往南北的两列列车,从此南北分离…… + +于是从另一个角度来说,距离虽然产生了美,但也是爱情的杀手,许多看似深刻的爱情最后抵挡不了距离的阻隔。许多时候,人们更多地选择最近的爱。想想你身边的那些人,他们有多么地爱你?当你辞别人世的时候,他们能否抛下一切事务,甘愿地搭乘 4 个小时的火车,去参加你的葬礼——见你生命里的最后一面,即使知道你已经无法回报。 + +不由得想起了在里面提到过的另一个故事:在相隔了漫长的战火与冷山之间的两个年轻的恋人英曼与艾达,彼此做着自己的努力,只为再次相见。距离没有打断他们的相思之情,那座兀立于天地间的冷山成了他们之间唯一的联系,是他们回忆与向往的地方。也许,这便是真爱的魅力。 + +不由得想起了在[《最是一番长相思》](/posts/sauvignon-blanc/)里面提到过的另一个故事:在相隔了漫长的战火与冷山之间的两个年轻恋人英曼与艾达,彼此做着自己的努力,只为再次相见。距离没有打断他们的相思之情,那座兀立于天地间的冷山成了他们之间唯一的联系,是他们回忆与向往的地方。也许,这便是真爱的魅力。 + +爱我就请去搭火车,只因为真爱。试曾想真正爱上另一个人时便意味着心的交织与牵挂。时不时地要去惦记那个她(他):现在在做啥、晚饭吃什么、吃得好吗、什么时候回家……这爱一旦牵系,便从此无法割舍,无法脱离。纵使你负我千百回,纵使你我天人相隔,爱人之间的惦念依旧不会绝迹。这爱,今生今世,一直相随。 + +爱我就请去搭火车。 + +——原写于 2011 年 9 月 26 号,2012 年 2 月 26 号重写 + + + +> ## 题外话:关于本文插曲 +> +> 一直在追求一种与文章相协调的插曲,简单、舒缓、淡雅,可以在某个安静的午后,闲下来的时候,静静地听。在看去年还是前年的动漫《玉响》的时候,便被它的结尾曲所深深地迷恋。歌曲简简单单地讲述了主人公在夏天,坐着火车去自己所爱人的家乡小镇的故事。 +> +> 重写本文的时候突然想起里面的歌词,不由得觉得是那么的协调。电影《爱我就请去搭火车》同样记录了在艺术家兼老师让·巴蒂斯特逝世后,爱人、朋友、泛交、还有亲戚去坐火车吊唁的相似经历。 +> +> 于是我在写下此文时,耳机里面一遍又一遍地播放着此曲。幻想未来的某天,又会是谁,也能让我坐着慢悠悠的火车,去遥远的地方见面呢?无限期待…… diff --git a/src/content/posts/2012/2012-02-27-old-house.mdx b/src/content/posts/2012/2012-02-27-old-house.mdx new file mode 100644 index 0000000..b83c4f1 --- /dev/null +++ b/src/content/posts/2012/2012-02-27-old-house.mdx @@ -0,0 +1,29 @@ +--- +title: 随想——老屋 +slug: old-house +date: 2012-02-27 10:25:56 +updated: 2020-09-06 11:45:37 +tags: + - 灵魂 + - 过去 + - 老屋 +category: 文章 +summary: 在搬进新家前,我曾在一条老街上住了四年,那是一条真正的老街,几乎所有的房子都始建于20年代之前。有的房子还有人在住,有的屋顶已经坍塌,外面的墙壁上爬满了干枯的藤蔓。 +cover: /images/2012/02/2012022022154700.jpg +--- + + + +<MusicPlayer netease={37782782} /> + +在搬进新家前,我曾在一条老街上住了四年,那是一条真正的老街,几乎所有的房子都始建于20年代之前。有的房子还有人在住,有的屋顶已经坍塌,外面的墙壁上爬满了干枯的藤蔓。每到傍晚时分,同藤蔓一样干巴巴的老人们坐在门口,讲述着祖辈们口口相传的古老故事。夕阳的照射着苍老的容颜,映射出眼底的沧桑,并且伴着一份平和,这些都是岁月所给予的财富。 + +可我却是如此的年轻,对于老街、老屋、老人来说,我是一个局外人,与这破败的气息格格不入。但是我却喜欢这里的一切,尤其是老屋。每到星期天清晨,当人们还沉浸在睡梦中的时候,我就已经起来,在街里游荡。这里的每一间老屋都能强烈地吸引我,屋顶的青砖绿瓦,有的经受着时间的考验,依旧完整;有的断成两片、三片,屋檐前的一排青瓦是最特别的,每一片上面都缀有花纹,各不相同,十分精致。墙角不知什么时候已经爬满了青苔,点点的碎绿,是在记述那些过去吗? + +我就像一个幽灵一样在老街上飘荡,身处这样一个弥散着古老气息的老街上,我忍不住去漫无边际地遐想:在某个老屋里,曾经,也许有一位母亲在昏暗的灯光下为远在他乡的游子做新衣;某一天,一位美丽的新娘穿着花嫁衣,坐着花轿,进了其中一间老屋;也许哪间老屋还发生过宝黛般的爱情——到底发生过什么事呢?我不知道,只有老屋依旧兀立在那里,无声地讲述着那些曾经。 + +如果这个世间有幽灵,我真的相信这些老屋里住着幽灵,与我们活着的人共存。 + +——つづく + + diff --git a/src/content/posts/2012/2012-03-17-strangeness.mdx b/src/content/posts/2012/2012-03-17-strangeness.mdx new file mode 100644 index 0000000..160bb3c --- /dev/null +++ b/src/content/posts/2012/2012-03-17-strangeness.mdx @@ -0,0 +1,40 @@ +--- +title: 随想——陌生 +slug: strangeness +date: 2012-03-16 18:07:52 +updated: 2020-09-06 11:47:35 +tags: + - 回忆 + - 陌生 +category: 文章 +summary: 习惯了也是一种淡然,便习惯了一种生活,静静地思考,细细地品味,那人、那景、那事……缓缓流入心底,给自己一份淡然,心如止水。 +cover: /images/2012/02/2012021422120000.jpg +--- + + + +<MusicPlayer netease={640866} /> + +> 习惯了也是一种淡然,便习惯了一种生活,静静地思考,细细地品味,那人、那景、那事……缓缓流入心底,给自己一份淡然,心如止水。 +> +> ——题记 + +经过了最初的好奇,中期的激动后,对于博客,似乎有一种小小的厌倦,不再习惯天天打开博客留言、回复。文章也由一天一篇逐渐变成两天一篇,最后干脆多日一篇,越来越少。而心中总有很多未说出来的话语,而想要写下来时,却颓然发现,熟悉的博客后台是那样的陌生…… + +闲来无事去听以前的英语课,拿出熟悉的课本,听着熟悉的课文却有一种空虚的陌生。周遭的一切似曾相识,却又有一种浓浓的距离感。陌生的面孔,陌生的教室,陌生的嗓音,无一不在昭示着一个赤果果的现实——你不属于这个环境。 + +于是,种种陌生的场景就在心底长久地堆积、埋葬,一次又一次地迷茫了我的双眼。就像是身处命运的十字路口,一次又一次遇见岔路口,却不知如何选择…… + +前天和昔日的高中同学视频聊天,同学笑着说:“你还没变。”可是对面的那个昔日熟悉的容颜已经消散,呈现在我眼前的却是一张棱角鲜明的脸,不再圆滑,更加成熟。似乎一瞬间周身的所有人都长大了,都变得理想蓬勃。而我,依旧停留在最初的起点,看着陌生的路口,驻足徘徊。 + +而人生,其实无力的连一句脆弱都不敢提起,一朵花落,一片叶黄,已然是茫然的陌生,匆匆的路人。 + +日子,其实经不起推敲,风过就是一天,雨过就是一季。恍然间,就已经长大,迷茫地看着身后。 + +于是最后,只剩一声叹息,一丝回忆。 + +但只怕是这样的机会也许都不再有,我们匆匆走过,各奔前程。过去,已经走远…… + +——つづく + + diff --git a/src/content/posts/2012/2012-03-25-walk-on-playground.mdx b/src/content/posts/2012/2012-03-25-walk-on-playground.mdx new file mode 100644 index 0000000..fa597cd --- /dev/null +++ b/src/content/posts/2012/2012-03-25-walk-on-playground.mdx @@ -0,0 +1,32 @@ +--- +title: 随想——操场时光 +slug: walk-on-playground +date: 2012-03-24 16:38:33 +updated: 2020-09-06 11:47:27 +tags: + - 随想 + - 时光 +category: 文章 +summary: 高中住校时,我喜欢在被黑暗笼罩的时候走进操场,此时这里只有三三两两的人,不怕拥挤,不怕吵闹,是个放空自己的好地方。 +cover: /images/2012/02/2012021822255600.jpg +--- + + + +<MusicPlayer netease={1387913820} /> + +高中住校时,我喜欢在被黑暗笼罩的时候走进操场。此时这里只有三三两两的人,不怕拥挤,不怕吵闹,是个放空自己的好地方。沿着被黑夜吞噬了鲜红色彩的跑道慢慢地走,可以不用担心是否会吵到别人而肆无顾忌地调高手机音量,让歌声和我一起在这个静谧的夜晚散步,悠扬而沉醉的旋律传递到远方,久久不散。 + +还记得这个时候,应该是跃动的夏季,身旁不时有夜跑的同学经过,他们说笑着、追逐着从我身边经过。超过我,最后消失在夜色弥漫的幕布之后,只剩下迷蒙的身影,舞动着、跃动着。而我只是任双脚习惯性地前后交替行进。每个人都有每个人的节奏,我无心去追赶。 + +空旷的操场足以融化我的疲惫,积攒了一整天的压力可以随性卸载。晚风轻轻吹拂,丝丝缕缕的发梢也一起飞扬。随之而去的,还有许多愁绪,别样的轻松与舒适围绕着我。这奇妙的感觉就像窒息了很久后忽然呼吸到了新鲜空气一样让人身心舒坦,让人贪念。想起冰心说过:“最乐的时间,就是和最知心的朋友同在最美的环境之中,却是彼此静默着没有一句话说。”虽然此刻没有友人陪伴,这依旧是我最快乐的时间。 + +从操场往外看,整座城市沐浴在灯火的世界里。那些闪烁着灯光的窗口里,每一片延伸出来的光亮都是一个温馨的标识,指引着还在路途上的人儿回家。于是乎,每一盏灯就有了温暖的气息,就像是此刻定是在门口守望者自己归来的父母,那种简单的温情,总是莫名的让人忍不住落泪。而不管是明亮的还是昏黄的,这样温馨的灯火,总让人久久不忍移开视线。 + +这美丽的操场时光,就像心中永不熄灭的灯火一样明亮在我的记忆深处。多少年后,当我已经上了大学时还记得当年的情境。毕竟,那是在烦躁苦闷的高中生活中,唯一可以给予我不竭安宁与平静之处。 + +那里,是我心中的伊甸园。 + +——つづく + + diff --git a/src/content/posts/2012/2012-03-26-at-home.mdx b/src/content/posts/2012/2012-03-26-at-home.mdx new file mode 100644 index 0000000..0da2dd4 --- /dev/null +++ b/src/content/posts/2012/2012-03-26-at-home.mdx @@ -0,0 +1,28 @@ +--- +title: 随想——在家 +slug: at-home +date: 2012-03-26 01:00:04 +updated: 2020-09-06 11:47:08 +tags: + - 随想 + - 情境 +category: 文章 +summary: 在家时,即使什么也不做也是快乐的。每天劳累后回到家,晚上泡一杯茉莉,淡淡的茶香溢满整个空间,使人微醉。 +cover: /images/2012/03/2012032502314500.jpg +--- + + + +<MusicPlayer netease={32803232} /> + +在家时,即使什么也不做也是快乐的。 + +每天劳累后回到家,晚上泡一杯茉莉,淡淡的茶香溢满整个空间,使人微醉。从小喜爱喝茶,有时候为了能呷一口极致的味道,夏日里不惜走上二十几公里,待满头大汗,嘴唇干裂,回来烧一壶开水,捏上一撮香茶,滚烫的水裹着茶叶像浪一样在杯中翻滚,再静静地沉淀下去,这时的我也沉在已经干瘪的沙发里,共舞时光。 + +斜靠在床头,翻看以前的书,文字好似都变了一种调。易安人说,“旧时天气旧时衣,只有情怀不似旧家时”,这就是流年如斯吧。老乡远隔千年,如今却恍如对面,一场忧伤的邂逅。人是脱胎不了世道的,她少有快乐,后家破国亡,诗调总是太悲伤苍凉,要么饮酒,要么睡梦,只没心思弄妆。少有“和羞走,倚门回首,却把青梅嗅”的羞涩;也有新妇“云鬓斜簪,徒要教郎比并看”的快乐。只是在这样的日子太短暂,后来,命运就成笔下的“感月吟风多少事,如今老去无成。谁怜憔悴更凋零”了,什么心情呢?“试灯无意思,踏雪没心情”。 + +书看倦了,没有一点睡意,放平枕头,关上灯,拉开窗帘,四仰八叉地躺在床上,抬眼向窗外望去,是四方四正的星空,白墙上,是它涂抹成淡蓝色的菱形。世间我看两物总没有厌烦,一是碧蓝色的海,另一个就是这夜晚的星空。有时竟能几个小时地就这么看着,直到东方的天由暗黑变成深蓝,鱼肚白变成处子红,远处传来叽叽喳喳的叫声,清晨了。 + +“看天亮是一件寂寞的事情”,这是顾城的天空;海子在一首诗中写,“天空一无所有,为何给我安慰”。我想,夜晚的天空,守护多情的浪子。 + + diff --git a/src/content/posts/2012/2012-04-02-the-wounds-of-the-tree.mdx b/src/content/posts/2012/2012-04-02-the-wounds-of-the-tree.mdx new file mode 100644 index 0000000..3928516 --- /dev/null +++ b/src/content/posts/2012/2012-04-02-the-wounds-of-the-tree.mdx @@ -0,0 +1,28 @@ +--- +title: 随想——树的伤口 +slug: the-wounds-of-the-tree +date: 2012-04-01 16:31:50 +updated: 2020-09-06 11:48:18 +tags: + - 随想 + - 伤口 +category: 杂思 +summary: 这世间,只有我一棵有着伤口的树吗?应该不是。也许我们每一个人都是一棵有着伤口的树,都在痛,只不过有轻有重。 +cover: /images/2012/04/2012040101152600.jpg +--- + + + +<MusicPlayer netease={1489061392} /> + +走在这条通向图书馆的靠山小路上,我无意于过往的事物,目光在周围的一棵棵树上游离。猛然间,我的目光停留在路边一棵树上。乍一看,它高大茂盛,但真正抓住我注意力的不是这些,而是树的主干。从中间往下都没有分枝,有的只是“伤口”。 + +树枝被砍下来后愈合留下的痕迹,有些像人的眼睛,注视着人的生活。而不单单只是这棵树,公路两旁,每一棵树上都有一两只“眼睛”,好像诉说着枝干被砍下来时的伤痛和不得不承受命运安排的无奈。它们是无奈的,为了符合人类的审美观,为了保证车辆不被伸长的树枝“骚扰”,身体的一部分被强制夺走。 + +树的伤口,静静地诉说着曾经的无奈与现在的挣扎,那种沉默的诉说是如此悲伤。对于那些无奈的树,我心中有些许同情,但另一种感觉是同命相怜!我是一棵有着伤口的树,我外形完整,但伤口愈合留下的痕迹却永远留在了心上。社会不会轻易接纳一个人,尤其是一个没有伤口的人。我曾经生活在我的世界里,不需要跟社会打交道,只是与天真无邪、心灵纯净的同龄人玩耍,那时我是个孩子,是一棵没有伤口的树,那时是社会与我都不需要对方的时候。在人生的道路上,我留下的脚印越来越大。当有一天,我发现我开始需要社会的时候,我不得不砍掉我的“枝”——单纯美好的幻想,对陌生人的百分百信任。有人说那是从幼稚走向成熟的必经之路,而我却觉得好痛好痛。那些,对我来说,都是舍不得放弃的“异珍”,割舍了,我就会痛。所以我蜷缩在一个灰暗的小角落里,不停地抚慰伤口,希望它们慢慢愈合,而每一次的抚慰只会让我更痛,让我迷失感更强。 + +这世间,只有我一棵有着伤口的树吗?应该不是。也许我们每一个人都是一棵有着伤口的树,都在痛,只不过有轻有重。但是,我们真的是树吗?只能被动地任人掌控吗?不是,不是!我们有思想,可以去选择要不要那些“伤口”。以前的我做了让我痛到现在的选择,而今的我决定选择保留我心中最宝贵的品质,不再厌弃! + +——おわり + + diff --git a/src/content/posts/2012/2012-04-07-the-poem-of-nalansingde.mdx b/src/content/posts/2012/2012-04-07-the-poem-of-nalansingde.mdx new file mode 100644 index 0000000..5e06ecb --- /dev/null +++ b/src/content/posts/2012/2012-04-07-the-poem-of-nalansingde.mdx @@ -0,0 +1,38 @@ +--- +title: 人间何处问多情? +slug: the-poem-of-nalansingde +date: 2012-04-06 18:52:15 +updated: 2020-09-06 11:49:16 +tags: + - 纳兰性德 + - 情思 +category: 杂思 +summary: 这般流水一样清澈的字句,定然属于如同秋天一般忧郁的词人。轻轻拂开时光的厚重褶皱,一个名字展现在世人面前:纳兰容若。 +cover: /images/2012/04/2012040801480400.jpg +--- + + + +<MusicPlayer netease={1407500990} /> + +> “漫惹炉烟双袖紫,空将酒晕一衫青,人间何处问多情。” +> +> ——题记 + +这般流水一样清澈的字句,定然属于如同秋天一般忧郁的词人。轻轻拂开时光的厚重褶皱,一个名字展现在世人面前:纳兰容若。 + +纳兰名性德,而我却更喜欢叫他容若。一个精致的才子理应有一个精致的名字,而这个名字本身就是一首婉约的词曲,平平仄仄平地念出来,伴着曲调唱起来,唇齿间便盘旋着漠然寂寥之意…… + +或许是红颜薄命,才子命苦。纳兰的父亲权倾朝野,贪婪成性,而纳兰却厌倦仕宦生活,早早地看透了那些丑陋的尔虞我诈。清朝的夜晚“太冷了”,也过于漫长,纳兰也只好躲进了词里。“我是人间惆怅客,知君何事泪纵横,断肠声里忆平生。” + + + +好在纳兰还有一位妻子卢氏,卢氏知书达理,性情温婉,和纳兰朝夕相伴,恩爱有加。而良辰美景总难长久,此恨绵绵无绝期。不完美的人生成了纳兰后半辈子的主旋律。短短数年的举案齐眉,相敬如宾的生活后,卢氏竟先于纳兰而卒。 + +于是,在悲伤酷梦无处可发之后,纳兰研墨执笔,写下大量悼亡词。“梦好难留,诗残莫续,赢得更深哭一场。”碧落茫茫,人自然是无处可觅;只叹是天上人间,前缘尽去。衣香鬓影的痕迹中,举杯而下的是悲辛交集的眼泪。也许上苍总是公平的,给予你一身才气,却要夺走你一生的挚爱,这公平,如此残忍!人生如寄,浮浮沉沉,几多断肠,谁能相握?唯能掬一捧清泪,自问:此情何时休,此恨何时已? + +红颜薄命固然让人叹惋,才子英年早逝却更教人扼腕。他的词可谓是“天雨粟,鬼夜哭”,人间少了一位君子,夜台却又多了一颗文星。如同他在某首咏雪词中写道:“冷处更佳,别有根芽,不是人间富贵花。”于是乎他自己,似乎也不应属于人间。他是天上的一颗明珠,终将回到天上去。 + +如今觥筹交错的局面早已消逝,丝竹管弦也只是古书中附加的背景。无论金粉有多浓重、场景有多华丽,纳兰永远是其中最清逸的一道色彩。万古是非浑短梦,人间何处问多情? + + diff --git a/src/content/posts/2012/2012-04-09-when-u-were-young.mdx b/src/content/posts/2012/2012-04-09-when-u-were-young.mdx new file mode 100644 index 0000000..57f078a --- /dev/null +++ b/src/content/posts/2012/2012-04-09-when-u-were-young.mdx @@ -0,0 +1,39 @@ +--- +title: 轮回,苍白了年少轻狂 +slug: when-u-were-young +date: 2012-04-08 23:10:43 +updated: 2020-09-06 11:49:53 +tags: + - 轮回 + - 成长 +category: 文章 +summary: 百日轮回,倏然一瞬,有的只是成长的记录和曾经的感悟。但,说不尽,道不完的,还是回忆。 +cover: /images/2012/04/2012040802235300.jpg +--- + + + +<MusicPlayer netease={1892046117} /> + +无意间掐指算算,距上一次写下[第几个 100 天](/posts/one-hundred-days/)之后又过去了 100 天。百日轮回,说长不长,说短不短,只是不经意间回首,便苍白了记忆。 + +一开始建博的时候,只是想将自己内心的想法一一表述出来。所以,每次满怀欣喜与期待地发表一篇文章之后,便会忐忑不安并激动地等待你的留言和评价。那是一份期待能有人认可和赞赏的盼望和心切,一种想展示内心自我的冲动。于是乎,那么多的文字就这样一点点地日积月累,随着时间的流逝,风格一变再变,访客也是新颜换了旧颜。但是,真正变了的,只有自己的心态。 + +虽说花谢了来年还可以再开,曾经的自己傻傻地以为年华也是这样,无忧无虑的年少时光可以像花期一样循环往复。却不懂得,其实成长,就是一场盛宴,也是一种伤。其实那些写下的文字,都将是我们生命中最为难忘的记述,过去了,就不再拥有。 + +有的时候,看见后台里的一个个鲜活的面孔,心中总是感到莫名的痛。只为似水流年中,那些消逝的曾经。 + +写下此文的时候,我又一次重新审视了那些稚嫩的文字,突然有一种想笑的冲动,是过去的我太天真,还是现在的我太成熟? + +> 看见的熄灭了,消失的记住了。 +> 我站在海角天涯,听见土壤萌芽。 +> 等待昙花再开,把芬芳留给年华。 +> 彼岸没有灯塔,我依然张望着…… + +这样一个安静的夜晚,一个人静悄悄地听着王菲的《彼岸花》,心情起伏,那一段段的文字划过眼帘,又那么地消逝于视野…… + +一滴无声的泪珠划过脸庞,冰冷的,混合着苦涩,苍白了昔日的少年痴狂。突然间明白,在成长的盛宴中,我们得到了很多,也遗忘了很多。 + +百日轮回,倏然一瞬,有的只是成长的记录和曾经的感悟。但,说不尽,道不完的,还是回忆。 + + diff --git a/src/content/posts/2012/2012-04-14-bougainvillea-spectabilis-willd.mdx b/src/content/posts/2012/2012-04-14-bougainvillea-spectabilis-willd.mdx new file mode 100644 index 0000000..21891cc --- /dev/null +++ b/src/content/posts/2012/2012-04-14-bougainvillea-spectabilis-willd.mdx @@ -0,0 +1,47 @@ +--- +title: 揽月楼前的三角梅开花了吗? +slug: bougainvillea-spectabilis-willd +date: 2012-04-13 21:35:55 +updated: 2020-09-06 11:51:51 +tags: + - 回忆 + - 三角梅 + - 高中 +category: 文章 +summary: 一场淅沥淅沥惹人心烦的清明小雨后,软件园教学楼旁的海棠花纷纷扬扬地开放了,粉色的花瓣映衬着来来往往的青春容貌,带来一份熟悉和喜悦,还有一段淡淡的回忆…… +cover: /images/2012/04/2012041301591600.jpg +--- + + + +<MusicPlayer netease={424060342} /> + +一场淅沥淅沥惹人心烦的清明小雨后,软件园教学楼旁的海棠花纷纷扬扬地开放了,粉色的花瓣映衬着来来往往的青春容貌,带来一份熟悉和喜悦,还有一段淡淡的回忆…… + +——题记 + +今早上上课时,校园的小径上漂浮着丝丝的柳絮,绵绵的,让人欣喜。我不由得想起《圣斗士》里面沙罗双树园之战里的故事,“最接近神的人”加沙在被杀死的时候曾说道:“沙罗双树的花也凋落了吗?” + +沙罗双树开花的时候亭亭玉立、比邻而居,纯白色的花瓣洒落空中的时候像极了此刻晚春的落英与柳絮。济南的 4 月刚刚回暖,所以校园里西府海棠多于此时绽放。再想想高中校园里的三角梅,此刻也定是花团锦簇了吧。 + +高中读书时,教学楼的名字叫做揽月楼,其后有一个走廊形式的小花圃,一开始由于才建好,光秃秃的。进入高中的第一个春天,那个三角梅盛开的季节。我第一次看到花圃中绽放的紫红色花骨朵,热烈的、大把大把地绽放着,就像是一种生命的燃烧与舞动,给你一种由心的惊艳之感。 + +在厦门读完高中三年,每到冬天的时候,我常常习惯性地望向楼下的花儿,心里问:三角梅什么时候开花啊?开了花,意味着温暖舒适的春天就要来了。 + +寒假时,父母都去上班,一个人在家时,心中总会浮现出风中摇曳的光秃秃的花枝。心里想:它们什么时候才会开花啊?当它们开花的时候,新的学期就要来了。 + +我是如此地盼望着它们的盛开,看着它们慢慢长出花苞,在某个清晨,当我走进校园的时候一齐盛开怒放。就像是一种一年一次的约定,只有看到了盛开的三角梅,万紫千红的春天才算是真正的开始了! + +揽月楼前的三角梅,承载了苦闷高中三年的记忆,是我中学时代中最为美好的风景之一。 + +毕业后考进了山大,离开了南国温热的气候,来到济南这么遥远的北方。我常常怀念高中典雅幽静的校园,怀念揽月楼前的三角梅。今年年初的时候为了拍摄特意在假期返了一次母校,整个校园空荡荡的,花圃里的三角梅也只是散散零零地开了几多,迎着风儿打着旋儿。我那亲爱的三角梅啊,怎么还不开花? + +2 月中旬,因为开学,又匆匆回到济南,一转眼 2 个月过去了。前天,还在母校读高中的校友兴匆匆地打电话告诉我,三角梅开花了。急匆匆地打开校友的空间相册,映入眼帘的便是那熟悉的紫,依旧是那么奔放地绽开。那种熟悉感,就像是我与它跨越了南北 3000 公里的漫长距离般,在心灵上又一次共鸣。 + +三角梅,花语:热情、坚韧不拔。就像是当年在[花圃榕树下的那个她](/posts/blue-turkey/ '蓝色土耳其'),一起拼搏过,奋斗过。曾掐下一朵紫红三角梅,别于她的发梢间,两人间只需会心一笑,一切便尽在不言中…… + +写下此文时,我特意去翻了翻图书馆里关于植物的书籍,才发现三角梅原来还有一个诗意的名字叫做九重葛,又名毛宝巾、簕杜鹃、叶子花、纸花。但三角梅也好,九重葛也罢,我却很难再对于相似的花海有所感触了。就像是此刻我看着窗外的海棠花儿,只是惊艳于它的美丽,别无他想。 + +想来也是,花儿何处都有,但是那些年少的心迹却不会随意开放,一年又一年,这些类似的场景只是涂描于心中的某个不知名的角落。只可谓年年岁岁花相似,岁岁年年人不同。 + + diff --git a/src/content/posts/2012/2012-04-20-left-time-right-live.mdx b/src/content/posts/2012/2012-04-20-left-time-right-live.mdx new file mode 100644 index 0000000..d292b10 --- /dev/null +++ b/src/content/posts/2012/2012-04-20-left-time-right-live.mdx @@ -0,0 +1,38 @@ +--- +title: 光阴向左,生活向右 +slug: left-time-right-live +date: 2012-04-20 07:58:25 +updated: 2020-09-06 11:52:13 +tags: + - 未来 + - 忙碌 +category: 杂思 +summary: 周一时信誓旦旦地对松鼠哥哥说:“我要开始写博文了,准备好抢沙发。”然后,便没有了下文……似乎每天都有很多的事情要忙碌,前半个学期一直忙于数据结构的项目,刚做完,操作系统的实验又来了。 +cover: /images/2012/04/2012042002132500.jpg +--- + + + +<MusicPlayer netease={874229} /> + +周一时信誓旦旦地对松鼠哥哥说:“我要开始写博文了,准备好抢沙发。”然后,便没有了下文……似乎每天都有很多的事情要忙碌,前半个学期一直忙于数据结构的项目,刚做完,操作系统的实验又来了。 + +于是,这个一周的时间便全身投入了 Linux 之中,查找资料,一边不熟悉地使用着 vim,一边头大地查找 Library 中的函数。编译、测试,不知不觉,一周就过去了,说好的文章却一直没有写。 + +辅导员说:“雨帆,你活得太累了,不要这样子。”可是,谁又能知道自己心中的无奈?当年,在高考之后填写志愿的时候便和父母发生了争执。我一直想要学习化学,痴痴地想要将全部的精力投身于其上。可是,生活的无奈,父母的反对,为了坚持自己的兴趣,不得不选择了软件专业。 + +于是,为了证明自己,或者说由于无时无刻不在担心当初那个不被认可的选择会不会贻笑大方,常常强迫自己去学习。于是,越来越忙碌,越来越没时间思考,似乎自己的感情都被牢牢压抑了。有时候,我会很怀念读小学的生活,可以那样无所顾忌地放声大哭的日子。那样痛声的哭泣,还往往可以换来父母温暖的抚慰。但是,女友云儿说,已经懒得哭了。 + +那么,是什么时候开始,已经学会了隐藏自己的情感呢?有时候心里很难过,就一直对自己说,不要哭,你已经是大人了。上课、吃饭、自习,每天都有很多事要做。于是,很辛苦地仰头呼吸,强迫自己将一切的情感压回心底,继续如平常般忙碌、寒暄、微笑。 + +等到了睡觉的时候,已经心力交瘁、筋疲力尽,除了困倦别无其他,此时最好的选择便是洗洗睡吧。于是,我还是不多愁善感的好。就让自己的神经粗一点吧,我不想哭。 + +曾经疯狂地迷恋上了网络游戏,因为在那个虚拟的世界里面,可以忘记一切的现实烦恼。时间、精力、金钱,自己将一切的一切花于游戏中。但是,当年回到现实世界的那一刻,才发现,一切都是那么的空虚和无奈。 + +看着窗外前段时间还开得烂漫的海棠,此刻已经落了大半。心中突然明悟,人生也许就是这样子了,顺着自然的,顺着自己心意的,即使是再忙碌,也并没有什么无奈与不安。就像说花谢也无需哭泣,因为这是顺应自然的。 + +人生路上的前方,常常就像是迷雾、花海,远看的时候朦朦胧胧、并不真切,只有走近了,才能看到与远看时完全不同的场景。那么,就让我来揭开自己迷途般的未来吧! + +光阴向左,生活向右。 + + diff --git a/src/content/posts/2012/2012-04-22-chirography-on-letter.mdx b/src/content/posts/2012/2012-04-22-chirography-on-letter.mdx new file mode 100644 index 0000000..3eefdc5 --- /dev/null +++ b/src/content/posts/2012/2012-04-22-chirography-on-letter.mdx @@ -0,0 +1,30 @@ +--- +title: 见字如唔 +slug: chirography-on-letter +date: 2012-04-21 19:19:11 +updated: 2020-09-06 11:52:25 +tags: + - 回忆 + - 书信 +category: 杂思 +summary: 见字如唔,即见字如见人,看见写信的那一方熟悉的字体,心里面便会浮现出对方温暖的身影,仿若近在身边。而曾经的很长一段时间里都很喜欢这个词,或者说是怀念它所承载的一段记忆。 +cover: /images/2011/05/2011051521491300.jpg +--- + + + +<MusicPlayer netease={668451} /> + +见字如唔,即见字如见人。看见写信的那一方熟悉的字体,心里面便会浮现出对方温暖的身影,仿若近在身边。而曾经的很长一段时间里,我都很喜欢这个词,或者说是怀念它所承载的一段记忆。记得早年在外地的时候,每次和昔日的故友、表弟通信,第一句便是见字如唔。只是现在再谈起,又有几个人会懂? + +一直以来,我对于纸张和笔记本有一种特别的迷恋。 + +每次发表博文时,第一件事情便是在纸张上勾画好大纲,写好草稿,再慢慢修改好后通过打字誊写到博客上。我常常喜欢写字的这一过程,看着自己的思绪变成了文字,印在了纸上,便有了一种莫名的兴奋。想想这些纸张的前身都是树木,每次写下想法时,常会闻到一股淡淡的香。写着写着,当我无意中去翻看昔日的存稿时,才发现,已经垒成了厚厚的一摞,也算是一种意外的惊喜吧。 + +去年,宿舍换床位的时候整理杂物,从书摞里面翻出一大袋明信片。突然觉得,似乎写信的日子离我越来越远了。现在每年过生日的时候,我常常收到无数的 E-mail、短信。虽然,它们很漂亮,很完美,内容中包含着真挚,但我却一点也不喜欢。想来这些朋友也都是十分忙碌。我们的思想、友情,都被留在了硬盘里面,经受不起任何一场病毒或是格式化。有时又觉得很无奈,我们的生活就是无数个 1 或 0。那么丰富多彩的情感,又怎可能是 1 或 0 所能表达的? + +于是乎,我常怀念书本中的那个信息通讯极其不发达的年代。那时候,远方的亲友间的联系,还不能通过无线电、基站来传递。很多说不出的话语,常常只能满满地写于纸张上面,藏于厚厚的信封中,向远方传递。于是乎,那种等待与期待,往往是最为美好与焦急的时刻。想想自己上初中追求初恋的时候,便是通过简短的书信来往。每次都是偷偷地将纸张塞于隔壁她的书桌抽屉里,之后便是焦急的等待回信。一封又一封,似乎那个时候,语文课本中一切可用的华丽辞藻都被我拿来描绘。那种情境现在想起来都是那么的可爱。现在的生活,每天和老婆之间,即使相隔 200 米,也能立刻通过手机、QQ、微博让对方知道自己的情况。有时候觉得这样子很方便,又有时觉得没有了距离的熟悉感是那么的厌烦。 + +这周一的时候,收到了昔日高一的女友寄来的明信片,封面的第一句写着:见字如唔。那一刹那间,我仿佛看见了多年前的那个[榕树下的下午](/posts/blue-turkey/ '蓝色土耳其'),那张永不退色的脸庞…… + + diff --git a/src/content/posts/2012/2012-04-23-dragon-nest.mdx b/src/content/posts/2012/2012-04-23-dragon-nest.mdx new file mode 100644 index 0000000..261e2b9 --- /dev/null +++ b/src/content/posts/2012/2012-04-23-dragon-nest.mdx @@ -0,0 +1,35 @@ +--- +title: 我已经舍不得花一个小时 +slug: dragon-nest +date: 2012-04-23 11:52:33 +updated: 2020-09-06 11:53:24 +category: 文章 +summary: 对于每个人而言,长大了,意味着不同的改变。但如果要我说自己有什么不同,我定然是想不出的。突发奇想问问旁边的人,都说没变啊,还是和以前一样挫。 +cover: /images/2011/04/2011041420484000.jpg +--- + + + +<MusicPlayer netease={440114051} /> + +对于每个人而言,长大了,意味着不同的改变。但如果要我说自己有什么不同,我定然是想不出的。突发奇想问问旁边的人,都说没变啊,还是和以前一样挫。“靠!”寒假的同学聚会倒是让我吃了一惊,身边的同学都变化蛮大,大家几乎认不出彼此,只能通过似曾相识的眉眼、容颜揣测。 + +看来岁月催人老,我们还是潜移默化地改变了。 + +前些日子,机油叫我一起打剑灵,玩了不到一个小时,我便无聊地 Shift + Delete。 + +如果非要说我对哪些游戏比较有感情的话,《奇迹》一定会是在里面占上大大的一笔。2004 年第一次接触到网络游戏开始算起,陆陆续续玩了许多网游。《奇迹》是我玩的第一个游戏,也让我第一次在网游里面体会到那种叱诧风云的激情与快感。那种热血的回忆,到现在都难以忘记。 + + + +上了初中后,心思开始专注于学习上了,这期间玩的游戏便少了,印象深刻的,便是《梦幻西游》。当年,为了抓一只泡泡,三天三夜地苦苦研究秘籍,讨论哪里遇见的几率大,遇到后怎么抓。现在想想,又有些好笑,年少的思想就是单纯。前些天突然在微博上看到一句话:亲,你还记得当年大明湖畔的泡泡吗?瞬间便有一种流泪的冲动。 + +到了大学后,我的第三次游戏生涯才算是正式开始。2010 年年底,第一次看到同学在玩《龙之谷》。瞬间便被它丰富的连招和华丽的画面迷上了。可以说,这是一个好游戏。但是为什么玩的人越来越少?服务器越来越卡呢?有时候,打开游戏,里面在线的好友只有几个,公会里的人也越来越少。有时候想组队刷图,半天都没一个。是我抛弃了游戏,还是游戏抛弃了我? + +仔细想想看,我们中国人很难理解韩国游戏运营商的开发模式。在一个生活压力很大的韩国,他们似乎更愿意一边上班,一边玩着版本缓慢更新的游戏来缓解压力。而国人,很多都像我一样,把游戏当作了生活。所以当对于一个事物熟悉到失去兴趣的时候,便会离开。想想韩国现在还不断更新的《奇迹》,和国内两年没有维护的《奇迹》官网,便是活生生的例子。 + +说到底,其实还是我自己变了。我已不再如从前,有了自己的事情和兴趣。网游里面的打打杀杀、刷怪练级的生活已然对我无趣,甚至连一个小时都舍不得花费。 + +变与不变,真正的生活还要继续。而游戏,也许只是生活的调剂品,真正的主菜,还是现实。 + + diff --git a/src/content/posts/2012/2012-04-23-the-bns-cbt3.mdx b/src/content/posts/2012/2012-04-23-the-bns-cbt3.mdx new file mode 100644 index 0000000..8d3ab3a --- /dev/null +++ b/src/content/posts/2012/2012-04-23-the-bns-cbt3.mdx @@ -0,0 +1,33 @@ +--- +title: 越来越近的CBT3 +slug: the-bns-cbt3 +date: 2012-04-23 11:54:00 +updated: 2020-09-06 11:54:33 +category: 文章 +summary: 在解说我所谓的CBT3是什么之前,我想继续上文来吐槽思密达棒子们的脑袋到底是怎么想的。 +cover: /images/2011/04/2011042321083500.jpg +--- + + + +<MusicPlayer netease={28844150} /> + +在解释我所谓的 CBT3 之前,我想继续上文来吐槽一下思密达棒子们的脑袋到底是怎么想的。如果你一直在抱怨小米手机的饥饿营销让人愤怒的话,那么我要说:比起 NC Software 来说,那些都是小孩子过家家,人家才是玩弄这个的鼻祖。——好了,吐槽完毕。^\_^ + +韩国的游戏,一直以来都吸引世界各地游戏玩家的眼球。有些游戏在韩国不受欢迎,但是在中国等地却能异常红火。例如,《毒奶粉》(DNF)便是一个活生生的例子,这本在韩国业绩不佳的游戏在中国却死灰复燃,到现在还是那么火爆。于是,在厌倦了国产游戏的大宣传、大制作、大烧钱、极其垃圾的质量之后,我便将目光集中到了韩国游戏上。然而,这便是坑爹的开始…… + +似乎,就像是笑话里面说的那样,韩国人的一切都是和泡菜息息相关的。比如游戏,必须要像泡菜一样经过长时间的腌制和发酵,才能向公众开放。于是,一次又一次封闭内测,一次又一次的删档,一次又一次的跳票……(某人无限怨念中……)也就是在这样的等待和激动中,《剑灵》的 CBT3(Close Beta Test 3)就要开始了! + + + + + +今晚,外游网的论坛里《剑灵》板块小小地火了一把,韩国的 NC 公司终于在今天宣布,开始为期半个月的第三次封闭内测。作为二测的老玩家,我可以从 25 号开始直接登录测试。好激动的说,话说回来,这次的宣传视频中,最为特色的就是之前一直猜疑的召唤师。怎么样?是不是很可爱啊?实话说回来,上面的喵星人彻底把我萌了一把。不管怎么说,继续坐等 25 号。 + +对于 NC Soft 的这种营销策略,我们必须从两个角度来看待。一方面,频繁的封闭测试确实能确保游戏在公开发布前达到最佳状态。通过反复的删档测试,可以收集大量玩家反馈,修复漏洞,优化游戏体验。然而,这种策略也极大地考验了玩家的耐心,特别是在期待值和现实体验之间的差距容易引发玩家的情绪波动。 + +从商业角度来看,这种“饥饿营销”手法不仅在游戏行业内十分常见,更是被广泛应用于各类消费品市场。它的核心在于通过制造稀缺性来提升产品的市场需求和消费者的期望值。对于 NC Soft 来说,这种策略不仅可以维持高昂的市场热度,还能有效控制游戏的运营节奏,避免因为提前上线而导致的不成熟产品打击品牌声誉。 + +总的来说,《剑灵》的 CBT3 代表了韩国游戏产业在开发和运营策略上的独特路径,也提醒我们在面对新游戏时,既要保持足够的期待,也要有适度的耐心和理性。期待 25 号的测试,希望这次能带来更好的游戏体验。 + + diff --git a/src/content/posts/2012/2012-04-25-the-first-day-of-bns-cbt3.mdx b/src/content/posts/2012/2012-04-25-the-first-day-of-bns-cbt3.mdx new file mode 100644 index 0000000..01861fb --- /dev/null +++ b/src/content/posts/2012/2012-04-25-the-first-day-of-bns-cbt3.mdx @@ -0,0 +1,42 @@ +--- +title: 剑灵 CBT3 第一天感言 +slug: the-first-day-of-bns-cbt3 +date: 2012-04-25 11:55:22 +updated: 2020-09-06 11:55:57 +category: 文章 +summary: 怎么说好呢?这个蛋疼的一天真的是悲喜交加,或者说让人无爱的Play NC让人郁闷。 +cover: /images/2011/04/2011042521393900.jpg +--- + + + +<MusicPlayer netease={28844152} /> + +怎么说呢?这个蛋疼的一天真的是悲喜交加,或者说让人无爱的 Play NC 让人郁闷。花了两天时间辛辛苦苦地通宵下载完庞大的客户端后(校园网标准 100k/s 的下载速度,还不定时抽风),便开始了激动的安装。好了,一切就绪后,就准备开始玩了。 + +首先按照外游网里御龍御龍大大的方法,将 `Client.exe` 创建了一个快捷方式到桌面上,在快捷方式的属性里加上了 `/LaunchByLauncher` 参数,小小地登录进去看了一下,发现登录界面和二测的一样没有变化。现在是 12 点,坐等下午 1 点的开服啦。 + + + +挂好 VPN,登录进入[官网](http://bns.plaync.co.kr),首页左下角的灯笼就是登录游戏的地方,现在还没开放,所以不能点击。等啊等,终于,YY 的某个基佬说,可以了。 + +可是我这里的官网还是点不了啊。在等待 3 分钟后果断刷新,就可以点击了。 + + + + + +激动地通过官网启动了客户端后便是坑爹的开始啊。首先是上面的更新。 + +我的更新卡在了 6% 不动,然后是各种报错。真搞不懂棒子们是怎么想的,是不是为了体现自己的网络有多么优良,整个 1.4G 的补丁文件全部在线更新,连一个离线下载的地方都没有。于是,就这样更新了整整 4 个小时。期间服务器宕机了一次,最后干脆放出服务器维护的消息,尼玛整整维护从四点到六点 2 个小时。幸运的是,终于在再次开服的时候进入了游戏。由于及时,没有排队哦。放出截图两张,让你们嫉妒嫉妒。 + + + + + +最新消息,游戏服务器期间突然又卡了一下,然后 8 分钟后才恢复。结果,尼玛回档了,继续从 0 开始练级。o(︶︿︶)o 唉,坑爹的 NC。 + +> PS +> +> - CBT:Close beta test +> - 剑灵:韩国网络游戏著名开发商 NCsoft 的最新作品。这是一款试图摆脱单调的游戏方式,让玩家体验新乐趣的奇幻武侠动作 3D MMORPG。 diff --git a/src/content/posts/2012/2012-04-26-your-second-home.mdx b/src/content/posts/2012/2012-04-26-your-second-home.mdx new file mode 100644 index 0000000..5d776e4 --- /dev/null +++ b/src/content/posts/2012/2012-04-26-your-second-home.mdx @@ -0,0 +1,41 @@ +--- +title: 给你一个家的感觉 +slug: your-second-home +date: 2012-04-25 17:06:44 +updated: 2020-09-06 11:56:24 +tags: + - 西门 + - 主机 + - 主机格调 +category: 文章 +summary: 傍晚,我和云儿携伴行走在校外的街道上。来来往往的人潮,每个人行色匆匆地与我擦肩而过,涌向远方…… +cover: /images/2011/05/2011052622280900.jpg +--- + + + +<MusicPlayer netease={281530} /> + +傍晚,我和云儿携伴行走在校外的街道上。来来往往的人潮,每个人行色匆匆地与我擦肩而过,涌向远方…… + +我立身于人海之中,望着这些匆忙的人们,他们的脸上没有焦急的神色,每个人都是淡淡的安详。汽车声、谈话声、脚步声交织在耳畔,好一副人间烟火的景象。 + +人群中的某些人,终会在某个角落、拐弯处消失,融入略微发昏的夜色里。他们的目的地却是那么出奇的一致——家。 + +此刻黄昏已然降临,街边的路灯依次亮起,像是一道道迷茫中的方向标,指引着归途的家人。远处的建筑里亮起了点点光亮,就像是一座座守望塔,等待着、盼望着亲人的下班、放学归来。想想上小学冬季时的回家,每次都能远远地在路上看到家门口的那盏路灯和母亲在门口张望的身影,那是不变的约定和真情的守候,等着你的归来。 + + + +生活,就是痛苦地生下来,勇敢地活下去。在岁月的进程里,悲伤、酸辛、惆怅如同一条河流,总是和着往事与现实的纠葛,有着说不清的怅然和隐隐的痛。而一个人,只有在一个地方才能将思绪调到最淡,暂时放下浑身的担子。那就是,家。 + +网络茫茫,浩大无边,已经超越了我们的想象。每个人通过网络,获得需要的资源,也创造着属于自己的信息。 + +厌倦了人人网上分享的无聊消息和各种签名;厌倦了 QQ 上一个个闪烁的头像和悦动的消息;厌倦了各个门户网站上密密麻麻的明星八卦绯闻后,我们常常希望能够在互联网上拥有这样一个小小的地方——一个只属于自己的网络空间,一切全部属于你。就像是一块画板,你可以在上面描绘自己的色彩;就像是一本精致的日记本,你可以写下任何心事、思绪,快乐的、不开心的、任何心情;就像是一间小屋,你可以设计它的一切。 + +而就像你通过网络看到我的文章一样,除了现实生活中的家之外,其实每个人在网络上也可以有一个家。那就是,独立博客。 + +独立博客,互联网中不常为人注目的一艘小舟,是你在互联网上的又一个栖身之地。不需要多少人的关注,不需要宣传,就像是墙角的一朵不为人注目的花,淡淡地写着自己的心事,留下那些藏身心中多年的话语,一笔一笔地勾勒着自己的人生…… + +何处是家?独立博客,网络中属于你的家! + + diff --git a/src/content/posts/2012/2012-05-03-the-flavour-of-sunshine.mdx b/src/content/posts/2012/2012-05-03-the-flavour-of-sunshine.mdx new file mode 100644 index 0000000..dcc1bee --- /dev/null +++ b/src/content/posts/2012/2012-05-03-the-flavour-of-sunshine.mdx @@ -0,0 +1,58 @@ +--- +title: 阳光的味道 +slug: the-flavour-of-sunshine +date: 2012-05-03 14:34:24 +updated: 2020-09-06 11:58:10 +tags: + - 回忆 + - 童年 + - 外婆 + - 爱 +category: 文章 +summary: 4 月底的阵雨过后,久违的晴天终于来临。傍晚和舍友携伴去收被子,阳光漫漫扬扬地倾洒在身上。沐浴着金色的阳光,抱着晒得柔软温暖的被子,我的思绪却不知不觉飘到了很远…… +cover: /images/2011/06/2011062418273300.jpg +--- + + + +<MusicPlayer netease={740530} /> + +4 月底的阵雨过后,久违的晴天终于来临。傍晚和舍友携伴去收被子,阳光漫漫扬扬地倾洒在身上。沐浴着金色的阳光,抱着晒得柔软温暖的被子,我的思绪却不知不觉飘到了很远…… + +两人高的屋檐,漏下一方四四方方的半个篮球场大小的光斑,这就是童年记忆深处中熟悉的场景了。小时候,父母的工作总是那么忙,于是每天大半的时光便是在外婆家度过的。 + +外婆的住房大约始建于 70 年代,属于目前很少见的双层单位公寓楼,外婆住在楼下。和很多老屋子一样,一楼背阴的屋子,总是潮湿阴冷的。所以一到阴天的时候,外婆的双腿总是会隐隐作痛。小腿肚上一按下去就会凹下一大块,久久不见复原。 + +于是,午后屋外的那片阳光成了每天和外婆必去的地方,直到今天,还能依稀记得一些模模糊糊的情境…… + +某个秋初的下午,秋老虎已经过去的日子。家家户户的门前都开始晒起了冬天要盖的被子,一如往常一样,我和外婆坐在了有些倾斜的光影下。趁着外婆不注意,我开始玩起了钻被子的游戏。 + +“小雨!”,身后响起了外婆有些生气的叫声,“回来。” + +被外婆抓了个现行的我垂着头,闷闷不乐,两只腿推拉着回到外婆旁边。坐下来后便把头偏向一边,不理外婆。 + +耳畔传来外婆的笑声,“小雨,来给外婆唱个小曲。”“不唱,就是不唱。”我把头偏得更偏了,继续不理睬外婆。 + +“怎么了?小雨。要不外婆给你讲个故事,你知道吗?阳光也是有味道的……” + +“不听,不听,不听。”我双手捂着耳朵,背对着外婆,“上次你说钻被子会长不高,我问了老师,老师说是假的。” + +“不信?你去外婆家的被子上闻一闻?不就知道了。”外婆带着十分肯定的语气说道。 + + + +此时的阳光依旧那么灿烂,天空中从远处飘过一大片云朵,慢慢遮住太阳,地上由远到近慢慢出现一片暂时的阴影。对面的那栋楼前长出屋顶的梧桐树还在沙沙响动。我回过头,半信半疑地看了外婆一眼,又看了看被子,磨蹭磨蹭地走了过去。 + +面前向阳处晾晒的是我晚上睡觉时要盖的小棉被,握在手中暖暖的,似乎带着一种闻之欲睡的味道。外婆的被子孤零零地晒在略微背阴的角落,冰冷冷的、硬梆梆的。 + +不由得对外婆的说法信了几分,记得当时的我一路小跑扑进外婆的怀里,“外婆!外婆!真的有一种味道哎!外婆,阳光的味道到底是怎么一回事啊?” + +“哎呦,我的心肝呦。”外婆接住了我,只是看着我笑,却什么也不说。 + +缠着外婆问问题的我渐渐困了,不知什么时候起进入了梦乡。外婆的手有一下没一下地慢慢轻拍着我的后背,邻居贾奶奶家的大黄狗从我身旁擦过,风过梧桐树的淅淅声久久回荡在耳畔,越来越模糊…… + +这样散碎的记忆就这样结束了,回过神,身边是还在说笑的舍友。说笑着感叹道:“好一个阳光明媚的晴天!” + +其实,阳光的味道,即是幸福。 + + diff --git a/src/content/posts/2012/2012-05-07-novel-story-0.mdx b/src/content/posts/2012/2012-05-07-novel-story-0.mdx new file mode 100644 index 0000000..135a8a0 --- /dev/null +++ b/src/content/posts/2012/2012-05-07-novel-story-0.mdx @@ -0,0 +1,101 @@ +--- +title: 交织的羁绊 - 序章 +slug: novel-story-0 +date: 2012-05-07 14:33:18 +updated: 2020-09-06 12:04:17 +tags: + - 悠久之翼 + - 小说 + - 同人 +category: 小说 +summary: 这是一个同人小说的开篇,也是一个故事的开始。在这里,我将写一篇短篇小说,名为《交织的羁绊》。故事的原型和人物完全是对动漫《悠久之翼》的改写。 +cover: /images/2011/07/2011070220190200.jpg +--- + + + +<MusicPlayer netease={527778} /> + +这是一个同人小说的开篇,也是一个故事的开始。在这里,我将写一篇短篇小说,名为《交织的羁绊》。故事的原型和人物完全是对动漫《悠久之翼》的改写。昔日的我曾经想把它写下去,但一直没有坚持,不光是因为时间或者心情,还有沉淀于心的感受。 + +时间带给人的不仅是苍老,也有见识上的阅历。所以我想慢慢写,用时间来写出每一章、每一字。这个故事将是一个巨大的、不知何时才能填满的水坑 ;-) 但是我会写下去,就像是一种记忆与幻想。幻想童话中那双闪光的音羽之翼。 + +无论是谁都会有向神祈祷的时候。就算是毫无信仰,但也必然会有全心全意去祈祷的那一刻。谁都会有寻觅之物、祈望之物、伸出双手想要获得之物。无尽的思念之中,由人与人的羁绊生出之物。那……一定是——**交织的羁绊** + +银白色的天空、大地,雪中的世界银装素裹。白色的圣诞节傍晚,音羽镇的街道上已然寥无行人。此时做完弥撒后的教堂门口突然出现一个漆黑的身影,他穿着厚重的大衣,围着一条略显老旧的围巾,手拿一束不该出现在这个时节的鲜花,停驻在教堂半掩的门口,似在沉思。漫天的雪花纷纷扬扬地交织洒落,不一会儿为他披上一身白大衣。小小的身影似与这白色的世界融为一体,带着寒意的空气弥漫了整个天空的忧伤。 + +深呼吸一口气,男人抬起头看着眼前这扇半掩的教堂大门。一次又一次地伸出双手,想要推开它,却每伸到一半便不敢再向前。眼前仅仅有一尺的大门就在那里,似乎在期待,期待门后会有怎样的故事、人物。昔日的记忆交织在脑海,回忆着那些一个又一个美好的记忆,男人的眼角不觉露出笑意。某一刻,远处街道上自行车的叮铃声响起,惊醒了还沉浸在回忆中的他。想想自己不远千里来到这个充溢着伤感与回忆的童年小镇,只为实现一个心愿,完成一份愿景。而她,会在里面吗?想到这,男人仿佛下定了决心般走向那扇门…… + +随着轧轧声,男人缓缓推开那道沉重的门。踏入的瞬间,迎面扑来一阵热气,镜片上也因此糊上一层水汽。但是,为什么心中却突然感到刺骨的寒冷?呼出白色的气息,望向面前的环境。弥撒后空寂的教堂,同远方他守候的教堂一样的布局,却总感觉少了什么。男人走过一排排长椅,墙壁上的蜡烛将他的影子层层叠映,咚咚的踩在地板上的脚步声回响在这个无人的教堂里。一步一步,终于来到了大道末端的圣母像前,回望四周,还是没有那个日夜思念的身影。男人的心中不觉有些失落,但也如释重负地松了一口气,唇间一抹苦笑,自己还是太天真了啊,人死了怎么又会重现于世呢?纵使似传说般变成了天使也不可能啊! + +男人失落地转身、迈步,向着来时的方向走去,手里的花束紧紧地攥在手中。微湿的眼角、沉重的步伐展现了此刻他心中的失落。少女的笑容还在心间浮现,但只是模糊的记忆。 + +突然间,他的耳畔传来一声温柔的话语:“你来晚了,弥撒早做完了哦。”已然麻木的男人突然惊喜地回过头,祭坛前的圣母像下不知什么时候多出了一位少女背对着男人,飘逸的长发、靛蓝色的厚重棉袄。而男人却已然失了言语,就这样愣愣地注视着少女,手早已松开,扎好的花束洒落一地。仿佛有一个世纪那般漫长,最后,只吐露出两字:“优——子”…… + + + +我们会不会,在某个时间某个地点,会在某个叫不出名字的地方,会在某片风划成线条的场景,看到曾经那张熟悉的面容,同时也就在那么一瞬间,天昏地暗。谁的忧伤,埋没在雪地上扯着风静静旋转的风标,留下晃动拉长的影子,像是几十世纪前斑驳的呈现。谁的呢喃,像是塞壬的歌喉,拂拭着人们心灵最脆弱的沙洲,带来天空瞬息万变的风景,奏动了锈迹斑斑的琴弦。谁的女孩,离散在古老的荒原,隔着圣安德烈斯大断层双目对视的瞬间,看见了曾经的永远。谁的身影,站立在世界毁灭的尖端,看着面前疮痍满目的画面,湮没了所有传唱千年风干的誓言。没有荒原上扯着风旋转的风标,没有海洋深处塞壬的歌喉,没有空间隔离的圣安德烈斯地球大断层,没有世界毁灭的声响,只有站在圣母像下面的女孩。秀美的长发色头发,调皮地挽在肩膀前面,更深更长的睫毛,能看得见一整个银河的眼睛,融合在周围环境里…… + +“那么,我是什么时候,软弱到会做这种梦了?”男人这样想到。 + +“啊啦”,祭坛前的少女轻轻地转过身来,“晚上好。”少女的脸上洋溢着澄澈的笑容,微微地低下了头,那头飘逸的长发也随之荡漾出美丽的波纹。 + +“……”男人无言地望着少女的双眼,胸口间有一股被人深勒的疼痛,曾经自己的双耳听过无数遍的她的声音,那每一言一语都是如此的悦耳动听。 + +“……哟”男人费了半天,仿佛用尽全身力气地挤出了这句话。 + +少女调皮地眨着双眼,微笑着说道:“啊?不对哦。今天应该是——圣诞快乐,才对呢!”她的整个身影埋没在教堂微弱的烛光下,恍若梦境。 + + + +“圣诞—快乐。”男人深吸一口气,回复了才来时的平静,深邃的眼眸注视着少女。 + +“圣诞节,却是一个人吗?”少女调皮地撅起嘴,抬起头看向男人,露出好奇的神态。 + +“啊,一个人过圣诞节已经很多年了…” + +“哎呀,还真是一个寂寞的人啊!”少女撅起了嘴,微垂眼帘,小声喃喃道,“不过说起来我也总是一个人呢。” + +“那么……”男人突然打断了少女,语气间透着一丝急迫,“如果可以的话,可以稍微聊聊吗?” + +少女的脸上绽开了笑容,阴沉的教堂似乎因为她的微笑而明亮起来,“嗯,十分乐意。”笑容间,透露着先前没有的亲切,“好久没见了呢。” + +“一直都……”男人重重地咽了咽口水,言语间透着些紧张,“……让你等了很久了,真是非常抱歉呢,优子。” + +“你是?”优子打断了男人的话语,似在思考,“火村……火村·夕君,没错吧!”少女像小孩子做错了什么事似的低下头抬起了眼,那双明亮的大眼睛灼灼地盯着火村,像是在等待这边的肯定。 + +和优子对视的火村的双眼里明显透露出难以置信的神色,“难道说,你已经忘记了…关于我的事情了吗?” + +“嗯,其实呢。”少女轻轻地笑出声来,没有继续说下去。 + +“是真的忘记了吗?还是…仅仅是一时恍惚呢?” + +“就在刚才。就在刚才,想起来了。”优子调皮地一笑,露出了得逞的表情,“这个样子,总感觉和高中校园的时候正好相反呢!” + +优子仰头望向教堂的天花板,那里有圣母像的浮绘,在火村眼里,她的笑容和高中的样子相比丝毫未变。“那个夏天也好,再会也好,还有其他的一切,都已经远远而去,再也找不回了。” + +“是很遥远……很遥远。都该是几年前的事情了呢。”火村略带伤感应道。 + +一阵沉寂,两个人似乎都在回忆着自己的故事,久久没有说话,最后还是优子打破了尴尬,只听她调皮地说道:“怎么好像是老爷爷的发言呢。我们看起来都还没有老哦!” + +“你不也一样吗?”从火村的脸上第一次露出了笑容,两个人互相望着苦笑起来。 + +“那么,为什么,你要来到这里呢?”优子问。 + +“我们不是约好的吗?在这里相见的约定。”在数年前的圣诞的早晨,两人间的确做过类似的约定,但是却没有履行。“大概,一直呼唤着我的人就是你,没错吧。” + +优子微微点了点头,又摇了摇头:“说不定是这样。” + +“那么,告诉我吧。在我不在的这段时间,在你身边究竟发生了什么事?”火村向前走了一步,微微靠近优子,急切地问道。 + +“发生了什么吗……”望向火村身后教堂的门扉,优子开始找寻想要说的话,“故事的开始……” + +“会是很悠长的故事,可以吗”,优子话题一转,继续调皮地看向火村君。 + +“当然,到黎明前还有很久呢。”火村似乎也被优子逗乐了,做出我服了你表情来。 + +“那么,就让我娓娓道来吧……从去年的圣诞节夜晚开始,那个冬日的故事……” + +To Be Continued! + + diff --git a/src/content/posts/2012/2012-05-08-novel-story-1.mdx b/src/content/posts/2012/2012-05-08-novel-story-1.mdx new file mode 100644 index 0000000..c8bf8ad --- /dev/null +++ b/src/content/posts/2012/2012-05-08-novel-story-1.mdx @@ -0,0 +1,113 @@ +--- +title: 交织的羁绊 - 初遇与未来 +slug: novel-story-1 +date: 2012-05-08 01:47:52 +updated: 2020-09-06 12:05:07 +tags: + - 悠久之翼 + - 小说 + - 同人 +category: 小说 +summary: 音羽小镇建立于地震后的废墟之上,在小镇的边缘有一个废弃已久的车站,是音羽镇在地震后存留下来并且保存完好的事物之一,对于几乎被地震完全毁坏的音羽小镇来说,不得不说是一个奇迹。 +cover: /images/2011/07/2011070220190200.jpg +--- + + + +<MusicPlayer netease={527794} /> + +音羽小镇建立于地震后的废墟之上,在小镇的边缘有一个废弃已久的车站,是音羽镇在地震后存留下来并且保存完好的事物之一,对于几乎被地震完全毁坏的音羽小镇来说,不得不说是一个奇迹。由于早就没有列车从这里经过,车站外已经生锈发黄铁道上布满了杂草。月台上不知何年树立的站牌上布满了斑驳的苔藓,上面的字迹也被雨水冲刷得依稀难辨。 + +寂寥、空旷,似乎这里已经被人遗忘。对于莲洽来说却是他最喜欢的地方,安静、没有车流的小站,最适合一个人静静地看书、思考,不受外人的打扰。 + +像小时候一样,莲洽踩着铁轨,一边伸开双臂保持平衡,一边向着车站前进。此时已经是黄昏时刻,太阳早已收敛了一天的炎热,仅留下点点余晖染红了远处的半边天。绚丽的云彩、布满天空的火红色,总是会让人忍不住驻足观望。而对于莲洽来说却似乎没有那个心情,此时的他正尴尬地站在站台的角落,不知怎么是好。 + + + +原本应该空无一人的车站今天却有了一位客人捷足先登了,在站台上备置候车的长凳上,正坐着一位少女,少女高高地昂着头,仰望着远处依旧灿烂的晚霞。傍晚的空气略带点阴冷,而少女保持着毫无防备把喉咙暴露在外的姿势,看上去就像是深深沉醉于景色之中,对此刻正不知所措站在她身旁的莲洽毫无察觉。 + +莲洽呆呆地凝视着少女,大概是这样的景象实在是太美了,油然而生出一份“不应该打扰到她”的想法。在转身离开之前,莲洽好奇地顺着少女的角度去仰望那片天空,希望发现有什么特别的地方能让人凝视那么久。可是,从少女的角度看过去,什么也没有。只有一成不变的天空在那,秋季的晚霞像是象征着寒冷一样传达着寒意。“也许少女那样仰望天空发呆有她的意义吧”,这样想着莲洽从天空中移回视线,却发现,不知什么时候起,少女已经翻过身来盯着自己看。夕阳倾洒在她的身上,反射出朦胧的光晕,让人恍惚间有一种不真实感觉。 + +红色略微泛紫的发丝,调皮地在左耳间挽了一个小发辫。忧郁微蹙的眉峰,左眼不知怎么了,用白色的眼罩遮住,是患有眼疾吗?而看向莲洽的右眼是那么的纯净,仿佛只需简单一瞥,便可以看见倒映在里面的天空。少女身着一身略带保守的连衣长裙,但是鞋边的卡通装饰和放在身旁的粉色小猪背包却暴露了藏于心中的少女情节。到了这时,莲洽才回过神来,思考接下来该怎么办的问题。 + +“这……这个车站,是没有电车的。”莲洽不大自然地笑着对她说道。 + +少女一愣,眼神中露出迷茫的表情:“诶?”本来随口敷衍的一句话,却被少女如此认真的回应了。 + +莲洽连忙尴尬地摆了摆手,感觉此时的自己就像是一个小丑,在那么纯真的眼神面前竟不知如何是好,匆匆回了句:“对不起,没什么。”对话并没有继续下去,本来就没有继续下去的话题,这是理所当然的。“对方先来的,应该离开的是我吧……”莲洽在心里这样想到。 + + + +习惯性地抓了抓头后,莲洽继续表情抽搐地对着少女说道:“那么…再见了。”举起右手轻轻挥了挥,转身便跑。 + +少女看向莲洽轻轻地嗯了一声,虽然还带着一脸的茫然,但很快就像是知道了什么的样子,捂起嘴浅浅地一笑,又挥了挥她纤细白皙的小手,目送着莲洽的远去…… + +就这样,莲洽和月台少女的相遇结束了,在这个平凡的秋日,一次不足45秒的邂逅…… + +一阵带有丝丝凉意的清风拂过月台上的长椅,拨动了放在少女身旁的小猫笔记本。只见翻开的那页上面写着:“坐在车站的长椅上时,来了一个穿着学生服的男孩子,说了些奇怪的话就马上回去了。” + +简单、平淡的邂逅并没有在少女的日记中留下多少记录,既不让人吃惊,也不具有戏剧性的相遇,或者是命运般邂逅的预感——之类的话语也没有被写进日记里。但是,谁又能知道命运的未来丝线将要缠向何方? + + + +白云在天空缓缓飘移,大朵大朵,宛如层层叠叠庞大的宫殿。而那些穿梭在云朵间隙里的阳光,迫不及待地穿过窗外花坛中的树林,在教室内的地板上斜射下一道道的“光柱”。光束里面上下浮动的尘埃飘絮,在空气中反射出若有若无的辉光,像是在等待一个还未开始却已经进行了的传奇。让人仿佛坠入了宫崎骏的动画里那些大段大段的让人心痛的美好时光。 + + + +距和少女的相遇到现在,又一个星期过去了。已经到了下午放学时间,除了社团的活动外,大部分的学生都陆陆续续整理好书包走出音羽高中的校门。二年级一班的教室里的人越来越少,随着当天值日的学生的离开,教室中只剩下一个孤零零的身影还坐在左斜后方窗边的那个角落上。窗外,操场上的喧哗声越来越小,整个空间里充斥着令人不忍打破的静。寂寞和空虚将这个小小的身体重重包裹,让人喘不过气来。某一刻,窗外刮起了一阵轻风,吹动了那个孤小身躯手中所拿的一张纸,啪啪作响,打断了还在沉思的他…… + +每个少年的心中都曾有过这样的幻想:希望有一天能有让自己成为特殊人物的事情,或是某一天能遇到承认自己有才能的契机。就像是童年的童话里面,那个为了保护公主,历经无数战斗的王子。但是,儿时的童话般的梦想终究不可能成为现实,随着年岁的增长必将做出新的决定。亦如此刻坐在角落的麻生·莲洽。 + +下课前10分钟,班主任发下来一张《未来志愿调查表》并交代下个月初上交。手拿这张即将决定自己一生的薄薄的纸张,才上高二的莲洽陷入了苦思之中。想起最初的幻想,莲洽苦笑地摇了摇头,“不像是儿时所见的那些未来梦想那样,而是必须要决定未来了。想成为保护公主免受灾难的王子,却早已经错过那班梦想的‘班车’。那么,我的未来该做啥呢?” + +此时的十一月初的秋天已经略微有些深度了,投映在室内的阳光洋洋洒洒地照射在莲洽微卷的亚麻色头发上。望着窗外花圃里缓慢落下的梧桐叶儿,莲洽的眼神里更多的是一份迷茫。光线将他脸上细微的毛孔照得发亮,反射出一阵微光。像是把他整个人都笼罩在那层薄光里,空气中弥漫着暖暖的阳光的温香。 + +纸张被风晃动的响声惊醒了还在思考的莲洽,望着手中那张已经捏得发皱的调查表,深吸一口气。再次抬头望向天空,清澈透明的蓝天,深秋的天空看上去是那么的低沉,却始终无法伸手触摸,“不过,确实到了该好好确定将来的时期了呢!”莲洽像是说着与自己无关的事情一样轻声嘟哝着,“话说到现在的我还真没什么紧张感呢,还是与往常一样,一直在原地徘徊不前呢。要不试着拿这些像是别人的事情一般的自己的事情,去听下别人的意见吧。”莲洽这样想着。整理好散乱的书包,揉了揉想得发胀的额头,走出了教室,踏上那条通往校门的大道。这是一条长年落满树叶却无比干净的道路,每次莲洽踏足这里的时候,总是会看见不经意间落下的翻舞的树叶,一片一片缓慢得就像一幅静止了千年的画面,隐藏着许许多多说不清道不明的结局与开始,让人听不到它的述说,却能感受到那种异样的莫名迷茫。 + + + +“这就是你来找我的原因吗?”含糊的声音在宽广的空间中回响,这里是坐落在住宅区一角的教堂,虽然室内肯定是密封的,但是窗户很多,天花板也太高了,里面相当寒冷,或者说,总感觉有风在从某处的缝隙中灌进来。 + +“真的好冷啊!”莲洽嘟囔道。 + +“喂,你在听吗?莲洽。”面前的人有点不满地问道。 + +“诶,当然有在听。”他的声音比刚才还要低沉,莲洽不由得慌了神,把视线和意识都集中到他身上,“是关于前途的问题,想来征询一下大人的意见。” + +“……这样啊。”眼前的男子带着点惊讶地点点头,细细地眯起眼睛,“这本身倒是没什么,也不一定,到不如说,问题是,你为什么会跑到我这里来?” + +“自己似乎也不是很清楚。”莲洽轻轻地叹了口气,答道:“不知不觉呢。” + +教堂的男子有点无语地问道:“你没有朋友吗?” + +莲洽有点尴尬:“这……两者之间有关系吗?” + +他环抱起双手道:“我并不是神父,也不是作为志愿者在这里开导人。”他有点无奈地嘟哝着,全身上下都穿着纯黑的服装,虽然有点神父的模样,不过他的言行确实和教会不相符,就像外表第一眼看上去,倒像是个很难与之交流的数学老师。 + +这个男人——火村·夕,既不是宗教相关人士也不是咨询师。不仅如此,莲洽连他的年龄、职业、经历完全不清楚,虽然已经和他像这样交谈过很多次了,实际上并不了解他的详细情况。不过其貌似一直在教堂里闲晃悠,不知不觉间火村似乎已经被莲洽判定为同年龄的人可以倾述和商量的对象了。 + +“总是呆在这样的地方里,也难怪我会来找你商量啊。”莲洽回到之前的问题。 + +“这样的地方?”火村有点疑惑。 + +“因为是教堂啊,总会有抱着一两个烦恼的人来的吧?”莲洽解释道。 + +火村耸耸肩,摊开双手:“这个比较也太牵强了吧。”继续摆出一副无奈的表情。 + +“不过商量啊,你才读高中二年级,最近学校弄这种事情还真是早呢。”火村说道,“那么,也就是说,如果已经决定了想成为什么人的话也就没有商量的必要了呢。”他轻瞟向莲洽,双手环抱在胸前,“有没有什么拿手的事情或者喜欢做的事情呢?” + +“诶?喜欢的东西?”莲洽一愣,仰着头想了想,“大概…嗯…是读书吧。喜欢小说之类的。拿手的,倒是没什么了。” + +“那么这就对了!”火村斩钉截铁地提议道,“去文科大学,毕业后从事出版相关工作,自己写小说也可以。” + +一阵无言……“诶?说完了吗?”莲洽先打破沉默。 + +“说完了,这样不就行了吗。”火村平淡地说道。 + +“……不是,虽然是这样没错。”莲洽对他那冷淡的忠告皱起了眉头,“把喜欢的事情当成工作是不是有点太武断了?” + +“比起做自己不喜欢的工作,可好上千倍了吧!别烦恼了,自己考虑吧!建议结束,如上…是大人的意见。”说完,火村把手往前一指,低下头,不再搭理莲洽。 + +“大人的意见?”莲洽一边思考一边转身离开,“似懂非懂,总得自己做决定吧。虽然说起来……这么简单。” + +To Be Continued! diff --git a/src/content/posts/2012/2012-05-10-novel-story-2.mdx b/src/content/posts/2012/2012-05-10-novel-story-2.mdx new file mode 100644 index 0000000..f16dc09 --- /dev/null +++ b/src/content/posts/2012/2012-05-10-novel-story-2.mdx @@ -0,0 +1,147 @@ +--- +title: 交织的羁绊 - 明天再见 +slug: novel-story-2 +date: 2012-05-09 17:40:08 +updated: 2020-09-06 12:05:46 +tags: + - 悠久之翼 + - 小说 + - 同人 +category: 小说 +summary: 走出教堂大门的莲洽“嗖”地抽了一下鼻子,深秋的季节要说冷也确实很冷,在空旷的教堂中尤为明显。仰望布满云丝的绯色澄空,在清风的吹拂下感觉尤为舒畅。 +cover: /images/2011/07/2011070220190200.jpg +--- + + + +<MusicPlayer netease={527785} /> + +走出教堂大门的莲洽“嗖”地抽了一下鼻子,深秋的季节要说冷也确实很冷,在空旷的教堂中尤为明显。仰望布满云丝的绯色澄空,在清风的吹拂下感觉尤为舒畅。对于莲洽而言本来是为了理顺心情才来这里的,现在却感觉一直在无关痛痒的地方伤脑筋。“成年人”的意见,莲洽总觉得似懂非懂,但是说到底,这些东西还是要靠自己决定。“现在又该做什么事呢?已经没有其他的可做的事了,但也不想这么快就回家,还是找个地方让头脑稍微冷静下比较好吧!”莲洽低下头摸了摸放在胸口准备在月台上阅读的小说,很自然地向车站走去。但是,说到底,除了自然之外,也同样抱着一点期待的吧。那个女孩子还在吗? + +时间的铁轨呼啸而过,未知的未来在前方等待……像是印证了莲洽的想法般,当莲洽来到车站时,眼前的情景简直如同时光倒流般熟悉。少女依旧坐在长椅上,呆呆地望着此刻太阳落山后变得色彩斑斓的天空,像是在等待着什么东西一样。和第一次初见的时候一样,莲洽尴尬地站在月台的边缘,一阵无言。 + +“该怎么办?自己先去搭话会很奇怪吧。但是要是就这样回去心里却会觉得有点不甘心。”当莲洽还在踌躇的时候,少女被莲洽遮住的阴影所注意,转过头来看向莲洽。“呃……” + +“呀,你好。”莲洽拘束地打着招呼。呆了一拍之后,少女轻轻别过了头,似乎有些怕见到生人般。只用着眼角的余光偷偷地看着莲洽,小声地打了声招呼:“你好。”她像是害羞似的看着她膝盖上放着卡通小猫记事本。 + +“我打扰到你了吗?”莲洽小心地问道,虽然是深秋,但额头间已经微微冒出了汗丝。 + +她依旧是小声地答道:“没有。”简短的回答,总是给人一种陌生的感觉。只见少女匆匆地合上了那本一直放在膝盖上的笔记本,似乎害怕别人看到里面的内容般小心。从莲洽的角度来看,少女的头发和眼罩的带子随风飘动着,外貌上,应该比自己还小一两岁吧。不过,却没有给人留下应该与她年龄相符的可爱的印象,与其说漂亮——不如用端庄来形容吧。因此,即使那只眼罩看上去很显眼,但是很不可思议的并没有损害到少女的养眼度。玩具娃娃般无暇的容姿中,那份不协调的部分反而像是她确实存在着的证据一样。 + +“那个,我可以问你一个奇怪的问题吗?”在偷偷看了莲洽好久后,少女微微转过身来,稍微歪着头,看着莲洽。“你以前和我见过面吗?” + +“呃?”大概是这个问题太突然了,莲洽有些不知所措,但很快便反应了过来:“嗯!” + +“是这样吗?对不起!果然我们是见过面的呢……”少女急急忙忙地说着,生怕对面的莲洽会生气般。但声音越来越小,越来越小,直到细不可闻。 + +“这个…其实也只是一面之缘而已啦。”莲洽略带说笑的语气解释道,希望稍微缓和两人间冷寂的气氛。 + +“好像是呢。”她说话方式很直率,只是,让人总觉得措词很奇特。 + + + +“嗯。”之后便是久久的沉寂,夕阳渐渐落下的地平线,天空也逐渐阴沉下来…… + +“两个人之间果然没有什么可以说的话题呢,该怎么办?”莲洽突然着急起来,“糟了,明明很期待她在这里的,却完全没有考虑过见到她后要怎么做。原本远远地看上一眼,再感叹上一句‘好可爱的女孩子啊~’就够了,我为什么还要站到她面前来啊!” + +莲洽无意义地动了好几次嘴巴,还是什么话都没说出来,额头上的汗迹越来越明显…… + +“那个?”最后,还是少女先开了口,打破了寂寞。 + +“啊,什么?”莲洽有些慌忙地抬起头来,望向少女。只见她不知什么时候起已经站起身来面对着莲洽,双手拿着笔记本垂在身前,似乎有些紧张地看着莲洽。 + +“请问,你经常来这里吗?” + +“嗯,只是偶尔来这里啦。” + +少女,低下了头,恢复了开始的平淡的语气:“这里很安静,是个好地方。” + +“是呢,这里可是个得天独厚的读书场所呢。”莲洽接过话说道,双手交叉在胸前,“而且还能正大地体验‘STAND BY ME’哦。” + +“哎?”少女诧异地诶了一声,眼神中充满不解。莲洽自嘲地笑了笑,解释道:“就是在铁路上走啦,因为在这里玩的话不会被人骂嘛。” + + + +少女先是一愣,但很快便懂了我的意思,第一次笑了起来:“啊,原来如此,好像很有意思呢。” + +少女手捂着嘴微微地笑着,原本暗淡的傍晚车站似乎因为她的笑容变得明亮起来。晚霞的余晖弥漫在少女的身上,似乎反射着亮丽的色彩。莲洽也被少女的微笑所吸引,就这样直愣愣地盯着少女的面庞,再也挪不开眼睛。 + +“千寻。”少女突然说道。 + +“额?”莲洽一呆,从刚才的发愣中回过神来。 + +“我叫千寻,名字是新藤·千寻。狮子会把孩子推进千寻的山谷里面的那个千寻。”少女如陌生人般冷冰冰地说道,仿佛刚才的微笑都是幻影般不存在。 + +“千寻?啊,那是你的名字吗?”莲洽有些慌乱地回答她,“我叫麻生·莲治。”似乎还在为刚才的着迷尴尬。 + +千寻默念道:“是麻生吗?” + +“嗯。”莲洽笑道,“叫我麻生也好,莲治也好,怎么都可以。” + +千寻稍微垂下头:“就称呼为麻生先生吧。”受到她优雅的微笑影响,莲洽也露出了微笑,仿若就在这一瞬间两人间的距离逐渐消失。 + +“终于有话可说了。”莲洽这样想到,又稍稍转移了话题:“说起来,千寻还真早呢。” + +千寻抬起头好奇地问道:“早?” + +“嗯。”莲洽应道,“上次你也是比我早来到这里的啊。” + +“那是,因为我没有去学校上学……”千寻平静地说道,但是因为紧抓笔记本而微微发抖的双手却出卖了她内心的不安。 + +“你……没有去……学校吗?”莲洽对于少女的回答不知所措,原本交叉于胸前的双手也放了下来,略带僵硬地回复着。 + +“是的。” + +“啊,这样啊。”虽然莲洽很在意是怎么样的情况,但还是不好意思对一个才认识几分钟的女孩问出口,只好抓了抓头发,继续习惯性地应道。 + +“嗯……” + +两人间一阵无言,对话到此为止了,又回到了开始时像是在春天黄莺即将鸣叫前的沉默。天边的晚霞也渐渐阴沉下来,傍晚的冷风呼呼响起,似调皮的手指般划过两人的发梢,吹动了彼此的发丝、少女的裙摆,在这寂寥的暮色中尤其显得静…… + +“对不起。”千寻突然这样说道,从长椅那走了过来,“我马上就要回去了,请不要在意。” + +“呃?怎么了?”莲洽继续着今天已经无数次的发愣。 + +千寻依旧向着莲洽走来,微垂着头,“这里明明是麻生的地方,我在这里会给你添麻烦吧,觉得你好像有点平静不下来的样子。” + + + +和想象中原因不大一样,莲洽如释重负地松了口气,但也因为差太多被惊到一下。对于千寻的认真感觉到十分想笑,但是此刻却不是笑的时候。莲洽急忙地说道:“完全不是那么回事,我也在考虑和你同样的事情呢!我在想,是不是因为我在这里,让千寻不能安静地读书。”莲洽几乎是大声地说出这些话来,因为着急,双手紧紧地攥成了拳头。 + +“差不多的事情?”千寻有点惊讶,停住了脚步看向莲洽。此刻的千寻完全从车站的阴影中走了出来,两人就这样相隔不足 1 米地面对面站着,稍稍一愣,却又彼此都像是恍然大悟般笑了。笑声穿越了暗淡的暮色,久久地在空旷的车站回荡…… + +此刻的莲洽清楚地看到,千寻的脸颊红了。这么可爱的千寻真是不可思议的女孩子,有着洋娃娃一般的笑容,也能清楚地表达自己,却又像个孩子一样容易把玩笑当真,一会儿赌气一会儿又会害羞。就像是把内容和包装弄错了的生日蛋糕一样。 + +望向已经黑了下来的天色,莲洽突然意识到还在家等自己吃饭的母亲,“——啊,糟了。天色不早了,我要回家吃饭去了。” + +“啊,是这样吗?”千寻问道。 + +莲洽轻轻嗯了一声,本想说“其实还想和你多说会话的”,但是却没有把这句话说出口的勇气——“你家在这附近吗?我顺路送你吧。” + +“那个我想待在这里。”千寻又坐回了长椅上,半个身影隐没在月台的黑暗中,看不清脸上的表情。 + +“可是,天已经黑了啊。”莲洽有些奇怪地问道。 + +“我想待在这里。”千寻的话语透着一丝坚决,黑暗中模糊可以看见她如开始一样抓紧了手中的笔记本…… + +“这样啊。”莲洽有些失望地转开身,准备离开。 + +“那个!”千寻突然抬起头叫了一声,有些害羞地问道,“我……还可以来这里吗?”说完便又垂下头别过身子,就像是受委屈的小猫般。 + +“当然可以啊。”莲洽转过身来,激动地说道,似乎在为下次能继续邂逅而高兴。 + +只见千寻如释重负地松了一口气,高兴地笑出了声道,“非常感谢。” + +“啊,哪里哪里,不用客气的。”虽然不是很明白,莲洽还是反射地回答了,“那么,明天见。” + +千寻小声地啊了一下,在阴影中隐约看见,肩膀猛地抖动了一下。莲洽有点担心地问道:“怎么了?” + +“没事……明天……见。”千寻稍微有点颤抖地回答着,轻轻地向我挥了挥手,那样子真的非常可爱,对于长这么大还没怎么和女孩子搭讪的莲洽来说,完全已经脸红了。匆匆道别,莲洽转身便离开了车站。 + + + +黑夜终于降临了大地,各家各户的窗户前也亮起了灯光。莲洽回身望向来时的车站,少女的身影已经完全与黑夜融为一体,再也无法分辨了。 + +明天、将来、未来,谁又能知道命运之神的双手将要将你引向何方?那么,明天,还能再见吗? + +To Be Continued! diff --git a/src/content/posts/2012/2012-05-12-mothers-day.mdx b/src/content/posts/2012/2012-05-12-mothers-day.mdx new file mode 100644 index 0000000..1117c00 --- /dev/null +++ b/src/content/posts/2012/2012-05-12-mothers-day.mdx @@ -0,0 +1,43 @@ +--- +title: 妈妈,母亲节快乐 +slug: mothers-day +date: 2012-05-11 17:06:31 +updated: 2020-09-06 12:07:33 +tags: + - 回忆 + - 母亲节 + - 妈妈 +category: 杂思 +summary: 对于母亲总有一种深深的愧疚感。小时候记事还很模糊的时候,父亲便下海了。所以,童年的绝大多数时间,妈妈就是家里的顶梁柱,为我支撑着小小的半边天。 +cover: /images/2012/05/2012051121064800.jpg +--- + + + +<MusicPlayer netease={459069} /> + +亲情,是最不需要刻意修饰的词,简单的话语,却是最能表达心中的爱。 + +—— 题记 + +对于母亲,总有一种深深的愧疚感。小时候记事还很模糊的时候,父亲便下海了。所以,童年的绝大多数时间,妈妈就是家里的顶梁柱,为我支撑着小小的半边天。小时候调皮、打过架,每次当别人父母找到家门告状的时候,母亲就会显得十分弱小。 + +一直以来,母亲对我都是恨铁不成钢的。小时候各种打架,初中时迷上了网吧、抽烟。直到高中时才幡然醒悟,开始用功读书。有时候不忍心回想,在这么漫长的日子里,妈妈为我掉了多少泪,说了多少唠叨。那么多让人揪心的眼神,为何自己在那时迟迟没有体会? + +现在的我总想为“你”写点什么,却总是搁笔,也许明天会有更多的时间。 + +总想和“你”说点什么,却总是迟疑,也许明天会有更好的措辞。 + + + +坐火车上学的时候,同桌是一位抱着小孩独自去济南探亲的母亲。在那么漫长的一段旅途时光里,我看到这位母亲几乎一直没有休息,一会儿要看孩子的包被有没有裹好,一会儿又要喂奶,一会儿又要哄小孩……恍惚一刹那间,我回想起在厦门忙碌工作的母亲,突然就眼泪掉下来…… + +去上海游玩,回来的路上和一个同样无座的新疆人聊天。他是当兵退伍的,讲到自己的母亲的时候,这位硬汉的眼眶湿了。他有些沙哑地说:“今年过年的时候我给家里汇了 5 万块,后面我妈妈就打电话给我说,‘孩子啊,你汇这么多钱干嘛,我们老人家又花不了这些钱。’我说,‘你们拿去用,就算是我孝敬你们的。’”当时,这位新疆人的兜里只有 500 元,过年是回不去了,他却忘不了自己母亲对自己的照顾,将积蓄全部寄回家…… + +有时候,想想自己,真不是个东西。上了大学两年了,和家里通话的次数,屈指可数。更多的时候,都是在月末没钱的时候,才想到给家里打个电话。而母亲节这种日子,如果不是看到松树哥哥的文章,我几乎快要遗忘。 + +昨天晚上,第一次主动给妈妈打了个电话。听着电话那头安静的话语,熟悉的关照,第一次觉得是那么的安心。也许现在的我无法给予母亲什么回报,但是,那份血浓于水的亲情,却是我心中永远不能忘却的情怀。 + +在这个世界母亲的节日里,我想说:“妈妈,节日快乐。” + + diff --git a/src/content/posts/2012/2012-05-12-one-more-time.mdx b/src/content/posts/2012/2012-05-12-one-more-time.mdx new file mode 100644 index 0000000..19b5ff3 --- /dev/null +++ b/src/content/posts/2012/2012-05-12-one-more-time.mdx @@ -0,0 +1,50 @@ +--- +title: 樱花般的记忆——秒速5厘米 +slug: one-more-time +date: 2012-05-12 13:37:01 +updated: 2020-09-06 12:10:20 +tags: + - 樱花 + - 情感 +category: 杂思 +summary: “呐,你知道吗?听说樱花飘落的速度是秒速五厘米哦。”秒速 5 厘米,那是樱花飘落的速度。那么怎样的速度,才能走完我与你之间的距离? +cover: /images/2012/05/2012051221344000.jpg +--- + + + +<MusicPlayer netease={1310906134} /> + +“呐,你知道吗?听说樱花飘落的速度是秒速五厘米哦。” + +秒速 5 厘米,那是樱花飘落的速度。那么怎样的速度,才能走完我与你之间的距离? + +每个男孩都会有一个暗恋着自己却婉言拒绝的女孩,也都会有一个深深喜欢却已嫁作他人妻的女孩,最后还会有一个没什么感觉却要相濡以沫的女孩。 + +—— 题记 + + + +让命运的时钟拨回 1990 年的日本,那时远野贵树与篠原明里还是同班同学兼好朋友,彼此间有着朦胧的爱意。但是小学毕业之后,两人入读了不同的初中。分隔两地的两个人,靠着书信往来保持联络,直到贵树知道即将跟随家人搬到鹿儿岛,距离明里更远的地方,于是两人约定了再见面的时间。计划好的行程,却遇上了暴风雪,电车在漫天飞舞的雪夜走走停停,贵树的心也在细微的变化…… + +光阴的流逝,转眼间都已长大成人。曾几何时,彼此约定好要共赏樱花,时至今日,擦肩而过,相遇却如陌路人。影片的最后一幕:一样的铁道闸口、秒速五厘米的落花速度、似曾相识的两个身影,微风依旧,花香不变,唯一不同的只是那咫尺天涯。 + + + +对于贵树而言,在过往数年里,一直只想着先往前走,想要触及某种遥不可及的事物。但连那具体的目标是什么,以及那几乎可以称作威胁一样的回忆是从哪里涌现出来的都不知道……只是不停地学习着、工作着,直到某一天,他突然意识到,那渐渐失去“弹性”的心原来是那么的痛苦。于是此时的贵树才恍然察觉到,曾如此真切的感情就这样干干净净地消失殆尽! + + + +那是属于两个人的雪夜,属于两个人的樱花树,属于两个人的誓约——“来年一起赏樱花”,过去的一切随着时间的流逝而随风飘扬。而时间和空间真是个可怕的东西,曾经的相信永远,到头来都是苍白无力的偏执。明明手机里面存储的全是未发出去的短信,明明心中惦记,却已陌生到无法表达……心中的那份寂寞、那些许的迷茫,影响不仅仅是自己……“即使发了一千条短信,心与心的距离也仅仅接近了一厘米而已。”无法接受他人,即使光阴荏苒,即使咫尺天涯,即使誓约、感情都消失殆尽。而潜意识中却一直记得,在时间与空间交织而成的广阔无际的世界中,与我人生速度相同的仅仅一人,那速度恰恰是——秒速五厘米。 + + + +其实在最后的那一刻,回头与不回头已经显得并不重要。虽然也许两人的距离仅仅是五厘米,但是两人已经不再拥有儿时的纯真,不再拥有彼此默契的人生速度。长长的轨道上,曾经的奔跑、誓言都已经随风而逝。如今两人背道而行,飞驰而过的电车阻断了两人的视线,即使那仅仅只有五厘米…… + +列车过后的樱花,是一切的开始,也是一切的结束。在无法逾越的时间与空间中,任何事物都会被淡忘。唯一不会忘记的只有那缓缓飘落的承载着人们无数回忆的樱花,而它飘落的速度永远都是秒速五厘米。 + +One more time, one more chance。可是世界上哪来的那么多的时间,哪里能有没完没了的机会?无论何时,过去的只能成为过去。应该以怎样的速度度过人生,才能与你重逢?这个问题甚至超越哥德巴赫猜想,成为世界上永远无法解决的难题。即使还是以相同的秒速五厘米前行,不再拥有默契的人生交集也是毫无意义,相濡以沫,不如相忘于江湖…… + +**后记:** + +多年以后,物是人非。曾经的青梅竹马,曾经能够为彼此真心付出的人,最后,只剩下学生时代幸福又有些遗憾的回忆。樱花飘落的时间,秒速 5 厘米,美丽又短暂……不论愿不愿意,只要随着风的舞动,樱花们就会翩翩飘落,一直持续着这短暂又美丽的一瞬间。最后,都将归于尘土。然而,来年春天,会有新的花瓣飘落,永不停息。樱花虽然落下了,但我们还要继续向前走,时间与距离,可能只需一秒一步之遥,也可能耗尽一生都追逐不到。如果不曾拥有,又何来若有所失的感觉?秒速 5 厘米,表面上看是一部很压抑的动画,但请不要忘记樱花飘落时的美丽,来年我们可以再看见它们。人生的路还很长,也许,新海诚带给人们的一直都是希望…… diff --git a/src/content/posts/2012/2012-05-13-essay-of-spring.mdx b/src/content/posts/2012/2012-05-13-essay-of-spring.mdx new file mode 100644 index 0000000..a8697a6 --- /dev/null +++ b/src/content/posts/2012/2012-05-13-essay-of-spring.mdx @@ -0,0 +1,29 @@ +--- +title: 怀旧,春之随笔 +slug: essay-of-spring +date: 2012-05-13 07:29:38 +updated: 2020-09-06 12:10:28 +tags: + - 回忆 + - 暖春 + - 生活 +category: 文章 +summary: 夏日的炎热让我不由得怀念才过去的暖春,那个欣欣向荣的季节,无意中翻出一篇关于春天的“记忆”,发在这里,仅作回忆…… +cover: /images/2012/05/2012051421440600.jpg +--- + + + +<MusicPlayer netease={28411043} /> + +> 夏日的炎热让我不由得怀念才过去的暖春,那个欣欣向荣的季节。无意中翻出一篇关于春天的“记忆”,发在这里,仅作回忆…… + +再一次回到温暖的午后,我打开窗户,一阵春风拂面而过,带着淡淡的花香,清新的泥土味如同刚揭开西瓜般的新鲜。突然看到书上枝头蹦出的那只鸟,预示着 2006 年春天的来临。我很喜欢这样的感觉,没有孤单,没有压力,只要闭上眼睛静静地享受,就能打开春天独有的无限想象。同时也让我打开回忆,回忆 2005 年所经历的点点滴滴,有酸、有甜、有苦、有乐。 + +和所有人一样,对未来我有着美好的憧憬,有着些许担忧,但更多的还是期盼。曾有人说,伤感的人会因为一片叶子而产生对于秋天的怀念,会因为一场雨而勾起对某人的思念,会因为一个平淡的生活细节而不能自已。能体会这样的感觉,复杂的思想、丰富的情感,占据了你的整个思维。或许是过于苛求完美,一直被认为苛求完美的人是肩负着痛苦,敏感的人是继承脆弱,甚至是说孤独的人保守着精神上的寂寞,在常人眼里那都是不可能的。 + +安静的我喜欢独自在家,过着平淡安逸的生活,自然成为一种规律,不喜欢僵硬感,只喜欢简单。其实生活就像连绵不绝的流水,平淡无奇。尽管生活如此,但各自储蓄着不同的内涵。平淡的日子如同白开水,虽然淡而无味,但偶尔能品出清甜。就是这种淡淡的感觉,让我感到踏实与安慰。能享受到粗茶淡饭里的天长地久,拥有平平淡淡中的花好月圆…… + +2006 年 3 月,那个草长莺飞的日子 + + diff --git a/src/content/posts/2012/2012-05-14-my-grandpa.mdx b/src/content/posts/2012/2012-05-14-my-grandpa.mdx new file mode 100644 index 0000000..6dc0aac --- /dev/null +++ b/src/content/posts/2012/2012-05-14-my-grandpa.mdx @@ -0,0 +1,41 @@ +--- +title: 斯人已去 +slug: my-grandpa +date: 2012-05-14 12:54:52 +updated: 2020-09-06 12:11:01 +tags: + - 回忆 + - 亲情 + - 爷爷 +category: 文章 +summary: 写下这个题目的时候,脑海中突然浮现出小时候看《狮子王》时印象很深的一句台词:“当你孤独的时候,就看天上的星星,每颗星星都是离开我们的国王,这些国王都在看着你。”那么,爷爷,今夜天空中的那颗最大最亮的星星是您吗? +cover: /images/2013/09/2013092121155300.jpg +--- + + + +<MusicPlayer netease={27538413} /> + +写下这个题目的时候,脑海中突然浮现出小时候看《狮子王》时印象很深的一句台词:“当你孤独的时候,就看天上的星星,每颗星星都是离开我们的国王,这些国王都在看着你。”那么,爷爷,今夜天空中的那颗最大最亮的星星是您吗? + +—— 题记 + +这些年假期住在厦门,突然很不想出门闲逛。 + +每当我看到老人在胡同里的大榕树下面喝茶、下棋、晒太阳,或者是在公交车上给老人让座的时候,我总会想到我的爷爷。他走了,走得那么匆忙、那么无奈、那么不舍。让我这个做孙子的还没有来得及孝敬他,他就因病去世,带着 60 岁的生命,离开了这个世界…… + +记得小时候,我常和爷爷在一起说话,每当谈到梦想的时候,我总说我要考上大学,做我们盛家的第一个状元。冬天天气寒冷,爷爷的身体也是冷冰冰的,自己也曾说:“我要做爷爷的小暖炉,给爷爷暖床。”可是这些一切还都没实现的时候,爷爷便走了…… + +我是在高考前一个月被夜里爸爸的电话惊醒的,接到爷爷不行了的噩耗,我匆匆从学校搭着长途汽车往家里赶。山路弯弯,车辆颠簸,可我心里却交织如麻。可是,上天为什么这么残酷,为什么连爷爷的最后一面也不让我见到?当我赶到家的时候,爷爷已经悄然闭上了眼睛,只见到爷爷已经瘦得不成形的遗体,静静地躺在太平间里。我小声地哭着,喊着爷爷的名字,可是已经迟了。 + +总是不敢想,4 月初回家的时候还谈笑风生的爷爷,那个常在电话里声声叮咛的爷爷,就这样永远地失去了。 + +说好的,等我考上大学给您看呢? + +还没实现的愿望,还没报答的孝心,还没得到的快乐……还有太多没有及时表达的爱。都已经无法挽回了。直到今天,我都不敢在别人面前提起爷爷,忆起他的好。我怕一打开记忆的闸门,眼泪就会控制不住地流下来…… + +人们常说,十年修得同船渡,百年修得共枕眠。我相信,爷爷,我们之间的因缘,必定有很久很久。只是这缘分太浅、太短,还没相聚多久,便已缘尽。今夜遥望星空的时候,我想到了您,天上人间,我们永远在一起。 + +下辈子,还做您的孙子。 + + diff --git a/src/content/posts/2012/2012-05-16-your-city-my-dream.mdx b/src/content/posts/2012/2012-05-16-your-city-my-dream.mdx new file mode 100644 index 0000000..7b4083e --- /dev/null +++ b/src/content/posts/2012/2012-05-16-your-city-my-dream.mdx @@ -0,0 +1,61 @@ +--- +title: 他的城,我的梦 +slug: your-city-my-dream +date: 2012-05-16 08:06:53 +updated: 2020-09-06 12:11:38 +tags: + - 梦想 + - 上海 + - 游记 +category: 文章 +summary: 像梦一般短暂的 4 天上海之行结束了,我不知道应该以怎样的心情来回望这一段时光。就像是一只旅行的蜗牛,满怀欣喜抑或安之若素。颠簸的火车、匆匆的旅程、各色的面孔,这一切的一切扩宽了我生命的轮廓…… +cover: /images/2012/05/2012051622352100.jpg +--- + + + +<MusicPlayer netease={209228} /> + +像梦一般短暂的 4 天上海之行结束了,我不知道应该以怎样的心情来回望这一段时光。就像是一只旅行的蜗牛,满怀欣喜抑或安之若素。颠簸的火车、匆匆的旅程、各色的面孔,这一切的一切扩宽了我生命的轮廓…… + +——题记 + +踏上火车的那一刻,我在心里小小地对自己说,不过就是一场短暂的旅行,无需期盼。车厢颠簸,回响着铁轨和车轮撞击的声音,窗外的天慢慢地黑了下来。13 个小时的旅途里,大部分行程就是在这样的漫漫长夜中度过。我趴在床铺上,外面是漆黑看不清的夜,偶尔一闪而逝的灯光,却会让人莫名地心安。 + +4 月 31 日早晨 8 点,穿着短袖、马裤,下了火车后迎面感受到的是一阵清冷。虽然是晚春,天气应该炎热起来,但是在高楼密布的建筑群下却还是有些冷。在麦当劳吃完早饭给家人报平安后,我们便拖着行李去昔日舍友的同学的校外宿舍。由于地铁还没有建到那边,我们坐完地铁 2 号线后,便是漫长的沿海公交之旅。听着车上人说着的上海话,看着窗外的晴天白云,我在心里小小地呐喊着:“上海,我来了。” + +我们在海事大学的门口等到了根哥舍友老 C,老 C 是和我们打 Dota 认识的,这次上海之行都是他带我们逛的。到了宿舍,安置好行李,洗漱并吃好午饭后我们便出发去玩了。 + +根哥说要去外滩玩,所以出了地铁便一路朝人民广场飞奔,从人民广场沿着福州路便可直达外滩。下午的外滩由于节假日的缘故,滨江长廊上全是游人。那些给人拍照的贩子们频频上来要做生意,但一个个都被我们拒绝了。趴在外滩的栏杆上,看着不远处的外白渡桥上的婚纱拍摄,安逸的老外躺在后面黄石公园的草坪上休息。突然觉得时光要是在这里静止就好了,因为这一切都是那么完美。 + +那天下午逛遍了陆家嘴的每一个角落,当我踏上上海环球金融中心第 98 层的时候,我才发现周身的一切是那么渺小。仲子说要给我们拍照,我说我不拍。因为,这里将成为我未来的记忆,而不是回忆…… + +晚上一直泡在网吧打 Dota,出来时已经是 11 点以后,地铁站早已停运。于是四个脏兮兮的孩子,就在这人少的夜晚在街上闲逛,寻找 KTV 包夜。走过福州路的时候无意间看见一个上海的旧弄堂,从门口望进去可以看见老式的住宅、挂满了衣物的窗台,颇具一份老上海的风味。 + +随后的两天去了欢乐谷,还逛了上海的大学城,但是都已印象不深…… + +走的那天早上下了一场小雨,雨停后走在湿漉漉的小区小路上,突然想到:似乎就要这么走了,淡淡地来,淡淡地去。挥手说再见,再见,真的会再见吗? + +坐上火车的时候再一次给住在市郊的小姨打了个电话报平安,由于忙,这次去就没能去她那边玩了。火车慢慢开动,晃荡晃荡,让人迷糊。耳机里循环播放着的,是小果的《旅行的蜗牛》: + +> 我想做一只旅行的蜗牛, +> 慢慢穿行在城市角落。 +> 我想到看到听到知道, +> 属于我的只有泥土和青草。 +> 柔软的身躯背负岁月壁垒, +> 悲伤教会我如何面对伤悲, +> 东西南北属于我的错与对。 +> 平静地在喧闹中沉睡, +> 轻松的向前自由的转弯, +> 就会有个完美的句点。 +> 习惯看云的孤单, +> 偶尔和清风做伴, +> 像只蜗牛一样慢慢走远走远…… + +火车上写下此文时,相机就在手边,却不敢再次打开回望这段旅程。迷迷糊糊间,仿若做了一场梦。 + +再见上海,再见,我的梦…… + +——2012 年,5 月 2 日 + + diff --git a/src/content/posts/2012/2012-05-19-summer-air.mdx b/src/content/posts/2012/2012-05-19-summer-air.mdx new file mode 100644 index 0000000..a2bb6e3 --- /dev/null +++ b/src/content/posts/2012/2012-05-19-summer-air.mdx @@ -0,0 +1,117 @@ +--- +title: 夏语,夏影 +slug: summer-air +date: 2012-05-18 19:48:51 +updated: 2020-09-06 12:14:15 +tags: + - 音画 + - 夏影 + - 观铃 +category: 文章 +summary: 夏天,是什么样的感觉?喜欢夏天,因为喜欢酣畅淋漓的大雨,绿意盎然的草木,还有那热火朝天的空气。 +cover: /images/2012/05/2012051822452400.jpg +--- + + + +夏天,是什么样的感觉? + +喜欢夏天,因为喜欢酣畅淋漓的大雨,绿意盎然的草木,还有那热火朝天的空气。 + +我喜欢夏日的雨,如同喜欢冬日里鹅毛般无拘无束的大雪。大雨将春夏间生机勃勃的亮丽世界洗刷的绿意盎然,雨后的空气里透着清新的凉爽,本来的燥热沉闷一齐被驱赶得无影无踪,上午阴暗的天空乌云笼罩大地,似乎夺走了我快乐的阳光。但实际上并不是这样,它拿走了一部分阳光却还给了同样价值的雨景。世界总是公平的,它拿走你些什么,必会在另一个时候还给你很多。看着一年中的第一道闪电,听着第一声响雷,享受着窗外亮晶的雨点激起的水花,不仅有一种快感。同时拥有了一场雪和一场雨,充满情趣和伤感的雨和雪,岂不是很快乐? + +夏天的空气实在是让人歇斯底里,尤其是阳光爱抚下的。如果没有这闷热的天气,想必大家必会喜欢夏天多一点,但是如果没有这天气带给你的几分焦躁不安,你又怎能体会到秋季的凉爽? + +我喜欢夏日的风,那闷热的午后不经意间感受到的微风拂面,那种在学校大海边吹拂海风的感觉。清爽、干净,让人由心底觉得舒爽。 + +但是,对于现在看博客的你而言,可能无法体会到夏季的雨、夏季的风。那么,就让下面的歌曲带你进入夏天的世界。 + +盛夏,心微凉。 + +## 夏影 + +对于熟悉日本 Key 社的人来说,一定会知道名为《Air》的这部作品。故事第一集中,当国崎往人在长堤上的微风中醒来,看见一个美丽的少女神尾观铃在海风的吹拂中展开双臂面向天空的时候,响起了我们将要聆听的背景音乐。作为神尾观铃的主题曲,整个曲风温馨纯美,带着淡淡忧伤,没有冬天里的寒冷,带着夏日里暖风的气息,让人感到安静、舒适。 + +这首歌曲也成了经久不衰的翻唱神作,知名的有 Lia 版、茶太版、西国的海妖版、二胡版等等。据不可靠统计,目前的夏影翻唱版本已达 180 种。我们无法一一列出,只好精选最具代表的几首在此倾听,细心感受那段逐渐临近的夏季的别样旋律…… + +--- + + + +<MusicPlayer netease={28151024} /> + +所属专辑:AIR ORIGINAL SOUNDTRACK + +最初的夏影版本,如前面的介绍所言,是AIR神尾观铃角色曲。每当我听起这首歌的时候,心中总会感受到一种澄澈,一种安静,那种浪漫午后闲适的情调。 + +--- + + + +所属专辑:Natukage/nostalgia + +Lia,日本女歌手,作品风格包括各种 Anime Song 在内的多种流派,此曲便是其代表作之一。Lia 创作了「natukage/nostalgia」([夏影/怀旧])两首单曲,创作动机在于当时实在没有勇气把不见得能游提升戏的销量的原创歌曲做成单曲,便将 Air 中大受欢迎的 BGM “夏影”配上歌词并演唱。于是,这首“夏影”便这样诞生了。 + +--- + + + +<MusicPlayer netease={25841794} /> + +所属专辑:Lia COLLECTION ALBUM VOL.2 Crystal Voice DISK1 + +开头便是电子钢琴弹奏的风笛声伴随的久远吟唱,给人以寂寥的空旷之感。细腻的钢琴声加上 Lia 的水晶之音,总感觉飘翔在青空之巅,那种简单的曲调总是令人舒张每一个毛孔。 + +--- + + + +所属专辑:Ma-Na + +二胡的演奏伴着电钢琴的协奏,传统与现代的交织,给人以别样的听觉享受。后半段中点缀着丝丝风铃之声,摇曳出整个静默的长空。 + +--- + + + +<MusicPlayer netease={761317} /> + +所属专辑:Re-feel Kanon・Airピアノアレンジアルバム + +在听过的各个版本中,这个版本的夏影应该算最为小清新的。没有复杂的编曲,没有多余的乐器。黑白琴键,呈现的是最纯净的夏影,最纯净的心灵音乐。 + +--- + + + +<MusicPlayer netease={761609} /> + +所属专辑:Ornithopter - AIR Original Compilation Album + +Key Sounds Label 成立之前的 CD,AIR 初回版附赠 CD,Ornithopter AIR Original Compilation Album 中收录。同样是钢琴曲,不知怎么的,听起来,总感觉少了点让人触动的东西。 + +--- + + + +<MusicPlayer netease={778324} /> + +所属专辑:B・INFINITY - Boys Character Only Image Arrangement Album + +记不清是哪个季节,在听《萌动漫》附赠的 CD 的时候,突然听到了 \~It disappears in summer\~。当时歌词本还写错了,貌似写的是同人界三大歌姬共同演唱的,后来知道只是茶太一个人。任何言语都无法形容这首歌给我带来的感受。我只知道,它将永远留在我的 MP3 里,以最无损的音质。如果没有听到这首歌,我想我就不会在那个万念俱灰的暑假,在老家的音像店把 Air 的 DVD 整套买下来,然后自己躲在屋子里从头看到尾,一边看一边嚎啕大哭。那么估计也就会更晚一些知道 Key 社,知道 Kanon 和 Clannad……从那以后,“夏影”这个词成为了我生命中的一个烙印,茶太也成了我最喜欢的女歌手之一。终于,在多年后的今天,我找到了这张 CD——Little Wing 的 \~B·INFINITY - Boys Character Only Image Arrangement Album\~。 + +夏影百首,我将非官方的第一首,毫无疑问地留给你,It disappears in summer。 + +--- + +## 观铃,回到天上去了…… + + + +> 弊社所属俳優、川上とも子儀平成 23 年 6 月 9 日(木) 16 時 45 分、かねてより病気療養中のところ、誠に残念ながら薬石効なく急逝いたしました。 +> +> 生前中は皆様に多大な応援を頂き心から感謝申し上げます。ありがとうございました。 + +2011 年 6 月 9 日 16 时 45 分,川上伦子因卵巢癌医治无效不幸逝世,享年 41 岁。 + +那羽翼飞走了,从此人间再也没有观铃,再也没有佐祐理,再也没有小光,再也没有……唯余此念,铃音回响。 diff --git a/src/content/posts/2012/2012-05-27-graduation-season-farewell-season.mdx b/src/content/posts/2012/2012-05-27-graduation-season-farewell-season.mdx new file mode 100644 index 0000000..8f1b44e --- /dev/null +++ b/src/content/posts/2012/2012-05-27-graduation-season-farewell-season.mdx @@ -0,0 +1,41 @@ +--- +title: 毕业季 · 离别季 +slug: graduation-season-farewell-season +date: 2012-05-26 20:04:36 +updated: 2020-09-06 12:14:41 +tags: + - 回忆 + - 未来 + - 毕业 +category: 文章 +summary: 绿荫满地,踩着 5 月的尾巴,离意愈浓。走在傍晚通向食堂的大路上,看见身旁一排排学长卖书的身影。恍然间觉得自己也成了其中一员,扑朔如梦…… +cover: /images/2012/05/2012052618262000.jpg +--- + + + +<MusicPlayer netease={1475596788} /> + +绿荫满地,踩着 5 月的尾巴,离意愈浓。走在傍晚通向食堂的大路上,看见身旁一排排学长卖书的身影。恍然间觉得自己也成了其中一员,扑朔如梦…… + +——题记 + +岁月的兰花指轻轻敲了一个拨弦,我恍若又看见,当年的桌椅、标语、还有永远写满字的黑板。记得 2 年前高考前的最后一节课,那一天起,我们毕业了。没有过多的言语,没有丝毫的喜悦,大家都是匆匆地收拾好书本准备明天的高考。只是在最后,不知是谁突然吼道:“这是我们高中的最后一天了。”就在那个瞬间,我的心竟莫名地开始疼痛…… + +高二的时候看见楼上的学长,在毕业的时候尽情地呼喊、撕书,就像是疯子一般让人无法理喻。当我真正成为其中一员时,我才能切身体会到那种压力完全释放了的舒张、那种渴望张扬青春的心愿和一股抹不开只能通过呐喊才能发泄的悲伤。 + +同样是去年才上大一的时候,一样的 5 月末海棠花已经凋谢的季节,一群大四的学长在那里摆摊卖书、拍照。他们有说有笑,完全没有了昔日高中时的伤感、悲痛,就像是彼此打着平日里的招呼——再见。 + +于是乎,我不由得觉得现代的大学生对于离别是何等的洒脱。“执手相看泪眼”已经成为夕阳黄昏下一道远去的记忆。匆匆离别间,倒是遇见几位学长相互戏言,他日君若发达时定莫要忘记昔日一起打 Dota、看エロ片的基友。 + +是我们长大了忘记悲痛,还是习惯了分别? + +想想自己的求学经历,由于父母工作的原因,走南闯北倒是读了 7、8 所学校,认识的人算起来也有三四百号。离别的次数多了,对于分别的愁绪也就淡了。QQ 上的同学几年不联系,有时候突然聊起,竟忘记对方音容相貌。有时候心里总会在想:生命不就是一次次的遇见和离别吗?只不过有些人还会再见,有些一旦分开就只能相忘于江湖…… + +前些日子看完雨帆推荐的《18 岁的天空》,再看看现在学长忙碌的身影,突然就觉得:其实毕业,不需要任何感伤。毕竟过去的已经过去,未来所要面对的是另一个新的开始。就像在某本杂志上看过的一句话:“毕业,就是一窗玻璃。我们得撞碎它,擦着凛冽的碎片走过去,血肉模糊之后开始一个完全不同的世界。” + +再多的伤感,再多的不舍,再多的惜别。最后只能化作脑海中的记忆,身边的几张青春洋溢的照片,朋友间相互赠送的几件礼物,束之高阁。而那些对与错、留下的、得到的,那些零星点点的过去,蓦然间,却只在过往…… + +忘我今夏,不言夙伤。 + + diff --git a/src/content/posts/2012/2012-06-03-anonaha.mdx b/src/content/posts/2012/2012-06-03-anonaha.mdx new file mode 100644 index 0000000..5d1fa92 --- /dev/null +++ b/src/content/posts/2012/2012-06-03-anonaha.mdx @@ -0,0 +1,40 @@ +--- +title: 未闻花名——那朵花 +slug: anonaha +date: 2012-06-03 00:09:42 +updated: 2020-09-06 12:15:05 +tags: + - 动漫 + - 那朵花 +category: 杂思 +summary: 彼时花名未闻。昔日一起玩耍的伙伴们,随着年龄的增大,彼此间也渐渐变得陌生。但那仿佛已经快要忘记的儿时记忆,仍是连接我们的羁绊。 +cover: /images/2012/06/2012060318520600.jpg +--- + + + +<MusicPlayer netease={22817150} /> + +彼时花名未闻。 + +昔日一起玩耍的伙伴们,随着年龄的增大,彼此间也渐渐变得陌生。但那仿佛已经快要忘记的儿时记忆,仍是连接我们的羁绊。 + +——题记 + +物是人非事事休,欲语泪先流。 + +手中风筝的线,你随时可以放开。但是,放开了就别指望它还能回来。一部动漫,可能仅仅给我们讲述了一个故事,但更重要的是它可以让我们回忆那些动人的瞬间。 + +我们仍未知道那日所看见的花的名字,其实并不是我们不知道,只是我们面对眼前的物是人非,总是选择去逃避。儿时的我们,或许是因为一个玩笑,或许是因为一个误会,造成了一些无法挽回的结局。然而天真的我们,总是认为时间是最好的解毒剂,可以慢慢地冲淡那一切不愉快的记忆,将它们封存在记忆的盒子里,藏在心里的某个不愿开启的房间。时光流逝,光阴荏苒,岁月的尘埃飘落在记忆的盒子上积起厚厚的隔阂,逐渐疏远,逐渐遗忘……直到某天误打误撞过某些契机打开了那尘封已久的记忆盒子,才发现,过去也还是那么值得回味,那么值得珍惜。 + +每个人都有无尽的回忆,每个人都在成长。有时,为了追上时间的脚步,我们不得不抛弃以前的那份天真无邪,在他人面前,收敛自己本身的感情。有时想哭想笑,却只能独自对着荧屏。慢慢学会的是隐忍,是坚强,是每个夜晚过后用微笑迎接新一天的阳光。慢慢地把自己藏在一张伪善的面具背后,只有独自一人的时候,或许只是在梦里,才会问自己是不是开心,所做的一切是不是值得。慢慢变得烦恼现状,迷茫未知的未来,害怕前方命途多舛。 + +未闻花名,也许我们只是将那最童真、最天真无邪的记忆都埋藏在了内心的最深处。当我们能够放下一切,通过一些偶然的契机开启那尘封已久的记忆时,便会发现,其实那多绚丽多彩的花的名字,一直存在于自己的潜意识中。其实自己是多么向往曾经幼稚的自己,以及那段无忧无虑的幸福生活。 + +人面不知何处去,桃花依旧笑春风。印刻着“超和平 buster”的木板独自默默承担和守护着那朵花的愿望,即使时光流逝,不变的是小时候的那份刻骨铭心的记忆,那些现在看来荒谬的愿望。在漫漫成长的人生道路上,可能我们都不会再知道那天所见花的名字,但是,每逢那个季节,还是会有淡淡的清香随风而来,虽然那清香已经变得模糊,已经变得难以辨认,然而不变的那朵花还在我们人生的某个角落盛开着,而它也会一直承载着我们儿时的记忆和愿望,伴随着淡淡的幽香…… + +> **后记:** +> +> 我们在慢慢长大,一个个流转的季节让路旁开放的花朵也随之变化,那个季节开放的花…名字叫什么来着?轻盈地摇曳着,每次触碰都有点刺痛。把鼻子凑过去,有股淡淡的青涩的阳光的香气。渐渐地,这香气变模糊了,我们慢慢长大了。不过,那朵花一定还在什么地方盛开着。没错,我们不管到什么时候,都会继续实现那朵花的愿望。 + + diff --git a/src/content/posts/2012/2012-06-07-growing-pains.mdx b/src/content/posts/2012/2012-06-07-growing-pains.mdx new file mode 100644 index 0000000..22f69da --- /dev/null +++ b/src/content/posts/2012/2012-06-07-growing-pains.mdx @@ -0,0 +1,31 @@ +--- +title: 成长的烦恼 +slug: growing-pains +date: 2012-06-07 15:26:25 +updated: 2020-09-06 12:15:24 +tags: + - 未来 + - 成长 + - 烦恼 +category: 杂思 +summary: 越来越觉得无病呻吟是那些没长大的孩子们的特权,而我却总要时不时地卖萌来装一下嫩。 +cover: /images/2012/06/2012060719153400.jpg +--- + + + +<MusicPlayer netease={368800} /> + +越来越觉得无病呻吟是那些没长大的孩子们的特权,而我却总要时不时地卖萌来装一下嫩。 + +说自己长大了吧,却一点都不成熟,心理还是那么脆弱。说自己还没长大吧,却也没有了孩时的兴致,也变得越来越不容易感动。整天新闻里 RSS 里都是当前社会的负面新闻,搞得自己也越来越多疑,越来越麻木,所能感觉到的真善美也越来越少。 + +常在想,孩童时候能无忧无虑,是因为周围永远充满着爱。眼里没有假丑恶,只有顺意和不顺意。快乐就那么简单,顺意时你们就都是好人,不顺意时你们通通都是坏人。孩童时感觉全世界都绕着自己转,感觉自己站在舞台的中心,周围的人都在看着自己,所以每一个步子都迈得那么小心却又那么起劲。孩童时也很容易感动,这就是所谓的纯真吧。经历过的东西少,不会以最大的恶意揣度别人,并且即使是以最大的恶意揣度别人,那也无关紧要,因为一个孩子的最大恶意,在大人们看来那也是根本不值一提的。 + +有时候会想,小时候的快乐那么简单,我们能不能总保持着那份童心呢。成长是不可逆的,我们永远回不去那个孩童时候,或许每天不上网,只看看新闻联播还有点希望回到过去。不可避免的我们将走向成熟吧……成熟也没什么不好的,每个阶段有每个阶段的味道,从开花到结果到落叶归根,总有生命循环的意义,我们能做的就是在每个阶段尽可能活出那个阶段的美丽吧。成熟是一眼看破了尘嚣,却又以一颗童心去给自己的生活创造快乐,这状态可能就跟共产主义一样无法实现,但如果能无限趋近而不是相背离,那它远比社会主义来得实在一点。 + +嗯,差不多要睡觉了,不然连半封建半殖民地社会都没得混了。 + +> 写这些东西的时候我又感觉自己站在舞台中心了,只是这次不是小心又起劲地迈步,而是两眼装满着忐忑焦躁不安地等待拍砖。嗯,晚安。 + + diff --git a/src/content/posts/2012/2012-06-10-nocturne.mdx b/src/content/posts/2012/2012-06-10-nocturne.mdx new file mode 100644 index 0000000..aed75f3 --- /dev/null +++ b/src/content/posts/2012/2012-06-10-nocturne.mdx @@ -0,0 +1,45 @@ +--- +title: 夜の思考 +slug: nocturne +date: 2012-06-10 03:46:08 +updated: 2020-09-06 12:16:10 +tags: + - 思考 + - 夜 + - 转载 +category: 文章 +summary: 不知从何时起,我爱上了那深藏不露的黑色。只因为夜。每至深夜时,我总是习惯性地关上灯,静静地立在窗前,任凭月光如瀑般倾泻全身,以及随之而来的纷涌思绪。 +cover: /images/2012/06/2012061019245600.jpg +--- + + + +<MusicPlayer netease={114024} /> + +不知从何时起,我爱上了那深藏不露的黑色。 + +只因为夜。 + +每至深夜时,我总是习惯性地关上灯,静静地立在窗前,任凭月光如瀑般倾泻全身,以及随之而来的纷涌思绪。 + +也许,只有当俗世的一切喧嚣与繁华沉寂在这无边的夜时,我们才得以摘下白天的面具,让自己的灵魂在月光的抚慰下得到一丝安宁。或许,也只有此时,我们才能够真正地看清自我。 + +静默的黑夜是思想者的天堂。夜深人静之时,我们的心才得以自由地舞动于风中,在夜神的陪伴下细细地品味人生百态。 + +一向不喜在夜里喝咖啡,相反,我更情愿在这令人沉醉的黑夜中倒上一盏香茗。咖啡的味道太浓、太重,是只属于那些都市人的佳酿。而茶,却是淡淡一缕幽香。 + +茶香完美地与夜融为一体。人生,有时也如茶一样,淡然无味,甚至微微作苦。惟有在喝下去之后,才能体味到,那残留于舌根的一缕清香。 + +在夜晚听音乐亦不失为一种享受。闭上眼,听着那曼妙的旋律飘荡于月光中,只感到自己的呼吸已同时间一起消逝于无尽的黑暗中…… + +每一次在夜中,我都能获得不同的启示。有时,耳边仿若飘荡着来自古希腊吟游诗人的声音,一个个古老而又神秘的音符中,传颂着无数掩埋于历史尘埃之中的故事。关于爱情与热血、生命与信念…… + +夜,永远是最神秘莫测的精灵之一。它似乎无所不知,能够洞察每一个人的灵魂,却又如海般包容一切,所有的美与丑、善与恶,都被笼罩于黑暗之中。它总在你不经意间悄悄降临,当你回过神时,又早已离去。它像一只翱翔的鹰,孤傲地振翅于云霄之上,漠然地注视着人间的一切却又从不为之停留,只在地面上投下它巨大的身影。 + +> 轻轻的 +> 放缓呼吸 +> 让心带着你的全部 +> 一同溶解在似水的黑暗之中 +> 只余下夜…… + + diff --git a/src/content/posts/2012/2012-06-11-my-darling.mdx b/src/content/posts/2012/2012-06-11-my-darling.mdx new file mode 100644 index 0000000..b1bff35 --- /dev/null +++ b/src/content/posts/2012/2012-06-11-my-darling.mdx @@ -0,0 +1,99 @@ +--- +title: 亲爱的,你怎么不在身边 +slug: my-darling +date: 2012-06-11 06:17:35 +updated: 2020-09-06 12:16:51 +tags: + - 呆瓜 + - 笨蛋 + - 傻瓜 +category: 杂思 +summary: 其实不想哭的,其实只是很小很小的事,可是自己还是忍不住了。好像很久都没有哭过了。有人问,如果郁闷了应该怎么做?我说,吃东西,睡觉,看郭敬明。看着别人的故事,自己就不那么难过了。 +cover: /images/2012/06/2012061119343300.jpg +--- + + + +<MusicPlayer netease={1909962184} /> + +其实不想哭的,其实只是很小很小的事,可是自己还是忍不住了。好像很久都没有哭过了。 + +有人问,如果郁闷了应该怎么做?我说,吃东西,睡觉,看郭敬明。看着别人的故事,自己就不那么难过了。这是我一直选择逃避的方式,小说里面的人物哭了笑了,我就忘记自己了。 + +其实自言自语也是幸福的一种方式,一直说自己很开心很幸福,就似乎自己也就能感觉到开心与幸福了。再加上旁人肯定的话语,自己也更坚定了。 + +但是,骗得过别人,骗得过自己么? + +突然的,就会开心起来。因为自己才看了一篇关于异地恋的文章,多好啊:如果爱,请深爱。对于故事的主角来说,真是羡慕,因为拥有持久而稳定的幸福。 + +于是兴冲冲地发了日志找了插图: + +> “来,看看我写的新文章。” +> “要不要我帮忙修改一下?” +> “不用了,我可以。” + +直到这个时候,才意识到,你还在我身边。 + + + +我一直以为,我们是可以一起做很多很多事的。我一直以为,我们是可以走到很远很远的。我一直以为,你是那个会永远嘘寒问暖、“养两个孩子”的那个人的…… + +恍惚间才意识到为这个问题,彼此已经争吵过好多次了。或者说,是我自己闹过很多次了。查一查短信包流量,还剩 209 条,用了不到 1/3。而此时,已是月中。 + +以前总是会担心超过,两条短信也要压成一条短信发。现在,心里的话语,不知道怎么说出口。有的,也多是: + +> “好的”、“到了”。 +> “来了?”、“嗯。” +> “不早了,睡吧,晚安。”、“88” +> **再撒一次娇,**“不批准,以后我不睡你也不许睡!” + +或许是已经习惯了,因为彼此已经熟悉,但随后便是沉默,只能无力地挥挥手: + +> “好吧,88。” + +何时我与你的世界,已经相隔了那么遥远了呢? + + + +在小区楼下,看到一对对的情侣拥抱缠绵。在月台上,看到送别的依依不舍。在校内网上,看到人家写的“保卫老婆”。在公寓走道上,看到他人说,还是找个男朋友好。 + +一楼到十三楼,电梯上了又下,一楼到六楼,电梯下了又上。一个人在家,一个人去超市,一个人深夜去洗手间。好像忘记了,自己也需要他人的陪伴。 + +所有人都说,找个男朋友吧,管接管送,背后随时一站,便有了靠山。可是亲爱的,你怎么不在我身边。 + +> 你说,“保卫老婆的可是我哦。” +> 我说,“有人给我发消息说梦见我哦。”、“你信了没?” +> “信啊。” + +然后呢? + +- 然后我是不是该让别人陪我回家? +- 然后我是不是该让别人写下保卫宣言? +- 然后我是不是该让别人每天给我发个消息道早? +- 然后我是不是该让别人打个电话问你现在在干吗、心情好不好…… + +我是你的啊,你怎么无动于衷。 + +你甚至不会像别人一样傻傻地说上一句:“敢打我老婆心思,想死啊!” + +我做不好很多事,我太不小心,我懒散。可是我现在,只想有个傻气的男朋友站我身边,或者告诉我,老婆最近色狼出没注意安全,随时开机打我电话。 + +你在淘宝上买回的储蓄罐,哭着说被老婆抢去玩了,却拍下我专心玩的照片,感叹自己咋没发现这样的玩法。想要玩暗黑 3,左右找理由,猴急猴腮,终于被批准了,拍一张,说还是老婆最好。自己买的最大的笔记本,再拍一张,炫耀说老婆送滴。 + +你一直都是这么傻…… + + + +我想,等你来北京,我们是不是可以去逛逛地摊淘淘潘家园,做一本自己的小日志。我想,等你来北京,我们是不是可以去玉渊潭,看看能不能赶上最后一点樱花的踪影,放一次风筝。我想,你能不能在这周六就到北京。不是怕你不去了太遗憾,而是怕你不去了家里只留我一个人怕黑不敢睡…… + +可是突然发现,原来你什么都不懂。或者说,你依旧是那么呆,不会揣摩女孩子的心思。 + +上次便说,这样的问题,重复了好多次了,不希望再有下次了。看来,我还是要和你这个呆瓜说清楚。 + +> 这里的空气很新鲜,这里的小吃很特别,这里的 latte 不像水,这里的夜景很有感觉。在一万英尺的天边,在有港口 view 的房间,在讨价还价的商店,在凌晨喧闹的三四点。可是,亲爱的,你怎么不在我身边?我们有多少时间能浪费?电话再甜美,传真再安慰,也不足以应付不能拥抱你的遥远。我的亲爱的,你怎么不在我身边?一个人过一天像过一年,我很想为了你快乐一点。可是亲爱的,你怎么不在身边? + +你怎么不在,身边…… + +——写于 2011 年暑假,那个呆瓜还留在学校的日子。 + + diff --git a/src/content/posts/2012/2012-06-13-our-mtimes.mdx b/src/content/posts/2012/2012-06-13-our-mtimes.mdx new file mode 100644 index 0000000..d293bcf --- /dev/null +++ b/src/content/posts/2012/2012-06-13-our-mtimes.mdx @@ -0,0 +1,51 @@ +--- +title: 我们的时代——《小时代》读后感 +slug: our-mtimes +date: 2012-06-13 06:05:20 +updated: 2020-09-06 12:17:14 +tags: + - 郭敬明 + - 小时代 + - 感想 +category: 杂思 +summary: 不怎么喜欢看郭敬明的小说,总觉得那些文字应该是小女生才会去看的东西。也总受不了扭扭捏捏的剧情,故事的结局,每次总是悲剧,一定要到最后将你的眼泪完全骗干才罢。但是,他的这部小说却真真切切的感动了我。 +cover: /images/2012/06/2012061321240400.jpg +--- + + + +<MusicPlayer netease={26562741} /> + +> 每一天都有无数的人涌入这个飞快旋转的城市——带着他们的梦想; +> +> 每一天也有无数的人离开这个生硬冷漠的城市的摩天大楼组成的森林——留下他们的眼泪。 +> +> 这是一个浩瀚的巨大时代。 +> +> 这是一个匕首般锋利的冷漠时代。 +> +> —— 选自《小时代:折纸时代》 + +不怎么喜欢看郭敬明的小说,总觉得那些文字应该是小女生才会去看的东西。也总受不了扭扭捏捏的剧情,故事的结局,每次总是悲剧,一定要到最后将你的眼泪完全骗干才罢。但是,他的这部小说却真真切切地感动了我。 + +上海是中国经济最为繁华的都市之一,这里每天上演着无数不为人知的悲欢离合。我们所将看到的故事,就发生在这座灯光下埋藏着无数血腥、黑暗、阴谋、丑恶的都市。 + +我们的世界充斥着各色的人生,快乐、悲伤、恐惧、迷茫全部交织在这个时代。外滩上,奢侈品的门店一家又一家,里面门可罗雀。仅仅一道之隔的江边大道上,身着廉价衣服的游客在络绎不绝地拍照。原来,两个世界的极端竟可以如此的融洽…… + +轰轰烈烈的发展潮流中,故事里的主人公四姐妹开始了毕业后的上海生活。冥冥之中,仿佛有一双看不见的大手在操纵着每个人的命运,每个人的故事各不相同,但最后都来到了这里——《M.E》杂志社。 + +命运的齿轮不会因为某个事件而停止转动,亦不会因为时间的蜕变而改变转速。我们亦像是表面上的时针、分针、秒针,一边转,一边看着时针的重合,却只能擦肩而过,无能为力。惘然间才发现,我们身处在如此一个“小时代”。 + +折纸时代里,书写的是华丽的高中故事。有的只是羁绊,四姐妹的喜怒哀乐,那四个很要好很要好的小女孩的故事。单纯的宛如有喜欢的人,南湘有一个麻烦的男友,林萧和顾里都有段不错的青春爱情。看这一部分的时候还在上高中,对于里面的情节只是稍有感触。直到看到虚铜时代,里面的人物矛盾一一暴露出来的时候,才看得心酸,或者说闹心。 + +郭敬明写得很虐,崇光的癌症,简溪的那句“别折磨我了”,看了后都会让人心痛。《小时代》的故事里,有着太多的阴谋、情感纠葛,即使只是小说,也会让人联想到现实社会的险恶。当读大学的我看完刺金时代的时候,才真正地哭了。 + +主角们的死让人悲伤,结局的一场火,烧去了一切的开始与结束。即使是四姐妹关系复原,即使顾里战胜了病魔和资产危机,即使还有很多,但是都消失了。让人无法接受这个设定,感觉不应该是它应有的结局。但结局只有一个,它不可能让每一个人都满意。现实的生活中拥有着的是悲欢离合,太过美满的结局只有在电影、童话故事中才能看到。真实世界的完美结局,又能有多少? + +他们的故事,结束在这么一场让人难以置信的大火里,缓缓落下帷幕。但是时代的脚步却依旧向前,时间,是最能抹去一切痕迹的东西。小说里面的故事虽然结束了,但是我们的故事才刚刚开始,当你以一位旁观者的角度,翻到最后一页,合上书本的时候。关于他们的记忆,名字、悲欢、故事,已经编织进我们的生命里,无法剥离。 + +这是属于他们的谢幕,我们的开始。 + +小时代,你我的时代。 + + diff --git a/src/content/posts/2012/2012-06-15-evening-caprice.mdx b/src/content/posts/2012/2012-06-15-evening-caprice.mdx new file mode 100644 index 0000000..c48b17b --- /dev/null +++ b/src/content/posts/2012/2012-06-15-evening-caprice.mdx @@ -0,0 +1,31 @@ +--- +title: 傍晚随想 +slug: evening-caprice +date: 2012-06-14 20:59:42 +updated: 2020-09-06 13:15:56 +tags: + - 时光 + - 生活 + - 黄昏 +category: 杂思 +summary: 我曾经在某个闲适的傍晚,走过校区南边的操场。远处渐落的夕阳斜斜地投射着美丽的光芒,整个世界都被镀上了温暖的金色。我沿着足球场的草坪边缘缓慢地前行,连呼吸都放轻,仿佛不忍心打扰眼前的伊甸园。 +cover: /images/2012/06/2012061421301300.jpg +--- + + + +<MusicPlayer netease={406238} /> + +我曾经在某个闲适的傍晚,走过校区南边的操场。远处渐落的夕阳斜斜地投射着美丽的光芒,整个世界都被镀上了温暖的金色。我沿着足球场的草坪边缘缓慢地前行,连呼吸都放轻,仿佛不忍心打扰眼前的伊甸园。 + +天好晴朗,是那种火烧般的红艳。草好柔软,是那种生机盎然的绿。周围的人跑着、坐着、说笑着,整个世界充满着活力。风吹过来,带着一丝清爽,远处法国梧桐树梢上的叶子簌簌作响,荡漾在暮霞映照的操场,也留在了我的心中…… + +抬望眼,羽毛球场上快乐的一家四口在切磋技艺。赤红色的跑道上人们在阳光下慢跑,远处跑道中间的绿地上,一堆堆青年或坐或躺,亲密地交谈或只是安静地休憩。栏杆外,几位已经结婚的阿姨正推着婴儿车,幸福地看着蹒跚学步的小孩。旁边半大的小女娃正撅着嘴学骑自行车,努力地将车头扭正,歪歪扭扭。刚打完球的学弟满足地闭着眼睛坐在那里小憩。锻炼身体的学生在健身器材那里各显身手,生锈的踏板在他们脚下嘎吱作响…… + +忽然觉得,生活也许就是这样了。我们各自走在自己的道路上,走得很慢,隔得很远,却有着自己的故事和记忆。而时间,在这一刹那静止,不愿向前迈去。阳光下,人们的脸上都带着安详而又幸福的笑容,似乎还有点佛祖拈花一笑的禅意。当我走到了操场尽头的时候,我在心底默默地告诫自己,不许回眸,就让那个时刻、那些笑脸成为生命里永不褪色的回忆,然后在某个冬天温暖自己。 + +这是记忆里的一段温暖。 + +写于 10 年 5 月,即将高中毕业的日子。 + + diff --git a/src/content/posts/2012/2012-06-18-happiness-caprice.mdx b/src/content/posts/2012/2012-06-18-happiness-caprice.mdx new file mode 100644 index 0000000..2b5a9a7 --- /dev/null +++ b/src/content/posts/2012/2012-06-18-happiness-caprice.mdx @@ -0,0 +1,41 @@ +--- +title: 与幸福 +slug: happiness-caprice +date: 2012-06-18 01:34:44 +updated: 2020-09-06 12:19:49 +tags: + - 未来 + - 幸福 + - 心烦 +category: 杂思 +summary: 其实幸福看似很远,却又很近。这些天不知怎么的情绪一直很低落,弥漫了整个六月初。忧伤、愤懑、百无聊赖、偏激、肆意、任性与自我放逐。 +cover: /images/2012/06/2012061822004800.jpg +--- + + + +<MusicPlayer netease={1908267808} /> + +其实幸福看似很远,却又很近。 + +这些天不知怎么的情绪一直很低落,弥漫了整个六月初。忧伤、愤懑、百无聊赖、偏激、肆意、任性与自我放逐。也许是期末考试即将来临的压抑,也许是课程设计即将递交。真正的原因总是秘密地隐藏在微小的角落,生根发芽,默不作声,一点一点将根茎蔓延开来,开出自怜的花朵。而表面的自己,却依旧笑着说:“今天的阳光真好”。 + +济南的阳光已经灿烂多日了,炎热的季节,稀少的行人,而我始终找不到那个有着金黄色底色可以柔和包裹自己的角落。 + +偶然间发现微博关注的某位网友爆出了和老婆的合照。他说:“结婚纪念日,结婚两年,相识十年整。吃纪念晚餐,吃得好饱,老婆吃了半个剁椒鱼头,我不吃鱼,只能面带微笑目视老婆吃鱼,哈哈。”在他们的结婚照里,两个人依偎着,穿着西装与大衣,别着新郎新娘的胸花,笑得淡淡的。背景是硕大硕大的双喜,红色底金色边,围着一圈七彩气球,一角的吉祥结上还挂着一个乐呵呵的财神。不美,也不梦幻,却踏实而贴心。 + +他们都笑得好幸福。 + +还有一张十年前的照片,樱花与马路,微晃的镜头。他从后面抱过来,抓住了老婆的手,面露得逞的笑意。再看两人,其实都腼腆得要紧,只是手抓得好紧,一直没肯放。对比着看,才发现:时间虽然改变了容颜,让圆润的姑娘有了棱角,只是,陪在身边的人依旧没变。他们的照片里,充满了湖泊与花海,背景的熏衣草地柔柔的,却似乎刺痛到眼睛,那样的美好,短暂、也令人羡慕。 + + + + + +而我们的合照,似乎还只有那么一张。那个夏末,我还未长大,穿着白裙子披着发,不知道未来在哪里却相信世界会是充满阳光。你还是白衬衣,笑得傻里傻气,说现在有很多不如意,但未来会很好很好。而我们,有着熟悉却还疏离。那时,我们只是朋友。 + +恍惚间想起了失落的原因、彷徨的原因、放弃的原因。防线崩溃,终于扯了闺蜜开始絮絮叨叨地诉说,可是说完后才发现自己的空洞,又能如何,还能如何,自己能做的又还有什么…… + +又要到了放假离开的时候,想想自己即将拖着行李箱,对着宿舍与窗外刷刷作响的法国梧桐叶说再见,突然就感到一种悲凉,似乎一去不复返的悲凉。然而,我为什么会不回来呢?我自己也说不清。 + + diff --git a/src/content/posts/2012/2012-06-22-the-misspelled-word.mdx b/src/content/posts/2012/2012-06-22-the-misspelled-word.mdx new file mode 100644 index 0000000..8b9f087 --- /dev/null +++ b/src/content/posts/2012/2012-06-22-the-misspelled-word.mdx @@ -0,0 +1,32 @@ +--- +title: 那个拼错的单词 +slug: the-misspelled-word +date: 2012-06-22 06:25:43 +updated: 2020-09-06 12:20:15 +tags: + - 心灵的鸡汤 + - SHMILY +category: 文章 +summary: 在我读初中的时候,我还没有属于自己的电脑,阅读的来源只有书本和杂志。所以下课的时候,最喜欢去逛的地方便是学校二楼的图书馆,而我现在将要讲的故事也是从这而来。 +cover: /images/2012/06/2012062122492500.jpg +--- + + + +<MusicPlayer netease={544175479} /> + +在我读初中的时候,我还没有属于自己的电脑,阅读的来源只有书本和杂志。所以下课的时候,最喜欢去逛的地方便是学校二楼的图书馆,而我现在将要讲的故事也是从这而来。 + +图书馆的书架比起当年的我还要高出一点,很多时候,我喜欢随便找一个角落借本书看,无所谓内容,无所谓地点,更像是一种机械的汲取,类似任务般的阅读。 + +以这样的方式,我读了很多书,却都基本上忘得差不多了。值得庆幸的是还有一些故事一直牢刻于心,并能在现在一一讲述。也许得感谢自己一锅端的阅读方式,让我有幸在情感最为丰富却又迷茫的年代遇到了自己的第一本《心灵鸡汤》。 + +那时的我才从济南转学到厦门,新鲜的环境、陌生的同学、不同的教材,感觉自己就像是刘姥姥进了大观园。只是,最初的自己,是害怕的。总是坐在教室的最后一排,默默地看着周围的人说说笑笑,却不知道找谁说话,就像是空气一样被人遗忘。 + +一个人的角落,一个人的阅读,一个人的感动。《心灵鸡汤》的故事很简单,却又很温暖,记得最深的故事是一篇关于爱情的。故事讲述了一对祖父祖母互相让对方寻找单词 SHMILY 的游戏,简单却又意外。这个单词有时候会出现在手纸的最后一张上,有时浮现在洗澡时的镜子上,他们轮换着在屋前房后留下 “SHMILY”,一经对方发现,就开始新的一轮。直到最后,作者的祖母死去的时候,他才知道:SHMILY 表示的意思是 “See how much I love you”(知道我是多么爱你)。 + +这么温暖的一个故事,感动了我整整一个午后,在还书的时候,我也把这个单词记在了心底——SYHILY。很明显,你会发现我记错了这个单词。以至于在多年后的今天,当我和云儿说起关于这个单词的故事时,她突然露出了疑惑的表情:“这个缩写的单词不怎么对,‘See you have I Love you’ 的说法没见过呀?”百度一下,果然自己记错了,而且整整错误了 6 年。 + +流年里,往事如风,记忆如烟花,亦如浮沙。观悲忆,落日恢宏。当我回首审视的时候,竟然没有后悔,没有抱怨。我不愿修改这个错误拼写的单词,毕竟,那是年少时第一次对于爱的记忆。那种美好,即使错了,也无怨无悔…… + + diff --git a/src/content/posts/2012/2012-06-23-sunset.mdx b/src/content/posts/2012/2012-06-23-sunset.mdx new file mode 100644 index 0000000..bf3191c --- /dev/null +++ b/src/content/posts/2012/2012-06-23-sunset.mdx @@ -0,0 +1,36 @@ +--- +title: 汐阳 +slug: sunset +date: 2012-06-23 01:22:59 +updated: 2020-09-06 12:20:22 +tags: + - 汐阳 + - 日光 +category: 杂思 +summary: 夜晚,因为未知而神秘。将一切都笼罩在浓浓黑暗下面,显得那么单纯。深不可测的海如夜般未知、神秘。夜幕笼罩下的海没有都市里华灯与喧嚣的魅惑,那么的令人向往而又敬畏。 +cover: /images/2012/06/2012062222340200.jpg +--- + + + +<MusicPlayer netease={2154850028} /> + +夕阳是一朵晚开的花。而最美是海上的日光——汐阳。 + +——题记 + +夜晚,因为未知而神秘,将一切都笼罩在浓浓的黑暗下面,显得那么单纯。深不可测的海如夜般未知、神秘。夜幕笼罩下的海没有都市里华灯与喧嚣的魅惑,那么令人向往而又敬畏。 + +皓月当空,似白练般从天上倾下,幻化为薄纱将大海罩住。银白色的朦胧令人感到亲切。微风吹拂下,摇曳着的海面似静谧的摇篮,装载着多少人的梦…… + +一切美好的事物注定不会长久。幸福总是短暂,似多变的海,倏忽间就变得暴虐无常。一道闪电将月光渲染的均匀的夜撕开,霎时,涌动的天空沉了下来,当空的皓月也被乌云遮盖。风愈吹愈烈,摇曳的海面越荡越高,终于翻滚起来,浪花击打着礁石,伴着轰轰的雷鸣,静谧已然消逝。 + +终于,雨打了下来。天与海被雨幕连为一体,巨大的雷声在风雨间奏响。海燕迎风而上,在雨中欢舞,任雨点击打在每一寸翅膀上,任疼痛在身体的每个角落肆虐。它接受着暴风雨的洗礼,呼喊着:让暴风雨来得更猛烈一些吧!汹涌的海面似将一切都吞噬,海燕孤独地飞翔着,独享这暴雨中的欢舞,只因它坚信最美的夕阳会在破晓绽放。 + +不知咆哮了多久,厚重的云层间闪现一线光亮。是它,刺破了天地的混沌,一道白色的光辉在海平线尽头亮了起来,这是不可遏止的力量的前奏。海燕向着光辉飞舞,白色击退了阴霾,黑暗的夜幕被无情地撤下。 + +金色的阳光占据了整个天空,撒向了海天相接的蓝。重归平静的海面上,海燕自由地飞,尽情沐浴着它的日光。它坚信,最美的汐阳要经过风雨的洗礼才能欣赏。 + +我愿在风雨中飞翔,只因最美是海上日光,汐阳。 + + diff --git a/src/content/posts/2012/2012-06-24-fathers-love.mdx b/src/content/posts/2012/2012-06-24-fathers-love.mdx new file mode 100644 index 0000000..8fecc3d --- /dev/null +++ b/src/content/posts/2012/2012-06-24-fathers-love.mdx @@ -0,0 +1,49 @@ +--- +title: 那个角落里的父亲 +slug: fathers-love +date: 2012-06-24 07:47:48 +updated: 2020-09-06 12:21:31 +tags: + - 成长 + - 约定 + - 父亲 +category: 文章 +summary: 人总是在成长中学习生活,积累经验。有时候我们敬畏老人,就是因为他们有着比我们更加丰富的人生阅历。 +cover: /images/2012/06/2012062423151000.jpg +--- + + + +<MusicPlayer netease={4880631} /> + +人总是在成长中学习生活,积累经验。有时候我们敬畏老人,就是因为他们有着比我们更加丰富的人生阅历。 + +—— 题记 + +写下这个标题的时候,我又一次将电影《我与狗狗的十个约定》看完。相比三年前刚看这部电影时的感动,也有了一番新的感触。 + +那个时候的我还在高三备考,每天忙着的就是三点一线的学习生活。看电影的时候正好是第一次模拟考完,同桌绍君说:“一起来看电影吧。”于是那个午后,我将自己心中埋藏多年的泪水献给了这部电影里面的小狗:索科斯。 + +一直以来都将眼泪藏在心里,学习的压力使自己变得麻木、僵硬。很多时候,当自己伤心的时候,才发现,我是什么时候忘记哭泣了呢? + +电影的剧情很简单,只是讲了主人公明莉在妈妈过世后和小狗、爸爸一起长大的故事。平淡的剧情,不带做作的表演,比起具有强烈视觉冲击的好莱坞大片,《十个约定》的故事更像是一杯清茗,适合在午后细品。 + +时光飞逝,我们都在变化中成长,于是,就有了不一样的视角。三年前的我关注的只是那只小狗对于主人的默默守护,用自己一生来诠释的爱。而今的我再一次观看此片时,却不经意间注意起了一直在角落里的“父亲”。 + + + +当“妈妈”病逝的时候,我们可以看到父亲一直在努力:手忙脚乱地做着早餐、料理,为了女儿放弃了自己优渥收入的工作,学习洗衣服、做家务。父亲的关爱不像母亲那么亲密、炽热,更像是春雨般入微、细腻。因为女儿,父亲的生活空间仅仅局限于诊所、沙滩。当明莉离开去动物研究所工作时,我们可以明显看到在机场角落送别女儿的父亲眼里的黯然。在海边和狗默默地看风景,喝啤酒,感叹着女儿的工作忙;在房间里与狗默默相对,一起分享晚餐,挂记着女儿为什么还没放假。不知怎么的,当我看到这些镜头的时候,鼻子一直酸酸的。是以前的我看得不够仔细,还是现在的我已经长大? + +一直以为影片里的父亲会再婚,但是却没有。没有了老伴的父亲是寂寞的,尽管有女儿和狗狗的相陪,但是女儿会长大、会有自己的家庭;狗狗的生命只有十年,终会走得比人早……在狗狗死后,女儿要求父亲参加自己婚礼的时候,我明显看到父亲的不愿:挽着自己的女儿走上红地毯,送到另一个男人身旁,独自离开,余生漫长而又孤独。 + +妈妈走了,狗狗去了,女儿已经长大了,父亲也老了,似乎一切都到了结束的时候。我相信,当狗狗死后、明莉哭着对父亲说因为她而使爸爸的生活变得狭窄的时候,其实明莉已经懂得了父亲为自己的付出。父辈的肩膀承担的不仅仅是生活,还有对于子女的关爱。 + +人生生来寂寞,但是却有着无数亲人的相伴、相随。而关爱,无需述说,就像是风一样无声无息、不易察觉。 + +当如今的我看完这部影片的时候,我突然在想,下一个三年后的我再看这部电影时,又会有什么样的感悟呢?我想,阅历的增长总会带来不一样的感受,那么就让时间来告诉我们结果吧。 + +只道是,年年岁岁花相似,岁岁年年人不同。 + +**相关阅读:**[十年如昔](https://yufan.me/posts/the-story-of-time/ '光阴的故事') + + diff --git a/src/content/posts/2012/2012-06-26-goodbye-youth.mdx b/src/content/posts/2012/2012-06-26-goodbye-youth.mdx new file mode 100644 index 0000000..76cb373 --- /dev/null +++ b/src/content/posts/2012/2012-06-26-goodbye-youth.mdx @@ -0,0 +1,26 @@ +--- +title: 再见,青春 +slug: goodbye-youth +date: 2012-06-26 15:11:05 +updated: 2020-09-06 12:21:48 +tags: + - 青春 + - 再见 +category: 杂思 +summary: 传说,鱼的记忆只有七秒,七秒之后,它所游过的每一个地方都将是一个新的起点。在这个新的起点,它将会有一个新的梦想,这个梦想让它即使是禁锢在鱼缸中也能依旧保持活力。 +cover: /images/2012/06/2012062623222100.jpg +--- + + + +<MusicPlayer netease={435307128} /> + +传说,鱼的记忆只有七秒,七秒之后,它所游过的每一个地方都将是一个新的起点。在这个新的起点,它将会有一个新的梦想,这个梦想让它即使是禁锢在鱼缸中也能依旧保持活力。对于青春而言,青春不是一份承诺,告别,忘记并不意味着背叛——只要心中的梦一直在。 + +或许我也可以做一条鱼,忘记曾经,在目前的大学校园中揣起一个新的梦想,继续快乐地为着目标奋斗着。只是我还想追着青春对她说: + +青春,你等等我啊!我还有话对你说呢。谢谢你陪伴我一起走过的日子,再见,青春…… + +只道,浮生若梦。只叹,记忆未央。 + + diff --git a/src/content/posts/2012/2012-06-29-philosophy-and-thinking.mdx b/src/content/posts/2012/2012-06-29-philosophy-and-thinking.mdx new file mode 100644 index 0000000..94d9c8e --- /dev/null +++ b/src/content/posts/2012/2012-06-29-philosophy-and-thinking.mdx @@ -0,0 +1,28 @@ +--- +title: 哲学与思考 +slug: philosophy-and-thinking +date: 2012-06-28 18:55:39 +updated: 2020-09-06 12:22:17 +tags: + - 思考 + - 哲学 +category: 杂思 +summary: 有句话说得好,哲学,出自一群无聊的闲人手里。苏格拉底的妻子苏珊娜就曾经如此自白:“我是苏格拉底的妻子苏珊娜,我的丈夫苏格拉底是一个著名的懒汉。 +cover: /images/2012/06/2012062823283400.jpg +--- + + + +<MusicPlayer netease={28587152} /> + +有句话说得好,哲学,出自一群无聊的闲人手里。苏格拉底的妻子苏珊娜就曾经如此自白:“我是苏格拉底的妻子苏珊娜,我的丈夫苏格拉底是一个著名的懒汉。他每天一大早就起床,吃完早饭就出门了,他没有工作,我也不知道他每天都在外面做些什么。家里的日子很贫寒,总是无米下锅,我很为家里的生计着急,觉得不能每次都靠柏拉图他们来接济,咱们家应该自食其力,于是每次都劝他找份工作,干个家教什么的,但是他从来都把我的话当耳边风。” + +同样地,马克思也是有名的闲散之士,成天就靠着恩格斯的接济过活。而想想原因,也并非没有道理。大学教授问他的学生一天都干了些什么,学生列出满满一张日程表,最后教授惊呼“天哪,那你哪有时间思考呀?!” + +思考需要时间,这是显而易见的,但却又那么容易被人忽视。每天过着忙碌敲代码的生活,哪里有时间思考。强迫自己写一篇日志之类的东西,其实也是强迫自己抽出一些时间去思考。生活的忙碌,就像小沈阳说的,“一睁眼一闭眼,一天就过去了”。 + +时间就像流沙一样从指缝流逝着,而自己却似乎什么都还没有做成。 + +<p style={{textAlign: "center"}}>\~ fin \~</p> + + diff --git a/src/content/posts/2012/2012-07-07-novel-story-3.mdx b/src/content/posts/2012/2012-07-07-novel-story-3.mdx new file mode 100644 index 0000000..65e2e0a --- /dev/null +++ b/src/content/posts/2012/2012-07-07-novel-story-3.mdx @@ -0,0 +1,199 @@ +--- +title: 交织的羁绊 - 圣诞夜 +slug: novel-story-3 +date: 2012-07-07 07:05:02 +updated: 2020-09-06 12:23:43 +tags: + - 悠久之翼 + - 小说 + - 同人 +category: 小说 +summary: 有两个名唤「音羽」的小镇,在焦土和废墟上建起的真正的小镇和映在安详而美丽的大地上的虚幻的小镇。咀嚼着痛苦的过往,践踏着无数的不幸。 +cover: /images/2011/07/2011070220190200.jpg +--- + + + +<MusicPlayer netease={527797} /> + +有两个名唤「音羽」的小镇,在焦土和废墟上建起的真正的小镇和映在安详而美丽的大地上的虚幻的小镇。咀嚼着痛苦的过往,践踏着无数的不幸。日复一日的生息中,小镇点缀着名叫「人」的光芒。记忆中的小镇的虚幻的影子,虚幻的小镇中的真实的自己,不停回放的记忆与时间和空间的缝隙。在那尽头的,便是——一切的结束与开始。而我们现在将要看到的,便是那个日本小镇的圣诞节冬季的故事。 + +啪的一声,广野·纮手里拿来绘图的铅笔由于用力过度折断了。此时的他正在赶着下一期的《新漫堂》的稿子,可是无论怎么想都不知道怎么画教堂的部分。无力的他将铅笔扔在一边,重重地伸了个懒腰靠在椅子上,望着自己现在居住的单元房思索着。 + +“真搞不懂”,广野重重地叹气道,“要不出去取材一下吧。” + +手机的短信铃声响起,广野连忙起身查看,“怎么了,原来是景啊。”新藤·景是广野的青梅竹马,但是一直叫广野哥哥。只见短信里写着:圣诞快乐,哥哥别忘记来我家参加晚会哦! + +“真没办法”,广野抱怨着,“难道她不知道漫画家都是没有节假日的吗?”望着桌上才画了一半的手稿,想想刚才的取材计划,广野还是妥协了。“先去取材,然后顺便露一个脸吧。”一边嘴里这样说着,一边走出了房间…… + +此时正好是圣诞节里的平安夜,8点的钟声才刚刚响起,小镇上充满着欢声笑语。带着大胡子的圣诞老人、花花绿绿的气球、漂亮的彩灯装饰将小镇变得焕然一新。小镇街道的一角上,堤·京介正在拍摄圣诞节短片,作为社团参赛的作品。 + +“好,cut。”四处拍摄一圈后,京介满意地合上了摄像机。 + +“拍到好画面了吗?京介。”一旁一直陪伴的社长期待地问道。 + +“那当然,京介自信地答道”,他大手往前一挥,“我只拍好的,其实下雪的场景要是能拍到就更好了,但是到现在还是没下雪啊。” + +“那可不行,拼接场景的时候就够呛啊!”社长双手往腰间一插,断然拒绝了京介的想法。 + +京介摇了摇头,无可奈何道:“算了,反正也只是取材。走,去吃饭去吧。” + +“嗯。” + + + +京介刚要抬步走开,眼角不自然地捕捉到一段闪光的画面,就像是一瞬间油然而生的灵感,或者是一种莫名的触动。猛然转身望去,只见对面的街道上,一位紫色短发少女正在欢快的小跑着。她提着附近面包店的盒子,围着一条粉红色围巾,跃动的短发、眼角弥漫的笑容,让京介不由得看痴了。 + +不讳地说,女孩算不得怎么漂亮,并无吸引人之处,衣着也不出众,脑后的头发随着奔跑而上下抖动着。然而,相距50米开外的京介却从看见她身姿的那一瞬间,他的胸口便如发生地鸣一般的震颤,口中如沙漠干得沙沙作响。 + +每个人都有属于自己理想的女孩。例如喜欢足颈细弱的女孩、眼睛大的女孩、十指绝对好看的女孩,或不明所以地迷上慢慢花时间进食的女孩。但是要此时的京介明确勾勒出女孩形象,却无法做到,现在他所能记得的,只有女孩并非十分漂亮这一点。事情也真是不可思议。 + +“多么美丽的场景啊!”京介这样想着,拿起手中的摄像机想把她拍下来。只是,嗖~~一声,一辆运货车呼啸而过。一转眼,刚才还在的少女已经消失在视线内了。 + +京介茫然地放下摄像机,望向四周。突然,在他的身后传来了社长咬牙切齿的声音:“怎么了?京介。”“呃!”京介回过神来,吓了一跳,左顾右盼地不敢看社长的眼睛,“没什么,只是觉得对面的宣传海报不错,想拍下来。” + +“哼!”正在和京介交往的社长重重地哼了一声,“肯定是看到好看的女孩子了吧!” + +“……”京介不知如何应答,理智告诉他现在应该否认,可是不善于说谎的他一时找不出对付社长的话来。毕竟,这种情况不是一次两次发生了。 + +“果然又来了!又来了是吧。”社长充分体现了女强人的性质,一边愤怒地说着,一边上前使出了女生必会的龙爪手对着京介的耳朵就是一下。“好疼,疼疼疼疼疼。”凄惨的叫声回响在圣诞夜的街道,慢慢消散…… + + + +同一时间,京介所看到的短发少女已经到了家。“我回来了。”少女推开房门兴奋地答道。 + +“啊?欢迎回来,景学姐。”房间里坐着的是景的好友羽山·瑞希,被景一起来过圣诞平安夜。只是,此时的瑞希嘴里塞满了饼干,怎么看怎么有点好笑的味道。 + +“对不起,瑞希。蛋糕店里面的人太多了。”景一边穿好拖鞋,一边抱怨着,一抬头,“咦?哥哥人呢?” + +“还没有来啊。” + +“真的吗?他到底还要不要来!”只见景的脸色立刻变了,她的眼睛闪闪地像是烧着什么东西,“都和他说了这次再放鸽子就绝不会放过他!”景在那里咬牙切齿着,连瑞希都忍不住打了一个寒噤,她真没料到看起来乖乖女的学姐景生气的时候有这么可怕! + +“纮学长好像总是那么忙”,瑞希一边转移着话题一边和景一起摆放才买回来的饮料、零食,“明明没有参加社团活动也没有上补习班,应该有别的原因吧。” + +“谁知道?那个笨蛋!” + +“不过也真是奇怪的人啊,之前我看见他还以为他在思考,结果就突然发疯似的挠头”,说道这里瑞希忍不住笑了,“感觉就像是在最后期限前赶工的漫画家一样。” + +啪嗒一声,景仿佛是听到了什么不可思议的事情一般愣住了,手里拿的pocky饼干也随之滑落。 + +“怎么了?学姐。”瑞希奇怪地问道。 + +“啊,没事,没事!”景快速地转过身摆手道,脸上还带着一丝由于激动而显现的红晕,“我再次发送短信,那个家伙可能没看到。” + +景拿出手机,映入眼帘的是一条新短信。咦?难道是哥哥发来的。这样想着,景打开了短信:“圣诞快乐,姐姐。by——千寻” + +圣诞夜的喧闹只局限在小镇中心的街道上,偏向镇郊的一条通往教堂的道路上,广野正独自一人骑着自行车穿行在冰冷的夜色中,窜入靴子的寒气使他身体微微颤抖,而四周的寂静更让人有些害怕。从五光十色的路灯映照的街道仰望星空,是淡粉色的,只能模糊地看到明月绽放着朦胧的残光。“好冷……”广野想着,嘴里呼出的白气转眼间便融入了无边的夜色中。 + + + +不知不觉到了教堂的门口,推开厚重门扉,耳畔响起吱啦的开门声,只怕是大门年久失修的缘故。广野轻轻地走进教堂,嗒、嗒的鞋子撞击底板的声音回响在空旷的教堂里。教堂的光线很暗,没有灯泡,唯一的光源来自道路两旁柱子上的烛光。广野一边走着,一边观察着四周的摆设,“呦,原来里面是这个样子啊。” + +“很遗憾。”还在观察侧壁绘画的广野顺着声响转过了头,只见道路另一侧的圣母像下,不知何时出现了一位穿着修衣的少女,看起来很柔弱的样子,年龄可能比广野还要小上一两岁,“弥撒仪式已经结束了哦。如果想参加的话,请明年再来。” + +“啊……不,我并不是教徒,只是想来取材的。”广野连忙答道。 + +少女露出了好奇的表情说道:“那么,为什么来这里呢?这儿的教会并不搞赈灾救济活动哦。” + +“没有啦,我不是流浪汉。”广野·纮生气地说着,“我只是由于职业的原因,前来看看教堂内部到底是什么样子。” + +“原来如此。弥撒结束的话,虽说是圣诞节,这儿和普通的教会没什么区别。再说,弥撒本身就不是什么有趣的事情。”说道这里,少女叹了口气,满是疲惫的样子,让人的心都忽地一痛。 + +“那么……说起来,你是谁?”广野·纮好奇地问道。 + +“我么?和你一样的人哦。” + +“嗯?那是什么意思?” + +少女狡黠地一笑,对着广野眨了眨眼睛:“就是明明是圣诞节,却没有恋人共渡良宵的人啊。”语气里明显带了些自嘲。 + +“我想问的可不是这个!” + +“说笑而已啦。”少女摆了摆手,“露出那样的表情真的很吓人的啦!” + +虽然这么说,但是少女的态度却是十分轻松,一点也看不出害怕的表情。“我的名字叫雨宫·优子。”少女自我介绍起来,“顺便说,我也只是一个路人而已哦,既不是教会的工作人员也不是相关人士哦。” + +“优……子……”广野一边念叨着,一边在脑海回忆这个名字。似乎,在什么时候听过相同的名字,总是有一种莫名的熟悉感,可是怎么也抓不住那一瞬间的思绪。 + +“怎么了?” + +“啊,没什么,只是突然想到了某些东西,走神了而已。” + +“难道是,对我一见钟情?”优子突然恍然大悟地说道,“虽说这是情不自禁的事情,但如果可以的话我希望先从朋友开始做起吧……” + +“你想吵架吗?” + +广野使劲地瞪了女孩一眼,少女同样配合地故意缩了缩脖子,装出害怕想要逃跑的样子。“唉,完全被小看了。”广野无奈地叹气着。 + +“真是一个不懂幽默的人呢!” + +“很抱歉,我就是这么一本正经。” + +少女只是微笑,并不说话,墙壁上并列闪烁的微黄的烛光,为少女的面庞笼罩上一层朦胧的暗色。 + +“原来如此,那么,一本正经的你的名字是?” + +“没有报上名字的必要吧。” + +优子微微嘟起了她的小嘴:“这样太狡猾了,我都认真地报上了自己的名字呀。” + +“……” + +“没关系啦,名字而已,说出来不会少什么的啦。” + +“……”广野继续保持沉默。 + +“算了,算了。”仿佛是最后放弃了般,少女摇了摇头道,“反正我也不是特别想知道你的名字,知道了也没有任何好处。” + +“广野啦,广野·纮。” + +“嗯……乖癖的家伙。”优子恨恨地说。 + +“要你管!”广野·纮回应道。 + +“总觉得,你还真是一个奇怪的人呢……” + +“你一个人一直待在这种地方也很奇怪了吧,说到底,你是在这做什么呢?” + +接下来的很长一段时间里,教堂陷入了沉默之中。少女将视线望向了屋顶的圣母像,在广野以为她在烦恼什么的时候,她却又露出了笑容:“我有一个必须要见的人。”她的表情是那么的认真,不是一开始和广野开玩笑时的那种略带做作的微笑。眼神里,透露着一份坚定,还有一丝怀念。 + +虽然广野无法理解少女的那份坚持,但是还是鼓励道:“嗯。能见到的话就好了呢。加油吧!” + +“那么你呢?有没有想要一起过圣诞的人呢?” + +“没有!” + +“真的没有?”优子惊讶地问道。 + +“……”广野突然不知如何回答,对于他来说并不是孤身一人更好,只是确实没有想过要和谁在一起。优子依旧在那里微笑着看着他,但是他却没有了聊下去的愿望。他转身想要离开,身后传来优子的惊讶的呼喊:“咦?你要回去了吗?” + +“嗯。我在这里也没事可做,而且冷死了。”广野没有转身,继续往来时的方向走去。 + +“啊,请稍等一下。”优子叫住了正要离开的广野。 + +“嗯?” + +“有一句话忘记说啦!”优子扬起了一个恶作剧般的微笑,“圣诞节,快乐!” + + + +“好冷啊!”出了教堂,准备去赴约的广野使劲地搓了搓手,“会不会是要下雪了呢?”这样想着,耳边却突然传来少女的喊声:“小偷!”额?才避开了身边开过的摩托车的广野愣了一下,不由得叹气,“真是个骚乱的夜晚啊!才有一辆摩托车以疯狂的速度行驶过去,现在又来了小偷。” + +“站住!”从街道的另一边,一个女孩子啪嗒啪嗒地跑了过来。即使是漆黑并不明亮的圣诞夜,广野也可以明显地看到少女脸上的惊慌。 + +“啊,喂,站在那边的人!”少女冲着广野喊着。 + +“什么事?” + +“有没有看到一辆摩托车?”少女语气十分急促,脸上带着着急的表情。 + +“嗯,看到了。”广野指了指道路的另一边,“好像是往那个方向开走了。” + +“嗯,谢了。”少女麻利地爬上了广野的自行车,“那么,这个就借我一下吧。” + +“啊?”还没等广野回过神来,这个陌生女孩已经跨上自行车,消失在冬夜的夜幕中,只剩下一个愈渐模糊的影子…… + +“喂,等等啊!”广野一边喊着,一边追了上去。到底还是一个不平凡的圣诞夜,陌生的少女抢走了广野的自行车追赶小偷。而命运丝线的交阖,又会在这个冬日,北半球的另一个音羽小镇里开始怎样的故事? + +To be continued! diff --git a/src/content/posts/2012/2012-07-12-greedy-children.mdx b/src/content/posts/2012/2012-07-12-greedy-children.mdx new file mode 100644 index 0000000..1554090 --- /dev/null +++ b/src/content/posts/2012/2012-07-12-greedy-children.mdx @@ -0,0 +1,36 @@ +--- +title: 贪婪的小孩子 +slug: greedy-children +date: 2012-07-12 13:10:03 +updated: 2020-09-06 12:23:39 +tags: + - 回忆 + - 童年 +category: 文章 +summary: 现在和云儿逛超市的时候,总喜欢去儿童用品区逛逛,看看身边那些精致的小衣服、小玩具,我就忍不住说将来要是生个女娃,衣服什么的我全包了! +cover: /images/2012/07/2012071223421000.jpg +--- + + + +<MusicPlayer netease={1361378050} /> + +现在和云儿逛超市的时候,总喜欢去儿童用品区逛逛,看看身边那些精致的小衣服、小玩具,我就忍不住说将来要是生个女娃,衣服什么的我全包了!可是,每次看到那么多漂亮的童装,总会想起自己当年穿过的百家衣,简陋却玩了一个童年的积木…… + +其实我很羡慕在 01 年出生的表弟,因为现在很少有什么东西他得不到,也没有什么想做的事情会去无条件尝试。 + +至今,我还记得才来厦门时第一次坐电梯的经历。一直都只在电视里面见过电梯,却没有真正尝试过,直到随父母来厦门务工,才圆了心愿。记得当晚,一直兴奋得睡不着觉,现在还记忆犹新。可跟表弟讲起这件事时,他露出了困惑的表情道:“坐电梯?” + +在 Bilibili 上看别人回忆的老动漫合集,怎么就透着一股熟悉劲儿。我看过的第一部动漫也是《邋遢大王历险记》,那个时候,每天晚上一到 5 点半就守着央视 1 套的动画城,死活也不让父母换台…… + +读过 70 后的童年故事,尽管那个年代物质匮乏,没有什么好看的衣服。玩具什么的都是自制的,有的也就是一些华而不实的铁皮玩具。可是,70 后的童年也是快乐的。我羡慕他们可以整天整夜地在蓝天白云下蹦跑,呼吸着未经工业污染的带着泥土芳香的空气,做着简单却有趣的游戏,自由而又充满幻想。 + +在小县城里长大的一代 80 后,说起童年很是羡慕农村里的娃儿,可以爬山下水,不用整天扎根在兴趣班里。 + +都说 90 后开始,是物质发达、网络兴起的一代,他们想要什么有什么。他们脑子里面想的很多事,是许多 70 后、80 后上了大学还懵懂的。可是,作为 90 后的我还是羡慕着 00 后…… + +但是,羡慕也好,嫉妒也罢。每个人聊起童年的那些事儿,没有谁不津津乐道,乐在其中。虽然说比不了现在的孩子物质丰富,也没有他们那么丰富多彩的精神世界。可是,对于我们这些走过属于自己的童年时光的人,曾经的摸爬滚打、无忧无虑的儿时记忆,是谁也拿不走的。 + +那些年,我们都是无忧无虑的小孩子。 + + diff --git a/src/content/posts/2012/2012-07-21-koto-no-ha-no-niwa.mdx b/src/content/posts/2012/2012-07-21-koto-no-ha-no-niwa.mdx new file mode 100644 index 0000000..344e65d --- /dev/null +++ b/src/content/posts/2012/2012-07-21-koto-no-ha-no-niwa.mdx @@ -0,0 +1,48 @@ +--- +title: 雨朦胧 +slug: koto-no-ha-no-niwa +date: 2012-07-20 23:17:04 +updated: 2020-09-06 12:23:29 +tags: + - 恋爱 + - 雨 +category: 文章 +summary: 景泰蓝的天空,略带一丝阴沉,花坛里的君子兰也没有了往日的娇艳。炎热的午后,沉闷的季节,让人心中总是憋着一股气想要吐露出来。 +cover: /images/2012/07/2012072022533700.jpg +--- + + + +<MusicPlayer netease={2144244541} /> + +景泰蓝的天空,略带一丝阴沉,花坛里的君子兰也没有了往日的娇艳。炎热的午后,沉闷的季节,让人心中总是憋着一股气想要吐露出来。 + +独自坐在图书馆一角看书,窗外的天空低垂如灰色的雾幕,渐渐布满了乌云。屋内顶棚的灯一盏盏亮起,窗外的花草一动不动。有道是:溪云初起日沉阁,山雨欲来风满楼。 + +看书的心忽地乱了,似平静的水面被纤丝挑起涟漪。一抬头,望向对面,竟不觉看得痴了。面前的座位不知何时多了一位女孩。亦如每个关于图书馆的故事中都会有的熟悉场景,平淡得仿若黑白铺就的山水墨色画,却有着别样的心动和恰到好处的融洽。眼前容色姣好的少女正专心看书,明亮的眼眸中仿若倒映着整个世界。 + +这样温馨而又淡淡的情境,记忆中已经出现多次,但总隔着层迷蒙的距离感。屡屡觉得自己被某种感觉触动,却总是抓不住、悟不透。 + +第一次当她坐在我身边时,第一眼我便喜欢上了她,只是,我还没准备好表达的勇气。于是便固执地等待下一次的遇见,永远是最笨的人选择的最笨的办法,永远是最无能为力的人选择的最唯心的办法。 + +窗外轰隆的雷鸣声响起,打破了屋内无形的静谧。淅淅沥沥的雨声慢慢奏响,回荡在耳边。雨越下越大,对面的女孩也因雷声而惊扰,望向窗外。不经意间两人四目相对,她淡然一笑,刹那间的甜美,拨乱的不仅仅是思绪,还有心弦。 + +如果次次都能相伴而坐,可不可以让我倾诉:我一见倾心的姑娘就是你? + +此时的我静静地趴在桌子上,而她,就坐在对面。屋内是一片明亮的灯光,四周散落着一两个人,以点缀我们的存在。窗外哗啦啦地下着雨,她看着我笑了笑道:“外面雨下得好大。”我随意地应着:“夏季的阵雨就是这样,一会儿就小了。” + +不知不觉就聊开了话题,就像是隔着的一层纱被捅开了,没有了距离……雨渐渐地停了,窗外刚才还是乌云漫布,此刻已经露出了太阳。她高兴地说道:“雨终于停了,可以回去啦!”抬头寻找窗外她离开的身影,透过沾染了雨水的玻璃望去,是那么的朦胧。 + +既然已经有了这样温暖的、柔和得近似淡然的开始,分别又有什么重要?我们所处的世界彼此交缠错杂,互不干扰,但偶尔会在缝隙中漏出一些交集的机会,不急不忙牵引一段故事,令人悠然神往。也许某一天,百无聊赖大雨将至的下午,会有一个熟悉而又心动的人慢慢向你走来,你们也许在一起看书避雨,也许你会遇见一个回味无穷的故事。 + +谁知道呢? + +> **后记:《将你的微笑记下》** +> +> 我自时光走过,快乐汇成细雨,飘洒进悲伤的河; +> 美好化为纯白,氤氲进苍茫的夜。 +> 于是,泉水自在地唱着叮咚的歌,黑夜安然地奏响曼妙的曲。 +> 而我,抱紧双膝在寂寞的夜里,请萤火虫低低地盘旋,为我照亮曾经的路,去回首—— +> 每一个过往中你最美好的微笑! + + diff --git a/src/content/posts/2012/2012-07-25-the-first-year-of-blogging.mdx b/src/content/posts/2012/2012-07-25-the-first-year-of-blogging.mdx new file mode 100644 index 0000000..761a417 --- /dev/null +++ b/src/content/posts/2012/2012-07-25-the-first-year-of-blogging.mdx @@ -0,0 +1,56 @@ +--- +title: 写博的第一年 +slug: the-first-year-of-blogging +date: 2012-07-25 01:26:18 +updated: 2020-09-06 12:25:40 +tags: + - 博客 + - 写作 +category: 文章 +summary: 有一天晚上,在 QQ 上和一个准备写博的人聊了很久。那个人问我,写博客会不会很累?我想了想,也不知道该如何回答这个问题。 +cover: /images/2012/07/2012072523060500.jpg +--- + + + +<MusicPlayer netease={1995231785} /> + +## 零:常 + +有一天晚上,在 QQ 上和一个准备写博的人聊了很久。那个人问我,写博客会不会很累?我想了想,也不知道该如何回答这个问题。因为世界上没有什么事情是不劳而获的,即使是最简单的日记也需要长久的坚持。可是,如果就这样说出来,又觉得哪里不对。所以我告诉他,每天我早上起来后都会打开博客、查看订阅、浏览评论、回复。当我习惯做这些事情之后,就会有一种感觉,慢慢地在心中酝酿,让我觉得自己在网络中以一种与以往不同的方式存在着。我能够清晰地看到自己,回味着那些记忆中熟悉或者相似的镜头。 + +前几天厦门下了几场大雨,下午在图书馆看书的时候,窗外突然下起了瓢泼大雨。淅沥沥的雨,呼哧哧的风,总让人静不下心来看书。只是,在不经意间发现对面竟坐着一位漂亮的女孩。但其实,也就是两个人互相看了几眼,笑了笑。 + +接着仿佛整个世界沉默下来,我一边看着窗外的雨,一边在随身的笔记本上打开麦库笔记写下这个故事。雨滴打在玻璃上发出啪啪声,图书馆人很少,安静得像世界末日。我修改完错字,便顺手发表在自己的博客上。 + +这时我才意识到,我已经习惯于用博客记叙自己的故事,不是微博里随便发的一条状态那么简单。而是,我一边活着,一边写着,然后自己看着自己的故事思考起来…… + +这是我开始写博客的第一年。 + + + +## 壹:记 + +看村上春树的《且听风吟》时还在读高一,现在只记得小说开头的段落,说的是作者的朋友告诉他“不存在十全十美的文章,如同不存在彻头彻尾的绝望。”于是,每当作者提笔写东西的时候,经常陷入绝望的情绪之中。因为能写的范围实在过于狭小。譬如,可以就大象本身写一点什么,但大象的驯化却不知何从写起。 + +“十全十美的文章本来就没有”,在很长的一段时间里,这句话被我拿来安慰自己可怜的作文分数。后来我开始尝试做摘抄,写日记,将零零碎碎的文字铺满了一本又一本 Gamble 笔记本。刚开始写日记时,语文课代表教我如何使用修辞。她帮我改过好几次文章,每次都能找出一大把错别字,又送我一本字帖,很厚,她说只有先把字写好了,才能写出好文章。多年后同学聚会见到她时,还能记起当年被她敲着脑袋强迫炼字时的甜蜜。 + +高二时开始写网易博客,基本上会写的就是流水账,比如今天上了什么课、做了什么恶心的数学题一类的。或者也会去选摘一些名家的散文,将他们的名字堂而皇之地换成自己的。但是,当我阅读那些优美的字句时,总是可以莫名地心静。那种与作者相同的心路,常让人感动得想要落泪。 + + + +## 贰:散 + +刚上大学后的很长一段时间里,我都没有脱离失恋的伤痛,曾在 QQ 空间里写过那种孤独一人的绝望。同学的 QQ 状态赤果果地提醒着我的脱节。我憎恶着手机、MSN、E-mail 这些只因为距离而存在的东西。我所渴望的无非是有人能静静地倾听自己的心情,一分钟也好。 + +于是渐渐开始喜欢上阅读博客,每天打开电脑的第一件事就是打开 Google Reader 查看订阅。有时候一遍又一遍地看着某篇文章品味,有时候只是漫无边际地点开一个又一个的留言链接。或许会看到不同博主的生活、喜怒哀乐,或许会有另一个惊喜的感动。 + +习惯了这样,就好像忘记了一些大学生活中最初所感觉到的困难。渐渐地,变成了一个无言的旁观者,阅读着你的我的故事。 + +倒是在不知不觉中开始尝试描写,模仿那些熟悉或类似的字句,一点一点堆砌成自己的片段,散文、杂记这些,突然之间自己都会写了。过去也并不是不会写,但从来不觉得自己写的能看,干巴巴的句子,总有一种想要撕书的冲动。当有一天半夜里自己开始给啊囧的美图控更新的时候,我才真的觉得匪夷所思,一个几乎没什么访问的网站,所以一点也不知道自己发表那么多的图片是要干嘛。 + +我行过许多地方的博客,看过许多的文章,品过许多种类的心情,经历着一个正当书写的年龄。 + +写博客的第一年,自己对自己说:“我能行。” + + diff --git a/src/content/posts/2012/2012-08-08-scattered-fireworks.mdx b/src/content/posts/2012/2012-08-08-scattered-fireworks.mdx new file mode 100644 index 0000000..9ba321e --- /dev/null +++ b/src/content/posts/2012/2012-08-08-scattered-fireworks.mdx @@ -0,0 +1,36 @@ +--- +title: 烟花散 +slug: scattered-fireworks +date: 2012-08-08 00:30:25 +updated: 2020-09-06 12:25:50 +tags: + - 情感 + - 烟花 +category: 文章 +summary: 总有一些东西,没有谁能准确地捕捉或描绘,例如爱情和回忆。浅念里,回忆中,悠然升起对你的思念。就像江心飘摇的水榕,遥不可及;就好像其实烟花也有最灿烂的微笑,而你们谁也不知道。 +cover: /images/2012/08/2012080819554000.jpg +--- + + + +<MusicPlayer netease={496869422} /> + +总有一些东西,没有谁能准确地捕捉或描绘,例如爱情和回忆。浅念里,回忆中,悠然升起对你的思念。就像江心飘摇的水榕,遥不可及;就好像其实烟花也有最灿烂的微笑,而你们谁也不知道。 + +又一次参加大学同学聚会,我们说着老故事、旧光阴,忙着记下彼此的手机号码,巴结着有权有势的同学。望着昔日害羞的她现在如此的神采飞扬,突然觉得,我们一起翘了晚自习去操场上散心的简单岁月,已经一去不复返了……“不知魂已断,空有梦相随。除却天边月,没人知。”回忆着韦庄的这首词,有一种想哭的冲动。 + +听青春,迎来笑声羡煞许多人。那史册,温柔不肯下笔都太狠。烟花易冷,人事易分。而你在问,我是否还认真? + +命运中曾有一个人与你相伴,是他让你懂得了爱恨,经历了悲欢。在你的人生书页上划下了重重的一笔,让你知道了这个世界的现实与虚伪。只不过,你是否还记得? + +雨纷纷,旧故里草木深。我听闻,你仍守着孤城。城郊牧笛声,落在那座野村,缘分落地生根是我们。 + +昔年一起学习的旧庭院,院子里有梧桐细雨、寒烟漠漠、大雪飘临。也许我们一起在那做过一个关于“浮生”的梦,只不过,你也许已经忘记了。 + +花开荼蘼,韶华胜极,青春最灿烂的时候的终结。而我们,也随毕业分别。就像那盛开的彼岸花,花叶不相见,生生总相错。 + +烟花散,每一次绽放,都是一道绚丽的回忆。我记得这些光阴中的刹那,记得如花般的你,那袭白色的裙装,冷蓝银白,藏着世间无尽的繁华与热闹。而我仅能想起的,却是那些无法忘记的真实和疼痛。 + +烟花尽,刹那的芳华,缔结着一个个生命的轮回。 + + diff --git a/src/content/posts/2012/2012-08-28-the-forgotten-accent.mdx b/src/content/posts/2012/2012-08-28-the-forgotten-accent.mdx new file mode 100644 index 0000000..c2334df --- /dev/null +++ b/src/content/posts/2012/2012-08-28-the-forgotten-accent.mdx @@ -0,0 +1,38 @@ +--- +title: 遗忘的乡音 +slug: the-forgotten-accent +date: 2012-08-28 15:06:44 +updated: 2020-09-06 12:28:53 +tags: + - 乡音 + - 故乡 +category: 文章 +summary: 似乎随着时代的发展、普通话的普及,我们越来越少听到儿时常用的方言、俗语。但是我相信,乡音已经融于我们的血脉之中,代代相传,无法忘记。 +cover: /images/2012/08/2012082820070400.jpg +--- + + + +<MusicPlayer netease={119429} /> + +似乎随着时代的发展、普通话的普及,我们越来越少听到儿时常用的方言、俗语。但是我相信,乡音已经融于我们的血脉之中,代代相传,无法忘记。 + +——题记 + +其实,我是一个从农村出来的孩子。已经记不清有多久没有重复这样熟悉的句子,或许只是无力地提醒,暗示自己不要忘记自己来自何方。也正是这样的表达,赤裸裸地预示着我早已远离了家乡…… + +对于目前大多数的乡下人来说,其实我们早就离开了赖以为生的土地,来到城市。要么是以读书的方式(高考),要么就是直接进城务工。乡村与城市的生活代表着两种极端,城市的现代生活气息吸引着每一个来自农村的人,灯红酒绿的街道让人陶醉。于是,大家都拼命地想脱离乡村,洗去身上的每一点土渣子气。乡音,便是最先遗忘的东西。 + +于是乎,南来北往的人们,一个个都操着流利的普通话,似乎你很难发掘出真正的外乡人。我老家是安徽的,家里人说话一口方言。我们那管鞋子叫海子,管做完事情叫歇火,大声说话叫秦西鬼叫,等等。在我心里,这乡音就像是一枚明晃晃的刺青,无时无刻不在提醒着周围的人们我是来自贫困落后的农村。所以,当我离开老家来到厦门的时候,马上便撇掉乡音,试着用不熟练的普通话和人交流。 + +离老家多年后,乡音也渐渐地遗忘,当我回老家高考的时候,我可以清晰地感觉到自己与它的脱节。周围的同学都操着一口方言交谈,我听不懂,也不会说,感觉就像是两个世界的人。可是我依旧固执地说着字腔正圆的播音腔,我讨厌那在外人眼里土得掉渣的方言,讨厌落后的故乡,渴望远离它…… + +道格·桑德斯在《落脚城市》里面说过:很多人宁愿在城市里过着朝不保夕的生活,却不乐意回到家乡。这其中蕴含着一种希望,那就是如果回到家里重复着父辈的生活,一辈子就会被困在土地上;而在城市中,发展的快节奏,机遇的巧合,自我的努力都会产生一种改变自我和改变命运的希望。他们依靠这种微薄的希望生活,哪怕生活在城市的最底层,遭受着各种形式的歧视与白眼,但仍能感觉到幸福就在不远处。 + +但是,世间一切没有什么不会改变,尤其是人更是善变的动物。远离父母亲人独自上了几年大学后,我愈发地怀念家乡的一草一木,甚至是那一直被我深刻厌恶的乡音。 + +重拾乡音的故事倒是很简单。今年过春节回家的时候,我竟不由自主地操起了好久不说的方言。8 年多没说,一开始倒是有点结巴,但随后便越说越流利。那些熟悉的声音,原来一直没变。 + +想想看,也许从出生那一天起,家乡那一片土地的乡音便深深烙印在我们的心里,融铸于我们的血脉之中。这乡音,与生俱来,代代相传。 + + diff --git a/src/content/posts/2012/2012-09-02-the-season-of-walking.mdx b/src/content/posts/2012/2012-09-02-the-season-of-walking.mdx new file mode 100644 index 0000000..e5c695f --- /dev/null +++ b/src/content/posts/2012/2012-09-02-the-season-of-walking.mdx @@ -0,0 +1,40 @@ +--- +title: 行走的季节 +slug: the-season-of-walking +date: 2012-09-02 00:51:18 +updated: 2020-09-06 12:29:00 +tags: + - 时光 + - 旅行 +category: 文章 +summary: 济南的夏天似乎没有了昔日的炎热。一个人坐列车回学校的时候,看着车窗外飞速变换的风景,心情却愈发地烦躁。有时四处想找人说话,但看着周围陌生的面孔,便会有一种疏离的味道。 +cover: /images/2012/09/2012090220180700.jpg +--- + + + +<MusicPlayer netease={1901728522} /> + +济南的夏天似乎没有了昔日的炎热。 + +一个人坐列车回学校的时候,看着车窗外飞速变换的风景,心情却愈发地烦躁。有时四处想找人说话,但看着周围陌生的面孔,便会有一种疏离的味道。 + +列车停停走走,终点越来越近…… + +不变的街道,熟悉的建筑,暮夏时分我又回到了旅途最开始的起点。望着路上来来往往的新生和家长,那种铭心的熟悉感由心中萌生。但是,如果不是再次遇见,却很难会想起曾经的画面。 + +不知怎么的,对于记忆总是有一种感触。许多事物,一旦分别,即使印象再深也会渐渐模糊、淡化、最后忘记。时光的无情,可以抹去一个人铭心的过去。 + + + +但是,忘得了一切,能忘记她吗? + +送云儿上火车的时候我差点哭了出来,我努力地微笑、挥手,将心中满满的离愁放下。那渐行渐远的火车,慢慢成了一个缩影。就像是灰白纸面上的一抹暗红,似乎停顿了时光的流走。 + +分别后的时光总是过得太慢,站台上的车来来去去,要等的她却迟迟未来。 + +再次见面的那一刹那,世界仿佛静了下来。粗重的呼吸,甜美的微笑,激动的目光在此时交织。千言万语到了嘴边只剩一句:“呦,回来了。” + +身后缓缓开动的列车,成为这灰色天际的一抹光影,在这漫天而坠的时光里,悠然远行…… + + diff --git a/src/content/posts/2012/2012-09-07-where-is-my-dream.mdx b/src/content/posts/2012/2012-09-07-where-is-my-dream.mdx new file mode 100644 index 0000000..bdbd0e0 --- /dev/null +++ b/src/content/posts/2012/2012-09-07-where-is-my-dream.mdx @@ -0,0 +1,33 @@ +--- +title: 最初的梦想在哪里? +slug: where-is-my-dream +date: 2012-09-07 13:31:14 +updated: 2020-09-06 12:30:46 +tags: + - 梦想 +category: 文章 +summary: 最初,算起来应该还是在小时候,我喜欢涂鸦,曾暗自想:以后要当个画家哦!安静地记录下所有美好。后来,由于一些原因,画没学成。 +cover: /images/2012/09/2012090720304800.jpg +--- + + + +<MusicPlayer netease={427419132} /> + +最初,算起来应该还是在小时候,我喜欢涂鸦,曾暗自想:以后要当个画家哦!安静地记录下所有美好。后来,由于一些原因,画没学成。于是就想:那当个服装设计师喽!让自己的设计成为流行。 + +再后来,服装设计也没学成,我又想:不如当个建筑设计师吧,让凝固的音乐充满生命力。 + +然后,建筑设计也失之交臂,再想:没事,当个结构设计师啦!只是由外观变成内部结构而已。 + +终于到了某一天,老爸老妈开始整日说:当初怎么不报师范?当老师多好!听得多了,便想:嗯,当个老师也不错呢!还有寒暑假期…… + +而最后,我开始从事软件工程。 + +如今,还没到回忆的年龄,我却总是回想起那些曾经的梦想,然后心便生生地疼,感觉像是少了些什么,虚无的、飘渺的、那些再也回不来的东西。恍惚间如同做了一个漫长的梦,天昏地暗的,我追着唯一的光亮奔跑,却总也跑不到尽头,学不会拥有。然后,唯一的光芒终于消失,我失去方向突然停下,心有戚戚而不知置身何处……只会自欺欺人地安慰着自己:也许,也许这一切的一切是个莫比乌斯带,就像轮回一样,无尽的旅途中终有一天会回到最初。而内心深处却不得不承认:其实这一切只能是一条一直向前的直线,只是在最初与我匆匆相交,然后擦肩而过,渐行渐远…… + +这些片段是我童年的一些记忆,尤其是那些已经无法实现的梦想。 + +梦醒时分,未来依旧继续…… + + diff --git a/src/content/posts/2012/2012-09-14-two-miscellany.mdx b/src/content/posts/2012/2012-09-14-two-miscellany.mdx new file mode 100644 index 0000000..930a533 --- /dev/null +++ b/src/content/posts/2012/2012-09-14-two-miscellany.mdx @@ -0,0 +1,46 @@ +--- +title: 二人杂记 +slug: two-miscellany +date: 2012-09-14 11:00:22 +updated: 2020-09-06 12:30:08 +tags: + - 文字 + - 花儿 +category: 文章 +summary: 巧合其实无处不在,只要留个心眼。上午的时候,我想今天的文章就写“那些花儿”吧。下午的时候,校广播台就在放范玮琪的“那些花儿” +cover: /images/2012/09/2012091420462600.jpg +--- + + + +<MusicPlayer netease={1876460058} /> + +## 那些花儿 + +巧合其实无处不在,只要留个心眼。上午的时候,我想今天的文章就写“那些花儿”吧。下午的时候,校广播台就在放范玮琪的“那些花儿”——“那片笑声让我想起我的那些花儿,在我生命每个角落静静为我开着……” + +母亲是一个爱花之人,家里曾养过许多花草,很多都慢慢枯萎忘记了,印象较深的一个是茉莉花。之所以印象深刻是因为茉莉花开,极芳香。如今想来,只记得是很香,甚至有点美化的意味,真正的记忆却已经淡漠了。花儿小小的,本来是白的,随着时间的推移慢慢地变黄色。届时,母亲会把花剪下来,晒干后可以泡茶来饮用。至于茉莉花茶的味道却没什么印象,想来不是很美味。不知何时,不知何因,茉莉花淡出了我家的生活,不见了。 + +另一个是含羞草,记得这个的原因更明显,因为它很好玩。只要触碰叶子经脉,两边的叶子就会合在一起,然后垂下来,相当有意思。似乎以前我还对它做过一些小实验,检验何种程度的刺激不会引起人家害羞。现在想想,才发现家里曾经有过的小动物或者植物都是不知不觉就不见了,若不是忘记了,就是事情发生在我上学期间,而我又没注意到。╮(╯▽╰)╭ + +最后一个是水仙,理由是她长在水里,不需要泥土。也因此觉得水仙很纯净,但,其实那只是错觉。我家的水仙花冠色青白,花萼黄色,花被6瓣,中间有金色的副冠,形如盏状,花味清香,所以叫“金盏玉台”亦名“酒杯水仙”,花期约半个月。曾经写过一篇作文就以水仙为对象,题为“凌波仙子”。而且,水仙常常在春节期间开花,那时大家齐聚一堂,水仙花是很漂亮的装饰,相当能吸引弟弟妹妹们的注意力,防止他们捣乱。 + +“但是,如今这里荒草丛生没有了鲜花;好在曾经拥有你们的春秋和冬夏……” + +说是荒草其实不确切,应该是芳草,现在家中养的是芦荟和兰草,对它们的印象不多,可能是因为我远在山东,很少在家。不过,在家的时候,都是我给它们浇水。 + +“我们就这样,各自奔天涯……她们已经被风吹走散落在天涯……” + + + +## 矛盾的文字 + +> 文学是指以语言文字为工具形象化地反映客观现实的艺术,包括戏剧、诗歌、小说、散文等,是文化的重要表现形式,以不同的形式(称作体裁)表现内心情感和再现一定时期和一定地域的社会生活。 + +有时候,也只是随便写写而已,并没有想要表现内心情感的想法。但是,感觉很有趣的是,情感就像水流一样在字里行间流动,让我想起了《虫师》中的淡幽和她那些活着的文字。不过,有一千个读者就有一千个哈姆雷特,也许传递给别人的感情会千差万别,甚至南辕北辙。于是,我时不时地回顾自己所写的文字时,也能从中发现一些新的感情。但是当时我应该没有那一层的意思,至少在显意识上是这样的。 + +显意识和潜意识如同光和影一样相生相灭。大概,在不知不觉中,潜意识躲开了监察官,将一些思想注入到我的所书写的文字当中。而当我回顾时,这些情感就像春天到了一样,争先恐后地破土而出。有时让我十分惊喜,有时让我羞愧万分。 + +其实,把自己所写的东西给别人看,就像是脱光了衣服站在大街上一样让人难为情。情感这种东西,无论怎么说都是比较私人的。再加上,人非圣贤,孰能无过,在我文字也会显露出我的许多缺点和懦弱,卑鄙等等。但是却又像皇帝的新装一样,明明大家都看见了,却未必认为自己看见了,或者认为自己看错了。当然有时候,是真的看错了(笑=W=)。 + +但是,人又是社会的,希望得到他人的认可与接纳,希望别人了解自己。于是,我们也需要展示自己。就像模特或者公众人物一样,出现在镁光灯下。 diff --git a/src/content/posts/2012/2012-09-18-hello-tomorrow.mdx b/src/content/posts/2012/2012-09-18-hello-tomorrow.mdx new file mode 100644 index 0000000..e37f8c5 --- /dev/null +++ b/src/content/posts/2012/2012-09-18-hello-tomorrow.mdx @@ -0,0 +1,38 @@ +--- +title: 明天,你好 +slug: hello-tomorrow +date: 2012-09-18 12:37:11 +updated: 2020-09-06 12:30:37 +tags: + - 未来 + - 明天 +category: 文章 +summary: 忘不了我们俩的那次奔跑。这是我记忆中的画面,炎热的午后,我和雨帆一起追着刚刚离站的 119 路公交车奔跑在城市的街角。 +cover: /images/2012/09/2012091821131300.jpg +--- + + + +<MusicPlayer netease={1917191859} /> + +忘不了我们俩的那次奔跑。 + +这是我记忆中的画面,炎热的午后,我和雨帆一起追着刚刚离站的 119 路公交车奔跑在城市的街角。幸亏红灯,让我们创造了从校门赶上车的惊喜。上车时我回想刚刚我们狂奔的样子——你挎着个单肩包,在人流车缝间奔向前面的 119。而我,穿着凉鞋,亦步亦随地跟在后面,手里举着相机,试图用快门记录下这极具喜感的身影…… + +想来,我俩只是为了赶赴山师的那一场毕业摄影展,好像要努力去抓住一些自己不愿失去的东西,那是大学稀少的时光印记。摄影作品中几多乖僻,几多平凡。在环形的展台边写着他们的毕业誓言——“今天,我们在这里展示我们的成果,明天我们将带着新的梦想起航。” + +昨天和今天说着再见,奔向明天。再见,有谁会喜欢上说“再见”呢? + + + +静静地听着关于作品的阐述,我偷偷按下快门,想象着还有多久就该自己被围观,抑或也会像学姐学长那样选择宅在自己的田地里,开始无比吝啬在校园里的每一次出现……那个时候的自己又会是什么样子呢?是心怀坎坷强装着老成地给学弟学妹们分享经验,把几年的学习工作游玩经历打包作程式化的三言两语给他们增添未来道路上的曙光;是混迹在跳骚市场,粗枝大叶地清理出曾经视若珍宝的物件连同记忆一起贩卖;还是依旧想要做一个静好的女子,悠忘岁月赖群书…… + +雨帆你一直都不愿我去过多地猜想我们以后的样子。只是,我活在这个时间的维度里,无法像你一样释然地去看待我们在岁月里的痕迹。于是,我止不住地遐想,猜想着会在哪一天遇见未知的自己。 + +然后在去图书馆还书的路上遇见一群可爱的中学生由老师引导着来来去去,其中不乏一些巴巴张望着路上学子的眼睛。我想,他们是不是怀揣着无数关于未来象牙塔的斑斓梦想?而旁边,是忙着毕业留影的学长。学士服里的祭奠情结即将把他们的大学时光裹挟而去,融入未知的现实社会。在憧憬进入和行着离开的交接里我看到了一座亘古的围城…… + +只是,我自己身在其中,不曾想过要抽离,因为一直相信着“生命贵在经历”的言语。在这个收获的九月里,即使受着委屈招着埋怨,细细想来却也无悔。于是就慢慢学会了受着刺激说着“不负厚望”的话,然后在这纷繁交错的人事里记着要淡定,抓紧仅有的时光际遇,以此来纪念那些流过的眼泪、受过的委屈以及被无私给予的力量。 + +在命运的广场中央,我要想今天一样,笑着奔跑。说一声:“明天,你好!” + + diff --git a/src/content/posts/2012/2012-09-27-the-feeling-of-love.mdx b/src/content/posts/2012/2012-09-27-the-feeling-of-love.mdx new file mode 100644 index 0000000..608596c --- /dev/null +++ b/src/content/posts/2012/2012-09-27-the-feeling-of-love.mdx @@ -0,0 +1,34 @@ +--- +title: 喜欢的感觉 +slug: the-feeling-of-love +date: 2012-09-27 10:39:05 +updated: 2020-09-06 12:30:49 +tags: + - 爱 + - 眼泪 +category: 文章 +summary: 人活着是不是会有很多来不及。比如,说一句未说出口的话对一个来不及的人。 +cover: /images/2012/09/2012092721182400.jpg +--- + + + +<MusicPlayer netease={406232} /> + +人活着是不是会有很多来不及。比如,说一句未说出口的话对一个来不及的人。 + +有一次约你出来,然后你问我找你干嘛。我……我半天说不出来。其实我只是突然觉得,如果明天是世界末日的话怎么办,然后就把你约出来,见一面。 + +送你离开,想抱抱你。但觉得现在抱了的话,以后怎么办?还是算了吧。 + +我喜欢每次去找你的时候的自己,因为要反复考虑,挣扎很久。像虐待即将渴死的鱼,一点一点,终于要受不了。 + +我也不想喜欢一个人喜欢得那么累。我一直不能放弃你。是因为,我真的没办法接受,别人陪在你左右。 + +如果在我的生命中真的有一个你。那么,可不可以,请你,早点出现。我不知道你在哪里,但却不会分裂得难受。 + +如果我去过你曾经住的地方、走过你走的路、看过你看的风景。那,是不是就能离你近一点?请原谅我,我真的没有办法不让自己这么说。毕竟你一直是,我全部的眼泪。 + +——2011 年 3 月草长莺飞时的情书 + + diff --git a/src/content/posts/2012/2012-09-30-i-love-you-forever.mdx b/src/content/posts/2012/2012-09-30-i-love-you-forever.mdx new file mode 100644 index 0000000..880f52c --- /dev/null +++ b/src/content/posts/2012/2012-09-30-i-love-you-forever.mdx @@ -0,0 +1,29 @@ +--- +title: 最喜欢的人,是你 +slug: i-love-you-forever +date: 2012-09-30 03:17:59 +updated: 2020-09-06 12:31:09 +tags: + - 爱情 +category: 文章 +summary: 当天空出现太阳的时候,就不可能再有月亮的存在。人生就是一部不可复制的电影,没有后退也没有快进,我最期待的那个结局就在这里,所以我没有任何遗憾。 +cover: /images/2012/09/2012093021252300.jpg +--- + + + +<MusicPlayer netease={1852070279} /> + +当天空出现太阳的时候,就不可能再有月亮的存在。 + +人生就是一部不可复制的电影,没有后退也没有快进,我最期待的那个结局就在这里,所以我没有任何遗憾。 + +你指间的温柔流过我寒冷的心沟,温暖舒适如春季的阳光,你嘴边的微笑穿过我紧闭的心墙,灿烂可爱如春季的花香。舍不得你的手,忘不了你的笑,便选择拉着你的手接受你的笑。 + +无奈的人生给了我们太多的阴差阳错,无知的未来却可以让我们望而却步,是因为过去和现在让我们失去了追求?但,最终还是遇见了你,最喜欢的人是你,万千个喜欢却不知道怎样说出口,你懂我的心,所以我相信你会明白这一切。 + +恍如梦境,世间的事太多太复杂太变换,我们总是措手不及然后又被命运安排。谁是赢家呢?不知道,但是我不是输家,因为这是我内心的选择。 + +最喜欢的人,是你! + + diff --git a/src/content/posts/2012/2012-10-28-the-memory-of-smell.mdx b/src/content/posts/2012/2012-10-28-the-memory-of-smell.mdx new file mode 100644 index 0000000..c2c75c4 --- /dev/null +++ b/src/content/posts/2012/2012-10-28-the-memory-of-smell.mdx @@ -0,0 +1,40 @@ +--- +title: 香味的记忆 +slug: the-memory-of-smell +date: 2012-10-27 21:00:16 +updated: 2020-09-06 12:31:29 +tags: + - 香味 + - 自然 +category: 文章 +summary: 前些日子在淘宝上买了一块手工香皂,洗衣服时无意间弄错了香皂,以至于这些天衣服上总带着股淡香,干净纯洁而又温柔的味道。秋雨初晴的午后,我和云儿携手行走在校园里,甜韵的檀香混杂着泥土特有的芬芳,空气凉凉的,紧握的手暖暖的。 +cover: /images/2012/10/2012102720033500.jpg +--- + + + +<MusicPlayer netease={1913262091} /> + +前些日子在淘宝上买了一块手工香皂,洗衣服时无意间弄错了香皂,以至于这些天衣服上总带着股淡香,干净纯洁而又温柔的味道。秋雨初晴的午后,我和云儿携手行走在校园里,甜韵的檀香混杂着泥土特有的芬芳,空气凉凉的,紧握的手暖暖的。雨后的空气里香味来得分外浓些,嗅在心里绵绵地化不开。云儿笑着说:“这就是恋人间的味道吗?” + +一直以来,对于香味都有一种特别的追求,我喜欢那种不张扬、不呛鼻、不浪漫的香味,素雅内敛,就像我们的传统审美,恬淡而深邃。比如腊梅香、茶香、竹香之类的,袅然散发之际,内敛芬芳。 + +最怕的是洗发水的味道,同样还有空气清新剂。无论它们的香味是多么婉约祥和,或是与真实的香味出奇地一致,但总不喜欢那种刻意的感觉。那种煞费苦心使用各种香料、药剂搭配出来的香味,没有了本身自有的源香,反而浓重得有些令人窒息。 + +表弟晨晨才满月时,一家人去探望,到的时候才刚洗完澡,抱过手便闻到一股体香,淡淡的,嫩嫩的,又柔柔的,有一种奶香的甜沁。于是满怀好奇地问了表弟用的沐浴露的牌子,可是买回来用过后,才发现不是沐浴露的味道。那种香味,是婴儿小小的身体所自然散发的、温馨的味道。 + +90 年代初时,家具还是要请木匠自制的,当时妈妈的嫁妆便是一整套檀香木打造的家具。衣服在衣橱放久了便会带上一股厚重的木香,那种婉约祥和的香味,自然而然地让人联想到“儒雅”两字。坐在同样是檀香木打造的书架前看书久了,便会喜欢上那股木头的气味,那种既有些香同时又隐藏着无可言说的味道。 + + + +而如果问我夏天的味道是什么,我想我能想到的便是竹子的味道。家住皖南,山区多毛竹,所以一到了夏天满屋飘散的都是新制竹器的清香味,竹凉椅、竹席、竹篮、竹枕席、竹竿……所以家乡有一顺口溜叫:“小时青青腹中空,长大头发蓬蓬松,姐姐撑船不离它,哥哥钓鱼拿手中。”讲的,便是竹子。青涩的竹子最后变黄变得光滑、温润,但仔细抚摸轻嗅还是能品出股先天的内敛秀劲。 + +暑假和妈妈逛超市的时候看见了竹枕头促销 20 元,其实也就是竹皮编成的枕头布,里面塞满了废弃的茶梗。谈不上舒服,但那股清香的气味与茶叶的芬芳,让我一闻就走不动路了,立刻买了两只。 + +买回来还没用多久,茶香和竹香便挥发得所剩无几,只有将鼻子贴上去时才能闻到若有若无的暗香,好生邈远。虽然买的时候已经预料到了这种情况,但香味存留之短还是让人有些埋怨。 + +想来香味还是自然点的好,缕缕恬淡、见素抱朴。也只有这样的香味让人闻起来,舍不得一下子吸进肺里,要慢慢缓缓地呼吸上一阵。 + +这,是香在心上的一丝儿。 + + diff --git a/src/content/posts/2012/2012-11-07-ccf-meeting.mdx b/src/content/posts/2012/2012-11-07-ccf-meeting.mdx new file mode 100644 index 0000000..bd37961 --- /dev/null +++ b/src/content/posts/2012/2012-11-07-ccf-meeting.mdx @@ -0,0 +1,74 @@ +--- +title: 亦行亦走 +slug: ccf-meeting +date: 2012-11-07 14:33:22 +updated: 2020-09-06 12:35:01 +tags: + - 记忆 + - 旅行 +category: 文章 +summary: 开始读余秋雨的《出走十五年》时还在上高中,学习的枯燥、束缚让我对于旅行有一种近乎本能的渴望。于是大学填志愿时我选择了与厦门相隔大半个中国的济南,从遥远的南海之城远行千里来到这北国之都。 +cover: /images/2012/11/2012110720214400.jpg +--- + + + +<MusicPlayer netease={1475737587} /> + +开始读余秋雨的《出走十五年》时,我还在上高中。学习的枯燥和束缚让我对旅行有一种近乎本能的渴望。于是大学填志愿时,我选择了与厦门相隔大半个中国的济南,从遥远的南海之城远行千里来到这北国之都。 + +往返的次数多了,也就腻了,没有什么新奇可言。无非就是这些,蹉跎也好,枯燥也罢,都只是一种意味,一样的色彩。 + +不知从何时起,我开始习惯一个人旅行、一个人行走,习惯在短暂的行程中做一个寂寞的人,恋上这种单纯与简单的旅程。或许是厌倦了繁华世态,内心更加坚决地想要拥有一份安静与纯粹。 + +时常会想,自己喜欢的究竟是旅行的过程,还是那未知目的地的暂留。千帆过尽,回首当年,那份年少时志在行走的梦想已经消失殆尽。渐渐迷恋上的是一种不愠不火的生活,不奢求多少爱,也不会有多少怨,无论快乐与否,都要笑着面对。 + +那,为什么内心愈加空落? + +想来我还是没能忘记,或者说那种感觉深藏于心,对于旅行目的地到达的惊喜和期待一直伴随着我。直到今天,我还可以细数刚到济南时的百感交集,那是生命中不可或缺的感触。 + +而现在,我将讲述的将会是另一个关于旅行的故事…… + +——引子 + + + +金秋十月,伴着梧桐落叶的簌簌声,我参加了山大软件学院组织的 2010 级学生大连实训活动。如今回想,收获颇丰,感触良多。 + +迎着清晨的第一缕曙光,我踏上了开往大连的长途客车。窗外的天起初还是灰蒙蒙的,像极了此刻我迷茫的心情。渐渐地,天亮了。随着旅途的推进,外面有时是一望无际的盐滩,有时是连绵的山丘,有时是望不到边际的平原。漫长的路途让人寂寞乏味,但车厢内同学们的欢声笑语总让人莫名心安。 + + + +出发 19 个小时后,我们来到了未来五天的宿营地——大连河口软件园。与班级大多数同学不同,我们被分配到与东软的三个员工同住的宿舍。虽然到宿舍时已经是子夜时分,但那三位大哥哥们都还没有入睡,简单交流了一会儿后便分别道了晚安。 + +不知怎么的,夜里总是无法入睡,侧趴在床上,望着窗外黑漆漆的夜,心中想的更多是未来三天的猜想。是期待?还是害怕?可是,这又有什么关系呢?既然选择了远方,便只顾风雨兼程。 + + + +18 号一早,天还未亮我们便开始集合。夜里的失眠让早起的我有些昏沉沉的,但陌生城市的新鲜与兴奋让我忘记了疲劳。9 点,我们来到了大连世界博览广场。由于时间紧迫,我们还没看清路就被引导员匆匆带进会场(后来才知道会场的工作人员全是大连大学的学生志愿者,笑)。今天我们参加的大会是由 CCF 中国计算机协会联合大连大学、大连市政府举办的 CNCC(China National Computer Congress)2012 中国计算机大会。进入会场时,前台的大屏幕上循环播放着大连大学的宣传片,但其实内心还是瞧不起大连大学的,笑╮(╯▽╰)╭。 + +待参会人员全部入场后,期待已久的计算机大会便正式开始了。我该怎么评价呢?整个大会气氛热烈,与会人员空前高涨,大家在此学习到了许多东西,那是骗人的。9:00~9:42 的开幕式毫无任何价值可言,一言以蔽之——中国特色。充其量就是认识了协会的几位主要人员,几位政局的牛人,ACM 的两位主席候选人。 + +随后的大会特邀报告受益颇丰,但也局限于前两个。第一个是 1994 年图灵奖获得者、美国卡内基梅隆大学计算机学院教授 Raj Reddy 做的关于 “Educating a Child Machine: The Unfinished Agenda of Human-level AI” 的人工智能方面的报告。 + + + +刚听这个报告时我是有点不屑的,因为到目前为止,以现有的计算机体系结构都无法实现随机数生成。但 Raj 教授从图灵机开始,以人脑学习过程、结构类比的报告给我们展开了人工智能的另一个新方向——混合智能。目前所谓的人工智能成果,大都得益于信息存储、统计推理、决策模型及数值计算方面的研究进展。但就模拟人类思维过程和智能行为这两个具有里程碑意义的智能属性而言,仍然缺乏突破性科学技术成果。Raj 教授从生物脑模型为基础,阐述了计算机学科目前正以神经学为基础构建智能计算机系统。由此,此行最大的收获也就是对生物脑信息感知方面的内容有了新的认识。 + + + +第二个报告开始之前有长达半个小时的休息时间,但我的问题是,为什么在这个时候大家都走了,只剩下不到百人?说好的组织到 11 点呢?第二个报告是香港中文大学的常务副校长华云生做的关于网络多媒体传播的讲座:Joint Optimization of Video and Audio Quality For Real-Time Video Conferencing。华校长一口流利的英语让人印象深刻,不过整个报告并没有多少学习的内容,只是介绍了以抓包和钩子函数方式对网络 IM 聊天工具在不同带宽下的通信测试,最后人为计算出延迟数的设定来优化通话质量。由于华校长的演讲速度很快、中文很烂、听不清楚,大体上了解的就这些。 + +第三个报告本来应该由王坚(阿里巴巴的首席技术官)做的,但是由于行程安排的原因临时换了人,结果很水,只能说是变相的阿里云广告。但也有收获,就是一直很时髦的云计算充其量也就是一个数据中心,云计算的说法也只是一种包装。 + +随后上午的大会便这样结束了,很遗憾,我这个穷学生无法在会场附近找到任何一家消费得起的餐馆。坐了十分钟的公交车晃晃悠悠地来到大连大学城吃了一顿自助餐,真贵! + +下午的专题论坛专门去听了高性能计算的部分,到的时候浪潮的高级副总裁王思东老师正在讲述高效能计算机架构应用与创新。说实话,就是变相推销他的服务器的。系统软件论坛中关于淘宝架构的介绍,展示了基于开源软件构件的淘宝帝国。 + + + +之后,我便去看了科技成果展。个人觉得有一种作秀的嫌疑,区区 56 个展位中,大连大学独占了 50~56 号展位,是因为大连大学出钱协办吗?在这些展览中,最吸引我的是阿里云的展位。以前我试用过一些云主机,但对于阿里云的了解,还是第一次。阿里云的技术总监林晨曦先生详细介绍了阿里云现有的经营项目。对于我提出的“阿里云为什么不做云分发(CDN)”的问题,他解释道,小客户赚不了钱,主要是专门为大客户提供服务。最让我惊喜的是,场中的一位阿里云老总还送了我一张一个月的阿里云代金券(好激动)。 + +随后两天的行程都是游玩,现在大都记不清了…… + +回济南的路上,窗外一直下着大雨,猛然间,感觉像是做了一场梦。 diff --git a/src/content/posts/2012/2012-11-11-cherry-blossoms.mdx b/src/content/posts/2012/2012-11-11-cherry-blossoms.mdx new file mode 100644 index 0000000..40237b7 --- /dev/null +++ b/src/content/posts/2012/2012-11-11-cherry-blossoms.mdx @@ -0,0 +1,32 @@ +--- +title: 樱花烂漫 +slug: cherry-blossoms +date: 2012-11-11 03:20:26 +updated: 2020-09-06 12:35:13 +tags: + - 动漫 + - 小樱 +category: 文章 +summary: 总有很多事情是我们所不知道的,或早已经忘记的。也许它们并没有被忘记,只是遗留在记忆深处罢了。 +cover: /images/2012/11/2012111120345400.jpg +--- + + + +<MusicPlayer netease={555959} /> + +总有很多事情是我们所不知道的,或早已经忘记的。也许它们并没有被忘记,只是遗留在记忆深处罢了。 + +就像我这个 90 年代初生的人,关于童年的动漫记忆,不过就是寥寥几部而已。然而,就是这寥寥几部动漫,却在童年这个珍贵而短暂的人生阶段上,划过一条条美丽的星辉。若是给每个动漫加上一个标签,我想《龙珠》会是热血,《Touch》将是青涩,《名侦探柯南》是智慧,《足球小将》是拼搏,还有本文的主题《魔卡少女樱》则是魔幻。我们的魔法记忆,从这里延伸。 + +CLAMP 为我们带来的想象,在每一集都是不同的。不同的库洛牌,不同的小樱装,不同的魔法。然而,一样的是小樱那樱花般的笑容和她华丽的变身。在小樱的魔法世界里,我们沉醉,我们翘首以盼,期待下一集的精彩。 + + + +在我看来,小樱的世界,魔法不是全部,也许只是次要的。它不过是一个载体,承载着小樱与家人的亲情,小樱与伙伴的友谊,小樱和小狼的爱情。不仅仅是无尽的魔法,还有纯真的愿望。这些所有的美好,在星之杖触击库洛牌时被完美释放,在 CLAMP 的大姐姐们的温柔笔触间尽现纸上。如果说,看似冷饭再炒的《翼·年代记》是 CLAMP 展现给年轻一代的一种世界价值观,那么,《魔卡少女樱》就是 CLAMP 奉献给我们的最为纯净的美好愿望。 + +请记住那个穿着水手服、脚踩轮滑鞋的女孩,记住那樱花般境遇里与她的邂逅。 + +樱花烂漫里,我们的故事才刚刚开始…… + + diff --git a/src/content/posts/2012/2012-11-15-the-elegant-past.mdx b/src/content/posts/2012/2012-11-15-the-elegant-past.mdx new file mode 100644 index 0000000..ad79cba --- /dev/null +++ b/src/content/posts/2012/2012-11-15-the-elegant-past.mdx @@ -0,0 +1,35 @@ +--- +title: 优雅的旧时光 +slug: the-elegant-past +date: 2012-11-15 02:18:45 +updated: 2020-09-06 12:35:19 +tags: + - 随笔 +category: 文章 +summary: 周一晚上,考完经济双学位考试后,我在回软件园的公交车上睡着了。被雨帆的电话吵醒时,正好眼睁睁地看着错过了要下车的站点,坐到了齐鲁软件园站。想来长达半个小时的车程,怎么每次都睡得这么深沉呢? +cover: /images/2012/11/2012111521361400.jpg +--- + + + +<MusicPlayer netease={1357953768} /> + +周一晚上,考完经济双学位考试后,我在回软件园的公交车上睡着了。 + +被雨帆的电话吵醒时,正好眼睁睁地看着错过了要下车的站点,坐到了齐鲁软件园站。想来长达半个小时的车程,怎么每次都睡得这么深沉呢?下车的时候已经是夜里九点,但幸好只错过一站。思前想后,决定走回去。深秋的济南才下了一场雨,夜里独自走在人烟稀少的人行道上,总感觉空气那么湿冷。身边偶尔擦身而过的情侣提醒着我的孤单,让我不由得回想起刚刚过去的夏天,一如既往的思念弥漫的季节。我想,那时的你也许和我一样,一个人走在回家的路上,怀念着我们在一起的旧时光。又或许,不会…… + +一个人的时候,总是羡慕那些在风雨中相伴漫步的情侣,羡慕那些在长椅上温柔依偎的恋人,更羡慕像父母一样提篮买菜的老夫老妻。在当今通信如此便捷的年代,我不知道为什么总是满怀这么多的想念。 + +曾几何时,我也做过那柔情的人儿,为花开低眉,为云朵驻足,为萌芽而感动。我将一切的思绪埋藏在阁楼的笔记本里,用满是华丽的词藻去替代细腻的感触。这世间的女子,我想都有过相似的优雅,素然却令人心动,回首间让人有了一种不敢轻触的美好。 + +周三的上午没有课,一个人在寝室听了一个早上的广播剧《致我们终将逝去的青春》。辛夷坞用满怀温情的笔触写着:“青春就是用来追忆的。当你怀揣着它时,它一文不值。只有将它耗尽后,再回过头看,一切才有意义。爱过我们和伤害过我们的人都是我们青春存在的意义。”想起某次在淘宝上看到一位同龄人将自己二十岁的身体拍照做成明信片纪念,似乎年轻的美好在那个时候统统凝结——永远年轻的二十岁。 + +听着广播剧,看着人人网大家的状态,发现失恋很久的闺蜜写道:“越来越爱。”我替她高兴,因为她终于找到了自己喜欢的人。我一直坚信着,善良美好的孩子,怎么会不幸福? + +妈妈说过,女孩子要开朗、要坚强、要温柔、要活泼,要相信美好,要带着一点纯真而活。仰起头看着阳台外枯萎的梧桐叶摇摇欲坠,细碎的阳光透过叶隙散落在我的眉角,我习惯性地打了一个大大的喷嚏。时间素淡如水地流逝,简单就是最好的日子。就像现在,一个人在宿舍,听着 QQ 语音里雨帆的絮叨声,写下这些字,回忆才刚刚过去的些许小事。内心淡然安稳,但还没到万事波澜不惊的境地,只是这样也没关系。活着,何必费心于计较心情,想着天天可以遇到好事情。 + +但其实每个人都明白,人生没有绝对的一帆风顺。既然我们都只是过客,为何不携一颗从容恬淡的心,走过山重水复的似水年华,笑看风起尘落的人间,许一世安然。淡淡红尘,淡淡心境,淡淡而来,淡淡而走。 + +优雅的旧时光里,浅笑嫣然。 + + diff --git a/src/content/posts/2012/2012-11-28-the-third-year-of-loney.mdx b/src/content/posts/2012/2012-11-28-the-third-year-of-loney.mdx new file mode 100644 index 0000000..cfcd243 --- /dev/null +++ b/src/content/posts/2012/2012-11-28-the-third-year-of-loney.mdx @@ -0,0 +1,37 @@ +--- +title: 一个人的第三年 +slug: the-third-year-of-loney +date: 2012-11-28 14:39:40 +updated: 2020-09-06 12:35:42 +tags: + - 孤独 + - 三年 +category: 杂思 +summary: 听风者,不听风,只为繁花一落尽,君辞去。望星者,不望星,只为明月一思乡,君欲归。 +cover: /images/2012/11/2012112821464700.jpg +--- + + + +<MusicPlayer netease={2134293836} /> + +> 听风者,不听风,只为繁花一落尽,君辞去。 +> 望星者,不望星,只为明月一思乡,君欲归。 + +偶然间收到高中前女友的 QQ 消息:“好久不见。” + +此时正好是下午,冬日的阳光不是很充足,依然透着股寒意。看到消息的那一刹那,心里茫然间有些恍惚。高中毕业后只身一人来到济南求学,就不再去想起一些人和事,匆匆碌碌地在城市的角落奔走,一直不知道自己在想什么、为什么而忙碌。如果说以前的我追寻的是一个比较遥远的目标,那现在的自己追寻的就只是一个似有若无的影子,明知道已然机会渺茫,却仍然不舍得放弃。只顾仰望着星空的人注定不会留意到自己下一步是否会跨入深渊。 + +“三年了”,我应道,“真的很难想象,我们竟然有三年没见面了。有时候我会有种错觉,我们现在还在上高中,而这一切都是梦。” + +“呵呵”,回复很短,苍白无力,昔日无话不说的好友什么时候连最简单的寒暄都说不出来了? + +“分别了这么久,你变了没有?”我的手指在发送键上迟迟没有按下去,最后颓然地删除那一行字叹气。 + +手中的《读者·原创版》已经是 12 月,翻开一看,映入眼帘的是“一年过得真快啊!”这是世界上最温暖的一句话,因为它在不同的年份、不同的人、和不同的环境底下反复听到,总难免沾染上人心的温度。这也是世界上最寒冷的一句话,因为它提示着时间的流逝,往昔时光难再。但忽而某日有讯息给自己,或是牵挂的人对自己问一声好,却让自己感动不已,还算没有被人遗忘。就像是心中的那份简单的珍存,顾忌着每一个人的感受,然后仔细认真地回复,又惴惴不安地等待着下一句。有时甚至想把那简单的回复拆分为一撇一捺仔细品味,就像是一种不安,又像是期待。 + +一个人的时候,容易联想到孤单的滋味。也正如徐思贤写的那样:我们会卸下坚强的外壳,露出那颗也曾有过伤怀的心,想想在记忆中流淌的一些人,一些事。而相聚和离别,仿佛一个转身,一圈接着一圈,连缀成生命的舞蹈。陆陆续续地有人从我们生命里走过,遇见、分开或是最后的相依,这是生活也是无奈的必然。 + +一个人的第三年,自己对自己说:“不寂寞”。 + + diff --git a/src/content/posts/2012/2012-12-10-the-meaning-of-independency.mdx b/src/content/posts/2012/2012-12-10-the-meaning-of-independency.mdx new file mode 100644 index 0000000..b6238ba --- /dev/null +++ b/src/content/posts/2012/2012-12-10-the-meaning-of-independency.mdx @@ -0,0 +1,46 @@ +--- +title: “独立”的意义 +slug: the-meaning-of-independency +date: 2012-12-10 14:49:28 +updated: 2020-09-06 13:14:58 +tags: + - 独立 + - 90后 +category: 杂思 +summary: 无意中看到陌生人的几句话,短短的几句话,总结的及其到位。我无法再进行简单的转移,顺着他的精辟,繁琐的回味一下好了。 +cover: /images/2012/12/2012121021594300.jpg +--- + + + +<MusicPlayer netease={1961264446} /> + +无意中看到陌生人的几句话,短短的几句话,总结得极其到位。我无法再进行简单的转述,只能顺着他的精辟,细细地品味一下。 + +我们这一代人。 + +因为是独生子女,生活上便缺少同代人的交流。与父母之间又存在代沟,于是下意识地开始“封闭自我”。因此,在人与人沟通上,我们很成问题。 + +因为是独生子女,生活上便“衣来伸手,饭来张口”。我们往往幻想自己是某个世界的国王,这种高于人群的优越感,造成了我们的“国王意识”。 + +在封闭的基础上,再加上“国王意识”,我们怎么可能和别人真心地交往呢? + + + +当我们步入社会,首先要扛过前期的思想排斥,明白所谓的“生存”。开始思考自己的攻击武器和弱点。因为有弱点,所以需要盾牌,我们需要互补的同伴。 + +但是,在“不能真心交往”的基础上,同伴之间如何交流?于是,我们只是在相互利用。盾牌需要加强的时候,目的达到的时候,团队便随之瓦解。 + +所以说,我们确实是要改变自己。 + +或许某些人把“感情的利用”和“盾牌的替换”说得理所当然,毕竟这是他们生存下来的经验之谈。但就算如此,随着他们自身的强大和精神上的孤独,也会渐渐意识到自己的缺失。 + +为了生存,我们可以改变,但“真心的交往”和“庶民意识”真的一个都不能少。 + +当我们口口声声地把“孤独”和“自私”歪曲成“独立”,想想自己:是否依赖着父母?是否把同伴当成盾牌?所谓“独立”,是这样的吗? + +当那些“真心的交往”的片段,一条条地缓缓映过;当那些被我们扔掉的“盾牌”原谅我们的“过错”;当我们展开尚未硬朗的翅膀,想开始艰苦的独立旅程的那一刻; + +我们是否误解了“独立”的意义呢? + + diff --git a/src/content/posts/2012/2012-12-11-lend-me-more-time.mdx b/src/content/posts/2012/2012-12-11-lend-me-more-time.mdx new file mode 100644 index 0000000..fc807ad --- /dev/null +++ b/src/content/posts/2012/2012-12-11-lend-me-more-time.mdx @@ -0,0 +1,34 @@ +--- +title: 能不能给我一首歌的时间? +slug: lend-me-more-time +date: 2012-12-11 14:36:41 +updated: 2020-09-06 12:38:47 +tags: + - 情感 + - 时光机 +category: 文章 +summary: 每个人心里,都有着一架钢琴,弹奏着属于自己的乐章。这部乐章,叫做生命。雪霁,天晴,清晨的校园里朦胧地散发着昨夜的雾气,轻轻走过微湿的路面,看着久违的朝阳,茫然间有了种心痛的体悟。 +cover: /images/2012/12/2012121122120900.jpg +--- + + + +<MusicPlayer netease={2066670550} /> + +每个人心里,都有着一架钢琴,弹奏着属于自己的乐章。这部乐章,叫做生命。 + +雪霁,天晴,清晨的校园里朦胧地散发着昨夜的雾气,轻轻走过微湿的路面,看着久违的朝阳,茫然间有了种心痛的体悟。 + +就像是某一天,你在书店买了一本书或者是一张CD回家。那本书,翻过几页之后,就一直放在一旁。唱片只听过一次,便不怎么喜欢,于是长久放在抽屉里…… + +那些没看过的书,没听过的歌静静遗忘在时间的角落。直到某一天,偶尔间你在书架上发现了这本书,一看之下,竟有种相见恨晚的感觉。这么好的书,为何当初你会忘记它的存在?如果早一点看到,你的境界也许和现在不一样。然后,某个舒适的午后,你打开唱片架,无意中看到那张只听过一次的CD,你再次把它播出来,那动人的旋律和歌词竟使你震撼,原来你一直错过着这么好的歌。那时。为什么会不喜欢? + +一生中每个人总会有一、两本忘记了的书或一张没印象的唱片,时光流逝。偶然再会,才会懊悔自己曾错过了本好书,晚遇了首好歌。但也许,那不是遗忘,而是时间不对。第一次听那首歌的时候,它不能触动你心灵,因为大家心境不同。那本书无法让你惊讶,只因为当时你还没有那份阅历。 + +等待下一次的遇见,换个心态来看书,也意味着换个角度来生活。生活,本来就不该疲于奔命……有时候,一段属于自己的午后时光,一杯香茗或是咖啡,再加上一两本久置书架上的书。这,也可以是生活的全部。只是,一切仿佛已经渐行渐远,就像是很久以前某个时候听到的某段旋律,寻觅许久却终究仿若一场梦。 + +这个世界上,最无奈的东西恐怕就是时间了。不知不觉间,它便悄悄地远逝、流逝了,好像从来没有发生过一样。只是未来在我们身边的人,一直都在等待着,等着恰当的时光遇见,时间到了,你便会遇见并爱上他(她)。 + +时光机,能不能再给我一首歌的时间? + + diff --git a/src/content/posts/2012/2012-12-14-secret-of-boys-mind.mdx b/src/content/posts/2012/2012-12-14-secret-of-boys-mind.mdx new file mode 100644 index 0000000..5e9804b --- /dev/null +++ b/src/content/posts/2012/2012-12-14-secret-of-boys-mind.mdx @@ -0,0 +1,43 @@ +--- +title: 男孩子的秘密心事 +slug: secret-of-boys-mind +date: 2012-12-14 14:53:58 +updated: 2020-09-06 12:39:02 +tags: + - 秘密 + - 心事 +category: 文章 +summary: 我来不及年轻,待明白过来时,只能选择认真地老去。暑假回老家时被外婆叫去收拾堂屋里的东西,这才想起当年由于老家房屋拆迁改建,很多不需要的东西统统收拾到外婆这儿。 +cover: /images/2012/12/2012121422380800.jpg +--- + + + +<MusicPlayer netease={29922800} /> + +我来不及年轻,待明白过来时,只能选择认真地老去。——三毛 + +暑假回老家时被外婆叫去收拾堂屋里的东西,这才想起当年由于老家房屋拆迁改建,很多不需要的东西统统收拾到外婆这儿。虽然都是童年时最为宝贵的记忆,但过了这么久了,很多物件都变得支离破碎,情感也淡了很多。我象征性地翻箱倒柜出一个看起来包装还不算太坏的小盒子,嬉皮笑脸地对外婆说:“剩下的您先帮我收着啦!” + +回到家正好家里没人,我轻轻在地阳台上打开盒子,扑面而来的是簌簌飞舞的灰尘。盒子里面装着的,只有厚厚的一沓日记本、几张写好但从未寄出去的信笺、过生日的时候为数不多的几个好友送我的贺卡……时间的流逝让它们变得泛黄、脆弱,我不得不盘腿坐下,小心略带颤抖地翻开这些纸张。这些本来就属于我的东西,却因时间的包裹而充满了未知的神秘与兴奋。我像是一头闯进了某个被秘密包裹的内心世界,好奇又满怀怀旧地审阅另一个真实的自我,情绪略微妙。 + +> “那么以前雨帆有喜欢的女生吗?” +> “会不会是从来都没谈过恋爱吧。” +> “你们知道吗,我上次还看见雨帆偷偷看梁萱姣看了好久哦。” +> “你们这群混蛋,别不知道乱讲好不好。”(°ω°〃) + + + +喜欢过谁?对于现在的我可能悲哀的连名字都记不清了,倒只剩下几个模糊的面孔和一张泛黄发霉的毕业照。过去门廊下摩摩挲挲扑腾打闹的日子一去不复返,猛然间回忆起时倒是饶婧璐的样子白皙明媚起来。中等个子,齐耳短发,笑起来时眼睛总会眯成一条缝……记得当时上小学二年级的我曾惊世骇俗地写过封情书给她,只是后来被人告发。而父母也对此一直惊叹不已。(耻ずかしい)以至于才上大学时每次打电话,我那腹黑的老爸便会调侃我说:“怎么还没找到女朋友啊?你不是当年才9岁就会写情书追人家女孩子了吗?”(╮(╯▽╰)╭) + +关于男孩子的秘密,兴许没有多么的羞于启齿。只是那样青春萌动的年纪里,对于异性向往总是让人暗生情愫。女孩与男孩所不同的曼妙身材、柔软的手指、白皙的皮肤、莺莺的声线……统统构成了男孩子心里的一份柔软的梦。有时班里男生私下讨论着女生,一看见有女生走过来了,便会将食指放在唇间悄悄说:“嘘……女生来了”然后装作一本正经的样子,用眼角的余光偷偷地看女生。现在回忆起来,总是有种忐忑、紧张、酸涩与味苦的味道吧。 + +成长究竟是不是一件美好的事情呢?我不知道。我只记得当年偷偷把情书夹在心仪的女生书本里时的慌乱,悄悄在书缝间偷看女生春光时的羞涩。现在的我,也许早已脱离了当年的“纯洁”,我可以脸不红心不跳地和云儿的女伴插科打诨。昔日喜欢的女生也早就在人人上开辟了情侣空间…… + +当我再一次触及那些少年心事时,却没有疯狂的伤感,没有想哭的冲动,就像是听邻家女孩讲故事般平静。作为朋友,似乎微微遗憾;作成恋人,却默默地怯然了。 + +原来,那时的情感是假的;而写了未送的信,是真的。 + +男孩心事,你懂几许? + + diff --git a/src/content/posts/2013/2013-01-01-never-stop-writing.mdx b/src/content/posts/2013/2013-01-01-never-stop-writing.mdx new file mode 100644 index 0000000..3bad1c3 --- /dev/null +++ b/src/content/posts/2013/2013-01-01-never-stop-writing.mdx @@ -0,0 +1,44 @@ +--- +title: 笔耕不辍 +slug: never-stop-writing +date: 2013-01-01 15:02:31 +updated: 2020-09-06 12:39:22 +tags: + - 年度总结 + - 笔耕不辍 +category: 文章 +summary: 从来没有奢望过自己写的东西能有多少人来阅读。年末的济南的天空依旧那么干冷,路面上还残留着4天前下了未化的厚厚积雪,透着股寒气直逼心底。 +cover: /images/2013/01/2013010123033300.jpg +--- + + + +<MusicPlayer netease={570391} /> + +## Part 1 + +从来没有奢望过自己写的东西能有多少人来阅读。 + +年末的济南的天空依旧那么干冷,路面上还残留着 4 天前下了未化的厚厚积雪,透着股寒气直逼心底。住在温暖如春的厦门多年,突然在一个充满寒意的地方度过圣诞节和新年,这种经历,即使已经是第三次了,也让人一直觉得很奇妙。总觉得很多东西都消失了,然后又多了很多莫名其妙的东西。就像是一直朝着南北方向睡觉,某一天要睡到东西向的床上一样。但是,不管怎么说,日子总是要过下去。 + +12 月的济南过得有些慢,有些忙碌,大大小小的考试铺天盖地而来。IBM DB2 认证、六级、Web 技术考得让人心力交瘁,总期待着时间过得再快一点、再快一点,头大的考试周快点过去。猛然间回头看看自己的记录,才发现自己离最初的梦想越来越远。 + +已经多久没有写博了呢? + +回想起自己写博客的初衷,只是为了记录、生活、回忆。记得第一次发布博文的那个下午,阳光透过榕树的枝叶和胡须将时光和扁圆的光斑一起印在我的身上。[小 C 的微笑](/posts/blue-turkey/ '蓝色土耳其'),期待[三角梅开花](/posts/bougainvillea-spectabilis-willd/ '揽月楼前的三角梅开花了吗?')的那个下午,[男孩子的秘密与爱情](/posts/secret-of-boys-mind/ '男孩子的秘密心事')……这些真实的细节虽然在时间的纽带中拧乱了顺序,但依旧如同那些梧桐树下的光斑,模糊而并不微弱,光芒不减。 + +写博两年,过去的许多写作时的记忆还一直存留在心里。自从高中毕业、离别、昔日的女友成了路人、遇见云儿、认识了一群相仿的博友,那些感动过我的记忆细节,突然又在脑海中鲜活起来,我想我可以写出它们来了。巧合的是年初在家竟然翻出了高中时的日记本,虽然日记写的不全,但是我相信当年那些脑海中鲜活的人儿,必定会带着光芒在某个地方生活着。 + + + +## Part 2 + +每一天都有无数的人涌入这个飞快旋转的城市–带着他们的梦想;每一天,也有无数的人离开这个生硬冷漠的都会–留下他们的眼泪。《小时代》的故事至今仍记忆犹新,少女们那鲜明的个性与思想,都在故事中撒拿着独特的光芒,而他们之间那微妙而又茫然,高于友情又与爱情不同的,另一种方式的重叠……总能让人在不知不觉中就抛开时间的一切烦恼,身临其境一般,渐渐地,缩小心灵的距离。 + +很羡慕的说,郭敬明写的很好,而自己也一直想要写一篇同样感人的小说。在回家的火车上第一次看《悠久之翼》的时候还在读高二,那时起便有一种愿望,希望能用自己稚嫩的笔触写下这个催人泪下的故事。如今小说匆匆写了开头缺没了后文,不知是少了些心境,还是阅历。 + +新的一年来了,一年又一年,走过逝去的时光,却无法不让时光流逝。捧起时光的沙漏,心如细沙般柔弱。暮然回首也罢,感慨万千也好,豪言壮志飞扬也罢,我始终只是时光中的一粒沙,朦胧中,静静地把碎碎的字串成一段忧伤而淡然的回忆。 + +掐指一算,时至今日已经写博一年半载,我或可暂时停笔,但却又却无法决意罢笔、封笔。于是也就如同上学、过假期似地断断续续地笔耕不辍。 + + diff --git a/src/content/posts/2013/2013-01-09-sad-melody.mdx b/src/content/posts/2013/2013-01-09-sad-melody.mdx new file mode 100644 index 0000000..14be8c9 --- /dev/null +++ b/src/content/posts/2013/2013-01-09-sad-melody.mdx @@ -0,0 +1,38 @@ +--- +title: 忧伤的旋律 +slug: sad-melody +date: 2013-01-09 12:48:26 +updated: 2020-09-06 12:39:54 +tags: + - 文字 + - 忧郁 +category: 杂思 +summary: 青春是什么?小四说:“青春,是一道明媚的忧伤。”歌德说:“无酒而醉才是青春。”不管怎么说,似乎花季的年龄总有点伤春悲秋。 +cover: /images/2013/01/2013010923141500.jpg +--- + + + +<MusicPlayer netease={2149019981} /> + +青春是什么?小四说:“青春,是一道明媚的忧伤。”歌德说:“无酒而醉才是青春。”不管怎么说,似乎花季的年龄总有点伤春悲秋。 + +于是,从初中开始喜欢上了那种忧伤的感觉,手抄本里写满的是那唯美、深入人心的字句。看似简单却又支离破碎,让人的思想也濒临奔溃。我喜欢并热爱着这样非主流的思考,看似疯狂却如此恰当,如此忧伤地刺痛着心房。久而久之,我的文字也蒙上了一层忧郁的色彩,不明快,看着有些矫情。 + +有个朋友告诉我说,一直梦想着做自己喜欢的事情,随心而动。但实际上能做到这一点的人,少之又少。人的一生中,最后剩下来做自己真正想做的事情的时间往往极少。大部分的光阴,我们其实都在被他人的意志所挟持,自以为是应付生活的需要,做他人的嫁衣而牺牲自己的时间,茫然若丧家之犬,追逐劳累而丢弃享用——所以,每天多争取属于自己的自得其乐,也就是实际的人生意义了。对于我而言,我喜欢忧郁的文字,喜欢音乐,喜欢行走、不安定。这,便是我生活的意义。开始写博,更多的只是抒发内心满满的莫名愁绪,无论是记事还是回忆,对我来说其实都一样。 + +于丹曾说过,人会不知不觉地给自己的负面情绪披上一层华丽的外衣,久而久之变成了一种惯性。这种情绪在女性精英那里,主要表现为忧伤。在男性那里,主要表现为愤怒。 + + + +很多情歌都在讲述着忧伤的故事,很多小说都在演绎着一个又一个悲欢离合。读《悲伤逆流成河》的时候还在上高中,时隔五年后再来读这本当初让我在被子里哭得稀里哗啦的作品,只感觉索然无味。上网翻看郭敬明的微博,满满的都是小时代开拍电影的消息,意外之余,却少了份期待。群里面好多人说:“雨帆,你一定是女生。”(#゚Д゚)ゴルァ!! + +[咚门](https://www.dearzd.com)说:“语气太沧桑了吧,搞得你好像几十岁了一样。” + +是吗?对于我而言,或许本身我已经老了。当初那个喜欢小四的我已经长大了,面对逝去一半的大学生活,已经站在二十岁的起点,我深知:忧伤,只是青春里的一道风景线,但不是主旋律。可是,我却又矛盾着,不想停止忧郁心事的写作。我想世界上总有这么一些矛盾,无法解决,存在于自身。生长,生长,生长,直到漫山遍野,直到无处可逃…… + +我仅仅知道,这世界很大,我们很小,但生命总会在某个时刻召唤我们去实现自己的心愿。或者是透过梦境,或者是一本书、一部电影、一句箴言、一首歌、甚至是一次意外。是否接受,选择在我们。 + +所以,我来了,选择继续写着那微不足道的忧伤。 + + diff --git a/src/content/posts/2013/2013-01-13-when-i-was-young.mdx b/src/content/posts/2013/2013-01-13-when-i-was-young.mdx new file mode 100644 index 0000000..5d02ec2 --- /dev/null +++ b/src/content/posts/2013/2013-01-13-when-i-was-young.mdx @@ -0,0 +1,54 @@ +--- +title: 与青春有关的日子 +slug: when-i-was-young +date: 2013-01-13 10:13:57 +updated: 2020-09-06 12:40:24 +tags: + - 回忆 + - 青春 +category: 杂思 +summary: 简单地重温了一遍《与青春有关的日子》,停不住的思绪逐渐泛滥。还记得大一的时候,没有电脑的我们在床上疯狂地听着晚间电台入眠。回想起来,那时候是我大学期间接触音乐最多的时候。 +cover: /images/2013/01/2013011323292300.jpg +--- + + + +<MusicPlayer netease={29292454} /> + +简单地重温了一遍《与青春有关的日子》,停不住的思绪逐渐泛滥。 + +还记得大一的时候,没有电脑的我们在床上疯狂地听着晚间电台入眠。回想起来,那时候是我大学期间接触音乐最多的时候。 + +那时候的夜晚,在离家 1480 公里的济南,一夜又一夜听着熟悉的歌,不同人不同的故事... + +后来,偶然间,我发现了电视剧《与青春有关的日子》。那时候的我,第一次触摸到了北方孩子的生活——与江南截然不同的童年。贫,这个字,就是在那时候给了我最权威的演示。 + +再后来,生活开始混乱,开始颓废。 + +还记得 2009 年 5 月 12 日,同学在校内上写了一条状态:愿生者发奋,死者安息。看到这句话,我被感动了。这是纯净而无力的祈愿。心底是柔软的,希望今后所有人都会更好。 + +那时,我相信着世界会变得更好,所有人都会向着更高的地方迈步。 + +我认识的一位老师曾经这样对我说过:你不能够保证,你奔跑的方向比现在更高,但是,可以肯定的是,朝着那个方向,你在前进。 + +我始终没有明白他这句话的用意,却无意中记住了。现在突然想起,开始理解了这句话。当时被感动的我,潜意识地认定,这个社会,还有我自身,都处在仰望的角度。 + +我是错了吧…… + + + +岁月是钝器,砸到身上不会很疼,伤好的过程感受也不会很深刻。然而,有一天,在人生的大道上,回头看那过江之鲫般的人群,才发现,我们缺失了,不够完整了。那缺口不是上帝的青睐,而是受伤的痕迹。爱,无能了。 + +祈愿也无能。“默哀”,已经失去了那样的心境。不想去安慰受伤的人,不愿意跟艰难生活的人们说“加油”。 + +不要让人受伤,不要去问:“没事吧?”与其讨论着低级趣味的话题,与其闲得发慌伤害别人,不如着眼实际,做能做的事,改变可以改变的状况。 + +只记得在冬夜,在自习室,有了现在的女朋友; + +只记得自己的挂科越来越多,开始疏远他人; + +只记得自己偶尔打开电台的那一晚,犹豫着又关上; + +只记得那些与青春有关的日子,像四散在风中的纸屑,开始交错前进…… + + diff --git a/src/content/posts/2013/2013-01-29-choices.mdx b/src/content/posts/2013/2013-01-29-choices.mdx new file mode 100644 index 0000000..d6da7cc --- /dev/null +++ b/src/content/posts/2013/2013-01-29-choices.mdx @@ -0,0 +1,60 @@ +--- +title: 抉择 +slug: choices +date: 2013-01-29 15:45:13 +updated: 2020-09-06 12:41:08 +tags: + - 梦想 + - 现实 +category: 文章 +summary: 才上大学时和高中的老同学聊天,他问我:“你现在读哪个大学,什么专业?”我告诉他我现在在山大软院。他倒是惊讶了,“当年高中时你的化学读得那么好,为什么就放弃了呢?” +cover: /images/2013/01/2013012920023000.jpg +--- + + + +<MusicPlayer netease={22679062} /> + +才上大学时和高中的老同学聊天,他问我:“你现在读哪个大学,什么专业?”我告诉他我现在在山大软院。他倒是惊讶了,“当年高中时你的化学读得那么好,为什么就放弃了呢?”我想了又想,却不知道该如何回答。 + +“那么当初,为什么那么喜欢化学呢?” + +记得读小学的时候,妈妈是水泥厂的化验员,对于化学的兴趣,算起来是从那个时候开始。我至今仍能记得化验室里妈妈往样品里面滴定 EDTA 时的奇妙颜色反应,一会儿黄,一会儿紫。 + +于是满怀着对化学的好奇,从初三开始正式接触化学。那个时候,厦门中考时有一个加分制度,就是竞赛获得省级以上的奖项,中考加 10 分。当时我们大同中学化学组组长,也就是我的化学老师林舜卿,决定开一个化学竞赛培训课,每个班选 3 个人进行培训。那时我由于初一在济南读书,学的教材和厦门不同,成绩一直并不是很理想,所以名单中并没有我的名字。我私下找林老师说,我也想参加培训,林老师看了看我半天没说话。而其实连我自己都没有想到,当初鼓起勇气做出的决定会给我的未来带来多大的影响…… + +昨晚看 WPS Linux 版本开发记录时记得有这么一句话:历史总是惊人的巧合,简单的一个抉择往往会有意想不到的结果。对于我而言,应该是一种蜕变的开始。在意外地得到老师的同意后,我便专心投入竞赛的学习中。虽然以现在的观点来看,那两个月只是学了点氧化还原反应,一些简单的焰色基础。但是对于当时的我而言,却是很难的。《启东中学奥赛训练教程:初中化学》这本书有 500 多页,在短短的一个月备考时间中,不但要补习初一落下的英语,还要实打实看完这本书。那段日子里,身边一起上辅导班的同学在我眼中都是高高在上的,他们说着我不懂的化学术语、英语。我所能做的,就是低下头默默地看书,有时候夜里惊醒,还会梦见明天就要竞赛了,而该看的书还没看完。 + + + +你所浪费的今天,是昨天死去的人奢望的明天;你所厌恶的现在,是未来的你回不去的曾经。 + +或许是我的努力获得了回报,最后考试出来的结果是省二等奖,虽然这个奖项对于很多人来说微不足道。但是,正是努力的成功让我坚定继续读化学的梦想。人在年轻的时候总会有一个迷茫期,一开始以为自己无所不能,自己可以改变世界,但面对现实的冷峻后却往往会迷茫、怀疑。那个时候,我常常在想,人活这一辈子,其实也很短暂,我活着到底是为什么呢?那时候我的结论就是人活着就是做自己想做的事情,学习自己爱学的知识,并将它实践。 + +于是,才读高中的我更加坚定了学习化学的理想,或者说是一种目标,我喜欢化学,甚至愿意为它献出一生。于是大一上学期,便去参加了由厦门大学教授在双十中学初中部组织的一周一次的竞赛辅导。说是辅导,其实就是讲大学的化学课,短短的一个上午从 8 点半讲到 11 点半,中间不休息。对于一个只有高中化学知识的人而言,你很难想象,短短的 3 个小时时间内,你要记住一个大学生小半个学期学的内容。虽然老师只是蜻蜓点水地授课,但是由于不能拷课件,不能拍照,短短的一个上午,我就要在那里疯狂地记笔记,努力地记住任何我能记住的东西。 + +相比厦门一中、双十的人来说,我又是可怜的,科技中学由于生源较差,一直没有任何内部的竞赛辅导,所以在初三的情况又一次重现。在资料什么都不全的情况下,短短的高一上学期,我便天天通宵地学完了高中三年的化学知识。如果有人在那时问我,你学这么多为了啥,高中竞赛保送的资格那么渺茫。我想,当时的我也许只会说,我喜欢化学。 + +没错,我喜欢化学,正是这么简单的理由伴随了我高中三年。三年中读完了多少很多化学专业的本科生都不一定能读完的书籍,我已经记不清楚了,手中的化学笔记摞起来也有半米多高。那时我不知道自己为什么还要坚持下去,也不知道为什么还要支撑着麻痹的头脑继续去背那些概念,我只知道必须走下去。佛家反对执着,但是有许多时候我必须用执着来做生命的支点,不然的话我实在怕突来的空虚会让我无措。我怕迷路,更怕迷茫。但是,这一切都过去了…… + +当时竞赛的结果很出人意料,我拿到了省一等奖,进入了省队,但是由于老师忘记通知,我竟然错过了省队的冬令营。那个时候摆在我面前的只有一条路,和广大苦苦拼搏的高三学子一样的路——高考。老爸当时对我说,既然没法竞赛,你就给我把那些书籍丢掉,专心读书,学这些东西有什么用,能上大学吗?能找到工作吗?能赚钱养活自己吗? + +记得当时的我哭了很久,面对失败,我并不伤心,因为已经有了心理准备。但是与机会错过,就算是今天的我想起来都有一种深深的惋惜感。当时的我一狠心,将全部的书籍和笔记送给了教我化学的倪瑞琴老师,老师问我为什么,我笑着说自己已经用不着了。 + + + +时光过得飞快,半年后我高考了,半个月后高考成绩也出来了…… + +622 分,这个成绩在一本线里面高不成低不就,以当年的安徽成绩排名,也就是 4000 名的样子。当时填写志愿的时候对于我而言是一种抉择。是否继续选择化学?To be, or not to be - that is the question. 最后的结果是我向现实妥协,经过化学竞赛后,我懂得,很多时候,现实比梦想要来得重要。你可以选择自己的梦想,但是前提是你要能“活下去”。我不知道学习化学的出路在哪,我的家庭并不是那么富裕,相比大多数人来说我需要面对更加残酷的现实——你需要工作谋生。当初年轻时候的化学梦想太过于渺茫,太过于脆弱,我不知道未来只会化学而连基本的交际都不会的我该如何生存! + +也许,从把自己的一切送给老师的时候起,我便选择了放弃…… + +前些天重温《那些年》的时候,看到柯景腾霸气地说道:“你信不信十年后我连 log 都不知道是什么,我一样可以活得好好的。”不知怎么地,竟看得热泪盈眶。 + +走在高楼林立、人流如潮的都市,我为自己惋惜。当年少的追逐和年轻的梦想都被曾经的轻狂掩盖,被岁月的洪流洗成苍白,我能做的也只有托着无觉的肢体,在霓虹闪烁与灯红酒绿中徘徊。我来自何方又要归于何处呢?头顶的天空依然宽广,但是面对外面的车水马龙,我只觉得无措。 + +对于生活我还有太多未知,也有太多迷茫,也许沙漠中不会有绿洲出现,但是我仍旧期待明天的阳光…… + +> 感谢您看了我的废话这么久,谢谢。 + + diff --git a/src/content/posts/2013/2013-01-31-tender-feeling.mdx b/src/content/posts/2013/2013-01-31-tender-feeling.mdx new file mode 100644 index 0000000..e8647b6 --- /dev/null +++ b/src/content/posts/2013/2013-01-31-tender-feeling.mdx @@ -0,0 +1,40 @@ +--- +title: 温情 +slug: tender-feeling +date: 2013-01-31 16:00:42 +updated: 2020-09-06 12:41:29 +tags: + - 温情 + - 家人 +category: 文章 +summary: “你出生的时候才这么大,不足一尺。”老爸在那里形象地比划着,“当时没有保温箱,你的身体冰凉的,我一手把你夹在胳肢窝里,拿被子捂着。 +cover: /images/2013/01/2013013120175200.jpg +--- + + + +<MusicPlayer netease={2026358799} /> + +“你出生的时候才这么大,不足一尺。”老爸在那里形象地比划着,“当时没有保温箱,你的身体冰凉的,我一手把你夹在胳肢窝里,拿被子捂着。怕给你闷坏了,过一会儿还凑过去听听,嗯,还有呼吸,继续捂着,这样子才把你身体弄暖和了。”这时,一旁的老妈幸灾乐祸地说:“老猪(我妈对老爸的雅称),你怎么不说你年轻的时候狐臭味那么重。儿呀,你就是闻你老爸的狐臭味长大的。”(#゚Д゚)ゴルァ!!纳呢? + +双休日的午后,爸爸妈妈都在家休息,看着他们互相调侃对方,一股久违的温暖在心中蔓延开来。将近三年的大学生活让我与父母呆在一起的日子只剩下了寒暑假,也许正因为聚在一起的时间少了,我才越发地贪恋和父母在一起的日子。 + + + +记得小时候,老妈最爱开的玩笑就是:“孩子啊,你不是我亲生的,你是我从垃圾堆里捡来的。”我不信,老妈便说:“你看看你,不像爸爸,也不像妈妈,别的孩子哪个不像父母的?”那个时候,我就会在家门口哇哇大哭,然后哭着要去找自己的亲生妈妈。 + +大了一点识字之后,老妈继续骗我:“儿呀,你真不是我亲生的哦。”我说:“不可能,抽屉里面的《独生子女光荣证》写的是你和爸爸的名字。”“那个是假的。”“那我的准生证怎么解释?”“那个是补办的。”老妈腹黑地说道,“捡你的时候正好是 3 月 18 号,所以才去办了准生证,别的小孩子都是没出生就有证了,不信你看准生证时间是不是 3 月 18 号。” + +我半信半疑地一看,果然是,结果又去门口哇哇大哭去了。久了,我也就真的信了妈妈的话。那个时候家里比较穷,住的是平房,买不起好吃的、好玩的。每次我羡慕别的小孩的时候,我便幻想着某一天我的亲生父母会衣着光鲜地来到我的面前,对我说:“儿呀,爸妈终于找到你了。”然后,我会有好多好多我想要的东西。可是,长大后我与老爸越来越像的嘴脸让我的梦想砰然破灭。直到某一天,我把这段故事讲给爸妈听的时候,他们也哭笑不得。 + + + +也不知是不是由于老爸工作频繁变动,我与父母离多聚少的原因,我很喜欢和爸妈聊天、说笑。一顿饭,如果在学校吃的话只需要十分钟解决。可是回到家里后,一顿晚饭,往往要吃半个多小时,吵着笑个不停。记得大学才开始的时候,偶然间在宿舍接了个电话和爸爸聊了半个小时后,舍友惊讶地调侃我:“雨帆,你妈妈是不是把你当闺女养了?”(°ω°〃) + +关于与父母在一起的温馨话题,总是多得讲也讲不完。有时候我会想,关于我的家,一切的一切,也许就只是我在漫长人生里的一个梦。只是我在梦里,悄悄地喜欢上与父母聚在一起。就像是某一天,在洒满阳光的午后,用慵懒的心情,看着老爸对我说:“当年要不是我拽着你妈的手,你就被你妈用拳头捶死了。”然后老妈便会说:“乱讲什么,那个时候我只是腰疼,在捶腰。”然后,只是因为看到父母嘴角上扬的笑,就傻乎乎地开心起来。 + +对于家庭,每个人都有每个人的定义。我想,对于我而言,有父母的地方便是我的家。那种温馨的感觉,无法被替代。 + +> PS. 新的一年即将来临,也祝愿各位博友能和父母在一起,过个团圆年。 + + diff --git a/src/content/posts/2013/2013-03-02-gray-avatar.mdx b/src/content/posts/2013/2013-03-02-gray-avatar.mdx new file mode 100644 index 0000000..f9be474 --- /dev/null +++ b/src/content/posts/2013/2013-03-02-gray-avatar.mdx @@ -0,0 +1,37 @@ +--- +title: 灰色头像 +slug: gray-avatar +date: 2013-03-02 08:25:07 +updated: 2020-09-06 12:41:59 +tags: + - 春天 +category: 文章 +summary: 这些天一个人在家时,总是有些寂寞。不知道是由于不准备考研和云儿闹翻后的自责,还是放假分别后的孤单,不由自主地开始想起一些人,怀念起一些事。 +cover: /images/2013/03/2013030220520400.jpg +--- + + + +<MusicPlayer netease={2022348787} /> + +爱情,对于雨帆来说,一直是难以企及的奢侈品。 + +这些天一个人在家时,总是有些寂寞。不知道是由于不准备考研和云儿闹翻后的自责,还是放假分别后的孤单,不由自主地开始想起一些人,怀念起一些事。一个人深夜里登上雪藏两年的 QQ,看着一排排熟悉的头像,熟悉的昵称,猛然间看见名为老婆的头像,却怎么也翻不下去了…… + +点开聊天窗口,又关闭,心有千言万语凝噎在喉间,却连简单的一句问好都不敢说出。我怕一说出口,就成了永久,QQ 里就是迟迟未亮的灰色头像。才上大学时我们约好的要坚守到毕业呢?我说,绍君,你要等我啊,等我毕了业,找到工作,我们就结婚,生两个孩子。可是,为什么我们之间的话越来越少,越来越简短。有时候我拨通电话,通了之后彼此却都不知道说什么好,话筒里是那么凝重的沉默,最后只能道一声晚安。 + +> 昨夜做了一个梦,梦里我们回到手牵着手。醒来的失落,无法言说。打开了 OICQ,聊天记录停在去年的深秋。最后的挽留,没有说出口。我们还是朋友,是那种最遥远的朋友。你给过的温柔,在记录之中全部都保有。 +> +> 你灰色的头像不会再跳动,哪怕是一句简单的问候,心贴心的交流,一页页翻阅多难过。又想起你曾说的陪我到最后,暖色的梦变冰凉的枷锁。如果时光倒流,我们又能抓得住什么? + + + +分手时我安慰自己:我的幸福由我自己来定义。一心向着那些看得到的东西挥洒汗水,但是那些看不见的,那些虚无飘渺或是年少梦想的,恍然间发现是我最珍爱的。不想要半吊子,所以才会努力,因为那是看得见的;可是有时因为憧憬那些看不见的东西,被迷惑,而迷失了那些看得见的东西。我甚至不知道此刻我自己前行的动力,是对看得见事物的渴望,还是对看不见事物的依恋。做过很多事与愿违的事情、伤害别人的事情,亦做过很多温暖人心的事情。 + +于是,以前看得见的东西渐渐地消失了,看不见的却又浮现在眼前。一直以来,奉行着自己的信念,我的幸福,该用我的手,不!只有用我的手来抓住,对于我来说什么是幸福的,我不会让我以外的任何人来决定,然而有时如果继续寻找看不见的东西,继续改变我的世界,或许……所以在那个暑假,我做出了抉择,看不见的东西,果然还是不要看到的好…… + +世间万物无定形,变化永远比认知来得迅速,感情的滞留永远比变化来得缓慢,认可、被认可,否定、被否定,就这样,遇见了,错过了,珍视了,放下了,看得见的,看不见的。人绝对不会永远停留在相同的场所,不论是一边哭泣也好,大吼大叫也罢,总之是会不断地往前走,有时候我们必须舍弃什么,去选择其他的什么。是的,走着自己的路,迎接充满未知的下一步,又有谁可知前方的道路上,看不见的荆棘密布,看得见的似锦繁花。不过无论怎样那个绝不流泪的誓言,那份义无返顾的坚强,那个曾经的柔软,会一如既往。 + +> 仅以本文纪念那些青春的日子。 + + diff --git a/src/content/posts/2013/2013-03-08-pushu-and-his-flower.mdx b/src/content/posts/2013/2013-03-08-pushu-and-his-flower.mdx new file mode 100644 index 0000000..a4bc327 --- /dev/null +++ b/src/content/posts/2013/2013-03-08-pushu-and-his-flower.mdx @@ -0,0 +1,38 @@ +--- +title: 朴树与花 +slug: pushu-and-his-flower +date: 2013-03-08 15:15:11 +updated: 2020-09-06 12:42:14 +tags: + - 青春 + - 朴树 +category: 文章 +summary: 不知怎么的,这几天听起朴树的《那些花儿》时,总会有一种熟悉的孤独感。3 月的济南天渐渐回暖,一个人在宿舍整理文件时发现此曲,思绪不禁回到很久以前…… +cover: /images/2013/03/2013030821022700.jpg +--- + + + +<MusicPlayer netease={139392} /> + +不知怎么的,这几天听起朴树的《那些花儿》时,总会有一种熟悉的孤独感。3 月的济南天渐渐回暖,一个人在宿舍整理文件时发现此曲,思绪不禁回到很久以前…… + +在虾米上查查时间,《那些花儿》在 98 年发行,那年我才 6 岁。正处在看葫芦娃的欢乐年代。我丝毫不懂这个世界原来是会惹人愤怒、无奈、又讨人无限欢喜的。我不懂大人世界的悲伤,不懂爱与被爱的疼痛,年幼的无知尽情在童年里欢乐。那个时候距离我正式听流行歌曲还太久远了。 + +直到初一时我才接触到流行音乐,音乐老师教我们唱张雨生的《大海》,给我们放朴树的《那些花儿》。卡带上的他表情是那么的淡定,隐约间透露着一股微笑,长发以至于总是看不清脸。当时的我除了欣赏歌声,无法理解歌词的意思,只是喜欢那种慢慢的感觉。那种春末夏初的感觉,热烈,但是不张扬,有着特定的温柔。 + +时光过得飞快,一转眼 7 年过去了,而我差不多忘记他。当时的我和大多数的人一样喜欢听周杰伦的歌,喜欢 JJ。这大概和性格有关,那时总是肤浅稚嫩地快乐,不思考便不烦恼。一心只想着考大学,哪有时间来听朴树的寂寞和无奈、孤独和幻想? + + + +大一那年的暑假,偶然间在 Bilibili 上看到《那朵花 MAD》时让我再次想起曾经的朴树,那个有着坏坏的笑容的大男生。只是此时的《那些花儿》已经被范玮琪翻唱,高昂深情的歌喉少了朴树版本的那种简单、纯粹。我无法细说我更喜欢朴树的《那些花儿》的哪一点,我只记得听歌时某些相依的情绪。当时的我正经历着与高中女友分手的伤痛,一个下午只是安安静静地单曲循环着这首歌,想着某些过往的人和事,然后微微的心疼,小小地感动,简单地怀念和不舍。那时觉得朴树这首歌有些忧伤,十分符合我分手的心情。 + +然而你永远不可能在时间里找到个伴儿。真相是:每个人都深藏于日复一日的垒筑的时间轨道。无人能与另一个人公用同一。了不起,有几次彼与此交叉,譬如朋友、同事;最多,有几段并行,譬如夫与妻,父与子。就像是《云图》里讲述的那样:一个人是那么的孤独、渺小,却又了不起地决定着另一个人的孤独图式,跨越身边,跨过时间。我和朴树之间隔着 20 年的光阴,只是在孤独与孤独之间,有着相似的共鸣。 + +就这样恍恍惚惚地又过了三年,现在的我再听朴树的《那些花儿》,喜欢的是歌声里的那种孤独感,喜欢那种对青春年华逝去的感叹。发觉歌词里的有些事情和自己遇到的竟然好像,我们曾经那些,曾经静静为我们开放的花,今天我们已经离去,在人海茫茫。 + +> 他们都老了吧?他们在哪里呀?我们就这样各自奔天涯…… + +现在的朴树满脸的胡渣,古铜色的皮肤,半隐半现的忧郁。只是在我的脑海里、梦里、歌声里,永远都是当年那个站在麦田中笑着的他,那副没心没肺的傻样。 + + diff --git a/src/content/posts/2013/2013-03-17-trivial-thought.mdx b/src/content/posts/2013/2013-03-17-trivial-thought.mdx new file mode 100644 index 0000000..eefa956 --- /dev/null +++ b/src/content/posts/2013/2013-03-17-trivial-thought.mdx @@ -0,0 +1,56 @@ +--- +title: 琐碎 +slug: trivial-thought +date: 2013-03-16 18:04:33 +updated: 2020-09-06 12:43:05 +tags: + - 琐碎 + - 爱情 +category: 文章 +summary: 留了大半年的长发,实在是忍受不了每日的梳洗,年初回家后便决定去剪掉。街角的理发师大爷打理着我的头发,絮絮叨叨地抱怨着:“都这么长了剪掉多可惜啊。”一如一年前你那一脸惋惜抱怨的眼神。 +cover: /images/2013/03/2013031621245200.jpg +--- + + + +<MusicPlayer netease={2098472572} /> + +## 任性的我 + +留了大半年的长发,实在是忍受不了每日的梳洗,年初回家后便决定去剪掉。街角的理发师大爷打理着我的头发,絮絮叨叨地抱怨着:“都这么长了剪掉多可惜啊。”一如一年前你那一脸惋惜抱怨的眼神。 + +> “明明是个女孩子,为什么不愿意留长发呢?多可惜啊!” +> +> “我就喜欢短发呀,多清爽。” + +然后看着你一副服了你的表情偷偷开心起来。 + +其实,我一直在抽屉的角落里藏着一把檀香木梳,是上大学前妈妈塞在我的行李包里的。母亲说,女孩子嫁了人,绾起长发后,便需要一把梳子,只有心爱的人可以拿这把梳子为其梳发。梳子断了,情也到了尽头,散了。而万千青丝,又有谁能数得清、理得尽、留得住那些琐碎。一如 2 个月前的争吵,你我彼此第一次红脸。于是,当春节的假期快要来临的时候,你跟着其他的朋友一起,踏上了回家的飞机。没有了彼此间分别时应该有的关心,和期待能再回来的期盼。没有了“平安到家后记得打电话”这样的约定,也没有“要吃好睡好,养得胖胖的回来见我”的厚颜无耻。在我的心里,你留下的,只有深不见底、痛彻心扉的悲伤和寂寞。 + +我不知道我一辈子有多少个 10 年、20 年。我也不清楚在以后的日子里,我们还能坚守多久,留下看起来很小,却无法磨灭的心灵痕迹。突然很是怀念,怀念大三开学时的蒙蒙雨季,你那一身因为弄错洗衣皂的清爽味道。我们牵着手、笑着、调侃着你的马虎,只是心里,却暗暗地喜欢上指尖的那一抹隐约的温柔。 + +请原谅我的任性,原谅我的懒惰。我想,此时看到这里的你又会露出那副无奈的表情了吧(偷笑)。还有,记得要常常逗逗我,还有,不许在我面前提起别的女孩子。 + +其实,你一直都知道那不是洗衣皂,对吧? + + + +## 恍如梦境 + +前年的九月,夏天的尾巴里,天气仍然是那么炎热。我怀揣着无数无法细数的忧心忡忡和在异乡的磨练中变得稍微坚强了的心,再次踏上了回到这个城市的旅途。偶然间你出现在面前的时候,眉眼都带着笑,说:“你好呀,我好像认识你哦,你是学生会的 XXX。”我抬头,茫然地回答:“你好呀。”只是,在我眼中的你只是一个奇怪的路人,是的,只是路人。 + +我不知道你是不是注意到我无时无刻的任性和骨子里藏不住的寂寞,还是对我的一切都是那么了解。每晚的自习室总能看见你的背影和你小心到好笑的搭讪。我任性妄为地胡说,你无奈地笑,温柔得似乎一切都可以宽容。 + +从来没有遇到过如此好脾气的人,我这么想着,这样子简单地度过一天又一天。 + +之后的日子里,偶尔一起出去玩,偶尔一起吃饭,又偶尔……你带着我,包容着我的任性,小心翼翼地找着相同的话题。渐渐的我发现,这个城市的夏天,不再那么难耐,这个城市的天空,不再灰得那么孤寂和悲伤。这个空荡荡的城市里,渐渐有了让我心跳不已的所谓的“大哥哥”。 + +不知道是从什么时候起,虽然不肯承认,但是已经心甘情愿地做一只跟在你背后的捣蛋猫。将洗脸的手工皂作为香皂送给你,圣诞节时死皮赖脸地要当一天“大小姐”……所有朋友都说:“你们凑一对吧!”然后便是我的羞涩,和你煞风景的“她这是在装小姑娘,脸皮薄”。 + +我想,爱情也许就是这样了吧,简单的梦境,甜美的回忆。 + +> 我不想我不想不想长大,长大后世界就没有花。 +> 我不想我不想长大,我宁愿永远都笨又傻。 +> 我不想我不想不想长大,长大后就会失去他,我深爱的他…… + + diff --git a/src/content/posts/2013/2013-04-06-spring-essay.mdx b/src/content/posts/2013/2013-04-06-spring-essay.mdx new file mode 100644 index 0000000..d7ce0bc --- /dev/null +++ b/src/content/posts/2013/2013-04-06-spring-essay.mdx @@ -0,0 +1,36 @@ +--- +title: 春日随笔 +slug: spring-essay +date: 2013-04-06 13:49:27 +updated: 2020-09-06 12:43:41 +tags: + - 济南 + - 春天 +category: 杂思 +summary: 许多年前,当我还在读老舍的《济南的冬天》时,着实被其中的描写所吸引。古老的济南城配上半点烟雪的“水墨画”成了我的一种向往,我在想象着,这,就是济南。 +cover: /images/2013/04/2013040621410400.jpg +--- + + + +<MusicPlayer netease={2014036735} /> + +许多年前,当我还在读老舍的《济南的冬天》时,着实被其中的描写所吸引。古老的济南城配上半点烟雪的“水墨画”成了我的一种向往,我在想象着,这,就是济南。 + +伴随着动画《樱花庄的宠物女孩》的完结,山大软院的樱花也纷纷扬扬地盛开了。粉色的浪漫、樱花树下低头害羞牵手的情侣、伴随着微风洒下的樱花雨,构成了一幅唯美的画卷,让人不忍去破坏。 + +从小生活在安徽,已经看惯了年年的花开花落,也曾度过烟雨朦胧的春季。我想,兴许在我的记忆里少了点春天的刚毅、凛冽。就像初春的校园,冷风依旧带着令人瑟瑟寒颤的凉意,而我却莫名地喜悦起来。 + +清明时分的济南少了诗词里的“雨纷纷”。在去踏春的公交车上翻看着安意如的《思无邪》。不知怎么的,自从有了电脑和手机,我很少能在嘈杂的环境里看下书去。但这次却不同,不知是不是由于骨子里总有股伤春的文艺情节,身旁几个呜呜呀呀的女伴聊了什么我全然不知道,我只是看着自然平静的文字,品味着作者的风趣,有时竟忍不住地笑。 + + + +回过神时车已到站,在云儿喋喋不休的抱怨声中猛然想起《阿勒泰的角落》里常有的一句话——世界与我无关。说给云儿听,她也佯怒地笑起来。对于我而言,其实在意的不是风景,而是一种春季的感受和年轻的美好。就像此刻的我坐在山大中心校区的“小树林”里,看着四周温馨而厚重的学府,看着来来往往的学子寻觅着自己的梦。我喜欢这样一种简单的美好,它让我感到我还年轻,我还有我的未来,可以为之奋斗。 + +很多这样的时刻,我喜欢一个人走着、思考着、观察着,体味着属于自己的感动。我在寻找,一切都看见了,却又仿佛什么也没看见。此刻的我,对于春天有着无数的感受想要表述,却又不知从何说起。就像是青春的梦,在我的心中是零零碎碎的,只有一个简单的剪影,像是蒙太奇的影像般,触动我、吸引我、萦绕于心中却说不出口…… + +此刻的春天是那样美好,又何必在意那些想不出的体会?忘记了一切,只剩下天的蓝,地的广,什么都不想,似乎自己也不存在了…… + +世界与我无关。 + + diff --git a/src/content/posts/2013/2013-04-27-the-best-way-to-learn-css.mdx b/src/content/posts/2013/2013-04-27-the-best-way-to-learn-css.mdx new file mode 100644 index 0000000..5d1995e --- /dev/null +++ b/src/content/posts/2013/2013-04-27-the-best-way-to-learn-css.mdx @@ -0,0 +1,217 @@ +--- +title: 学习CSS的最佳途径 +slug: the-best-way-to-learn-css +date: 2013-04-27 12:47:55 +updated: 2020-09-06 12:49:28 +tags: + - CSS + - HTML +category: 编程 +summary: CSS 与 HTML 相结合地进行工作;HTML 整理出页面的结构,CSS 使它们看起来更加漂亮并且加入了细节上的交互。作为一个网站设计者你应该认真地学习这些语言。 +cover: /images/2013/04/2013042823510900.jpg +--- + + + +CSS 与 HTML 相结合地进行工作;HTML 整理出页面的结构,CSS 使它们看起来更加漂亮并且加入了细节上的交互。作为一个网站设计者你应该认真地学习这些语言。即使你并不需要自己来编程,理解它们如何工作将有助于你设计页面。 + +# 一、掌握基础:什么是CSS? + +C.S.S. 代表层叠样式表(Cascading Style Sheets);一种用于 HTML(或者 XML,以及一些其它结构化的格式语言)上的样式规则文档。多个样式规则可以对应一个 HTML 元素,在某种情况上来说就需要一种方式来确定哪个规则应该生效。单词 **Cascading**(层叠,朗文中译为瀑布似地落下)描述了从一般规则开始的渲染过程,直到遇到最确定的规则,然后此规则被选择来渲染它定义的元素。 + + + +通过 CSS,表现(样式)可以同结构分离<sup>注1</sup>。它解决了合并在 HTML 中的样式规则的需求,这将控制页面更整齐、更[整洁](http://en.wikipedia.org/wiki/Don't_repeat_yourself)。 + +CSS可以被网页游览器阅读。它们下载标记好的文档,然后在文档中渲染每个元素的样式。 + + + +每个游览器根据样式规则的展现并不总是相同,并且游览器开发中同样有着各自的对于新的样式建议<sup>注2</sup>的实现。经常是游览器厂商们自己来实践CSS特性,以期他们的建议能够被用户接受。 + +最后,由[万维网联盟](http://www.w3.org/)(W3C)来决定这些 CSS 特性是否标准。 + +# 二、掌握基础:学习语法 + +CSS 语法由一些基础的部分组成:Rules(规则)、Selectors(选择器)、Declarations(声明)、Properties(属性)和 Values(值)<sup>注3</sup> + + + +这个CSS规则包含了所有我们刚刚提到的零零碎碎的组成。 + + + +选择器对应着HTML标记内的元素,然后大括号内的声明确定了那些元素该被如何设计。一个规则内可以有多个声明,每个声明都由一个属性和一个相关联的值组成部分。 + + + +你可以有很多方式来选择HTML元素,比如简单地通过类型选择器(**type selectors**)。 + + + +> 上图将选择所有的图片并设置它们的内边距值为 0。 + +然后我们还有类选择器(**class selectors**)来指定应用于那些有明确类名的元素。看一看下面这个标记和它对应的CSS。 + + + +> 这是一个可以对应任何东西的锚链接。 + + + +> 然后这个将会选择所有类(class)值为 highslight 的锚链接并使它们变为橙色。 + +**注意:** 与你可能知道的所相反的是,没有一个确定的东西可以称之为 CSS 类(CSS class)。只有 CSS 选择器和目标 HTML 类。你可以在[tantek.com](http://tantek.com/2012/353/b1/why-html-classes-css-class-selectors)和[456 Berea St](http://www.456bereastreet.com/archive/200902/its_class_not_css_class/)上阅读更多相关的解释。 +有数不胜数的合理的选择器供你学习,也有更多的属性等着你来掌握(看一看 W3C 上的[这个列表](http://www.w3.org/community/webed/wiki/CSS/Properties))。后面我们将看到需要你学会许多选择器和属性才能解决的作业,尽可能多的掌握将使你成为一个更好的 CSS 码农! + +# 三、作业 1:学习一些初学者的课程 + +现在你对于什么是 CSS 有了一个基本的理解,是时候开始正确地深入学习了。网上有大量的初学课程能助于你的学习,这里列举一组你绝对值得去尝试的课程。 + +- **Code Academy** 的 [CSS 介绍](http://www.codecademy.com/courses/web-beginner-en-TlhFi)是它们的网站基础课的一部分。如果你在掌握了此课程后有所收获。请继续学习,不用花钱,完成交互的测试可以获得即时的反馈和建议。 + + + +- 如果你阅读完前面的大纲,那么你将会熟悉 **Tuts+ Premium** 的 [30 天学习 HTML 与 CSS](http://learncss.tutsplus.com/)。通过这份免费课程,Jeffrey Way 带你从完全的新手到掌握 HTML 和 CSS 的基础部分。 + + + +- **Code School** 的 [CSS 越野赛](http://www.codeschool.com/courses/css-cross-country)提供与 Code Academy 相似的交互学习,但是想要完成全部课程的话你需要成为一名登记会员(当前为 25 美元每月)。 + +# 四、作业 2:多设计一些东西 + +当 [Dave Shea](http://www.brightcreative.com/) 在 2003 年 5 月上线 [CSS 禅意花园](http://www.csszengarden.com/)的时候,他的目标是证明一个单独的 HTML 文档可以使用不同的样式表来进行无数种方式的设计。对于当时世界各地的设计师来说,这是一个美好的概念和指路明灯。 + + + +为什么不自我尝试看一些类似的事情呢?选取简单的一段标记(Chris Coyier 的[无序列表导航](http://html-ipsum.com/)就是完美的选择): + +```javascript +<nav> + <ul> + <li><a href="#nowhere" title="Lorum ipsum dolor sit amet">Lorem</a></li> + <li><a href="#nowhere" title="Aliquam tincidunt mauris eu risus">Aliquam</a></li> + <li><a href="#nowhere" title="Morbi in sem quis dui placerat ornare">Morbi</a></li> + <li><a href="#nowhere" title="Praesent dapibus, neque id cursus faucibus">Praesent</a></li> + <li><a href="#nowhere" title="Pellentesque fermentum dolor">Pellentesque</a></li> + </ul> +</nav> +``` + +看看只通过改变样式,你可以实现多少种不同的效果。 + +阅读一下这篇[社区工程:无序列表样式](http://webdesign.tutsplus.com/articles/workshops/community-project-style-an-unordered-list/),这当中有将近 100 个读者提交了他们对一个简单的无序列表定义的样式。正如你从这些[结果](http://d3pr5r64n04s3o.cloudfront.net/workshops/012_community_project_ul/unordered_list/index.html)中所看到的,一点点想象将使 CSS 走得更远! + + + +> 秘密的门-作者:[Noel Delgado](http://pixelia.me/) + +# 五、作业3:关注大师 + +如果人们懂CSS,他们将讨论它——这是显而易见的。关注 CSS 名人们在做什么你将能学到很多。下面是一组你应该关注的 Twitter 用户: + +- [@chriscoyier](http://twitter.com/chriscoyier) +- [@csswizardry](https://twitter.com/csswizardry) +- [@smashingmag](https://twitter.com/smashingmag) +- [@snookca](https://twitter.com/snookca) +- [@MeyerWeb](http://twitter.com/MeyerWeb) +- [@zeldman](https://twitter.com/zeldman) +- [@simplebits](https://twitter.com/simplebits) +- [@nettuts](https://twitter.com/nettuts) +- [@wdtuts](https://twitter.com/wdtuts) + +你还可以订阅[css-weekly.com](http://css-weekly.com/)新闻通讯来收取每周一次的 CSS 打包邮件。 + +## 额外方面 + +为什么不在像 [Github](http://github.com/) 或者 [CodePen](http://codepen.io/) 一类的社区编程站点上找到你心目中的大神?<sup>注4</sup>在这样的网络中最棒的事就是大家互相提的建议。如果你有一个 CSS 问题,某人在你之前遇到过的话将会乐意地搭一把手。 + + + +> [CodePen](http://codepen.io/) + +# 六、作业4:理解游览器的支持 + +正如我们早些时候提到的那样,游览器们并不总是相同地演绎你的样式。当你为那些老版本的IE设计时这种不同的现象尤其明显,它们远远落后于以CSS样式被采用为单位的时间。(注:就是不支持新的 CSS 特性)现代游览器们(例如:Google Chrome、Mozilla Firefox、Apple Safari、Opera 甚至是 [IE 10](http://technet.microsoft.com/en-us/ie/jj898508.aspx))拥有这更频繁的更新管理,以便减少老版本使用过久的可能性。 + +正如我们所言,在不考虑它们的最新版如何的情况下每个游览器之间都有些许不同。有些CSS在一个游览器中将被完美支持,在另一个游览器中会有不同的展现。由于这些原因,关注游览器的区别是一个不错的建议。 + +下面是一些有用的能资源,能够在你的学习过程中帮助你。 + +- [BrowserStack](http://www.browserstack.com/) 是当今非常简单且最棒的跨游览器测试工具。使用它来看不同平台上的不同游览器们如何弄乱你的 CSS。 +- [How To Deal With Vendor Prefixes](http://css-tricks.com/how-to-deal-with-vendor-prefixes/) 作者 Chris Coyier 的关于游览器兼容基础的文章。 +- [跨游览器的 CSS 编程法则](http://coding.smashingmagazine.com/2010/06/07/the-principles-of-cross-browser-css-coding/)发表于杂志 Smashing 上的有关你在处理多种游览器中将会遇到的一些问题,比如 CSS。 +- [Can I Use…](http://caniuse.com/#cats=CSS) 是一个无价的网站,主要用于每个 CSS 属性在每个游览器中是否支持。 +- [Prefixr](http://prefixr.com/) 将你的 CSS 转换为跨平台友好的语法,如果你在使用的属性需要一个特别的由游览器指定的前缀,Prefixr 将会帮你一把。这种转换仅在你使用 CSS3 属性有意义。 +- [Prefixfree](http://leaverou.github.io/prefixfree/) 是一个和 Prefixr 类似的工具,它仅允许你使用未前缀化的 CSS 属性,通过在需要时添加当前游览器的前缀到任何 CSS 代码上来工作。 + +# 七、作业5:阅读一本书 + +无论你是从头到尾地仔细阅读,还是简单地把它们作为需要时快速查找的手册,最棒的图书在阅读上是无可挑剔的。CSS 已经被无数次写成书籍,但是这些出版物是我所认为的精华: + + + +- [HTML and CSS Book](http://htmlandcssbook.com/) 是一本漂亮的有插图的针对完全新手的手册,尤其是书籍网站将所有的代码片段和实例可以被获取来实践。 +- [CSS: The Definitive Guide](http://www.amazon.com/CSS-Definitive-Guide-Eric-Meyer/dp/0596527330/ref=sr_1_1?s=books&ie=UTF8&qid=1366296089&sr=1-1&keywords=CSS%3A+The+Definitive+Guide):作者是 CSS 教父——Eric Meyer。 +- [CSS: The Missing Manual](http://www.amazon.com/gp/product/0596802447/ref=as_li_ss_tl?ie=UTF8&tag=jcdicrte-20&linkCode=as2&camp=1789&creative=390957&creativeASIN=0596802447) 是有一定的年头了(在技术层面上),但依然被许多 CSS 基础方面的 Go-to 书籍作为参考。 +- [CSS3 For Web Designers](http://www.abookapart.com/products/css3-for-web-designers) 作者是 Dan Cederholm(在完成作业3后你将在 Twitter 上关注他,不是吗?)。此书是近期的 A Book Apart 出版书籍之一。不完全为新手准备,但即使如此还是推荐获取它的纸质书。 +- [CSS Essentials(电子书)](https://tutsplus.com/ebook/css-essentials/)来自于 Smashing 杂志。 + +# 八、作业6:弄懂选择器和特性 + +正如你所相信的那样,你的 CSS 词库将不断增长。你将能保证记住 CSS 属性并且使用多种方式选取元素。现在是时候提升档次来进行关于 CSS 选择器的严肃学习。 + +- [你必须记住的 30 个 CSS 选择器](http://net.tutsplus.com/tutorials/html-css-techniques/the-30-css-selectors-you-must-memorize/):来自 Nettuts+ 真实地覆盖你所学的内容。 +- [选择器年鉴](http://css-tricks.com/almanac/selectors/):来自 CSS Tricks 用于加深理解。 + +学习 CSS 选择器也意味着开始掌握特性,哪个选择器将重载其它的选择器? + + + +> 帝国风暴兵图标 作者:[Jory Raphael](http://dribbble.com/shots/951479-Stormtrooper-Icon) + +我应该在我的选择器里面使用以便提升代码执行效率的最低限度语法是什么?我总是推荐人们去一个地方学习特性的规则,那就是 Andy Clarke 的 [CSS: Specificity Wars](http://www.stuffandnonsense.co.uk/archives/css_specificity_wars.html):一个能给人以联想的有关选择器如何由外置内影响彼此的可视化流程(黑色的是最强力的。<sup>注5</sup>) + +# 九、作业7:更进一步 + +CSS 是一门涉猎甚广的规则。一旦你掌握了基础部分,将有着无数的大道等着你去探索。例如: + +## CSS3 + +CSS3 还处于不断发展的过程中,新产生的特性正逐步被接受,其它的旧特性全部被游览器抛弃,有时候甚至语法都会变。通过 [CSS Gradients](http://www.colorzilla.com/gradient-editor/) 来掌握 CSS3,将会是另一个阻止你使用 Photoshop 的契机。当你可以用 CSS 处理图像时为什么还要使用分割好的图片呢? + +游览网站 [CSS3 Please](http://css3please.com/) 来了解当前所有正确的 CSS3 实现,此网站推荐去除那些不支持的游览器。同样,看一看 Tuts+ Premium 上的 [CSS3 Essentials](https://tutsplus.com/course/css3-essentials/),这将能提升你的知识。 + +## 媒体查询 + +响应式页面设计允许你流体式页面布局改变。这取决于页面被如何获取。CSS3 媒体查询助力于这一过程中,根据不同的情况提供不同的 CSS 规则。阅读一下[相应式式页面设计:一本可视化的指导](http://net.tutsplus.com/tutorials/html-css-techniques/responsive-web-design-a-visual-guide/)来开始学习。 + +## CSS 预处理器 + +原来 CSS 可以变得更棒。一旦开始在现实世界的项目中使用 CSS,你将可能会得出相同的结论。维持巨大的 CSS 文件是困难的,重复是普遍的——那么为什么你不能使用一种变量存储十六进制的颜色值而不是一遍又一遍地重复输入?CSS 预处理器,例如:Sass、LESS 和 Stylus 解决了所有这些问题甚至更多。甚至无需强制重学一种相似的语言(如果你愿意的话只需坚持普通的 CSS)你就可以利用预处理器的强大。 + +如果你有兴趣学习更多的东西的话,请查阅 [Get Into LESS](http://hub.tutsplus.com/categories/development/tutorials/webdesign-5216-get-into-less-the-programmable-stylesheet-language)、[Mastering SASS](http://hub.tutsplus.com/categories/development/sessions/net-19077-mastering-sass) 和 [Sass vs. LESS vs. Stylus: Preprocessor Shootout](http://net.tutsplus.com/tutorials/html-css-techniques/sass-vs-less-vs-stylus-a-preprocessor-shootout/)。 + +## SMACSS + +[SMACSS](https://tutsplus.com/ebook/scalable-and-modular-architecture-for-css/)(CSS 可扩展模块化架构)是一种由 Jonathan Snook 开发的概念,旨在与 CSS 文件的尴尬的维护性做斗争。它没有教授一种新的语言,而是推荐一种能让你当前的 CSS 更有组织性的一种方式。 + +编写模块化的 CSS 使你能将在别的项目中使用原有的大量的样式代码并扩展它,并且不会破坏你的其它风格,使特征管理处于最佳状态。 + +# 十、结论 + +毫无疑问拥有像 HTML 和 CSS 一类的技能将充实自我,你将成为一名更好的网站设计师。跟随着我们所列举出的两条学习流程大纲,你将能迅速进步。 + +如果你有任何关于 CSS 的学习建议,大声在评论里面喊出来吧! + +# 注释 + +1. 注1:[表现与结构分离](http://www.blueidea.com/tech/web/2004/2173.asp) +2. 注2:“新的样式建议”译法参考了 [W3C 的工作流程](http://www.w3school.com.cn/w3c/w3c_process.asp) +3. 注3:国内较好的 Web 设计社区有 [RunJS](http://runjs.cn/)、[GitCafe](https://gitcafe.com/) +4. 注4:原文是 the dark forces,指的是作者将选择器分成几类,有一类是以黑色小人做演示。详细的以后会翻译对应文章。 + +--- + +原文:[The Best Way to Learn CSS](https://webdesign.tutsplus.com/the-best-way-to-learn-css--webdesign-11906t) +译者:[雨帆](https://yufan.me),转载时请保留译文链接和原文链接。 diff --git a/src/content/posts/2013/2013-04-30-whose-youth-do-not-have-a-shallow-bruising.mdx b/src/content/posts/2013/2013-04-30-whose-youth-do-not-have-a-shallow-bruising.mdx new file mode 100644 index 0000000..5225c30 --- /dev/null +++ b/src/content/posts/2013/2013-04-30-whose-youth-do-not-have-a-shallow-bruising.mdx @@ -0,0 +1,49 @@ +--- +title: 谁的青春没有浅浅的淤青 +slug: whose-youth-do-not-have-a-shallow-bruising +date: 2013-04-30 12:49:51 +updated: 2020-09-06 12:50:44 +tags: + - 影评 +category: 杂思 +summary: 夜晚临近子夜,我看完了整部电影《致我们终将逝去的青春》,现在坐在桌前细细回味,感触颇丰。 +cover: /images/2013/04/2013043022435500.jpg +--- + + + +<MusicPlayer netease={4872578} /> + +夜晚临近子夜,我看完了整部电影《致我们终将逝去的青春》,现在坐在桌前细细回味,感触颇丰。去看的时候,同学说时光网上的评分太低了,还是去看《钢铁侠》吧。我说不看,就算是烂片我也要去看,因为我相信赵薇,相信原著辛夷坞的剧情。事实证明,整部作品很棒,从郑微的活泼、灵动上我似乎看到了当年小燕子的影子。不知怀旧是不是已为人母的赵薇改拍此作的理由之一。 + +话题扯得有点远了,回过头来谈电影。想起有一种很出名的说法:男人的魅力在于岁月沉淀后的睿智与淡定。而其实女人也是如此,所以我一直很崇拜杨澜。在各个方面,如果说她是我努力的方向、努力的目标,那么我会觉得自己又不要脸地在妄自菲薄。这是一个无比奢望的梦想。 + +突然扯到她的理由,只是今天看《致青春》竟然看到了偶像的镜头。这是先前未知的,其实不过才几秒钟,但我已经觉得那是足够的亮点。 + +是的,我很容易爱屋及乌。 + + + +也正如看电影前豆瓣上大家的评论所说,电影和小说有很多情节不同。比如阮莞、黎维娟的戏份大幅增加,原著一号男主林静则成了打酱油的;比如电影中许开阳纠集多人狠揍了陈孝正一顿;比如看到韩红当深夜节目电台主持人,我顿时笑喷…… + +只是我不明白的是,为什么电影中的那个年代,大学宿舍环境就像现在最底层的农民工处所,大学生也充满了屌丝气质?然后我就突然想到这两天看到的一条微博,说的是招募在厦大拍的某部剧群众演员:“具有屌丝气质的男生优先考虑”,然后再次笑喷。 + +是不是在高速发展的这个社会里,众屌丝成了主流?这也难怪我最近觉得自己越来越屌丝了。 + +而影片中韩庚几年后的造型直接被赵又廷完爆,我说赵导哟!为什么会把一个人毁成这样?好在我之前也没特别喜欢韩庚,所以其实并没有很大的不满︶︿︶(**小声说:不满很高哦!**) + +当然,在我看来亮点还有工作后郑微的短发。我发现最近的很长一段时间来,我一直开始喜欢上短发的女孩。嗯,精明、干练、清爽、气场,最重要的是美丽。我在默算着多久后云儿也会是短发。 + +写到这里,我觉得再不讲点和正题有关的就真的跑远了。虽然跑题对我来讲也是常事,连高考作文都跑了,那么平时也就不重要了。 + + + +“一个人竟然会变成自己曾经最反感的样子!”,这句话应该是我今晚最大的感触,也是记得最牢的台词吧。 + +从憎恨抽烟到抽烟,从必须垫书在屁股下否则不坐到白裤子也能随便坐。或许,这些只是表面上来呼应那句台词的作为,但是我依旧狗血地感到很有道理。就像现在大家走的路或许与最初的梦想相悖,导致一路上有太多的抱怨和自我鄙视。就像是我,前些日子依旧在迷茫最初高考的选择,也许这就是逝去的青春吧…… + +看到有人评价说:这是流水账式电影外加一个出乎意料的结尾。我突然倍感亲切,因为我一贯流水账式的日志。只是,对于未来,对于现在,就像是梦里花、水中月,不清楚、不明白。也许将来路途艰辛,也许将有无数次摔倒。但是,我相信,我会一路向前。 + +是的,谁的青春,没有浅浅的淤青?(以此作为结尾,看样子我又懒惰了哦。QAQ) + + diff --git a/src/content/posts/2013/2013-05-17-the-girl-who-leave-you.mdx b/src/content/posts/2013/2013-05-17-the-girl-who-leave-you.mdx new file mode 100644 index 0000000..d9498a3 --- /dev/null +++ b/src/content/posts/2013/2013-05-17-the-girl-who-leave-you.mdx @@ -0,0 +1,48 @@ +--- +title: 那个离你而去的女孩 +slug: the-girl-who-leave-you +date: 2013-05-17 12:52:59 +updated: 2020-09-06 12:59:48 +tags: + - 言叶之庭 +category: 文章 +summary: 雨,漫天漫地的雨,清澈透亮,不含一丝杂质。初看此片的第一眼,仿若置身于漫无止境的五月雨季。雨天潮湿的心情,凉亭下的不期而遇,那人似曾相识。 +cover: /images/2013/05/2013051722351900.jpg +--- + + + +<MusicPlayer netease={1950516520} /> + +雨,漫天漫地的雨,清澈透亮,不含一丝杂质。初看此片的第一眼,仿若置身于漫无止境的五月雨季。雨天潮湿的心情,凉亭下的不期而遇,那人似曾相识。 + +“我们,是不是以前见过?” + +小时候,天空仿若触手可及,于是慢慢喜欢上雨天,因为它带来天空的气味。雨,是贯穿《言叶之庭》的主旋律,无论是两人的相识、相知、互吐爱慕,无一不是在雨中所达成。 + + + +故事的主人公秋月孝雄和雪野百香里也是在雨季中偶然相遇,离别的时候,雪野留下了一首简单的对答短歌:“隐约雷鸣,阴霾天空,但盼风雨来,能留你在此。”由此开始了两人的缘分。孝雄曾说,晴天的早晨会按部就班地乘车上学,也会让他觉得不属于学校。而雪野也因为一些事情,只能通过啤酒和巧克力刺激味觉。或许正是雪野奇怪的举动吸引了孝雄,在雨天中,两人从相识到交谈,两颗心一点点被拉近。 + +在雨天清晨的再次邂逅,百香里第一次吐露心声:“我啊,无法顺利走下去了。”本来梅雨的季节被推迟,两人一次又一次地在清晨相遇,彼此却又不说话,但是心却越来越近了。每天都在期待着明天的早晨,一样的雨季,一样的邂逅。 + +然而,雨季无法避免地结束了。如旁白所说:“简直像有谁切换了季节的开关一样。”没有了下雨的早晨,凉亭里只剩下雪野独坐,而两颗暂时分开的心,满怀着期望,却走得更近了。 + +也许命运有时就是这么奇妙。 + +短歌的下半句“隐约雷鸣,阴霾天空,即使天无雨,我亦留此地。”而当孝雄懂得下半句的含义时,已无法逃离。原来,无论雨天还是晴天,我一直都在这等着你…… + + + +再一次遇见,两人已然熟悉彼此,孝雄说出从万叶集中找到的下半句。而突如其来的大雨,将两人困在那里,心也困在了一起。在雪野的家中,在至今为止的人生里,现在,这一刻,对于两人而言,或许这就是幸福。“雪野小姐,我好像开始喜欢上你了。”孝雄忐忑地说道。 + +“不是雪野小姐,你应该叫我雪野老师……”雪野委婉地拒绝了孝雄的爱意,只是在孝雄关门离去的那一瞬间,雪野的表情是那么的落寞。 + +接下来的几分钟里,是全剧的高潮。当男女主互相哭泣着、咆哮着道出心意,作为观众的我也被深深触动。伴随着恰到好处的主题曲《Rain》,情不自禁地落泪。那个不嫌弃你的姑娘,那个曾经喜欢着你的大女孩,为什么没陪你走到最后?当彼此眼泪流干的时候,人却再也留不住了。离别,走上仿若平行线的生活。物理上的距离,是两人最大的鸿沟,但是心与心的依靠,是距离所无法阻断的。有时候,离去不是一个简单的转身,而是,一辈子的幸福。 + +于是,在影片结束的最后,孝雄在当初相遇的凉亭中拿出了当年说要制作的女鞋,只是伊人已经回到家乡。“回望当初,那时我一定也一直在训练自己迈步,如果有一天,能够走得更稳更远了,就去见她吧……” + +> 殷其雷,天阴霾,雨零耶,盼君留。 +> 殷其雷,纵不零,卿若留,吾将从。 + + diff --git a/src/content/posts/2013/2013-05-20-lost-myself-in-may-day.mdx b/src/content/posts/2013/2013-05-20-lost-myself-in-may-day.mdx new file mode 100644 index 0000000..0d59043 --- /dev/null +++ b/src/content/posts/2013/2013-05-20-lost-myself-in-may-day.mdx @@ -0,0 +1,39 @@ +--- +title: 五月迷失记 +slug: lost-myself-in-may-day +date: 2013-05-20 12:51:21 +updated: 2020-09-06 12:52:01 +category: 文章 +summary: 五月的济南生活有点错乱,天气忽冷忽热地延续了 3 周,才想着是不是已经算作夏天时,昨夜又下雨降温到 18℃。搞得我现在的床上还放着毛毯、棉被、空调被,按照温度随时选取。 +cover: /images/2013/05/2013052022592400.jpg +--- + + + +<MusicPlayer netease={22651783} /> + +五月的济南生活有点错乱,天气忽冷忽热地延续了 3 周,才想着是不是已经算作夏天时,昨夜又下雨降温到 18℃。搞得我现在的床上还放着毛毯、棉被、空调被,按照温度随时选取。╮(╯▽╰)╭ + +雨天的那个晚上,想起前不久友人的书信:最近阴雨连绵,适合怀旧。我突然想起高中时那个已经忘了名字的姑娘,记不清她的样子,却还记得同学叫她的外号:小白。还记得为她第一次写过的情书,偷偷地夹在化学课的笔记本里。有时想想那时自己就是个伪文艺青年,迷恋着一个姑娘,情书里写着普希金的《假如生活欺骗了你》,这算是哪对哪呀! + +那个年纪,那个时代啊,那些女孩。 + +友人的信,简单地在海子的“春暖花开”里升腾,氤氲了整个五月初。 + +五月的季节,开始有些怀旧。不知是不是因为即将面对的新一届大四学长离校的缘故。看见离别,总是会习惯伤感、习惯抑郁。恍然间似乎看见自己也成了其中一员,面对着一年后相似的告别。只是,我所不知道的是,我与云儿的距离,是否能在毕业后继续交叠,而不仅仅是,两条平行线般遥远…… + +那天看完《致青春》后和云儿谈起这个话题,她笑着说:“还是留给时间来解答吧。” + + + +时间,真的很强大,甚至——残酷。虽然我极力想否认时间对我、对云儿的改变,但是我害怕,突然有一天,我会像现在忘记小白一样,与云儿成为过去时。 + +就像前些日子和济南的初中同学孙扬去喝酒,我们谈了很多、很多,最后谈到以前欺负我的同学。孙问我:“你还恨他们吗?”我想了想,也不知道该如何回答。对于他们的恨意、甚至是恶毒的想法早就是过往云烟,记不起来的人,又谈何恨? + +五月的我,像是推开了一扇回溯生命的门,随之而来的,是目光的躲闪,是成长的羞涩,是珍藏时光的陈酿,是青春放肆的香…… + +在怀旧的季节,开启尘封已久的潮湿往事。一件件晾晒,烙上新的成长的痕迹。对与错、爱与恨、那些年轻的仓惶与疼痛,似乎也就这样淡然了。 + +五月,迷失季。 + + diff --git a/src/content/posts/2013/2013-06-21-those-people.mdx b/src/content/posts/2013/2013-06-21-those-people.mdx new file mode 100644 index 0000000..d8f1300 --- /dev/null +++ b/src/content/posts/2013/2013-06-21-those-people.mdx @@ -0,0 +1,23 @@ +--- +title: 那些人儿 +slug: those-people +date: 2013-06-20 18:24:04 +updated: 2020-09-06 12:49:51 +tags: + - 回忆 +category: 杂思 +summary: 闲了两个月后,我又把原本打算停笔不写的博客重新搭建起来,这算不算是个人的又一次纠结呢?掐指一算,写博已经有两年之久,这期间建博的来来去去,有些人走了,有些人还在继续。 +cover: /images/2013/06/2013062023165500.jpg +--- + + + +闲了两个月后,我又把原本打算停笔不写的博客重新搭建起来,这算不算是个人的又一次纠结呢?掐指一算,写博已经有两年之久,这期间建博的来来去去,有些人走了,有些人还在继续。后台留言板内早些年的留言链接全是 404,只留下还存活着的头像,孤零零地像一座座坟墓。 + +记得刚开始写博的那段日子,总有那么一个夜晚,伴着舍友的呼吸声,从一个博客逛到另一个博客。看着大家的故事,品味着彷徨的心事,然后留下自己的链接,奢求能有同样认真阅读的人。而看多了安静凄美的文字,写多了哀而不伤的故事,挖掘透了刻骨铭心的恋情,心也就累了。有时想想,博客不是一种快乐,爱情也不是。如果你了解一个人经过怎样的岁月才会老去,你就能仔细品味出某种特异的感觉。就像博客,没有一年半载的坚持,又怎么知道最初的选择是否正确?曾打算不再写博,离开时抓紧双手,默默转身,无数次下定决心去遗忘。而当真的要走远时,却还是放不下名为牵挂的情绪。 + +一个雨夜,陪云儿寻找一家叫做“青春”的服装店。街边的路灯在雨雾中折射出迷蒙的光影,映照着迷路的我们。云儿忘了地址,见人便问:“青春在哪里?”话才说出口,便惊觉表达错误,被问的路人投来诧异的眼神,一对年轻情侣竟然向他问青春?费劲周折找到了传说中的那家店铺,看着云儿满意的微笑,心中七分甜蜜,三分疲惫。想来博客也是这样,我们怀揣着梦想起步,走过的日子,写过的故事,都恍惚化成了脑海中挥之不去的片片色彩。既然爱过,又谈何分别? + +想起在云刊上记住的一句话:“博客,是一个人的寂寞,寂寞,是一群人的孤单。”握一把孤单献给你,在这烈日炎炎的盛夏,趁着秋天还未到,你也许还能觉出一点我们手握的苍凉吧。 + + diff --git a/src/content/posts/2013/2013-06-30-unwilling-to-grow-old.mdx b/src/content/posts/2013/2013-06-30-unwilling-to-grow-old.mdx new file mode 100644 index 0000000..b711541 --- /dev/null +++ b/src/content/posts/2013/2013-06-30-unwilling-to-grow-old.mdx @@ -0,0 +1,43 @@ +--- +title: 我不想,我不想,不想变老 +slug: unwilling-to-grow-old +date: 2013-06-29 17:29:55 +updated: 2020-09-06 12:54:20 +tags: + - 青春 +category: 杂思 +summary: “为了看看阳光,我来到世上。”第一次读到巴尔蒙特的这句诗后,就几乎再也没有忘记过。那种内心的纯净、光明与温暖,在读此诗时铺面而来,简单地仿佛看不到忧伤的痕迹,一如你我十八年华。 +cover: /images/2013/06/2013062923260700.jpg +--- + + + +<MusicPlayer netease={2109677054} /> + +“为了看看阳光,我来到世上。”第一次读到巴尔蒙特的这句诗后,就几乎再也没有忘记过。那种内心的纯净、光明与温暖,在读此诗时铺面而来,简单地仿佛看不到忧伤的痕迹,一如你我十八年华。 + +—— 题记 + +前些日子整理旧时的笔记本,看着年轻时的自己无忧无虑的文字,不知不觉地忧伤起来。我知道现在的自己是再也回不去的了,可是倘若有机会,我是多么希望自己能将年华一直定格为 18 岁。 + +这样的场景或许只会发生在奇幻电影中,仿佛《不能说的秘密》中周杰伦回到过去的历程:21 岁的我坐在这里一字一字地写下 18 岁的回忆,周遭的景致便不停变化,有些记忆会消失,某些遗忘的事会莫名浮起。处在时间回溯洪流中的我看着过去的自己,就像是看着一部泛黄的老胶片电影…… + +某天早上,当朝阳透过阳台洒在我的书桌上时,我收到了小 A 姐姐的 QQ 信息:“小小,你说当我们老去的日子该有多可怕?我不想变老!” + +变老吗?想想人老去后的种种,那个瞬间,时间这看不见摸不着的玩意儿,沉重而清晰地跃出水面。对于“变老”这个词,我第一次如此地恐惧。 + +记得初中毕业的那个六月,我近乎虔诚地盼望着我的十八岁。那时我才喜欢上一个姑娘,却因毕业渐渐失去了联系。我想长大,能够拥有一段美丽的恋情。我想要尽快长大,然后背起行囊离开争吵不断的父母。我渴望长大后前往远方,那里有我的金色梦想…… + + + +然而踏上[十八岁的旅途](https://likeya.me/18-year-old-journey/)的我用忙碌的学习挥霍完仅存的一点青春,毕业来到一个新的城市后。面对着离家那么遥远的陌生城市,心中却开始莫名地寂寞。我用着文字祭奠着青春,一如《情人》中,玛格丽特·杜拉斯写道:“太晚了,太晚了,在我这一生中,这未免来得太早,也过于匆匆。才十八岁,就已经是太迟了。在十八岁和二十五岁之间,我原来的面貌早已不知去向。我在十八岁的时候就变老了。” + +我想,成长的路上总会有无限的迷茫,但我也坚信生命中有着能让我们忘记一切迷茫的寄托。记得上周重看了《小王子》,对于等爱的小狐狸来说,麦田因为小王子而有了特别的意义。一如一开始陌生的济南,由于云儿的存在让我异常地温暖。 + +我已经长大了,能够毫无顾忌地谈着恋爱,也能满怀希望地追寻自己心中的梦想。却发现在不经意间长大后,又开始在不经意间变老,一切都是那么的猝不及防。记得在初中阅览室里读过的《彼得潘:不会长大的男孩》的故事,有时幻想着是否存在着这样的“乌有岛”,我就是那个叫做彼得·潘的男孩,活在自己的伊甸园中。 + +于是一直很喜欢郑插插笔下的彼尔德,这只性别为女的可爱胖鸟做着各种可爱的表情,欺负着一只名为黄溜溜的小鸡。不愉快时看着她们,心情也就好起来了。每次发彼尔德表情时舍友总说我喜欢卖萌,却不知这是我对于长大的逃避,我害怕变老,害怕一切的未知。 + +那么请不要忘记在第二个路口往右转,然后一直走,直到天亮。这是前往“乌有岛”的道路,让我们一起不要变老。 + + diff --git a/src/content/posts/2013/2013-07-18-summer-training-record.mdx b/src/content/posts/2013/2013-07-18-summer-training-record.mdx new file mode 100644 index 0000000..8ba14f4 --- /dev/null +++ b/src/content/posts/2013/2013-07-18-summer-training-record.mdx @@ -0,0 +1,43 @@ +--- +title: 大三暑期实训记 +slug: summer-training-record +date: 2013-07-18 14:31:28 +updated: 2020-09-06 12:54:40 +tags: + - 实训 +category: 编程 +summary: 大概是很久没有提笔的缘故,一直找不到什么可以拿出来写的话题。七月的济南打破了一如既往的干旱,这一阵子阴雨连绵,恍然间有种已经回到厦门的错乱感。 +cover: /images/2013/07/2013071823431400.jpg +--- + + + +<MusicPlayer netease={571336152} /> + +大概是很久没有提笔的缘故,一直找不到什么可以拿出来写的话题。七月的济南打破了一如既往的干旱,这一阵子阴雨连绵,恍然间有种已经回到厦门的错乱感。只是现在的我依旧坐在实验室的机房内敲着代码,窗外下着大雨,身旁来自山东中医药的张远馨同学笑着对我说:“终于全部写完了。” + +**“哎呀?已经结束了吗?”** + +为期四周的项目实训终于在今天落下了帷幕,算起来,也好久没有像现在这样子忙碌了,早起晚睡、忙碌的学习和测试,实训中心里埋头敲代码的背影。恍然间,如同 Back To Seventeen。 + +有句话怎么说来的:纸上得来终觉浅,绝知此事要躬行。无论你学了多少,准备了多少,到了最后实施的时候总是觉得不够。只是,幸运的是我们做的只是项目实训,开学第一天和印度老师 Amit 交流时他就用英语和我们说:“这不到一个月的实训我的目的不是让你们学会多么深的技术,提高多少技术能力,主要是让你们在一种公司化的项目小组开发的气氛之下,严格按照公司开发步骤程序区完成这次的项目。”于是,公司化的管理,公司化的作息时间,公司化的小组协作开发……这一切的一切都是在之前自己的大学生活中并未体会过的。学习、设计、规划、编程、合并、测试,或许短短的流程线无法形象具体的表述出我们这二十多天的活动,但却可以隐约表示出自己在这实训期间充实的生活。 + + + +因为自己之前对于 Android 项目的开发也只是处于入门阶段,并不熟练。所以初期两周自己先在网上找了一些 Android 项目开发视频、资料学习。在前几天的较为系统的学习过程中,我也掌握了很多在之后的开发过程中很实用的方法、技巧。期间、自己也编写了部分小程序、范例进行熟悉。 + +而其实自己在做具体功能模块实现部分时花了不少的时间,其中遇到了很多复杂的问题。怎样在界面里实现各功能的代码编写,怎样实现 SQLite 数据库的初始化、更新、增删改查,怎样在各个 Activity 间相互传递参数等等。而这些又都是比较棘手的问题,又比如:利用 Intent 传递参数时,无法直接传递已经构建好的实体类参数;利用 SimpleAdapter 时,无法在 ListView 实现 Item 按钮的添加、绑定。但是通过向老师 Amit、同学请教;通过组员的帮助和一次又一次的调试,这些问题都解决了。直到这时我才深深的体会到,团队合作的力量是多么的巨大。正是因为有了老师和同学们的帮助,我的实训任务才可以提前并且很好的完成。 + + + +而代码整合中存在的问题,应该算是我的实训过程中最有意义的收获之一了。在此过程中,实际的教训使我再一次意识到评审的重要性。由于开发周期较短,需要每天进行一次评审,而我之前的评审时间有点晚,导致发现问题不够及时,因此最后拖慢了大家的进度。 + +最后,要感谢 Amit 师对我们的耐心讲解和帮助,还有我们组组长和小组成员对我的热心帮助,他们都给了我前进的动力,教给了我许多知识和课本以外的东西,没有他们的帮助,我就很难完成组长分配给我的任务了,没有他们的讲解,我也不会学到那么多的东西,有那么多的收获,所以也借此文章偷偷地感谢他们(╮(╯▽╰)╭)。 + +人非生而知之,虽然我现在拥有一定的知识结构,但是我知道自己需要锻炼动手能力,不仅要靠努力学习,还要靠潜心实践。没有实践,学习就是无源之水,无本之木。这次实训让我知道了不少知识:我们不可能永远呆在象牙塔中,过着一种无忧无虑的生活,我们总是要走上社会的,而社会,就是要靠我们这些年轻的一代来推动。不久后的我,面临是就业压力,我想我们都应该好好经营自己的时间,充实、完善自我,不要让自己的人生留下任何空白!相信努力就会有收获,每天努力充实自己,相信在不久的将来,可以打造一片属于自己的天地。 + +“既然选择了远方,便只顾风雨兼程!” + +写完实训报告时望着窗外,天空已然阵雨初晴。 + + diff --git a/src/content/posts/2013/2013-07-27-afternoon-nap.mdx b/src/content/posts/2013/2013-07-27-afternoon-nap.mdx new file mode 100644 index 0000000..a0a0b06 --- /dev/null +++ b/src/content/posts/2013/2013-07-27-afternoon-nap.mdx @@ -0,0 +1,41 @@ +--- +title: 难得的午后 +slug: afternoon-nap +date: 2013-07-27 14:26:33 +updated: 2020-09-10 06:23:46 +tags: + - 迷茫 +category: 杂思 +summary: 时常会望着天空,周遭的喧嚣便会变得平静。我并不明白存在的意义,就像我们追逐着的世界。若是我们能忘记目的地,你说,会是平淡的快乐,还是空洞的烦恼? +cover: /images/2013/07/2013072700011200.jpg +--- + + + +<MusicPlayer netease={28524471} /> + +时常会望着天空,周遭的喧嚣便会变得平静。我并不明白存在的意义,就像我们追逐着的世界。若是我们能忘记目的地,你说,会是平淡的快乐,还是空洞的烦恼? + +—— 题记 + +假期终于到了,不用上课、不用开会、不用干些七七八八的事,可是我躺在床上想要午休却因为腰酸怎么也睡不着。而其实我想说我是个很懒的人,不爱读书、不爱工作、更不爱运动。曾想过减肥变苗条点,可经过几天的训练,便腰酸背疼腿抽筋地放弃。想起前不久听献血英雄报告会的情形,那位略夸张的大爷说:“每次献完血,腰也不酸了,腿也不疼了,肩周炎也好了,腰椎肩盘突出也康复了。”我想,如果这是事实,那此刻就抽干我的血吧! + +有时会莫名怀念高中的生活,那种充实的节奏不会让我迷茫。每天有该完成的事,虽然更多的是自己不太乐意的。不过我真的想念以前翘课、泡小店、打牌、喝咖啡、听歌、闲聊的午后时光。 + + + +而有时觉得大学的生活十分错乱,看见身边的人一个个找到自己的目标在努力,而自己却总在原地踏步。看见人才市场人头攒动的样子,心中就隐隐害怕。一直在追求一种可以一杯茶一本书坐一下午的日子,可是我一度为了感情惶惶不可终日,又在社交网络上浪费了太多精力。恍然间发现自己与别人间的共同话题越来越少,距离越来越远…… + +上大学前无论多么放纵都不会有负担,可上大学后一干坏事,一拒绝不想参加的活动别人就说你是社团干事。可是,谁叫自己当初选择了呢?现在爆个粗口别人会说你是主席,要注意形象,有得必有失真的是亘古不变的真理。还记得初中时的班训是:既然选择了远方,那就风雨兼程。 + +是吧?自己选择的路,跪着也要走完。虽然岁月是把杀猪刀,虽然我也明显感觉自己老了。但 20 出头,依然是一个奋斗的年代。 + +> 午后的阳光,成就了我的天堂。 +> 绕着树林旋转,听落叶踩碎的声响; +> 看湖面的涟漪,一圈圈散去——散成悲伤。 +> 吹面不寒的东风,却溢满了深深的惆怅; +> 舞动的杨柳,孤芳自赏。 +> 张开双臂,想要飞翔,奔跑的快乐想要与你分享。 +> 可终究无人来解,我的失意徜徉! + + diff --git a/src/content/posts/2013/2013-08-02-the-moonlight-in-city.mdx b/src/content/posts/2013/2013-08-02-the-moonlight-in-city.mdx new file mode 100644 index 0000000..2ba3923 --- /dev/null +++ b/src/content/posts/2013/2013-08-02-the-moonlight-in-city.mdx @@ -0,0 +1,37 @@ +--- +title: 城里的月光 +slug: the-moonlight-in-city +date: 2013-08-02 07:51:26 +updated: 2020-09-06 13:01:25 +tags: + - 思念是一首诗 +category: 杂思 +summary: 听着许美静的《城里的月光》,不由得想起童年读过的一句小诗:梦中每迷还乡路,愈知晚途念桑梓。 +cover: /images/2013/08/2013080200113300.jpg +--- + + + +<MusicPlayer netease={5252268} /> + +听着许美静的《城里的月光》,不由得想起童年读过的一句小诗:梦中每迷还乡路,愈知晚途念桑梓。 + +对于家乡,思念的情感是难以割断的,而且会越来越萦绕在脑海的深处,形成可以称之为追忆的东西。每颗心上某一个地方,总有个记忆挥不散,每个深夜某一个地方,总有着最深的思量。无论你离家多久、离家多远,这一份浓浓的乡愁不会随着时间淡化,毕竟“月是故乡明”。 + +回忆往昔,恍然若梦。在泉城已经度过的四年。韶华流水,指间流沙,如今即将毕业我已站在了又一个新的起点上。似乎直到现在,故乡对于我来说一直是遥远的东西,那些与我有关的痕迹已经渐渐淡去,那个偷偷写小纸条表白的小姑娘,现在又在哪里?电影里说着念念不忘,必有回响,可现实却是名为残酷的玩意。 + +> 谁念西风独自凉,萧萧黄叶闭疏窗,沉思往事立残阳。 +> +> 被酒莫惊春睡重,赌书消得泼茶香,当时只道是寻常。 + +初读此诗的时候还在初中,当时的我只觉得这首词写的很有特色,纳兰性德文笔很好。那时的我并不懂得离合悲欢,不懂无奈。离家多年后,再一次从昔日的软文抄里面找到这篇《浣溪沙》,才恍然领悟名为寻常与珍惜的情绪。 + + + +旧城往昔,布满了记忆的青苔,时光是令人精神错乱的迷雾,恍然间已是夜未觉夜、华灯映射的都市。携一曲《城里的月光》,愿在这静静的夜里带走游子的愁绪,让旋律裹挟着以往快乐的片段,伴着泪水,在无声的悲伤中,迷失着自我。但愿今晚的月光能守护在你身旁,让追忆在远方游荡。城里的月光把梦照亮,请守护它身旁。若有一天能重逢,让幸福撒满整个夜晚。 + +世间万千的变幻,爱把有情的人分两端。心若知道灵犀的方向,那怕不能够朝夕相伴。我想,人的一生会遭遇无数次相逢,有些人是你看过便忘了的风景,而有些则会在你心底生根发芽。而我所知道的是,这一路会走得坎坷,走得艰辛,这人生的坎坷会让我明白谁是我要的寻找的那片月光,是我沧海桑田的家。爱是茫茫人海中不期然的相遇,像一场修行,修行的路像一首幽缓平静的曲调,意境优美、起落有致。 + +城里的月光映照着远行人的脚步,愿读此文的你能倾听到相仿的“回响”,享受那都市里如初的寂寞。 + + diff --git a/src/content/posts/2013/2013-08-07-fear-of-death.mdx b/src/content/posts/2013/2013-08-07-fear-of-death.mdx new file mode 100644 index 0000000..0480f01 --- /dev/null +++ b/src/content/posts/2013/2013-08-07-fear-of-death.mdx @@ -0,0 +1,57 @@ +--- +title: 害怕死亡 +slug: fear-of-death +date: 2013-08-07 00:52:58 +updated: 2020-09-06 13:02:04 +tags: + - 死亡 +category: 文章 +summary: 此刻有谁在世上某处走,无缘无故在世上走,走向我。此刻有谁在世上某处死,无缘无故在世上死,望着我。 +cover: /images/2013/08/2013080700214600.jpg +--- + + + +<MusicPlayer netease={411259267} /> + +> 此刻有谁在世上某处走,无缘无故在世上走,走向我。 +> 此刻有谁在世上某处死,无缘无故在世上死,望着我。 +> +> —— 里尔克《严重的时刻》 + +怕死是每个人都有的特点,小时候做梦梦到死去后的世界,常常会惊醒。长大后思考起死亡,我会想我要如何活好一辈子。看老舍的《我这一辈子》是在高二,当时的感触已经忘得七七八八了,但是忘不去的却是人生的短暂与无奈。 + +有时候觉得时光短暂,一转眼都 20 好几了,有时候越觉得好无聊,人要活这么久会不会很累。人就是这样自我矛盾与思考的动物,也许也正是有着复杂的唯心世界观,也才有了丰富的人生。有人说:“活着就朝着自己的目标去好好奋斗着,就算是失败又有何妨?而死亡只是一句简单的晚安,一种深层次的告白与解脱。”可是,到了真正面对死亡时,又能有几个人能淡定? + +一年前的时候我曾尝试着写死亡这个话题,对于死亡,试图长篇大论,结果是自己思维的渺小与肤浅。或许,正因为没有真正接触过,所以只能是一些只言片语。我只是觉得,太多人,对于死亡的思考,并不够深入。或者因为各种各样的忌讳,难于说出口。没错,这不是个轻松的话题,但相对生,面对生命的另一个端点,我们是如此漠视并恐惧死亡。但是如果不看清死亡,那生命的意义,我们至多理解了一半而已。对于死亡的思考的力度决定了我们生活的深度。 + + + +死亡是一个令我们忌讳的话题,可是谁能不面对呢?想想今后的自己,或许还要面对亲人的离去,心中不禁一寒。生命总是很脆弱,任何人,不论生前多么波澜壮阔或是波澜不惊,到最后的存在,只是那样一个小盒子,很残酷! + +十六年前我的叔叔因病去世;10 多年前,我还模糊记事的时候,我的小姑便因车祸离世;3 年前,我最挚爱的爷爷,因为病痛合上了双眼;一个月前,我那受了一辈子气的奶奶被查出癌症晚期。电话里和奶奶唠叨的时候,她絮叨着活着一天赚一天。生与死,转瞬之间,有时快得让人不知所措。 + +想起两年前的深夜和舍友一起看的电影《时间规划局》,生命变成了货币,人们可以永远不老不死,只要你有钱(时间)。有几幕我特别难忘:那位施舍了男主角一个世纪时间的富人,用最后的五分钟看着这个世界,然后,五秒的死亡倒计时开始。一对母子疯狂地跑向对方,母亲却没有多出一秒钟的时间,还是死在儿子怀里……每个人的死亡时间都是可知,那种恐慌,那种生活,让人不知所措。 + + + +一年前开始考虑写死亡话题时,我尝试着翻了翻陆幼青的《死亡日记》,时至今日,我依旧无法理解陆幼青的那份面对死亡的坦率与自然。对于我而言,缺乏的还是深度的思考,生命的沉重并不如死亡 + +那么坦率。 + +活着便是一切,我无法说我不害怕死亡,但也正是因为害怕,活着便有了意义,有了向前奋斗的动力,不是么? + +> “不能照例说再见的,虽然我们总要再见。 +> 且让我们入静,无论我们在哪里。正在干什么。 +> 在你去过的一座遥远的山里,向阳的山坡, +> 在一段久没有人走过的田埂,草丛中, +> 在枯涩昏黄的台灯光圈外。冷落的花盆中, +> 在为典礼而忙碌的皇家园林中,精致的圣坛, +> 有一些小小的,名叫向日葵的植物在生长, +> 笑脸为形,真金为色,且懂得寻找阳光, +> 让我们入静, +> 意念春光,静享人生……” +> +> —— 《死亡日记》的休止符 + + diff --git a/src/content/posts/2013/2013-09-21-mid-autumn-festival.mdx b/src/content/posts/2013/2013-09-21-mid-autumn-festival.mdx new file mode 100644 index 0000000..4ded9ef --- /dev/null +++ b/src/content/posts/2013/2013-09-21-mid-autumn-festival.mdx @@ -0,0 +1,34 @@ +--- +title: 皓魄当空宝镜升,云间仙籁寂无声。 +slug: mid-autumn-festival +date: 2013-09-21 13:16:57 +updated: 2020-09-06 13:02:26 +tags: + - 中秋 + - 思乡 +category: 杂思 +summary: 今晚的月光像从天堂里飘出的祈祷曲,安宁静谧,洒下一地慈悲。若不是身边的几个人正谈笑生风,真会让人觉得这清越微凉的月色有几分挽歌的意味,却不是将遁逝于无形的凄淡,而是禅意的透着一种繁华落幕,过眼无憾的泰然。 +cover: /images/2013/09/2013092100390300.jpg +--- + + + +<MusicPlayer netease={28785472} /> + +往日思绪缱绻,起舞于静夜暗自妖娆,清风徐来芳草荡,酣梦恰此时光。 + +今晚的月光像从天堂里飘出的祈祷曲,安宁静谧,洒下一地慈悲。若不是身边的几个人正谈笑生风,真会让人觉得这清越微凉的月色有几分挽歌的意味,却不是将遁逝于无形的凄淡,而是禅意的透着一种繁华落幕,过眼无憾的泰然。这仿佛不是属于人间的安宁大气,却在此刻毫无吝意地渐次铺展开,让人觉得分外奢侈。路边的石凳上泛着累年的光亮,有多少路过的人在这儿被赐予片刻的静憩,我想,那时时光俯首的姿势也定如这刻短暂而漫长。 + +那年灯下闹花衣,阿婆茶香绕松灯,也是在这样的细碎清光中你在桥边对我笑说“你也在这里”;一夜霓虹未歇,欢耍而倦的我尚能凭着年龄的优势伏在父亲的肩头酣眠,不问前路,不理夜长;闲来学人红笺寄情,只道素纸难透月中清愁,也总有那么几人捧场称好,不问真假,不理章法。朱颜年少,谁曾在你的指尖曼妙成花,谁曾在你的心池盛开年华? + +墨里浸染着古往,光阴败去了年华,不知什么时候,桥边的伙伴难觅,父亲也不在身旁,依旧熏风满帘渡玉兰香,绝景良时却是云间仙籁寂无声。于是,不敢再说自己寂寞,打回家的电话在极力展现境况之好;不敢再卖弄文字,朋友寒暄隐隐有了世故的成熟。前路摆在眼前,便不敢再“不问前路”了,青年已知愁滋味,便不敢再“为赋新词强说愁”。原来充满想象力的东西总是有无限的美好,而剪剪西风掠走的正是这岁月窖藏的想象力! + +风烟翠柳,夏花如画,是哪一年的光景中,船头清光碧波上,一行人醉笑三千,周末补课的空偷得渔村同学家里的船出湖赏光,男孩们在目光睽睽中脱得只剩裤衩纵身跃入水中,女孩们坐在船头嬉笑巧闹,泡在水里的脚荡开一湖褶皱;烟草风絮,秋日惶惶,火红的毕业花曾以一种对月临风,笙歌不散的看客姿态几度开败,也终于以这种姿态定格在我们记忆深处,一群人年少飞扬站在时光的交汇处挥手作别说着“以后常联系”…… + +如今往事散场,明媚的景致放在浮萍之上,岁暮的风一吹,全散了。常联系的不多,收到信息能让你感到由衷欣喜的就更少,听说有群发,看节日祝福时也不那么在意了,发祝福的时候也会想着多一个不多,而我们也或许是别人不嫌多的那多一个。我时常固执地不去加入节日码字的大军,固执地用心编写那为数不多的几条信息,可是 20 多岁的我终究不敢与这个时代格格不入,年龄是财富也是束缚。 + +黑夜如墨,朝露几许,我们总在彼此的相遇与离别中编织着一网故事,我相信总有人在为记忆的痕迹写下过往的细节。感怀的旋律中,也总有人是自己曲谱里的珍藏。时光霸道,抢夺了流年的芬芳,岁月的刻刀,也终将会划破红尘中曾相伴起舞的你我!但无论云卷间是否会把错落的年华镌藏,云散时又是否会流淌岁月滑落的故往,我都唯有珍藏,像这一刻的月色不带一点吝意地将曾经哪怕点滴的美铺展到整个生命。 + +身边的朋友们聊到了各自小时候的事儿,思绪辗转而回,此刻天心月圆,寂寂小路一地琥珀光。今天是中秋,月中仙是否已奏起笙歌,随风而起的思念在微风里含着柔情,最后还是不得不矫情地说上句,愿岁月静好,人事圆满。 + + diff --git a/src/content/posts/2013/2013-10-05-change-it-or-not.mdx b/src/content/posts/2013/2013-10-05-change-it-or-not.mdx new file mode 100644 index 0000000..399b1db --- /dev/null +++ b/src/content/posts/2013/2013-10-05-change-it-or-not.mdx @@ -0,0 +1,33 @@ +--- +title: 变与不变 +slug: change-it-or-not +date: 2013-10-05 11:33:12 +updated: 2020-09-06 13:02:52 +tags: + - 心路历程 +category: 文章 +summary: 开始写博,怀揣着思维变成文章的激动,心存着与人交流的憧憬。沐风栉雨,日复一日,更新、留言,方知写博不易。 +cover: /images/2013/10/2013100501035200.jpg +--- + + + +<MusicPlayer netease={30245099} /> + +10 年,《[雨帆](https://yufan.me)》呱呱落地。带着青春式的忧郁,一个人、一本写得满满的手抄本,一间写满喜怒哀乐的个人网站悄然面世。 + +开始写博,怀揣着思维变成文章的激动,心存着与人交流的憧憬。沐风栉雨,日复一日,更新、留言,方知写博不易。但是时光会赞许那些努力过的人们,小小的个人网站,在光阴的洗礼下,慢慢成长。那些逝去的日子里,总有些琐碎看上去无关紧要的记忆长久地扎根在脑海。淡淡的,让你几乎发现不了它的存在。可无意中回味旧文时遇见它们,竟然会莫名地感动。 + +旧时光是怀念的种子,好心情,难忘的事,都在《雨帆》的一点点成长中,发芽为美好的过去。 + + + +2 年,不长不短的时间,身边的人都变了不少。豆豆姐姐说:我已不再如从前、不想倾诉亦不再倾听。愿岁月静好!松鼠哥哥说:现在最关键的就是娶个小松鼠。咚门本科毕业,考上了研究生。而自己,也即将投身于茫茫的毕业求职大潮中。 + +与《雨帆》一起改变一起成长的岁月,是一叠写满故事的昨天。每每想起,那些逝去的、留给博客的青春,简单而朴素,忧伤并快乐,饱满地熠熠生辉。 + +说雨帆变了,其实也没变,依旧爱思考,依旧爱伤感。对于我而言,生活中的很多情感,藏在心底便是一种真实、深刻。一旦说出来,反而索然无味,比如爱情。但是沉默不等于不会说,而是一种积累、思考。我已不再如以前,每每遇到什么不幸就唉天叹地。相对的,看得更多,说的写的越少…… + +沉默是成长的标志,而雨帆之变抑或为某种成熟的标志,学会如何去沉默。想想岁月亦是如此的吧,这些年来,我们过得这么似水流长,静静的,却只在深处才见暗礁和漩涡,表面却风平浪静。我想,这大概是时光的艺术。 + + diff --git a/src/content/posts/2013/2013-11-04-see-it-or-not.mdx b/src/content/posts/2013/2013-11-04-see-it-or-not.mdx new file mode 100644 index 0000000..c77a039 --- /dev/null +++ b/src/content/posts/2013/2013-11-04-see-it-or-not.mdx @@ -0,0 +1,37 @@ +--- +title: 见与不见 +slug: see-it-or-not +date: 2013-11-04 04:39:28 +updated: 2020-09-06 13:02:58 +tags: + - 看见 +category: 杂思 +summary: 这段时间才入了 Kindle,看见贴吧里的人都在推荐《看见》,我是这两天才看。看完之后印象最深的不是柴静本人,而是她所描写的身边的林林总总。 +cover: /images/2013/11/2013110400534500.jpg +--- + + + +<MusicPlayer netease={1808104552} /> + +这段时间才入了 Kindle,看见贴吧里的人都在推荐《看见》,我是这两天才看。看完之后印象最深的不是柴静本人,而是她所描写的身边的林林总总。书里废话很少,都是朴实的文字但有重量。毕竟作为一个新闻人,你能看见什么,就决定别人能看见什么。 + +而其实我并未看过柴静主持的任何节目,只看过零星几个视频,还有别人写她的文章。但在我眼中她的书写得挺好,不是舞文弄墨的那种,而是那种信息量尤其之大,从容地对社会现象进行描述,特别的踏实没有戾气。 + +如果说柴静是个好记者,那多半是因为她总是不断在自省,书中记录了她的各种转变。而每一次转变的背后都是一股强大的力量,业界前辈的教导、同行的真实经历、自我的思考……看她写的文字,总会让你觉得莫名的安心,让我觉得如果她是个作家应该也不错。 + + + +书里写了:非典事件、山西煤矿、集体自杀的孩子、失地农民、吸毒的妓女,还有社会名流李安、卡梅隆、姚晨之类的。没有刻意选择标志性事件,她只选择了留给她强烈生命印象的人和事来写。 + +通往人心的道路是最艰难的道路,一个记者可能要付出生命才能得到别人的信任。但是你又必须在这个职业当中恪尽职守,所以我觉得记者必然是个很有内涵的职业。看惯了网易新闻和其中的评论,有时候我往往会有一种从众心理,这是极其可悲的。有时事情的表面并不像我们看到的那番真实,通过她的故事一点点地认识人、感受人、理解人,然后同时一点点地看清自我…… + +通过这本书你会接受真实的复杂无解,也或许能摆脱轻慢偏见和思维定势。在这书里你将看见生命的许多残酷,而一个人的生活,如果无法保持一颗积极的心,那必将哀莫大于心死。 + +我一直很喜欢看这种关乎社会现象的书,尤其是关乎最底层最不为人知的一面,比如我的最爱一直是韩寒极具抨击性的文章,因为对真实的任何粉饰都显得多余。所以,《看见》毫无疑问也是我的菜。 + +用书中的话结尾:我们都需要用点力气来生活,但如果太累了能不能就此歇着。市井人生,也不过如此。不要因为走了太远,忘了我们为什么出发? + +而见与不见,一切取决于心。 + + diff --git a/src/content/posts/2013/2013-11-18-wretched-history-of-my-childhood.mdx b/src/content/posts/2013/2013-11-18-wretched-history-of-my-childhood.mdx new file mode 100644 index 0000000..fea4125 --- /dev/null +++ b/src/content/posts/2013/2013-11-18-wretched-history-of-my-childhood.mdx @@ -0,0 +1,73 @@ +--- +title: 扒一扒当年的猥琐事 +slug: wretched-history-of-my-childhood +date: 2013-11-18 15:00:49 +updated: 2020-09-06 13:03:33 +tags: + - 黑历史 +category: 杂谈 +summary: 有道是人不猥琐枉少年,所谓宅男,鲜有不猥琐的。自古风流出少年,已然成为定理。作为即将大学毕业的大龄伪少年,我就来扒一扒当年自己做过的那些黑历史吧。 +cover: /images/2013/11/2013111801235800.jpg +--- + + + +<MusicPlayer netease={29822085} /> + +有道是人不猥琐枉少年,所谓宅男,鲜有不猥琐的。自古风流出少年,已然成为定理。作为即将大学毕业的大龄伪少年,我就来扒一扒当年自己做过的那些黑历史吧。 + +故事还得从大一才进大学开始说起,所谓“大四看大三的教大二的骗大一”,无非是说大一的什么都不懂,最好骗入社团,最容易被骗团费。可是我当时就只对一个社团感兴趣,就是那个跳健美操的社团。只是,只有这个社团只收姑娘,报名的学姐横眉一竖:“Just Girls”。本来这故事到了这里就该结束了,可是,某天我从澡堂洗澡回来的路上偶然发现前面的教室里面好像有一群姑娘。于是,我凑上去一看,哇,原来是健美操的妹子在里面练习。 + +那个时候博主还算是个屌丝男,算是那种愣头青。每周二、周四下午 6 点的时候洗澡回来,一手端个脸盆,一手提个超市 1 毛钱买的塑料袋装着换洗衣服,然后在那个位置看女生练习……那细胳膊细腿的,看得博主是气冲丹田,精虫上脑。恨不得上去亲自帮姑娘们压腿,拉韧带。但是,我不是女的,没法去练习,怎么办? + +没事,山人自有妙计也,上选课平台随便一搜。嘿~!博主的脸上瞬间露出了猥琐的笑容,色迷迷的小眼直勾勾地盯着中心校区的体育与舞蹈选修课。可是博主没选课,怎么破?大丈夫,萌大奶。我是去蹭课的,也幸亏当时博主脸皮厚,也就有了后面的猥琐事。 + +当时是 10 月上旬,天气还很热,去跳舞的姑娘都是短裙,一片白花花的大腿。跳舞人数差不多 80 人,女多男少,2:1 左右。我一般一节课要和 3 个女生跳。我记得有一节课,那个跳舞的女生很壮,一个男女转弯的舞步,直接把我甩出去,然后拽回来。女生的胸部很大,很大,非要用个字母的话博主告诉你是 E,真的是 E。然后一来二去每次跳舞到那个动作的时候,博主都会被那强大的胸部震撼到,情何以堪,但心里暗爽。 + +久而久之,那个胖妞就看上我了似的,每节课必须和我跳。你想想,我去跳舞就是为了和漂亮姑娘亲密接触的。那个胖胖的女孩并不好看,每次都像拧小鸡似的把我弄过来弄过去,折磨啊。于是我每节课都会换位置,可是一回头,那个妹子还是会站在我后面看着我,吓得我一身冷汗。 + +华尔兹跳舞的时候首先是男士摆出邀舞的姿势,然后女孩子过来“勾肩搭背”。当时有一次我还没摆姿势,那个胖姑娘就迎上来了,我当时就摆手说:“我还没准备好呢”。结果那个姑娘就有点丧气地转过身去了,后来据她同学说,她当时很受伤。 + +可是我怎么办,我可不想“狼入虎口”,于是我鼓动了我们宿舍的另外 4 个屌丝男一起去跳舞。有一个奶油小生长得很可爱的,如你所想,我解脱了。但是舞蹈课的中心校区离我们住的地方太远了,怎么办。于是我们 5 个屌丝男挤一辆的士。巧合的是每次都是同一个的哥。每次那个的士大哥就看着我们不说话,久而久之我们都和他熟了。 + +说实话华尔兹太无聊,还是恰恰舞好玩。没过多久我就厚脸皮跑去学恰恰舞。好几节课老师就在教女生怎么扭屁股,那个时候我还很屌丝。就在女生后面看她们怎么扭屁股。但是,我就悲剧了…… + +有一节课我看得津津有味的时候,没注意旁边站着老师,我就在那自言自语,“这个屁股大,扭起来真翘,那个如何如何”。结果,那个女舞蹈老师把我拉上最前面,要我当着 80 多个妹子前面学她们扭屁股!然后,每次和我跳恰恰舞的姑娘都会看见我就笑,完全出名了啊! + +但是,博主的春天也从这里开始起步。不过,那就是下一个故事了…… + +还有一个小插曲:当时那个胖妞还找我,让我向我的基友转告她的表白。我替她说完后,我的舍友吓一大跳,就直接说了句:“不会吧”。我记得当时在旁边偷听的那个妹子直接就泪奔了,整一个悲剧啊! + + + +下面继续扒一扒博主小学的故事。 + +那可以说是博主第一次情窦初开,第一次写情书的事。写情书的时候博主才上小学 4 年级,当时,小小喜欢班里一个大眼睛的女孩子。那个时候不知道怎么的,就是喜欢,现在想想,女孩子其实长得也不算很好看。不过记得很清晰的画面就是女孩子有点婴儿肥吧,手小小的,摸起来却很有肉感。 + +当时小学的座位是按照成绩排列的,某次考试后这个女孩就和我同桌了。 + +不知道有没有这种情况,有时候你喜欢一个人的时候你越喜欢她,你就会越疏远她。于是那时候还很羞涩的小雨就不敢正眼瞧那个女孩,桌上也没画三八线。但是小雨还是把自己书横在中间,然后用眼睛偷偷瞧。 + +很巧的是,那个时候应该是很炎热的夏天,四年级的女孩子其实已经有了点发育。然后那时候还没有男女之防,女孩子还穿着袖口开得很大的连衣裙,没有穿任何内衣。博主就从女孩子的袖口看到了不该看的春色,那小小的,有点微微发育的乳房。我偷偷瞅了一节课,就是那个很做贼心虚的看,偷偷瞄一眼,然后装作一本正经的样子。 + +但是你觉得你做得很隐蔽,可是在别人看来,却是正大光明的。一来二去,就被那个女孩发现了,我现在还记得那个女孩子生气的样子,真的很可爱。以前人家说气得眉毛竖起来,我当时倒是真的见到了。 + +然后那个女孩子就一直没有理过我,可想而知,当时对我的打击是很大的。 + +那个时候,你想想,9 岁的小孩子懂个啥,什么情呀、爱呀的怎么可能懂。但是,那个时候我的表哥就发挥了很大的作用。 + +有一次我在我的表哥房间里面发现了一大堆黄色小说,很小的小册子,就比小孩手掌大一点。里面说到各种剧情,我就不细说了,看得我是热血沸腾啊。 + +于是,从那以后我看那个女孩子的眼神就不一样。一开始只是觉得她很漂亮,然后很喜欢。后面就会想到很多色色的事情,7788 的,不能自已,我决定写一封情书给我喜欢的这个女孩(被琼瑶阿姨欺骗了)。 + +当时认为说,女孩子只要被男孩子写情书,就会喜欢上男孩子呀,就可以为所欲为了。于是我写的情书也很简单,用铅笔写的,就两句话:“饶婧璐,我喜欢你。我想和你困觉。”其中好几个字还用的是拼音。 + +当时上课的时候流行传纸条,我就写在语文课本上,撕下来给她的。那个姑娘看到之后什么表情我是不知道,但是我那一节课心情却很坎坷。 + +结果,那个姑娘直接就交给老师了。结果,我全家都被叫过来了,我那个时候在教室外面被罚站了 3 节课,甚至严重到差点被劝退,回家后又被爸妈男女双打。 + +但是结局你绝对猜不到,那个女生还真的被我泡上了,具体的细节我就不说了,五年级的时候我们就天天手牵手在一起了。 + +以上也就是博主的两件记忆深刻的黑历史,吐槽完毕,羞羞。 + + diff --git a/src/content/posts/2013/2013-11-25-the-poor-efficiency-of-android-program.mdx b/src/content/posts/2013/2013-11-25-the-poor-efficiency-of-android-program.mdx new file mode 100644 index 0000000..040bd59 --- /dev/null +++ b/src/content/posts/2013/2013-11-25-the-poor-efficiency-of-android-program.mdx @@ -0,0 +1,37 @@ +--- +title: 胡侃Android程序的效率 +slug: the-poor-efficiency-of-android-program +date: 2013-11-25 13:03:59 +updated: 2020-09-06 13:05:05 +tags: + - Android +category: 编程 +summary: 这天群里面大家都闲的时候,某君开始吐槽 Android 上的 UC 游览器,说以前版本的有多么快,现在的内存占用多大、多卡。一看到这个话题我就十分感兴趣,于是我就来胡扯一下 Android 上的程序效率问题,非专业文章,不喜勿看。 +cover: /images/2013/11/2013112501343300.jpg +--- + + + +这天群里面大家都闲的时候,某君开始吐槽 Android 上的 UC 游览器,说以前版本的有多么快,现在的内存占用多大、多卡。一看到这个话题我就十分感兴趣,于是我就来胡扯一下 Android 上的程序效率问题,非专业文章,不喜勿看。 + +说起 Android 程序开发,可谓是又爱又恨。想想我们当年写对应的项目开发的时候,是有多复杂就往复杂里面写。后面实实在在接触了 CPP,然后会了析构,才发现 Java 的性能,就算发展 10 年,也赶不上 C、CPP,然后对于 UC 的内存占用和效率就释然了。 + +Android 程序用的是 Java,底层的 JVM(Java 虚拟机)其实是用 C 写的。╮(╯▽╰)╭ 一想到这个,我很多时候就非常想笑。用一个性能优秀一点的语言 Target 指定,然后解析一个性能差一点的语言的字节码,这也算是跨平台的硬伤吧,这就和 python 说自己比 C 还要快一样是个冷笑话。 + +而其实,解释一下跨平台和不跨平台的区别,你就能对于很多程序的性能就释然了。学过编译原理的可能会知道,一般指定平台的程序的编译流程是:词法分析->语法分析->语义分析->中间代码生成->中间代码优化->目标代码生成。 + +于是,程序在编译过程中会针对目标的平台进行相关优化,这样子的优点是程序的性能可能会更好,因为不同的平台可能说的指令集和中断调度算法都不一样,所以说编译程序时指定平台效率更高。(这里面细节我有兴趣时再说,涉及细节的计算机体系结构方面的知识。) + +Java 一类的跨平台语言,比如还有 python,其本身的语法结构其实差不多,尤其在数据类型那边,基本一致。(因为编程语言的规范基本也就是 IEEE、MIT、ECMA 规定)它们的设计思想基本是编译到完整编译过程的中间代码部分,中间代码是平台无关的,一般是二进制文件。然后在通过平台相关的虚拟机运行中间代码。**所以说 Java 是跨平台的,Java 虚拟机不是。或者说 Android 程序是跨平台的,但是 Android 系统不是。**(正因为这一点,也导致了 Android 程序的反汇编很容易,破解也就自然不难了,目前大一点的 Android 程序都要混淆加密,虽然破解难度上升,但不是不能破解,只是运行效率不提也罢。) + +由于硬件架构、硬件芯片不同。(也就是解决方案不同,MTK 是完整打包整板,但是高通不是)不同手机之间的 Android 系统要指定编译。尤其是在目前开发基本用交叉编译的时候,对应的虚拟机部分其实也是有区别优化的。所以,所谓的 Android 深度定制,其实本质就是对虚拟机进行指定平台相关的优化。 + +反过来继续说 Android 程序,因为为了跨平台,所以需要涉及虚拟机。一般的虚拟机都是用 C 写的,本身虚拟机也为了最大化兼容,已经丧失了一定的效率。然后再用这样子的低效率运行一个更加低效率的程序,这就是 Android 程序的本质无奈。 + +所以外界永远不知道的一个我们程序员的真相就是,我们永远是在为未来写代码。因为我们的代码永远不可能高效最优,一个软件写得越久,就会越来越冗余,越来越低效。然后我们就会把责任推给硬件,然后硬件就发展了。然后大家就一直买新的设备,我们就乐得写越来越低效的软件。 + +但是,这点在中国有点行不通。因为大家基本都是穷屌丝,一台手机不可能年抛,基本要用上个几年。所以才有了优化在中国的兴起。所以小米才会以优化定制为乐。但是这个的本质还是不行的,小米以后手机出得越多,架构越复杂的时候,它的优化也就越来越难做。而做 APP 开发的也很难做,一个是你的程序肯定会越做越复杂。目前的 Android 应用开发模式基本是 Scum 敏捷开发而不是以前的瀑布流,周期短,但是更新频繁。所以,你所面对的程序优化就越来越难做。 + +程序写复杂了,运行起来必定比以前慢,然后那群消费者就不干了。没错,新手机运行很流畅,很好,我们这群老用户呢?然后就一群人开始骂骂咧咧,然后应用站就开始刷新应用好卡、好慢、好烂,负分、差评、滚粗。而其实 Android 的开发门槛真的很低,做的基本是大专和本科,核心的优化有真的不行。所以垃圾应用铺天盖地都是,然后不赚钱,于是,有技术的也都懒得做了。 + +所以说,在天朝硬件想换代,难。所以逼着我们写垃圾代码,写低效率软件,然后逼着你换代升级。(微软的 Windows 就是一个典型的例子。) diff --git a/src/content/posts/2013/2013-12-02-meeting.mdx b/src/content/posts/2013/2013-12-02-meeting.mdx new file mode 100644 index 0000000..2359bf9 --- /dev/null +++ b/src/content/posts/2013/2013-12-02-meeting.mdx @@ -0,0 +1,59 @@ +--- +title: 遇见 +slug: meeting +date: 2013-12-02 07:36:59 +updated: 2020-09-06 13:08:55 +tags: + - 信笺 +category: 文章 +summary: 写博客的时候最期待的就是遇见形形色色的人了,有时候能遇见这样一个可以聊得开的人,然后能交个朋友,其实真是一件非常舒心的事。 +cover: /images/2013/12/2013120201424100.jpg +--- + + + +<MusicPlayer netease={2014849468} /> + +写博客的时候最期待的就是遇见形形色色的人了,有时候能遇见这样一个可以聊得开的人,然后能交个朋友,其实真是一件非常舒心的事。下面节选了我和一位博友的来信,期待能遇见一个未知的你,和你交个知心朋友。 + +## 友人信 + +你好,雨帆妹妹。 + +前段时间在忙着毕业论文的开题答辩,没来的及给你回邮件,我表示很抱歉。 + +你给我发的邮件,我早已阅读。其实再忙,回个邮件的时间也还是有的,只是我看到你给我的邮件写得真诚很详细,这让我不忍心草草回复。想不到互联网中也还有这么细致的人,可以给一位陌生人写一封这么详细而真诚的邮件。这似乎让我看到了一点曙光,原来互联网上还有一个圈子,一个自由自(错别字,应改为“自由自 在”)分享观点与生活的圈子。我明白自己的文字表达能力欠佳,而且那个时候自己的心情也欠佳,所以拖到今天给你回复。 + +听着你博客里的“always with me”口琴曲写邮件真是一件惬意的事情。国内的互联环境真实坑爹(表述不恰当,可改为“国内的互联网环境着实令人无奈”),我只想说我很没安全感。今天颤颤巍巍地在阿里云提交了备案,不知道能不能通过。有时候在想,要是国内的所有个人站长能够组成一个联盟就好了,就相当于一个工会一样,能为我们的利益出头。 + +从你的博客中,终于得到了证实:你是个男孩子。我之前一直以为你是个女生,还想跟你搭讪呢!(嘿嘿)我去过厦门一次,那里真的很美。不过,那个海滩我很不满意,海滩太窄,而且沙子也不是很干净,跟三亚的海滩相比,很有差距。 + +我在三亚上大学,二本野鸭(错别字,应改为“二 本院校”)学校,坑爹的电子信息科学与技术专业。浑浑噩噩四年,现在都快毕业了,才发现工作真的很难找。正准备踏入独立博客圈,希望能在这个圈子提升自己。希望 3 个月之后,能找到一份跟网站开发有关的工作。 + +写了这么多,也不知道写了些什么。零零乱乱,满是怨气。不过看到了你的博客之后,我感觉自己比之前要平静得多。 + +雨帆兄,请你当个见证,今日我正式踏足独立博客圈,做一个独立的人,写一个有独立思想的博客。 + +PS:抄袭你的风格,我的域名是:<a href="http://xieqin.me/" target="_blank" rel="noopener noreferrer">xieqin.me</a>。 + + + +## 复书 + +既然知道我是男生还称呼我为妹妹,果然你是故意的,我无法想象你写下那个词之后脸上的邪恶表情。关于你在邮件中说道的细致和圈子,我想说:其实很多时候,博客就是一个人的独角戏。你苦心经营着一件属于自己的“店铺”,然后等待着同样“识货”的人的到访。有时遇见一个关注你的陌生人,心中就会有一种莫名的欣喜与安慰。 + +有时候我喜欢安静地看着后台的留言,那些活生生的头像、记忆中的点点滴滴细软,慢慢地想着属于自己的故事。有些暖心的留言,就像是无尽灰暗世界里面的一束光,永远闪烁、夺目…… + +关于你说的站长联盟,我有些无力与无奈,大家都抱怨备案,可是又有谁知道当年因为没有备案而导致的混乱呢?有些事情,真的说不好对与错,关键在于你心中的一把秤杆。 + +看见你抱怨学习,抱怨不好找工作,我真的不知道如何安慰,我上的是山大的软件工程专业,在 10 月忙碌了半个月的校招后轻松找到工作。也许是专业问题,也许是学历问题,我无法给予你恰当的安慰。但是,我所知道的是,毕业和工作,就像是人生中的一道坎。和高考一样,这道坎很高很难跨过,每个人都要面对,都有着类似的彷徨于无奈。我记得曾经在自己的某篇文章中写过:毕业,就是一窗玻璃。我们得撞碎它,擦着凛冽的碎片走过去,血肉模糊之后开始一个完全不同的世界。 + +而目前的就业现状,其实很多时候都是有心无力,你所要知道的是,无论任何工作和职业,最关键的其实是个人的能力。学历其实只是一道敲门砖,很多时候我看见了许多去霸面的大神,他们有些人的学历并不高,但是他们有的就是经验和技能。 + +见证了一个进入独立博客圈的博主,看见和自己当年相似的豪言壮语,我不知该是鼓励还是羡慕。2 年前的某天,我也曾像你一样起步,同样的宣言、别人的鼓励,温暖了我的一整个冬季。那时候孤独的我的心,第一次因为别人的赞美,提前窥视了明媚的春天。 + +所以,我在此也祝愿你能在独立博客圈的路上走得越来越远,欢迎加入独立博客大家庭。 + +走出宿舍门口时扭头看那已经凋谢了木槿,无意间竟然发现遗留在草丛间的旧作业纸,上面的字迹被雨水打湿,模糊难辨,只剩下一片的蓝。不知这样的作业交到老师的手里,会不会过于诗意?而生活其实就是这样,处处充满着惊喜,我们就像是草丛中的淡色小花,兀自开放,不必讨好,亦不在意。 + + diff --git a/src/content/posts/2014/2014-01-01-grown-old-with-a-age.mdx b/src/content/posts/2014/2014-01-01-grown-old-with-a-age.mdx new file mode 100644 index 0000000..6e80d69 --- /dev/null +++ b/src/content/posts/2014/2014-01-01-grown-old-with-a-age.mdx @@ -0,0 +1,45 @@ +--- +title: 同一个时代一起老去 +slug: grown-old-with-a-age +date: 2014-01-01 05:44:37 +updated: 2020-09-06 13:19:34 +tags: + - 怀旧 +category: 文章 +summary: 过去到底有什么呢?为什么会让这么多人怀念,甚至是想回到过去?本想一点点梳理、细说那些难忘的点点滴滴,却总记不起曾经的刻骨铭心,只剩下些支离破碎的片段可以回忆。 +cover: /images/2013/12/2013123101375300.jpg +--- + + + +<MusicPlayer netease={2131376044} /> + +过去到底有什么呢?为什么会让这么多人怀念,甚至是想回到过去?本想一点点梳理、细说那些难忘的点点滴滴,却总记不起曾经的刻骨铭心,只剩下些支离破碎的片段可以回忆。日本有句谚语:“三岁时眼睛里看见的东西,到了八十岁都不会忘记。”可是,才二十岁出头的我还是忘记了…… + +看来,谚语毕竟是谚语,它包含着人们对种种不美好的期盼、美化,而不是事实。我相信每个人对于自己三岁或者说小时候的事情都没什么印象,我对于过去的记忆很大一部分来自于父母的口口相传。有时候看着照片集里面那个似曾相识的自己,就会有种惶恐,似乎什么东西在慢慢离自己远去。倘若让我相信那句谚语是真的,我更愿意认为是,只有你到了八十岁,开始怀旧时,那些年少沉埋于心的记忆才会慢慢复苏,供人品鉴。 + +但,你还是忘记了,无论往事是否重现,那些过去终究不能成为你生命的一部分。那年花开年少,人面桃花相映红,你看过那些美景,爬过那些群山,走过那些小路。但是因为年少,你还不知记忆的重要性,于是便渐渐淡忘了。直到想要回忆,想要书写一篇文章缅怀时,才发现你只记得去过、见过、记过。 + +曾写过各种回忆的文章,绿皮车厢的记忆,种种过去的零食、玩意,久了,也免不了感叹时代的变迁,似乎一切都在慢慢老去。昔日一起 High 的大哥、大姐基本成家立业,同龄的小伙伴们很多也都开始实习工作,熟悉的一切都在慢慢离自己远去…… + +怀旧的博文写多了,免不得自己也开始忧郁起来,以致于谈起时代的变迁就会有无数的念头在心中浮现,颇有种不吐不快的感觉。而其实,这个世界一直在变,只因为我们不曾注意,猛然间环视周遭,才发现已经物是人非。 + +那个时代,那些人。 + +儿时最喜欢的童谣就是《节气歌》:“春雨惊春清谷天,夏满芒夏暑相连,秋处露秋寒霜降,冬雪雪冬小大寒。”每一个节气的名字连读出来,就像是一首诗。在那个没有暖气、没有空调的过去,季节的更迭,是那样的分明,让人愈发地想念,往往脑海中最先浮现的画面莫过于过去的砖瓦平房,那逼仄的小巷。 + +由于那个年代里还没有商品房的概念,富一点的人家都是自己盖起小平房,父母一类的工薪阶层则是单位分的房子。由于都是一个大院的,邻里邻外都是熟人,所以家长里短、谈天说地算是常见的一番特色。那个时候,家家户户不锁门算是正常现象,也没有防盗门的概念。由于不设防,往往一个大院里没有隐私,每每某家发生了点什么事,消息便会很快在左邻右舍间不胫而走。也就如腾讯《大家》杂志上的某篇文章写得那样:“彼时的人,以及孩子,很少有孤单之感,因为开门见“山”——一抬眼便见熟人,那时的人,何来孤独与寂寞?” + +那个时候的人,大多还是很有人情味的吧。因为大家都穷,所以就没有了攀比和嫉妒。因为大家文化水平都不是很高,所以思想也单纯些。但是,当那些早期走出体制赚了钱衣锦还乡的人增多时,某种平衡被打乱了。那个时候,渐渐开始向往大城市,奢求那些花花绿绿的稀罕物。直到 04 年随父母去大城市务工,看见来来往往冷漠的陌生人时,才忆起过去的种种好,但是,我已经回不去了…… + +时间似乎随着自己的长大流逝得越来越快,就像以前的我们一样,很难预料到未来是什么样子。好不容易赚了钱了,房价却高不可攀了;课程开始改革了,而其实却负担更重了;好不容易上了大学,才发现因为扩招大学生不值钱了;难得经济发展很好了,PM 2.5 又开始席卷中国了……也就在这样频繁的时代变迁中,我们这一代人似乎开始慢慢遗忘昔日的种种——我们的故事随时代一起褪去了。 + +无意间加入了一个以 00 后为主体的 QQ 交流群,他们聊着我听不懂的东西,说着我无法理解的 NETA;他们玩着我到现在还没玩过的游戏主机,听着我从没听说过的韩国歌曲…… + +什么时候,我已经离这个时代这么遥远了呢? + +记得《风雨哈佛路》中有这样一段话:“世界在转动,你只是一粒尘埃,没有你,地球照样在转动。现实是不会按照你的意志去改变的,因为别人的意志会比你的更强些。生活的残酷会让人不知所措。”这个世界、这个时代的变革我们无法阻止,只能顺势而立。 + +于是现在的我,每每看到各种怀旧贴,总是有种莫名的喜悦。一切往昔似乎因此还存在着,还活生生地被大多数人纪念着,依旧是我们生命中不可缺少的一部分。而我,也是这怀旧大军中的一员。忘记了某些难忘的过去,却又忆起童年的点滴,随着那个愈发遥远的时代一起,慢慢变老。 + + diff --git a/src/content/posts/2014/2014-02-18-the-things-you-dont-know.mdx b/src/content/posts/2014/2014-02-18-the-things-you-dont-know.mdx new file mode 100644 index 0000000..aefd205 --- /dev/null +++ b/src/content/posts/2014/2014-02-18-the-things-you-dont-know.mdx @@ -0,0 +1,49 @@ +--- +title: 那些你不知道的事 +slug: the-things-you-dont-know +date: 2014-02-18 15:33:36 +updated: 2020-09-06 13:11:41 +tags: + - 黑历史 +category: 杂谈 +cover: /images/2024/04/2024041620404500.jpg +summary: 有道是活到老学到老,用通俗的话说就是,“你丫永远不可能什么都懂”。因此每每因为不懂被人笑话时候,我常常用这样的话来安慰自己。也就是阿Q精神,所谓的精神安慰法。 +--- + + + +<MusicPlayer netease={22821014} /> + +这是一篇胡言乱语的文章。 + +有道是活到老学到老,用通俗的话说就是,“你丫永远不可能什么都懂”。因此每每因为不懂被人笑话时候,我常常用这样的话来安慰自己。也就是阿 Q 精神,所谓的精神安慰法。 + +抗生素用多了,细菌就会有抗药性。自我暗示多了,也就常常会不起作用。 + +去年年末的英剧《夏洛克》可谓是吸引了众多腐女的眼球,在女友的熏陶下,鄙人也看了这部片子。但是很遗憾的是,就算是被人提前告知此剧与福尔摩斯有关,我也愣是没看出来半分关联。甚至是福尔摩斯的原名其实就是夏洛克都不知道,原著是贝克街 221 号在《夏洛克》中是 221A 号等细节更不用说了。 + +说实话,从小到大我就没看过福尔摩斯的小说,以至于当和女友讨论起剧情时被鄙视了很久。现在想想还脸上发红,女友每次拿这件事笑话我,我便会像《中二病也要谈恋爱》里面的勇太一样在床上打滚卖萌,拼命暗示自己忘记。 + +同样因为种种无知加装逼闹出来的笑话多得数不清了,久而久之,也就脸不红心不跳了,但是还是有一次在众人面前的出丑让我印象深刻。 + + + +那还是大一的时候,计算机文化课需要每名同学在期末的时候上台当着大家的面介绍点与计算机相关的东西。当时我是此专业的课代表,所以准备的尤其认真,加上当时自己因为接触计算机比别人早,懂得多,所以就装逼地翻译了一篇关于计算机界面的文章在 PPT 里面。 + +轮到我讲的时候一切都很完美,PPT 中比较难的单词我都直接脑补过去。直到谈到界面的分类的时候,GUI 和 CLI 的时候我直接读成 GUI 界面和 CLI 界面。这还不算,当时 GUI 这个单词我是一个字母一个字母读的。当我下台的时候,就被老师赤裸裸的打脸了。老师先简单表扬了一下我,说我准备得很充分。然后就开始纠正错误,GUI 是指 Graphical User Interface(图形用户接口),读作“归”…… + +因为计算机专有名词读错闹的笑话真是太多,细说起来得有个三天三夜。什么 Java 不叫家娃,什么 GNU 不叫 G-N-U,什么 SQL 不读 S-Q-L,等等。 + +计算机的名词读音就算再蛋疼你还是得学,对不?于是,在博主战战兢兢学习3年后又一次迎来众人面前出糗的机会了。 + +当时选修了一门名为《新技术讲座》的课程,同大一一样,老师要求我们每个人做一份关于最新技术的 PPT。因为装逼,博主便把当时 OSC 济南线下交流会上的 PPT 打包发给了老师。于是,最后一节课的时候,老师很高兴,进来就表扬了我,要我上台讲解我的 PPT。可想而知,演讲的效果有多糟糕。 + +叔本华说人生其实就是一连串的苦难,当时听起来觉得很二,现在想想也就是那么一回事,从无知到学习的过程,这一路得有多少够你受罪的。从小的时候你缠着爸妈问这问那,什么为什么星星会“眨眼睛”啊,为什么开水会冒泡,为什么……到你自己开始学习来了解你想知道的一切,小学读完了要上初中,初中后面还有高中大学,找工作后你发现还要学。 + +等到你懂得越来越多,甚至是在某个领域完全超越了周围的人时,似乎苦尽甘来了。这个时候的你往往会有一种自我膨胀感,你会以一种鄙视的眼神看着周围的小白,对于别人的提问以一种极度欠扁的语气回答。 + +但是,因果循环,报应不爽。《无间道》里倪永孝曾说过:“出来混迟早要还的。”因为你的自负和无知,迟早会被别人纠正错误打脸。然后嘲笑加害羞之后,又是苦逼的再学习过程。所以微博里面最好玩的地方就是可以看某些专家学者公知在那边叫嚣,然后被人赤裸裸的打脸,噗! + +所以,总的来说,还是低调点好。现在的我,往往更喜欢看别人回答提问,轮到自己解答的时候,也是小心翼翼考虑很久,百度对比后才给出答案。但是,人在江湖飘,哪能不挨刀。遇到被打脸的时候,害羞的同时,还是恶补不足的好。 + + diff --git a/src/content/posts/2014/2014-02-20-black-history-of-my-childhood.mdx b/src/content/posts/2014/2014-02-20-black-history-of-my-childhood.mdx new file mode 100644 index 0000000..fac0fd0 --- /dev/null +++ b/src/content/posts/2014/2014-02-20-black-history-of-my-childhood.mdx @@ -0,0 +1,49 @@ +--- +title: 扒一扒当年与父母斗智斗勇的日子 +slug: black-history-of-my-childhood +date: 2014-02-20 06:22:07 +updated: 2023-12-03 10:34:58 +tags: + - 黑历史 +category: 杂谈 +cover: /images/2023/12/2023120310325235.jpg +summary: 如果有人和我说小孩子什么都不懂,阻止他们玩电脑、看电视很容易的话,那么我的经历绝对会告诉你,你丫太天真了。 +--- + + + +<MusicPlayer netease={34509840} /> + +如果有人和我说小孩子什么都不懂,阻止他们玩电脑、看电视很容易的话,那么我的经历绝对会告诉你,你丫太天真了。 + +这不是我的血泪史,严格意义上说是我爸妈的。 + +我的童年那个时候没什么娱乐设备或者是节目,家里唯一可以拿来消磨时间的就是电视机,于是从小我便养成了爱看电视的恶习。尤其是到了四年级,基本上天天晚上都要看电视,不看不行。《动画城》看完要看《大风车》,《大风车》看完要看黄金八点的《三少爷的剑》。久而久之,老妈嫌我看得太多了,不让我看电视。爸妈在家的时候没办法,只好收敛点,在写作业的时候时不时瞄一眼。 + +当时恰逢老爸出差,老妈上的是水泥厂化验员,三班倒,于是一场斗智斗勇的好戏就此上演了。 + +老妈要上小夜班,没法在家盯着我不让我看电视,可是电视在客厅里又没法锁起来不让看,这怎么办。老妈便想到了一个好点子。那个时候我们镇用的是闭路电视,就是类似现在数字电视用的同轴电缆的那种闭路线。老妈上班前把闭路线一拔,藏起来,我就没法看电视了。可想而知,等我放学回到家,家里就我一个人孤零零的,连电视都不能看,那是有多么寂寞。 + +于是我便开始了翻箱倒柜的找,连我爸妈藏避孕套的地方都没有逃过我的搜查,天无绝人之路,我终于在冰箱顶层的冷藏柜里面找到了闭路线。Happy,于是我的看电视斗争以小胜告终。 + +可是好景不长,很快老妈便发现闭路线别人动过的痕迹,在萝卜加大棒的威逼下,我不得不向父母坦白。于是藏的地点又变了,又是一番搜索,藏啊找,找到被发现后又重新藏。这么几次后,家里面能藏的地方实在是没有了,老妈也被我气得没法子,一怒之下,也不藏了,当着我的面把闭路线装进包里带走。 + +套用现在的流行语,当时我就惊呆了,有木有!一个人在家没有电视机,没有娱乐的孩子你丫伤不起啊! + +可惜道高一尺魔高一丈,我爸是学电工的,在他的影响下我小便在他怀里玩烙铁,所以我在这闭路线上起了歪心思。我记得那个时候无聊翻看我爸的书,有一本叫《闭路电视维修手册》。当时我也就当小说看了,什么电子管显像管的,什么信号解析的都看不懂。但是附录的内容吸引了我,闭路线的原理和制作方法。 + +现在距当时已经有10多年了,书里面的内容自然是记不清了,但是关键思想还在,那就是闭路线说白了就只有最里面的铜丝是有用的,外面有一圈塑料管做支撑,再外一圈是做电磁屏蔽用的铁丝网(这玩意我到了高中才懂什么是电磁屏蔽),最外面就是胶皮。我记得当时看完这个附录后,立刻便开始了实验,将家里放在碗橱底下的插排拿出来,随便剪一根线,然后插在闭路盒的中心最里面的孔里面,电视机那边如法炮制。嘿,还真能看了,虽然有些台信号不行,但是聊胜于无呀。 + +于是你可以想到当时的我是有多么得意,每次看到老妈上班前耀武扬威地当着我的面把闭路线装在包里面带走,我就在心里面冷笑,脸上却不动声色。 + +可是没过多久就坏事了,有一次老妈因为身体不舒服临时和别人换班提前下班,嘿,一打开门就发现我半躺在椅背上看电视。于是,一顿毒打加没收我的作案工具。哎,一下子又回到了解放前,我的看电视斗争又一次失败了。 + +家里没有用的电线一下子全被老妈扔了,一时半会还真有点巧妇难为无米之炊。作为我的阶级敌人,老妈可谓我肚子里的蛔虫,知道我不敢动家里面那些有用的电线。可是我又想看电视,这可怎么办?很快我便发现自己这是灯下黑啊,除了电线能导电,金属不是一样能导电?于是,家里面的衣架便惨遭我毒手,因为衣架多,少了一两个没人会注意。于是,我便偷偷肢解了两个衣架,串起来,嘿,依旧能看就是一些地方台信号差会有雪花,但是无伤大雅。 + +很快便是又一次发现加没收,然后我继续搜寻新的工具,这期间差不多有个十几次吧。最为经典的一次,是我直接把家里面的毛巾架拆下来,因为是铁管子,然后左右按照书上的原理拿赛车马达里面的线在左右两端做了两个简易的“放大器”。嘿,效果比一开始的电线还好。可是福兮祸之所伏,因为年纪小没法把毛巾架复原,于是可想而知的又是一番毒打。 + +现在上了大学,也就没有过去的种种限制了。我选的专业是软件工程,突然发现有一个好处:要是我的孩子有网瘾,看我玩不死你,嘿嘿。你爸爸我当年为了看电视无所不及,更何况电脑? + +当然,换句话说,以后要是有孩子的话还是女儿的好,我的经历足以引以为戒。 + + diff --git a/src/content/posts/2014/2014-03-15-the-poem-of-forget.mdx b/src/content/posts/2014/2014-03-15-the-poem-of-forget.mdx new file mode 100644 index 0000000..cc81b2f --- /dev/null +++ b/src/content/posts/2014/2014-03-15-the-poem-of-forget.mdx @@ -0,0 +1,91 @@ +--- +title: 忘却之诗 +slug: the-poem-of-forget +date: 2014-03-15 12:41:24 +updated: 2020-09-06 13:09:12 +tags: + - 爱情 +category: 文章 +cover: /images/2024/04/2024041620281800.jpg +summary: 有人说,记忆就像一首歌,你记不得它的词,却忘不了熟悉的曲调。香香姐姐说,记忆就像是陈年的女儿红,时间愈久才弥香。而我说:记忆,就是已经结痂的疤,每一次被迫想起,都扯得血肉模糊。 +--- + + + +有人说,记忆就像一首歌,你记不得它的词,却忘不了熟悉的曲调。香香姐姐说,记忆就像是陈年的女儿红,时间愈久才弥香。而我说:记忆,就是已经结痂的疤,每一次被迫想起,都扯得血肉模糊。 + +这不是一首忘记了的诗,而是一首由忘记组成的诗,它被我选择遗忘了八年。 + +<p style={{ textAlign: 'right' }}>——题记</p> + + + +## 一、あの日から + +对于小雨而言,04年那年他刚刚小学毕业,唱着羽泉的奔跑,随着父母的脚步,来到离厦门千里之外的济南读书。由于去得晚临近开学,小雨他爸不得不选择了全寄宿私立学校——齐鲁私立学校。时隔6年后,当小雨再次踏上这片陌生的故土,回望这所面目全非的学校的时候,那段尘封已久的记忆如洪水般袭来,心痛。 + +入学的那天小雨起了个大早,跟着老爸来到新学校报道,陌生的大门、陌生的面孔、看着很严厉的班主任,都让小雨对未来的生活充满着绝望。那段时间,是灰色的。对于一个只有十二岁的小孩而言,从那一天起,世界颠覆了。 + +第一次离家一个人住校,第一次和同龄人一起聊天到深夜,第一次晨跑,第一次在外一个人打理自己的生活,还有第一次对一个女孩刻骨铭心的伤害…… + +最初的最初,乃是最为寻常不过的相逢。只是在小雨的心底,成了命运的不期而遇。 + +至今小雨还记得那个姑娘,一头爽朗的短发,像极了男孩子,白皙细嫩的面庞,长长的“天鹅颈”,还有明明是初中生却比小学四年级学生还要娇小的身材。小雨还记得倒垃圾时,在垃圾桶里看到的她的作业本,皱巴巴的,上面张牙舞爪地写着——张清。 + +小雨还记得第一次见到那个姑娘,那是新生入学后的第一节班会,老师让大家轮流站起来自我介绍。轮到她时,她略带害羞地起身,小心翼翼地挪开凳子,低着头转过身来,以大家几乎听不到的声音快速地介绍完自己。然后迅速地转身坐下来,在桌上交错着手指,像极了受惊的小动物。可是,不是每个女孩会在被人欺负时那么平静不语。小雨记得,当自己把笔记本还回去时,名为张清的女孩只是漠然地接过笔记本,一句不语。 + +那天傍晚,小雨在学校的操场上一个人散步,一转头,看见她一个人孤零零地坐在操场旁的秋千上。夕阳同角落里的阴影交错地投射在她的身上,少女一个人荡着秋千,眼神却似乎在思考着什么。她的嘴角洋溢着淡淡的微笑,简单、美好。 + +她因紧张而交错的手指,她的小平头,她的大大咧咧的字迹,她那卸去伪装后的恬静微笑,在多年后的今年依旧在小雨的脑海里旋转,久久不能忘。 + +那一年,小雨恋爱了。 + +那一季,心事如花般绽放,年少到不知天荒地老,只想看着女孩微笑。 + +那一天,懂得心动,只需要一个瞬间。 + +love you more than I can say. + + + +## 二、好きって気持ち + +(还没写) + + + +## 三、さよなら + +(还没写) + + + +## 四、祈りの诗 + +那么年轻无虑的岁月究竟是何时被遗忘了,想要琢磨的那些时光却实实在在地模糊不清。那个每一天都饱满地像是一生岁月的年纪,那个想不出也不会想到明天的年纪,那个只喜欢在意一个女生的年纪。就像是漫长的前生,一直在某一个时光的转点之前悄悄地藏着。 + +那是怎样慢的一段时光呢?记忆里的每一个动作都像是分解开来的安然,缓缓地铺展成一片路途。想不出开始和结尾的日子,就这样远远地静默在时间里,轻易地想起却难再找回似曾相识的段落,只留悔恨。 + +继续遇见着一些人,离开了一些人。有些人不相识,却已是知己,有些人早就忘记。不时地想,我们已经分别多久?你,还好么? + +如果没有这篇记录,我可能什么都都回忆不起来,那些荒唐与幼稚的情绪。因为忘记,所以才可以成长不止。 + +于是那些在深夜不断浮现的伤痛记忆,一定是近乎悲伤地嚎叫着“不要忘记我们”吧。可是,最后你们一定会被我遗忘殆尽的。 + +对不起。 + +因为这是一首由忘却写的诗。 + + + +## 后书き~ + +有关此故事的草稿初期拟定后将近1年没有动笔,说到底,其实还是自己放不下这段往事。因为年轻时的不懂,我很难想象给那个女孩子造成了多大的伤害。而其实,我的内心一直是丑陋的、黑暗的,自己得不到的东西,总想着去毁坏。那个时候的我,因为自卑,觉得自己肥胖、长得丑,所以与周围的人一直格格不入。不会为人处事,不懂得如何交朋友,说白了就是书呆子。 + +而其实,真正的爱情故事并没有小说里面写得那么美好,因为年轻,每个人都会犯错,很多时候回头看当初的种种,才发现,自己错得离谱。也因此有了种种遗憾,无奈。 + +每个人的世界都是不同的,因为我们每个人都是独立的个体。我们不是任何人的一部分,每个生命诞生之后,其所要经历与承载的未来便与他人脱离了干系。相遇、分离、相爱、分手,这些都是。生命的本质是一场经历,一切的感触都取决于个人,正如真正的心痛,只能单方面的承受。一个人走一个人的路,经历一个人的人生。只有这些,才是真正属于我们自身的真实。 + +写下这么一个真实的故事,名字使用化名,还请不要对号入座。 + +PS:每一分篇的标题,都是一首如诗般优美的日语歌名,感兴趣的还请自己搜索。 diff --git a/src/content/posts/2014/2014-06-09-my-university-life.mdx b/src/content/posts/2014/2014-06-09-my-university-life.mdx new file mode 100644 index 0000000..4e386e7 --- /dev/null +++ b/src/content/posts/2014/2014-06-09-my-university-life.mdx @@ -0,0 +1,64 @@ +--- +title: 凡我在处,便是山大 +slug: my-university-life +date: 2014-06-09 13:19:55 +updated: 2023-12-03 07:01:05 +tags: + - 山大 + - 毕业 +category: 文章 +cover: /images/2023/12/2023120306435871.jpg +summary: 从忙碌的四月大补考到现在准备离校,一晃两个月过去了。停更的博客、塞满百封未读邮件的邮箱,似乎暗示的不仅仅是忙碌,还有某些道不出名的情绪。 +--- + + + +## 一、回忆 + +从忙碌的四月大补考到现在准备离校,一晃两个月过去了。停更的博客、塞满百封未读邮件的邮箱,似乎暗示的不仅仅是忙碌,还有某些道不出名的情绪。 + +忙碌的日子里,感觉时间飞逝,怎么也抓不住。就像一年前的[暑期实训](/posts/summer-training-record/),就是如此,往往抬头还是六月,低头离别的日子就这么到来了。 + +我能感觉到那些时间和日子逝去的彷徨,看着宿舍外的柳树从茂盛到枯萎,然后又迎来新的新生,有时候心情就像是那些路过的麻雀飞鸟,惶惶然又飞走…… + +但就在这种心情焦虑不安的情况下,回想过去,我也不曾后悔在大学度过的四年时光。虽然我曽一度沉迷于电脑中,翘课、通宵游戏、挂科,如同行尸走肉般活着。那段长达一整个学年的荒诞时光,就像是黎明前最为沉寂的黑暗,我挣扎地活着,想要逃脱那名为“寂寞”的牢笼,却发现自己已经身处围城之中。 + +但好在还有我的同学,是你们,让我及时悬崖勒马。彬哥的高数辅导、彤姐的考点划题、田妹的自习陪伴、亮仔的通宵答疑、阿峰的细致总结,没有你们的帮助,或许我并不能如期毕业,拿到手上的学位证。 + +从大一入学到现在与你们一一道别,也快有四年了吧。四年时间,说长不长,说短不短,也就南非世界杯到巴西世界杯的间隔。但四年前我们一起军训的那个夜晚,我们一起立下的理想,却永远不会更改。 + +我们依旧追求着自己的梦想,依旧爱着所爱的人,依旧向着美好人生的理想前进。有时挫折悲伤难过,但仍然前行,仍然走着选择的路。没有迷失在某个岔路口,仍然是我们当初所希望成为的样子。 + +希望再过十年,二十年,我们仍然在路上,不曾走失,不曾忘记年轻时的模样。不曾丢失爱我们和我们爱着的人。 + +## 二、爱情 + +对于雨帆而言,就是一个爱情失败者。两段大学爱情,就像是荷尔蒙不经意间碰撞出的火花,短暂,只留下名为嘲讽的空气。 + +我曾梦想过在这最美的时光中与某一位“你”不期而遇,谈一场只在青春中才有的风花雪月,携手漫步在校园里的一隅,也许只是一个微笑、一个眼神,便能理解彼此。 + +我就是这么天真着…… + +爱过痛过后才知道,人生有悲欢离合,感情也有高潮低谷,并不是每一段爱情都能天长地久。我们这一辈子总会遇到不同的人,展开不同的邂逅交集,一次次牵动着快乐和泪水,直到永远…… + +毕业、分手,独自一人乘公交车,一人走过木兰小路,无论多么悲伤难过,依旧得坚持走下去! + +那些回不去的少年伤痛时光,现在只能铭刻于心,随时间慢慢抚平。 + +爱过,因为青春;痛过,学会成长。我依旧坚信爱情,依旧相信生命中最美好的事物某过于此。炫若花火的激情固然难以忘却,然而一并度过流年何尝不是刻骨铭心? + +## 三、未来 + +我曾经在博客中写过,毕业,就像是一道窗,我们鼓起勇气撞破穿过它,然后血肉模糊地开始另一个新的开始。 + +生命那么长,又那么短。倘若按80年计算,那便是2522880000秒,就是这么漫长的生命轮回,一眨眼便过去了四分之一,让人惶恐无奈。 + +年少时曽有过的无数理想,青年时立下的化学研究梦,现如今都被现实扯得支离破碎,徒留着活着这一最底层的需求。也许我们中的大多数人,终年如一日地奔波在住所与公司之间,为着面包、住房、家庭而奋斗着。也许过去的豪言壮语是那么荒唐狗血,但依旧希望你不要将它们忘记,因为,这就是青春。 + +人生还很长,漫长到足够让我们忘记很多年前发生的事情……希望曾经一起并肩学习的朋友,无论你在哪里,你在何种阶段,学业、奋斗中、还是事业有成,都还能记得那些曾经的美好,不言夙伤。 + +很多年后,还是老朋友。 + +凡我在处,便是山大。有你在时,那便是家。 + + diff --git a/src/content/posts/2014/2014-07-14-the-first-week-of-accession.mdx b/src/content/posts/2014/2014-07-14-the-first-week-of-accession.mdx new file mode 100644 index 0000000..8397a93 --- /dev/null +++ b/src/content/posts/2014/2014-07-14-the-first-week-of-accession.mdx @@ -0,0 +1,46 @@ +--- +title: 工作一周记 +slug: the-first-week-of-accession +date: 2014-07-14 13:22:59 +updated: 2023-12-03 06:39:31 +tags: + - 毕业 + - 工作 +category: 文章 +cover: /images/2023/12/2023120306382895.jpg +summary: 有时候,伴着6点的闹钟声醒来,大抵会有种回到高中的感觉。习惯了大学里一觉睡到上午9点的感觉,现在突然要早起,一开始还真有点不适应。 +--- + + + +## 一、适应早起 + +有时候,伴着6点的闹钟声醒来,大抵会有种回到高中的感觉。习惯了大学里一觉睡到上午9点的感觉,现在突然要早起,一开始还真有点不适应。 + +原先读高中的时候,早上都是靠着爸爸把我叫醒,有的时候还要撒娇要老爸把我抱起来。工作一周后的我闹钟一响便能自动爬起来洗漱上班,想想还真有点不可思议,看来我还是蛮适合工作的。北京的地铁无时无刻不是那么的挤,即使是早上6点半的地铁,如果稍微晚了那么一会,也是人头攒动。因为我工作的地方属于北京CBD,所以我住的地方离公司很远。于是,每天的上班之旅,便是一场艰难的赛跑。 + +公交205路——地铁13线——地铁10线——步行,每天花在上班路上的时间就有1个多小时。记得以前在厦门科技中学读高中的时候,上学的路程也有将近1个多小时,每天我都是坐在晃悠的公交车的最后一排,一边迷迷糊糊地背着单词,一边色眯眯地瞟着漂亮姑娘。 + +记忆这玩意真的很奇怪,很多过去的事情,本来以为早已忘记,却又在遇到类似情境的时候回忆起来,让人捉摸不定。只是现在的我早已没有了看姑娘的心境,站在拥挤闷热的地铁车厢里,被人挤得连扶手都找不到。窗外是一成不变的黑暗,呼啸的风声让人恐惧,如同迷茫的未来…… + +## 二、消费水平 + +才来北京前同学间流传着各种关于北京的版本,无非不是什么北京消费高,环境差7788的。真正来到北京,开始工作才发现,很多东西,还是眼见为实的好。 + +北京的地铁和公交便宜到令人惊讶,2年前去上海玩,上海的地铁是按距离收费的,稍微远一点的地方,可能就要10元,北京的地铁是2元通票,无论你到哪个地方,无论你换乘几次,都是2元。而厦门的公交车就算优惠,也要0.85元,济南的空调车就算刷卡也要1.6元,而北京的公交都是4角,而且都有空调。 + +才工作的那几天的午餐倒是被坑了好几次,后面和前辈一起吃饭,才找到了物廉价美的地方。北京的生活消费水平没有想象中的那么贵,倒是房租,真的让人无力吐槽。 + +## 三、工作感受 + +不知道是因为才入职还是特例,我就职的公司易宝支付的工作没有想象中那么忙碌,好几个去了华为的小伙伴现在就开始天天加班。而我这里上班不需要刷卡考勤,工牌只有门禁的作用。工作的时间也可以自由调整申请,比如可以在OA上申请10点上班,7点下班。工作时间也讲究诚信自觉,比如饭点是12点,我们往往会提前20分钟就在部门群里面募集小伙伴吃饭,但是会早于1点自觉开始工作。比起大三暑假项目实训的各种准时准点的指纹考勤,没有考勤的正式工作让人更加轻松愉快。 + +公司的同事大都很年轻,即使是我的部门主管李均柠,也才32岁。大家的脾气都很好,相处起来也十分容易。就算是比较严肃的公司技术中心季度大会上也会直接拿主管开玩笑:“均柠你什么时候结婚啊?”更有甚者,在我们这群新员工集体介绍的时候会在下面吼道:“台上的妹子你们单身么?”(不要无视还在自我介绍的我啊!) + +--- + +总的来说,虽然才开始工作一周,但是我已经习惯了那种和读书不一样的节奏。每天晚上惬意地坐在回家的公交车上,看着窗外的灯红酒绿,总会有诸多感触。这也许是最糟糕的时代,但也一定是最好的时代。对于我而言,新的未来大门已经开启,等待着我去探索,去创造。 + +还记得高中毕业的时候班主任王晶曾[说过](/posts/when-i-was-young/):“你不能够保证,你奔跑的方向比现在的高,但是,可以肯定的是,朝着那个方向,你在前进。”学习、工作、赚钱、成家,也许我们一直在为着梦想而奔波着,但是一直不变的是,我们一直在努力。 + + diff --git a/src/content/posts/2014/2014-08-09-this-is-the-linux.mdx b/src/content/posts/2014/2014-08-09-this-is-the-linux.mdx new file mode 100644 index 0000000..25a8421 --- /dev/null +++ b/src/content/posts/2014/2014-08-09-this-is-the-linux.mdx @@ -0,0 +1,66 @@ +--- +title: 我的Linux学习历程:那些我看过的Linux书籍们 +slug: this-is-the-linux +date: 2014-08-09 13:24:49 +updated: 2020-09-06 13:26:51 +tags: + - 图灵 + - Linux +category: 编程 +cover: /images/2024/04/2024041520520400.jpg +summary: 来北京工作已经一个多月,大都市的生活比起读大学要忙碌得多,尤其是出行,基本以小时为计时单位。有时茫然看着窗外车水马龙,会有些迷茫自己选择的是对还是错。 +--- + + + +来北京工作已经一个多月,大都市的生活比起读大学要忙碌得多,尤其是出行,基本以小时为计时单位。有时茫然看着窗外车水马龙,会有些迷茫自己选择的是对还是错。 + +题外话不多说,回归这次的主题,扒一扒我看过的那些Linux相关的书籍。 + +对于Linux的了解和接触,缘起自大一时候的Linux限选课,老师说这门课可选可不选,但是选修后考试挂了的话需要补考。当时的我还比较爱学习,于是兴冲冲地选修了这门课,用的是清华大学出版社出版的《Ubuntu Linux应用技术教程》。这本书写的并不是很好,里面对于图形界面的叫法还是最原始的XWindows,此书一大半都是基于图形界面说什么安装啊、应用软件使用啊、7788的。但也简单讲了`bash`的使用和常见的命令,比如`ls -all`然后用管道`|`将输入导入至`wc -l`来计算文件数,还有一些简单的vi编辑器的使用,Shell脚本的写法。 + +当时因为才开始学的原因,什么都不懂,渐渐地,也就失去兴趣没怎么好好学。课程对应的实验都是和老师卖萌才过的,考试的时候也就是背了一下往年的考题,考完就忘得一干二净。现在想起来,还有点小后悔。 + +本以为噩梦就此结束,我与Linux应该是老死不相往来,作为一名从小学四年级就开始学习使用Windows的用户,我真的很难适应和使用Linux。可是大二学习操作系统原理的时候再一次无奈了,我们的一切实验的环境都是在Linux下面,使用那些基本`fork()` `pipe()` 等Linux下面的C函数进行操作系统的实验。当时在极其痛苦的情况下重拾课本,花了整整一周时间去学习使用Shell,学习简单的C语言(**妈的,看的是谭浩强的书**),会用vi来编辑,会手动写Makefile使用gcc编译。 + +这期间通过学长的介绍知道鸟哥这位Linux大牛,开始阅读他的《鸟哥的Linux私房菜》。很遗憾的是,鸟哥的教程是基于CentOS来介绍的,看完开头极其冗余复杂的安装部分,我就“阵亡了”。“妈妈啊,快来救我,Linux怎么这么复杂,什么Ubuntu、什么CentOS,还完全不怎么一样。” + +真正意义上接触并使用Linux,严格意义上说还得感谢“笨兔兔”这位Linux大牛。当时 Ubuntu 12.04 正好才出,本着不装逼就不会死的精神,我安装了这个系统,准备弄个双系统来装装逼。在研究如何配置 Ubuntu 12.04 的时候正好搜到了笨兔兔在他的博客发表的配置博文,当时也就是按照教程一行一行地复制粘贴命令。稍微知道如何使用 PPA 来安装 Ubuntu Tweak (一个国人写的对Ubuntu进行简单定制和优化的软件,你可以理解为Win里面的360)。这期间阅读他的博客,接触到深度的Linux发行版Deepin Linux。 + +什么?专门为国人打造的便于国人使用的Linux?不错,装! + +在我安装使用后立刻就被它的界面所吸引,坦白说 LinuxDeepin 12.04 真的很优秀,它基于Ubuntu 12.04 的基础上,去掉了那个真的超级丑超级难用的Unity,美化了各种常见的组件。直到现在,我家里上大学前的台式机还装的是此系统。 + +当时逛Deepin社区的时候,看到懒蜗牛Gentoo的《Linux入门很简单》出版了,看完电子版前2章后我就被此书深深地吸引了。真的,它一点都不枯燥,语言十分浅显风趣,内容也简单使用。实体版到货后我立刻通宵2天把它看完,虽然最后部分的程序编译有点云里雾里,但是基本的日常使用已经无碍。 + +这个时候Linux已经基本被我用于日常的装逼,每当我在自习室前排用着Linux上网,常常会以一种看土鳖的眼神看着那些 Mac 上装 Windows 的同学,心里暗自发笑。 + +故事本该到了这里就结束,反正Deepin日常使用已经无碍,还有什么好学的。可命运就是这么神奇,它往往会在你最得意的时候给你浇盆冷水,让你“压压惊”。 + +那时已经到了13年,我开始迷恋上写博客,在学校组团参加CCF大会的时候接触到阿里云,和阿里云的销售一聊天,他大手一挥给了我一张半年的代金券,此券也开启了我新的Linux学习之路。 + +下单安装ECS系统,果断Linux,选择系统的时候果断装逼,Ubuntu和Deepin一样,咱不屑于使用,咱要用CentOS。等云主机资源分配好可以运行时,我就傻眼了。纳呢,没有图形界面!只有一个简陋的Shell界面!这不是坑爹么! + +没有熟悉的 apt-get,没有了熟悉的软件包名,我不得不重拾大一的课本继续蛋疼地看那些常见命令,yum 的使用也让我蛋碎一地。等我使用 yum 搭建好 LAMP 环境嘚瑟地在一个主机交流群里面炫耀时,某位大神(**这里他要求不透露姓名**)很是鄙视地说:现在流行LNMP,流行编译源代码。 + +得,你丫瞧不起我是吧,我也给你整出来…… + +这期间学会了很多,参考了各种官方文档、手册、教程,一点点学会如何`wget`源码包,如何解包。看着`./configure --help`后面的一大串长到吐的参数一点点配置,看着`make`时候屏幕上滚动的各种debug信息暗自发呆。有时候为了解决一个简单的缺少依赖的问题Google一整个下午。即使是最后的编译完后,`make install`之后的配置也让我头疼万分,Nginx与FastCGI的交互,php-fpm的配置,MySQL的优化等等…… + +很庆幸有这么一段黑暗的学习经历,因为真正的动手学习配置才对 Linux 有了深入的了解。当然,用前女友云儿的话说:装逼是要付出代价的。因为对 Linux 本身产生了极大的兴趣,这期间也读了很多设计的书籍,比如那本《Linux/Unix设计思想》。我至今依旧记得那个经典的小即是美的设计理念,没有代码层面的讲述,全书薄薄的一册介绍了各种Linux相关的编程理念,十分经典。 + +还有就是那本《Linux内核设计与实现》,当时因为上选修课需要用到此书,在老师的讲授下结合以前学过的操作系统知识,真的能学到很多东西。比如,如何时间调度,如何实现排序,如何中断…… + +2013年年底买了Kindle,又一次开始了我的新的Linux学习之路,当时国行还没上市。因为学生党,兜里银子少,就买了日货。可是问题由此而来,日版没有中文界面。在研究时发现Kindle官网部分开源了Kindle的源码,于是我便萌发了自己编译Kindle内核来装逼的想法。从基础的交叉编译工具链的搭建,到内核源码的定制配置,BusyBox的编译,UBoot的定制,还有Eink驱动的移植…… + +因为涉及的东西很多很杂,在别人的指导下先看完了LFS手册,本着不装逼就不会死的原则先行尝试编译LFS,然后慢慢上手嵌入式系统的编译。因为基础比较薄弱的问题(连Shell脚本都不会写),又买了一本《Unix&Linux大学教程》读完。 + +说了这么多废话,该讲讲今天参加图灵活动赠送的书籍 **《Linux就是这个范儿》**。如果不是图灵市场部的英子姐姐在读者交流群里面公布了这个新书发布会,很有可能我就这的与这本好书擦肩而过。这本书是由阿里巴巴的两位大牛 **赵鑫磊** 和 **张洁** 写的,赵老师一直在淘宝大学里面做Linux的培训,此书的前身就是他的上课讲义。 + +书的内容真的很全很全,但很遗憾的是它不够细,可能是限于篇幅的原因,很多都只是简单介绍,一带而过。但是书籍的编写语言却十分风趣幽默,初看此书的第一眼,就有一种在看《Linux入门很简单的感觉》,十分亲切。 + +整个图书发布会上,张洁老师的精彩演讲,赵老师的健谈和广泛的知识面都让人印象十分深刻。很多问题,从他们的口中都能得到很好地解答。我曾经一个glibc的依赖问题将整个系统yum仓库弄坏,和赵老师交流时竟然发现他也有相似的经历,当然结果是无解。(╮(╯▽╰)╭) + +还记得赵老师在《Linux就是这个范儿》一书开头的那个“黄色冷笑话”,简单回顾一下我这短暂的2年Linux学习历程。其实很容易发现,学习,就像爬山一样,没有平坦的大道,需要努力地去攀登,即使途中某段是平面,那是因为后面还有更加陡峭的阶梯等待着你去攀登。 + +学无止境! diff --git a/src/content/posts/2015/2015-03-09-the-better-way-to-make-objects.mdx b/src/content/posts/2015/2015-03-09-the-better-way-to-make-objects.mdx new file mode 100644 index 0000000..d1d59cf --- /dev/null +++ b/src/content/posts/2015/2015-03-09-the-better-way-to-make-objects.mdx @@ -0,0 +1,202 @@ +--- +title: 如何更好地创建对象 +slug: the-better-way-to-make-objects +date: 2015-03-09 13:27:15 +updated: 2020-09-06 13:29:04 +tags: + - Java +category: 编程 +cover: /images/2024/04/2024041520472600.jpg +summary: 写Java一类的面相对象语言的程序员常常会遇到这么一个冷笑话:我今年都30了,还没找到对象,怎么办?简单啊,new 一个对象就好。 +--- + + + +写Java一类的面相对象语言的程序员常常会遇到这么一个冷笑话:我今年都30了,还没找到对象,怎么办?简单啊,new 一个对象就好。 + +当然这只是一个冷笑话,所谓的 new 一个对象,无非不就是调用这个类的构造方法去创建对象。乍一看也没什么问题,写个类ABC,用的时候new ABC()就好了。那么,会想一下,我们读书的时候,老师一定会说一个类的构造方法可以允许传入参数,甚至根据传入参数的不同创建多个构造方法。 + +学过面向对象的你一定会说,没错啊,就是这样,方法重载,签名校验。都是一个方法,Perfect!那么,我们设想下面这么一种情况: + +假如我们有一个DTO类 CredentialsAuthParam 作为对外接口的传入参数,作为一个POJO类,我们一般就是定义一堆属性,然后一堆Getter、Setter,比如,我们可以这么定义: + +```java +package me.yufan.dto; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import java.io.Serializable; + +public class CredentialsAuthParam implements Serializable { + + private static final long serialVersionUID = -1L; + + private String source; + + private String validationCode; + + private String operator; + + private String remark; + + public CredentialsAuthParam() { + } + + public String getValidationCode() { + return validationCode; + } + + public void setValidationCode(String validationCode) { + this.validationCode = validationCode; + } + + public String getOperator() { + return operator; + } + + public void setOperator(String operator) { + this.operator = operator; + } + + public String getRemark() { + return remark; + } + + public void setRemark(String remark) { + this.remark = remark; + } + + public String getSource() { + return source; + } + + public void setSource(String source) { + this.source = source; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this, + ToStringStyle.SHORT_PREFIX_STYLE); + } +} +``` + +看着很棒,多么简单,用 CredentialsAuthParam 的时候 new 一下,作为传入参数调用接口的方法就好。 + +那么,如果我的对象要设置属性怎么办?一个个Setter?为何不能在创建对象时创建呢?比如,构造方法里面指定参数?没错,然后我们就有了下面的一堆构造方法。 + +```java +public CredentialsAuthParam(String source, String validationCode) { + this.source = source; + this.validationCode = validationCode; +} + +public CredentialsAuthParam(String source, String validationCod, String operator) { + this.source = source; + this.validationCode = validationCode; + this.operator = operator; +} + +public CredentialsAuthParam(String source, String validationCod, + String operator, String remark) { + this.source = source; + this.validationCode = validationCode; + this.operator = operator; + this.remark = remark; +} +``` + +那么问题来了,参数这么多,又都是String,创建一个对象多麻烦。又比如,我只想指定其中3个属性,又都是String,但现在已经有了一个为3个String 参数的构造方法。怎么办? + +Java对方法重载的判断是按照签名的类型进行校验。所以方法参数顺序需要开发在使用时自己指定,也许我方法参数是:String source, String validationCode。但结果我因为复制粘贴不仔细变成了this.source = validationCode; this.validationCode = source;(别笑,你忙着写垃圾代码的时候就会出错) 或者构造方法使用者弄混了两个参数的顺序。那么就会出事啦。 + +其实如果你看过Java圣经Effective Java的话,一定会注意到里面说过构造器(Builder),多个参数的构造方法一定要考虑使用构造器。比如,我们可以这么写: + +```java +package me.yufan.dto; + +public class CredentialsAuthParamBuilder { + + private String source = ""; + private String validationCode; + private String operator = ""; + private String remark = ""; + + public CredentialsAuthParamBuilder setSource(String source) { + this.source = source; + return this; + } + + public CredentialsAuthParamBuilder setValidationCode(String validationCode) { + this.validationCode = validationCode; + return this; + } + + public CredentialsAuthParamBuilder setOperator(String operator) { + this.operator = operator; + return this; + } + + public CredentialsAuthParamBuilder setRemark(String remark) { + this.remark = remark; + return this; + } + + public CredentialsAuthParam createCredentialsAuthParam() { + return new CredentialsAuthParam(source, validationCode, operator, remark); + } +} +``` + +然后将原来类的构造方法定义为Protected,然后创建对象的时候只需要: + +```java +new CredentialsRequestParamBuilder() +.setRemark("remark") +.createCredentialsRequestParam(); +``` + +按照需求,设置几个属性就加几个 set 方法。 + +接下来,我们说说单例模式: + +单例(Singleton),顾名思义,就是只被实例化一次的类。比如,我在MVC的拦截器中需要调用一个公共类,它里面存放的东西是大家共享的,我可以这么写: + +```java +public class AuthorityInterceptorHelper { + + private static AuthorityInterceptorHelper instance; + + private AuthorityInterceptorHelper() { + + } + + public static AuthorityInterceptorHelper getInstance() { + if (instance == null) { + synchronized (AuthorityInterceptorHelper.class) { + if (instance == null) { + instance = new AuthorityInterceptorHelper(); + } + } + } + return instance; + } +// other code ... +} +``` + +我首先要在内部定义一个自身的静态对象,然后将构造方法私有,getInstance()会先去看静态对象存在否,不存在,先加锁,也许加锁期间其他方法先调用此方法创建对象,再看看对象是否存在,不存在,创建对象解锁。 + +看起来没什么问题,代码严密,十分规范,大家都是这么写的。但是,单例了么?定义为私有的方法一定没法访问了么?反射呢? + +其实枚举类便可以轻松实现需求,我们只需如下写法: + +```java +public enum AuthorityInterceptorHelper { + + INSTANCE; + +// other function ... +} +``` diff --git a/src/content/posts/2015/2015-05-09-lets-married.mdx b/src/content/posts/2015/2015-05-09-lets-married.mdx new file mode 100644 index 0000000..96846fe --- /dev/null +++ b/src/content/posts/2015/2015-05-09-lets-married.mdx @@ -0,0 +1,50 @@ +--- +title: 纵使生活平淡,爱情仍有万千期待 +slug: lets-married +date: 2015-05-09 13:29:16 +updated: 2023-12-03 06:25:45 +tags: + - 爱情 + - 影评 +category: 文章 +cover: /images/2023/12/2023120305291357.jpg +summary: 速度与激情7这一阵子很风靡,我却没有赶潮流看零点首映,上周末因为公司机房断电没法加班,便买了张票去看看,也算是我对保罗的致敬。 +--- + + + +速度与激情7这一阵子很风靡,我却没有赶潮流看零点首映,上周末因为公司机房断电没法加班,便买了张票去看看,也算是我对保罗的致敬。 + +只是不知道为什么看完速7,突然间想写些有的没的。如果你以为我写的是关于速度亦或是激情,那你就错了。今天我们聊聊时下热门的爱情喜剧《咱们结婚吧》。 + +一座城,四段爱,眼前的一切就是最好的安排。 + +听说暧昧和暗恋是最美好的感觉,高圆圆毫无疑问真女神。沉稳的男人应该是很多女生无法抗拒的,外加低调有才注重细节,也难怪国民女神最终沦陷。选择在女生无助的时候进攻一定不会失败,无法在一起那就是错的人。 + +对的人,是不会分开的。 + +若爱,请珍惜。 + +有没有一种女生让你一看就觉得心疼。我不知道陈意涵红起来是不是因为痞子英雄,但我知道每次看到她无辜的大眼睛,我都想替她掉眼泪。虽不是个恨嫁的姑娘,但29岁了想要个婚姻的承诺也是应该的。尤其是在这种男人40还一枝花的社会,对女生来说最重要的就是安全感。 + +这种片子一定少不了女强人+贴心男的戏码,以前有时候会认为:女强人是不是要跟男更强人才合适么?但后来渐渐觉得如果两个人是互补,那便再好不过。 + +再之后我看了杨澜的书,她说:“一个完美的女人在工作上要干练精明,下班后也要能够挽起袖子轻盈地走入家庭,角色的转换至关重要。”原话我已忘记,但是大意就是这样。所以我又改变想法,真正的女强人没有与谁更配之说,她该在工作与家庭之间找到完美平衡点。 + +而片中刘涛顾了前者却忘了后者,还好她是幸运的,因为有人包容。但要是你没那么幸运,那就只能做好自己。 + +在一起七年却在结婚当天发现这不是真爱,郭碧婷你特么以为你长得美就可以逗我吗?对于7年的感情输给7天呵呵即可。这段狗血出轨的剧情分分钟拉后腿,如果非要我给取个小标题,那就叫:你们离婚吧。 + +算了,荧幕上的爱情,总是具有多元性。而会为了这种无聊事物喜怒哀乐的,估计只有我这种双鱼座。 + +总的来说《咱们结婚吧》最大优点在于颜值较高,毫无疑问这点在这个看脸的时代极度吃香。对于这类劫财又劫色的电影,我真的是恨之入骨。但我又特么俗气到几乎每部都去支持票房。 + +人总是这么矛盾,老想找个平衡点,但在尝试之后发现有点点难。 + +不是影评,因为已经懒得去思考。不够深刻,因为没有犀利的视角。只感谢在此时的生活里,没有太多的不愉快。可是我一向不喜欢管人,所以我总在YY能出现一个人。Ta的作为总是与我的厌恶相悖,你说难不难? + +> Do not dwell in the past, do not dream of the future, concentrate yourself in the present。 + +PS: 速7不错看,歌不错听。 + + diff --git a/src/content/posts/2015/2015-05-10-having-a-lomo-life.mdx b/src/content/posts/2015/2015-05-10-having-a-lomo-life.mdx new file mode 100644 index 0000000..a94c93e --- /dev/null +++ b/src/content/posts/2015/2015-05-10-having-a-lomo-life.mdx @@ -0,0 +1,39 @@ +--- +title: 放慢,快乐 +slug: having-a-lomo-life +date: 2015-05-10 13:30:51 +updated: 2023-12-02 14:29:41 +tags: + - 慢生活 +category: 杂思 +cover: /images/2023/12/2023120214235774.jpg +summary: 因为工作的缘故,自己可控的闲暇时间越来越少,每日的加班,紧张得要死的工期。组长的口号就是:最短的时间,做出更多的事情。自然地,那种大学时的自由阅读时光愈发遥不可及。 +--- + + + +因为工作的缘故,自己可控的闲暇时间越来越少,每日的加班,紧张得要死的工期。组长的口号就是:最短的时间,做出更多的事情。自然地,那种大学时的自由阅读时光愈发遥不可及。也就过年时难得有空看看格言,开篇第一句话就是:“时间就像海绵里的水,总是挤,也会没有的。” + +不由得想起3年前看过的一本书:《放慢·快乐》…… + +我一向对喜欢笑的人很有好感,所以我从来不喜欢动漫里所谓的高贵冷艳型角色。会去看这本书,也只因喜欢封面上朱丹那明媚的笑容。因为我这人有个怪癖,没什么文化却喜欢逛书店,而且一般情况下只要那种封面看得爽的,然后书名取得文艺范儿一些的书我都会不管内容毫不犹豫入手。 + +但其实这类书大都没什么实质性的内涵,看了也不长见识,只会不断冲击你的各种人生观、价值观、世界观。还没准还会把原来正的给冲歪了,潜移默化地把我们领到一条没有尽头的不归路……朋友经常吐槽说我写的东西都属于无病呻吟款,估计也就是因为这类书看多了的缘故。23333333 + +而我们所不知道的是:“太多大家看似光鲜的东西,背后却是无人知晓的付出。”所以对于任何一个敢写自传的人,我都抱着佩服的态度。若没有足够精彩的人生经历,怎敢与众人分享? + +其实吧,在我看来,看一本书,只要自己能得到精神上的享受,在阅读的某一瞬间心里有震动过,那它就是一本好书。而《放慢·快乐》这本书里带给我们的是一个打不死的朱丹。无论是小时候家庭的变故,还是后来历经的挫折,都让她一度缺乏安全感。好在她总是乐观开朗,总能化灰暗为灿烂。 + +书里很多都在写亲情,朱丹说自己是一个恋家的姑娘,所有的努力都是为了家人。对啊!我一直坚信,恋家的孩子都很善良,自己一个人生活惯了,也难怪她内心强大。关于这个问题网上流行这么一个理论:“若内心足够强大,就可以选择你爱的人或事。若内心不够强大,那就选择爱你的。”你说这有理还是无理? + +而仔细想想,很多时候我们需要透过别人的眼睛看世界。我拙劣地认为,欣赏一个人的原因大抵有两种:“一是Ta身上有你的影子,你们有许多相似的地方,所以实际上你只是纯属自恋在自我欣赏。二是你想成为Ta那样的人,但实际上你没办法成为,只不过TA做了很多你想做却没做的事。” + +生命中总是有一些人与你不谋而合。 + +于是乎,我很欣赏林志颖,只因他的书《我对时间有耐心》中描绘的年轻时的匆忙和到中年时渐渐慢下来步调。 + +人生不能着急,挤出来的时间,被时间挥霍了。生命蒙上细尘,时间身不由己。慢工养艺,慢餐养胃,慢步养生,慢活养寿。总之,慢下来很养人。 + +只是我又在想,在这个什么都飞速的时代,慢生活是不是只能被无限YY? + + diff --git a/src/content/posts/2015/2015-05-12-i-am-right-here.mdx b/src/content/posts/2015/2015-05-12-i-am-right-here.mdx new file mode 100644 index 0000000..906e83b --- /dev/null +++ b/src/content/posts/2015/2015-05-12-i-am-right-here.mdx @@ -0,0 +1,32 @@ +--- +title: 你在哪里?我在这里 +slug: i-am-right-here +date: 2015-05-12 13:32:07 +updated: 2023-12-02 14:20:24 +tags: + - 雨季 +category: 文章 +cover: /images/2023/12/2023120214181317.jpg +summary: 浑浑噩噩熬过了一周,又是一个月的月底。书架上的《言叶之庭》,还只翻了两页。记得去年看完新海诚的同名动画的时候,就被动画里面爱情感动得落泪。跨越了年龄的距离,爱情,可以那么朴实。 +--- + + + +浑浑噩噩熬过了一周,又是一个月的月底。书架上的《言叶之庭》,还只翻了两页。记得去年看完新海诚的同名动画的时候,就被动画里面爱情感动得落泪。跨越了年龄的距离,爱情,可以那么朴实。 + +一直想着啊诚会不会像当年的《秒速五厘米》一样写一本同名小说,毕竟当年的那部动画,并没看明白。现实中,人与人之间的纠葛,并不是一部一个半小时的电影能够讲述完毕的。很多时候,文字往往比画面更有感染力。记得当时看完了“樱花抄”(小说的第一话),才慢慢懂了动画里贵树、明理的脆弱初恋。才懂了黑板上的姻缘伞,终究只是姻缘,而不是永远。 + +五月的初期,南方梅雨的季节,我如愿拿到了预定的《言叶之庭》简版。翻开书页,夹杂的是还未完全散去的油墨清香。啊诚的文字,依旧那么细腻,明信片上的手绘,依旧那么美好,男主的情感,还是简单到令人心碎。本想着第一时间将这本书读完,可现实中却是一拖再拖…… + +今年的五月,我已不是那个还在读书的小孩。繁忙的工作,排期到年底的超长计划,每天都要面对的零碎琐事,根本没有心思完全静下来读完一本书。五月的北京,没有了以前熟悉的雨季,也没有了熟悉的潮湿,更没有了熟悉的笑脸。有一次连续加了39个小时的班后很累,很累,连走回家的力气都没有,我就坐在公司楼下的长椅上看着来来往往路人,从黄昏看到夜幕降临,看到华灯初上。他们中大都行色匆匆,满脸严肃。 + +有时候会想,是不是现实真的如言叶里女主说的那样:生活中的我们,总是背负着自己的大大包袱,活得很累很累。出生、读书、工作、成家、相夫教子、退休、死亡。每个人都在按照既定的路线走着,或追寻梦想,或碌碌无为,终究只是这大社会的一粒缩影。无法放下,只能背负,我们的身上,凝聚着太多人对自己的期待和梦想。父辈的遗憾,需要我们来完成;未来的生活,需要我们自己独立打拼;自己的抱负,需要一点点去积攒。夜里的无眠,是因为和别人的差距太遥远,是因为生活的压力和迷失。 + +上周的北京,突然下了几场久违的小雨。淅沥的雨声,熟悉到令人发酸的水汽,还有那因为没带伞而奔跑着的我…… + +> 我们都是没伞的孩子,下雨了,不得不奋力奔跑,为了少淋些雨。 +> 只是无论跑得有多快,却总逃不了被淋湿的命运。 +> 一直在奔跑,也一直在寻找,只为找把能遮风挡雨的伞儿,以及那伞下的人儿。 +> 今天又下雨了,我在这里,可你又在哪儿? + + diff --git a/src/content/posts/2015/2015-05-31-how-to-choose-your-tools.mdx b/src/content/posts/2015/2015-05-31-how-to-choose-your-tools.mdx new file mode 100644 index 0000000..47af363 --- /dev/null +++ b/src/content/posts/2015/2015-05-31-how-to-choose-your-tools.mdx @@ -0,0 +1,71 @@ +--- +title: 如何找到适合你的软件 +slug: how-to-choose-your-tools +date: 2015-05-31 13:33:34 +updated: 2020-09-06 14:10:21 +tags: + - 软件 +category: 杂谈 +cover: /images/2024/04/2024041520204000.jpg +summary: 我一向不喜欢做一名所谓的“传教者”,向你推荐哪个软件好用,哪个软件比哪个软件好用,做什么事有什么好的软件可以实现。很多时候别人问我类似的软件推荐需求时,我都尽量避免回答。 +--- + + + +我一向不喜欢做一名所谓的“传教者”,向你推荐哪个软件好用,哪个软件比哪个软件好用,做什么事有什么好的软件可以实现。很多时候别人问我类似的软件推荐需求时,我都尽量避免回答。 + +当然,造成这样的结果还是因为去年年底开始,公司开始给我们配置了Mac笔记本。作为一个很早就开始使用Mac的人,自然地,看到初拿Mac的同事的各种Low B的使用,会忍不住吐槽和推荐。 + +可是,结局却不尽如人意。有些很棒的软件,要么是你给他装上去之后他一次都不用,要么是他坚持着自己的使用习惯。对于大多数人而言,切换了一个新的平台,第一时间想的却是以前的各种使用习惯,如果改变过大,便会抱怨…… + +于是也就有了以下的文字:(全部以文本编辑器为例) + +## 一、弄清软件定义 + +这个软件主要用来做的是什么? + +比如,文本编辑器,维基百科这样定义: + +> 文本编辑器是计算机软件中的一种。主要用于用来编写和查看文本文件。有一些特殊的文本编辑器支持增加自有的格式来丰富文档的表现形式。操作系统或者集成开发环境通常会带有可以查看和编辑纯文本的编辑器,可增加格式的文本编辑器通常是个人用户或者公司在制作需要格式的文件中使用。 + +PS,记事本真心不适合写代码,尤其是php代码 ;) + +## 二、你真的弄清楚了? + +1. 你现在的系统上有多少常见的文本编辑器,你能列举多少个? +2. 它们每个的特点又是如何,你们说出一两个它们的优缺点么? +3. 百度、谷歌之后,你能说出哪个该用来写代码,哪个该用来编辑Markdown了么? + +同样,对于任何一个类型的软件,我们不可能百分百了解这么多。但是,在寻找自己的心仪软件前有意识地收集归纳,是必要的。不是别人说这个软件好,这个软件就好了,要多知道几款,有意识地对比。 + +## 三、你的目的是什么? + +目的,也就是你的使用需求,你究竟想要用这个软件做什么事。比如说,上次我想编辑排版Markdown,有人向我推荐Word,我委婉地拒绝了他。因为他不懂我的需求,Word和Markdown完全是两码事。 + +你想做什么,是你选择某一款软件的决定性因素,也是你的最终目的,挑选任何一款软件前都必须明确,不能将就。 + +## 四、立刻下载使用 + +如果你觉得好,对它感兴趣,那就立刻下载,立刻使用。不要总是像松鼠一样囤积一堆软件放在那里,却一次都不用。 + +很多时候,需求是通过使用来慢慢明确细化的,比如你一开始只是想要文本编辑器,但是你后面发现你需要支持Markdown的文本编辑器,然后你又发现你不光需要它能支持,还要能高亮并实时显示。 + +通过大量使用有助于你对某个软件有自我的评价,而不是人云亦云。 + +## 五、及时更新版本 + +人是不断进步的,软件也是如此,新的版本也许有未知的BUG,也许有较大的改动,需要新的学习成本。但是新的版本也意味着新的功能,这样的体验,不是很美妙么? + +每时每刻都会有新的软件诞生,关注了解它们,丰富你的软件知识库,以防不时之需。 + +## 六、参与软件改进 + +软件的进步,需要用户的反馈,也需要你我的参与。对于缺点、BUG、需求,如果你真的喜欢某个软件,都要记得去提出。一般的开源软件基本都会有社区,或者是联系Email,或者是反馈地址。提出你的需求,有助于软件的改进。 + +当然,如果你是一名程序员,你还可以完全直接参与到某个开源软件中去。或者贡献翻译,或者丰富文档,或者提交代码变更。 + +--- + +那么,您是用户,还是缔造者,还是贡献者呢? + + diff --git a/src/content/posts/2015/2015-07-04-gossip-on-profligate-spending.mdx b/src/content/posts/2015/2015-07-04-gossip-on-profligate-spending.mdx new file mode 100644 index 0000000..bd3c649 --- /dev/null +++ b/src/content/posts/2015/2015-07-04-gossip-on-profligate-spending.mdx @@ -0,0 +1,203 @@ +--- +title: 扒一扒毕业后的败家记 +slug: gossip-on-profligate-spending +date: 2015-07-04 14:19:27 +updated: 2023-12-02 15:14:44 +tags: + - 败家 +category: 杂谈 +cover: /images/2023/12/2023120213463189.png +summary: 当年玩基三的时候流行着这么一句话:一入基三深似海,从此节操是路人。对于我这个用惯了Apple的人而言,可能感触最深的话就是,一入苹果深似海,从此金钱不够买。 +--- + + + +当年玩基三的时候流行着这么一句话:一入基三深似海,从此节操是路人。对于我这个用惯了Apple的人而言,可能感触最深的话就是,一入苹果深似海,从此金钱不够买。 + +今天,我就来扒一扒毕业后的败家记。(这是一篇中二病满满的文章,阅读前请戴好钛合金眼睛,以防被刺瞎。) + +## 败家前夕 + +作为索尼忠实粉丝的我,对于索尼的游戏机产品可谓是垂涎已久。(没错,请叫我索狗。)记得上高一的时候,“大法”的小霸王掌机(PSP)可谓是风靡整个学校。我的那群小伙伴天天上课就在那边刷怪物猎人,可谓是十分眼馋。 + +可恨的是,那个时候哪有什么钱,每次都是饭卡没钱了,问老妈要个50、100。印象最深的就是大一时对生物极其感兴趣,想买本《陈阅增普通生物学(第二版)》,但是又不敢向父母要钱。怎么办?我就以饭卡没钱的名义向母上要了100块,其中50元充值了饭卡,剩下的50拿来买了这本书。可想而知,那一个月我过得十分凄惨,每天在学校一顿只吃一块五:一个蔬菜一元,一碗饭五毛。 + +拿到书那天还是超级高兴的,07年那会网购还不流行,我当时通过邮局给高教出版社电汇买的这本书。这张邮局电汇的回执单至今依旧贴在我的《普通生物学》背面,纪念当时为了买书的幸酸挨饿史。 + +在这种兜里没几个银子,有几个钱也都拿来买书的情况下,我只能眼巴巴地看着我的同学玩着PSP。唉,无法守护“姨夫”的微笑还真是对不起了。 + +本以为这种兜里没钱的窘境到了大学会有所好转,结果我那お父様说既然读了大学,那就该自我独立了,大一的学费生活费我们给你出了,大二以后的生活费和学费就靠你自己了。 + +纳呢?(°ω°〃) 当时我就整个人都不好了,你们所不知道的是,山大软件工程大三大四的学费是一万六啊,一万六啊,一万六啊!(因为很重要,所以重复三遍。) + +这期间的幸苦,我就不说了,到了大四毕业,我才还完了问父母借的学费。(生活费我一个子都没要,哼。 (๑•̀ㅂ•́)๑✧) + +终于,苦尽甘来的时刻到了,哥毕业了!哥有钱了!如同吃了金坷垃般,开始了疯狂的购买历程,根本停不下来,老夫的麒麟臂要发作了…… + +## 开始败家 + + + +### Lamy Safari + +在疯狂败家前我还是一个爱读书的好孩子,所以非常喜欢做读书笔记,摘抄一些看起来很精致的文字,于是便买了一根白色Lamy Safari钢笔。工作后嫌以前的笔比较难看,便买了一根苹果绿的。 + +然而,工作后并很少有需要写字的情况,大多数时候,我都用于在开会的时候卖萌(就是转笔啦)。后面买了iPad之后,基本开会都玩iPad,就基本放在那吃灰了,233333。 + + + +### Playstation Vita 2000 + +工作后的第一个月,我如愿地拿到了第一笔工资,7800元。那个时候才来北京,交完压一付三的房租和其他的费用,提前扣除完下个月的伙食费和交通费后就只剩下2000多。 + +然而所剩无几的工资并不能阻止我购买 PSV 的脚步,工资到账时博主正随部门在爬华山。等下山入住西安后,已经是半夜8点。我立刻打开淘宝找了一家西安的电玩店,打电话确定还没关门,便在人生地不熟的情况下飞奔过去,店主sama有种你下班别走。 + +PSV2000 白黄机还有么?来一台。Project Diva F2 还有么?来一份。什么?内存卡只有 32G 的,没事,咱有钱,来一张。刷了卡就跑,真刺激! + +有了PSV后我超级开心,因为大四的时候在B站上看到一个名为[梅露露英语教室](http://www.bilibili.com/video/av392050/)的游戏视频合辑,说的是一个日本 Gust 社出品的 JRPG 游戏 [Atelier Meruru](http://www.ateliergames.eu/meruruplus/),当时看完后就超级喜欢,因为那配音、那人设实在是超级萌,瞬间激发了我的宅男之魂有木有!于是也想来一发,奈何这是一个PS3游戏,我还是个穷学生,连手机都买不起啊!后面通过Google了解到这个游戏有PSV版,我就早早计划着毕业后一有工资一定要买一台。而现在终于如愿啦! + + + +### Macbook Air 2014 Early + +7、8两个月陆陆续续买了1000多块钱的游戏,同时,在这期间我做了一个非常重大的决定——换电脑。其实我在大二下学期才有了自己的电脑,联想的Y460p,算起来也只使用了3年不到。才毕业入职时公司人力说,如果使用自己的电脑的话,公司提供每月200元的电脑补助。作为一个穷得叮当响的新人菜鸟,200元虽少,也是肉啊,所以果断使用自己不算太旧的小Y来写代码。 + +本来电脑也能凑合着用,如果不用 IDEA 写代码的话也不卡,奈何我旁边的同事使用的是 Macbook,有一天我们一起讨论一个设计方案时,他向我演示各种 Macbook 上的软件和便捷的命令行使用。 + +当时我就对 Mac 程序的流畅性惊呆了,说实话,我一直很喜欢 Linux 上的命令行。因为很多软件啊,比如 git、vi,都是只有命令行的,且 Windows 上想使用这些开发必备的软件都不是很容易。为了用 git,我记得我花了一个晚上下载了 MinGW,然后自己蛋疼地编译源码,期间解决各种依赖问题,最后为了整文件编码,花了3天时间,才成功在 Windows 下面使用 git 命令提交代码。 + +所以,看到 OSX 那亲切的命令行之后你知道我有多开心么?在换 Macbook 之前,我使用的是 LinuxMint,为了定制它花了很多心血,但是系统并不是那么流畅,而且没有 QQ 一类的中国电脑必备软件。恰好这个时候苹果在暑期针对学生优惠,价格便宜了近2K。Stop! Stop! Shut up! And Take My Money. + +我立刻去楼下办了张信用卡,借实习生的学生证分期买了台 Macbook Air。至于小Y,那破电脑在 Macbook 到手那天我就顺丰快递给我妈玩 QQ上海麻将去了。 + + + +### iPad mini2 + +iPad mini2的购买说起来还蛮有意思的,那个时候我还不是一名称职的果粉,说果黑也不为过,因为买不起,所以只好黑了,2333。而最后的购买的原因更多的是脑子一冲动的结果,因为在这之前,我都是一个很理智的消费者(谁信啊)。作为[平板盒子](http://www.pbhz.com/author/xiaoyu)的编辑一枚,我很早就接触了关于平板的内容,也常体验各种 Android 平板(其实就是觍着脸玩土豪同学的平板QAQ)。所以呢我一直都想有一台属于自己的平板,然后拿来看电子书,因为我是一个爱学习的好学生(此处该有掌声)…………才怪呢! + +iPad Air 2发售的那天晚上,我没有熬夜观看,也不知道有这么一件事,那个时候我还住在离公司28公里远的上地软件园,住的地方也没有网,所以早早的洗洗睡了。 + +第二天早上在西二旗排队挤地铁,无聊刷驱动之家新闻时才发现,iPad 竟然出新款了,出于某种IT从业人员的敏感度,我猜旧款的 iPad 一定会降价,而且这个时候一定会有大量的翻新机,所以价格一定是历史性的冰点价格。一到公司我就打开 Apple 的在线商城,卧槽,果不其然,翻新的 iPad mini2 只要2200块,比港水还便宜。二话不说,买买买。 + +付款成功后不到1个小时,iPad mini2 便断货,别说翻新机了,连全新机都没货了。可想而知,当时的我是有多得意,虽然兜里的钱越来越少,但是又圆了一个梦。从此博主踏上了钱包君一去不复返(啊呸),踏上了 Apple 全系列制霸(啊呸),踏上了忠实果狗的道路,离姨夫的微笑越来越远…… + + + +### iPad Air2 + +如果说 iPad mini2 的购买是一个美丽的意外的话,我想 iPad Air 2 的购买更像是一次理智的思考后的选择(谁信哦),有了 mini2 之后我深刻体会到 iOS 系统的流畅和强大,相比较下 Kindle 版的多看简直就是渣,于是在 mini2 拿到手的第二天,我便把伴随我2年的 Kindle Paperwhite 2 二手交易掉了。 + +恰巧,这期间因为表现好提前转正,工资也涨了不少,于是我手上可以挥霍的钱也多了不少。有一天晚上我加班到凌晨2点,只好在公司的休息室睡觉。在床上刷[古树旋律](http://tieba.baidu.com/f?kw=deemo)的时候突然觉得 mini2 的屏幕似乎有点小,然后就各种越看越不顺眼。(你丫不就是想找理由换个新的 Air 2 么?我懂,我懂。) + +上苹果团一看,最新的 iPad Air 2 港水只要3500,卧槽,这么便宜!(一个月前你还不是穷得只买得起mini2么?)立刻下单买了一台。 + +拿到手时,那外观、那手感自然是极好的,因为这逼格满满啊。尤其结合 Macbook 办公使用,真心很方便,这期间正好接触到 GTD,开始学习使用 Omni Focus。于是我花了258元在 iPad 上来了一发,然后放在电脑旁边做时间管理,真心很方便。 + +什么?越狱可以免费装,我去,买得起 iPad 和 Macbook,买不起一个软件么?(我才不会说那个时候我什么都不懂呢 QAQ!因此入手 iPad 一个月后,在上面光游戏就花了700多块钱了) + +### iPhone 6 + +忙碌的日子持续到2014年年底,工资越来越多,加班也越来越多,自身的幸福指数也越来越低。尤其是那台伴随我2年的Lenovo A789,不知为何,最近感觉它越来越卡。(不就是你丫手痒想换了) + +于是,又到了动物们交配的季节(啊呸)又到了该换手机的时候了。其实,在 iPhone 6 发售的当晚,我就在 Apple Store 上来了一发,但最后又退款了。因为对于我而言,Macbook 是生产工具,而 iPhone 更多的是一种娱乐工具,尤其是在我不经常用手机的情况下,买一台 iPhone 简直是浪费。(我才不会说那是因为你孙子突然发现买了 iPhone 之后还不起下个月的信用卡贷款了,才无奈退货。) + +那为何现在又想买了,废话,有钱了买一台爽一爽不行啊。有钱,任性。 + +### Macbook Retina Pro 15 2014 Mid + +换 Macbook Retina Pro 15 土豪版的时候已经是15年初,其实本来没有这一茬的,去年买 Macbook Air 的时候正好 Pro 系列更新,国行版要等上几周,尤其是乞丐版的 13 Pro价格只比我的定制 8G i7 128G 土豪版 Air 贵500块。 + +但是当时出于早买早享受的心理,直接下单 Air 了。后来一起入职的同事换了 13寸的 Pro,博主一边星星眼地看着那完全看不出像素点的视网膜屏幕,一边不断暗示自己:Air 轻便,身轻体柔易推倒。啊呸! + +这个时候正好兜里钱不少了,于是那还等什么,买买买,立刻购买!那买哪款呢?这还用问,必然是最贵的! + +当然,我才不会告诉你,这期间公司开始决定给所有员工配备定制顶配的 Macbook Air,导致我无法装逼,于是才决定换电脑的。(害羞脸 MuA) + +### iPod Shuffle & CX215 + +买 iPod Shuffle 的时候还是去年,那个时候还没从西二旗搬到后来的十里堡,所以上班要40多分钟。那个时候在地铁上要么看 Kindle,要么看技术书籍,印象极深的是有一次,我因为看《数据结构与算法JavaScript描述》那本书太专注,直到看完了,才发现,我在10号线上已经坐了好几圈了。 + +当然,地铁上不是每次都有空座的,尤其是人多的时候,你连移动一根脚趾都做不到。这个时候,往往就不知道该如何消磨时间,不如说,这个时候听听小曲,也是极好的。 + +但说到底,我并不是一个很喜欢听歌的少年,我对音乐的绝大多数记忆,都只局限于上个世纪80年代,我奶奶辈妈妈辈们喜欢的歌曲,还有就是某些日本萌系动漫的 OP 和 ED。所以当我初来到北京,听到满世界都是小苹果的时候,我的内心是极度崩溃的。 + +咳咳,话题扯的有点远,正因为这种原因,我买了一台 iPod Shuffle,因为不是音乐发烧友,也不迷信所谓的玄学,所以买了一根不是很贵的森海塞尔CX215,黑东只要299包邮哦。 + +你说什么?手机不就可以听歌了?不不,那可不行,你见过哪个音乐发烧友在地铁里摇头晃脑,然后掏出手机切歌的?你不是非音乐发烧友么?不不,这不符合我的身份,手机听歌没有逼格,逼格你懂么?就是 Bigger Than Bigger,比大更大。 + +后面搬家到了十里堡,上班坐地铁只有两站路,这个时候正好北京地铁即将涨价,想想兜里没几个银子,(废话,你这么买,能剩多少钱?)于是又买了一个风火轮,每天听着歌,骑着风火轮上下班,想想,也是极好的。(当然,那画面太美,我可不敢看`>\\<`) + +### Playstation 4 ice white + +农历新年后又开始了忙碌的工作,无意中发现,之前只和 Destiny 捆绑销售的 Playtation 4 白色机型开始有零售版了。我去,那还不赶快买买买!还没到中午12点便跑到最近的北京鼓楼电玩一条街提了一台才到货的日水。 + +这可不得了,买了后发现没显示器,那哪能行,立刻又跑到京东下单台Dell U2413。回到家,PS键开机,刷刷357,真是“西亚哇塞”啊!当然,目前发现 U2413 作为 Macbook 的外接显示器太悲剧,准备下个月入手 Dell P2415Q 4K 24寸显示器了。 + +其实这一段主要想讲的不是 PS4,而是对应的游戏。作为曾经的 3DH,啊不,3DM 资深 PC狗,浪迹三大妈论坛10余年,我一贯是主张咱们玩游戏的钱在八国联军时代已经付过了。然而,这并没有什么卵用,你要想玩 PS4 游戏,还是得老老实实交钱。WTH!WTF! + +于是,我的麒麟臂又开始痒了,[TLOU](https://psnine.com/psngame/6418?psnid=syhily)咋样?不错,当年看[纯黑的视频](http://bbs.a9vg.com/thread-4236049-1-2.html)就觉得了不得了,买!那个娇喘9(古墓丽影9)如何?不错不错,娇喘什么的,我是最喜欢的了`>\\<`,买买买…… + +就这样,博主踏上了购买游戏的不归路,我似乎看到胸前的红领巾越来越鲜艳,姨夫的微笑越来越灿烂。每当我会想起当年的酣战,我都会高呼,索尼大法好!千古罪人刘睿哲! + +### Playstation Vita 2000 Special Edition + +为何保卫姨夫的微笑,落实我的索狗头衔,自然又买了一台 PSV。我才不会说因为裸奔导致前一台机器屏幕刮花然后土豪地直接买一台新的把旧的直接当玩具拆卸一遍送给我的表弟的事实呢。(因为一口气说完没有断句 2333333) + +换了新的 PSV,自然也就有了一点闲钱,立刻把我前面提到的工作室系列全部收集完毕,花了1200大洋,全系列制霸,然后慢慢玩。(就是照片里面中间一排的4个游戏)为何不玩一部买一部?因为有钱呗。 + +当然,因为有了 PSV 和 PS4 两台机器,自然地买了 PS+ 会员,每个月也就买一两个游戏,然后买了放在一边,玩玩会免的4399,幸福指数爆表啊! + +### Apple Watch + +MLGB(买了个表)的时候应该是今年4月了,这个时候的博主已经是忠实果粉了,作为以 Geek 自居的我,自然地来了一发。然而并没有什么卵用,发现还不如我大学时买的 70 元山寨 Casio 看时间方便,现在不知道给我丢在哪里吃灰呢…… + +### New Macbook + +新 Macbook 其实是和 Apple Watch 一起买的,这个时候我的 Macbook Air 已经二手卖掉了,上下班背个 RMBP 15 又嫌重。没办法,娇气呗。正好这新笔记本这么好看,这么有逼格,京东白条还12期免息(刘强东我爱你,我要给你生猴子)。 + +还用说么?还不赶快买买买! + +现在,它已经成为我的星巴克主力电脑、回家后的大号 iPad。晚上用它看 B 站的时候,那温度,还是蛮感人的。你脸上怎么热得流汗了?不,你看错了,那是我因为感动流下的泪水,才不是什么汗呢! + +### FC660M + +在买 FC660M 之前,我有两把机械键盘,一把是 NOPPOO 的 Choc Pro POM 黑轴。性价比极其高。400元不到的价格你能买到 Cherry 原厂的黑轴加手感很独特的POM键帽。POM的质感很独特,非要说感觉,那就是很硬。 + +对你没有看错,就是很硬。因为很硬,加上黑轴特有的直上直下,当年被我专门拿来打 [osu!](http://osu.ppy.sh/)了,也就是这把键盘和 Wacom 的 CTL470 数位板伴我度过了无数个日夜,帮我 Rank 多首歌曲,BPM 300的歌曲也可以无压力,结合屌双和单点的指法轻松 Solo。 + +另一把机械就是大家很熟悉的 Cherry 原厂 MX 3.0 茶轴,买的时候图便宜,又冲着 Cherry 的牌子买的,买完后才发现,这货的质量就和它的价格一样,毫无人性。ABS 的键帽手感虽然极好的,但是才用2个月就油光可鉴,非浸染非二次成型只是丝网印刷的字体也糊成一片。要不是当时纯用于龙之谷,我才不买。 + +这两把键盘在我换了 Macbook 之后全部二手掉,无它,Macbook 太好用尔。然而,当我用烂了第四张 45 元的 Macbook 键盘膜之后,我又免不了想再买把机械爽爽。 + +可是,绝大多数机械键盘,都是为 PC 设计的,要想用专门的 Mac 键盘,有!1500多的HHKB(这货我从同事那借过来爽了一周后放弃),还有1800的 Filco 蓝牙键盘,还有一个 M 开头的品牌,但是它们的键盘都好丑啊。 + +我理想中的 Mac 机械键盘,首先要小,所以一开始我就直接考虑 60% 的布局。然后要有方向键,瞬间只剩下Race II 和 可以编程的 Poker II 和 FC660M了。 + +然后想要上PBT,想要热升华,想要铝板而不是铁板。这样一来,无论从哪个角度,FC660M 都是首选,可是 Mac 的键位和 PC 不一样,这是一个大问题。 + +在百度、谷歌、必应之后发现牛逼的 Karabiner,借了同事的鸭子尝试了专门的定制发现可以自由地指定键盘改指定按键之后(当然这是下一篇文章要说的事了),我果断决定买了。 + +买的时候因为志海和停止生产,韩国原厂准备找 KBT 代工。处于这个变更的间隙我,在淘宝全网无货的情况下,只能加钱花了800多在某黑心商人那买到了最后一把红轴白帽黑底。(心痛ing.....) + +### TrackPad & mStand & Thunderbolt to RJ45 + +为了装逼买了机械键盘自然也要付出对应的装逼成本,其实早在才拥有 Macbook 的时候,我便被 V2EX 上的某些人的工位毒到了。无他,因为那个 mStand 实在是太好看了,太有逼格了,太酷炫了。尤其是在买了机械键盘之后,我更加坚信:这个逼,我装定了。 + +淘宝搜索一番,卧槽,因为有了大陆的代理,原来500多的价格现在只要300块,立刻购买。买了这个之后想用触摸板怎么办?买个588块的 TrackPad 呗,世界上最大的苹果触摸板,我早就眼馋很久了。因为要用 USB 连接键盘导致 USB 接口不够怎么办?买个200块的 Thunberbolt 转 RJ45 的转接线呗。 + +于是,就有了你上面看到的画面,当然,我已经预定了2000元的 Thunberbolt 的 Dock,预计下个月从美国飘过来…… + +### 其它琐碎 + +别看博主买了这么多电子产品,博主也是一个爱看书的追风少年呢!买书看书什么的可是一本不拉,上面的书籍只是我的藏书量的三分之一,而且每本我都有看哦。 + +这个抱枕博主花了300还是400大洋买的,记不得了,超级喜欢哦。无聊的时候可以抱在怀里卖萌,可以中午睡觉拿来当枕头,不开心时还可以放在屁股后面当靠垫,还能摆在桌前说明我不是Gay。(似乎有什么奇怪的东西混进去了……) + +当然我还喜欢收集各种漂亮的明信片,喜欢和人交换,每一次交换,都是一次满怀故事的遇见。期待遇见同样一个爱好明信片的你,期待下一个百无聊赖中可以回味的故事…… + +## 结 + +不知不觉毕业后的一年就这么稀里糊涂地过去了,学到了很多,也失去了很多,但是不变的,还是那一颗买买买的心,23333。 + +战神3 PS4下周就出了,卧槽,还不赶快买买买!!! diff --git a/src/content/posts/2015/2015-09-06-we-are-stranger.mdx b/src/content/posts/2015/2015-09-06-we-are-stranger.mdx new file mode 100644 index 0000000..ddfec20 --- /dev/null +++ b/src/content/posts/2015/2015-09-06-we-are-stranger.mdx @@ -0,0 +1,59 @@ +--- +title: 我们都是陌生人 +slug: we-are-stranger +date: 2015-09-06 14:24:39 +updated: 2023-12-02 13:42:04 +category: 杂思 +cover: /images/2023/12/2023120213404421.jpg +summary: 还未从忙碌中回神,八月就这么不知不觉地过去,周遭的人事变换,认识了些陌生的新面孔,也少了些熟悉的旧面孔。 +--- + + + +还未从忙碌中回神,八月就这么不知不觉地过去,周遭的人事变换,认识了些陌生的新面孔,也少了些熟悉的旧面孔。 + +——题记 + +### 1. + +今年的八月,没有去年那般湿热,不知是不是因为毕业的日子早已离我远去,印象中里的毕业季总是在热火朝天的季节里,热得烦躁不堪却也要坚持穿上累赘的学士服四处拍照。就和初到北京时住的地下室一样,湿漉漉的地板墙壁,湿漉漉的被单床铺,像是初面职场时内心焦急的大汗淋漓。 + +那时的我,面对着陌生的职场,从来没接触的知识和技能,内心焦躁不安并自我怀疑。那样烦躁的日子里,睡前唯一能做的事,就是强迫自己阅读几页《Java编程思想》,每多掌握一点知识的时候,心中的焦虑便会被抚平一些。后来习惯了在公司通宵加班,大多时候,其实都是在看书,看设计模式,看关系数据库,看NoSQL,看并发编程…… + +看了那么多还是看不清前路,公司的休息室睡起来不是很舒适,每每梦里迷迷糊糊好像看见许多面孔,醒来却头沉沉什么都想不起来。却又总会莫名其妙回想起很多旧时的事儿:六岁那年那只追着我三条街的狗;中秋节的外婆牌麻糍;爷爷去世时躺的那块旧门板。 + +后来因为工作中种种事情焦虑甚至绝望的时候,就会没来由地想起这些细节,好像滴滴答答的流水,绵长久远,把时间拉长一点,把步子拉慢一点,甚至可以把记忆拉回好几年前。想起过去的种种,然后愈发地对自己陌生起来,就像是一个局外人,麻木看着那些属于自己的过去。而有时,又会有一种正在经历过去的不真实感,矛盾、错杂。 + + + +### 2. + +前不久的一天晚上,我看着自己的键盘。毫无疑问,我们已经熟悉到无话可说了。 + +工作后之后才知道,程序员的生活其实是一种乏味到极致的体现,两点一线的生活,上班时的代码和调试更像是某种重复的洗脑。有时候想要发泄什么,才发现生活平淡到你连骂人都没了素材。无聊的时间里也会想找东西发泄,比如在动漫和游戏中麻木自己,或是在一本又一本技术书籍中埋没自己。直到某一天,悲哀地发现自己连哭的力气都没有了。 + +大概是因为心累,七月的时候进行了一次转岗,开始到银行组,着手开发重构公司的核心交易系统。从专注技术的组件组转而开发业务系统,对我而言是一件很大的挑战。业务的不熟悉,设计的不全面,还有旧系统遗留下的各种坑,在初次接手的一个月里为此出了好几次风险事故。 + +领导对自己的不信任,同事对自己的抱怨,让自己一度绝望想要放弃。那时的我一个人负责全部项目的技术重构设计,项目组只有一个新入职的产品,一个才毕业的测试。全部的需求要我带着去过,测试也要我手把手教,代码只有我一个人写。算不清喝了多少咖啡,回家的次数也屈指可数。 + +记得有一次凌晨4点,Review完明天要上线的代码,我却不知道该做什么好,就这么静静地坐到天亮,动都不想动。窗外,是一成不变的灯红酒绿,屋内,却是一片漆黑。我看着屏幕上的那个自己,陌生、迷茫…… + + + +### 3. + +昨夜有个陌生的QQ号申请加我为好友,聊了半天才发现是当年的高一同学。高一时彼此就不怎么来往,高二分班时便断了联系,聊起毕业后的工作学习生活,竟然有些羡慕他。能够按照自己的兴趣研习化学、心理学,并已经硕博连读。而那个明明最喜欢化学的我,却在填写志愿的最后,毅然划去了第一行的基础化学,成为现在的码农。 + +后悔么?不后悔,只是还有些羡慕,羡慕同窗这种随性自主的选择。但无论与否,既然是当初自己选择的路,跪着也得走下去。我不是王小波,无法说出:“我是今古之人。我是阿基米德,我是米开朗基罗。我和眼前的一切都没有关系。”这么任性的话语,很多时候必须服从现实。人生很多时候充满着矛盾,不断获得,却又不断摆脱。有时以为下一刻波澜壮阔,却也就平平淡淡过了大半。有时以为平凡得不值一提,可一转角说不定又会遇上一个高中的伙伴,告诉你当初的你是他的榜样。 + +时间在走,年龄也在长。懂得的东西多了,看透的事情多了,快乐也就自然而然地越来越少了。我不得不承认,相比以前,时间真的改变了我很多很多。 + +以前的我,疯过、傻过、执着过、也坚持过。可到了最后,我还是我,最初的那个我。我承认我不好,但全世界也就只有一个我,独一无二的我!友情也好,爱情也罢。我若离去了,便后会无期。 + +现在的我,一切只求顺其自然。可你别说我不在意,就算我在意了又能如何呢?只因懂得了,自然就看开了。有些事,我们真别看清。看清了,反而心痛。更何况有些人,我们真别看懂。看懂了,反而伤情。 + +走过迷茫的8月,圆满地工作一周年。爱情也好,生活也罢,说出来的最后都是柴米油盐,写下的都是朴素的日常,平淡却也细密绵长。我抬头回想着过去的点滴,低下头看到张怡微写着[^1]:有时我也是自己的陌生人,同栖于亲爱的人生。 + +前方依旧是一团迷雾,也还好,在这漫漫的人生路上,有自己这么一个陌生人厮守相伴。 + +[^1]: 出自张怡微的《我自己的陌生人》 diff --git a/src/content/posts/2015/2015-12-08-rest-api-desgin.mdx b/src/content/posts/2015/2015-12-08-rest-api-desgin.mdx new file mode 100644 index 0000000..9568f3a --- /dev/null +++ b/src/content/posts/2015/2015-12-08-rest-api-desgin.mdx @@ -0,0 +1,306 @@ +--- +title: Rest API 的那些事儿 +slug: rest-api-design +date: 2015-12-08 14:30:45 +updated: 2020-09-10 06:26:16 +category: 编程 +cover: /images/2024/04/2024041520433700.jpg +summary: 在软件行业快速发展的今天,传统的软件授权已经不能足以满足一个IT类的公司的发展。虽然在大部分公司里,它还是现金池的直接源头。 +--- + + + +# 一、前言 + +在软件行业快速发展的今天,传统的软件授权已经不能足以满足一个 IT 类的公司的发展。虽然在大部分公司里,它还是现金池的直接源头。但是在可遇见的未来,受摩尔根理论的失效、物联网的发展等影响,应用的架构会越来越趋于简单化,架构越来越倾向于分布式水平扩展,对外的服务提供也会越来越 SaaS 化。在这种大背景下,很多公司都开始提供所谓的开放平台。 + +查阅各个大公司的开放平台,我们不难发现,都是 Rest API,都是 HTTP 请求,响应报文都是大同小异的 XML 或者是 JSON 等众多雷同的特点。这是为什么呢?让我们唠唠 API 平台的那些事。 + +# 二、定义 + +[查看历史][4],我们惊讶地发现,其实 Rest 的概念早在 2000 年就被人提出。用一句话描述它,就是**用固定的 URI 和可变的参数访问某个服务,来完成一系列业务请求。** + +1. 每一个 URI 代表一种资源; +2. 客户端和服务器之间,传递这种资源的某种表现层; +3. 客户端通过几个 HTTP 动词,对服务器端资源进行操作,实现“表现层状态转化”。 + +## 2.1 Rest API 格式 + +Rest API,无论它的名字多么高大上,它本质还是一个 HTTP 请求,POST 也好,GET 也罢,都是不同的数据提交方式。所以,能够决定一个 Rest API 的也就:URI、参数、请求方式、请求头等。 + +我们一般用 `URI` 来定义希望对外暴露的服务。结构基本类似 `schema://yourCompanyDomain/rest/{version}/{application}/{someService}`。`schema` 可以是 `http`,也可以是 `https`,`version` 指的是你这个API的版本,`application` 一般会指向底层的某个子系统,`someService` 就是这个子系统对外提供的服务。当然,如果按照业务为边界划分,也可将业务维度相同但隶属于底层不同的系统的服务定义为一个 `application`。 + +对于这种Rest请求,常见的响应结果就是XML或者是JSON形式,往往结果中会包含请求状态,和时间戳,业务系统响应结果。 + +具体的格式约定,可以看底部的参考文献。 + +### 2.1.1 API的版本概念 + +在 `URI` 的格式定义中,我们包含了version这个字段,这在早期,其实被认为是不优雅的方式。阮一峰有[一篇文章][4]就专门抨击这种设计,后面他又自己打脸说还是拼接version的好。_(不知道是不是因为Github的设计缘故)_ + +`API`设计时常会考虑版本这个概念,无论是在URI还是在请求参数里面,至少有一个地方得指明含版本,为什么呢? + +这很简单,就和系统迭代一样,API也是快速迭代开发的。也许初期,你的老大脑袋一热,我们要上API,于是你们就加班加点做,设定了一版请求协议。当时你们想,写完就能赚钱,必然带来一堆问题,比如说,代码难以维护,功能单一。后面这个`API`的第二版,你们要基于它去做一些新的变更,比如请求参数多了,返回内容多了,必然就有了第二版。但是又不能影响现有的业务。这个`API`基本的`URI`没变,但是会同时存在两个版本,老用户继续请求旧版,没问题,你无需动旧版?有需求的新用户,你要请求新版才能提供服务。这样通过版本来区分了不同的服务,便于以后的升级和维护。_(就像BAE那货可以毫无压力地废弃掉2.0的API)_ + +**所以一开始设计API时,就要定义好版本。其次,版本化可以骗钱。** 我们可以满怀恶意地猜测,1.0为了抢用户,免费。2.0老牛逼了,你用的爽了,想更爽,付费。233333333 + +## 2.2 架构特点 + +API平台的架构,其实和底层公司的业务系统架构有着密切的关系,基于一个好的系统架构写一个Rest API平台基本是水到渠成的。我们先从业务系统的架构变迁说起,再来分析上面的API平台。 + +### 2.2.1 业务系统架构变迁 + +基本的软件公司的业务系统,一开始都是`单机,单节点,单库`。慢慢随着业务量的增加。这个系统越来越复杂,机器性能越来越不能满足需求。于是,第一种可能,领导说,换机器。上一台牛逼机器。但是机器性能有限,越牛逼的机器价格越贵,有时候都能买3~5台现有配置机器。于是就有了方案二,三个臭皮匠赛过一个诸葛亮。`单应用,多机器,多节点`。 + +但是慢慢过了几年。你发现,这代码写的越来越屎,越来越复杂。基本上新来的开发要熟悉好几个月的业务。就代码因为快速上线。一堆坑,无法改。于是,大家现在都在做的事情,就是拆分。也就是现在常说的`SOA`。拆分,也有拆的好的,拆的不好的。不好的,就是一个大的恶心系统,变成了一堆恶心的小系统,互相调用,成一团乱码。小系统看似很好。但是某个不起眼的小系统。一挂,那么全部的系统都瘫了。这个时候这个万年不维护的小系统还找不到负责人,他么早就滚了。这就是拆分的技术欠债,你无法避免。 + +那么,就谈到拆分的架构设计。其实这块分两个架构,`技术架构和业务架构`。技术架构,就是要分清`技术系统和业务系统`。技术系统也可能是一个业务系统,但它一定是一个通用的服务组件。它提供的服务无任何定制需求,就是纯简单服务。比如,发短信发邮件发微信的通知系统,它就是通知。你业务有何特殊需求,就在上面自己实现一个XXX通知系统,那么业务系统的拆分,才是最关键的。就是要**`划清边界`**。 + +> 这个边界问题很可怕,什么你该做,什么你不该做。每个系统的职责都要明确。不要你也实现一个他也实现一个,然后相互调。**这种可怕性就是在两个服务都瘫痪的时候,完全都无法启用**。最后你的系统架构变成了一个通用技术组件系统,完成各个基础服务,每个产品线,业务端,基于你的技术系统包装出业务定制化服务系统,然后最上层就是业务子系统。业务子系统组合在一起,就是一个大的业务系统,也叫服务化平台。 + +**这个时候,你需要做开放平台。暴露一套Restful API,就是水到渠成了。** + +PS,实际的架构远比这个复杂,截图选自《大型网站系统与Java中间件实践》。 + +### 2.2.2 基于不同系统架构的 API 平台 + +**1、演变** + +初期的API平台往往是上图左侧那种,某个庞大的业务系统希望暴露一套API,于是大家就在这个系统上做,直接设计一套协议。但是,这样子带来的缺点十分明显,第一,它与业务联系太重,理想的API平台是通用的,不是只给你设计一个。第二,它不好扩展,每次变更都得和业务系统一同上线,糟糕的情况下代码还会影响原有正常的业务。第三,性能问题,理论上会降低原有应用的性能。 + +这种情况下,如果应用部署了多台机器,多个节点,我们就可以独立出来。也就是右边所示的API Gateway,它做的事情本质上就是反向代理,将外部的请求校验完合法性之后反代至内部实际想要对外暴露服务的服务集群上。 + +所以,这种场景下,API Gateway也就如名称所说,就是一个入口。实际的Rest API的东西还是建立在各个业务子系统上,只是只需要提供最简单的服务,无需考虑授权等东西。用户管理,API注册发布,调用统计等,均由API Gateway实现处理。对于想要快速上线的开发人员而言,实在是一个不错的福音。 + +然而,当系统应用拆分到了SOA化之后,API的架构由有了新的变革,我们有了注册中心的概念。因为SOA化,所以每个业务子系统其实都有了对外的统一接口,有了ESB(注册中心)。实际的内部系统间请求也有了较好的路由、熔断等策略。 + +在这种大背景下,API平台对外暴露的Rest API无需底层的业务专门开发了。直接使用现有的内部接口,选择性暴露即可。问题点就在于,如何根据定义的Rest API请求,实际模拟内部的RPC协议请求。 + +某种程度上,这时候的API平台,已经不仅仅是HTTP Rest请求了。我们完全可以实现相同RPC协议的透传,比如你就是一个Hessian接口想对外暴露,我只需包上一层认证,直接注册于API Gateway,外部Hessian请求直接透传至内部子系统。 + +在这个基础上的 Rest API 平台,才是灵活的,可扩展的,易于维护的。然而有得必有失,Mock请求必然会有性能上的损耗,但是这个架构的公司,已经不在乎钱了,上10台虚机,不够加呗。 + +**2、特点** + +1. C/S结构 +2. 无状态(API平台无需存储业务状态,只做认证和转发) +3. 有缓存,API会对指定URI的请求转发做缓存,保证并发性,业务系统也对同样的请求针对性缓存。 +4. 结构分层,每层间无法直接访问。 + +API平台的背后,就是庞大的各个业务子系统。每个API,就相当于一个业务子系统。API平台要做的事,就非常清晰和简单。就是业务子系统注册发布API,对外部请求校验计费,模拟请求内部业务子系统,对子系统结果包装序列化为`JSON`返回。 + +## 2.3 交互流程 + +上面是一个简单的交互,简单显示了外部系统和内部系统通过Rest API的交互过程:开发者(企业)注册,申请APP_KEY,开通API。按照开发接入,请求签名。转发至后端调用返回结果,API平台计费(预付费或者后收费),统计调用情况。 + +外部通信本质上还是`HTTP`,那么必然存在了授权问题,生产的API平台是直接暴露于公网的,如果认证授权策略出现纰漏,影响是可怕的。 + +比如,这个API是群发短信,你要是没有好的授权体系,允许人随意推送。某个人想搞你,调用发布反共信息,你整个公司都会跨。`HTTP`协议本质上没有这一块的内容,所以我们必然要在这上面考虑安全策略的内容。 + +### 2.3.1 如何保证Rest API的安全性 + +如果单纯考虑加解密,或者签名方式来保证请求合法,其实是远远不够的。事实上,一个安全的API平台往往需要多方面一起考虑,保证请求安全合法。 + +**1、是不是实际客户端的请求?** + +1. 设计专门的私有请求头:定义独有的Request headers,标明有此请求头的请求合法。 +2. 请求包含请求时间:定义时间,防止中间拦截篡改,只对指定超时范围内(如10秒)的请求予以响应。 +3. 请求URI是否合法:此URI是否在API平台注册?防止伪造URI攻击 +4. 请求是否包含不允许的参数定义:请求此版本的这个URI是否允许某些字段,防止注入工具。 +5. 部分竞争资源是否包含调用时版本(Etag):部分竞争资源,使用If-Match头提供。如用户资金账户查询API,可以返回此时的账户版本,修改扣款时附加版本号(类似乐观锁设计)。 + +**2、API平台是否允许你调用(访问控制)?** + +访问控制,主要是授权调用部分。API都对外暴露,但是某些公共API可以直接请求,某些,需要授权请求。本质的目的,都是为了验证发起用户合法,且对用户能标识统计计费。 + +以HMac Auth为例,我们简单设计一个签名算法。开发者注册时获取App Key、App Secret,然后申请部分API的访问权限,发起请求时: + +1. 所有请求参数按第一个字符升序排序(先字母后数字),如第一个相同,则看第二个,依次顺延。 +2. 按请求参数名及参数值相互连接组成一个字符串。param1=value1¶m2=value2...(其中包含App Key参数) +3. 将应用密钥分别添加到以上请求参数串的头部和尾部:secret + 请求参数字符串 + secret。 +4. 对该字符串进行 SHA1 运算,得到一个二进制数组。 +5. 将该二进制数组转换为十六进制的字符串,该字符串为此次请求的签名。 +6. 该签名值使用sign系统级参数一起和其它请求参数一起发送给API平台。 + +服务端先验证`是不是实际客户端的请求`,然后按照App Key查找对应App Secret,执行签名算法,比较签名是否一致。签名一致后查看此App Key对应的用户是否有访问此API的权限,有则放行。 + +执行成功后包装返回指定格式的结果,进行统计计费。 + +# 三、需求与实现 + +## 3.1 需求 + +### 3.1.1 系统需求 + +1. 支持rest类API接口动态发布及运营,包括但不限于: + - 安全认证 + - 会话管理 + - 流量统计及限流 + - 计费收费 + - 熔断 +2. 支持现有子系统RPC协议的API动态发布及运营,外部请求透传。 +3. 支持json、xml响应报文,可以请求时选取所需报文格式。 +4. 支持动态直接将后端SOA服务暴露为API。 +5. 支持动态将普通Web接口暴露为API。 +6. 支持动态将MQ服务暴露为API。 +7. 支持多个服务组合编排后暴露为API。 + +### 3.1.2 业务需求 + +**1、API管理** + +所有API可后台查询管理,包括动态发布、参数映射配置、后端服务接口配置、API禁用、启用,多版本、分组、分级别等。 + +**2、应用管理** + +后台管理开放平台接入的应用(第三方应用),包括查询、禁用、启用、审核。 + +**3、API鉴权&授权** + +1. 应用申请审核通过后生成公钥,开放平台需提供支持分布式系统的密钥管理 +2. 服务可设置为两个安全等级:需授权访问和无需授权访问(后者即任意客户端都可以发起调用),默认所有API都需授权访问。 +3. 非正常状态(禁用、停用、黑名单等)的应用直接抛异常不允许访问——**熔断机制** + - 调用次数、调用频率、并发数可运行时控制,避免某请求量过大影响其他应用的调用。 + - 可对某个应用某个API设置强制熔断,所有请求无视阀值直接抛出异常。 +4. 易用性 + - 与SOA集成,SOA服务一键发布到API平台。 + - 支持后台动态发布API,而不是新上一个API就需上线一次。 + +**4、计费统计** + +1. API的调用统计,每笔请求时间,响应时间,响应状态。 +2. API的计费计算,按照请求量和请求资源计费,实现多种计费模型。(预付费,后收费。按量,按时间周期。) + +**5、开发者平台** + +1. API开发者平台,开发者注册、访问、申请API授权、计费统计、调用统计。 +2. API文档系统,详细的API文档展示,SDK下载,用户登录后还可专门生成不同编程语言请求,在线模拟请求结果等。 + +### 3.1.2 角色定义 + +**1、外部用户** + +<table> + <thead> + <tr> + <th>用户</th> + <th>做什么</th> + <th>使用目的</th> + </tr> + </thead> + <tbody> + <tr> + <td>API平台接入方</td> + <td>接入API平台</td> + <td>使用XXXX提供的开放平台服务</td> + </tr> + </tbody> +</table> + +**2、各个业务产品线** + +<table> + <thead> + <tr> + <th>用户</th> + <th>做什么</th> + <th>使用目的</th> + </tr> + </thead> + <tbody> + <tr> + <td>各个业务产品线</td> + <td>作为外部应用接入API平台</td> + <td>使用XXXX提供的开放平台服务</td> + </tr> + <tr> + <td>各个业务产品线</td> + <td>提供服务</td> + <td>提供后端服务,发布到API平台供外部应用接入</td> + </tr> + <tr> + <td>公司后端应用</td> + <td>提供服务</td> + <td>提供后端服务,发布到API平台供外部应用接入</td> + </tr> + <tr> + <td>API平台</td> + <td>API治理</td> + <td>运营,管理API、第三方应用等</td> + </tr> + </tbody> +</table> + +## 3.2 请求模型 + +API 的所有服务请求域名是相同的,区别在于Request Path等。请求参数分为系统级参数和业务级参数两部分,系统级参数是所有 API 都拥有的参数,而业务级参数由具体服务 API 定义。 + +### 3.2.1 统一服务 URL + +建立API Gateway接受所有请求,按照Request Path,Request Method,Request Head分发所有的请求。 + +**1、 通用统一URL** + +**格式**:`schema://<api Gateway URI>/DispatcherServlet?method=XXService.xxMethod?xxxObj.xxxParam=xxxValue。` + +**说明**:所有请求直接走`DispatcherServlet`分发,所有内容均定义于URL参数中。`method`为后端某个子系统的某个方法。`xxxObj.xxxParam`为方法参数实体的某个属性的值定义。 + +**示例**: +`http://api.xxxxx.com/router?method=SMSService.sendSMS&user.phoneNumber=18888888888&sign=ds234324sdsad&date=20151229231232` + +**2、Rest类型URL** + +**格式**:`schema://</api><api Gateway URI>/rest/{version}/{service}/{method}/{params}` + +**说明**:请求按照Gateway定义的Rest地址匹配,动态映射至具体系统具体方法,模拟调用。请求中包含`version`字段。 + +**示例**: +`http://api.xxxx.com/rest/v1/XXService/xxMethod/{xxParam}` +`http://api.xxxx.com/rest/v1/XXService/xxMethod?xxxParam=xxxValue` + +### 3.2.2 参数设计 + +**1、系统级参数** + +系统级参数是由 API 平台定义的一组参数,每个服务都拥有这些参数,用以传送框架级的参数信息。如我们前面提到的 method 就是一个系统级参数,使用该参数指定服务的名称。 + +**2、业务级参数** + +业务级参数,顾名思义是由业务逻辑需要自行定义的,每个服务 API 都可以定义若干个自己的业务级参数。API Getaway 根据参数名和请求属性名相等的契约,将业务级参数具体的方法请求对象中。 + +## 3.3 常见框架 + +1. Kong:[https://github.com/Mashape/kong](https://github.com/Mashape/kong) +2. Zuul:[https://github.com/Netflix/zuul](https://github.com/Netflix/zuul) +3. ROP:[https://github.com/itstamen/rop](https://github.com/itstamen/rop) +4. Resty: [https://github.com/Dreampie/Resty](https://github.com/Dreampie/Resty) + +# 四、优劣 + +## 4.1 好处 + +1. **跨平台**,管你是`Java`,还是`PHP`,还是`Node.js`还是`Go`,你丫都得支持`HTTP`请求。我`API`平台只需要提供这个语言的`SDK`,保证能按照消息协议调用就好。 + +2. **将复杂的内部业务系统抽象为通用调用请求**。包装了复杂的业务逻辑,对外提供统一的,好管理的接口。并可以定制化设计,计费,授权一类的容易管理。 + +## 4.2 坏处 + +1. **协议描述能力弱化**,`Restful`的`URI`无法完全对请求参数做强格式校验。最后的方法参数绑定,模拟内部请求时往往容易出问题,尤其是以Java等强格式语言的系统。不能像`WebService`一样清晰描述请求报文。 + +2. 同样的道理,响应结果为了是`JSON`、`XML`。这当中,编码,正反序列化,等操作,往往就会有性能瓶颈。而且,Java在这块资源消耗极大。以Github的`ROP`这个框架为例,当年测试时,它在并发请求过高的时候就会有一个内存泄漏问题。 + +--- + +# 附:参考资料 + +1. [REST Is Not About APIs, Part 1][1] +2. [REST Is Not About APIs, Part 2][2] +3. [RESTful API 设计指南][3] +4. [理解RESTful架构][4] +5. [撰写合格的REST API][5] + +[1]: https://nirmata.com/2013/10/01/rest-apis-part-1/ +[2]: https://nirmata.com/2013/11/12/rest-apis-part-2/ +[3]: https://www.ruanyifeng.com/blog/2014/05/restful_api.html +[4]: https://www.ruanyifeng.com/blog/2011/09/restful.html +[5]: https://kb.cnblogs.com/page/521718/ diff --git a/src/content/posts/2016/2016-02-04-dumplings-in-winter-solstice.mdx b/src/content/posts/2016/2016-02-04-dumplings-in-winter-solstice.mdx new file mode 100644 index 0000000..1ff23df --- /dev/null +++ b/src/content/posts/2016/2016-02-04-dumplings-in-winter-solstice.mdx @@ -0,0 +1,55 @@ +--- +title: 冬至的水饺 +slug: dumplings-in-winter-solstice +date: 2016-02-04 06:55:33 +updated: 2020-09-04 21:05:07 +tags: + - 饮食 +category: 文章 +cover: /images/2020/09/2020090420592363.jpg +summary: 昨天冬至,大家都吃水饺了么?事实上,当我昨晚下班兴匆匆地打电话给老家的爸妈时,他们是茫然的。 +--- + + + +昨天冬至,大家都吃水饺了么? + +事实上,当我昨晚下班兴匆匆地打电话给老家的爸妈时,他们是茫然的。 + +> “什么,吃水饺?儿呀,咱这没这习俗呀?” +> “(°ω°〃)なに,老妈,我见识少,你可别骗我。” + +上面当然是玩笑话,事实上,作为一个通吃南北的人,我可以拍着胸脯告诉你,冬至吃什么在全国各地的习俗还真的是不大一样。 + +高中毕业前,我在厦门住了整整10年。厦门这边的饮食习惯外地人可能第一时间都无法接受,因为地域问题,偏清淡,偏海鲜,腥甜。尤其是我这个土生土长的安徽人,窝在山沟沟里12年。去了厦门之后,硬生生地从原来130斤的小胖子瘦成110斤的小小胖子,你就知道我是多么不习惯厦门的饮食口味了。海蛎煎、蛤蜊汤,这些从外观看就像是“黑暗料理”的食物给我带来的阴影,至今都挥之不去。——(泥垢了,pia) + +安徽菜,或者说,徽菜、皖菜,最大的特色就是重油,喜爆炒。在“某鱼”的 1:1:1 还没有安利到人人皆知的时候,我吃的有两种油——猪油、菜籽油。菜籽油是生油,直接从油菜籽压榨出来的,所以杂质很多,不能立刻食用。需要将下锅油烧热,配合菜炒一下才能吃。因为菜籽油的沸点比较高,所以小时候,老爸老妈三班倒,自己一个人炒菜的时候,蔬菜都是丢锅后立刻盖上锅盖,怕溅了一身。而猪油,则是取猪身上的脂肪和肥肉,切成块,然后热锅慢慢炼制,剩下的油渣子还可做菜、包水饺、煮汤。冬天的时候,老妈去上班,我和老爸又懒得买菜做饭,就会拿大米锅巴,掰碎,然后加上猪油和盐,开水泡着吃。 + +菜籽油和猪油的味道,都是极其香的,在九几年那个物质还不是很丰富的年代,它们陪伴了我整个童年。后面生活条件好了,大家都整细粮精食,这种油也就慢慢吃的少了。今年冬至在北京吃煎饺,第一口我就觉得是菜籽油煎的,向老板一打听,果然猜中了。那个时候店里的收音机放着歌曲《九月九的酒》,茫然间真有一种回到家的错乱感。 + +正如开头说的那样,冬至在我们那个破地,是没什么特殊习俗的,能吃饱饭就不错了。后面到了厦门,冬至那天陪母上逛沃尔玛,就觉得奇怪,整个超市都在买汤圆。一打听,今天冬至,按照当地的习俗要吃汤圆。也就从那天起,我家也加入了冬至汤圆大军。 + +高中毕业后到济南读大学,才发现:嘿,原来不是每个地方冬天都吃汤圆,竟然还有的地方要吃水饺。山东菜,或者说鲁菜,我对它可是又爱又恨。一来鲁菜的口味喜干煸和炖炒,口味不是那么清淡。二来,地三鲜一类的菜品挺对我胃口的。但是,我要说但是,为毛所有的鲁菜都喜欢先拿大葱和油混合炒一下,美其名曰——炝锅。要知道,我生平最不喜欢两种蔬菜,大蒜,大葱。 + +后来待久了,也慢慢习惯了大葱和大蒜的味道。冬天和基友出去溜达喝羊汤时,也会习惯性地说:老板,给我来碗羊杂汤,两个饼。对了,再给我来头蒜。 (・`ω´・) + +而其实,要说这南北的饮食的差异,除了冬至的饮食习惯,还有很多很多。比如主食,我在安徽时喜食米饭。到了厦门,发现这里人喜欢吃地瓜粉,尤其是我那前前前女朋友,竟然满眼星星地对我说:“地瓜粉好好吃哦”(请配上地瓜腔想象)。到了济南,发现这里的人可不得了,喜欢就着生大葱大蒜吃馒头包子。有一次,我也想体验一下,就按照厦门的饭量买了三个馒头。(厦门这馒头是细面的,酵母比较多,比较松软,实际没多少量。)第一口下去我就惊呆了,这馒头真实在,板实板实的,硬把我噎得连喝两大口水。后面连吃带塞也就吃了一个半,妾身吃不下去啊。 + +上周在《大象公会》上看到这么一篇文章,说兰州拉面的起源和各地兰州拉面的口味不同,兰州拉面在各地都做了改变,使得它更加贴近当地人的口味。这点我感受过,自然十分赞同。而其实,福建名小吃《沙县小吃》也是一样。 + +才到北京的时候,蛮不喜欢这边的餐饮风格的,比如说早上的地沟油鸡蛋灌饼怎么那么贵,为什么每顿都会有腌制的咸菜,为何路边的烧烤总是那么多人?后面找到了公司旁边的沙县小吃,我是相当激动啊,可算是找到老乡了。进门,瞅着前台如花似的收银美眉说:“我要一碗扁食,加一个猪心汤。” + +> “什么,扁食,扁食是什么呀,我们这里不卖。猪心汤这里没多少人喝,我们早不做了。” +> “(;´༎ຶД༎ຶ )扁食就是扁食啊,福建那不都叫扁食,北方叫做馄饨,重庆那叫抄手么?” +> “哦,你说馄饨是吧,说馄饨不就好了,我还以为你说啥呢。来,二位里面请。” +> “……” + +后面要了一个老鸭汤饭,菜上来的时候,我又崩溃了,为何饭里面出现了厦门沙县小吃没有的北京特色——榨菜。 + +看书上说:原先物质年代不发达,人员不流动的时候,大家自然是有啥吃啥,南北的饮食差异自然比较大。这几年改革开发,经济好了,我们也慢慢感觉到南北差异越来越小,大家是有钱喜欢啥吃啥。 + +事实上正如俗话说的那样,民以食为天,吃这个话题在中国永远是一个热点话题。无论是见面时的“你吃了么?”,还是如《舌尖上的中国》那样津津乐道的私家菜品。 + +无论如何,最后还是问一句。“冬至那天你吃水饺/馄饨了么?” + + diff --git a/src/content/posts/2016/2016-02-04-oauth-on-kong.mdx b/src/content/posts/2016/2016-02-04-oauth-on-kong.mdx new file mode 100644 index 0000000..5372117 --- /dev/null +++ b/src/content/posts/2016/2016-02-04-oauth-on-kong.mdx @@ -0,0 +1,228 @@ +--- +title: 基于 Kong 的 OAuth2.0 的使用 +slug: oauth-on-kong +date: 2016-02-04 09:21:00 +updated: 2020-09-04 20:29:36 +tags: + - Kong +category: 编程 +cover: /images/2020/09/2020090420223787.jpg +summary: 一个完整的 OAuth 2.0 认证需要好几步,然而,Kong只完成最后几步,实际使用时需要开发上层的服务。 +--- + + + +## 1. Kong OAuth 2.0 认证流程 + +### 1.1 相关角色 + +1. **第三方应用:** 实际想要访问API的应用,需要在Kong上注册,定义自己的访问口令和回调地址。 +2. **用户:** 实际的第三方应用的使用者,和API访问权限的授权主体。 +3. **认证服务:** 基于Kong搭建的认证服务,主要完成用户信息的部分,也就是登录和授权提示页面。它作为第三方应用和Kong之间的中间桥梁,因为Kong不直接接管这些信息。 +4. **Kong:** Api Gateway,完整API的认证和应用注册等,将请求向后端转发。 +5. **API 提供者:** 实际的API提供者,与Kong交互,外部无法直接访问。 + +### 1.2 认证流程 + +1. Client为第三方应用,当它想访问某些需要用户授权的用户信息。 +2. Client将用户跳转至 Kong 上的认证服务来认证应用。 +3. 如果认证服务发现用户未登录,那么将会跳转至登录界面。 +4. 在登录界面完成登录,将会跳转至认证服务的授权页面,显示第三方应用想要获取的用户信息,用户可以确定是否允许第三方应用访问。 +5. 用户确认,认证服务提交信息至Kong上完成注册认证流程,Kong返回认证口令和跳转地址给认证服务。 +6. 认证服务将用户跳转至 第三方应用 在 Kong 上定义的回调地址,传递认证口令。 +7. 第三方应用从回调地址读取认证口令,请求Kong,获取实际的信息访问口令。 +8. 应用通过每次请求传递附加上访问口令来调用API。 + +## 2. Kong OAuth 2.0 问题,开发需求 + +一个完整的 OAuth 2.0 认证需要好几步,然而,Kong只完成最后几步,实际使用时需要开发上层的服务。 + +用户登录模块用户系统已经实现,登录方式为使用SDK传入Session ID获取用户登录信息,并不是很优雅。但是结合已有的登录服务,只需写一个登录界面,授权确认界面和与相关的交互服务。 + +## 3. 交互信息,协议,格式 + +### 3.1. 协议定义 + +(1)、新增 API + +```bash +# 请求 +$ curl -X POST http://127.0.0.1:8001/apis --data "name=httpbin" \ +--data "upstream_url=https://httpbin.org" \ +--data "request_host=yufan.me" \ +--data "preserve_host=true" +``` + +```json +// 响应 +{ + "upstream_url": "https://httpbin.org", + "id": "b00e2c79-a87a-4688-b16f-7b2034171b13", + "created_at": 1456299654000, + "preserve_host": true, + "name": "httpbin", + "request_host": "yufan.me" +} +``` + +(2)、API 配置 oAuth 认证 + +```bash +$ curl -X POST http://127.0.0.1:8001/apis/b00e2c79-a87a-4688-b16f-7b2034171b13/plugins \ +--data "name=oauth2" \ +--data "config.scopes=email,phone,address" \ +--data "config.mandatory_scope=true" +``` + +```json +{ + "api_id": "b00e2c79-a87a-4688-b16f-7b2034171b13", + "id": "a21450ac-4aa6-459e-9678-21275fc15d6f", + "created_at": 1456299868000, + "enabled": true, + "name": "oauth2", + "config": { + "mandatory_scope": true, + "token_expiration": 7200, + "enable_implicit_grant": false, + "scopes": ["email", "phone", "address"], + "hide_credentials": false, + "enable_password_grant": false, + "accept_http_if_already_terminated": false, + "provision_key": "a36c23485d414ffb9eba7a85de0e7335", + "enable_client_credentials": false, + "enable_authorization_code": true + } +} +``` + +(3)、添加开发者帐号 + +```bash +$ curl -X POST http://127.0.0.1:8001/consumers \ +--data "username=testuser123" \ +--data "custom_id=12345" +``` + +```json +{ + "custom_id": "12345", + "username": "testuser123", + "created_at": 1456299997000, + "id": "364381e9-acf7-424d-a87f-f4be80871ee2" +} +``` + +(4)、添加应用 + +```bash +curl -X POST http://127.0.0.1:8001/consumers/364381e9-acf7-424d-a87f-f4be80871ee2/oauth2 \ +--data "name=My%20Test%20Application" \ +--data "redirect_uri=https://httpbin.org/get" +``` + +```json +{ + "consumer_id": "364381e9-acf7-424d-a87f-f4be80871ee2", + "client_id": "54b968c73da64b328ed92b05548179b6", + "id": "ce2906cb-3442-44c1-888e-848bafd0a442", + "name": "My Test Application", + "created_at": 1456300207000, + "redirect_uri": "https://httpbin.org/get", + "client_secret": "3b4537ac7c94492f81b251110e2d0f33" +} +``` + +(5)、模拟用户授权,获取回调码 + +```bash +$ curl -X POST https://127.0.0.1:8443/oauth2/authorize \ +-H "Host: yufan.me" \ +--data "client_id=54b968c73da64b328ed92b05548179b6" \ +--data "response_type=code" \ +--data "scope=email" \ +--data "authenticated_userid=yufan" \ +--data "provision_key=a36c23485d414ffb9eba7a85de0e7335" \ +--insecure +``` + +```json +{ "redirect_uri": "https://httpbin.org/get?code=f2987a670ab246a38b2a3e6d58713019" } +``` + +(6)、获取两码,完成初次认证 + +```bash +$ curl -X POST https://127.0.0.1:8443/oauth2/token \ +-H "Host: yufan.me" \ +--data "client_id=54b968c73da64b328ed92b05548179b6" \ +--data "client_secret=3b4537ac7c94492f81b251110e2d0f33" \ +--data "grant_type=authorization_code" \ +--data "code=f2987a670ab246a38b2a3e6d58713019" \ +--insecure +``` + +```json +{ + "refresh_token": "a42472728fd74075ac8db82a0cb50b44", + "token_type": "bearer", + "access_token": "c28b23745aa84c14a001a32476be3d6c", + "expires_in": 7200 +} +``` + +(7)、API 请求 + +```bash +$ curl -X POST https://127.0.0.1:8443/post \ +-H "Host: yufan.me" \ +--data "access_token=c28b23745aa84c14a001a32476be3d6c" \ +--insecure +``` + +```json +{ + "args": {}, + "data": "", + "files": {}, + "form": { + "access_token": "c28b23745aa84c14a001a32476be3d6c" + }, + "headers": { + "Accept": "*/*", + "Content-Length": "45", + "Content-Type": "application/x-www-form-urlencoded", + "Host": "yufan.me", + "User-Agent": "curl/7.43.0", + "X-Authenticated-Scope": "email", + "X-Authenticated-Userid": "yufan", + "X-Consumer-Custom-Id": "12345", + "X-Consumer-Id": "364381e9-acf7-424d-a87f-f4be80871ee2", + "X-Consumer-Username": "testuser123" + }, + "json": null, + "origin": "127.0.0.1, 61.148.202.186", + "url": "https://yufan.me/post" +} +``` + +(8)、API Token 刷新 + +```bash +$ curl -X POST https://127.0.0.1:8443/oauth2/token \ +-H "Host: yufan.me" \ +--data "refresh_token=a42472728fd74075ac8db82a0cb50b44" \ +--data "client_id=54b968c73da64b328ed92b05548179b6" \ +--data "client_secret=3b4537ac7c94492f81b251110e2d0f33" \ +--data "grant_type=refresh_token" \ +--insecure +``` + +```json +{ + "refresh_token": "de64c9df218b4a0eb2a24af83cd93a56", + "token_type": "bearer", + "access_token": "98ff79467dd6450f95061da94bd81d02", + "expires_in": 7200 +} +``` diff --git a/src/content/posts/2016/2016-03-24-work-summary.mdx b/src/content/posts/2016/2016-03-24-work-summary.mdx new file mode 100644 index 0000000..1501c33 --- /dev/null +++ b/src/content/posts/2016/2016-03-24-work-summary.mdx @@ -0,0 +1,43 @@ +--- +title: 工作心得总结 +slug: work-summary +date: 2016-03-24 05:25:42 +updated: 2020-09-04 20:20:03 +tags: + - 工作 +category: 编程 +cover: /images/2020/09/2020090420111684.jpg +summary: 去任何一家公司都会遇到很多新鲜的知识,很多新鲜的内容,所以日常的学习过程中需要及时总结笔记,作为备忘。每个人都不可能纯凭记忆记住很多东西,所以日常的学习中,需要及时总结,也方便未来的梳理。 +--- + + + +## 注意总结与反馈 + +去任何一家公司都会遇到很多新鲜的知识,很多新鲜的内容,所以日常的学习过程中需要及时总结笔记,作为备忘。每个人都不可能纯凭记忆记住很多东西,所以日常的学习中,需要及时总结,也方便未来的梳理。 + +所谓的反馈,也就是展示自我,你要清楚的让上级知道你现在在做什么,会什么,有什么能力。也就是说,主动展示自我,主动秀出自己。通过这个,一来证明自己的能力,不是在那边混日子。二来也是一种资源的获取,上级懂的永远比你多,通过这种方式,可以要求到更多的学习资源。 + +## 不断学习进步 + +对于一个开发人员而言,你需要不断学习,因为这个世界上有着太多的牛人和技术。很多时候,你都会有瓶颈(自己的舒适区)。的确,现有的知识和能力足矣满足你的工作需求和未来的开发。 + +所以,要时刻惊醒,多去主动学习。 + +## 问题处理与解决 + +解决一个问题时,首先把上下文弄清楚。 + +对于负责解决问题的人要做到: + +1. 明确问题提出的人是谁 +2. 确定问题描述清楚没有 +3. 及时将解决进度告诉大家 + +如果问题解决了,要通过更新`Jira`或者在相关讨论组讨论的方式,告诉大家问题原因、解决办法、遗留问题。如果问题解决不了,或者提问者说OK了,一定要追问发生了什么,或者是如何解决的。 + +整个问题的生命周期都要与大家分享出来,不能不明不白的就关闭一个issue。 + +提问者需要及时追踪问题进度。同时,我认为:无论是任何原因,只要一个issue被长时间搁置,那么这个问题优先级一定不高。 + + diff --git a/src/content/posts/2016/2016-04-04-just-try.mdx b/src/content/posts/2016/2016-04-04-just-try.mdx new file mode 100644 index 0000000..e38e123 --- /dev/null +++ b/src/content/posts/2016/2016-04-04-just-try.mdx @@ -0,0 +1,63 @@ +--- +title: 不要总是走在准备的路上 +slug: just-try +date: 2016-04-04 12:45:43 +updated: 2020-09-04 19:54:37 +tags: + - 随笔 +category: 编程 +cover: /images/2020/09/2020090419532852.jpg +summary: 上周和一个即将毕业的大学生聊天,他很厉害,学了很多,抱怨到很多人学了很多编程语言,但最后都只是会写一个“Hello World”的程度。 +--- + + + +上周和一个即将毕业的大学生聊天,他很厉害,学了很多,抱怨到很多人学了很多编程语言,但最后都只是会写一个“Hello World”<sup>〔1〕</sup>的程度。我说,因为他们大多是一直在准备学习,往往刚开始学的时候,便放弃了。 + +<p style={{ textAlign: 'right' }}>——题记</p> + +我叫雨帆,所有的汉字中我觉得我“雨”、“帆”这两个字写的最好看,不是因为我字写的好,而是因为我专门针对这两个字专门练习。 + +同样的话语可以套在很多东西上,许多东西,比如人的技能,擅长的东西,并不是一蹴而就的,需要频繁的练习。没有谁能一开始就能成长为参天大树,即使是所谓的天才,在你看不见的背后,也有着常人难以想象的汗水与努力。 + +所以一直一来,我很赞同一句话:[信念永远不能达到目的地](/posts/intimate-in-mind/)。每个人都有自己的梦想,但是如果只是梦想,却不去付诸行动,那么它也仅仅是梦。 + +记得三年前有一个叫做[谢钦](/posts/meeting/)的网友邮件问了我很多关于独立博客的话题,当时的感觉就是在茫茫大海中看到一束光的感觉。就是一直以来,你一直以为只有自己一个人在做什么事情,周围没有一个人懂你的时候,突然有一个人理解你的感觉。 + +然而过了三年,他的博客还是一句话:“未命名博客更新中”…… + +当然,我不是刻意黑这位朋友,更多的是想表达一种遗憾。因为写一个独立博客的准备工作真的很麻烦很麻烦,如果像我一样在国内的话还要备案一类的繁琐程序。如果不是喜欢写博客,真的一开始就会想放弃。那么为何都准备好了,最后关键的写文章一步却放弃了呢? + +--- + +写代码的时候老大总教育我们一句话,不要过度设计。什么叫做过度设计呢?就是和业务无关的东西写了一堆一堆,但是关键的业务的代码却写的很少。 + +说这个前,不得不提知乎上之前一个很流行的问题:[为什么有些大公司技术弱爆了?](https://www.zhihu.com/question/32039226/answer/76059969)当时看到的时候就想起前老大的一句话,“满足业务需求的代码就是好代码”。 + +对于很多还未毕业的计算机专业学生可能会觉得不可思议,尤其是看到很多外表看似光鲜的项目,底层竟然是如此垃圾的代码。甚至某些方式(如数据库的设计),完全是教科书般的错误案例。而实际上,它们只做好了一件事,满足业务需求,然而,因为做好了这件事情,它至少可以给公司带来收益。 + +当然,我并不是为了给烂代码洗地,对于互联网公司而言,快速的上线和迭代开发才是保证收入的根本。如果是使用智能机的你,尤其是Android手机的话,可能最大的感受就是那些APP,基本上一周恨不得更新个十几次。为何不能从一开始就是设计好呢? + +从产品的角度而言,需求是不断变化的。比如输入法,一开始,人们的需求就是能打字的时候少一些选择,于是有了词库,包含常见词。后面有了按照词频不同的动态候选词序,再后来,由于互联网聊天的流行也许有了所谓的Emoji、字符画等特定需求等……但是一开始就想做好这些,是不可能的。比如你潜心花上几个月甚至几年打磨一个输入法,往往还没开发出来,要么是市场被人抢走了,要么是你自己耗死了。 + +话题扯的有点偏,换句话说,很多东西,不可能一开始就做的很好,如果不去做,而是一直在想怎么写好,怎么做才好,那是永远做不出来东西的。你只有上手做了,比如,先写个demo,然后完成一个主流程,再一点点考虑里面的问题细节。如果一开始就想做好,要么是你很累,想要放弃;要么是团队不会给你太多时间。 + +--- + +记得上周参加Openresty Meetup的时候和一个架构师聊天,聊架构。在他看来,架构的存在是在公司的业务数量级达到一定的规模之后的必然产物。然而,对于一个初创公司而言,往往却是可有可无的产物。因为你的业务数量级没有到这个级别,套用**安迪比尔定理**,这个时候的业务量,无需多好的架构设计,关键是满足主要业务需求就好。按照业内常见的标准,只有业务量上升到百万这个级别,你才需要考虑架构,考虑设计。 + +当然这也许有点偏激,在此我保留意见,回到前面说写代码这事上。我觉得,这事应该是这么一个顺序:`能写出代码` => `能写出满足业务需求的代码` => `能够按照业务需求优化代码` => `能够考虑未来可能的需求变更预留扩展的接口` => `能将唯一可变行为剥离接口参数化` => `能在现有的语言发展层面上进行演进` => `能不再为设计模式而设计模式` => `开始理解熟记 Clean Code 的全部准则` => `拥抱 TDD,不断重构测试驱动` + +当然,换种说法也许就是:不要为了设计模式而设计模式,不要提前优化,不要过度封装,不要过于追求最新的技术。 + +看一些牛逼的老程序员写代码就非常有意思,你会发现,他们写出来的代码,往往都十分小而简,恰当的地方使用一些让你眼前一亮的设计。当时我在写公司的开放平台,写的很累很累,花了半个多月,进展基本还是起步阶段。当时和带我的人聊天,他的一句话点醒了我:“理解需求,构建抽象实体,打通主流程”。如果我总是在想要用什么,要怎么写,也许我到今天什么都写不出来。 + +很多人都有完美主义倾向,什么东西,一定要做好,做棒。为此付出大量时间做准备。等到开始做的时候,才发现,后面的人已经超过了自己…… + +当然,做好一件事,离不开准备。但是,只准备,不去做,那么永远做不好。我的话说完了。 + +--- + +[1]、Hello World,基本上任何编程语言的教科书,一开始都是教大家如何写一个Hello World,久而久之成为一个梗。 + + diff --git a/src/content/posts/2016/2016-04-30-forget-past.mdx b/src/content/posts/2016/2016-04-30-forget-past.mdx new file mode 100644 index 0000000..b46d2cb --- /dev/null +++ b/src/content/posts/2016/2016-04-30-forget-past.mdx @@ -0,0 +1,46 @@ +--- +title: 忘记时间 +slug: forget-past +date: 2016-04-30 12:09:53 +updated: 2020-09-06 19:12:27 +tags: + - 回忆 +category: 杂思 +cover: /images/2020/09/2020090419362643.jpg +summary: 最近一次登录快盘,忽然发现登录界面上出现了6月30日后关闭的字样。不知道你的家乡是否也有这样的店,天天喊着最后三天歇业,总是副破落不堪即将被扫地出门的模样。 +--- + + + +最近一次登录快盘,忽然发现登录界面上出现了6月30日后关闭的字样。 + +不知道你的家乡是否也有这样的店,天天喊着最后三天歇业,总是副破落不堪即将被扫地出门的模样。但总是三天又三天,打折又打包,撑了至少一年半载。我不知道快盘是否属于这一种,但如果是这一种,也许是好的。就像那个万年不更新的[饭否](http://fanfou.com),破落归破落,但还是存个念想的地方。就像儿时的秘密基地,越是蜘蛛网,越是灰尘漫天,越是秘密,越是勾人。 + +我想,那些存在网盘上的数据终究会被我遗忘的吧,但并不要紧。 + +反正我已有太多的无所谓,它们像磨豆汁一样粗砺地被放进时间里。我不知道什么时候快盘滚落到如此的下场,但现如今却有一种被摊平的感受,和别的说不出的味道交融在一起。 + +对于过去,我不开放心扉,也不愿开动大脑,我只需要Hey Siri,wake me up at 8:30,明天自然会醒来。 + +--- + +每次登陆博客的时候,都不知道该写点什么好。也许是我太久没有写了,我好像无法展开,也无法收敛。无处与人去说,也无处想与人倾诉。于是我想告诉别人的只是最后的结果。比如: + +- 我吃过饭了 +- 我睡过觉了 +- 我爱过人了 +- 我受过伤了 +- 我绝过望了 +- 我说过话了 + +这样说完的时候,我可以省去所有故事和梗概,本来我就是个不会说话的人,也不愿意抓着被人掏出来,所以这样就好。简单明了,你知道了想知道的八卦,我也不用再次回忆想不起来的过去。 + +我相信未来看到这篇文章的人,都已长大,会买菜会做饭会炒股票不会轻易死去。时间是轻微的,浮浮地飘在城市角落,被眼泪打入地面,又随着别人的眼光重新着落。乘风飘去的灰尘让人艳羡,然而充满逼格的话语始终是在城里回荡,这些话语与这些灰尘一样,生而不自由却也忘记了初始的人设。 + +忘记了也好! + +只是我不甘心,我仿佛能听到时间在我身上咔嚓咔嚓的作响,怎么能不感觉到后怕? + +希望随时随地都可以再见那些过去。 + + diff --git a/src/content/posts/2016/2016-05-06-introduction-to-webpack-part-1.mdx b/src/content/posts/2016/2016-05-06-introduction-to-webpack-part-1.mdx new file mode 100644 index 0000000..ec2554a --- /dev/null +++ b/src/content/posts/2016/2016-05-06-introduction-to-webpack-part-1.mdx @@ -0,0 +1,192 @@ +--- +title: Webpack 介绍:第一部分 +slug: introduction-to-webpack-part-1 +date: 2016-05-05 18:15:29 +updated: 2020-09-04 19:31:49 +tags: + - 前端 +category: 编程 +cover: /images/2020/09/2020090419260539.png +summary: Webpack 是近段时间非常流行的前端流程处理工具,用于实时执行构建任务和预处理你的文件。 +--- + + + +Webpack 是近段时间非常流行的前端流程处理工具,用于实时执行构建任务和预处理你的文件。 + +你也许会使用 [Grunt](http://gruntjs.com/) 或者 [Gulp](http://gulpjs.com/) 来做类似的事情。首先建立一个编译链,然后在上面定义从何处读取代码,将压缩处理好的 CSS 和 JavaScript 等静态资源输出到什么地方。 + +这些工具都非常流行和好用,然而我却要向你安利另一种实现此类需求的方法,那就是使用 [Webpack](https://webpack.github.io/)。_新技能Get!_ + +## 什么是 Webpack? + + + +Webpack 常被人们定义为“模块打包工具”(module bundler),它读取 JavaScript 模块,分析它们之间的依赖关系,然后用尽可能高效的方式将它们组织在一起,最后生成一个独立的 JS 文件。似乎看起来并没有什么牛逼的技术,像 [RequireJS](http://requirejs.org/) 在多少年前就能实现相似的功能了。 + +当然,如果是这样子我就没必要安利你了,相比 RequireJS 之流它还是有自己的特色的。Webpack 能读取的不光是原生的 JavaScript 文件,模块加载器的设计使得它能支持更丰富的格式。 + +例如,它能分析出你的 JavaScript 模块需要一个 CSS 文件,甚至能分析出这个 CSS 文件需要的图片资源。然后,处理过的资源文件只包含最精简的必须文件。不信?让我们现在来实战体验。 + +## 安装 + +首先必须要安装的是 [Node.js](https://nodejs.org/en/),在这里我们假定你已经正确安装并且配置完毕。那么安装 Webpack 所需要做的事,就只剩下输入下面的这条命令: + +```bash +npm install webpack -g +``` + +这条命令将全局安装 Webpack,并能在系统的任何路径下执行 `webpack` 命令。下面我们新建一个文件夹,在里面新建一个基本的 HTML 文件,名为`index.html`,内容如下: + +```html +<!doctype html> +<html> + <head> + <meta charset="utf-8" /> + <title>Webpack fun</title> + </head> + <body> + <h2></h2> + <script src="bundle.js"></script> + </body> +</html> +``` + +需要注意的是,这里定义的`bundle.js`暂时还不存在,稍后将由 Webpack 帮我们创建。另外,那个空的 H2 标签稍后我们将会使用到。 + +接下来,在上面文件夹里创建两个 JS 文件,分别叫做:`main.js`、`say-hello.js`。`main.js`你可以理解为 main 方法,也就是我们代码主要的执行入口。`say-hello.js`是一个简单的模块,它接收一个人名和 DOM 元素,然后在这个 DOM 元素上显示一条包含人名的欢迎信息。 + +```javascript +// say-hello.js + +module.exports = function (name, element) { + element.textContent = 'Hello ' + name + '!'; +}; +``` + +定义完 `say-hello.js` 这个模块后,我们在 `main.js` 里引用它,引用方法十分简单,只需要下面这两行代码: + +```javascript +// main.js +var sayHello = require('./say-hello'); + +sayHello('Guybrush', document.querySelector('h2')); +``` + +如果现在我们打开前面创建的那个 HTML 文件,你们发现页面上没有显示任何内容。因为我们既没有引用`main.js`,也没有将其处理成浏览器可执行的代码。接下来,我们使用 Webpack 读取`main.js`。如果能成功分析它的依赖,将会创建一个名为`bundle.js`的文件,并能在浏览器中执行。 + +回到命令行里执行 Webpack,只需简单输入如下命令: + +```bash +webpack main.js bundle.js +``` + +第一个参数定义了 Webpack 分析依赖的起始文件。首先,它查看起始文件里是否定义了相关的依赖。如果有,它将读入依赖的文件,看看这个文件是否也有其他的依赖。通过这种方式,递归读取完整个程式依赖的全部文件。一旦阅读完毕,它将整个依赖打包为一个文件,名为 `bundle.js`。 + +在这个例子里,当你按下回车后,你会看到类似下面的输出: + +```bash +Hash: 3d7d7339a68244b03c68 +Version: webpack 1.12.12 +Time: 55ms + Asset Size Chunks Chunk Names +bundle.js 1.65 kB 0 [emitted] main + [0] ./main.js 90 bytes {0} [built] + [1] ./say-hello.js 94 bytes {0} [built] +``` + +现在,打开`index.html`,浏览器将会显示`Hello Guybrush!` + +## 配置 + +如果每次运行 Webpack 都要指定输入和输出文件的话就太让人讨厌了。当然,开发者早就替我们想好了。其实和 `Gulp`、`Grunt`类似,Webpack 需要在我们的项目根目录下创建一个名为`webpack.config.js`的文件,就可以简化大量重复的命令参数。 + +在本例中,内容如下: + +```javascript +module.exports = { + entry: './main.js', + output: { + filename: 'bundle.js', + }, +}; +``` + +现在,我们只需要输入`webpack`这个命令,就能实现和之前一样的操作。 + +## 开发服务器 + +首先提个问题:每次你做了一些改动,如果都要手动去执行`webpack`命令来看结果的话,是不是特傻逼?要知道,`Gulp`在很早之前就支持定义`watch`这种监视文件修改的任务了。所以,Webpack也不例外,甚至它还更进一步,提供了一个基于Node.js Express框架的开发服务器。 + +```bash +npm install webpack-dev-server -g +``` + +首先运行上面的命令安装开发服务器,然后运行命令`webpack-dev-server`。这个命令将会启动一个简单的 Web 服务器,以命令执行的路径为静态资源根目录。下面我们打开浏览器,输入[http://localhost:8080/webpack-dev-server/](http://localhost:8080/webpack-dev-server/)。如果一切正常,你将看到类似下面的内容: + + + +现在,我们不仅有了一个超赞的轻量级 Web 服务器,我们还有了一个孜孜不倦地监听代码变更的观察者。如果 Webpack 发现我们修改了一个文件,它会自动运行 `webpack` 命令打包我们的代码并刷新页面。 + +假想一下,我们可以双屏写代码,一个屏幕放浏览器,一个屏幕开编辑器。浏览器实时刷新结果,无需我们做任何配置和操作,是不是很酷? + +现在你可以自己感受一下:修改`main.js`里面传给`sayHello`方法的姓名参数,然后保存文件,看看浏览器里面的实时变化。 + +## 加载器(Loaders) + +对于 Webpack 而言,最重要的特性就是[加载器](https://webpack.github.io/docs/loaders.html)。加载器和`Gulp` `Grunt`上的“任务”(tasks)类似。基本上都是读取文件,然后通过某种方式处理文件,最后打包为我们所需的代码。 + +本文中,我们想在代码中用一些[ES2015](http://www.ecma-international.org/ecma-262/6.0/)的语法。因为 ES2015 是当前最新的 JavaScript 版本,所以并没有被所有的浏览器支持。可是淫家就想写最新的代码装逼怎么办?那只好先写,写完后将 ES2016 版本的代码转换为老的 ES5 代码。 + +为了实现这个需求,我们需要使用当下最流行的 [Babel Loader](https://github.com/babel/babel-loader) 来进行转换。根据官网的教程,我们使用下面的命令进行安装: + +```bash +npm install babel-loader babel-core babel-preset-es2015 --save-dev +``` + +这条命令不仅安装了 Babel 加载器,还包含了它支持 ES2015 时所需要的依赖。 + +安装完加载器,我们需要告诉 Webpack 使用什么加载器,参考下面的实例更新 `webpack.config.js` 文件: + +```javascript +module.exports = { + entry: './main.js', + output: { + filename: 'bundle.js', + }, + module: { + loaders: [ + { + test: /\.js$/, + exclude: /node_modules/, + loader: 'babel', + query: { + presets: ['es2015'], + }, + }, + ], + }, +}; +``` + +在这个配置示例里,我们需要注意几个地方。首先,`test: /\.js$/`这行是一个正则表达式,表示文件名满足此正则表达式的文件将会被此加载器处理。这里,我们的定义是全部的JS文件。类似的,`exclude: /node_modules/`则是告诉 Webpack 忽略`node_modules`文件夹。`loader`和`query`我觉得十分好理解,就是使用Babel loader加载器处理ES2015语法的文件。 + +重启开发服务器,在命令行里按下`ctrl+c`,重新输入`webpack-dev-server`。现在我们来测试一下 ES6 的代码是否能被正确翻译呢?不如试试看将`sayHello`变量定义为一个常量。 + +```javascript +const sayHello = require('./say-hello'); +``` + +保存后,Webpack应该自动重新编译我们的代码并刷新浏览器,你会发现代码正常执行,什么都没有变。我们用编辑器打开`bundle.js`文件,你会发现没有`const`这个单词。 + +Webpack就是这么叼! + +## 第二部分预告 + +在这篇教程的第二部分,我们将学习使用 Webpack 加载 CSS 和 图片文件,同时让你的网站为部署做好准备。 + +## 相关链接 + +1. [Introduction to Webpack: Part 1](http://code.tutsplus.com/tutorials/introduction-to-webpack-part-1--cms-25791) +2. [详解前端模块化工具-Webpack](https://segmentfault.com/a/1190000003970448) +3. [Webpack Made Simple: Building ES6 & LESS with autorefresh](http://jamesknelson.com/webpack-made-simple-build-es6-less-with-autorefresh-in-26-lines/) diff --git a/src/content/posts/2016/2016-05-23-primary-school-student.mdx b/src/content/posts/2016/2016-05-23-primary-school-student.mdx new file mode 100644 index 0000000..f688b7b --- /dev/null +++ b/src/content/posts/2016/2016-05-23-primary-school-student.mdx @@ -0,0 +1,51 @@ +--- +title: 好羡慕,你还是学生 +slug: primary-school-student +date: 2016-05-23 15:23:42 +updated: 2021-08-26 22:58:13 +tags: + - 回忆 +category: 杂思 +cover: /images/2020/09/2020090419142440.jpg +summary: 上周日在图灵读者群看见一个小学生在图灵社区写古典音乐的点点滴滴,不由得觉得现在的小学生真的好厉害。那个时候像他们那般大的我们,究竟在做什么呢? +--- + + + +上周日在图灵读者群看见一个小学生在图灵社区写古典音乐的点点滴滴,不由得觉得现在的小学生真的好厉害。那个时候像他们那般大的我们,究竟在做什么呢? + +前些日子刷 Facebook,看网友恶搞柯南。 + +> 太一:我上中学了。 +> 小樱:我也上中学了。 +> +> 柯南:诶,好羡慕。 + +如果是我,面对初中生的小樱,小学生的柯南,大概也会说:诶,好羡慕。 + +不同的是,一直都在上小学的柯南桑羡慕小樱和太一终于可以上中学。我羡慕的是,他们都还是学生,我却要开始过成年人的生活了。虽然,曾经我和他们同级过,甚至比他们还要年轻…… + +作为一个从头到尾看着小樱读了70集小学的 Otaku,我并不习惯叫它『魔卡少女樱』,在那个连网络是什么都不清楚的年代,仅有的视听娱乐就是电视。电视台预告决定了我们对它的称呼——百变小樱。 + +百变小樱最吸引我的,除了那每一集都不一样的裙子(啊,我的少女心要融化了),爸爸那简直 BUG 般的厨艺,当然就是美貌的雪兔君。 + +第一次见到雪兔时就被惊艳到,世上竟有如此好看的男子。那个时候还是小学六年级,仰望着国中的他,心里面只想着快点长大,快点变得和他一样帅气迷人。后来终于成为一名和雪兔一样的だんしこうこうせい,只是这段的时光过得很快。一不小心,我们就错开了,然后越来越远。 + +在二次元的世界里,时间几乎是冻结的,就像说,柯南永远都是小学一年级,小智永远在成为神奇宝贝大师的路上。后来再次与他们相遇时,我们已经是大学生和中学生的差距了。这样的差距,只会随着时间的流逝,越来越大。 + +然而置身时间之中,我们并不敏感,就像是黑客帝国里面的 Matrix。往往只有到了某个固定的节点才会惊醒,比如上周六我在楼下被4岁的小女孩叫叔叔(違う、そうじゃない)。又比如,昨天看到百变小樱的20周年新连载开催予定。再比如,这次的奥运会一定会让人回想起八年前的北京奥运会。 + +这样的场景并不多见,所以更多时间,我们都沉浸在自己的年轻里。然而,我们终究还是藏不了自己的改变。越来越光亮的脑门,偶尔出现的白发,不再有弹性的肌肤,都在暗示着自己的衰老。 + +不知何时,我越来越不愿记住自己的年龄。不像小时候,对于年龄的增长有一种几近狂热的向往。每过一年除夕,都会毫不含糊地在年龄上加上一岁,张开五指,然后骄傲地告诉大人『私は今年五歳』。现在的我,年龄早就不是一只手能数的清的,当然也不会做这么幼稚的事了。 + +除了不再敏感也不再向往,自身也有一种逃避的心理在吧。虽然我知道,这只是一种掩耳盗铃,自己虽假装不知,但根本藏不住啊。 + +容颜终将老去,无法定格在年轻的模样。光阴向左,生活向右,我们已经长大,有自己的家庭,新的人生…… + +可是,我还是好羡慕,你还只是一个学生。 + +> きっと 何かが 何かが どこかで 出会える日を待ってる +> Do! Do! Do! Dreaming ! Dreaming ! そして扉がひらくよ... + + diff --git a/src/content/posts/2016/2016-07-01-how-to-read-a-technology-book.mdx b/src/content/posts/2016/2016-07-01-how-to-read-a-technology-book.mdx new file mode 100644 index 0000000..fb0200f --- /dev/null +++ b/src/content/posts/2016/2016-07-01-how-to-read-a-technology-book.mdx @@ -0,0 +1,19 @@ +--- +title: 如何阅读一本技术书 +slug: how-to-read-a-technology-book +date: 2016-07-01 14:22:12 +updated: 2020-09-04 19:11:07 +category: 文章 +cover: /images/2020/09/2020090419102255.jpg +summary: 读技术书籍分为三步,第一步,扫读,不用弄懂,就是那么读过去,可以称为囫囵吞枣的状态,直到读完。 +--- + + + +读技术书籍分为三步。第一步,扫读,不用弄懂,就是那么读过去,可以称为囫囵吞枣的方式,直到读完。(这么做的理由很简单,计算机类的知识不可能线性地排列,让读书的人从零开始一步步学习,比如某些 Java 书籍上来就说面向对象,但没几个人能一开始就理解这个概念。但你读到后面会发现,很多前面不懂的东西,到了后面讲到某个知识点就懂了。但是为何不先讲后面的东西呢?因为太难,你需要前面的某些基础知识。) + +第二步,就是精读,但也不是一个字一个字读,书那么厚,你没那么多时间来精读的。所以就要专门读代码,书中的代码永远是最好的老师,比如 Java 编程思想,你要是看懂代码了,就不用看旁边的文字了,我接触的大部分技术书都是如此。所以读代码为主,阅读旁边文字为辅。代码阅读时不要一行行敲打,那是 useless 的。因为那样子的成果和强制自己理解一行行看的成果差不多,但是时间上更少。 + +第三步,我姑且称为查漏补缺,看目录,那些你还不清楚是什么玩意,去看看那一页对应的内容。 + +书看完后基本目标是要会用,所以在学习上就要分清主次,按照理解能力的不同,优先在项目和练习中使用那些已经懂了的知识,而无需在全部都学过一遍之后再去尝试。但在使用出问题的时候,我更推荐看文档,而非翻书,因为书籍永远不是最新最全的,文档永远是相对权威的(因为最权威的是源码)。 diff --git a/src/content/posts/2016/2016-08-09-my-fickleness-life.mdx b/src/content/posts/2016/2016-08-09-my-fickleness-life.mdx new file mode 100644 index 0000000..0d98ff8 --- /dev/null +++ b/src/content/posts/2016/2016-08-09-my-fickleness-life.mdx @@ -0,0 +1,37 @@ +--- +title: 重看08奥运会开幕式有感 +slug: my-fickleness-life +date: 2016-08-09 14:04:59 +updated: 2020-09-04 13:37:13 +tags: + - 奥运会 +category: 文章 +cover: /images/2020/09/2020090413365426.jpg +summary: 这些天被里约热内卢的奥运新闻刷屏。看了好几篇长篇累赘的报道,基本都集中在几点上:环境差,房间烂,场馆没建好,社会乱…… +--- + + + +这些天被里约热内卢的奥运新闻刷屏。看了好几篇长篇累赘的报道,基本都集中在几点上:环境差,房间烂,场馆没建好,社会乱……微博上也是一堆不求奥运健儿拿金牌,只求平安回家云云的评论。更有意思的是周六CCTV5体育新闻在微博上分享了8年前的北京奥运会剪辑,配上评论:『我们是认真的!』 + +记得自己两个月前在博客里[写道](/posts/primary-school-student/):『这次的奥运会一定会让人回想起八年前的北京奥运会。』诚然,08年奥运会对于大多数人而言是一个终身难忘的记忆。它的高标准,使得我在大学看伦敦奥运会开幕式的时候,是满怀不屑的。带着这样的心情,我在 U2B 上重温了08年北京奥运会的开幕式,却发现,并不如想象中那么美好。 + +我所谓的不好,不是指奥运会开幕式本身不够精彩不够震撼。而是指,它和我记忆中的影像,有着太大的偏差。导播生硬的切换机位,很多匪夷所思的抠鼻、扇扇子的特写镜头,播音员在介绍入场运动员的混乱,演出中一些不该被看到的工作人员……甚至在对比了 NBC 的版本之后,我觉得,他们录制的版本,才是我心目中北京奥运会应该有的样子。 + +那么,为什么当年的我,没有这种想法呢? + +同样的场景发生在去年阅兵式的直播,靠着前公司的某位大佬的帮助,其实我是看过彩排的。所以正式阅兵那天我就在家睡懒觉,没看。如果不是地铁循环滚动的阅兵画面,我都难以想象,导播切的镜头都是什么玩意,还我看彩排时候的感动! + +虽然某些政治必要性,需要给予国家领导人充足的镜头。但是混乱的切机视角,尤其是给只有6人的非洲朋友们的远景长焦(你这是故意衬托别人人少么?),总让人觉得这导演水平不够啊!虎嗅上有篇文章《吐槽自己我比你们更狠更专业,但我们可能是央视最后的导播人才》更是淋漓尽致地吐槽了种种导播的不足。 + +这样的变化还有很多很多,比如今年『三观太正』的春晚,各种被大家誉为雷剧的青春偶像片。但和父母聊天时,才惊讶地发现,爸妈竟然并没有觉得这些难看,阅兵式的节目他们之前看了直播,在过年时听到我的吐槽,硬是拉着我看了一遍给他们当解说。春晚我爸晚上看了一遍还不够,第二天下午又拉着全家四世同堂看了一遍。 + +其实父母没变,央视的导播水平也一直没变,春晚也没变,变的只有我们自己罢了。因为工作和专业的缘故,基本从10年起,我就没怎么看过电视了。每天的近三分之二的时间,是在电脑前度过的,所以,我的一切信息来源于互联网,不再是新闻联播说什么就是什么。 + +就像说,8年前,我还不知道外面的世界,我还在啃砖头般的《邢其毅基础有机化学》,梦想搞一辈子科研,还会为快乐女声一类选秀节目的歌手的悲惨故事感动落泪。那时的我坚信,每个人都有着自己的梦想,自己也不例外,并朝着梦想的方向不断前进着。 + +从时间点上,90后的我们踩在了国企改革的起点,经历过大锅饭经济,父母在市场化改革中纷纷下岗、早退。我们从无到有感受了互联网,IT领域的发展,被数字信息的洪流淹没。 + +于是乎,不断增长的买房压力,越来越多的工作学习压力,理想和现实的一次次落差。开始变得焦虑,变得对这个社会充满批判。也许,我们这一代人是焦虑的。 + + diff --git a/src/content/posts/2016/2016-08-10-summer-dream.mdx b/src/content/posts/2016/2016-08-10-summer-dream.mdx new file mode 100644 index 0000000..5760f5b --- /dev/null +++ b/src/content/posts/2016/2016-08-10-summer-dream.mdx @@ -0,0 +1,35 @@ +--- +title: 盛夏的记忆 +slug: summer-dream +date: 2016-08-10 00:28:59 +updated: 2020-09-04 13:06:18 +category: 文章 +cover: /images/2020/09/2020090412582748.jpg +summary: 恍然间已经在北京度过第三个夏季。明明阳光明媚,却突然下起了瓢泼大雨,这在北京的夏天算不得什么奇事,但也着实让我感到一些不高兴。 +--- + + + +恍然间已经在北京度过第三个夏季。 + +明明阳光明媚,却突然下起了瓢泼大雨,这在北京的夏天算不得什么奇事,但也着实让我感到一些不高兴。毕竟作为一个男生,我又不可能像女生一样总是随身带把伞,也就免不得淋一身的雨。有时早上醒来看见窗外在下雨,反而让我满心欢喜,因为有理由磨磨蹭蹭,也有理由在办公室正大光明地穿上人字拖。我试图绕开积水, 却又不可避免地踩在了小区门口的水坑里,心里是挥之不去的烦躁:『暴雨如注,我想回家葛优瘫。』然后慢吞吞地回去换凉鞋。 + +北京的夏天,有时候阳光闪闪发亮,整个世界都明亮起来;有时候骤然大雨,如世界末日,而大多时候只是潮湿而闷热。工作上日复一日地在deadline与deadline之间追赶,有时也让人身心疲惫。刷微博时看到洛之秋老师写,喜欢夏天的台风“给原本乏味的城市带来的那种微型末日之感”,但“这戏剧化的天空必将逝去,我们最终只能回到那个潮湿、闷热的梦里”。在很多个短暂却很沉的午睡中醒来,恍如隔世般地看着刚被我点亮的显示器之后,我觉得,“潮湿、闷热的梦”也是好的,如果有的话。 + +大概是为了找寻那个“潮湿、闷热的梦”,7月底的我去了上海 ChinaJoy 散心。在去上海的飞机上,看了一小会漫画『元气囝仔』,就迷迷糊糊地睡着了。到了上海,总想起漫画里こといし在海岛上,咬着好看的冰淇淋,扎着俏皮小短辨的画面。于是在夜晚的南京街,看到冰淇淋小摊后,我迅速选了一根同样好看的绿色冰淇淋,上面嵌了一片薄薄的发苦的黄色柠檬。在模糊夜色和拥挤人群里,我还是努力地给绿色冰淇淋留了影,为绿色的夏日作证,为不知道算不算“潮湿、闷热的梦”留影。 + +今天傍晚从回龙观东大街地铁站出来,没有吃晚饭,走回家的时候路过站门口的夜市摊,诱人的烧烤散发着孜然味的热气,有人围着吃粉丝生蚝加几对烤鸡翅和鸡腿,再喝几杯冰啤酒下肚,满满都是烟火气。刚好在听PodCast上很久没听的《味之道》,妙雅讲到越南西贡的凉水铺子,此时的越南热到冒烟,街上走几步路就能遇到一个歇脚的凉水铺子。老板挤一点青柠檬汁,加两勺糖(声音高八度),塞很多的冰块。人们捧着这杯做好的柠檬水坐在旁边的塑料板凳上,聊天或者什么也不做。我想,那杯柠檬汁就是他们几乎唯一的消暑利器。 + +去不了越南旅行,也无法在这个荷尔蒙躁动的七夕找到自己的另一半,我只好坐在窗台上拿出素描本描绘傍晚的天空。自从三月搬了家,最让我喜欢的,便是新家大大的窗台,夏天坐在上面,冰凉、舒爽。看着一窗之隔的燥热,总有一种淡淡的不真实感。 + +也因此总有些下午让人日后反复想起,那些下午虽不见得意义深重,但却不知为何难以忘怀。上周六,我吃完午饭,拉上窗帘,在昏暗的房间里午睡。醒来吃了个冰镇西瓜,清爽甜蜜。还有一个周日,打扫完卫生,我做在窗台拿钩针勾线。有那么一瞬间感到天地都是平和的,不用赶,也不用给任何人交代,那个瞬间大概是不忧将来,不思过去,也不想现在的。 + +> “午后下起滂沱大雨。雷声隆隆,房间里阴暗。我在客房午睡,她来回走动,絮絮叨叨。搬动被子毯子,扫地,擦桌,整理做晚饭要用的菜蔬,用高压锅炖煮红豆,准备明天早上的豆沙糯米圆子。这类食物是冬季的点心,她知道我喜欢,所以夏天也煮。发出的琐碎声一如以往。她有时会忽略顾及他人的感受。一意孤行做乐意的事。 +> +> 但这些声音照例使我很快入睡,睡醒之后,近黄昏,雨已停。她切开西瓜,我们吃瓜,说些日常话。” + +读庆山的新书《月童度河》后,时常想起这段话里的场景,说不清是想起那个下午的大雨,睡梦中的细碎声,午睡到黄昏的酣畅,还是睡醒后的西瓜。 + +今天中午,午睡前耳机里放着莫倪的《7月的南方》,歌里唱,阳光在七月的天空闪耀的发烫。我在空调房里眯起眼睛,透过窗帘的缝隙看到外面阳光热烈,庆幸夏天还长。决定卷起被子睡到黄昏,做一个长长的关于潮湿闷热的梦…… + + diff --git a/src/content/posts/2016/2016-08-15-future-plan-on-kids.mdx b/src/content/posts/2016/2016-08-15-future-plan-on-kids.mdx new file mode 100644 index 0000000..bc884d8 --- /dev/null +++ b/src/content/posts/2016/2016-08-15-future-plan-on-kids.mdx @@ -0,0 +1,43 @@ +--- +title: 未来鬼父计划 - 萝莉养成 +slug: future-plan-on-kids +date: 2016-08-14 23:15:57 +updated: 2020-09-04 12:44:48 +category: 文章 +cover: /images/2020/09/2020090412370067.jpg +summary: 按照中国目前的计划生育策略,在不考虑交高额罚金的情况下,我能被允许养育的最高子女数量为两个。按照未来生活水平的提高和自我对于生活品质的追求,我不可能也没有精力抚养过多的孩子。 +--- + + + +按照中国目前的计划生育策略,在不考虑交高额罚金的情况下,我能被允许养育的最高子女数量为两个。按照未来生活水平的提高和自我对于生活品质的追求,我不可能也没有精力抚养过多的孩子。所以,现阶段来看,两到三个小孩是不错的选择。但是,计划赶不上变化,也许未来我可能丁克,可能只要一个小孩。所以,这里只是待定稿。 + +首先,我希望我的第一胎是女儿,这点比较关键,我个人十分喜欢女儿,喜欢程度远大于男孩。所以,如果可行,我可能在妊娠初期就去鉴定性别。(不开玩笑,这块相关知识作为动物生理学为竞赛自学完的我而言,并不是难题。B超影像图谱,我基本能看懂,关键在于找到合适的渠道进行检测。) + +那么按照第一胎的情况,分别有不同的考虑。 + +### 如果第一胎是女儿 + +我一向坚持男孩穷养,女孩富养的观点。但是说明的是,这里的穷和富并不是传统意义上的穷和富。 + +穷养,更多的是,在生活上要求男孩更加自理,希望在很小的时候,就能养成能吃苦,能有自我想法的天性。也就是说,我希望他有自己的个性,我不会将我的任何意志压在他身上,要他做啥做啥。只要不犯错(违背法律,社会基本价值观,伤害他人),我不会苛责。但是相对应的,很多时候,并不会百依百顺,许多他渴求的东西,需要通过某些努力换取。(但我并不觉得是考试考多少)相对应的,我在学习上并无过高的要求,只要求能够完成基本的12年『义务教育』。因为12年的时光,足以打磨一个人的性格,12年的学习生活也会让他和同龄人有更多的话题,更多的知识沉淀。 + +富养,和穷养最大的区别,就是在于物质给予上。我觉得按照当代社会价值观体系对于女性的定位,她们未来更多是当家母的角色,而非八九十年代港台剧里的全职太太。也就是说,在女权主义越来越普及的中国和目前男女比例失调的社会。女孩,很多时候都是属于管理小家庭的一方。一方面,在男性主要忙于赚钱的时候,她需要担负起主要的子女教育。另一方面,她需要考虑全家生活起居等琐事。按照最新的调查,男女双方都有各自事业的家庭更加和睦,所以作为一位优秀的贤内助,有时候也需要承担一部分家庭生计。 + +这么一对比,在一开始就富养,尤其是较为富裕的零花钱给予。一是让女孩一开始养成资金的管理,二是能让她有更多的钱进行自我兴趣的释放。(省的被个穷小子三言两语就骗了一辈子的幸福,哼!)富养的另一好处,就是女孩子的各方面能力会更加多样,我不会要求自己的小孩会这会那,报各种艺术班。一,我没那么多钱。二,小孩不一定愿意学。三,我觉得能喜欢一件事并一直坚持下去才能真正做好。但是,只要是她喜欢的爱好,我会全力支持。我觉得,这种方式养成的萝莉,才是最吼得! + +### 如果第一胎是男孩 + +第一胎一定要女儿,我压根就不会做男孩的考虑。 + +### 二胎什么时候要 + +按照我个人的生活规划,我的计划是28岁结婚,顺便还能去 Tokyo 看个奥运会,搞个蜜月啥的。所以,我要一胎的时候最小也应该是29岁。因为秋季适合女性怀孕,按照妊娠280天的大概计算,应该是在第二年夏季预产。所以二胎理论上,我希望在一胎上小学的时候要,那个时候我未来的老婆应该是在33~38岁间。一来,按照女性的生理周期,38岁之后的排卵就开始减少,卵巢的卵子的质量也明显不如年轻的时候,就女性自身的各方面生育质量也不如以前。 + +伴随妊娠可能会有的高血压糖尿病,使得怀孕不见得是一个好的选择。尤其是过了38岁,就属于高龄产妇,有一定生产的危险,这个时候的医生会推荐剖腹产,我疼老婆,自然不愿意她这么挨一刀。二来,我个人认为,38岁,算一个男人的事业黄金期,所以这个时候的生活收入,足以支持两个小孩的负担。如果那个时候我事业不行,只要一个小孩是必然的选择。 + +当然,如果生两个女孩,自然是最吼得。衣服什么的,不用买新的啦,妹妹直接穿姐姐的,还能继续 Cosplay 动漫 loli 什么的,想想我的鬼父之心蠢蠢欲动。 + +未来谁说的准呢?13年的时候我在网易邮箱的笔记本里写了十样东西,是我未来想买的。在这周末伴随着最后一件电钢琴的购买,终于全部实现了。 + +所以啊,人还是要做梦的,万一实现了呢? diff --git a/src/content/posts/2016/2016-11-16-a-scala-exercise-a-day-1.mdx b/src/content/posts/2016/2016-11-16-a-scala-exercise-a-day-1.mdx new file mode 100644 index 0000000..b4c282c --- /dev/null +++ b/src/content/posts/2016/2016-11-16-a-scala-exercise-a-day-1.mdx @@ -0,0 +1,116 @@ +--- +title: A scala exercise a day 1 +slug: a-scala-exercise-a-day-1 +date: 2016-11-16 10:44:41 +updated: 2020-09-04 12:44:34 +tags: + - Scala +category: 编程 +cover: /images/2020/09/2020090412164155.jpg +summary: 编写一段代码,将 a 设置为一个 n 个随机整数的数组,要求随机数介于 [0, n) 之间。 +--- + + + +1、编写一段代码,将 a 设置为一个 n 个随机整数的数组,要求随机数介于 `[0, n)` 之间。 + +```scala +def randomArray(n: Int) : Array[Int] = { + (for (i <- 0 until n) yield (math.random * n).toInt).toArray +} +``` + +2、编写一个循环,将整数数组中相邻的元素置换。例如,`Array(1, 2, 3, 4, 5)` 经过置换之后变为 `Array(2, 1, 4, 3, 5)`。 + +```scala +def transferArray(array: Array[Int]) : Array[Int] = { + for (i <- array.indices if i % 2 == 1) { + val temp = array(i) + array(i) = array(i - 1) + array(i - 1) = temp + } + array +} +``` + +3、重复前一个练习,不过这次生成一个新的值交换过的数组。用 `for/yield`。 + +```scala +def transferArray(array: Array[Int]) : Array[Int] = { + (for (i <- array.indices) yield { + i % 2 match { + case 1 => array(i - 1) + case 0 => if (i + 1 == array.length) array(i) else array(i + 1) + } + }).toArray +} +``` + +4、给定一个整数数组,产出一个新的数组,包含元素组中的所有正值,以原有顺序排列,之后的元素是所有的零或负值,以原有顺序排列。 + +```scala +def sortArray(array: Array[Int]) : Array[Int] = { + val (left, right) = array.partition(_ > 0) + left ++ right +} +``` + +5、如何计算 `Array[Double]` 的平均值? + +```scala +def arrayAverage(array: Array[Double]) : Double = { + array.sum / array.length +} +``` + +6、如何重新组织 `Array[Int]` 的元素将它们以反序排列?对于 `ArrayBuffer[Int]` 你又会怎么做呢? + +```scala +def reverseAverage(array: Array[Int]) : Array[Int] = { + for (i <- array.indices if i < array.length / 2) { + val temp = array(i) + array(i) = array(array.length - i - 1) + array(array.length - i - 1) = temp + } + array +} +``` + +对于 `ArrayBuffer` 如下 + +```scala +def reverseAverage(array: ArrayBuffer[Int]) : ArrayBuffer[Int] = { + array.reverse +} +``` + +7、编写一段代码,产出数组中的所有值,去掉重复项。 + +```scala +def distinctAverage(array: Array[Int]) : Array[Int] = { + array.distinct +} +``` + +8、创建一个由 `java.util.TimeZone.getAvailableIDs` 返回的时区集合,判断条件是它们在美洲。去掉 `"America/"` 前缀并排序。 + +```scala +val sortedAmericanZone = java.util.TimeZone.getAvailableIDs.filter(_.startsWith("America")).map(_.replaceFirst("America/", "")).sorted +``` + +9、引入 `java.awt.datatransfer._` 并构建一个类型为 `SystemFlavorMap` 类型的对象: `val flavors = SystemFlavorMap.getDefaultFlavorMap().asInstanceOf[SystemFlavorMap]` 然后以 `DataFlavor.imageFlavor` 为参数调用 `getNativesForFlavor` 方法,以 Scala 缓冲保存返回值。 + +首先导入包 + +```scala +import java.awt.datatransfer._ +import scala.collection.JavaConversions._ +import scala.collection.mutable.Buffer +``` + +然后编码 + +```scala +val flavors = SystemFlavorMap.getDefaultFlavorMap().asInstanceOf[SystemFlavorMap] +val flavor: Buffer[String] = flavors.getNativesForFlavor(DataFlavor.imageFlavor) +``` diff --git a/src/content/posts/2017/2017-03-06-rewrite-your-logic.mdx b/src/content/posts/2017/2017-03-06-rewrite-your-logic.mdx new file mode 100644 index 0000000..f21d2fc --- /dev/null +++ b/src/content/posts/2017/2017-03-06-rewrite-your-logic.mdx @@ -0,0 +1,335 @@ +--- +title: 在编程中思考,简化你的判断逻辑 +slug: rewrite-your-logic +date: 2017-03-06 12:31:33 +updated: 2019-05-18 18:24:08 +tags: + - 思考 + - 编码 + - 编程 +category: 编程 +cover: /images/2019/05/2019051407531632.jpg +summary: 之前看 Linus Toward 在去年的某次采访中说到的好代码坏代码,当中提到了逻辑的精简,能用更通用的逻辑减少 if else 的判断在某种程度上可以使你的代码变得更好。 +--- + + + +之前看 Linus Toward 在去年的[某次采访](https://www.youtube.com/watch?v=o8NPllzkFhE&feature=youtu.be&t=890)中说到的好代码坏代码,当中提到了逻辑的精简,能用更通用的逻辑减少 if else 的判断在某种程度上可以使你的代码变得更好。最近一段时间重构了部分老代码,也 Review 了不少代码,对此观点深有感触。 + +很多时候,程序员接到的需求,产品巴不得你立刻就能搞定,有时候会给非常紧迫的时间点。这种情况下会带来的最直接问题,就是[“设计坏味”](http://www.ituring.com.cn/article/263057)。有整体的架构设计的不合理,也有代码逻辑的问题。尤其是对于边界条件的处理,因为需求的急,很多时候大家就会按照业务语言去写。 + +比如,下面这个例子: + +某一报警系统产生了报警邮件,现在需要按照类型显示不同的内容。 + +| 类型 | 报警选择对象 | 邮件中展示内容 | +| ------- | ------------ | ------------------- | +| Web事务 | 单条Web事务 | Tier,Web事务,节点 | +| Web事务 | Tier | Tier,节点 | +| 节点 | 某一个节点 | 节点 | +| 节点 | Tier | Tier,节点 | + +如果按照业务的语言,我们可能写出如下的伪代码: + +```java +if (Web事务&& 单条Web事务) { + return Tier,Web事务,节点; +} +if (Web事务&& Tier) { + return Tier,节点; +} +if (节点&& 某一个节点) { + return 节点; +} +if (节点&& Tier) { + return Tier,节点; +} +``` + +可能你看到这里会立刻笑出来,哪有只写 `if` 不写 `else` 的。那好,也许你会写出这样的代码。 + +```java +if (Web事务) { + if (单条Web事务) { + return Tier,Web事务,节点; + } else if (Tier) { + return Tier,节点; + } +} else if (节点) { + if (某一个节点) { + return 节点; + } else if (Tier) { + return Tier,节点; + } +} +``` + +我相信,大部分人都能将判断逻辑写到这一层,但是,这就完了么?也许你会说完了,逻辑也正确,看起来也很清晰。然而,这远远不够。 + +其实我们可以发现,在每种情况下,都会返回 `节点` 信息。只返回节点信息的只有一种情况,其他的情况下,基本都返回 `Tier` 信息。只有 `Web事务 && 单条Web事务` 的情况需要返回 `Web事务` 信息。所以,最后我们可以精简为两个判断。 + +```java +result = "节点"; +if (Web事务&& 单条Web事务) { + result = "Web事务" + result; +} +if (Web事务 || !某一个节点) { + result = "Tier" + result; +} +return result; +``` + +回到最初的命题,为何不要用业务的语言来编写判断逻辑呢?因为业务语言是给用户和产品看的,他们在描述上本身就不够精简。其次,业务的描述,很多时候,是定义边界,说明问题,而不是告诉你判断逻辑。 + +所以,在写代码的时候,更多的时候要细化逻辑。这样,在维护修改时,才更为方便。下面我举另一个更具体的例子。 + +这是我 Review Scala 代码的时候遇到的一个问题,首先我先用业务语言描述一下需求。需要判断某个规则的开闭状态,在一天的几点到几点间启用,且还可以额外设置是周一到周日的哪几天启用。 + +于是我看到当时的同事,写一个方法 `isSuppressTime` ,会给两个参数,第一个参数为一个时间戳 `timestamp` ,第二个参数为一个 `List[Map[String, String]]` 。 + +`Map[String, String]` 里面有4个值,分别是: + +1. startTime,从零点到某个具体开始时间的秒数,0~86399。 +2. endTime,从零点到某个具体结束时间的秒数,0~86399。 +3. isDaily,当时间戳在 startTime endTime 之间时,如果此项为 true,则返回 true。 +4. weekdays,周一到周日,1~7,以`,`间隔组成的字符串,如`1,4,5`。表示周一、周四、周五且时间戳在 startTime endTime 之间时返回 true + +最后他写出了如下的代码(Scala): + +```scala +def isSuppressTime(now: Long = System.currentTimeMillis(), + suppressTimes: java.util.List[java.util.Map[String, String]] = rule.getSuppressTime): Boolean = { + if(suppressTimes == null) + return false + import scala.collection.JavaConversions._ + suppressTimes.foreach(params => { + if (params != null && params.size > 0) { + val startTime = params.get("startTime") + val endTime = params.get("endTime") + val isDaily = params.get("isDaily") + val weekdays = params.get("weekday").split(",").toList + + val zero = zeroTimestamp() + //今天零点零分零秒的毫秒数 + val start = zero + startTime.toLong * 1000 + val end = zero + endTime.toLong * 1000 + + if (start < = now&& end >= now) { + if (isDaily.toBoolean) + return true + val cal = Calendar.getInstance() + cal.setTimeInMillis(now) + var day = cal.get(Calendar.DAY_OF_WEEK) + if (day == 1) + day = 7 + else + day = day - 1 + val weekday = day.toString + if (weekdays.contains(weekday)) + return true + } + } + }) + return false +} + +private def zeroTimestamp(): Long = { + val cal = Calendar.getInstance() + cal.set(Calendar.HOUR_OF_DAY, 0) + cal.set(Calendar.SECOND, 0) + cal.set(Calendar.MINUTE, 0) + cal.set(Calendar.MILLISECOND, 1) + cal.getTimeInMillis() +} +``` + +这个代码看着很长,判断很多,而且还用了超级多陈旧的 API,使得它的性能也不好。而且这是一段 Scala 的代码,却用了较多的 `return` 和 `var` ,这两个都是 Scala 不提倡的。最关键的,明明是函数式的代码,他却写出了过程式的感觉。给后面的维护人员(我)带来了不少困扰。 + +下面,我们来一点点优化这段代码(需要一点点 Java 功底),首先对于方法 `zeroTimestamp()` ,我第一眼看到的时候,是惊讶的,原作者用了一个比较旧的 `Calendar` 。对它最深刻的印象就是当年写 `SimpleDataFormat` 的时候,因为 `Calendar` 这货导致线程不安全。而每次创建 `SimpleDataFormat` 的开销比较大,最后不得不写了个 `ThreadLocal<simpledataformat>` 。 + +而Java8以后,我们可以直接用 `java.time` 下面的类来改写 `zeroTimestamp()` ,这里只需要一行代码,如下: + +```scala +private def zeroTimestamp(): Long = { + Timestamp.valueOf(LocalDate.now().atStartOfDay()).getTime +} +``` + +回到 `isSuppressTime` 方法上来,我姑且不说他的设计多么麻烦,因为这是一个已经被广泛使用的方法,我能做到的就是在不改变签名的情况写来优化实现。 + +首先,开头我们就看到 + +```scala +if(suppressTimes == null) + return false +``` + +这个空的判断和强制 `return` ,在 Java 里面, `null` 是一个很痛苦的事情,Scala 因为基于 JVM 也不例外,但是 Scala 和 Java 8 都分别有一个 `Option` 类(Java8是 `Optional` ),来做空值处理。 + +所以,我们这里第一时间可以干掉这个判断,写成如下方式 + +```scala +Option[util.List[util.Map[String, String]]](suppressTimes).map(times => { + // ba la ba la +}).getOrElse(false) +``` + +代码里面的 `times` 为方法中非空的 `suppressTimes` ,注释部分为核心的处理逻辑,这样我们避免了一个 `if` 判断,减少了一个 `return` 。 + +而其实, `Option([A]).map([B] => Boolean).getOrElse(false)` 等价于 `Option` 的 `exists` 方法,最后完整的代码应该如下: + +```scala +def isSuppressTime(now: Long = System.currentTimeMillis(), + suppressTimes: java.util.List[java.util.Map[String, String]]): Boolean = { + Option[util.List[util.Map[String, String]]](suppressTimes).exists(times => { + times.foreach(params => { + if (params != null&& params.size > 0) { + val startTime = params.get("startTime") + val endTime = params.get("endTime") + val isDaily = params.get("isDaily") + val weekdays = params.get("weekday").split(",").toList + + val zero = zeroTimestamp() + //今天零点零分零秒的毫秒数 + val start = zero + startTime.toLong * 1000 + val end = zero + endTime.toLong * 1000 + + if (start < = now&& end >= now) { + if (isDaily.toBoolean) + return true + val cal = Calendar.getInstance() + cal.setTimeInMillis(now) + var day = cal.get(Calendar.DAY_OF_WEEK) + if (day == 1) + day = 7 + else + day = day - 1 + val weekday = day.toString + if (weekdays.contains(weekday)) + return true + } + } + }) + false + }) +} +``` + +在上面的例子里面,我们已经干掉了两个 `return` 和一个 `if` ,让它有一点 Functional 的感觉了。 + +上面重构后代码中, `times` 的类型是 `util.List[util.Map[String, String]]` 。 `times.foreach(params => {})` 里的 `params` 对应的是 `util.Map[String, String]` 类型。所以,我们看到判断 `if (params != null && params.size > 0)` 时应该会发现,这就是一个list filter的过程嘛。 `.filter()` 之后不就是一个 `.map()` ,于是我们可以这么改: + +```scala +Option[util.List[util.Map[String, String]]](suppressTimes).exists(times => { + times.filter(params => params != null&& !params.isEmpty).map(params => { + // ba la ba la + }).contains(true) +}) +``` + +当然 `.map(xxx => Boolean).contains(true)` 等价于 `.exists()` ,于是我们重构的方法如下: + +```scala +def isSuppressTime(now: Long = System.currentTimeMillis(), + suppressTimes: java.util.List[java.util.Map[String, String]]): Boolean = { + Option[util.List[util.Map[String, String]]](suppressTimes).exists(times => { + times.filter(params => params != null&& !params.isEmpty).exists(params => { + val startTime = params.get("startTime") + val endTime = params.get("endTime") + val isDaily = params.get("isDaily") + val weekdays = params.get("weekday").split(",").toList + + val zero = zeroTimestamp() + //今天零点零分零秒的毫秒数 + val start = zero + startTime.toLong * 1000 + val end = zero + endTime.toLong * 1000 + + if (start < = now&& end >= now) { + if (isDaily.toBoolean) + return true + val cal = Calendar.getInstance() + cal.setTimeInMillis(now) + var day = cal.get(Calendar.DAY_OF_WEEK) + if (day == 1) + day = 7 + else + day = day - 1 + val weekday = day.toString + if (weekdays.contains(weekday)) + return true + } + false + }) + }) +} +``` + +这次重构,我们又去掉了一层 if 判断,改为 filter 实现,减少了一次返回。到了这一步,我们会发现,下面需要实现的就是一个方法,对 `util.Map[String, String]` 去做处理,返回一个布尔值,于是我们精简方法的实现代码为两部分: + +```scala +def isSuppressTime(now: Long = System.currentTimeMillis(), + suppressTimes: java.util.List[java.util.Map[String, String]] = rule.getSuppressTime): Boolean = { + Option[util.List[util.Map[String, String]]](suppressTimes) + .exists(times => times.filter(params => params != null&& !params.isEmpty).exists(isValidateTimes(_, now))) +} +``` + +这个为边界过滤的方法。 + +```scala +private def isValidateTimes(params: java.util.Map[String, String], now: Long): Boolean = { + val startTime = params.get("startTime") + val endTime = params.get("endTime") + val isDaily = params.get("isDaily") + val weekdays = params.get("weekday").split(",").toList + + val zero = zeroTimestamp() + //今天零点零分零秒的毫秒数 + val start = zero + startTime.toLong * 1000 + val end = zero + endTime.toLong * 1000 + + if (start < = now&& end >= now) { + if (isDaily.toBoolean) + return true + val cal = Calendar.getInstance() + cal.setTimeInMillis(now) + var day = cal.get(Calendar.DAY_OF_WEEK) + if (day == 1) + day = 7 + else + day = day - 1 + val weekday = day.toString + if (weekdays.contains(weekday)) + return true + } + false +} +``` + +这个为我们要重构的核心处理逻辑。我们优化整理它的判断条件,最后可以实现如下的完整代码: + +```scala +def isSuppressTime(now: Long = System.currentTimeMillis(), + suppressTimes: java.util.List[java.util.Map[String, String]] = rule.getSuppressTime): Boolean = { + Option[util.List[util.Map[String, String]]](suppressTimes) + .exists(times => times.filter(params => params != null&& !params.isEmpty) + .exists(isValidateTimes(_, now))) +} + +private def isValidateTimes(params: java.util.Map[String, String], now: Long): Boolean = { + val zero = zeroTimestamp() + val start = zero + params.get("startTime").toLong * 1000 + val end = zero + params.get("endTime").toLong * 1000 + val isDaily = params.get("isDaily").toBoolean + val weekdays = params.get("weekday").split(",").toList + val weekday = LocalDate.now().getDayOfWeek.getValue.toString + + (start < = now&& end >= now)&& (isDaily || weekdays.contains(weekday)) +} +``` + +这样,我们就实现了一个 `if` 都没有,一个 `return` 都没有的纯函数式写法。 + +总的来说,代码谁都能写出来,但是把需求从文字或者是流程描述换成编码实现时就有了对程序员抽象逻辑能力的需求。如何组织抽象,就像是如何写作文,或者是 Kata(空手道里面的招数、套路),不要按照业务描述写 if else,而要尽可能简化找到一致性的简单逻辑描述。 + +如果能将所有的特殊情况变为通用情况,简化逻辑判断,那么代码在后面的迭代中也会比较易于维护。 diff --git a/src/content/posts/2017/2017-03-13-yume.mdx b/src/content/posts/2017/2017-03-13-yume.mdx new file mode 100644 index 0000000..c27c02f --- /dev/null +++ b/src/content/posts/2017/2017-03-13-yume.mdx @@ -0,0 +1,36 @@ +--- +title: 夢 +slug: yume +date: 2017-03-13 14:46:57 +updated: 2019-05-18 18:46:18 +tags: + - 梦想 + - 日文 +category: 杂思 +cover: /images/2019/05/2019051408062596.jpg +summary: 「あなたの夢は何ですか?」この質問はよく聞かれている。違うときに、同じ人は違う夢を追う。いくつになっても夢を持ち続けているとハッピーですよね。 +--- + + + +「あなたの夢は何ですか?」この質問はよく聞かれている。違うときに、同じ人は違う夢を追う。いくつになっても夢を持ち続けているとハッピーですよね。そんな夢に向かって何か努力をしている人って輝いていますよね。 + +> “你的梦想是什么?”常常会被问到这样的问题。在不同的时期,同一个人有着不同的梦想。无论有几个梦想,不断追寻梦想的过程是快乐的。向着梦想努力的人是光荣的。 + +私の夢は世界一周することです。いろんな人と出会って、違う景色を見て、人生の経験を豊かにしたいです。そして、おいしい料理を食べたいです。旅行のとき、違う生活を体験できるので、とても面白いと思います。 + +> 我的梦想是环游世界。想认识各色的人、观赏各异的景色、丰富人生经历。还有,也想品尝各地的美食喔。旅行的时候,可以体验不同的生活,我觉得是非常有趣的。 + +もしそれをするとしたら、まず元気な体、十分なお金と周りの人のサポートが必要だと思います。だがら、この夢の実現ために、スポーツをしたり、一生懸命に働いています。そして、外国人と交流できるように、外国語を勉強しなければなりません。 + +> 如果我要实现这个梦想,我觉得首先要有健康的身体、足够的资金和周围人的支持。所以,为了实现梦想,我要锻炼身体、拼命工作。除此之外,为了能跟外国人交流,我必须要努力学习外语。 + +人々は自分の夢がありますが、実現できない人が多いですね。現実は厳しいのに、いろいろな人は夢の実現が難しいと思ったら、放棄しますが、わたしはそんなことはしません。 + +> 人人都有自己的梦想,但是,很多人并没有实现自己的梦想。因为现实的残酷,很多人认为自己很难实现梦想,从而放弃了。我是不会这样的。 + +皆さんの夢は何ですか?もう実現しましたか?どうしても、絶対に自分の夢を諦めないでください。一緒にがんばってね! + +> 大家的梦想是什么呢?已经实现了吗?无论如何,请坚决不要放弃自己的梦想。让我们一起努力吧! + + diff --git a/src/content/posts/2017/2017-05-13-springboot-brief-intro.mdx b/src/content/posts/2017/2017-05-13-springboot-brief-intro.mdx new file mode 100644 index 0000000..a2271ac --- /dev/null +++ b/src/content/posts/2017/2017-05-13-springboot-brief-intro.mdx @@ -0,0 +1,236 @@ +--- +title: Spring Boot 简介 +slug: springboot-brief-intro +date: 2017-05-13 12:51:59 +updated: 2020-03-01 18:05:31 +tags: + - Spring + - 演讲 +category: 编程 +cover: /images/2019/05/2019050913525690.jpg +summary: 第一次使用 Springboot 应该是15年年底,当时就被这种约定大于配置的设计惊呆了。那个时候才从上一家公司跳槽,用的是 Spring 3。 +--- + +第一次使用 Springboot 应该是15年年底,当时就被这种约定大于配置的设计惊呆了。那个时候才从上一家公司跳槽,用的是 Spring 3。所以每次开发新项目的时候,配置起来都让我十分痛苦,也因此喜欢上了 Springboot 的种种便利。 + +众观 Springboot 的发展,可以发现,其在简化开发上不断地进步。很多常见的组件框架也有了 Springboot 版本。我想,作为 Java 程序员,是时候进入 Springboot 的世界了。 + +这里分享一份一年前,我在公司内部分享上用的 Slide,以期对于阅读此文的你有所帮助。 + + + +大家好,今天由我来向大家简单介绍一下 Spring Boot 相关的内容,详细的与 Spring Boot 相关的知识将后面由吴一敏同学分享。 + +首先自我介绍一下,我叫盛宇帆,15年年底加入 OneAPM,现在已经1年多了,目前主要负责和告警引擎相关的开发。 + + + +Spring 官方的博客介绍 Spring: **Spring** is the **“glue”** in your application。我认为 Spring Boot 就是 A glue in Spring Framework。 + +相信大家都经历过配置 Spring XML 的阶段,十分痛苦地去配置一个 Bean,后面 Spring 3发布之后,基本上很多配置都是通过注解加扫包去配置初始化。 +我常见到的一种配置方式,就是和 Spring 框架集成部分的配置,如数据库啊,Web 模板一类的,使用的是 XML,自己项目的 Service、Dao 等类,使用注解初始化。 +后面 Spring 4开始流行 @Configuation 注解的配置类初始化配置。 + +然而,这样子还是十分麻烦,所以才有了 Spring Boot,它给我们最直观的感受,就是 简化了配置。一言一概之,约定大于配置。 + +然而,仅有这些,并不能说明为何现在 Spring Boot 开始流行,说道 Spring Boot 的兴起,我想起前几天一个技术群的提问:为什么 Spring Boot 应用倾向于打 fat jar 直接启动,而传统的应用倾向于打 war 包从应用容器启动? + + + +Java 应用部署于应用容器中,其实是受到 J2EE 的影响,也算是 Java Web 有别于其他 Web 快速开发语言的一大特色。一个大大的 war 压缩包,包含了全部的依赖,代码,静态资源,模板。 + +在虚拟化流行之前,应用都是部署在物理机上的,为了节约成本,多 war 包部署在一个 Servlet 容器内。 + +但是为了部署方便,如使用的框架有漏洞、项目 jar包的升级,我们会以解压 war 包的方式去部署。或者是打一个不包含依赖的空 war 包,指定容器的加载某个目录,这样所有的war项目公用一套公共依赖,减少内存。当然缺点很明显,容易造成容器污染。 + +避免容器污染,多 war 部署变为多虚拟机单 war、单容器。 + +DevOps 流行,应用和容器不再分离,embedded servlet containers开始流行 Spring Boot 在这个阶段应运而生。于是项目部署变为 fat jar + 虚拟机 + +Docker的流行,开始推行不可变基础设施思想,实例(包括服务器、容器等各种软硬件)一旦创建之后便成为一种只读状态,不可对其进行任何更改。如果需要修改或升级某些实例,唯一的方式就是创建一批新的实例以替换。 + +基于此,我们将配置文件外置剥离,由专门的配置中心下发配置文件。 + +这也是我们为何要学习和使用 Spring Boot 的背景,我觉得这才是 Spring Boot 开始流行的主要原因。 + + + +总的来说 Spring Boot 有以下几个特点。 + +1. 配置简化,这个我印象最深刻的就是写 MyBatis 的时候,一堆东西要配置,一般大家都会用那个 Generator 去生成。而实际上 Spring Boot 推崇 jpa,如果只是简单的 CRUD,用 Spring Boot + JPA 的方式简单到只需要几行关于数据库的配置就好了。 +2. 自动配置机制,很多教程都称它为 Magic,基于项目的某些条件,自动初始化装配必要的 Bean,稍后会在后面的演示中详解。 +3. Starter 本质上就是 Spring 基于 Gradle 和 Maven 这两种构建工具定义的一组依赖,一般是按照功能或者框架划分。在有了自动配置的机制下,我们只需要依赖 Starter 指定的坐标,和非常简单的属性配置即可集成我们想要的框架。 +4. 嵌入的 Servlet 容器,主要是为了方便部署的。 +5. 主要是 `spring-boot-starter-actuator` 和 `spring-boot-starter-remote-shell` 的使用,当然,这里还可以使用 JMX 一类的做管理,大家可以参考文档。(2017年更新 remote shell 已经废弃) + + + +首先,我们来用 Spring Boot 写一个 Hello World吧,这个是仿照 Spring 官方的示例代码改的,使用 Groovy,所以连 import 都省了。这里主要是为了演示一个最简单的 Spring Boot 应用,通过下面的这行命令我们就能把它启动了。 + +```java +@RestController +class GreetingRestController { + @RequestMapping("/hi/{name}") + def hi(@PathVariable String name) { + [ greeting: "Hello, " + name + "!"] + } +} +``` + + + +现在,问题来了,刚才那个项目那么简单,那个,整个项目的启动过程中,到底发生了哪些魔法呢? + + + +我们将 Groovy 的代码翻译为 Java版本,大概会看到,一个项目想要启用 Spring Boot,关键在于 `SpringApplication` 类和 `EnableAutoConfiguration` 注解的使用。 + +SpringApplication 是 Spring Boot 提供的用于 Java main 方法的启动类。它的执行操作首先为: + +1. Create an appropriate ApplicationContext instance (depending on your classpath) +2. Register a CommandLinePropertySource to expose command line arguments as Spring properties +3. Refresh the application context, loading all singleton beans Trigger any CommandLineRunner beans + +然后 `EnableAutoConfiguration` 则为 Enable 类注解这里通过此注解,告诉 Spring Boot 开启自动装配的特性。 + + + +除了 `EnableAutoConfiguration`,我们常常和它并列使用的还有 `ComponentScan` `Configuration` 注解。这三个注解合起来,有一个等价的注解,叫做 `SpringBootApplication`,一般在我们的项目开发中,喜欢在项目最外面的包下面创建包含 main 方法的程序启动类,然后这个类上标记为 @SpringBootApplication 这个注解,这样就等价于基于 main 方法类所在的 package 为 Spring 扫包的基础包路径,且开启自动化配置。 + +自动化配置的实现,不得不说 Spring Boot 本质上是通过 Conditional 类注解来实现的。 + +`@ConditionalOnClass` 表示对应的类在classpath目录下存在时,才会去执行注解所标示的自动配置类或者自动配置方法,与之对应的我们就@ConditionalOnMissingClass 注解,也就是找不到对应的类的时候。 + +`@ConditionalOnBean` 和 `@ConditionalOnMissingBean` 则同样很容易按照字面意思理解。 + +当然 `Conditional*` 注解不仅仅上面提到的这些,还有 `ConditionalOnExpression` 一类的。 + + + +这个是我们从 Spring Boot 当中节选的一段代码,主要是为了演示自动化配置的具体实现。首先我们在项目配置里面标明 spring.jmx.enabled = true,ConditionalOnProperty 注解生效,然后 Spring 发现能找到 `MBeanExporter.class` 这个类,于是开始执行自动化配置的方法,因为这个时候项目中没有定义 `MBeanExporter` 这个 Bean,于是 `ConditionalOnMissingBean` 注解生效,Spring 开始读取配置属性,自动创建此 Bean 对象。 + +同理,任何一个自动装配的实现,基本上就是组合这些条件注解。 + + + +当然,如果能被 Spring Boot 官方直接支持的话是最吼的,目前被支持的肯定不止上面这些,我只是简单地列举了一些常见的项目。 + +Spring Boot 官方之前发起过好几次投票,就是列举一些框架,然后大家投票选择哪些想要被官方支持的。上半年的时候,我还在里面看到了之前姜老师维护的 camel,然而似乎并没有被选中。MyBatis 目前虽然有 Spring Boot 版,但是是由 MyBatis 团队自行维护,至少我6月份尝试使用的时候,问题还是蛮多的。 (2017年之后的版本基本可用,主要是有了 Boot 版本的 VFS) + + + +上面是我从 Spring Boot 1.3.6 中找到的 spring.factories 文件的截图。当然,基本上只要上面有的,都能得到不错的支持。 + + + +前面我们简单介绍了自动配置的实现原理,基本上流程就是配置文件标明启用什么服务,然后找到对应的依赖(class),然后结合条件装配初始化 Bean。 + +所以 Spring 就更进一步,按照功能模块,划分出一个个 Starter 模块。以 Maven 为例,基本上我们只需要将 Spring Boot 自己的那个 POM 文件设置为 parent,然后依赖中直接依赖所需的 Starter 坐标,即可依赖所有所需的 jar 包,剩下的的东西,仅有最基础的属性值配置。 + + + +当然 Starter 也是一把双刃剑,比如我在项目里面依赖了 `spring-boot-starter-data-jpa` 之后在 IDEA 里面看到的依赖树,简直就是 jar 包狂魔,虽然我们需要 jpa,但是不一定需要全部这些包。 + + + +这也就引出了我使用 Starter 的时候的几个困扰。比如项目需要以 spring-boot 的 pom 为 parent,这个就比较讨厌了,尤其是我前公司,所有的项目是同一内部的 parent,这样子可以管理大家的依赖。如果要用Spring Boot 的话,就会略有麻烦。可能就需要通过依赖 Spring Boot 的 pom 的方式,并不是很优雅。 + +问题二是我在用 Spring Boot 时依赖 logstash 遇到的, logstash自己依赖了一个 logback-access 和那个版本的 Spring Boot 依赖的 logback 不一致,导致一直报一个 `java.lang.AssertionError` + +问题三就是我最近想用 Spring Boot 去读写 Kafka,结果我们用的 Kafka 版本比较老,最后只好自己配置,特别麻烦。很多老的组件,要么你得用老的 Spring Boot,要么你就得自己配置。 + + + +比如我们基于 YAML 定义了上图这么一段配置,最简单的方式就是 `@Value` 注解,通知这货还支持 Spring El 表达式,做一些简单的处理判断。 + +但是对于一个组件的配置,或者是项目自己的配置,更需要比较好的梳理,Spring Boot 便支持了所谓的 prefix 前缀的概念,我们可以把所需要的配置信息定义为一个配置类,在里面定义好必要的 Getter Setter 一类的东西。在初始化项目的时候使用 `@EnableConfigurationProperties` 注解即可实现配置参数注入到配置类里面。 + +当然麻烦的地方在于如果配置文件定义的层级过深,配置类会变得极其复杂。建议这种情况下,尽可能简化层级。 + + + +配置文件的加载,其实 Spring Boot 有一个非常复杂的流程,大家好奇的话可以看 Spring Boot 文档中的定义,大概有十几种情况。但是大部分情况下,我们用不了这么多,上面是我认为应该知道并且利用的几种情况,配置加载的顺序是由上往下。 + +第一种情况,和 jar 包在同一目录下,一般是应用发布到生产,然后还想修改更新配置的情况。 + +项目 resources 目录和 resources/config 下面的配置文件,就是我们在开发的时候会选取的存放配置的位置。 + +当然配置文件的名称默认是 application,还可能根据你所启用的 Profile 加载不同名称的配置文件。 + +由于配置文件的指定在 Spring Boot 中极其灵活,(官方可能把所有的情况都考虑到了)所以大家可以自己按需选择。 + + + +测试当然也有 Starter,我们只需要依赖 `spring-boot-starter-test`,即可轻松写测试。常见的测试注解就是上面几个 + +`@WebIntegrationTest` 注解相当于 `@IntegrationTest` + `@WebAppConfiguration` 注解结合使用,在 1.3 之前,主要是使用前面4个注解进行测试。 + +1.4 之后,我们主要使用 `SpringBootTest` 注解做测试 + + + +最老的方式,你可能会使用 `@ContextConfiguration` 注释和 `SpringApplicationContextLoader` 的组合去写单元测试。 + +当然,我们可以去掉 loader 的配置,使用方法2 的 `SpringApplicationConfiguration` 注解去测试 + + + +当想写一个集成测试的时候,可以使用 `IntegrationTest` 注解,和前面的不一样的是,前面两种方式不会初始化全部的 Bean,而 `IntegrationTest` 会和生产环境一样,完整初始化程序。但是它不会初始化 嵌入式的 Servlet 容器。 + +当你需要嵌入式的 Servlet 容器做一些接口的集成测试的时候,就需要使用 `WebIntegrationTest` 注解 + + + +然而一个项目,基本上包含 `SpringApplication` 和 main 方法的类只有一个,所以在1.4 之后,我们连 App.class 都不需要给定,直接使用 `@SpringBootTest` 注解即可,更加优雅。 + + + +这个就是我基于 Spring Boot 1.3 写的一个集成测试,当然它使用的是我们前面说的方法3。 + + + +前面我们其实已经说到了 Spring Boot 的 `Profile` 可以让我们区分不同环境下加载的配置文件。比如开发环境,测试和线上,很多值都可以实现定制,而不需要重新打包项目。 + +使用 Profile 的第二个场景就是不同的 Profile 需要初始化不同的bean,比如以 DataSource 为例,测试的时候,因为测试环境不一样,我们更期望 DataSource 能用 H2一类的嵌入式数据库模拟。开发和生产环境,就需要初始化一个 MySQL 的 DataSource。当然我说的这个场景不需要我们专门去配置,因为 Spring Boot 已经替我们考虑到了这种情况,在需要 DataSource,但是没有这个 Bean,切依赖了 H2的 Driver 的时候,Spring 会自动创建一个 H2 的 DataSource。 + +还有一个我使用 Profile的场景就是 Swagger,它十分好用,尤其是开发的时候能基于注解自动生成 API Doc,和测试页面,然而,会存在的问题就是它有漏洞,我只希望在开发的时候启用 Swagger,这个时候就可以利用 Profile 来实现。 + + + +Profile 可以启用一个或者多个,然而,也会导致一些问题,比如我们没有指定 Profile 的时候怎么办,或者我们有 profile 名为 mysql、cassadra。它们是相互 block 的,如何检查校验,避免冲突的 profile 同时启用呢? + + + +这个是添加默认 Profile 的方式,原来我是尝试在 application 配置文件里面设置,但是不生效,最后我只好手动编码实现。 + + + +这个方法是和 main 方法同级的一个方法,需要 Autowired Spring 的 Environment 接口,然后获取 Profile 的配置,即可自行实现判断逻辑。(期待后面 Profile 能更加完善,实现 Block 一类的属性) + + + + + + + + + +Spring Boot 官方推崇的部署方式是 jar,原因我们前面也分析过了,但是也会存在打包为 war 去部署的需求。这里我们只需要在和 Application.class 同级的路径下继承 SpringBootServletInitializer 类去定义一下 SpringApplicationBuilder 的配置即可,还是很轻松的。我这个截图的示例里面用了前面设置默认 Profile 的方法,重用了一下代码。 + +有了这么一个类之后,我们就可以在 pom 里面设置项目打包为 war,它既能 java –jar去执行这个 war,也能直接丢到 Tomcat 一类的容器里面运行。 + +我们在 17年的实践中发现,很多时候,非 Fatjar 也有一定的意义,于是有了下属的打包启动实践,大家可以去参考。 + +https://gist.github.com/syhily/c66310c150653e8f92b9fa6693df8207 + + + +如果想要快速创建一个 Spring Boot 项目开发,有且不仅有上述几种方式。 + + + + + + + +你可以点击 [这里](https://cat.yufan.me/uploads/springboot-intro.pptx) 下载到本地浏览。 diff --git a/src/content/posts/2017/2017-06-28-atelier-firis-first-year-walk-through.mdx b/src/content/posts/2017/2017-06-28-atelier-firis-first-year-walk-through.mdx new file mode 100644 index 0000000..f69d4c0 --- /dev/null +++ b/src/content/posts/2017/2017-06-28-atelier-firis-first-year-walk-through.mdx @@ -0,0 +1,880 @@ +--- +title: 《菲莉丝的工作室》一年期主线任务流程攻略 +slug: atelier-firis-first-year-walk-through +date: 2017-06-27 23:52:42 +updated: 2020-03-01 18:03:52 +tags: + - 工作室 + - 游戏 + - 菲莉丝 +category: 文章 +cover: /images/2019/05/2019050909531558.jpg +summary: 这作不知道是不是因为变革太大,还是 BUG 太多,日版销量暴死,本人买完繁中后才看到要出 PC 的新闻。 +--- + + + +这作不知道是不是因为变革太大,还是 BUG 太多,日版销量暴死,本人买完繁中后才看到要出 PC 的新闻。果然,这很暗荣。不过到现在也没有找到很好的攻略,A9上,该板块虽然升区,但是帖子也多为日文版讨论。本着照顾像我这样的手残玩家的想法,我准备重新打一次一年期。一点点完善该攻略。 + +这作的汉化质量怎么说好呢,就我个人而言觉得有点诡异。比如,“无事发生”这个完全是等着被我们吐槽么? + +本作的狗牙完全闪瞎我的狗眼,明明那么萌的菲莉丝,用 PS4 Pro 能解锁60帧成就,PS4 下很多场景会有明显的掉帧和加载缓慢(果然 Gust 技术不到家么?) + +本人并不精通工作室,前面7作完全坑着,不信你看我的奖杯表。所以合成也不是很懂,如有不足之处,还请各位大佬指出。 + +**为何写这个:** + +菲莉丝太萌了,感觉我就像莉雅尼一样,玩此作很有代入感。写此文,主要是为了满足大姐姐我对菲莉丝的吐槽欲望。 + +其次,这作的变化让我这个“老玩家”有点无所适从。写此文带领大家度过一年期的限时任务,快速熟悉菲莉丝这作的世界观,掌握基本的游戏技巧还是很有必要的。而且,避免初期走冤枉路,毕竟,跑图很费时间,找采集点很费时间。 + +当然,姐姐我对菲莉丝的爱才是写本文的动力源泉。 + +**注意事项:** + +1. 本作的地图极其大,跑图十分累(当然地图建模、怪物建模一如既往地挫),前期探索完地图之后一定要善用传送。传送也是要消耗时间,但是比走过去要快,一周目之后出门会给你做扫把的“发想”,跑图就是飕飕的。 +2. 本作没有了传统的主城工作室,工作室都是随身携带,看到篝火就可以使用。BGM一如既往在工作室内更换,和以前不一样的是,可以叠加全部的前作,随机歌曲。换装功能在得到第一件衣服后解锁,不像爱夏一类的前作在开始 Title 处换装。装饰功能极其重要,可以用于将牛逼炸弹放置于此,二周目可以直接继承(虽然我还没打到二周目)。 +3. 在本作里不同的服装也有了额外的特性,有减少移动消耗 LP 的,有增加合成特性的。DLC 服装主要是可以增加采集的质量。 +4. 主线任务里很多 NPC 的房子到了晚上是上锁的,需要到了6点天亮了才能进去。尤其需要注意控制时间,否则,你就只能四处瞎逛到天亮。(当然,最优雅的磨时间方法是在小屋里面合成,或者愉快地做一个“采蘑菇的小女孩”,到了天亮就立刻“闪现”去 NPC 处。) +5. 本作最令人诟病的一点就是任务提示极其不友好,很多任务都不知道如何触发。索菲时代的炼金合成联想在本作的提示也令人发狂,不像索菲,可以直接从咖啡馆购买提示。 +6. 很多时候合成的素材如果忘了采集,可以从小地图上的蓝色 NPC 处购买,然而令人抓狂的是,NPC 处有时候购买的数量还是不够。 +7. 第四和第五主城的推荐书任务需要炼金 Lv 比较高,可以通过刷没有合成过的物品来快速提升等级。 +8. 一年期的任务和初期在家的限时任务的时间完全足够,但是不推荐瞎逛地图,因为后期有飞行扫把随意玩。 +9. 地图上可以通过和人聊天开启各种有意思的任务,要素,建议完成一年期后再探索。 +10. 本作可选队友比较多,但是加入队伍的人有5人上限,上场作战是4人上限。不像罗吉那作加入队伍可以有7人,如果队伍达到5人,新加入的小伙伴就需要和现有的伙伴替换,建议慎重选择。初期推荐前作的胖子(本作变帅了,我的少女心),还有那个在海滨需要5000金雇佣的那货。组队后,相关 NPC 会在工房里站着,与之对话可以解雇,还有额外剧情,能解锁 NPC 的相关技能。解雇和未雇佣的队友会出现在酒馆和旅馆里面,与之对话即可重新加入队伍。 +11. 地图上的骷髅头位置建议一年期不要去作死,除了第一幅图的狮子我用炸弹炸死之外,其他的要么是打不动,要么是被秒 +12. 一年期的考试不是很难,所以不需要刻意准备,不过推荐采集的材料品质要好点。攻略后面会特别指出。 +13. 小地图上标为黄色正方形处为宝箱,开启后可以获得装备或者素材。 +14. 工房的收藏箱物品上限是1000,但是可以合成额外的保险箱来增加上限,最高是3500个。 +15. 本文里面所有括号内的文字均为废话,可以 PASS。 +16. 其他想到了再补充…… + +## 艾尔托纳日常 + + + +开场,菲莉丝走到村门口的大门处,看着紧闭拦着自己出去的大门,叹了口气,继续回去工作。菲莉丝回到长老处,开始采集任务,主要是采集教学。 + +(从黄昏系列之后,工作室的采集就变为跑到闪着不明亮斑的地点,按 「O」 键采集,无需额外的选择采集的东西。本作最大的特色是,可以通过采集点的外观粗略判断采集内容,但是相同外观的采集点,在不同的图里面产出会略有区别。) + + + +采集两个蓝色的水晶后自动进入剧情,剧情结束后提示菲莉丝回家。回家路上菲莉丝看着拦着自己紧闭的大门,想出去不得,准备回家,遇见自己姐姐莉亚姊回来。 + +往前走自动触发莉雅尼与长老对话剧情。 + + + +两人一起回家,菲莉丝家在地图的最里面,初期跑图时容易迷路(比如我)。跑图到一半自动触发剧情,爸爸妈妈亮相,妹妹也想出去,妈妈严肃拒绝说教了一番。 + + + +第二天,菲莉丝没有工作,姐姐也出门了,于是准备出去看看 [南方的光芒照耀之地],眺望天空。 + +跑到截图处,触发剧情,此处为村庄内唯一一处能看到天空的,菲莉丝一直未出去过,所以对外面的世界十分向往,自然地对于这唯一的一方阳关照耀之处也十分喜欢。 + + + +与姐姐吵架之后,菲莉丝准备去门那边看看。触发剧情,遇见前作的(村姑)苏菲,菲莉丝带着苏菲去家门口空地搭帐篷。进入苏菲的工房(帐篷)之后,菲莉丝第一次见识到炼金术的神奇,产生了极大的兴趣。 + +(没有了托托莉、梅露露、爱夏等前作里面经典的爆炸桥段,我好伤心。虽然一年期之后补全了这个遗憾,因为菲莉丝想继续旅行无心工作导致合成失败爆炸。) + +剧情完毕之后解锁桌子和炼金釜,提示菲莉丝合成“无事发生”,也就是炼金教学剧情。炼金教学对新人更友好,分为两个剧情,目前只是让你选择材料和简单图例。 + +(此作和前作的合成形式上大致还是相似,类似的拼图游戏,不同的是,本作增加触媒的概念,也就是材质能覆盖触媒的话能解锁额外特性。触媒的颜色如果是白色,表示它不关心覆盖的材料的颜色。如果触媒的花纹有别的颜色,则需要特定颜色的材质。) + +如果安装 BGM DLC,此时还不能从桌子处更换。点击桌子目前只能存档,回到标题。 + +合成结束后有一大段剧情,菲莉丝回家睡觉,第二天出门后看见苏菲向村民兜售炼金产物。菲莉丝发现炼金术好厉害哦,合成的东西理论上可以让她出门不怕魔物,于是决定向苏菲小姐姐学习炼金术。然而,父母知道菲莉丝想通过学习炼金术出门之后,毅然拒绝了。(可怜天下父母心啊)与父母吵架后,菲莉丝哭着跑到大门,向苏菲述说了对外面世界的向往。苏菲十分感动,(多么单纯的孩子,就让我来教坏她吧。)于是决定当菲莉丝老师,教她炼金术。 + +回去的路上遇见村长和姐姐,村长下发了课题,用炼金术在一定期限内帮助村里人,只有证明菲莉丝炼金术水平才能让她出去玩。于是菲莉丝正式开始和苏菲老师学习炼金术。 + +(梅露露里面,虽然父皇不同意,但好歹托托莉老师亲自去帮助梅露露说情,而且定下了3年期国家建设。这里姐姐大人说情,村长大人代替父母向菲莉丝下发任务的设定有点违和。而且这简直是阿尔兰系列就玩烂的套路啊,罗罗娜是托托莉老师,托托莉是梅露露老师,目测菲莉丝是下作女主的老师。) + +进入第二次正式炼金教学环节,这里主要就是教我们怎么“拼图”,和触媒初探。合成后苏菲提示菲莉丝出去寻找大家的困扰,通过解决大家的问题来在实战中提升自己,一举两得。 + +此处需要对话的 NPC 有三个人,靠近需要对话的 NPC 时,该人头上会自动有话语提示,十分好找。 + + + +第一个为直接南下遇到的红衣女子天亚,开启任务“柔皮液的治疗方法”。 + + + +第二个为继续南下遇到的“膝盖中箭男子”丹尼斯,开启任务“腰疼的治疗方法”。 + + + +第三个为往右侧岔道走处遇到的歌尔特对话,开启任务“坚\~硬岩石的破坏方法”。 + +使用教学里面的捷径回到家门口,进入工房和苏菲对话,习得调合发想系统。 + +(在菲利斯达成一定的条件后,比如使用一定次数的爆弹诸如此类,可自动发想领悟新的制作道具的配方。发想条件可以在系统菜单“配方笔记”中查看。部分带问号的发想配方虽然未达到条件,但可以使用发想点数解锁。但是,这个点数实际上是非常珍贵的,因为后期很多重要材料条件十分苛刻,用发想点数解锁省事,所以前期这些简单材料,能省点数就尽量省。) + + + +菲莉丝出门找人对话获得炼金灵感,从这时开始推荐善用大地图标记任务,小地图跑图。按 「Touch Pad」 进入大地图,「L1」、「R1」 切换到任务栏,点击任务即可在地图上标记。方便小地图跑图时,查看是不是跑对位置(我只到玩到很后面的时候才知道这个技巧,大雾。) + + + +和工房门口的老太太对话,提示去采集“妖精的阳伞”。后得知“妖精的阳伞”对于治疗腰疼有奇效。 + + + +工作室后方的楼梯上就有我们要采集的材料,这个游戏的设定里面,就是需要采集的东西不会满世界跑,一般就在任务 NPC 旁边,不要和我一样满图跑。 + + + +”妖精的阳伞“的另一个更新点,就是最西边的小男孩处,需要注意的是,工房后面的刷出来概率不如这个点高。此处基本是100%出。 + +不断进出工房,刷这两个位置,即可集齐三个”妖精的阳伞“。(此技巧在后面的很多材料采集的时候也十分有效,因为时间完全足够你这么任性。)与老太太对话,发想获得“艾尔托纳软膏”的调合配方。当然这里建议收集6个以上,3个交任务,其他的用于合成。 + +在老太太旁边的井处按 「O」 打水,获得”无事发生“和“艾尔托纳软膏”合成必需品水。 + +(本作不像苏菲等前作,一天只能在井水处取一次水。可以多次取水,我们这里最少取水两次。) + + + +无事发生的另一个合成材料是纸张,这里请在村子里瞎逛,按 「口」 打碎房子旁边纸箱获得。 + + + +在跑图的路上一边愉快滴采集,一边打碎纸箱搞破坏,我们跑到了大门处,和旅行商打扮的大哥哥对话后得知在坑道深处破坏石头可以获取火岩石。(来制造爆炸的东西) + + + +用 「Touch Pad」 开图传送至光芒照耀之地,开启奖杯,然后继续南下去坑道打石头,获取”火岩石“和”自然矿物油“。分别为”炎烧“和”艾尔托纳软膏“的合成材料。这里建议稍微多采集一点火岩石,避免来回跑图,很累。 + +(前期只能用权杖敲石头,又慢又浪费时间,后期发想出道具十字镐的时候一定要合成,采集神器。) + +传送回工房,发想出炎烧,开始合成”炎烧“和”艾尔托纳软膏“。先合成”炎烧“和”无事发生“提升炼金等级,合成成功后触发剧情,妹控姐姐大人进来抱怨:“妹妹大了,不理姐姐了,姐姐好伤心。”为什么我瞬间想到了点兔里面的爱酱,简直完全一样。 + +继续合成,完成”炎烧“和”艾尔托纳软膏“的合成。期间触发剧情,姐姐大人和妈妈大人的关爱,“饼干”Get。全部合成后触发前作的吐槽,玩过苏菲的名那也许会会心一笑,没玩过的可能就直接懵逼了。 + + + +传送至“住宿:光辉水晶亭”,下来往南走,紫色水晶处即可与姐姐大人对话,获得柔皮液的制作大法。继续往南走,顺便把“艾尔托纳软膏”交付给腰痛的大哥哥,触发剧情(这里的菲莉丝萌死我了,“好像有个开心得不得了的女孩呢”)。 + +转头朝西北方向,将炎烧交付给另一个发型杀马特的大哥哥。触发剧情,从苏菲那得知还有炼金术师考试这么一茬,还需要三封推荐信。顺路采五个蘑菇回家,用于合成柔皮液。触发剧情结束后,发想出“中和剂 · 蓝”。 + +交付柔皮液,传送回工房合成一个炎烧,中和剂蓝也可以顺便合成一下。合成期间会自动触发一次剧情,菲莉丝对于工作室为何这么大的疑问。再合成一次后退出合成,会触发剧情,村长找上门来,要求菲莉丝帮忙打败野生噗尼,为其私房钱而战…… + + + +装配上前面合成的炎烧。传送至挖掘区入口,地图上标记好任务位置,用炎烧炸死即可。 + +返回工房,村长允许菲莉丝到外面世界去,但是需要在1年内取得公认炼金术师资格,就这样菲利斯和莉雅尼两人一起上路。这里和父母的重归于好、告别感动死我了。(实际冒险开始时的倒计时是361天,Gust 不会数数系列。) + +和以前的作品们一样,教学关卡结束。进入 OP 环节,卧槽,为何不是中文歌。 + +## 干枯平原带漫步 + + + +地图 + +(这张图本质上是给新老玩家初次熟悉大地图准备的,并不是很大,且无主线任务,初期一年期的时候可以直接南下去开主线,沿途可以采集点东西。**但是在造船的剧情里面需要40个金属,一般推荐合成大量炎烧,在右上角的迷宫前面,有三个蓝水晶炸开获取,运气好的话,一次可以炸出7个来。**所以,到时候你就得痛苦地跑图回来炸。) + +出门后,苏菲和菲莉丝告别,将工房送给菲莉丝。菲莉丝决定和姐姐大人一起踏上去莱森堡考试的道路。(姐姐大人十分开心,终于没人来和我抢菲莉丝了。) + + + +往前走几步,会有篝火教学。建议立刻在不远处的篝火处搭建工房,会有 LP 教学,LP 如果低于0,就会强制休息,低于50,采集、战斗的效果都会降低。此时的工房已经解锁 BGM 更换,同时菲莉丝发想出十字镐和中和剂 · 红。 + +(LP 的回复主要是在工房休息或者是花时间合成道具恢复,个人倾向于使用后者。既能合成道具提升炼金等级,又能恢复 LP和血量。) + +出门前,确保有一个“无事发生”没有装备放在包裹里。出门后,朝小地图右上角的白色 NPC 处走去,会触发战斗教学。与 NPC 对话,开启任务“前辈的委托”,用一个无事发生换取两个爆破用炎烧。 + +(菲莉丝这作的任务里面需要的物品,有部分是接了任务之后获取的才算,需要注意任务描述是否有类似 [0/1] 的字样。) + +告别 NPC 后朝南走就有“野棉花”可以获取,记得采集。 + +完成任务“前辈的委托”之后的“前辈的激励”更像是物品使用教学……完成任务报告给 NPC,触发任务“前辈的报恩”。 + + + +在旅行商处往东侧直走,朝小地图上骷髅处的狮鹫走去,触发任务,不知畏惧。可以直接用“爆破用炎烧”打败此处的狮鹫,获得触媒狮鹫的羽毛。 + +(姐姐只管给自己和妹妹使用道具加血,妹妹用“爆破用炎烧”炸三次即可轻松打过。) + + + +继续往东走,在东北处篝火旁边用炎烧炸蓝色水晶获取金属类素材(建议进出工房炸5次,后面主线任务需要),同时完成任务“前辈的报恩”。(地点参考本页的完整地图) + +(这里虽然推荐用爆破用炎烧,但是普通炎烧也是可以的。所以爆破用炎烧还是拿去打怪好,目前很难合成出这种伤害的炎烧,当然后期另论。) + +回来报告任务后,继续往南走,会看到绿洲提示你采集三个水,还有“荒野之绿”,提示你采集三种颜色的花,基本是顺着大路一边走一边做,属于流程任务。 + +顺着大路走会遇到一个红衣大姐姐,与之对话接受“危险的绿洲”,打三只沙漠龟,基本平 A 即可,无需浪费炸弹。 + +继续往南,可以看到绿普尼和舔舔菇,讨伐即可完成初期的讨伐任务,需要注意的是舔舔菇只在白天出没。 + +(菲莉丝里面部分 NPC、怪物等只在白天或者夜晚出现,有时候你走过去,因为恰好过了时间,就只能眼睁睁看着他在你眼前消失。比如前面说的红衣大姐姐,只在白天出现。) + +一边走一边打怪,搭建帐篷几次后,会自动触发剧情,一位不知名的剑士留下坏的钥匙希望菲莉丝用炼金术修复。修复钥匙需要炼金 Lv 10,后面等级达到修复钥匙后,该 NPC 会自动上门并想加入队伍。即可在酒馆邀请组队,该角色攻击一般,主要给力点在于平 A 的时候有机会触发两次攻击,还有给全队加防御的技能。还有,肉盾效果不错,建议用他挡伤害。 + +继续南下,会遇到第三个 NPC,与之对话开启任务“苏菲的药秘密”,给他一个“无事发生”完成。(得了便宜还在那哔哔你的药不如苏菲。) + +## 广茂的法维丘陵 + + + +地图(岩中隧道是一条每次通过都需要炸开的近道,推荐从下面走) + +从干枯平原带出来,到达地图法维丘陵,剧情后解锁世界地图。本图正中的村落可以获取到菲莉丝的第一份推荐书。 + + + +往南走,遇到冒险者,与之对话获取任务“干草多得很”,交付三个红麦面包,获取简单的干草做法。 + + + +采集大哥哥旁这种图示的作物,获取红麦(这里任务需要,至少采集4个),稍后回到工房后即可解锁红麦面包。 + + + +红麦面包的另一个合成必要材料是蜂蜜,通过击打大哥哥左侧的苹果树获取蜂巢来合成。(鄙人一周目的时候,为了找蜂巢可是几乎跑遍全图,采集地上的黄花,因为它会随机出蜂巢。没想到100%出的地点藏在这。) + + + +屋后可以采集到核桃或者海胆。 + + + +大哥哥右侧的树敲打可以获取海胆或者核桃。 + +此时的采集足够合成红麦面包,在篝火内合成即可。如果此时你的炼金等级不够,可以先合成蜂蜜、麦粉等,将等级刷到 Lv 8。交付完红麦面包往南走,走到桥处,触发剧情,介绍天气系统。 + +这个时候你会遇到一个移动旅行商,小地图上为蓝点,本作小地图上的蓝点均为商人。如果你钱不少的话,可以从他这里购买到德娜的木材(后面剧情需要,十字镐的合成也需要。)不过,即使不购买,也可以在地图右侧的小河边捡到。 + +沿着大路一边打怪一边采集,来到村落缅亨。自动触发生剧情,遇到天才炼金术师伊尔梅莉亚,后期菲莉丝的好姬友就这么相遇了…… + + + +剧情结束后不要急着移动,先和图中右侧的老太太对话,询问公认的炼金术师情报。我特么在这个地方卡了5天(游戏时间),直到后面查找日文攻略。 + + + +与老太太对话完毕之后直接向东走,过了桥,左手边的第一栋房子就是迪翁的工作室。(本作各个炼金术师们的房子从外观上看,辨识度还是蛮高的。除了最后一个图,雪山里面的村庄的工房之外,其他的都是门口一个黑板的那种) + +需要注意的是,去见迪翁需要在白天,也就是6:00 \~ 18:00。这个时候地图的传送已经包含篝火,善用篝火+地标的+NPC 的传送能节省时间,避免黑夜无法交任务。 + +进入工房,迪翁要去忙着修理风车,将两人撇在一边,于是两人决定跟上去看看。(记得善用小地图标记任务,能标记的我就尽量不截图标明位置了。) + +两人看见修好风车的迪翁,向其说明来意,迪翁欣然同意,但是需要先考察菲莉丝的炼金水平。这时遇到寻求帮助的村民,迪翁无法抽身,菲莉丝决定帮助迪翁来解决村民的烦恼。(真是好孩子啊,姐姐我喜欢。) + + + +与修好的风车旁边的杀马特大叔对话,开启“逃走的牛牛”任务,牛牛需要美味的干草才会跑回来。所以前面任务获得的干草发想派上了用场。(该杀马特大叔,只出现在白天。) + +(本攻略未标注白天的任务,基本是不限时间。) + + + + + +在旁边的工房合成干草,一路向西边走,在牧场入口处会看到截图所示的发光处,将干草放置于此即可,贪吃的牛牛就会跑回来吃草。(PS,截图里面的小女孩,与之对话,会开启小任务,一年期之后再来解决。) + + + +交了任务后,过桥往东北方向去帮大妈妈收集水果,可以顺路看到提亚娜,与之对话,获得艾森磺。 + +与大妈妈(她只在白天出现)对话完之后从南方绕一个圈,即可看见第一、第二果园,开启剧情后即可收集,记得和前面的蜂巢一样,是敲击苹果树,不是捡地上的。(我收集了两天后觉得不大对,才发现……) + +(交任务物品技巧:先按 「△」 选择品质排序,然后从后往前选,按住 「O」 不要松开,然后按住 「右方向键」 不要松开,会自动选好。) + +完成任务后,记得在白天去找迪翁报告。结果还没说几句话,就有人跑来说,刚才修好的风车又出了故障。菲莉丝跑去凑合闹,被迪翁拜托制作风车零件,然而,却没给菲莉丝制作方法。 + + + +迪翁的炼金工房南边的房子外侧,有一位白天黑夜都干活的“不知疲倦男”,过了桥右手边就是。与之对话,提示去工房里找找笔记。 + + + +进入工房,在炼金釜正后方问号提示出获得配方。 + + + +游星齿轮合成需要德娜的木材、金属类素材、粘土类素材。德娜的木材可以直接在“城中的篝火”东侧的旅行商处购买获得。 + + + +如果你和我一样舍不得花钱,请继续沿大路往东走,走到小河边往北走,看到一座木桥,下了桥往北走,即可在河边打碎树干获得。(人穷志不穷) + +合成完游星齿轮,去迪翁的工房报告。(需要在白天)然后去坏了的风车处于迪翁对话,交付材料后获得第一封推荐书。 + +去下一张图的方式在本页最初处已经说明,像我这种舍不得炸弹的穷屌丝自然是选择绕远路。从刚才修理风车处的大路往南走。一边采集一边打怪,到了尽头过桥后一直朝东方走即可到达旅人的杂木林,期间会看到一个篝火,下个图起点到篝火的距离比较大,建议补充满 LP。 + +本图到此结束。 + +**PS** + + + +1、理论上本图菲莉丝的炼金 Lv 与素材等足够修复“怪人”的钥匙,合成后触发剧情,认识队友雷比,菲莉丝的第一个队友。 + + + +2、在小镇的回转牛厂里,可以邀请雷比为队友。 + + + +3、理论上本图菲莉丝的炼金 Lv 与素材足够合成**十字镐**,记得合成,便于采集。合成之后,记得在主菜单的“战斗装备”里选择菲莉丝,在探索一栏内装备。装备之后可以按 「左方向键」、「右方向键」 来选择十字镐,切记切记。 + +4、理论上本图菲莉丝的炼金 Lv 与素材足够合成**探索用煤油灯**,菲莉丝装备之后无需选择,在洞穴里面自动生效。(虽然我觉得这个的用处不是很大。) + +## 旅人的杂木林 + + + +还算比较完整的地图 + +(此图很多位置是水路,需要一年期之后合成扫把才能通行。参考下面的世界地图后会发现,此图比较复杂,会有五条对外通道,呈五角星分布。一年期我们要走左下角的出口去南方原野,目的是正好顺着去生命之森。) + + + +世界地图 + +(**旅人的杂木林**北接**宁静之森**,西接**法维丘陵**,东接**郊区的小道**,南部与**南方原野**和**白雾之森**接壤,是十分重要的交通要道。 + +**宁静之森**主要是支线剧情图,整个地图和蚊香一样,物产也不是很丰富,一年期不建议在此图浪费时间。 + +**生命之森**是重要的采集地图,此图的怪物也不算太强,采集的材料后期均有大用,比如金丝,比如德娜的木材。 + +**白雾之森**内可以获得第二封推荐书,第一件时装,建议顺着**生命之森**去。 + +**郊区的小道毫**无任何探索价值,只为三岔路。) + +进图后先沿大路朝东方前行,到达第一个篝火处,与篝火旁的老妇人,交付一个海胆蛋即可。 + +篝火处顺着大路往东南方前行,自动触发剧情,与见识院院长“安涅莉斯”初遇。 + +继续往南走,过了桥之后略往西南处前行,会自动触发任务美味的蜂蜜,放置五朵 Hana(花)结束。 + + + +(黄金树之叶的采集点,切记一定要过来。) + +继续往南走,见到第二个篝火。建议在此修整之后,一路往西,到达出口附近时,我们可以往北走,会遇见第三个篝火,然后继续往北,用十字镐打碎拦路石头,在此采集黄金树之叶,记得采集4个以上,后面剧情需要。 + +本图结束 + +**吐槽:** + +本图场景各种掉帧,场景加载慢,Gust 药丸。 + +## 危险的南方原野 + + + +(如标题所属,南方原野是一张比较危险的地图,也没啥物产。一年期没有飞天扫帚,很多地方都到达不了,左下角的地方目测是水下剧情?) + +(这张图和前面那张图一样,都属于过渡图,加上怪物普遍比较硬,刚不过去。建议一年期后再来慢慢磨。我们这里就直接朝着右下角的生命之森前进即可。整张图里面的噗尼为比较容易打的怪,建议有多少刷多少,升级神怪。) + +首先往西南方向前行,到达第一个篝火,一路上可以顺便虐虐可爱的噗尼们。(感觉这个已经和史莱姆没啥区别了,其次为何中文怪物名和海王星里面的那么像) + + + +篝火旁的小男孩(仅在白天出现),与之对话开启任务“如同树一般的矿石”,需要交付一个漆黑倒木石。 + + + +漆黒倒木石,采集处稍微有点远,在篝火的正南方有一个小湖泊,地上有破树干,打碎即可获得。(此物在白雾之森的产量比较可观) + + + +小屋西面的动物遗骸采集后会获得“动物皮革”,结合柔皮液可以用于合成背包,方便我们多采集。后面水潭边比较多,但是怪物都比较强,打不过…… + +继续往南方走去,一路炸弹开道,顺便欺负欺负可爱的噗尼们。路上会遇到很多狮鹫,建议绕开它们。到达观景点大湿地之后,转而向东南方向跑,即可找到出口到达生命之森。 + + + +行走路径如图所示,建议不要走冤枉路,不要被狮鹫欺负惨了。 + +本图结束 + +## 富饶的生命之森 + + + +(如前面所述,此图物产太丰盛了,一年期,我们水平走至最右方完成必要的收集和剧情即可) + +第一次进此图会触发剧情,菲莉丝遇见前作男生奥斯卡,剧情结束后奥斯卡可以加入队伍。 + +(卧槽,奥斯卡你怎么变帅了,果然是一瘦遮百丑。摸摸自己的小肚子) + + + +(Tips:后面造船时需要大量木头,这里尽可能多收集一点,用十字镐砸木头比较轻松。其次,红色类似食人花的植物处收集可以获得金丝,**记得在造船后的背包里面一定要留有3个**。 + +地图上蝙蝠初期如果等级不够,比较难缸,建议直接炸弹流,雷比和菲莉丝可以使用炎烧、爆破用炎烧等,姐姐可以用卡夫、海胆袋等。) + + + +一路往东走,一边走一边采集,地图上的怪能打就打,刷刷等级。完整探索路径如上,进入白雾之森。 + +(一路上只有开始有篝火休息,后面全部没有,建议尽量避让怪物,多采集,尤其是在一开始合成扩充背包是王道。) + +本图结束 + +## 古朴的白雾之森 + + + +地图 + +(白雾之森是一个不算太复杂的地图,其特色就是大。如果是从旅人的杂木林到这张图,很容易错过这张图的村庄,错过第一件极其有用的时装。所以,这也是为何要从生命之森过来的缘故。) + + + +进入白雾之森,自动触发剧情,遇见一位容易迷路的武士少女多萝瑟尔(胸部比姐姐我大,嫉妒),剧情后可以与之对话,加入队伍伙伴。 + +沿着地图一路向东边略偏北的方向前行,遇见第一个篝火。(本人走到这的时候 LP 已经不是很够了)休整后顺着大路往东南方向走到达名为德娜的村庄,自动触发剧情。 + +菲莉丝遇到一位大姐姐,提醒她们先去拜访长老,因为老人家,事多。(建议这里用传送,虽然图不大,但是绕圈圈什么的也很烦,长老老人家晚上不接客,与之相关的任务请在白天。) + +果然是很不友善的老人啊,菲莉丝才进去就被骂出来,还索要伴手礼。 + + + +剧情结束后,菲莉丝为背对“长老的庵堂”的状态,在其左前方有一位可爱的红发蓝连衣裙的小女孩,与之对话知道长老喜欢吃甜点。 + +回到工房,我们合成“噗尼果冻”,理论上前面采集的材料足够,比如蜂蜜什么的…… + +**噗尼果冻**需要素材: + +> 1. 蜂蜜:需要用蜂巢调合,蜂巢可以在法维丘陵、白雾森林、生命之森等几个地方采集到。(最容易的采集点前面已经提及) +> 2. 噗尼噗尼珠:击败噗尼类怪物掉落,照着我的攻略你应该囤积很多了。 +> 3. 水 +> 4. 中和剂 + + + +如果合成之后还是黑夜,有些无聊的话,可以来葛雷纳酒馆,奥斯卡在这里等待我们的队友邀请。新肉盾 Get + +(需要注意的是,全世界各地的酒馆里面都有我们解雇或者未雇佣的小伙伴,并不限制特定地点。) + +带着噗尼果冻,再次去见长老欧蕾莉,这次果然待遇不同了。(长老:孺子可教也)互相认识之后,长老就让菲莉丝去买甘竹。找村内的行商人(地图蓝色提示点)购买5个甘竹,返回交给长老。 + +长老继续下发任务,这里需要帮忙收集5个木材,从生命之森一路走过来的各位,应该手上一大把,直接回去交差,即可。如果木材不够,村庄德娜四周散落着很多,拿十字镐敲碎即可采集。 + +交纳完任务后,长老会问,要不要继续帮我做事。当然要啊,我还等着你送我你的衣服跑图轻松点呢。长老看了看菲莉丝,这么水灵的小姑娘,心肠不错,就是太瘦弱了。不行,炼金术师怎么能这么羸弱,去给我打怪锻炼去…… + +(这里一定要用地图标记任务,我初期不知道标记这个技能,找了6天吧,后面还是看 Y2B 视频攻略。) + + + +一边采集,一边打怪到达任务指示地点,这里直接四人平 A 即可。(这怪物就是战斗力只有5的渣渣。) + +(如果此时还是黑夜,建议做一个采蘑菇的小女孩,捡些柴火。) + +熬到天亮,传送回去和长老欧蕾莉对话,长老认可菲莉丝,并在村正中的大树下给出了最后的任务,需要菲莉丝合成“特制的湿布药”。 + +**特制的湿布药**需要素材: + +> 1. 布类素材 +> 2. 药材 +> 3. 长颈通草:可以在白雾森林,草类采集点采集获得。建议直接在商店购入,城镇篝火旁边的旅行商处可以买到。 +> 4. 灌木莓:可以在白雾森林,采集灌木丛获得采集点见下面的截图。PS,理论上这个在法维丘陵的采集路途中能获取到。**(お姉ちゃんとして頑張るね)** + + + +传送至郊外的篝火,往西北方前行,到达森林中央的篝火。其西边的灌木丛为灌木莓的采集点,不是100%出,好在篝火就在旁边,进出工房慢慢刷。我大概刷了3次 + +合成完毕之后,交给欧蕾莉长老,获取第二封推荐书。然而,这还没有结束。 + +此时我们传送回城镇的篝火,进入工房,随便合成一个道具出来。(记住,出来的时候要是白天。不是的话,睡到白天。) + +出来后会自动触发剧情,姐姐发现菲莉丝的衣服破了,菲莉丝抱怨,衣服这么容易破。路过的长老看见了:“你这丫头,年纪轻轻的贪图好看穿得这么清凉,老了肯定要‘受罪’。干脆,我把我做姑娘时候的衣服送给你,年轻人别冻着。” + + + +剧情后解锁服装系统,之前的服装DLC此时可以用了。 + +(本剧情解锁的衣服特别适合跑图,虽然保守了点。) + + + +与篝火旁的旅行商对话,解锁任务古老记忆,然后在地图上标识,朝着那个方向离开白雾森林去静寂的迷宫探险吧!记得路上多捡柴火哦! + +本图结束 + +到达静寂的迷宫之后,会自动触发剧情。在这里,菲莉丝结识了新的小伙伴——对姐姐见色起意的卡鲁德。此小伙伴在佛鲁斯海姆的酒馆内可以邀请,我觉得其没啥用。 + +静寂的迷宫一年期可以不探索,直接朝北走,就是出口,采集的必要性不是很大。这样,我们到达郊区的小道,顺路往东到达下一主城佛鲁斯海姆。 + +(郊区的小道上可以采集到白冷石,如果需要,可以备一点。) + +**编后记:** + + + +年轻人,你懂什么,不知道绵软少女才是最可爱的么?尤其是略带肉感的感觉,大姐姐我特别喜欢抱个这样的丫头在怀里,捏啊捏。 + +## 佛鲁斯海姆 + + + +城市地图 + +(这个城市的地图还是槽点满满的,最右侧的传送点距离大门还是很远,就算一年期之后有飞天扫帚,这里你也只能老老实实走。蛮不好的设计,如果见识院能挪靠右一点就好了。) + +进入佛鲁斯海姆后自动触发剧情,菲莉丝遇见怒气冲冲的伊尔梅莉亚,对引发其愤怒的水手十分好奇。朝东走过桥,自动触发剧情,见到弱鸡(罗吉)桑,大哥哥一如既往地帅气,就是没法带出去一起打怪。与罗吉桑对话,雷电磺没有的话,可以稍微买几个。 + +沿途的酒馆内有一位老者武士安谷利夫,需要给他5000,才能加入同伴,不过实力“很强”。(感觉和奥斯卡差不多)有钱的话,带着也不错。当然此时你的钱不够也不用怕,稍后会赚够的。 + +从罗吉那出来后继续朝东走,到达水池处触发剧情,遇见水手,告知无法继续旅程,菲莉丝决定去和伊尔梅莉亚商量对策。 + +传送至篝火处,然后继续往西走,过两座桥就是度假村,伊尔梅莉亚在里面。两人决定出去打探消息,探明为何船舶停止航运。 + +出门后传送至锻冶屋,与罗吉桑对话,果然没什么卵用。 + + + +走到喷水池处,自动触发剧情,如果是夜晚的话,请磨时间到天亮即可。本作的任务基本在白天,且部分需要隔天才能触发,建议善用原地踏步磨时间。 + +(你这是活生生地把一对 CP 拆散了啊。对了,梅亚也好萌,祖国欠我一个这样的妹妹。) + +梅亚告诉菲莉丝,她知道事情的真相,但是要去她的店里买东西才能告知。 + +这里的地形极其不讨喜,最优雅的跑图法是从左侧下桥,一直贴着最左侧跑,外面绕一个圈子即可到达。 + +(到达后可能是晚上,但是这里可以直接进入“梅亚的店”。当然鉴于本图很小,可以完全探索,解锁奖杯成就。) + +与梅亚对话,购买一样东西。这里你可以选择购买两个鱼介类素材,比如螺贝,便宜且后面任务需要。当然你也可以随便买,比如朴实的甜食大全这种我就很想要。(螺贝可以在城中通过击碎瓦罐获取。) + +退出购买页面,触发剧情,得知海上出现了牛逼的龙卷风,梅亚得意洋洋地向菲莉丝介绍她的情报来源。我们前往莲的炼金工房,进入后发生剧情。(这里只能白天去) + + + +(京子的既视感) + +剧情结束后,传送回旅店,和伊尔各自决定了想要做的事情,菲莉丝准备造一艘能抗住龙卷风的大船。 + +首先出门,拜访罗吉桑,得知其需要金属块。如果之前的旅途中合成过金属块,这里可以直接交付,或者回工房合成。 + +交付完毕之后往南走,在水池边触发剧情,帮助梅亚合成美味的鱼饵。(梅亚仅白天出现在此处) + +继续往南,过了桥触发剧情,遇见前面见到的安涅莉斯,这里交付完见闻。可以赚一大笔钱,理论上足够雇佣安谷利夫。(见闻院晚上不开门) + +出门继续往东走到尽头,进入舟歌大道,自动触发剧情,凯伊需要10个木材来修船。继续对话,交付我在前面两张图里面总提示你们注意收集的木材。触发剧情,知道船最需要坚固的地方为龙骨。 + + + +蛋疼地往东跑图至最东侧,解锁观光点便于下次传送。观光点处自动触发剧情,姊妹两个对于龙卷风规模的惊叹。观光点下方的宝箱还请务必打开,获得一堆鱼介类素材。(这个本地化我给差评,为毛要叫鱼介,这是日本人对于鱼类和贝类的统称说法。) + +一路向西慢悠悠跑回去,传送回篝火,进入后触发剧情任务“想到了好主意 2”。稍后出去再说,这里先着手合成任务道具“感觉很美味的钓饵”。 + +**感觉很美味的钓饵**需要素材: + +> 1. 麦粉:由红麦调合而成。 +> 2. 鱼介类:前面再三提示你收集了。 +> 3. 动物类材料:生命之森的蜘蛛丝、金丝都可以算。 + +调和完成之后,确保时间在白天,最好12点前吧。先传送和罗吉桑对话,获得灵感。出门往水池处跑去,将鱼饵交付给在旁边钓鱼的梅亚。此时时间如果足够(18点前),会在水池旁看到爱斯卡,跑过去自动触发剧情。 + +(唉,多好的一对 CP。) + + + +传送至酒馆,见到为老不尊男“安谷利夫”,可以支付5000克隆雇佣,我选择暂不雇佣(其实是钱不够,完全本图的全部主线加上见闻的收益,应该足够支付5000佣金。如果是第一次晚上去这里的酒馆,还能遇见吟游诗人露易丝,其收购价格及其黑心,千万不要在她那边出售东西。) + + + +熬到第二天之后,继续去广场水池处,这次需要主动和爱斯卡对话,触发玩耍剧情。剧情结束后菲莉丝决定调和石头饼干与爱斯卡分享。(注意该剧情结束后时间强制到晚上) + +**石头饼干**需要素材: + +> 1. 海胆:法维丘陵西北角,前面的攻略有提示。 +> 2. 双核坚果:主产地也是法维丘陵, +> 3. 水类物质:这个基本不缺 + +(鄙人玩到这里的时候发现,双核坚果不够了,所以跑回法维丘陵采集了一发,而且后面造船需要40个金属,这里推荐顺路跑回干枯平原带东北角用十字镐收集。这里推荐路线从郊区的小道一路向西到旅人的杂木林,再直达法维丘陵。) + + + + + +双核坚果的产出地,东南的篝火处的广茂草原上的绿色灌木丛出采集即可获得。 + +调和完石头饼干,白天(尽量12点前)在喷水池广场与爱斯卡对话,交付任务道具。剧情结束后传送至梅亚的店,与梅亚对话,获得梅亚的想法。 + +到目前为止主线卡在了爱斯卡处,需要等到隔天清晨,跑到水池处自动触发剧情,得到爱斯卡的“报恩”,解锁最后一个造船零件。 + +罗吉、爱斯卡、梅亚三者任务完成后,即可去舟歌大道与凯伊商讨,记得直接传送到码头。(我讨厌这个跑图) + +在白天前往莲的炼金工房,和莲商讨后发现没有满足需求的炼金釜。菲莉丝回到工作室,得到了苏菲老师的炼金釜配方。 + +继续在白天前往莲的炼金工房,遇见苏菲老师还有伊尔梅莉亚,大家决定一起帮菲莉丝实现愿望。 + +(伊尔真是不坦率的孩子啊。) + +剧情结束后,菲莉丝回到工房合成造船所需的四个零件:**(这几个的合成完全不需要考虑拼图,太累)** + +**龙骨**需要素材: + +> 1. 普通合板:需要木材类素材、植物油、德娜木材、永恒之蓝来合成。永恒之蓝在白雾森林木材采集点取得。植物油通过在杂木林采集灌木获得。 +> 2. 木材类素材:前面一直提醒收集的玩意。 +> 3. 金属类素材:前面有提醒。 + +**强化舵**需要素材: + +> 1. 金属块:矿石和燃料合成,选取时记得保留神秘之力、金属类别的材料。 +> 2. 木材类素材 +> 3. 金属类素材 + +**坚固的帆布**需要素材: + +> 1. 布料:使用线材素材、植物类、动物材料调合。 +> 2. 线材:可以在生命之森红色圆形大花采集获得。 +> 3. 植物油:生命之森,木材采集点概率获得。 +> 4. 布类素材:各种合成的布料均算。 + +**轧制金属板**需要素材: + +> 1. 金属块:矿石和燃料合成,选取时记得保留神秘之力、金属类别的材料。 +> 2. 金属类素材 +> 3. 燃料类素材 +> 4. 水类素材:不够的话西边三岔路一堆水 + +全部合成后,前往莲的工房,剧情后获得超弩级釜,回到工房开启超弩级调和教学。这里需要需要材料:40个金属类素材、30个燃料、10个火药类素材、10个神秘之力素材。唯一比较麻烦的是金属类材料,前面已经说明获取方式。调和选材料时可以 「△」 按照品质排序。**记得金丝也属于燃料,一定要保留三个。** + +制作出推进炉后,前往舟歌大道,传送至码头找凯伊对话,随后回工房调和或者是睡觉即可。几天后,凯伊会自动找上门来,船建好了。剧情后,在码头和凯伊对话,选择准备好了。 + +到岸后伊尔因为害羞跑掉了,菲莉丝上岸走到一半突然想起来可以从莲那里获取推荐信,于是又调头回去了。菲莉丝返回佛鲁斯海姆后,前往莲的工房,与莲对话,开启课题任务,调合青炎烧。 + +**青炎烧**需要素材: + +> 1. 苍刚石:如果不够,建议在喷泉广场附近的女行商人处购买,再跑回去采集好辛苦。 +> 2. 燃料类素材 +> 3. 火药类素材 +> 4. 中和剂类素材:手动合成即可 + +此时回到工房,会解锁剧情,菲莉丝对于母上大人的思念。合成青炎烧完毕与莲对话,提示出去使用一下。回工房装备青炎烧,期间触发剧情,获得妈妈亲手缝纫的衣服一套。(十分少女心的一套衣服,可惜我已经不是穿这种衣服的年纪了。) + +前往最近的“静寂的迷宫”,用青炎烧打怪一下即可回去报告,期间菲莉丝自我决定用于炼金术做啥,(创造和毁灭均可)第三封推荐书 Get。 + +本图结束,可以直接乘船去吊钟杯平原。 + +到目前为止,我们已经获得三封推荐书,你可以选择直接去考试,或者获取接下来的两封推荐书,然后再去考试,区别不大。个人推荐前者,因为雪山那边还是有一些必要的采集要素和时装获取的。 + +(穿雪地时装的菲莉丝比平时更萌了怎么办?) + +**PS** + +1、理论上本图菲莉丝的炼金 Lv 与素材等足够合成鱼竿,建议无聊耗时间的话,可以合成一发,装备后解锁钓鱼技能。 + + + +2、桥对面的商人处有售卖黄金树之叶,这个物品后期比较需要,虽然价格贵,但是采集起来也很痛苦,如果需要,可以购买。 + + + +3、在本地图游玩过程中,使用几次工房后会出现菲莉丝喊热的剧情。这时,在白天去梅亚的商店,记得 Get 到新时装。(鄙人最喜欢这套。) + +## 吊钟杯平原 + + + +(这张图上的禁区还是蛮多的,一年期速刷的时候要小心。) + + + +(参看世界地图,吊钟杯平原和旅人的杂木林一样算一个枢纽地图,这里我们先南下去废弃平原获取第四封推荐信。) + +下船后直接往港口的篝火处走去,自动触发剧情,口嫌体正直的伊尔酱在这里等着菲莉丝,希望和她一起去旅行。 + +(邀请伊尔之后我的5人队伍,分别是:伊尔酱、奥斯卡、安吉利夫、菲莉丝和姐姐大人) + + + +白天在吊钟杯码头处会有一蓝发小女孩,与之对话,交付给其我前面反复提到的金丝线。获得重要道具:龙鳞片。 + +交付完任务后,一路往东南方走去,便会到达吊钟杯大桥。 + + + +(真特么省建模,前作的直接抄过来,随便搞几个人,就这么复用) + +与杀马特男对话,开启任务“坏掉的石桥”。桥的修复在任务描述里可以看到,有三种途径: + +1. 使用碎裂的石材从旁边的洞窟穿过,到达南面区域,修复石桥。 +2. 调合全能修补剂直接修复石桥。 +3. 暂时不管这个任务,随着时间流逝,石桥会自动被修复。 + +方法三肯定不行,我们还要推荐信呢,这里我们使用方法二,多快好省。 + +先沿着大路往东北角进发,到达望雪的篝火,在桥处捡到一封信,开启任务“见闻院的遗失物”。过桥往东前行,到达法塔利亚的山岭,发生剧情,遇到前作最终BOSS双子。继续往南走,到达见闻院本部(那个地名我不认识) + + + +往南前往见闻院本部,遇见前作的人偶师弗里兹,这个会有支线奖杯,一年期后来做。与接待员对话,随后要查文献,调查上面截图的位置的书架可发现全能修补剂的配方。(直走右手边第三排书架) + +调查完毕后即可想出全能修补剂,在北侧有篝火可以合成,合成需要炼金 Lv 19,等级不够的话刷没合成过的东西升级。 + +**全能修补剂**需要素材: + +> 1. 黄金树之叶:民家旁的商人处可以购买,但只有一个,价格死贵。采集的话有 DLC 那套**“度假悠闲”**的话,建议穿着去旅人的杂木林(西方的洞窟门口)采集,100% 出。(某中文教程告诉我是宁静之森,虽然也有但是我刷了10天没爆出来,看来是欧气不够。[参考链接](https://h1g.jp/firis/index.php?黄金樹の葉) +> 2. 普通合板:合成道具 +> 3. 黏土类素材 +> 4. 矿石类素材 + + + +(黄金树之叶的购买点) + + + +(黄金树之叶的采集点) + +合成后回到断桥处,使用全能修补剂修复断桥,一直向南走,到达废弃平原。 + +本图结束 + +## 废弃平原 + + + +(因为比较懒,速刷一年期,只完成右边一半,左边还有一半未解锁,自己探索。) + +进入后顺着大路一路往南走到达村庄,自动触发剧情,遇到了颓废的不洗头发男。其本人就是炼金术师,却调戏菲莉丝,要她自己去找。 + + + +剧情结束后正前方三个黑石头处的蓝衣商人,与之对话。 + + + +商人北侧,屋前的红衣女子,与之对话。 + + + +红衣女子东侧,屋前有一位老太太和一位武士,与老太太对话。 + +对话后触发剧情,提示菲莉丝去尔贝鲁特的工房找找看,工房在地图西北角,很容易找到。 + +剧情后获得推荐书,菲莉丝离开工房后,触发剧情,菲莉丝觉得似乎哪里不对,这个看起来就不是好人的怪蜀黍一定有什么坏心思,我要回去找他对峙。 + +返回工房,剧情后开启任务“挽回的机会”,需要获得3颗“噗尼噗尼珠 · 金”,传送荒野道的篝火,刷附近的黑色噗尼即可获得。(这个时候,怪物的等级普遍开始高起来,我是速刷,所以只能靠炸弹流,前面合成的青炎烧这里效果好极了。) + +回去交付材料,提示合成一个炎烧。这里注意合成的炎烧品质要在80以上,要不然会被骂回来重做。(我比较懒,选择品质最好的材料合成就是了。) + +交付炎烧,下发最后的任务,击败可疑的噗尼。 + + + +前往提示点,击败噗尼后,会出现强敌狮鹫兽,该怪物弱点雷属性,提前准备雷属性炸弹。当然,我是直接青炎烧带走,记得满血带好补血,17级也能轻松过。(注意怪物是在出了村庄后左拐,绕个大圈子处,我右拐了。) + +交付完任务后,第四封推荐信 Get。 + +本图暂时结束 + +**PS** + + + + + +和此位置的大叔对话,即可开启任务“桥的修复”,一年期可以先不做。 + +## 北奥罗雪原 + + + +从废弃平原回来,我们回到吊钟杯平原,前往法塔利亚山岭,这次我们前往东北方出口的南奥罗雪原。这张图一年期可以直接无视直接顺着大路往北方走去北奥罗雪原。(其实朝着任务“初次到达雪山”的标记方向走就对了) + + + +一路上看到很多这样的石头,采集后可以获得重力石,记得在获得雪地时装后采集几个,此时采集比较消耗 LP。 + + + +记得在路上采集点啪汽啪汽水,后面合成需要。 + +进入北奥罗雪原,朝着地图东北处的村庄走去,这里可以获得第五份推荐书和最后一件时装。(期间善用篝火恢复体力) + + + +剧情后,往前走,自动触发与前方老太太的对话,得知村内有炼金术士奇尔榭。(奇尔榭小姑娘只在白天接客)奇尔榭的炼金工房在小地图上最北面的那个门。与奇尔榭对话,获得课题配方,返回工房剧情后菲莉丝发现完全看不懂(人家才学不到一年的炼金术,就给我这么难的配方),再次前往奇尔榭的工房。 + + + +与“温泉前的篝火”旁的提亚娜对话,开启支线任务“冲天大树的居民”,一年期之后再去做。 + +回去与奇尔榭对话后,给了道具提示1,我们回工房合成过反应触媒,前面采集的啪汽啪汽水有用了。(如果炼金等级不够的话刷刷没合成的素材) + +**过反应触媒**需要素材: + +> 1. 啪汽啪汽水:前面提示你采集了 +> 2. 药品类素材 +> 3. 炸弹类素材 +> 4. 中和剂类素材:合成即可 + +合成成功后,与奇尔榭对话,给了道具提示2,我们回工房合成无限燃烧棒即可。 + +**无限燃烧棒**需要素材: + +> 1. 过反应触媒 +> 2. 燃料类素材 +> 3. 万灵药类素材:万灵药类素材可以选用炼金粘土,炼金粘土需要通过配方笔记,消费发想点数500点习得,获得发想条件是“采集100次木材类型素材以及制作3次查科尔贴纸”。 + +合成完毕之后我们发想出冰中燃灯,此时一定不要合成! + +奇尔榭对话,之后再调合“冰中燃灯”,素材比较简单,无限燃烧棒、砂类素材、粘土、金属类,合成后前往奇尔榭的工房,与奇尔榭对话完成课题,获得第5份推荐书,我还有203天。 + +本图暂时结束 + +**PS** + + + +1、这里如果等级不够,建议先去采集一些这种水晶碎片,用于合成核水晶,核水晶合成后,会发想出凝缩核来考试。我为了刷等级,把凝缩核刷到很高的等级……其次野外的小怪血厚但是攻击不高,可以刷等级。 + + + +2、在进出工房几次后,触发剧情,菲莉丝觉得很冷,遇到一位老太太,愿意帮菲莉丝制作衣服,但是布不够,合成5个手织布交付给老太太即可获得。 + +## 莱森堡考试 + + + + + +从北奥罗雪原出来,往南奥罗雪原南方走,会有出口,到达蚁巣山道,最右下角为目的地莱森堡。 + +进入莱森堡,就是最后的考试剧情了,这里需要注意的几点事项。 + +1. 报名后无法再出去了,如果你这个时候身上的材料不多了,建议先准备好,报名。 +2. 报名后可以继续游戏直到364天,参加考试。也可以直接回工房睡觉,一觉睡到考试当天,这里推荐直接回工房睡觉。(工房自带此选项) +3. 城里的商人可购买的材料并不多。 +4. 考试前如果心里没底一定要存档,一定要存档,一定要存档。 + +下面说说考试: + +考试总共分为四部分: + +第一部分,笔试题,总共有20道选择题。一题2分,满分40分。(题目和选项均为随机) + +| 部分题目(没力气补全) | 答案 | +| --------------------------------------------------------------------------- | ----------- | +| 请由下列4者中,选出属于【效果】的东西 | 麻痹 | +| 请由下列4者中,选出适合炼金术士工作场所的地点 | 工房 | +| 请由下列中选出分类为魔物者 | 岛鱼 | +| 请由下列中选出适合作为【小恶魔的恶作剧】材料的东西 | 可疑液体 | +| 请由下列中选出仅以【水底的水】、【蒸馏水】与【地底水】3种材料下去调和的结果 | 中和剂 · 蓝 | +| 请由下列中选出属于【有毒材料】类别的东西 | 闇夜菇 | +| 请由下列中选出属于【食材】类别的东西 | 海胆 | +| 请由下列颜色中,选出【噗尼噗尼珠】实际有的颜色 | 蓝 | +| 请回答欲调和出【天使缎带】时,最多可以使用几种材料 | 5种 | + +第二部分,合成题,调合品质最高的道具。第一次我调和了一个100品质以下的,分数是个位数,我调和一个120多的,给了18分,很好奇其计算方式。 + +第三部分,用道具打噗尼,按照伤害计算分数,有人说是10%伤害为分数。 + +如果到这里的分数低于50分,会直接触发 Bad End。 + +如果高于50分,会和伊尔对战,即使输了也没事。 + +如果高于100分,会和苏菲对战,即使输了也没事。 + +考试通过后就是各种剧情,没力气打字了……ED 不好听 diff --git a/src/content/posts/2017/2017-08-12-rain-in-august.mdx b/src/content/posts/2017/2017-08-12-rain-in-august.mdx new file mode 100644 index 0000000..c785b63 --- /dev/null +++ b/src/content/posts/2017/2017-08-12-rain-in-august.mdx @@ -0,0 +1,40 @@ +--- +title: 8月的雨 +slug: rain-in-august +date: 2017-08-12 06:24:40 +updated: 2019-05-18 18:19:45 +tags: + - 雨 + - 碎碎念 +category: 杂思 +cover: /images/2019/05/2019051818191979.jpg +summary: 昨日下班,从园区走出来,傍晚的天空乌云密布,伴随着闪电,但却不知道为何,想要走路回家。 +--- + +[](/images/2019/05/2019050908302180.jpg) + +昨日下班,从园区走出来,傍晚的天空乌云密布,伴随着闪电,但却不知道为何,想要走路回家。 + +大雨如期而遇,湿黏的皮肤在雨中疾跑,一如那个[没带伞的小孩](/i-am-right-here)。不知为何,一直想这么痛快地淋一场大雨,只因在这样的雨中,可以哭泣不被人发现。 + +你知道,就是夏季最特别的天气里,笑着哭。 + +每当周末和假期来临时,工作日里想做没时间做的,心中暗记下的那些 To do List 都被抛之脑后。只想窝在家里懒懒地躺着掰着手指一天天地细水流长。有时摆弄着手机,都是在刷新朋友圈,默默暗中关注着那个她的只言片语。然后在最后一天,快要上班时,看完拖欠的全部新番。 + +窗外是燥动的炎热,吹着凉爽的空调,只觉得身子越来越重,一直向下,陷入更延绵无轮廓的地方…… + +早上一觉新来,只觉得呼吸之间带着股雨后特有的清凉,窗外还在窸窣地下着小雨,立秋后的北京已经一连下了好几天的雨。窗外小区的草坪绿油油的,带着股碧色的气息拂面而来。 + +原来扰人的蝉鸣已了无音讯,仅听见水滴打落叶片几枚。 + +或许,回到很多年以前某个八月的暑假,也是这样连下了几天的雨。偷偷拿出老妈珍爱的油纸伞,溜到外面的院子里捉蝉。想来是听某人说起,捉住了蝉,却捉不住蝉鸣,留不住夏天。那时的我小,只记得,在雨中找到刚蜕了壳的蝉。伏在微湿的树干上,身上薄薄的蝉翼,在雨中发出淡淡的光芒。对于新生生命的喜悦,明媚了我的整个夏天。 + +现在的我,可能已经没有了那份恬淡。 + +工作上的压力,一天比一天要大。每天,都要面对着新的需求,新的挑战。程序的世界,只有 if else,对的就是对的,错的就是错的。而工作、交际却往往比你想的复杂。许多时候,即使是对方的不行,或者是错误,也不能妄加指责。因为程序开发,不是一个人的战斗,是一个团队的努力,在自我努力的时候,也要兼顾他人的进步。 + +下了楼,发现草坪上竟然有些星星点点的浅淡小花。比起旁边被雨打得有些月季,它们只是兀自开放,不刻意讨好,亦不在意。 + +对于工作,也是这样吧,靡不有初,鲜克有终。 + +[](/images/2019/05/2019050908380382.jpg) diff --git a/src/content/posts/2017/2017-09-30-evolution-of-data-structures-in-yandexmetrica.mdx b/src/content/posts/2017/2017-09-30-evolution-of-data-structures-in-yandexmetrica.mdx new file mode 100644 index 0000000..d883d9f --- /dev/null +++ b/src/content/posts/2017/2017-09-30-evolution-of-data-structures-in-yandexmetrica.mdx @@ -0,0 +1,192 @@ +--- +title: Yandex.Metrica 的革命性的数据存储结构 +slug: evolution-of-data-structures-in-yandex-metrica +date: 2017-09-30 02:51:53 +updated: 2019-05-18 18:29:19 +tags: + - 数据库 + - 存储 +category: 编程 +cover: /images/2019/05/2019051818284917.jpg +summary: Yandex.Metrica 是世界第二大的线上分析系统,Metrica 处理来自网站或者应用的数据流,将它解析成可分析的格式。 +--- + + + +Yandex.Metrica 是世界[第二大](https://w3techs.com/technologies/overview/traffic_analysis/all)的线上分析系统,Metrica 处理来自网站或者应用的数据流,将它解析成可分析的格式。 + +Metrica 处理分析消息起来游刃有余,我们主要的技术挑战在于如何以最便于使用的格式来存储处理结果。在整个开发过程中,我们前后几次改变了存储方式。从最初的 MyISAM 表,到后面的 LSM 树,最后变成列式存储数据库 [ClickHouse](https://clickhouse.yandex/)。我将在本文中详解为何我们最后选择自己开发了 ClickHouse。 + +Yandex.Metrica 从2008年公布至今已经平稳运行9年了,每次我们改变数据存储访问方式都是因为它不够高效。这当中有:数据写入性能不理想的原因;有存储不可靠的原因;有消耗过多计算资源的原因;或者仅仅是它不能按照我们的需求去扩展。 + +旧的 Yandex.Metrica 网站有超过40多种固定报表类型(例如:访客地域报告);几个内页分析工具(例如:点击图);网站访客(帮助你详细分析单独访客行为)。当然,Yandex.Metrica 还提供单独的报表构造器。 + +新的 Metrica 和 Appmetrica 系统允许你定制每种报表,而不是以前的“固定”类型查询。你可以增加新的**查询维度**(例如:搜索词条报告中,你可以增加访问页面进一步分析)、**分段**、**比较**(例如:所有的访客数据和旧金山的访客数据比较),改变你的**查询指标集**等。所以,新的系统依赖的数据存储方式和我们之前使用的完全不一样。 + +## MyISAM + +在设计初期,Metrica 被设计为 Yandex.Direct 的分支之一,搜索广告服务。因为 Direct 使用 MySQL 的 MyISAM 引擎,所以 Metrica 开发初期同样沿用了相同的存储。2008 年至 2011 年,MyISAM 引擎被用于存储**“固定”**的分析报表。 + +请让我以地域报表为例,介绍一下报表的数据结构。一份报表是对特定网站的数据汇总(更具体地说,是一个特定的Metrica计数标识),这代表着主键应该包含计数ID(`CounterID`)。因为用户可以选择任意报告周期,所以按照每个日期对方式存储数据毫无意义。因此,数据按照产生的日期去存储,然后通过查询的时间区间累积计算。综上所述,主键中包含日期。 + +报告中的数据,要么按照地域维度展示为列表,要么按照国家、地域、城市等维度展示为一棵树。所以,需要在主键中存放地域ID(`RegionID`),这样可以在应用代码中将数据聚合成一棵树,而不是依赖数据库层面的计算。 + +同时,我们需要计算平均会话周期。这意味着数据表中应该包含**会话总数**和**总的会话时长**。 + +按照上述需求,数据表的结构应该是: `CounterID`, `Date`, `RegionID -> Visits`, `SumVisitTime`, ... 基于这种结构,我们在 `SELECT` 查询时,应该按照 `WHERE CounterID = AND Date BETWEEN min_date AND max_date` 的条件去查询结果。换言之,主键的范围是命中的。 + +### 数据在磁盘上如何存储? How is data actually stored on the disk? + +一张 MyISAM 引擎表由一个数据文件和一个索引文件组成。如果更新表的时候不删除数据且不改变长度,数据文件将按照插入的顺序存储每一行序列化的数据。索引(包含主键索引)是 B-树,叶子节点存储数据文件的位移。当我们读取一个索引中的范围数据时,首先从索引中查出一组满足查询条件的数据文件位移,然后按照查出来的位移依次去从数据文件中查找出实际的数据。 + +以索引存储于RAM(MySQL 的键缓存或者是系统页缓存)而数据没有被缓存的实际场景举例。如果使用磁盘,读取数据的时间取决于需要读取的数据量以及需要完成多少次检索操作,检索的次数基于在磁盘上存储的区域数量。 + +Metrica 事件基本按照它们生成的顺序接收处理,在收集端,数据从不同的计数器随机产生。换言之,数据存储时按照时间是连续的,但是按照生产者是不连续的。当写入至一张 MyISAM 表时,来自不同计数器的数据也是非常随机地存储的。这意味着生成报告的时候,需要几行数据,就可能需要执行同样次数的随机检索。 + +一块经典的 7200 转的硬盘可以每秒钟执行 100 ~ 200 次的随机读取。一个磁盘矩阵,如果使用得当,可以按照比例地执行更多次随机读取。一块使用7年的 SSD 每秒钟可执行 30000 多次的随机读取,但是我们无法支付将数据存放于 SSD 的硬件成本。在目前的系统中,如果我们在一份报表中需要读取10000行数据,大概需要10秒钟,这是完全无法接受的一个时长。 + +InnoDB 引擎更适合用于主键范围检索,因为它使用聚集主键(聚集索引?)。简单说,数据基于主键以有序的方式存储。但是 InnoDB 的写入速度慢到无法接受。如果你推荐 TokuDB,请继续阅读。 + +我们采取了一些措施来让 MyISAM 引擎在主键范围检索时更快。 + +**表排序** 因为数据需要立即更新,对表只做一次排序是远远不够的,但是每次写入都去做排序也不现实。虽然我们可以定期对旧数据做排序。 + +**分区** 一张表可以划分成许多小的主键范围,这么做的目的是为了让同一分区的数据存储得更加连续,基于主键范围的检索能更快。此方法可参考在聚集主键的上手动实现。虽然这么做会导致插入速度明显下降,但是通过控制分区的数量,我们可以在插入速度和检索速度中找到可接受的数值。 + +**按照数据的年龄分割** 单一分区的检索会非常慢,分区多了,插入速度也会变慢。当在这当中取一个中间分区数时,插入和检索速度都不是最快的。对于此问题的解决方案就是将数据分成几个单独的代。举例来说,第一代我们叫做可操作数据,这是数据写入时,分区(按时间)或者不分区的地方。第二代我们叫做归档数据,这是随着数据检索(按照计数ID)进行分区的地方。数据通过脚本从一个代转移到另一个代,但不会特别频繁(例如:一天一次),并能在所有的代上立刻检索。这的确解决了问题,但是也增加了许多复杂性。 + +上面(还有一些别的未列举)就是 Yandex.Metrica 使用的优化策略。 + +让我们总结一下这套方案的缺点: + +- 无法支撑数据在磁盘上连续存储 +- 在插入时表需要加锁 +- 复制十分慢,副本经常有延迟 +- 硬件故障后的数据一致性不能保证 +- 诸如独立用户数量的聚合查询很难计算和存储 +- 数据压缩很难实现并且不高效 +- 索引很大,并且不能在内存中完全存储 +- 许多计算需要在 `SELECT` 查询之后编程去计算 +- 运维麻烦 + + + +图片:数据在磁盘上的存储区域(艺术渲染) + +总而言之,MyISAM 引擎使用起来极不方便。每天的服务器磁盘阵列的负载都是满的(磁头一直在移动),这种情况下,磁盘故障频发。我们在服务器上使用了SAN存储,换言之,我们不得不频繁恢复RAID阵列。有时候,副本的延迟极高导致不得不删除重建,切换至复制主节点极其不便。 + +尽管 MyISAM 缺点多多,到了 2011 年,我们已经基于它存储了超过 5800 亿的数据。在那之后,所有的数据被转换至 Metrage,因此释放了很多服务器资源。 + +## Metrage and OLAPServer + +2010年后我们开始使用 Metrage 存储固定报表,假设你有下述场景: + +- 数据持续以小批次写入数据库 +- 写入流相对比较大(每秒至少几十万行) +- 检索查询想多较少(每秒大概几千次查询) +- 所有的检索命中主键范围(每次查询高达100多万行) +- 每行数据相对较小(未压缩的数据大概100个字节) + +数据结构中的 LSM 树十分适合上述的业务需求,且比较常见。 + +--- + +A fairly common data structure, LSM Tree, works well for this. This structure consists of a comparatively small group of data "chunks" on the disk, each of which contains data sorted by primary key. New data is initially placed in some type of RAM data structure (MemTable) and then written to the disk in a new, sorted chunk. Periodically a few sorted chunks will be compacted into one larger one in the background. This way a relatively small set of chunks are maintained. + +This kind of data structures is used in HBase and Cassandra. Among embedded LSM-Tree data structures, LevelDB and RocksDB are implemented. Subsequently, RocksDB is used in MyRocks, MongoRocks, TiDB, CockroachDB and many others. + + + +Metrage is also an LSM-Tree. Arbitrary data structures (fixed at compile time) can be used as "rows" in it. Every row is a key, value pair. A key is a structure with comparison operations for equality and inequality. The value is an arbitrary structure with operations to update (to add something) and merge (to aggregate or combine with another value). In short, it's a CRDT. + +Both simple structures (integer tuples) and more complex ones (like hash tables for calculating the number of unique visitors or click-map structures) can serve as values. Using the update and merge operations, incremental data aggregation is constantly carried out at the following points: + +- during data insertion when forming new batches in RAM +- during background merges +- during read requests + +Metrage also contains the domain-specific logic we need that's performed during queries. For example, for region reports, the key in the table will contain the ID of the lowest region (city, village) and, if we need a country report, the country data will finish aggregating on the database server side. + +Here are the main advantages of this data structure: + +- Data is located pretty locally on the hard disk; reading the primary key range goes quickly. +- Data is compressed in blocks. Because data is stored in an orderly manner, compression works pretty well when fast compression algorithms are used (in 2010 we used QuickLZ, since 2011 - LZ4). +- Storing data sorted by primary key enables us to use a sparse index. A sparse index is an array of primary key values for each Nth row (N-order of thousands). This index is maximally compact and always fits on the RAM. + +Since reading is not performed very often (even though lot of rows are read when it does) the increase in latency due to having many chunks and decompressing the data blocks does not matter. Reading extra rows because of the index sparsity also does not make a difference. + +Written chunks of data are not modified. This allows you to read and write without locking - a snapshot of data is taken for reading. Simple and uniform code is used, but we can easily implement all the necessary domain-specific logic. + +We had to write Metrage instead of amending an existing solution because there really wasn't one. LevelDB did not exist in 2010 and TokuDB was proprietary at the time. + +All systems that implement LSM-Tree were suitable for storing unstructured data and maps from BLOB to BLOB with slight variations. But to adapt this type of system to work with arbitrary CRDT would have taken much longer than to develop Metrage. + +Converting data from MySQL to Metrage was rather time consuming: while it only took about a week for the conversion program to work, the main part of it took about two months to work out. + +After transferring reports to Metrage, we immediately saw an increase in Metrica interface speed. We've been using Metrage for five years and it has proved to be a reliable solution. During that time, there were only a few minor failures. It's advantages are its simplicity and effectiveness, which made it a far better choice for storing data than MyISAM. + +As of 2015 we stored 3.37 trillion rows in Metrage and used 39 \* 2 servers for this. Then we have moved away from storing data in Metrage and deleted most of the tables. The system has its drawbacks; it really only works effectively with fixed reports. Metrage aggregates data and saves aggregated data. But in order to do this, you have to list all the ways in which you want to aggregate data ahead of time. So if we do this in 40 different ways, it means that Metrica will contain 40 types of reports and no more. + +To mitigate this we had to keep for a while a separate storage for custom report wizard, called OLAPServer. It is a simple and very limited implementation of a column-oriented database. It supports only one table set in compile time — a session table. Unlike Metrage, data is not updated in real-time, but rather a few times per day. The only data type supported is fixed-length numbers of 1-8 bytes, so it wasn’t suitable for reports with other kinds of data, for example URLs. + +## ClickHouse + +Using OLAPServer, we developed an understanding of how well column-oriented DBMS's handle ad-hoc analytics tasks with non-aggregated data. If you can retrieve any report from non-aggregated data, then it begs the question of whether data even needs to be aggregated in advance, as we did with Metrage database. + + + +On the one hand, pre-aggregating data can reduce the volume of data that is used at the moment when the report page is loading. On the other hand, though, aggregated data doesn't solve everything. Here are the reasons why: + +- you need to have a list of reports that your users need ahead of time +- in other words, the user can't put together a custom report +- when aggregating a lot of keys, the amount of data is not reduced and aggregation is useless +- when there are a lot of reports, there are too many aggregation options (combinatorial explosion) +- when aggregating high cardinality keys (for example, URLs) the amount of data does not decrease by much (by less than half) +- due to this, the amount of data may not be reduced, but actually grow during aggregation +- users won't view all the reports that we calculate for them (in other words, a lot of the calculations prove useless) +- it's difficult to maintain logical consistency when storing a large number of different aggregations + +As you can see, if nothing is aggregated and we work with non-aggregated data, then it's possible that the volume of computations will even be reduced. But only working with non-aggregated data imposes very high demands on the effectiveness of the system that executes the queries. + +So if we aggregate the data in advance, then we should do it constantly (in real time), but asynchronously with respect to user queries. We should really just aggregate the data in real time; a large portion of the report being received should consist of prepared data. + +If data is not aggregated in advance, all the work has to be done at the moment the user request it (i.e. while they wait for the report page to load). This means that many billions of rows need to be processed in response to the user's query; the quicker this can be done, the better. + +For this you need a good column-oriented DBMS. The market didn’t have any column-oriented DBMS's that would handle internet-analytics tasks on the scale of Runet (the Russian internet) well enough and would not be prohibitively expensive to license. + +Recently, as an alternative to commercial column-oriented DBMS's, solutions for efficient ad-hoc analytics of data in distributed computing systems began appearing: Cloudera Impala, Spark SQL, Presto, and Apache Drill. Although such systems can work effectively with queries for internal analytical tasks, it is difficult to imagine them as the backend for the web interface of an analytical system accessible to external users. + +At Yandex, we developed and later [opensourced](https://github.com/yandex/ClickHouse/) our own column-oriented DBMS — ClickHouse. Let's review the basic requirements that we had in mind before we proceeded to development. + +Ability to work with large datasets. In current Yandex.Metrica for websites, ClickHouse is used to store all data for reports. As of September, 2017, the database is comprised of 25.1 trillion rows. It’s made up of non-aggregated data that is used to retrieve reports in real-time. Every row in the largest table contains over 500 columns. + +The system should scale linearly. ClickHouse allows you to increase the size of cluster by adding new servers as needed. For example, Yandex.Metrica's main cluster has increased from 60 to 426 servers in three years. In the aim of fault tolerance, our servers are spread across different data centers. ClickHouse can use all hardware resources to process a single query. This way more than 2 terabyte can be processed per second. + +High efficiency. We really focus on our database's high performance. Based on the results of internal tests, ClickHouse processes queries faster than any other system we could acquire. For example, ClickHouse works an average of 2.8-3.4 times faster on web analytics queries than one of top performing commercial column-oriented DBMS (let's call it DBMS-V). + +Functionality should be sufficient for Web analytics tools. The database supports the SQL language dialect, subqueries and JOINs (local and distributed). There are numerous SQL extensions: functions for web analytics, arrays and nested data structures, higher-order functions, aggregate functions for approximate calculations using sketching, etc. + +ClickHouse was initially developed by the Yandex.Metrica team. Furthermore, we were able to make the system flexible and extensible enough that it can be successfully used for different tasks. Although the database can run on large clusters, it can be installed on single server or even on a virtual machine. + +ClickHouse is well equipped for creating all kinds of analytical tools. Just consider: if the system can handle the challenges of Yandex.Metrica, you can be sure that ClickHouse will cope with other tasks with a lot of performance headroom to spare. +ClickHouse works well as a time series database; at Yandex it is commonly used as the [backend for Graphite](https://github.com/yandex/graphouse/) instead of Ceres/Whisper. This lets us work with more than a trillion metrics on a single server. + +ClickHouse is used by analytics for internal tasks. Based on our experience at Yandex, ClickHouse performs at about three orders of magnitude higher than ancient methods of data processing (scripts on MapReduce). But this is not a simple quantitative difference. The fact of the matter is that by having such a high calculation speed, you can afford to employ radically different methods of problem solving. + +If an analyst has to make a report and they are competent at their job, they won't just go ahead and construct one report. Rather, they will start by retrieving dozens of other reports to better understand the nature of the data and test various hypotheses. It is often useful to look at data from different angles in order to posit and check new hypotheses, even if you don't have a clear goal. + +This is only possible if the data analysis speed allows you to conduct instant research. The faster queries are executed, the more hypotheses you can test. Working with ClickHouse, one even gets the sense that they are able to think faster. + +In traditional systems, data is like a dead weight, figuratively speaking. You can manipulate it, but it takes a lot of time and is inconvenient. If your data is in ClickHouse though, it is much more malleable: you can study it in different cross-sections and drill down to the individual rows of data. + +After one year of open source, ClickHouse is now used by hundreds of companies worldwide. For instance, [CloudFlare](https://blog.cloudflare.com/how-cloudflare-analyzes-1m-dns-queries-per-second/) is using ClickHouse for analytics of DNS traffic, ingesting about 75 billion events each day. Another example is [Vertamedia](https://www.dropbox.com/s/l0qx4feez3kokd9/Go%20July%20meetup.%20Go%20-%20ClickHouse%20-%20Grafana.pdf?dl=0) (a video SSP platform), which processes 200 billion events each day in ClickHouse with an ingestion rate of about 3 million rows per second. + +## Conclusions + +Yandex.Metrica has become the second largest web-analytics system in the world. The volume of data that Metrica takes in grew from 200 million events a day in 2009 to more than 25 billion in 2017. In order to provide users with a wide variety of options while still keeping up with the increasing workload, we've had to constantly modify our approach to data storage. + +Effective hardware utilization is very important to us. In our experience, when you have a large volume of data, it's better not to worry as much about how well the system scales and instead focus on how effectively each unit of hardware is used: each processor core, disk and SSD, RAM, and network. After all, if your system is already using hundreds of servers, and you have to work ten times more efficiently, it is unlikely that you can just proceed to install thousands of servers, no matter how scalable your system is. + +To maximize efficiency, it's important to customize your solution to meet the needs of specific type of workload. There is no data structure that copes well with completely different scenarios. For example, it's clear that key-value databases don't work for analytical queries. The greater the load on the system, the narrower the specialization required. One should not be afraid to use completely different data structures for different tasks. + +We were able to set things up so that [Yandex.Metrica](https://metrica.yandex.com/)'s hardware was relatively inexpensive. This has allowed us to offer the service free of charge to even very large sites and mobile apps, even larger than Yandex’s own, while competitors typically start asking for a paid subscription plan. diff --git a/src/content/posts/2017/2017-10-18-two-years-in-oneapm.mdx b/src/content/posts/2017/2017-10-18-two-years-in-oneapm.mdx new file mode 100644 index 0000000..f8dd6c1 --- /dev/null +++ b/src/content/posts/2017/2017-10-18-two-years-in-oneapm.mdx @@ -0,0 +1,624 @@ +--- +title: OneAPM 工作两年总结 +slug: two-years-in-oneapm +date: 2017-10-17 20:52:36 +updated: 2020-03-01 18:05:26 +tags: + - 学习 + - 代码 + - 总结 +category: 编程 +cover: /images/2019/05/2019050908152192.jpg +summary: 掐指一算,从 OneAPM 离职也快一个月了,在 OneAPM 工作的种种,仿佛还像是在昨天。细数两年的工作经历,我很庆幸在恰当的时间点和这么一群有激情有活力的人共事。那么,是时候总结一下我在 OneAPM 做的牛(cai)逼(ji)事情了。 +--- + + + +掐指一算,从 OneAPM 离职也快一个月了,在 OneAPM 工作的种种,仿佛还像是在昨天。细数两年的工作经历,我很庆幸在恰当的时间点和这么一群有激情有活力的人共事。那么,是时候总结一下我在 OneAPM 做的牛(cai)逼(ji)事情了。 + +[PPT 下载](https://cat.yufan.me/uploads/two-years-in-oneapm.pdf) + + + +大家好,今天由我来分享一下,我在上家公司做的 Ai 和 告警 相关的一些内容。 + +首先,我先简单介绍一下,今天我要分享的两个项目: + +1. Ai 是 OneAPM 服务器端应用性能监控分析程序,它主要是能收集Java、CSharp、Python等偏后端语言的系统的一些指标数据。然后分析出调用 Trace 和完整的调用拓扑图,还有一些其他图表数据的展示。 +2. 告警系统原先作为一个 Ai 系统的子模块,用的是流式计算框架 Flink,后面不能满足对外交付和业务功能需求。我们就重新设计开发了纯粹的CEP计算引擎,依托于此在Ai上构建了新的告警系统,然后服务化拆分成独立的告警系统,并接入了其他类似Ai的业务线。 + +这次分享,一是我对以前2年工作的整理和思考,二也是和大家交流学习。 + + + +对于 Ai,我不属于它的主要研发,我只是在上面剥离开发了现有的告警系统。所以我就讲讲我接触过的架构部分的演进。本身,就功能部分,其实没有东西。 +我在说告警的时候会说的比较细一些。 + + + +我是15年年底入职OneAPM,17年9月初离职加入咱们这个团队。这期间Ai伴随着业务的需求,也进行了三次大的技术架构演进。最明显的,就是每次演进中,Ai对应的存储在不断变化。同时,比较巧的是,每次架构变化的同时,我们的数据结构也略有不同,并且学习的国外竞品也不大一样。 + +说老实话,我们每次改变的步子都迈的略大,这中间也走了不少弯路。很多技术、框架,一开始看十分好,但是却不一定契合我们的需求。项目在变革初期就拆分出SaaS和企业级两套代码,并且各自都有比较多的开发分支,这些东西的维护,也让我们的代码管理一度崩溃。 + +但是,我这里主要想分享的,就是我们在业务和数据量不断增长的同时的架构设计变化,以及最后如何实现灵活部署,一套代码适配各种环境。 + + + +OneAPM 在 2013 年开始涉足 APM 市场,当时在13年做了我们的第一代产品 Si ,它是那种庞大的单体应用,功能也十分单一。 + +在 2014 年初 OneAPM 基于用户需求和学习国外同类产品 NewRelic 开发了第一版 Ai 3.0。它的架构非常简单,就是一个收集端收集探针的数据写入Kafka,然后落到HBase里,还有一个数据展示端直接查询HBase的数据做展示。 + +在 2015 年初的时候,企业版开始做架构演进,首先是在存储这块,对于之前用 HBase 的聚合查询部分改用 Druid,对于 Trace 和 Transaction 数据转而使用 MySQL,同时,我们学习国外竞品 dynaTrace 完善了我们的分析模型。 + +2016 年的时候,我们发现存储是比较大的问题,无论是交付上,还是未来按照数据量扩容上。且 Druid 的部署、查询等都存在一些问题。在SaaS上线Druid版本之后,我们调研各类存储系统结合业务特点选用ClickHouse,并基于它开发了代号为金字塔的查询和存储模块。 + +2017 年的时候,我们开始梳理各个业务系统、组件,将它们全部拆分,公共组件服务化、Boot化,打通了各个系统。 + + + +这是2014年初期的第一次封闭开发后的架构,当时正好大数据Hadoop之类的比较火,所以初期的架构我们完全是基于它来做的。我们的前端应用分为 Data Collector 数据收集端,Data Viewer 数据展示层。探针端走 Nginx 将数据上传至DC来进行分析处理,页面访问通过DV获取各种数据。 +Data Viewer 初期是直接读取 HBase 的,后面进行简化,部分热数据(最近5分钟调用统计),缓存于 Redis。 + +这里要提一下它和云迹的应用性能分析的区别,我们为了减少HTTP请求量和流量(小公司)探针端做了聚合和压缩,一分钟上传一个数据包。所以DC端变为解包,然后写入Kafka,对于最新的 Trace 数据,我们写入 Redis 用于快速查询生成拓扑图。 + +Consumer 主要是处理翻译探针的 Metric 数据,将其翻译为具体的监控指标名称,然后写入 HBase。 + +这套架构部署到 SaaS 之后,我们的市场部就开始推广,当时的日活蛮高,几十万独立 IP。瞬间,我们就遇到了第一个直接问题——HBase 存在写入瓶颈,HBase在大量数据持续写入的场景下,经常OOM,十分痛苦。 + + + +我们开始分析问题,首先,写入上,我们拆成了如图所示的三大部分,而不是之前的单一 HBase。 + +而就OLAP系统而言,数据读写上最大的特点就是写多读少,实时性要求不高。所以,查询中,HBase主要的性能问题是在对于历史某条具体的 Trace 调用指标的查询(也就是 Select One 查询)。我们在系统中引入了 MySQL,Metric 数据开始双写 HBase 和 MySQL。Redis 负责生成最新的调用拓扑,只有一条最新的 Trace 记录,MySQL 存储 Metric 数据,HBase 存储所有的 Trace 和 Metric 数据进行聚合查询。DV 还会将一些热查询结果缓存于 Redis 中。 + +这个时候的 Consumer 开始负责一定量的计算,会分出多个 Worker 在 Kafka 上进行一些处理,再将数据写入 Kafka,HBase 改为消费 Kafka 的数据。(这么做的目的,就是为了在线上拆分出不同的 Consumer 分机器部署,因为 SaaS 上的数据量,连 Consumer 都开始出现瓶颈。) + + + +在这个时候,我们引入了 Camel 这个中间件,用它将 Kafka 的操作,MySQL 的操作,还有和 Redis 的部分操作都转为使用 Camel 操作。在我介绍为什么使用 Camel 之前,我想先简单介绍一下它。(下一页PPT) + +我们在引入 Camel 的时候,主要考虑几个方面: + +第一,屏蔽Kafka这一层。当时SOA还比较流行,我们希望能找到一个类似 ESB 的设计,能将各个模块的数据打通。就比如MQ,它可能是Kafka,也可能是 RabbitMQ,或者是别的东西,但是程序开发人员不需要关心。 +第二,我们希望一定程序上简化部署运维的麻烦,因为所有的 camel 调用 Route 的核心,就是 URL Scheme,部署配置变为生成 URL。而不是一个个变量属性配置。 +第三,camel 自身的集成路由,可以实现比较高的可用性,它有多 Source 可以定义选举,还有 Fallback,可以保证数据尽可能不会丢失。(我们就曾经遇到 Kafka 挂了丢数据的情况,大概丢了3个小时,后面通过配置失败写文件的 camel 策略,数据很大程度上,避免了丢失。) + +而且,上面的功能,基本都是写Camel DSL,而无需修改业务代码。核心就是一个词——解耦。 + + + +Camel 用官方的话来说,就是基于 Enterprise Integration Patterns 的 Integration Framework。在我看来,Camel 在不同的常见中间件上实现集成,Camel 自身定义好链路调用 DSL(URL Scheme 和 Java、Scala、Spring XML 的实现),还有核心的企业级集成模式的设计思想,组成了 Camel 这个框架。 + +我们通过定义类似右侧的数据调用路由,将Kafka等各类中间件完全抽象出来,应用程序的逻辑转为,将数据存入Camel Producer,或者从 Camel Router 中注册 Endpoint 获取数据,处理转入另一个数据 Endpoint。(回到前面的架构图) + + + +当然我们在开发过程中也设计了很多很有意思的小工具,Mock Agent 便是其中之一。 + +当时我们经常遇到的开发测试问题是,测试不好造数据来进行测试,无法验证某些特定指标的数据,开发无法脱离探针团队单独验证新功能和数据。于是我们决定自己写一套探针数据生成器,定义了一套DSL语言,完整地定义了应用、探针等数据格式,并能自动按照定义规则随机生成指定数据到后端。 + +测试需要做的事情,就是写出不同的模拟探针模板。第一,简化了测试。第二,将测试用例能代码化传承。避免人员流动的问题。 + +后面基于它,我们还写了超级有意思的压测工具,用其打数据测试后端。还有自动化测试等。 + +当然,这也是我们尝试开发的第一个 DSL。 + + + +主要是我们无法避免写入热点问题,即使基于 Row Key 进行了写入优化,大数据量的写入也常常把 HBase 搞挂。 + +最关键的是,持续的 OOM 丢数据,已经给我们的运维带来的太多麻烦,对外的 SLA 也无法保证。(这个时间段你经常听到外面对OneAPM的评价就是数据不准,老是丢数据。) + +基于 HBase 的查询时延也越来越高,甚至某种程度上,已经不大能支撑新的数据量。当时最高峰的时候,阿里云机器数量高达 20 台。所以,是时候考虑引入新的数据库了。 + + + +这个时候,来自 IBM 研究院的刘麒赟向我们推荐了Druid,并在我们后面的实践中取代了 HBase 作为主要的 Metric 存储。 + +2015年的时候 Druid 架构主要就是上述这张图,Druid 由4大节点组成, Real-time、Coordinator、Broker、Historical 节点,在设计之初就考虑任何一个节点挂了,不会影响其他节点。 + +Druid 对于数据的写入方式有两种,一种是实时的,直接写入 Real-time 节点,对应的是那种写多读少的数据,还有一种是批量的直接写入底层数据存储的方式,一般是对应读多写少的数据。这两种方式在 OneAPM 都有涉及,Ai 作为应用性能监控,对应的是海量的探针数据,主要是使用实时写入。Mi 是移动端性能监控,探针上传数据存在时延等问题,所以是在上层做了简单的处理缓冲后,批量写入 Deep Storage。 + +Real-time 节点主要接受实时产生的数据,例如 Kafka 中的数据。数据会在实时节点的内存中进行缓存处理,构建 memtable,然后定时生成 Segment 写入 Deep Storage。写入 Deep Storage 的数据会在 MySQL 生成 meta 索引。 + +Deep Storage 一般是 HDFS 或者是 NFS,我们在查询的时候,数据来源于 Deep Storage 或者是 Real-time 节点里面的数据。 + +协调节点主要是用于将 Segment 数据在 Historical 节点上分配,Historical 节点会自行动态从 Deep Storage 下载 Segment 至磁盘,并加载到内存查询提供结果。 + +Broker Nodes 只提供对外的查询,它不保存任何数据,只会对部分热点数据做缓存。它会从 Realtime 节点中查询到还在内存未写入 Deep Storage 的数据,并从 Historical 节点插入已经写入 Deep Storage 的数据,然后聚合合并返回给用户。 + + + +所以,我们可以看到数据写入和查询遵循上面的数据流图,这里我们没有把协调节点画出。 + +数据在 Druid 上的物理存储单位为 Segment,他是基于 LSM-Tree 模型存储的磁盘最小文件单位,按照时间范围划分,连续存储在磁盘上。 +在逻辑上,数据按照 DataSource 为基本存储单元,分为三类数据: + +1. Timestamp:时间戳,每条数据都必须有时间。 +2. Dimension:维度数据,也就是这条数据的一些元信息。 +3. Metric:指标数据,这类数据将在 Druid 上进行聚合和计算,并会按照一定的维度聚合存储到实际文件中。 + + + +除了上述说的查询方式 OLAP 的数据其实有几大特性很关键: + +1. 不可变,数据一旦产生,基本上就不会变化。换言之,我们不需要去做UPDATE操作。 +2. 数据不需要单独的删除操作。 +3. 数据基于时间,每条数据都有对应的时间戳,且每天的数据量极高 + +所以,对于一个 OLAP 系统的数据库,它需要解决的问题也就两个维度:写入 和 查询。 + +对于 Druid 而言,它支持的查询有且不仅有上面的四种方式。但是,我们进行梳理后发现,OneAPM的所有业务查询场景,都可以基于上述四种查询方式组合出来。 + + + +于是在基于 Druid 开发的时候我们遇到的第一个问题就是 Druid 的查询方式是 HTTP,返回结果基本是 JSON。我们用 Druid 比较早,那个时候的 Druid 还不像现在这样子,支持 SQL 插件。 + +我们需要做的第一个事情,就是如何简化这块集成开发的难度。我们第一时间想到的就是,在这上面开发一套 SQL 查询语法。我们使用 Antlr4 造了一套 Druid SQL,基于它可以解析为直接查询 Druid 的 JSON。 + +并基于这套 DSL 模型,我们开发了对应的 jdbc 驱动,轻松和 MyBatis 集成在一起。最近这两周,我也尝试在 ES 上开发了类似的工具,SQL 模型与解析基本写完了:[https://github.com/syhily/elasticsearch-jdbc](https://github.com/syhily/elasticsearch-jdbc) + +当然这种实现不是没有代价的,我的压测的同事和我抱怨过,这种方式相比纯 JSON 的方式,性能下降了 50%。我觉得,这里我们当时这么设计的首要考虑,是在于简化开发难度,SQL对每个程序员都是最熟悉的,其次,我们还有一层考虑就是未来更容易适配别的存储平台,比如 ES(当时其实在15年中旬的时候也列入我们的技术选型)。 + + + +Druid 另一个比较大的问题就是,它实在是太吃硬件了。记得之前和今日头条的广告部门研发聊天,聊到的第一个问题就是 Druid 的部署需要 SSD。 + +我们在前面的架构分析当中很容易发现,Druid 本质上还是属于 Hadoop 体系里面的,它的数据存储还是需要 HDFS,只是它的数据模型基于 LSM-Tree 做了一些优化。换言之,它还是很吃磁盘 IO。每个 Historical 节点去查询的时候,都有数据从 Deep Storage 同步的过程,都需要加载到内存去检索数据。虽然数据的存储上有一定的连续性,但是内存的大小直接决定了查询的快慢,磁盘的 IO 决定了 Druid 的最终吞吐量。 + +另外一个问题就是,查询代价问题。Druid 上所有的数据都是要制定聚合粒度的,小聚合粒度的数据支持比它更大粒度的聚合数据的查询。 + +比如说,数据是按照1分钟为聚合粒度存储的化,我们可以按照比1分钟还要长的粒度去查询,比如按照5分钟一条数据的方式查询结果。但是,查询的时间聚合单位越大,在分钟的聚合表上的代价也就越高,性能损失是指数级的。 + +针对上面两个问题,我们的最终解决方案,就是数据不是写一份。而是写了多份,我们按照业务的查询间隔设置了3~4种不同的聚合表(SaaS和企业级的不同)。查询的时候按照间隔路由到不同的 Druid 数据表查询。某种程度上规避了磁盘 IO 瓶颈和查询瓶颈。 + + + +在充分调研和实践后,有了上面的新架构图。3.0 到 4.0 的变化主要在HBase存储的替换,数据流向的梳理。 + +我们将探针的数据分为三大类,针对每类的数据,都有不同的存储方式和处理方式。 + +探针上传的数据,分为三大类,Trace、Metrics、Analytic Event。Trace 就是一次完整的调用链记录,Metrics 就是系统和应用的一些指标数据。Analytic 数据使我们在探针中对于一些慢 Trace 数据的详细信息抓取。最终所有的 Metrics 数据都写入 Druid,因为我们要按照不同的查询间隔和时间点去分析展示图表。Traces 和事物类信息直接存储 MySQL,它对应的详细信息还需要从 Druid 查询。对于慢 Trace 一类的分析数据,因为比较大,切实时变化,我们存入到 Redis 内。 + + + +但是,Druid 一类的东西从来都不是一个开箱即用的产品。我们前面在进行数据多写入优化,还有一些类似 SelectOne 查询的时候,越来越发现,为了兼容 Druid 的数据结构,我们的研发需要定制很多非业务类的代码。 + +比如,最简单的一个例子,Druid 中查到一个 Metric 指标数据为 0,到底是这个数据没有上传不存在,还是真的为 0,这是需要商榷的。我们有些基于 Druid 进行的基线数据计算,想要在 Druid 中存储,就会遇到 Druid 无法更新的弊端。换句话说,Druid 解决了我们数据写入这个直接问题,查询上适用业务,但是有些难用。 + +针对上述这些问题,我们在16年初开始调研开发了现有的金字塔存储模块。它主要由金字塔聚合模块 Metric Store 和金字塔读取模块 Analytic Store 两部分组成。 + +因为架构有一定的传承性。所以它和 Druid 类似,我们只支持 Kafka 的方式写入 Metric 数据,HTTP JSON 的方式暴露查询接口。基于它我们改造 Druid SQL,适配了现有的存储。它的诞生,第一点,解决了我们之前对于数据双写甚至多写的查询问题。 + + + +我们在要求业务接入金子塔的时候,需要它提供上述的数据格式定义。然后我们会按照前面定义的聚合粒度表,自动在 Backend 数据库创建不同的粒度表。 + +金字塔存储引擎的诞生,其实主要是为了 ClickHouse 服务的,接下来,请允许我先介绍一下 ClickHouse。 + + + +从某种角度而言,Druid 的架构,查询特性,性能等各项指标都十分满足我们的需求。无论是 SaaS,还是在 PICC 的部署实施结果都十分让人满意。 + +但是,我们还是遇到了很多问题。 + +1. 就是 Druid 的丢数据问题,因为它的数据对于时间十分敏感,超过一个指定阈值的旧数据,Druid 会直接丢弃,因为它无法更新已经持久化写入磁盘的数据。 +2. 和第一点类似,就是 Druid 无法删除和更新数据,遇到脏数据就会很麻烦。 +3. Druid 的部署太麻烦,每次企业级的交付,实施人员基本无法在现场独立完成部署。(可以结合我们前面看到的架构图,它要MySQL去存meta,用 zk 去做协调,还有多个部署单元,不是一个简单到能傻瓜安装的程序。这也是 OneAPM 架构中逐渐淘汰一些组件的主要原因,包括我们后面谈到的告警系统。) +4. Druid 对于 null 的处理,查询出来的 6个时间点的数据都是0,是没数据,还是0,我们判断不了。 + +所以,我们需要在企业级的交付架构中,采取更简单更实用的存储架构,能在机器不变或者更小的情况下,实现部署,这个时候 ClickHouse 便进入我们的技术选型中。 + +[ClickHouse 架构解析](/posts/evolution-of-data-structures-in-yandexmetrica) + + + +在介绍 ClickHouse 之前,我觉得有必要分享一下常见的两种数据存储结构。 + +第一种是 B+ Tree或者是基于它的扩展结构,它常见于关系型数据的索引数据结构。我们以 MySQL 的 MyISAM 引擎为例,数据在其上存储的时候分为两部分,按照插入顺序写入的数据文件和 B+ Tree 的索引。叶子节点存储数据文件的位移。当我们读取一个索引中的范围数据时,首先从索引中查出一组满足查询条件的数据文件位移,然后按照查出来的位移依次去从数据文件中查找出实际的数据。 + +所以,我们很容易发现,我们想要检索的数据,往往在数据库上不是连续的,上图显示常见的数据库磁盘中的文件分布情况。当然我们可以换用 InnoDB,它会基于主机定义的索引,写入顺序更加连续。但是,这势必会导入写入性能十分难看。事实上,如果拿关系型数据库存储我们这种类似日志、探针指标类海量数据,势必会遇到的问题就是写入快,查询慢;查询快,写入慢的死循环。而且,扩容等操作基本不可能,分库分表等操作还会增加代码复杂度。 + +所以,在非关系型数据库里面,常见的存储结构是 LSM-Tree(Log-Structured Merge-Tree)。首先,对于磁盘而言,顺序写入的性能是最理想的。所以常见的 NoSQL 都是将磁盘看做一个大的日志,每次直接在后端批量增加新的数据以达到连续写入的目的。但就和 MyISAM 一样,会遇到查询时的问题。所以 LSM-Tree 就应运而生。 + +它在内存中和磁盘中分别使用两种不同的树结构存储数据,并同时对外提供查询能力。如 Druid 为例,在内存中的数据,会按照时间范围去聚合排序。然后定时写入磁盘,所以在磁盘中的文件写入的时候已经是排好序的。这也是为何 Druid 的查询一定要提供时间范围,只有这样,才能选取出需要的数据块去查询。 + +当然,聪明的你一定会问,如果内存中的数据,没有写入磁盘,数据库崩溃了怎么办。其实所有的数据,会先以日志的形式写入文件,所以基本不会丢数据。 + +这种结构,从某种角度,存储十分快,查询上通过各种方式的优化,也是可观的。我记得在研究 Cassandra 代码的时候印象最深的就是它会按照数据结构计算位移大小,写入的时候,不足都要对齐数据,使得检索上有近似 O(1) 的效果。 + +昨天汤总说道 Schema On Read,觉得很好,我当时回复说,要在 HDFS 上动手脚。其实本质上就可以基于 LSM-Tree 以类似 Druid 的方式做。但是还是得有时间这个指标,查询得有时间的范畴,基于这几个特点才有可能实现无 Schema 写入。 + + + +Druid 的特点是数据需要预聚合,然后按照聚合粒度去查询。而 ClickHouse 属于一种列式存储数据库,在查询 SQL 上,他和传统的关系型数据库十分类似(SQL引擎直接是基于MySQL的静态库编译的)它对数据的存储索引进行优化,按照 MergeEngine 的定义去写入,所以你会发现它的查询,就和上面的图一样,是连续的数据。 + +因为 ClickHouse 的文档十分少,大部分是俄文,当时我在开发的时候,十分好奇去看过源码。他们的数据结构本质上还是树,类似 LSM tree。印象深刻的是磁盘操作部分的源码,是大段大段的汇编语句,甚至考虑到4K对齐等操作。在查询的时候也有类似经验性质的位移指数,他们的注释就是基于这种位移,最容易命中数据。 + +对于 ClickHouse,OneAPM 乃至国内,最多只实现用起来,但是真正意义上的开发扩展,暂时没有。因为 ClickHouse 无法实现我们的聚合需求,金字塔也为此扩展了聚合功能。和 Druid 一样,在 ClickHouse 上创建多种粒度聚合库,然后存储。 + + + +这个阶段的架构,就已经实现了我们最初的目标,将所有的中间件解耦,我们没有直接使用 Kafka 原生的 High Level API,而是基于 Low Level API开发了 Doko MQ。目的是为了实现不同版本 Kafka 的兼容,因为我们现在还有用户在使用 0.8 的 Kafka 版本。Doko MQ 只是一层外部的封装,Backend 不一定是 Kafka,考虑到有对外去做 POC 需求,我们还原生支持 Redis 做MQ,这些都在 Doko 上实现。 + +存储部分,除了特定的数据还需要专门去操作 MySQL,大部分直接操作我们开发的金字塔存储,它的底层可以适配 Druid 和 ClickHouse,来应对 SaaS 和企业级不同数据量部署的需要。对外去做 POC 的时候,还支持 MySQL InnoDB 的方式,但是聚合一类的查询,需要耗费大量的资源。 + + + +部署与交付是周一按照汤总的要求临时加的,可能 PPT 准备的不是很充分,还请大家多多包涵。 + +Java 应用部署于应用容器中,其实是受到 J2EE 的影响,也算是 Java Web 有别于其他 Web 快速开发语言的一大特色。一个大大的 war 压缩包,包含了全部的依赖,代码,静态资源,模板。 + +在虚拟化流行之前,应用都是部署在物理机上的,为了节约成本,多 war 包部署在一个 Servlet 容器内。 + +但是为了部署方便,如使用的框架有漏洞、项目 jar包的升级,我们会以解压 war 包的方式去部署。或者是打一个不包含依赖的空 war 包,指定容器的加载某个目录,这样所有的war项目公用一套公共依赖,减少内存。当然缺点很明显,容易造成容器污染。 + +避免容器污染,多 war 部署变为多虚拟机单 war、单容器。 + +DevOps 流行,应用和容器不再分离,embedded servlet containers开始流行 Spring Boot 在这个阶段应运而生。于是项目部署变为 fat jar + 虚拟机 + +Docker的流行,开始推行不可变基础设施思想,实例(包括服务器、容器等各种软硬件)一旦创建之后便成为一种只读状态,不可对其进行任何更改。如果需要修改或升级某些实例,唯一的方式就是创建一批新的实例以替换。 + +基于此,我们将配置文件外置剥离,由专门的配置中心下发配置文件。 + + + +最初的时候,Docker 只属于我们的预研项目,当时 Docker 由刘斌(他也是很多中文 Docker 书的译者)引入,公司所有的应用都实现了容器化。这一阶段,我们所有的应用都单独维护了一套独立的 Docker 配置文件,通过 Maven 打包的方式指定 Profile 的方式,然后部署到专门的测试环境。换句话说,Docker 只是作为我们当时的一种测试手段,本身可有可无。 + +2015年上半年,红帽的姜宁老师加入 OneAPM,他带来了 Camel 和 AcmeAir。AcmeAir 本来是 IBM 对外吹牛逼卖他的产品的演示项目,Netflix 公司合作之后觉得不好,自己开发了一套微服务架构,并把 AcmeAir 重写改造成它组件的演示项目,后面 Netflix 全家桶编程了现在很多北京企业在尝试的 Spring Cloud。而 AcmeAir 在 PPT 中的 Docker 部署拓扑也成了我们主要的学习方式。 + +那个时候还没有 docker-compose、docker-swarm,我们将单独维护的配置文件,写死的配置地址,全部变为动态的 Hosts,本质上还是脚本的方式,但是已经部分实现服务编排的东西。 + +然后我们开始调研最后选型了 Mesos 作为我们主要的程序部署平台,使用 Mesos 管理部署 Docker 应用。在上层基于 Marthon 的管理 API 增加了配置中心,原有脚本修改或者单独打包的配置文件变为配置中心下发的方式。最后,Mesos 平台只上线了 SaaS 并部署 Pinpoint 作为演示项目,并未投产。 + +后面,在告警系统的立项开发过程中,因为要和各个系统的集成测试需要,我们慢慢改写出 docker-compose 的方式,废弃掉额外的 SkyDNS。 + + + +Mesos 计划的夭折,主要原因是我们当时应用还没有准备好,我们的应用主要还都是单体应用各个系统间没有打通。于是在 16年我们解决主要的存储问题之后,就开始着力考虑应用集成的问题。 + +应用服务化是我们的内部尝试,是在一次次测试部署和对外企业交付中的血泪总结。当时我们考虑过 Spring Integration,但是它和 camel 基本如出一辙,也调研过 Nexflix 全家桶,最后我们只选用了里面的 zuul 做服务网关。 + +在应用层面,我们按照上图所示,将所有的应用进行服务化拆分,分成不同的组件开发维护,并开发了注册中心等组件。RPC 这边,我们没有使用 HTTP,而是和很多公司一样包装了 Thrift。 + + + +我们基于前面的服务拆分,每个应用在开发的时候,都是上述5大模块。中间核心的中间件组件,业务系统均无需操心。在交付的时候,也属于类似公共资源,按照用户的数据量业务特点弹性选择。 + +最小化部署主要是为了给单独购买我们的某一产品的用户部署所采用的。 + + + +但是我们已经受够了一个项目维护多套代码的苦楚,我们希望一套代码能兼容 SaaS、企业级,减少开发中的分支管理。于是我们拆分后的另一大好处就体现了,它很容易结合投产未使用的 Mesos 在 SaaS 上实现部署。 + +为了打通各个产品,我们在原有的前后端分离的基础上,还将展示层也做了合并,最后实现一体化访问。后端因为实现了服务化,所有的应用都是动态 Mesos 扩容。CEP 等核心计算组件也能真正意义上和各个产品打通,而不是各做各的。 + + + +到了这里,我的第一阶段就算是讲完了,大家有问题么? + + + +告警系统的开发,我们和 Ai 一样,经历了几个阶段,版本迭代的时间点也基本一致。整个开发过程中,我们最核心的问题其实不在于告警功能本身,而是其衍生的产品设计和开发设计。 + + + +和 Ai 一样,初期的告警实现特别简单。当时来自 IBM 研究院的吴海珊加入 OneAPM 团队,带来了 Cassandra 存储,我们当时用的比较早,是 2014 年 2.0 版本的 Cassandra,我们在充分压测之后,对它的数据存储和读写性能十分满意,基于它开发了初版告警(草案)。 + +初版告警的实现原理极其简单,我们从 Kafka 接收要计算的告警指标数据,每接收到一条指标数据,都会按照配置的规则从 Cassandra 中查询对应时间窗口的历史指标数据,然后进行计算,产生警告严重或者是严重事件。然后将执行的告警指标写入 Cassandra,将告警事件写入 Kafka。(看下一页) + +所以你会发现初版的告警,从设计上就存在严重的 Cassandra 读写压力和高可用问题。 + + + +你会发现,每从业务线推送一条指标数据,我们至少要读写两次 Cassandra。和同时期的 Ai 架构相比,Ai 对 HBase 只有写入瓶颈,但读取,因为量不高,反而没有瓶颈。(回上页) + + + +这里是我们和 Ai HBase的对比总结。我们初版的设计和 Ai 一样都需要全量地存储指标数据,而且 Cassandra 的存储分片本身是基于 Partition Key 的方式,数据必须基于 Partition Key 去查询,我们对于计算指标,按照 业务系统、应用 ID、时间 作为 Partition Key 去存储。很意外的是几乎和 HBase 同时出现了读写瓶颈。而且比较尴尬的地方也和 Ai 类似,因为 Partition Key 的定义,完全无法解决写入热点问题。 + + + +所以我们首先想到的是,对于当前的告警架构进行优化,我们有了上述的新架构设计。但是在评审的时候,我们发现,我们做的正是一个典型的分布式流式处理框架都会做的事情,这些与业务逻辑关系不大的完全可以借助现有技术实现。 + +由于这个时期(15年)公司整体投产大数据,我们自然把眼光也投入了当时流行的大数据计算平台。 + + + +首先,对于初版的架构,我们需要保留的是原有的计算数据结构和 Kafka 的写入方式,对于核心的告警计算应用需要去改造。 + +我们需要实现的是基于**单条数据**的实时流式计算。需要能分布式水平扩展。能按照规则分组路由,避免热点问题。需要有比较好的编程接口。 + + + +首先我们考察的便是 Spark,Spark 最大的问题是需要我们人为指定计算的时间窗口,计算的数据也是批量的那种而非单条,这和告警的业务需求本身就不匹配。 + +因为当时我们想设计的告警计算是实时的,而非定时。Spark Streaming 在后面还因为执行模式进一步被我们淘汰。 + + + +Strom 各方面其实都蛮符合我们需求的,它也能实现所谓的单条实时计算。但是,它的计算节点不持有计算状态,某些时候的窗口数据,是需要有类似 Redis 一类的外部存储的。 + + + +**Flink优势:** + +Spark 有的功能 Flink 基本都有,流式计算比 Spark 支持要好。 + +1. Spark是基于数据片集合(RDD)进行小批量处理,所以Spark在流式处理方面,不可避免增加一些延时。 +2. 而 Flink 的流式计算跟 Storm 性能差不多,支持毫秒级计算,而 Spark 则只能支持秒级计算。 +3. Flink 有自动优化迭代的功能,如有增量迭代。它与 Hadoop 兼容性很好,还有 pipeline 模式增加计算性能。 + +这里,我需要重点说一下 pipeline 模式。 + + + +Staged execution 就如它的名字一样,数据处理分为不同的阶段,只有一批数据一个阶段完全处理完了,才会去执行下一个阶段。典型例子就是 Spark Streaming + + + +Pipeline 则是把执行串行在了一起,只有有计算资源空闲,就会去执行下一个的操作。在外部表象是只有一个阶段。 + +上面的不好理解,我们思考一个更形象的例子: + +某生产线生产某钟玩具需要A,B,C三个步骤,分别需要花费10分钟,40分钟,10分钟,请问连续生产n个玩具大概需要多少分钟? + +**总结:** + +stage的弊端是不能提前计算,必须等数据都来了才能开始计算(operateor等数据,空耗时间)。pipeline的优势是数据等着下一个operateor有空闲就立马开始计算(数据等operateor ,不让operateor闲着,时间是有重叠的) + + + +综合前面的调研分析,我们有了上面这张表格。对于我们而言,其实在前面的分析中 Flink 就已经被我们考虑了,尤其是它还有能与 Hadoop 体系很好地整合这种加分项。 + + + +综合前面的分析,我们最终选择 Flink 来计算告警,因为: + +1. 高效的基于 Pipeline 的流式处理引擎 +2. 与 Hadoop、Spark 生态体系良好的兼容性 +3. 简单灵活的编程模型 +4. 良好的可扩展性,容错性,可维护性 + +在架构逻辑上面,我们当时分成了上述五大块。 + +元数据管理主要指的是告警规则配置数据,数据接入层主要是对接业务系统的数据。 + +计算层主要是两类计算,异常检测:按照配置的静态阈值进行简单的计算对比、No Event 无事件监测,主要是监控应用的活动性。 + +缓存区主要是计算数据队列的缓存和应用告警状态的缓存。存储区第一块是从原有架构继承的 Cassandra。离线存储是考虑给别的大数据平台共享数据使用的。 + + + +这里画的是 Standalone 的部署方式,也是我们在本地开发测试的架构,在生产上,我们采用了 Flink on YARN 的部署模式。 + + + +对于 Flink 的任务调度,我们以左下角的一个简单操作为例,它是一个 source(4) -> map(4) -> reduce(3),其调度在 Flink 中如图所示,会分成几个不同的 TaskManager 来操作,每个 TaskMananger 中有多个执行单元,但呈管道式。将外部网状的处理流程变为独立的线性处理任务。 + +我们基于 Flink 首先需要开发的,就是异常检测流程。告警的异常检测就相当于 Flink 的一个 Job(Streaming),借助 Flink 简单易用的编程模型,我们可以快速的构建我们的 Flow。 + +在设计的初期,我们考虑了几个方面的问题: + +1. 作为通用的计算引擎,谁可以使用这个 Job。 +2. 如果后面某些产品提出一些变态的需求,我们是否可以快速开发一个针对特殊需求的 Job 提交到同一的平台去运行? +3. 平台是否可以提供稳定的运行环境、可维护性、可扩展性、可监控性以及简单高效的编程模型,咱们可以把更多的精力放在两个方面:a.业务;b.平台研究(确保稳定性) +4. 生产上统一到 Yarn 上之后,我们可以在一个集群上公用一份数据,根据不同场景使用不同的计算引擎做他适合做的事情。比如,暴露数据给 Spark 团队使用。 +5. Akka 集群化研究,我们原有的 Akka 开发经验,不能浪费。对于企业交付,还是需要有一个小而美的程序架构。Akka 那个时候是 2.3 版本,提供了 Akka Cluster,重新被我们纳入研究范畴。 + + + +我们遇到的第一个问题,就是多数据源,生产上提供计算数据源的可能不仅仅是 Ai 一个产品,还有别的产品。我们研究后发现,Fink 原生支持多数据源。 + + + +说到Rule的问题,我们逃不开一个问题:Rule管理模块到底应不应该拆出来。 + +首先,元数据管理的压力不大,数据量也不会大到哪里去,他的更新也不是频繁的。 +其次,让 Flink 在各个节点上启动一个 Web服务去更新规则是不现实的,也不值当。 + +所以,把Rule管理模块单独抽取出来是合适的。 + +抽取出来之后,自然就涉及告警计算的 Job 如何感知 Rule 变更的问题: + +完全依赖外部存储,例如 Redis,Job 每次都去查存储获取 Rule(这样完全规避了 Rule 更新问题,但是外部存储能够扛得住是个问题,高并发下 Redis 还是会成为瓶颈)。 +Job内存里自己缓存一份 Rule,并提供更新机制。 + +无论怎么搞都得依赖外部通知机制来更新 Rule,比如元数据管理模块更新完 Rule 就往 Kafka 发送一个特殊的 Event。算子收到特殊的 Event 就去数据库里把对应的 Rule 查询出来并更新缓存。 + +有了更新机制,我们要解决的就是如何在需要更新的时候通知所有的算子,难点是一个特殊的Event只能发送给一个算子实例,所以我们上面采用了单实例,存在两个问题。 + +1. 性能瓶颈 +2. 消息表变大了(key,event)—(key,event,rule),更加消耗资源 + +其实,我们忽略了一个问题,当Rule有更新的时候我们完全没必要通知所有的算子实例。 + +虽然我们不是一个 Rule 对应一个算子,但是 Flink 是提供分区机制的,我们已经用 key 做了hash。Rule 的更新不会更新 key,产生的特殊 Event 会分区到固定的算子具体实例,具有相同 key 的 Event 也必然被分区到相同的算子实例。所以我们的担心是多余的,而且借助分区机制,我们对内存的占用会更小,每个算子实例只缓存自己要用的Rule。 + +所以 Rule 的更新只有三种场景:初始化时不做预加载缓存,第一次使用Rule时查数据库并缓存,收到内置Event时更新缓存。 + + + +No Events 检测主要的问题是 Flink 是实时数据计算,他是来一条数据计算一次。无事件本身的的特点就是没有数据推送过来,无法触发计算。 + +这个问题其实已经非常好解决了,我们在告警计算的流程里已经更新每个Rule对应event的最后达到时间到Redis了。我们可以单起一个批处理job简单运算一次即可,逻辑非简单,我测了一下16000个Rule,5个并发度,可以在5s内计算一次。注:带注释才用了不到120行java代码,稍加改进即可在生产上使用。 + + + +最终,我们在解决上述问题之后在阿里云上实现了上述的告警计算平台。 + + + +从某种角度而言 Flink 版本是第一个在 SaaS 上投产的系统,然而,它并不完美,有着上述这些问题。 + +从某种角度而言,Flink 计算告警有些大材小用,我们需要更轻量的架构。(这里中断,展示一下我们的告警系统。) + + + +在 Flink 版本开发3个月后,我们开始着手开发新的企业级告警平台。因为现有的 Flink 版本,因为很多原因无法对外交付。 + +我也是从这个时候开始参与 OneAPM 告警的研发,我们做的第一件事情,就是结合之前 DSL 开发的经验,思考如何重新定义告警规则。这是因为 Flink 上定义的告警规则,就和现有的云迹 CTMAM 的告警规则一样,比较死板,不好扩展,且较为复杂。 + +这期间也参考了 Esper 之类的开源项目,比较后我们惊喜地发现,最好的告警规则定义方式就是 SQL。 + +我们在定义好规则模板之后,便开始由解析计算引擎 -> 处理队列引擎 -> 分布式管理平台 -> 操作接口的顺序 开发了现有的告警引擎。 + + + +首先是基于规则 DSL 的解析计算引擎。之前的 Mock Agent,我们使用的是 Scala 原生提供的语法分析组合子设计的。Druid SQL 使用的是 Antlr4,先解析出基本的 AST 语法树,然后转义为 Druid JSON 查询模型,最后序列化为查询 JSON。 + +这里的告警规则 SQL,我们用的是类似 Druid SQL 的方式。语法模板定义甚至都是类似的。只是增加了四则混合运算表达式的解析和运算,还有 avg 一类的计算函数的实现。 + +最终,它的解析处理流程就和 PPT 图示的一样。规则 SQL 语句被 Antlr4 做词法语法分析,将部分非逻辑单元符号化,然后构建出一棵 SQL 语法树。我们按照 Antlr4 提供的 Visitor 模式,以深度优先检索的方式遍历,然后不断的将结果按照定义的算子单元组合。最后对外暴露出两个方法,一个返回布尔值表示是否满足规则运算定义,另一个返回计算中想要获取的指标数据。 + +我们基于解析出来的规则对象,在 Engine 层对计算的事件队列和当前事件结合起来,就产生了实际想要的计算结果。 + + + +Engine 就相当于最小粒度的计算单元,但是,它缺少一些上下文管理。我们需要事件队列管理,规则和计算数据的关联,才能真正意义上调用 Engine 去计算。 + +基于这个需求,我们开发了 Runtime 模块。它在逻辑上有两大抽象,一个是 RuntimeContext,一个是 EventChannel。 + +RuntimeContext 就和它的名称一样,表示运行时上下文,每个RuntimeContext 对应一条具体的规则示例,内部会维护对应的 RuleTemplate。我们在设计初期就考虑类似多数据源的情况,一条计算规则可能对应多个探针数据,于是内部定义了 InputStream 的概念。 + +它相当于实际的一条计算指标数据流,实际存储在 EventChannel 上,EventChannel 为在内存中存储的一个指标数据队列。它有两块数据:一个是一个 Event Queue,一个是当前才来的一条要计算的指标数据。Event Queue 的设计参考了 Guava Cache 里面的队列,因为规则创建时对应的数据窗口大小是确定的,于是这个 Queue 的大小也是确定的。 + +一个 RuntimeContext 示例可能对应多个 EventChannel,一个 EventChannel 也可能对应多个 RuntimeContext,二者基于一个唯一的 key 关联起来。我们修改规则的时候,需要修改对应的 RuntimeContext。事件来了要计算的时候,是直接 sink 到 EventChannel 中。 + + + +Runtime 相当于 Flink 里面最小的计算任务,有着自己的状态,能解析 SQL 并进行运算。 + +但是对于分布式、集群等部署环境,它还存在着较大的问题。在其之上,我们使用 Akka 开发了核心的运行模块。 + +我们使用 Akka Cluster 开发了计算集群,Akka Cluster 将 Akka 应用分为 Seed Node 和一般 Node。启动的时候,要先启动 Seed Node,才能启动子 Node。但是启动后如果 Seed Node 挂了,Akka 可以选出一个新的存活节点当做 Seed Node。 + +我们在 Akka 集群启动后,会使用 Seed Node 创建 Kafka Message Dispatcher Actor 来和 Kafka 消费数据,然后分发到各个子节点上。这么做的话,同一时刻,只有一个线程在从 Kafka 消费数据。使用单线程的考虑有很多,比如避免 Kafka repartition。其次,我们测试后发现,从 Kafka 消费这块使用单线程不存在瓶颈。 + +每个 Akka 节点都分为 EvenStreamActor、RuleActor 两类核心处理计算单元,EventStreamActor 除了管理 EventChannel 之外,还会将数据分发到别的 Akka 节点,做二次计算。RuleActor 管理 RuntimeContext,其下包含 Persist Actor 将告警事件和应用实时状态持久化到金字塔存储,Alert Actor 将告警数据写入至 Doko MQ 用于接入系统执行告警行为(如短信、邮件、WebHook 等)。 + + + +Jetty模块本身用于暴露接口对外提供规则、事件、数据源管理。和 Flink 版本一样,我们遇到了一个问题就是如何在所有的 Akka 集群上更新告警规则。 + +后面我们的实现策略和 Flink 的版本一样,规则在 Cassandra 上更新完毕后,会以特定的更新消息写入 Kafka 中。这个时期,所有的告警规则配置,使用用户,告警数据源的配置,都保存在 Cassandra 中。因为 Partition Key 的创建不大合理,也给我们在做检索,分页等操作时,尤其是告警事件的筛选,带来了极大的麻烦。这也直接导致我们在 3.0 版本里面将所有的配置数据存于 MySQL,告警事件改为使用金字塔存储。 + + + +基于计算引擎,我们抽象出三大逻辑模块,告警计算和管理模块、告警策略管理模块、推送行为管理模块。 + +1. 计算引擎,也就是前面说的 Runtime 模块那层、它只关心什么规则,基于数据算出一个 true/false 的布尔值表示是否告警,同时返回计算的指标集。 +2. 事件生成引擎,它基于前面的计算结果,还有指标的元数据等组合生成实际的告警事件。2.0 版本只有三种:普通、警告、严重。 +3. 推送行为模块,其实就是配置支持哪些通知用户的方式,在 2.0 里面只有发邮件、执行 Shell,3.0 之后支持 Web Hook 和短信。 +4. 策略模块,就是关联某个规则应该用那些现存的通知配置。 + + + +2.0 版本的告警系统主要是 CEP 计算引擎模块,所以在部署上,他是集成在各个业务系统上的。 + + + +2.0 的时候,告警系统只产生三类事件,普通事件、警告事件、严重事件。我们调研之后发现,其实用户在意的不是这类事件,而是这三类事件相互转换之后产生的事件。 + +于是我们重新定义了告警事件。 + + + +所以我们将告警引擎产生的事件分为两大类:HealthStatusEvent、HealthRuleVolatation 事件。 + +前者就是图上的三个圈,也就是前面的正常、警告、严重。(做鼠标指点状)应用状态从“普通”到“严重”会产生“开启严重”事件。应用状态从“警告”到“普通”会产生“关闭警告”事件,应用状态持续在“警告”或者“严重”会产生持续类事件。我们对于告警的触发配置转为这种状态转换的事件。 + + + +有了前面的设计之后,我们遇到了第一个问题,如何在现行的 Akka 应用上设计一个告警事件状态机。我们想了很多方式,后面我们发现,自己完全想岔了。 + +之前开发的 Engine 模块结合 Runtime 模块完全可以解决这个问题,我们只需要按照之前定义的 8 个事件转换状态定义 8条 SQL,配置三个子 RuntimeContext 即可解决这个问题。比如开启警告事件,它的 SQL 定义如上。也就是之前一个告警事件如果为空或者为NORMAL事件,当前这条事件为警告事件,则生成开启告警事件。 + + + +我们对于不同时间段应用的期望运行情况可能是不一样的,比如一天当中的几个小时,一星期中的几天或者一年当中的几个月。举个例子来说,淘宝应用在周末两天可能会存在较多的交易从而产生高于平时的吞吐量。一个工资支付应用可能相较于一个月中的其他事件,会在月初和月末产生较大的流量。一个客户管理的应用在周一的营业时间相较于周末来说会有较大的工作负荷压力。 + + + +我们在 2.0 的版本开始受制于 Cassandra。 + +一方面,我们建表的时候,为了某些性能在 Partition Key 内增加了时间戳导致查询的时候必须要提供时间区间。另一方面,沿用的是2年前的 Cassandra 版本,无法像 3.0 之后的版本一样有更丰富的查询方式,比如基于某一列的查询。 + +其次,在 2.0 之前的版本,每条指标的计算结果,就算是 Normal 都会存入 Cassandra,这是因为 Flink 版本计算的遗留问题。而我们在设计了告警事件的状态变化告警之后,存储 Normal 变为意义不大。 + +最后,除了告警事件,其他的数据:如规则、策略、行为等配置数据,撑死了也就几十万条,完全没有必要用 Cassandra 来存储。它的使用,反而会增加企业级的部署麻烦。 + +所以我们进行了变更,用 MySQL 去存储除告警事件之外的数据。告警事件因为有了金字塔模块,所以我们直接写入 Kafka 即可。 + + + +为了应对 2.0 版本的接入麻烦,因为构造 SQL、告警通知行为等在 2.0 版本都是外包给业务线自己做的,我们只是打造了一个小而美的 CEP 引擎。所以只有主要的产品 Ai 接入了我们系统。为此,我们把 Ai 中开发的和告警相对于的代码剥离,专门打造了 CEP 上层的告警系统,并要求业务方提供了应用、指标等 API。自行消费处理 Kafka 中的告警事件,触发行为。 + +其次,做的一个很大改动就是适配了各个业务线的探针数据,直接接受全量数据。 + + + +4.0 阶段的告警其实并没有开发,当时主要协作的另一位同事在6月离职,我在8月底完成 3.0 的工作后也离职,但是设计在年初就完成了。 + +我们在开发金子塔存储的时候,很大的一个问题就是如何流式消费 Kafka 的数据,当时正好 Kafka 提供了 Stream 编程。我们使用了 Akka Stream 去开发了对应的聚合应用 Analytic Store。 + +同样,我们希望这个单独开发的 CEP 应用,也能变成 Reactive 化。对应的我们将上下行的 Kafka 分别抽象为 Source 和 Sink 层,它们可以使用 Restful API 动态创建,而非现在写死在数据库内。 + + + +基于这一思想,我们大概有上述的技术架构(图可能不是很清晰)。 + +**设计目标:** + +增加CEP处理数据的伸缩性(scalability),水平伸缩以及垂直伸缩 +提高CEP引擎的弹性(Resilience),也就是CEP处理引擎的容错能力 + +**设计思路:** + +在数据源对数据进行分流(分治);在Akka集群里,创建Kafka Conumser Group, Conumser个数与Topic的分区数一样,分布到Akka的不同节点上。这样分布到Akka某个节点到event数据就会大大减少。 + +在数据源区分Command与Event;把Rule相关到Command与采集到metric event打到不同的topic,这样当Event数据很大时,也不会影响Command的消费,减少Rule管理的延迟。 + +对Rule Command在Akka中采用singleton RuleDispatcher单独消费,在集群中进行分发,并且把注册ruleId分发到集群中每个EventDispatcher里。因为Rule Command流量相对于Event流量太少,也不会出现系统瓶颈。 + +因为RuleDispatcher在Akka集群是全局唯一的,容易出现单点故障。因为RuleDispathcer会保存注册后的RuleIds,需要对RuleId进行备份,这个可以采用PersitentActor来 + +**实现** + +对于RuleDispatcher down掉重启的这段时间内,因为RuleDispatcher分发过RuleId到各个节点的EventDispatcher,因此各个节点事件分发暂时不会受到影响。 +在Akka集群里每一个Kafka conumser,对于一个EventDipatcher,负责把事件分发对感兴趣对RuleActor(根据每个RuleId对应感兴趣对告警对象)。 + + + + + +常见的聚类算法有三类:基于空间划分的、基于层次聚类的和基于密度聚类的方法。聚类算法一般要求数据具有多个维度,从而能够满足对海量样本进行距离(相似性)度量,从而将数据划分为多个类别。其中维度特征一般分为CPU利用率、磁盘利用率、I/O使用情况、内存利用率、网络吞吐量等。 + +1. 相似性度量方法 + +相似性度量一般采用LP范式,如L0、L1、L2等,其一般作为两个样本间的距离度量;Pearson相关系数度量两个变量的相似性(因为其从标准分布及方差中计算得到,具有线性变换不变性);DTW(动态时间规整算法)用于计算两个时序序列的最优匹配。 +其中基于LP范式的时间复杂度最低O(D) + +2. 数据压缩(降维)方法 + +在数据维度较大的情况下,通过数据压缩方法对时序序列进行降维是聚类算法的必备步骤。其中较为常用的数据降维方法有Discrete Fourier Transform, Singular Value Decomposition, Adaptive Piecewise Constant Approximation, Piecewise Aggregate Approximation, Piecewise Linear Approximation and the Discrete Wavelet Transform。下采样方法也是一类在时序序列中较为常用的技术。 +降维方法的时间复杂度一般在O(nlogn)到O(n^3)不等。 + +3. 聚类方法 + +基于空间划分的、基于层次聚类的和基于密度聚类的方法。如 K-means,DBSCAN 等。K-Means 方法是通过对整个数据集计算聚类中心并多次迭代(时间复杂度降为O(n*K*Iterations*attributes)),而Incremental K-Means方法是每加入一个数据项时,更新类别中心,时间复杂度为O(K*n),所以其对初始化中心不敏感,且能很快收敛。 +时间复杂度一般在 O(nlogn) 到 O(n^2) + + + +之前看 Openresty 的作者章亦春在 QCon 上的分享,他谈到的最有意思的一个观点就是面向 DSL 编程方式。将复杂的业务语义以通用 DSL 方式表达,而非传统的重复编码。诚然,DSL 不是万金油,但是 OneAPM 的告警和 Ai 数据分析,很大程度上受益于各类 DSL 工具的开发。通过抽象出类 SQL 的语法,才有了非常可靠的扩展性。 + +Akka 和 Scala 函数式编程的使用,很大程度上简化了开发的代码量。我在16年年初的时候,还是拒绝 Scala 的,因为当时我看到的很多代码,用 Java 8 的 Lambda 和函数式都能解决。直到参与了使用 Scala 开发的 Mock Agent 之后才感受到 Scala 语言的灵活好用。函数式语言在写这种分析计算程序时,因为其语言本身的强大表达能力写起来真的很快。这也是为什么目前大数据框架,很多都是 Scala 编写的缘故。 + +Akka 的使用,我目前还只停留在表面,但是它提供的 Actor 模型,Actor Cluster 等,在分布式平台还是极其便捷的。 + +Antlr4 的学习,符号化与 SQL 生成。在编写 DSL 的时候,最大的感受就是解析与语言生成,它们正好是两个相反的过程。一个是将语言符号化解析成树,另一个是基于类似的定义生成语言。这一正一反的过程,在我们适配旧的告警规则配置数据的时候,感受颇深,十分奇妙。 + + + + diff --git a/src/content/posts/2017/2017-11-13-first-three-month-in-oneapm.mdx b/src/content/posts/2017/2017-11-13-first-three-month-in-oneapm.mdx new file mode 100644 index 0000000..ecdb27d --- /dev/null +++ b/src/content/posts/2017/2017-11-13-first-three-month-in-oneapm.mdx @@ -0,0 +1,57 @@ +--- +title: OneAPM 试用期工作小结(2015年) +slug: first-three-month-in-oneapm +date: 2017-11-12 18:52:46 +updated: 2020-03-01 17:56:43 +tags: + - 工作总结 +category: 编程 +cover: /images/2019/05/2019050902371572.jpg +summary: 最近整理文档,突然看到这份当年写的试用期述职PPT。当时才加入 OneAPM 什么都不知道,姜宁老师带着我步入微服务的大门,知道了 Gateway,了解了 Openresty。 +--- + + + +最近整理文档,突然看到这份当年写的试用期述职PPT。当时才加入 OneAPM 什么都不知道,姜宁老师带着我步入微服务的大门,知道了 Gateway,了解了 Openresty。 + +那个时候是 15 年年底,任何一个东西对我来说都是全新的领域。也借此认识了春哥,认识了今日头条的 Sumory 等人。对我来说这三个月的试用期弥足珍贵,因此我也在此将当时的种种一并分享出来,纪念当时那段年轻时光。 + +[PPT 等文件下载](https://cat.yufan.me/uploads/oneapm-first-three-month-work.zip) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/content/posts/2017/2017-11-13-watashitachi-ha-mokuzaidesu.mdx b/src/content/posts/2017/2017-11-13-watashitachi-ha-mokuzaidesu.mdx new file mode 100644 index 0000000..26c9d2f --- /dev/null +++ b/src/content/posts/2017/2017-11-13-watashitachi-ha-mokuzaidesu.mdx @@ -0,0 +1,88 @@ +--- +title: 我们都是木头人 +slug: watashitachi-ha-mokuzaidesu +date: 2017-11-13 01:52:05 +updated: 2019-05-18 18:41:21 +tags: + - 人生 + - 抉择 + - 北漂 +category: 杂思 +cover: /images/2019/05/2019051818392913.jpg +summary: “唉,你还真是一个不安分的家伙啊!”电话那头的老妈无可奈何地宠溺道。此时还是八月初,火辣辣的太阳炙烤着大地,北京西小口软件园东边的花坛边开满了月季等鲜花。 +--- + + +“唉,你还真是一个不安分的家伙啊!”电话那头的老妈无可奈何地宠溺道。 + +此时还是八月初,火辣辣的太阳炙烤着大地,北京西小口软件园东边的花坛边开满了月季等鲜花。池塘里一群鸭子正在那争抢着午休员工投食的馒头,让这本该静谧的大热天增添了一抹生气。 + +此时的我,才和老妈通完电话,在这短短的30分钟的时间里,做出了对我来说极为重要的决定——离开北京,回南京工作。 + +<MusicPlayer netease={441116287} /> + +为何离职?为何离开?很多人问过我,我也给出了不同的回答。对同事,我的说法是回家结婚生子。对朋友,我说北京空气太差,想回南京健康点。对家人,我说新房快交房了,想回来准备装修…… + +从 14 年 7 月大学毕业到决定离开北京,已经整整北漂 3 年整,北京从来就不是我心里能够长待的地方。当时毕业的同学要么出国,要么保研、考研、公务员,要么就回家乡发展。只有我一个人从为数不多的 Offer 中挑了一份看起来还行的去了北京,同学当时都笑道,雨帆你要住地下室了。然而,我还义无反顾地放弃了父母早就准备好的“前程”,选择从来没有去过的最北边,北京。 + +在我看来,无论是吃喝穿住都不愁的厦门,十分稳定的济南校企,还是那各种意义上都十分繁华的大上海,都不是我向往的地方。它们要么就是在家边上离家近,要么就是看不到发展的前景。我的骨子里,还是向往冒险,向往诗意和远方。 + +我渴望离开父母身边,渴望逃离这烦闷无趣的大学生活,渴望拥有自己的收入。这一次,我没有听任何人的劝诫,一个包,一把伞,一个箱子,一个人,坐着最便宜的绿皮车硬座,来到了北京。 + +朋友,你见过北京早上 5 点钟的太阳么?我见过。 + +那个时候的我,为了省钱,住在离公司 27 公里外的上地,公司在南三环的万通中心。每天天没亮,我就得早早爬起来和 60 多个人争抢 2 个水龙头洗漱,然后在西二旗那一眼望不到边的地铁排队大军中蹒跚而行。下班到家时,也已经是晚上 9 点。 + + + +在易宝支付的一年半里,为了攒钱,我基本在公司睡觉不回家。因为这样可以省下一天 5 元的地铁费用,同时还有最高 25 元的晚餐补助。省一点,一天的开销基本为 0。每天在公司加班,就是看当天别人提交的代码,看别人写的设计文档。到了夜里 11 点,关掉一层楼的灯,在前台旁边铺好地铺睡到 8 点保洁阿姨来上班。然后起来洗漱,在工位上趴一会,开始新的一天工作。 + + + +那个时候的我,基础比别人差得太多太多,什么都不会,代码也没怎么写过。每天对我而言,除了学习看书工作,就是睡觉。工位后的柜子上摆的书越来越多,一本、两本,十本、二十本,一书架……每本书都基本看完。 + +我记得有一天晚上 2 点我还在看正则,CEO 余晨从我们那排走过,关心地问我,怎么这么晚了,还在加班,而且只有一人。那一瞬间,我突然想哭,在这离家2000多公里的土地上,第一次感受到来自别人的关怀。虽然只是简单的问询,但是,那个时候才接手银行路由,又出了大大小小很多事故,真的很苦闷。 + +这期间从[柏涛](http://im47.cn/about.md)这位前辈那里学会了很多,他是我至今都十分佩服和嫉妒的前辈,比我早 2 年入职,在各个方面都十分优秀,完美地简直不是人。在公司,加班最狠、最多的就是他,不论是节假日,还是周末,基本都能在公司工位上看到他。晚上还和我争抢监控室的小床,逼我打地铺,哼! + +时间很快到了 15 年年底,我所在的部门要拆分,基础架构部基本名存实亡,老大包旺也有意出去单干。当时对我来说,是恐惧的,我那微乎其微的技术能力,真不知道还能干什么,易宝的基础组件也基本看了个遍,没有什么新的好玩的东西。于是,我选择跳槽。 + + + +去面试 OneAPM 前经常在图灵社区上看到它们的“广告”,Software Design 和 Web DB Press 上也能看到它和知道创宇两个公司的招聘信息。对我而言,它是陌生而又神秘的。去东升科技园面试前一天才下了雪,从永泰庄地铁站走出来,扑面而来的除了冷还是冷,在公司窝了 1 个月没出门的我不禁打了一个寒战。因为地图导航的错误,我得绕整个园区一圈才能到 OneAPM 那,漫行在银装素裹的东升科技园,就好像进入了一个白茫茫的世界,看不到出路,一如我当时迷茫的思路。 + +到了目的地后发现,OneAPM 真的很小、很小,小到它的面试,只能在前台旁边的茶几上进行。然后,我见到了职业生涯中的另外两位导师,姜宁老师和晓光老师。当时我并不认识姜老师,只是人力说他很厉害云云。姜老师面试我的时候,只是考察了几个简单的尾递归,问问我会不会写 Scala 和一些简单的技术问题。然后,便是晓光的二面。我至今记得和他第一次见面的场景,个子不高,戴着一副粗绿框眼睛,满脸胡子,像是几天没洗漱,风尘仆仆地走过来。屁股一坐,开始审阅我的简历。那一瞬间,我突然有了一种被人看透的恐慌。 + +很快,我便入职 OneAPM,才入职期间,人员走了很多。部门一大批人去了杭州,回来的只有几个。招进来几个,也很快走了。最后,招我的人力也离职了,当时让我一度十分恐慌,我是不是掉坑里了。唯一能接触的用户系统的代码写得十分可怕,让我甚至对公司的技术研发产生了质疑。虽然每天都是在学习研究姜老师给我安排的新东西,但是心还是揣着的。直到友国入职后,才算是稍微安心下来。 + +友国当时从搜狐畅游跳槽过来,入职的原因很简单,在这可以写 Scala。在他眼里 Scala 天下第一,Spring 什么的 Akka 秒了。他一入职,便和张健一起写 Mock Agent,将那个我原来就看不大懂的项目,写得更让我看不懂。后面他维护用户系统,用 Play + TS2 强行写了一版管理后台,现在想想都是个坑。 + + + +OneAPM 很小,甚至说很穷,公司所有的开支大头,就是人员工资,很多硬件条件很差。但还是愿意支出很多钱让海珊姐姐去参加国外大会,将最新的 APM 领域的东西给大家分享。CEO 和大家讲话分享,都是站在凳子上。 + +易宝支付有一句话叫做“一群人的浪漫”,在这里才真正意义上体会到了其中的种种,无论是姜宁老师给我们扩宽的技术视野,还是晓光那强悍的编码设计能力,抑或是友国天天喊着的 Scala 大法好,殷湘老师教会我如何写测试用好 IntelliJ IDEA。对我来说,都是职业生涯中难得的财富。 + +在易宝支付的一年半,大都得靠自己,老大包旺(包大人)并不能给我太多的指导,后来的老大锁文强能把通道运维好已经不容易,还要为我背通道事故的锅。来了 OneAPM 之后,太多新的东西,太多挑战,很多技术,一出来你可能就能看到在 OneAPM 里面的应用,让人有学习的动力。 + +**那么为什么要离职呢?** + + + +> 我在延静里租的小房子,一个小餐厅改造的客厅,放了一张桌子和一张床,仅此而已。为了好看,没有拍床。 + +因为,北京从来没有让我有安定的感觉。无论你是在繁华的三环内,还是充斥互联网公司的海淀,抑或是百度总部的西二旗上班。当你忙完一天,带着浑身疲惫回到家里,北京的恶意就会迎面袭来,让你无所适从。洗到一半热水器坏了没有热水,因为没有钥匙被锁在门外一晚,通勤时间高达 2 小时的路程……这些种种,总让我在北京找不到任何归属感。我只能在工作中麻木自己,让自己像木头人一样,不去想,不去看。 + +电话里,老妈常说的话就是,你又买了XXX,到时候你是要搬家的,还不是要扔掉! + +于是在 2016 年 10 月,纵然房价那么高,我还是做出了人生中第一笔大额消费——买房。交完订金的那晚,我和父母绕着即将建好的小区走了很久很久。谈不上高兴或者激动,只是心突然安定下来,就好象是茫茫大海中有了一座灯塔,你能看到方向,并且知道该往哪里走。 + +于是在今年 8 月底,即将交房的前夕,我回到了南京开始另一段工作旅程。 + +昨天看最新一期暴走漫画,王尼玛对那个咨询父母不让考研的小孩说,你要学会自己思考,自己去争取想要的东西来向父母证明他们错了。我想,我就是他口中那个不安定又矛盾的小孩吧,一方面,想趁着年轻出去闯闯;一方面,又对各种琐碎觉得委屈要找人求安慰,容不得半粒沙子。 + +然而,很多事情,也只有经历过,吃过亏,才知道对错与否,不是么? + +**谨以此文纪念我那已逝的三年青葱岁月。** + + diff --git a/src/content/posts/2017/2017-12-14-leave-some-by-myself.mdx b/src/content/posts/2017/2017-12-14-leave-some-by-myself.mdx new file mode 100644 index 0000000..fb1c5a5 --- /dev/null +++ b/src/content/posts/2017/2017-12-14-leave-some-by-myself.mdx @@ -0,0 +1,57 @@ +--- +title: 总得给自己留下点什么 +slug: leave-some-by-myself +date: 2017-12-13 18:41:55 +updated: 2021-11-23 18:15:12 +tags: + - 思考 + - 代码 +category: 杂思 +cover: /images/2019/05/2019050902332168.jpg +summary: 网易云音乐一直是一个值得吐槽的地方,比如,它常常会认为你懂五国语言,动不动给你日推一些稀奇古怪的歌曲。因为我会日语,所以日推的大部分都是日文歌,还可以接受网易云音乐一直是一个值得吐槽的地方,比如,它常常会认为你懂五国语言,动不动给你日推一些稀奇古怪的歌曲。因为我会日语,所以日推的大部分都是日文歌,还可以接受。但最近网易云音乐开始变本加厉,给我日推俄文歌,这实在是不能接受。 +--- + + +网易云音乐一直是一个值得吐槽的地方,比如,它常常会认为你懂五国语言,动不动给你日推一些稀奇古怪的歌曲。因为我会日语,所以日推的大部分都是日文歌,还可以接受。但最近网易云音乐开始变本加厉,给我日推俄文歌,这实在是不能接受。 + +一般我熬夜时,都喜欢开着网易云音乐听歌,不是说我多喜欢音乐,而是为了防困。精力专注的时候,歌曲就像是一种微噪音,你根本感知不到。有时也会听到一些不错的歌曲,下载收藏。 + +<MusicPlayer netease={812400} /> + +周一时听到一首名为 **[「PLANET」](http://music.163.com/#/song?id=812400)** 的歌曲,前奏就十分抓耳,当时就立刻点击下载,可惜这歌竟然要付费。生在天朝,仗着自己从事 IT 相关的工作,最大的好处便是能免费搞到一些数字出版物。但我在谷歌、百度上查找甚久,竟找不到此曲的 320 Kbps 版本,不禁有些沮丧。 + +在网易的「チーズ牛丼」(沙拉牛肉)上找到一篇关于「PLANET」的创作组合**「ラムジ」**的[介绍](http://music.163.com/#/topic?id=17639053)。 22 岁的山下佑树在过生日的时候,只因想要唱点什么东西来到东京,和报复不得施展的井上慎二郎桑如童话般在雨中相遇,并开始了长达 8 年的演艺事业。 + +> 当時、井上慎二郎に初めて出会ったとき、雨に濡れて震える子羊のような容姿だった為、当時の山下のイメージから羊を連想し、アニメの子羊キャラクターからラムジと命名。 +> +> 当时山下佑树遇到井上慎二郎,看到他被雨淋湿的姿态,联想到了动画《ラムヂーちゃん》里“子羊”这一角色,因决定采用ラムジ这一名字为组合名。 + +一切都是那么巧合、随性,连乐队名都是以上面这么哭笑不得的[缘由][wikipedia-link]命名。然而,不是每个梦想都能瓜熟蒂落,ラムジ在 12 年便[宣布 13 年解散][oricon]。我翻遍他们为数不多的专辑、单曲,喜欢上的,也只有那首「PLANET」。 + +可我还是不死心,我能感受到歌曲里那种热情和呼唤,那种渴望展露头角被大众所关注认识的心情。因为现在的我和当时的主唱山下佑树年龄相近,我更能感受到山下先生的期盼与绝望,两种矛盾心情交织下的悲伤心境。我翻遍脸书、推特、所有我所知道的社交网络,却没有找到任何关于山下佑树的信息。他随着ラムジ的解散,消失在大众眼里。即使是推特上,也很少有人提起。 + +可是我还记得,就和他们的歌还在被人听被人唱一样,我还记得这么一个乐队,如流星般存在过。 + +--- + +前些天翻推特,看到有人说,大部分代码的存活时间只有 5 年不到。回想自己目前接手过的很多老项目,的确如此,在 OneAPM 上班的时候,兄弟部门的系统,一年重写了 2 次。自己维护的系统,也因个人的审美变化,在一年内留下了 3 种不同风格的代码。 + +如果说乐队的解散,还能留下当时传唱的歌曲,那么程序的重写,可能就是彻彻底底的消失。那么,作为程序员,我们还能留下什么呢? + +**我想,只有编程思想吧。** + +记得 4 个月前带小弟写的 [SQL Generator](https://github.com/byWeaponLin/sql-generator)。核心的思想便是对当时业务 DSL 的抽象封装,还有函数式的变换思想。即使后面这部分代码废弃,我想它的定义还是能好好传递给每个维护过它的人吧。这个设计思路再精进,便是在[Language Implementation Patterns](https://pragprog.com/book/tpdsl/language-implementation-patterns) 里面提到的解析与生成的两种形态,虽然SQL Generator 独立于底层的解析器开发,但是最后二者的抽象结构,是惊人的一致的。 + +同样的说法可以应用于程序设计的很多地方,比如说单元测试。我以前一直不知道什么是测试,怎么写测试。后面有意识地学习模仿后发现,单测无非也就是三大步。构造测试对象、测试数据,调用方法,断言。 + +测试对象有些可能是 Mock 的接口,但一定不能是 Mock Static 的对象,存在的话说明你的代码抽象存在问题。测试数据,也叫样本,关键在于能命中边界条件。而断言,无非就是各种 `true` `false` `equals` 的判断,hamcrest 之类得无非是简化了判断过程而已,但切记慎用 Mock 里面的 `verify` 做断言。 + +所以说,测试代码,再怎么变,逃离不了上面的编程方法,即使是别的编程语言,亦是如此。我很费解的是,在苏宁,看到我的同事写测试的时候,写的是一个 `main` 方法,用 `System.out.print` 输出结果人肉判断。因为上线有单测覆盖率要求,竟写出了针对实体 `Getter` `Setter` 方法的测试代码。这种测试代码,有存在的意义么? + +有时我觉得,编程就是一种体力活,想好了怎么设计,后面的编码加测试,纯粹是一种[肝][moegirl]的状态。有时候又觉得很多代码纯粹是套路(模板代码),只是因为某些需要不得不这么写。正如标题所言,总得给自己留下点什么。我希望给自己留下的,是那些有意思的设计思路,而不是那些**「垃圾代码」**。 + + + +[wikipedia-link]: https://ja.wikipedia.org/wiki/%E3%83%A9%E3%83%A0%E3%82%B8_(%E6%AD%8C%E6%89%8B) +[oricon]: https://www.oricon.co.jp/news/2020043/full/ +[moegirl]: https://zh.moegirl.org/%E7%88%86%E8%82%9D diff --git a/src/content/posts/2017/2017-12-24-teruteru-1.mdx b/src/content/posts/2017/2017-12-24-teruteru-1.mdx new file mode 100644 index 0000000..33ed1f0 --- /dev/null +++ b/src/content/posts/2017/2017-12-24-teruteru-1.mdx @@ -0,0 +1,254 @@ +--- +title: 晴天娃娃(第一话) +slug: teruteru-1 +date: 2017-12-24 10:42:47 +updated: 2019-05-18 18:16:47 +tags: + - 晴天娃娃 + - 小简 +category: 小说 +cover: /images/2019/05/2019051818154567.jpg +summary: 送你一个晴天娃娃,你若安好,便是晴天。记忆太散,故事太杂,我无法把那么多细枝末节串成一串,只能略带总结地回想。就好比花间十二声,你看着四季的风云变化,记述着个个回味的故事…… +--- + + + +送你一个晴天娃娃,你若安好,便是晴天。 + +记忆太散,故事太杂,我无法把那么多细枝末节串成一串,只能略带总结地回想。就好比花间十二声,你看着四季的风云变化,记述着个个回味的故事…… + +## 零、缘,起 + +故事那么长,写到关于你时,却又无话可说了。或许,本就不是会写故事的人。我们,终究什么也不算,对你的喜欢,还是败给了时间。承诺那么长,所有的约定都忘记了,或者与我无关。不管永远有多远,都要好好的幸福。 + +我想把这些心情写给你,算是我给你的礼物。因为故事写在纸上,总会有结局,而放在心里,等不到结局…… + +<p style={{ textAlign: 'right' }}>——致小简</p> + +## 壹、缘,分 + +小雨在学校公告栏后面偷偷贴上自己抄来的情诗:“我曾爱过这世上最美的侧脸!青春里的那么多思念,年少时的种种自以为是,可等到遇见你时,早已错过了你说的无爱不欢的年纪。” + +小时候,小雨总是喜欢围在妈妈们身边,听一些家长里短。很久之后,听小简分析儿童心理学,小雨才明白,人的性格都是打小养成的。小雨喜欢自己打小就养成的心灵手巧、文静安逸,但多愁善感的性格总感觉要不得。 + +也许,这就是有那么多父母要注意胎教的起因。教育,不仅仅是要从娃娃抓起的。 + +书上说的,十岁之前的小孩子没有性别之分,只有童性。有一个笑话讲的是,“医院里两个刚出生的婴儿在摇篮里,其中一个问另一个,‘你是男孩还是女孩?’另一个摇头。于是第一个爬过去看了一阵后回到自己的摇篮里对第二个说,‘我知道了,你是女的,我是男的。’知道为什么吗?因为你穿的是红袜子,我穿的是蓝袜子。”当小雨把这个故事讲给小简听的时候,电话那头的小简不置可否。 + +传统文学老师说过,喜欢一个人,便要给喜欢的人讲笑话。那样就可以让自己喜欢的人每天都很开心。可是书上说的,所有的青梅竹马,都等不到彼年花开。不是因为彼此之间的不喜欢,只是因为太喜欢。 + +远处传来清远的笛音,恍恍惚听不清,品不出音调中的喜怒,心中却莫名凄苦。一个人,太寂寞,难免会想什么。小雨想这个时间小简应该会在自习室埋头苦读,两耳不闻窗外事。 + +想起自己第一个真正喜欢过的女孩,留着及腰的长发,浅浅的微笑。所以已经过了这么久,小雨还是喜欢在人群中留意有长长的头发的女孩。那个名为蓝雪的女生,只因为对小雨说过一声“谢谢”,便被小雨深深地喜欢上了。 + +那年,小雨六年级。 + +缘,分。 + +## 贰、缘,散 + +有一天,小雨在QQ上对小简说“我喜欢你”。小简问“喜欢什么”时,小雨却一时语塞,想了好久,还是不知道喜欢的是什么。其实,有些时候,连说喜欢你,都是一种奢求。明明可以感觉到的喜欢,却迟迟不愿意说出口。自以为是的结局,只有听到,才会刻骨铭心。 + +就像小雨曾经骨气勇气给蓝雪写的信,一封又一封,最后有一天,还是忍不住送了出去。那以后的日子,小雨总是怀着忐忑的心情。研究说人在空闲的时候总是会忍不住看时间,那段时间,小雨会以猜中手机上的时间为一种运气。而与蓝雪不期的相遇,被小雨当作了生命里一场又一场永不落寞的电影,背景是泛红的落日,又或是昏暗灯光下黄绿色的法桐。 + +美术老师说过,生活里不是缺少美,而是缺少发现美的眼睛。但当她面对小雨那抽象得一塌糊涂的大作时,却实在是发现不了什么地方是美的。也许这就和小雨认为所有的与蓝雪的不期而遇,只是因为每天都要在固定的时间去教室,固定的时间去吃饭,仅此而已。 + +故事里面的那么多的坚持,只是因为彼此喜欢了吧。爱一个人或不爱一个人都不是说说就可以算的,总要给自己一个机会,习惯着放弃和接受。可故事毕竟是故事,所有的主角,只不过是女生,与小雨无关。 + +在不懂爱的年纪,我们便已爱得死去活来,遍体凌伤,所有的措辞,只是因为第一眼的喜欢。曾经,总是要把喜欢和爱的界线分得那么清,一个天南,一个地北,没有交集,老死不相往来。谁说的,爱是淡淡的喜欢,喜欢是浅浅的爱。小雨总是以为,喜欢了,便要在一起,不喜欢,就算在一起,什么也算不上。可还是会为了那种浅浅的习惯所伤,努力付出了,却只是幻想。 + +小雨在人群里找了一个又一个长得像蓝雪的女孩,因为知道长得像,所以知道不是她。物是人非,所以可以毫不顾忌地盯着你,可某天终究是不能再骗自己,会遇到一个让自己不好意思面对的女生。 + +**过了那么多年,小雨依旧还是个害羞的小男生啊!** + +## 叁、路人 + +初中毕业聚会的篝火映红了小雨的脸,因为靠得太近,脸上有种灼热的感觉。彩色的锡纸泛着翠绿的光,有种妖艳的色泽。那些一起有过交集的日子,在初中毕业分开之后,总是忘不掉,却也不能时时被想起。放在心里,落了灰尘。最后要那么努力才可以从新想起。 + +谁说的,忘记一个人要比记得一个人更容易?小雨以为要用喜欢蓝雪等长的时间来忘记她的。忘记那个夏日,在宿舍门口看见她在水池边晾长长的头发。忘记春日里她在柳树下静谧的笑,洒了阳光,安静而好看的侧脸。忘记…… + +小雨以为自己都懂的,所以从来都没有说过喜欢,可结局早就已经被预见。每次早操都会偷偷看她的侧脸,每次相遇她总是会低着头。写信告诉她,不喜欢她额前的刘海,不喜欢她戴眼镜的样子。她的回信,看了好多遍,可每次看,都还是那么认真,也从来不曾读懂。 + +开始和蓝雪的舍友熟悉,没有拘束。小雨偶尔会在信里面问候她们,叫她们姐,偶尔会坐在一起聊天,话题简单,相互之间关心一下,见了面打个招呼,摆摆手。后来,蓝雪搬到学校旁边住,不再坐同一辆班车回家,日子久了,小雨渐渐地忘记是什么时候那么认真地喜欢过。只是,偶尔会在中午吃饭时听见蓝雪班里的人偶尔说起谁喜欢谁,听的人不置可否。那是年少时我们最喜欢玩的把戏,在一起说着谁喜欢谁,其实在意的人是自己而已。 + +看着火苗燃尽,小雨把那根发丝也一并投到了火里。 + +蓝雪在信里说,知道头发是别人要了之后给小雨的,可还是给了。那信的最后,为什么还是说:“让我们做最好的朋友?” + +有些话不说,我们就可以永远地在一起,算是朋友叫做蓝颜。可是还是说了出来,最后,我们成了路人,天南地北老死不相往来。 + +## 肆、放手 + +初中毕业后,小雨与蓝雪去了不同的学校,失去了蓝雪的消息。后来小雨听人说,原本两人都分到了同一所高中,只是蓝雪,转去了别的学校。没有结局,便匆匆放弃了。 + +小简说:等待,不是要等某个人回来,而是找个理由让自己不离开。可小雨还是满怀期待,两所高中就算不能在一起,可还是会预见。错过便不再遇见,所以遇见便不能错过。 + +再后来,蓝雪到小雨的学校找原来的同学玩,彼此便又见过几次。蓝雪剪了头发,依旧留着长长的刘海。小雨被人叫了过去见面,而两人之间却什么话也没有,连一句简单的问候都不愿意说出口了…… + +原来有好多话,都只能写在纸上或者在心里默念。所以小雨会在心里无数次的构想过见到蓝雪之后该说些什么,可真正见面时,却又一句话都说不出口。 + +总有些感情是要被遗忘掉的。曾经的刻骨铭心、海枯石烂,终究是抵不过时间的流转。一个人的独角戏,谢了幕,连眼泪都欠安。 + +小简说:小雨,你就像个宝宝一样可爱。这句写在离别赠言上的话,让小雨开心了一夜。 + +想没想过,喜欢你的和你喜欢的如果不是同一个人,你会选择谁?恋爱本来就是自卑者的游戏,总是小心翼翼地守护着微不足道的幸福。所有爱过的爱错的,终不过是自己的一厢情愿,终究还是自己受不起。 + +## 伍、过客 + +小雨注意到小简,是转到三十班后很长一段时间之后的事情了。 + +那时小雨带着老大的不情愿回到熟悉的一中,就是在这破败的校园里度过初中三年时间。时隔半年,又回到这熟悉的谷底,可伊人不在,唯有相思。原以为刻骨铭心的喜欢,其实,什么也不算。 + +很久之前就有学长开玩笑说,谈恋爱要趁早,不然好的都被抢走了。小雨想,也好,就用三年的时间来忘记蓝雪,与喜欢等长的时间,刚刚好。那时小雨第一次发现可以在校园里找到那么多熟悉的面孔,原本陌生的感觉也一点点地消逝。 + +日子仿佛依旧沿着原来的轨迹,不会因为谁的出现或消失发生什么变化。依旧是紧张而繁重的学习,偶尔上课看小说,课间会做懒懒的广播操,会有无所事事的体育课,晚上宿舍里的打闹。 + +忘记一个人最好的方法便是喜欢上另一个人。而每个人都是有故事的人…… + +盈盈在打扫卫生时捡到吉祥写的情书,偷偷地看了。吉祥一味的单恋,便在班里天下大白了。不过当吉祥告诉小雨这件事让他帮忙时,小雨还是有些吃惊。帮忙这种事,记忆里好多人都做过,虽然实践告诉我们,最后那么多送花使者,都成了护花使者。 + +那时,我们的认识是那么的狭隘,一个人,谁先说喜欢便可以占为己有,虽然爱本来就是自私的。 + +小雨偶尔会跟着吉祥逛街,两个男孩,压过长长的马路,玩着Stand By Side(一部美国铁道电影)。小雨很少自己买东西,在餐厅吃饭时都要犹豫好久才能做出决定。每次吉祥问小雨关于衣服的观点,小雨都只能给出一句不置可否的回答,找不出任何可用的意义。 + +有次吉祥拉着小雨去看手饰,挑着各种的耳环、戒指,又想起好久之前妈妈说过的送给姥姥娘一副豆瓣坠的事,还被夸很好看。妈妈说当时很高兴,只是早已是物是人非了。小雨早已习惯用忘记来逃脱痛苦了,只要不被提及,便可以安逸地苟活,直到最后便自以为真的忘记了。 + +盈盈说不许小雨叫自己盈盈,所以那之后在一起的日子里,小雨只叫盈盈猴子。盈盈的名字:侯盈盈。猴子说,连那个谁,都没有允许他叫自己盈盈。 + +谁说名字只是一个称呼?至少我们会在意某些人对自己的称呼,想让我的手机号在你的电话薄里有最亲昵的名字。 + +那个谁,指的应该是大婶,小雨的上铺。 + +高中男女不相往来的怪圈里,小雨以为三十班是个特例,因为他听过那么多女孩的故事。可故事总是故事,不是心事,自以为是。那么多年之后,对着熟悉的群组,却很少有人能出来说一句话。好多人都已忘记了名字,原以为熟悉的人群,只不过有三五个女生。 + +花了那么长的时间来看忧伤的文字,小雨唯一能想起的只有小四在《夏至未至》里写下的:那个男孩会教会我成长,那个女孩教会我爱。 + +原来,可以在记忆里留下名字的,只有可数的几个人。 + +那个喜欢过你的人,永远比陪你说话的人更重要! + +## 陆、八卦 + +每晚还是在宿舍里各种八卦,偶尔小雨会给大家讲蓝雪的事。吉祥跟袁袁的关系不咸不淡,因为大家都不怎么喜欢袁袁。小雨想告诉大婶猴子应该很喜欢他。不过时间、情节都不对,每次都会逗大婶说关于猴子的事情,心满意足地听他喊一声“滚”。 + +吉祥说,袁袁喜欢班长,老毛。老毛就是宋国庆,据说生在国庆节,不过没人承认。吉祥说袁袁为了毛写了整本周杰伦的歌词。吉祥说他知道袁袁喜欢初中时的班长,毛是高中的班长,所以爱屋及乌地喜欢。喜欢一个人,就会不自觉地留意关于她(他)的一切。可更多的是臆测,越得不到,就越害怕失去。 + +每晚,说完大婶,便会扯到吉祥的暗恋,可宿舍里的人都不喜欢袁袁。喜欢一个人便注定了会义无反顾,喜欢上所有的优缺点,至死不渝。 + +小雨和袁袁是初中同学。小雨想起刚转到十三班的时候,袁袁他们那一群老同学便开始七嘴八舌地介绍班里的情况。袁袁介绍到班长时,已经顺带说出老毛已经有喜欢的人。喜欢一个人,连他喜欢谁都已经知道的一清二楚。有好多话,我们没说出口,我们以为别人会懂的,就像喜欢。可有时候却又要假装不懂,永远可以在一起,心与心的距离,不远,不近。 + +高二开始,分班前的一场课,吉祥在讲台上唱《就是爱你》,同学们都在下面起哄。年少时的那点心思,谁也藏不住。对于谁喜欢谁之类的话,总是会很快就传开。又是用多大的勇气,孤注一掷。 + +可是喜欢,与浪漫无关。 + +小雨总是以为,吉祥与赵楠在一起,是不是有一部分原因是要报复袁袁。喜欢一个人,便是用自己所有的好来疼她,可从没想过那是不是她想要的。 + +后来那么长的日子里,小雨听吉祥说着自己与赵楠的一切,每次碰见他们在食堂里吃饭。冬天,吉祥会去校门口买烤地瓜在教室里等着赵楠,放假时回早起送赵楠坐车回家。小雨相信吉祥喜欢上赵楠了,因为喜欢一个人,才愿意为她做所有的事。 + +只有被喜欢,才会被接受。 + +## 柒、换座 + +雪雪说,调整座位的时候要和小雨一桌。 + +高中班主任从大一一开学就开始严防死守,争取要把一切早恋扼杀在摇篮里。但却从来没有想过,这就像治水,堵不如疏。就好比大家常说的段子,我十年后连Log(n)是什么都不知道,但照样活得好好的,我们学的和我们工作需要用的知识,从来都不是同一种玩意。 + +文理分科的前一个月,不知道是不是对于恋爱控制结果的绝望,班主任破罐子破摔,允许大家自主协调座位。 + +后面小雨上了大学,工作。看了无数部青春电影,听了无数遍同桌的你,却总是忘不了那个要和自己同桌女孩——雪雪。雪雪总是喜欢开小雨的玩笑:小雨,你为什么总喜欢笑,那么开心。每次说完,总会装作大人的样子深沉地叹口气。 + +那个时候雪雪和文娜一桌,吉祥说要和小雨一桌,但是小雨更喜欢和雪雪一桌。于是最后变为小雨告诉文娜,吉祥要和你一桌。 + +但是,有了这么多的努力和借口,最终,都没有变为我们在一起同桌的理由。 + +换座位的努力,最终还是无疾而终。 + +不知道是不是因为即将分科,即将走向不一样的未来道路,那个时候,整个教室都是人心惶惶的。换座位,需要班长和团支书的同意,那个时候,老毛是班长,袁袁是团支书。小雨想和雪雪一桌,却最终还是没有勇气说出来。所以,就算多年后老毛和雪雪分手了,小雨和雪雪,什么也算不上。 + +吉祥说,老毛小心眼的很,就像他不能允许赵芳与以前的同学说话一样。 + +## 捌、路人 + +星子是小雨的初中同学, 在毕业的同学录里写到:“我们算不算得上是个朋友?”那个傻傻的,说过几次话,在小雨和蓝雪的信中偶尔提及的女孩。自从初中毕业之后,便再也没有了联系。同学录里面的联系方式,又有几个能长久,又有几个被人尝试? + +孙超有一次问小雨,为什么会认识他的前女友星子?那个时候,小雨一愣神,又想起蓝雪,那个名字和雪雪相近的女孩…… + +就算是过了那么久,那么久,某些人,还是会被你记得。 + +女孩子喜欢让她笑的人,可真正爱的,却是让她哭的那个坏蛋。可是小雨怎么舍得让蓝雪哭呢?所以也只好守着她的微笑,看着她在人人网上晒着的满满幸福。 + +## 玖、坏蛋 + +宝很幸运地成为了被小雨带坏的唯一一个坏孩子。那个时候,小雨转到了三十班。周边的同学,除了原来熟悉的初中同学,还多了一个人,便是宝。这让小雨一度有种幻觉,宝是自己的高中校友。 + +那个时候,小雨迷上了看小说,盗版的网络小说,路边摊买的,很厚的一大本。每买一本回教室分享时,围观的除了所谓的坏孩子,偶尔也会出现宝的影子。一来二去,宝和小雨成了好朋友。宝走读,小雨住校。在忙碌的高中生活里,走读生和住校生的交流玩到一起的,一般很少,很少。 + +记忆中的高中似乎十分漫长,宝与小雨看了无数本小说,坑了无数把Dota,吃了学校里那么多难吃的馒头,也由此认识了许多许多女生。 + +这个时候的女生宿舍因为学校扩招,位于校外,很多女生中午都不会回宿舍,而是选择买好饭在教室里吃。小雨跟着宝,在教室蹭过很多女生的菜。后来小雨回想起这段往事,还不得不感谢宝,如果不是他在,小雨在三十班里能说得上话的女生,不会超过五个。 + +宝后面喜欢上小美,是在文理分科之后。那个时候小雨从来没想过宝会喜欢小美。因为小雨经常看见小美和别的男生在一起打打闹闹。知道宝喜欢小美的,除了小雨,还有一个女孩——宝的同桌小苗子。偶尔小苗子会拿小美的事打趣宝。 + +他们常常会因为这件事斗嘴,吵闹,甚至一度让小雨产生一种他们在恋爱的错觉。然而,小苗子和宝的关系一直很好,很好很好,却也只是朋友。 + +宝偶尔会和小雨说一些关于小苗子的事情,偶尔也会说,他一直都喜欢着小美。那个时候,已经高中毕业很久了。 + +最后一次联系宝,他说,他遇见一个叫小迪的,和小美很像,他要和小迪在一起了。 + +## 拾、如果当时 + +吉祥偶尔提起,孙超和石玉好了。小雨一脸茫然,彼年,小雨在石玉和孙超中间,却完全没有发觉。 + +其实,好多人,好多事情,总是与你无关的。曾想要那么努力地进入其中,最后,终究还是过眼云烟。时间久了,联系少了,关系便越来越淡了。流年里所有喜欢过的人或物,终究还是要搁浅。那时的岁月,如指尖砂轻轻划过,握紧时划痛手心,错过时,才知道喜欢的味道。 + +就好比学长谈起投资时,拿一见钟情举例,说一见钟情就是那种投资快,见效快。完全不符合社会规律,终究不会有什么好的结果。然而,不管过了多少年,小雨还是为QQ里阳阳的笑所打动。因为,喜欢一个人,不需要什么理由。想起的,总是第一次喜欢的样子,第一次被打动的瞬间。 + +小雨对阳阳说,“忘记一个人的方法就是喜欢上另一个人。”阳阳说,“那你好好努力,让我喜欢上你忘记他。” + +小雨告诉宝,他网恋了。喜欢一个人的时,便想让最亲密的好友知道,得到他们的祝福。就算是不喜欢,有没有一刻,会为某个人感动,想要牵起她的手,天荒地老? + +小雨不知道,小雨只记得把《如果当时》的歌词抄给阳阳时,语音里的阳阳笑着说,“好喜欢这首歌,谢谢。”不由想起了以前那个对自己说谢谢的女孩,阳阳说:“自己也留着长长的头发。” + +开始喜欢上阳阳,偷偷地给阳阳设置了隐身对其可见,每次看见阳阳的灰色头像跳动,小雨总是觉得两个人之间有些小隔阂。却从未想过自己从来不曾隐身,隐身对其可见形同虚设。 + +多少年后,小雨在聚餐玩真心话大冒险时,对一个女生说:“我喜欢你,你喜欢我吗?” + +那么是什么时候开始,对女生说喜欢也不会脸红了? + +很早之前,小雨问阿太:“老和女生打电话都是说些什么?”那个时候,阿太和他妹保持每天两个小时飞信,两个小时电话。小雨说,阿太嫣然成为一个可以顶礼膜拜的对象。 + +其实,小雨只是厌倦了每晚与阳阳那么长的通话…… + +## 拾壹、分手快乐 + +幸福,一直都是自己要找到却又得不到的东西。柏拉图的永恒里面说的,“喜欢一个人,只要能陪着,看着她幸福就可以了。”说的也许就是这样的情形吧。习惯了喜欢,习惯了习惯。谁和谁说好的,相互陪伴,终老一生? + +“你说害怕让我看见你白发的样子,最后连你的样子,都没有看见。”错过了,便是错过了。 + +小雨开始给阳阳打电话,相互沉默。偶尔会发一条短信祝彼此晚安,可那么亲昵的话,无论如何也开不了口。说过一百零一次晚安的人会一辈子在一起,就像是一个一千零一夜的童话传说。 + +小简在小雨的世界里那么突兀的出现,在小雨就要快忘记蓝雪的时候,突兀到让小雨回想起那么刻骨铭心的喜欢。 + +小简说:“一个人心里只能放得下一个人的位子,连其他人的影子,都找不到位置来搁置。”那个曾经那么喜欢过的影子,就这么远了。爱情里,多一点点,便已是一场错过。 + +最后一次和阳阳通话,她哭着对小雨说:“你也曾经喜欢过我吧。” + +电话里阳阳哭起来的声音,有点哽,让人有种心酸的感觉。小雨想起阳阳曾经说的,你喜欢的女孩一定有好看的侧脸,因为我喜欢你说的那句“我曾爱过这世上最美的侧脸。” + +> “你说让我喜欢上你,真的做好了。” +> +> “你给我写的歌词,我好喜欢。” +> +> “晚安。” +> +> “你有没有,喜欢过我,哪怕一瞬也好?” + +时间过了那么久,小雨忘了是哪个混蛋说过,“放手,让彼此好好的过。”一直以为说祝福是最假的东西。就像是阳阳对小雨说,她的前男友又来找她了,他们又在一起了。 + +原来,说祝福真的很假。尽管,最后还是没有把祝福的话说出口。 + +> “小孩,我们的幸福,只能是我给的。” + +曾经那么多我们爱的人,最后都爱不了。曾经那么多爱我们的人,最后都不爱了。 + +那个为自己流过泪的女孩,就那么不在了。 diff --git a/src/content/posts/2018/2018-01-13-teruteru-2.mdx b/src/content/posts/2018/2018-01-13-teruteru-2.mdx new file mode 100644 index 0000000..bac155c --- /dev/null +++ b/src/content/posts/2018/2018-01-13-teruteru-2.mdx @@ -0,0 +1,176 @@ +--- +title: 晴天娃娃(第二话) +slug: teruteru-2 +date: 2018-01-13 11:42:41 +updated: 2019-12-06 15:06:29 +tags: + - 晴天娃娃 + - 小简 +category: 小说 +cover: /images/2019/05/2019050902101874.jpg +summary: 小雨曾在笔记本的扉页上写道:“樱花不及樱桃,相见不如想念。”彼时大明湖畔的春天,似乎在下着一场樱花雪,小雨在电话这头跟小简说,本来想在今天去见你的 +--- + + + +## 拾贰、樱花开了——小简 + +小雨曾在笔记本的扉页上写道:“樱花不及樱桃,相见不如想念。”彼时大明湖畔的春天,似乎在下着一场樱花雪,小雨在电话这头跟小简说,本来想在今天去见你的。而两人相处的十九公里的距离,遥远地像是天各一方。最后,只能是相忘于江湖,老死不相往来。 + +多年以后,小雨又想起那年春天,有点惆怅,又有些欢喜。错过了一场花雨中漫步的浪漫,换来了一个星期的顺延。 + +小简说:“小雨,你是我的蓝颜。” + +“失去了你,只是因为你换了手机号,把我从你的好友列表中删去,会不会忘记我比做这些还要容易?”小雨早该习惯忘了小简的。只是,每次在快要忘记的时候,她总是会出现,在快要喜欢上她的时候,再消失…… + +小雨在与蓝雪分开后曾想写一个故事。关于自己的故事,幸福总是会让人变懒散掉。小雨只相信着痛苦过后的人生感慨,看过一本又一本印着青春文学的书,相同的故事,会遇见不同的影子。 + +小简说:“小雨你快点写出来,我第一个看。” + +可是,我们把那么多的沉默当作默认,那么多的沉默当成喜欢。那么轻易地忘记自己许下的承诺,却又害怕别人忘记对自己的承诺。 + +谁又在乎得了谁的在乎? + +最后连最后也忘记了。 + +> 小简对小雨说:“他要和别的女人结婚了,可是为什么被辜负的是她自己?” +> +> 小简问:“相不相信这个世界上的存在某种诅咒,能让他立刻死去。” +> +> 小简说:“小雨,谢谢你陪着我说话,**我们是最好的朋友。**” + +小雨看了小简那篇日志,她说:“八十岁之后,'她'死了,我便可以和他在一起了,没有人能挡在我和他之间了。” + +宝说过,喜欢一个人便是从看他的日志开始的。 + +多年以后,你未嫁,我未娶。我们可不可以在一起? + +## 拾叁、毕业季 + +我们轻易说过的永远,永远都抵不过时光。 + +那年夏天,小雨看着小简说,以后记得照一张照片给我。要侧脸的,还要有满满的阳光。 + +那年夏天,小雨还是没有和雪雪一桌,就算那以后那么长的日子里。小雨每次见到雪雪还是喜欢拍一下她的头。年少时我们有那么多亲昵的暧昧,不知是无意还是刻意。 + +那时候老毛已经和文娜在一起,一起吃饭,在不长的校后林荫散步,一起去水房打水。 + +距离小雨烧掉用一个暑假写的一整本日记的信,已经一整个夏天一整个冬天了。 + +雪雪高三分班后的教室就在小雨的教室下面,有一次先是雪雪一个班都感冒了,后来了小雨一个班也跟着感冒了。 + +我们从来不知道,其实,我们每天都呼吸着相同的空气。心和心的距离,为何如此遥远呢? + +高三毕业后,娟才告诉小雨她早已不再上学。之前她告诉小雨的所有关于学校的故事,都只是故事而已。 + +此时正是大学第一年的寒假,吃完年夜饭,窗外是鞭炮的噼里啪啦,屋内是爸爸妈妈的家长里短。小雨抱着手机,耗光一格又一格的电,像是海中即将溺死的鱼。只是谁也没注意到,小雨眼中执意不想落下的泪水。 + +娟说,她现在也在看春晚,顺便绣一对抱枕。 + +后来小雨与小简说起娟,说到这段往事,小简在电话那头说她也在绣一对抱枕,她要和“他”结婚了。 + +你永远猜不出自己有多少勇气做到自己永远做不到的事情。小简说起自己的故事,一个人,一生中第一次坐那么久的火车,去一个从未踏足的陌生地方,去见他的家长。 + +分开半年,谁也没有忘记谁。只是不管遇到谁,都让小雨伤心。 + +## 拾肆、忘记 + +高中三年,小简与娟做了两年同桌,第三年,楼上楼下。 + +小简说起高三时两个人在一起的过往,而小雨关于她们的记忆,都留在那个夏天,之前之后,早已成了空白。 + +高一那年,小雨和吉祥注意到娟,吉祥开玩笑说,让娟和他在一起。 + +但仿佛对某些人,从一开始,便注定了认为不合适。不管怎样,都不认为两个人之间会在一起。所以,两个人在小雨的同学录里,都写下了同样的话:“小雨,下次见面,要记得领一个漂亮媳妇给我们看。” + +那些说好的记得的幸福,永远都与我们无关,故事从开始到结尾,都只有你、我这两个称谓,从不曾出现过我们。 + +记忆里那么亲昵的举动,也不过是只限于课间说会话,偶尔见面会拍一下头。仅此而已,都不算得了什么。 + +许多时候,那些我们认为一辈子都忘不了的东西,就那样轻易地被忘记了。 + +记得一个人,恨永远比喜欢来的久些,因为不恨了,所以不爱了。 + +故事到了最后还是故事,只是到了最后,忘了是什么故事,什么是真实出现过的现实。梦想交织过后的现实,留着你的影子,其他的,都已看不见了。 + +**Bad End!** + +--- + +> Happy End 线过渡章节 + +## 拾伍、那年多时 + +阳光穿过攘攘的人群,透过一幕幕剪影,脑海中映出的一个个面孔,或喜或悲。 + +喧闹的夜晚,不够晴朗的天空,躁动的空气充满了不安分的因子。人群中那么多的欢闹,只不过是散场的前奏,留下的,记住的,那么多年以后还剩下什么呢?剩下的,只是些对那年那些青春岁月的怀念,还有偶尔会想起的你好看的侧脸。 + +最后,我和你还是走失在人群中,像极了缘分两个字。却永远都不是,都不可能在一起。 + +当毕业晚会唱到《老男孩》的时候,小雨想这个时候应该会有很多人哭。坐在会场后排,只听得见音响传来的响动,夹杂着间或响起的掌声以及人群里的私语。 + +因为有太多的人站在凳子上,挡住了小雨的视线看不清晚会的横幅。但是猜也能猜到,应该有“毕业生”和“晚会”两个词,在昏暗的灯光下若隐若现。台下那么多的喧嚣,让人看不出任何分别与不舍,也许从这里离开时的我们,还有着我们的梦想,我们喜欢的人。 + +还是,所有的美好,都只是强颜欢笑? + +社团换届大会上,小雨猛然发现,不久之后,便要作为学长迎接可爱的学弟学妹们了。 + +离遇见你,已经过去一年了。 + +喜欢你,只是一时兴起,等着你爱上我,却是那么地痛苦于甜蜜。偶尔看到一张书签,等待,不是等某个人回来,而是找个理由不离开。 + +已经要那么努力才能够想起我以前幻想的我们的未来。 + +搁下笔好久了,写不成想要的故事,总是变成说教的文字。你,会厌烦的吧。 + +## 拾陆、记忆里的故事 + +年少的我们路过那个叫做花季的季节,等我想起你的时候,所有的花已经谢了。 + +驻在过道里上仔细,微风,偶尔有阵大风卷过,吹起桌上的试卷,飘出好远,也不会有人理会。 + +小雨又想起娟好久之前说过的,已经是大人了,要穿成熟的衣服了。而记忆里,小雨很少看见女生穿裙子的样子,又错过了一场花季里美好的回忆。 + +妈妈在家翻箱倒柜地倒腾出小时候穿的衣服,准备丢掉。有那么一个瞬间,小雨想要把衣服留着,给自己未来的孩子。 + +可以那么笃定未来不曾谋面的孩子会长得很可爱。记忆里会想起自己小时候穿着裙子招摇过市的样子。 + +可放在记忆里那么久了,久到自己都会怀疑记忆里会不会出现问题。 + +小雨一直都像是女孩子,那么小心眼。——不是故意要把女孩子和小心眼牵扯到一起。 + +看书的时候不喜欢在书上留下折痕,看到别人弄皱自己的书会心痛。呵呵,现在的书纸张好厚,不用担心了。 + +相信一切关于美好的传言,就算错过了一场有一场流星雨,还是坚信对着流星许愿会实现。因为小雨自己许下的是:我们永远在一起。 + +想让自己喜欢的人喜欢上自己的所有,书、电影、笑话…… + +偶尔会想,会不会在我放弃喜欢你的时候,你喜欢上我? + +某年,你问起为何笑得越来越少。我说,总是笑会变老的。我们说过的那么多话,说不清楚了,误会了,又怪谁呢? + +亲爱的,你不在我身边,我怎么笑呢? + +## 拾柒、幸福的样子 + +小雨想起那年在同学录上写下的自己想要的礼物是一条手链。很少有见男孩子戴手链的,小时候小雨总是喜欢在手腕上画一个小小的手表。就那样靠在父母怀里撒娇耍小脾气。 + +一转眼,自己已经长大了。 + +已经有好久,不再撒娇了。 + +很久之前编好的那一对手链,还在抽屉里,褪了色,沾了灰尘。洗了很多遍,还是没能洗净。 + +也许,永远都不会去买一个招财猫送给云儿来补一个生日礼物,也永远会欠她一个晴天娃娃。 + +好多东西,不是说说就可以算的。 + +一直都没说过,祝你的幸福,是要由我来给你的。不是一时兴起,心血来潮。 + +可不可以,某天,让我看见你的幸福是什么样子? + +那些与你有关的心情,开心的,不开心的。伤心的,不伤心的,都跟你没有关系。 + +已经可以不用假装便可以忽略掉。 + +**Happy End** diff --git a/src/content/posts/2018/2018-01-19-three-stage-of-programming.mdx b/src/content/posts/2018/2018-01-19-three-stage-of-programming.mdx new file mode 100644 index 0000000..9c634ce --- /dev/null +++ b/src/content/posts/2018/2018-01-19-three-stage-of-programming.mdx @@ -0,0 +1,31 @@ +--- +title: 編碼三境界 +slug: three-stage-of-programming +date: 2018-01-19 09:20:12 +updated: 2019-05-18 18:13:36 +tags: + - 思考 + - 编码 + - 编程 +category: 编程 +cover: /images/2019/05/2019051818123745.jpg +summary: 很多人停留在第一階段,也就是能寫出來,能用。但是代碼邏輯不精簡,質量一般,同時雜亂無章。典型的特點是寫之前毫無想法,隨想隨寫。 +--- + + + +編碼三境界: + +``` +由少寫多 (開始懂得寫代碼) +由多寫少 (有意識地精簡優化邏輯) +由少寫多 (理解抽象設計) +``` + +很多人停留在第一階段,也就是能寫出來,能用。但是代碼邏輯不精簡,質量一般,同時雜亂無章。典型的特點是寫之前毫無想法,隨想隨寫。 + +第二階段是指,有意識地去精簡邏輯,簡化思路。但是代碼因為刻意地精簡,反而不好維護。寫出來的很多細節異常考慮均不到位。很多人甚至走上刻意追求簡潔的道路,寫出極其難看的麵條代碼。 + +第三階段,寫之前需求清晰,考慮到了各種未來擴展可能,適度抽象,邏輯條理。好的代碼,不一定是最簡潔的代碼,但一定是最好維護的代碼,同時也是最好擴展的代碼。 + +所以,我發現一個特點,好代碼,其編程風格都是相似的。寫代碼關鍵在於思路,在於你想要什麼,要寫什麼。沒想法寫出來的代碼,再好看都沒用。 diff --git a/src/content/posts/2018/2018-12-22-hanabi-ga-hana-jyanai.mdx b/src/content/posts/2018/2018-12-22-hanabi-ga-hana-jyanai.mdx new file mode 100644 index 0000000..6988ab3 --- /dev/null +++ b/src/content/posts/2018/2018-12-22-hanabi-ga-hana-jyanai.mdx @@ -0,0 +1,43 @@ +--- +title: 烟花散 · 花非花 +slug: hanabi-ga-hana-jyanai +date: 2018-12-22 13:15:51 +updated: 2019-05-18 18:13:56 +tags: + - 时光 + - 烟花 +category: 文章 +cover: /images/2019/05/2019051818094781.jpg +summary: 花非花,雾非雾。夜半来,天明去,来如春梦几多时,去似朝云无觅处。最难解的的确是闲愁,才去春花,落红满径,便有月照窗纱,倦理琵琶的愁情。 +--- + + +花非花,雾非雾。夜半来,天明去,来如春梦几多时,去似朝云无觅处。 + +最难解的的确是闲愁,才去春花,落红满径,便有月照窗纱,倦理琵琶的愁情。 + +自古愁情如一江春水流不尽。黛玉惜花、葬花,叹花无觅处。花开花落本自然之理,黛玉却愁上眉头,吟出“侬今葬花笑人痴,他年葬侬知是谁”的凄凉。李清照夫妻相别苦相思,独自一人把酒黄昏后,闲愁甚是撩人,消得人比黄花瘦。 + +闲愁似水般剪不断。春去时添一段闲愁,撩人窗前披月;雁过时寄一份闲愁,思念断人肠。一声长叹,倒不如对酒当歌,去了肝肠寸断,换得醉意朦胧,且管他欲说还休的闲愁! + +--- + +<MusicPlayer netease={777203} /> + +世间的沧海桑田的变化就像那奔马般匆促,谁的生命会永远停在烟花绽放的瞬间?谁又会悄然隐去,竹林深处,留一抹孤寂而洒脱的身影? + +杨家女一朝选在君王侧,以一顾倾城,再顾倾国姿色使君王从此不早朝。箫鼓声声,长夜尤梦,似这般恩宠骄奢的生活永无尽日。奈何“渔阳鼙鼓动地来,惊破霓裳羽衣曲”,君王有心无力,终被赐死马嵬坡以塞天下怒!尘埃落定,繁华散尽,阴阳两隔。旧事如流水,过往如烟云,道不出荒凉。 + +世变无涯,是陆游笔下与唐婉重逢时的悔,是杜牧“十年一觉扬州梦,赢得青楼薄幸名”的自嘲,是张爱玲笔下曼桢14年的生死别离。 + +一掬清泪,缠绵了亘古的哀怨。 + +--- + +岁月的脚步不停地惊扰悠远的长梦。佛说“世人不知有因果,因果何曾饶过谁”。看不透这世间的因果,便尝尽苦楚,换得人蒙尘,心蒙垢。 + +生命不过是张爱玲所说的一袭华美的袍,盛装而来,如转瞬即逝的烟火,争得刹那辉煌。 + +既然人生注定如戏,也就没什么可黯然的了。黛玉虽苦,却耗尽宝玉一生的真情。琵琶女虽苦,却有“五陵年少争缠头,一曲红绡不知数”的年少。如花虽怜,还有一低眉,一抬眼的两情相悦。 + +浮生如梦,却也终有不愿醒的时候,叹的是看戏人,迷的是戏中人,各有烟花尽落的快活。 diff --git a/src/content/posts/2019/2019-07-05-wagahaihanekodearu.mdx b/src/content/posts/2019/2019-07-05-wagahaihanekodearu.mdx new file mode 100644 index 0000000..9695966 --- /dev/null +++ b/src/content/posts/2019/2019-07-05-wagahaihanekodearu.mdx @@ -0,0 +1,33 @@ +--- +title: 吾輩は猫である +slug: wagahaihanekodearu +date: 2019-07-05 06:29:06 +updated: 2020-09-06 16:20:40 +category: 文章 +cover: /images/2019/07/2019070506303116.jpg +summary: 初次看到《我是猫》这本书应是5月下旬的一个周末,在芜湖西西弗书店有关于它的预售活动,买一本送一套日式清酒杯。可惜当时忙着赶回杭州,只能作罢。 +--- + + + +## 缘起 + +初次看到《我是猫》这本书应是5月下旬的一个周末,在芜湖西西弗书店有关于它的预售活动,买一本送一套日式清酒杯。可惜当时忙着赶回杭州,只能作罢。再次看到此书,是和女朋友一起逛书店的时候,见她喜欢便买了一本予以赠送。 + +## 书名 + +其实大陆出版社很早便有出版夏目漱石的《吾輩は猫である》,可惜销量并不好。这几年受日本ACGN文化影响,部分传统经典日本文学著作得以多次再版。可不管再版几次,此书书名都坚持叫“我是猫”,让人极度不喜。可以说,从书名翻译开始,便丢了灵魂。 + +记得才学日语时,第一件事情就是**自我介绍(自己紹介)**,常见的表达句式为是**私(わたし)は〜です**。但是说多了会让人感觉你多以自我为中心,所以一般表述里省略“我”,直接说**~です**。 + +“我”的表述方式在日语里面有几十种,此书书名里用的是**吾輩(わがはい)**,其实是过去一种相当高傲的自我称呼。翻开大辞林可以看到它的释义:古風で尊大な言い方であり、現在では余り用いられない。“吾辈”这个词,源于日本古代老臣在新帝面前的谦称。明治前后,“吾辈”这个词流于市井,类似中国评书中的“在下”,孙悟空口里的“俺老孙”,还有自鸣得意的“咱”,以及“老敝”等。而中文语系里面的吾辈,不管是文言文还是现代文,含义都为“我们”。 + +可以说外语的翻译对于每个译者来说,都是一种痛苦而又美妙的过程。一方面,想要尽可能地用母语准确表达原文的意思,另一方面,有些更深层次的含义,非原文母语使用者不能体会。 + +比如在日语里面有两个词都表季节,一个是**季節**,另一个是**シーズン**。前者多表示具体的四季,春夏秋冬。后者多为某种活动的时候,比如旅游旺季之类的。所以春天三四月多为樱花盛开的时候,也是恋爱的季节,我们理论上应该用**恋愛のシーズン**来表述。上次看到一篇文章用的是**恋愛の季節**,一开始觉得奇怪,后面仔细体会,它暗含了恋爱也有类似的春夏秋冬,高潮低谷的意思。这样的含义,用季节,是很难表述清楚的。 + +同样的情境还存在于其他语言的翻译,比如 present 既有“礼物”也有“现在”的意思,有些时候便会合在一起用:**The present is a gift. And I just wanna be...**。当下即为礼物,一语双关妙不可言。 + +前面对于书名的过度追究,可能在很多人看来有些过于咬文嚼字,其实不然。猫这种生物,和狗不同,在生活中给予大多数人的印象就是,冷漠高冷,生人勿近的形象。如若能读懂书名,一只小猫咪的形象便会跃然浮现于脑海之中了。 + +对于书名的讨论,仅限于此罢,至于内容,留予下回分解。 diff --git a/src/content/posts/2019/2019-08-12-blind-date-review.mdx b/src/content/posts/2019/2019-08-12-blind-date-review.mdx new file mode 100644 index 0000000..25a3a36 --- /dev/null +++ b/src/content/posts/2019/2019-08-12-blind-date-review.mdx @@ -0,0 +1,33 @@ +--- +title: 内网相亲帖观感 +slug: blind-date-review +date: 2019-08-12 09:09:02 +updated: 2019-08-12 09:09:47 +category: 文章 +cover: /images/2019/08/2019081209080689.jpg +summary: 常看内网相亲帖,看的目的是什么呢?不是为了找姑娘,因为我已经订婚。看的目的更多是思考,思考什么呢? +--- + + + +常看内网相亲帖,看的目的是什么呢?不是为了找姑娘,因为我已经订婚。看的目的更多是思考,思考什么呢? + +思考当下女生对男生需要什么,思考这样的女生为何还是单身,思考如何让自己更加有竞争力(大雾)。 + +其实说点实在的,一个女生到了 28 岁以后,还是单身就要思考:“为何她还是单身?”这个问题。对于我们这个阶段身边大多数女生而言,在她们 24 岁毕业起就会开始被人安利对象(如果单身的话),这种安利一般在 28 岁到达巅峰。这个年龄段女生会发现,自己就像是大白菜,谁都想给你安利头“猪”拱一下。 + +如果在这个年龄段还没有找到满意的,很有可能,就会更难找了。(别急着反驳,后面有详解。)这个世界对于女生还是有些刻薄的,因为摆在所有适龄女性面前的都会有生小孩这个环节。男生一点都不傻,过了 28 岁最佳生育年龄,后面再生育,其实是一年不如一年的。所以,你会发现,过了这个岁数,会越来越没人愿意找你谈恋爱,相亲对象质量越来越差。 + +从某种角度上,年龄也不是问题,成熟知性的大姐姐们对于男性的吸引是全年龄秒杀的。某种程度上,可以毫不客气地说,对男生的吸引力上:年龄小又知性可爱的小姐姐 > 年龄成熟又知性的小姐姐 > 年龄小可爱但不太懂得照顾人 > 老阿姨。 + +所以看内网的相亲帖就很有意思,大部分女孩子都会对男生有所物质要求,大部分都会说自己喜好美食或者是旅游。收入不高,但是满世界跑的比比皆是。所以作为男生就有点感慨,女孩子们为何单身,答案呼之欲出。看到被加爆的热帖,更能说明如此。 + +理想是丰满的,现实是骨感的,很多女孩子,化妆(粉底、眼妆、隔离、防晒、高亮、口红、腮红、眉毛)自拍加美艳加滤镜加 P 图后自己就认为上天了。然而,大部分女孩子,其实都用错了地方,你能接触到的人的上限,基本就是你找男朋友的上限。这个世界不存在那么多的吴彦祖,你也不是张曼玉,如果没有绝世容颜,与其把钱花在“蹦迪”、“美食”、“化妆”上,不如更多打磨自己的内在。这才是你有吸引力的根本。 + +所以看到内网相亲贴的时候,更多的是感慨,她为何要这么介绍自己啊,她到底需要什么样的男生? + +其实男孩子也不傻的,能在阿里工作的大部分程序员,虽然部分情感上可能单着,但是看热帖也知道对姑娘想要什么的。单身交友版块,就像是一个菜市场各取所需,只是作为旁观者心态来看,会觉得很有意思。 + +> 男人有钱就要颜,女人有颜就要钱。婚姻爱情若儿戏,丢了容颜失了钱。 ——甄士隐 + + diff --git a/src/content/posts/2019/2019-11-29-gossing-on-winter.mdx b/src/content/posts/2019/2019-11-29-gossing-on-winter.mdx new file mode 100644 index 0000000..2650a52 --- /dev/null +++ b/src/content/posts/2019/2019-11-29-gossing-on-winter.mdx @@ -0,0 +1,57 @@ +--- +title: 冬日碎碎念 +slug: gossiping-on-winter +date: 2019-11-28 18:44:49 +updated: 2020-11-19 19:20:40 +category: 杂思 +cover: /images/2020/11/2020111918513875.jpg +summary: 今年的雨好像特别多,就比如前天半夜,突然间就电闪雷鸣,窗帘没有拉好,于是就可以清楚地看见一道闪电以及随之而来的巨大的雷声 +--- + + + +不知什么时候,冬天悄然登场。 + +今年的雨好像特别多,就比如前天半夜,突然间就电闪雷鸣,窗帘没有拉好,于是就可以清楚地看见一道闪电以及随之而来的巨大的雷声。我尽力不去想一些可怕的故事或者电影桥段,把自己严严实实地裹在被子里,慢慢睡去。第二天一大早起来,就看到路上厚厚的洁白的雪,满心欢喜,于是再回想起昨晚的电闪雷鸣,也不再心有余悸。 + +对我来说,漫天飘散的雪花或许是冬天带来的最好的礼物了。从小就是这样。虽然惧怕冬日的严寒,却因了雪花的降临,对冬天多了一份期待。很多时候,对于很多事,也有相似的感觉,期待、害怕,害怕、期待……如此循环往复。 + +最近的天气,冷,有风,很少见到太阳,这让我想到几米说的一句话“那年的冬天,特别寒冷,整个城市笼罩在阴湿的雨口。灰蒙蒙的天空,迟迟不见着阳光,让人感到莫名的沮丧,常常走在街上就有一种落泪的冲动……但是冬天总会过去,春天总是会来。” + +我不知道这样的天气是不是很容易让人感到失落或者沮丧,反正我是不喜欢这样的天气,就好像整座城市都被笼罩在阴霾里,找不到出口。我想这时候是应该有一束光的,有一束具有穿透种种阴霾迷雾的力量的光,驱散阴霾。但是,这束光还未曾出现。在这样的天气下,人的心情也是压抑的吧,像有什么堵在胸口,想找一个空旷的地方,大声笑或者大声哭,甚至简单的大喊一声,心里就会轻松许多的吧。 + +在这阴冷的雨口就特别怀念阳光的味道。这让我想到了十几年前的一个夏天,正午时分,阳光强烈耀眼,我从小姨家院子里走过的时候,有些意外地听到了绿豆在烈日暴晒下发出的清脆声响,然后嘴角就不知不觉上扬了。时至今日,那时的场景依然清晰可见,阳光很充足,人的影子很短,急着进屋的我被突如其来的声响止住了脚步,然后时间定格,思维脱节,鸡鸣狗吠、蝉声虫鸣都被隐去,世界归于寂静,唯有清脆的哔哔啵啵的声响在阐释着生命的力量。 + +而此刻,阳光终日短缺,空气有些浑浊。不过 好在,冬天总是会过去,春天总是会来。 + +我不知道从什么时候开始就和你断了联系,试过很多办法可还是联系不到你,你不会就此消失了吧。其实,我找你没有什么重要的事情啦,只是想知道你最近过得好不好而已。 + +还记得那天我满心欢喜地编辑好短信想告诉你我们这里正在下雪,却在微信里找了半天也没找到你的名字,于是就有点小小的失落了,然后把那条编辑好的消息 Delete 掉。再次遇到你,要了你的微信号,保存好。 + +下午去公司加班,有太阳的余光,可是连温暖都称不上,路上有风,不过还好。周末公司人很少,一个人在工位落了脚,办公室的灯光有些暗,空调一直开着,感觉不冷也不热,温度刚刚好。 + +“丢进海里的瓶中信,总是失去踪影。是被鲸鱼吃掉了吗?还是又漂到另一个无人岛屿?这种随波逐流的缘分,除了青春浪漫的孩子,又有谁会相信呢?”那么,你相信吗?这种随波逐流的缘分? + +我想,我是有些相信的吧。不然,和你,和你们的相遇相识,又该如何解释呢?从小学到现在,认识多少人了呢?可是在听到某首歌,看到某个场景,想到某个地方,提到某句话的时候,总能在第一时间想到你,是不是很神奇?只是希望在光阴流转,年复一年的平淡日子里,You are always with me 一直在我身边。可是,这算不算是一种奢望呢? + +> “生命中,不断地有人离开或进入 +> +> 于是,看见的,看不见了;记住的,遗忘了。 +> +> 生命中,不断地有得到和失落 +> +> 于是,看不见的,看见了;遗忘的,记住了。 +> +> 然而,看不见的,是不是就等于不存在? +> +> 记住的,是不是永远不会消失?” +> +> ——几米 + +梁静茹的《情歌》,一遍又一遍。不知为什么,最近比较迷恋这首歌。 + +The future that we have been so nervous and curious about is bright in our hearts. + +那些我们一直惴惴不安又充满好奇的未来,会在心里隐隐约约地觉得它们是明亮的。 + + diff --git a/src/content/posts/2020/2020-03-07-the-sun-in-march.mdx b/src/content/posts/2020/2020-03-07-the-sun-in-march.mdx new file mode 100644 index 0000000..1baac66 --- /dev/null +++ b/src/content/posts/2020/2020-03-07-the-sun-in-march.mdx @@ -0,0 +1,55 @@ +--- +title: 三月的阳光 +slug: the-sun-in-march +date: 2020-03-07 05:54:22 +updated: 2020-11-22 11:25:25 +category: 杂思 +cover: /images/2020/11/2020111919163265.jpg +summary: 今天又是阴天,我怎么觉得我好久都没看见阳光了呢。三月已经到来了,早就春天了吧。我怎么感觉我还没看到小区里的花开呢? +--- + + + +今天又是阴天,我怎么觉得我好久都没看见阳光了呢。 + +三月已经到来了,早就春天了吧。我怎么感觉我还没看到小区里的花开呢? + +去年的这个时候,早就换上春装了吧,怎么今年我还在老家穿着棉衣呢? + +从过年到现在,新冠的疫情遍布中国大地,四处一派萧条景象,这真的是春天吗? + +…… + +总是有这么多奇怪的事情发生,像极了这个变幻无常的世界。 + +印象中的春天应该是这样的。有刚长叶的树,刚吐绿的草,刚绽放的花,刚回来的鸟;有流动的水,和煦的风,温暖的阳光;有奔跑的孩子,放飞的风筝,晨练的老人…… + +这些,不知道有没有出现,只是我没有看到也说不定。 + +于是乎对江南小巷心向往之。绵长的雨巷,湿漉漉的青石板路,有些湿润的天气,小桥流水的景象……江南的那些最古朴,最自然,最平常的景象,对我总是有着很大的吸引力,那里就像是一方净土,干净透明,未染尘埃,超脱凡俗。 + +总觉得那里,是容易发生故事的地方,比如一场意外的邂逅,一个美丽的传说,一段短暂但又珍贵的回忆,一个尘封多年不曾解开的谜底。于是又不自觉的给她涂上一层神秘的色彩。 + +我总是在想,有生之年,要去那里感受一番。在最安静,最美好,最与世无争的地方,哪怕只是闭上眼睛感受耳边的风,洒在身上的阳光,空气里花的味道,我也很满足了。 + +一直对一个电视剧的桥段念念不忘。 + +“公车的秘密我只告诉你一个人,你为什么不喜欢我? + +朱莉的绳子我只让你一个人牵,你为什么不喜欢我? + +那一句话太过珍贵,所以我从来舍不得说,那么,我以后是不是再也没机会说了?” + +Jeremy 像一个可怜的孩子,他带着哭腔说完了这一番话,他说 当公车在回到原点的时候,他也要回到那个快乐的 Jeremy。当他跳下公车转过身来的时候,我看到的是他灿烂的笑脸以及还未风干的泪痕。 + +这样的事情在现实中是不是也真的可能发生呢? + +自己那么小心翼翼喜欢的人,可以分享自己最最珍贵东西的人,知道自己小秘密的人,因为太过珍贵所以从来不舍得说那句话的人,突然之间,在你不知道的时候,已经喜欢了别的人,那么,你是否也会在公车绕了一圈之后,又回到原来的自己呢。我想,即使能够做到这一点,心里的伤痛恐怕只有自己知道吧。脸上是笑着的,心却哭了。 + +现在的天气和早晨一样,阴天没有阳光;心情和早晨一样,平静没有波澜…… + +生活仿佛总是一成不变,但是昨天我看到了喜欢的衣服,吃到了喜欢的东西,每天晚上躺在被子里是我最幸福的时刻,可以边写代码边听自己喜欢的歌,发现自己喜欢上了龙应台的文字。《红楼梦》终于快看完了,接到好朋友的电话,家人都很平安……于是我发现,生活还是很美好的啊。 + +窗外是久未放晴的天空,我很想念阳光的味道。 + + diff --git a/src/content/posts/2020/2020-10-15-round-bowl.mdx b/src/content/posts/2020/2020-10-15-round-bowl.mdx new file mode 100644 index 0000000..de5e164 --- /dev/null +++ b/src/content/posts/2020/2020-10-15-round-bowl.mdx @@ -0,0 +1,39 @@ +--- +title: 碗 +slug: round-bowl +date: 2020-10-15 10:23:02 +updated: 2020-11-19 19:31:44 +category: 文章 +cover: /images/2020/11/2020111616333446.jpg +summary: 传统的中国人有一种,可称之为“碗筷崇拜”的习惯。比如过年,讲究给家里添加碗筷,寓意增人进口,祈祷家道兴旺。 +--- + + + +传统的中国人有一种,可称之为“碗筷崇拜”的习惯。 + +比如过年,讲究给家里添加碗筷,寓意增人进口,祈祷家道兴旺。 + +比如碗碟磕破不能用,不会简单丢弃,而是裹上红纸或缠上红布条,再放在外面,一是表达对器皿的感激敬畏;二是希望有需要的人可以拣去经补锡之后再使用——锔碗是一门手艺,应该是非遗项目,现在不常见。那些将紫砂壶装上豆子,浇水发芽后使其自然胀裂再经精工锔补,镶以别材的有意之作,就是利用的这个手艺。有一出非常好看的评剧《锔碗丁》,演的就是老北京齐化门外以锔碗为生的丁家的故事。 + +我喜欢传统的碗盘碟盏。造型无不是圆形的,只在色彩、高低、深浅、花色等方面做文章,所谓“万变不离其宗”。北京的老式餐厅里那种有宫廷风格的餐具就很好看,也耐看。 + +碗盘碟盏,以圆形为正,无论容量、制作、使用等角度,都是法天象地,得乎其正。 + +我很不习惯,甚至说很鄙视当今时尚餐厅的时尚餐具,造型非常怪异,什么怪样的都有,把不是餐具的其他东西制作成瓷器便成了餐具,总之就是不愿意用规规矩矩的圆形。有的菜上来,菜没多少,盛菜的器皿倒占了近半个桌。往往菜没点几个,但很快台面就放不下了。怪异求变,以正圆为耻,以奇崛为尚,正是本末倒置,反客为主,以下犯上,恶紫夺朱,浮糜伪矫甚矣。 + +这种望规矩则厌、见奇异则喜的风气,对消费者是迎合,也是刺激。我经常担心,这种怪模怪样的器皿,一是不好清洗,二是不好存放,三是不好运输。 + +器皿是世道人心的物化表现。上古为何以鼎鼐制度规划礼仪、制定封建?原因正在此。器具的确太重要了, 现在常见的瓷器餐具,仿古则必标乾隆年制,其心诈伪,其器多不可用。而上述新式时尚瓷器,设计乖张怪悖,违理逆情之作比比皆是,浅薄丑陋不说,也多不好用,人反以为时尚。其实还不如农村从前的土旧制式,虽粗糙不精细,但得人情、顺人心。 + +由此可知俗云:美食不如美器。其说颇有意味,但能理解这句话的人越来越少了。 + +器具是世风人心的物化,又反过来塑造人情流俗。 + +再想想日本人福泽喻吉说的改造社会须三改造,曰:人心(教育)、器物、政治。这是有道理的。 + +古人从风水、气运角度,反对用奇怪的东西,非正则非礼,非礼则逆天悖理。古人认为,应寓教化于日用伦常当中,对人心进行潜移默化的影响,使其弃邪归正、删杂归一。而尚好怪俗、追逐奇异,必然对人心起到相应的影响,容易启迪其不靖之志、挑动其非分妄念。而人心思异,必言语纷乱,尽呈无根浮词,尚好争辩却无向学慕道之心。 + +从这个角度说,作为餐厅,做生意,使用奇怪餐具、不伦不类,自己承担经营成本;而作为居家过日子,不使用正经餐具,追逐怪异.很难说于家道有益。 + + diff --git a/src/content/posts/2020/2020-11-17-could-educate-make-us-better.mdx b/src/content/posts/2020/2020-11-17-could-educate-make-us-better.mdx new file mode 100644 index 0000000..171ae9d --- /dev/null +++ b/src/content/posts/2020/2020-11-17-could-educate-make-us-better.mdx @@ -0,0 +1,37 @@ +--- +title: 教育能让我们变得更好么? +slug: could-educate-make-us-better +date: 2020-11-16 17:08:41 +updated: 2020-11-16 17:29:30 +category: 杂谈 +cover: /images/2020/11/2020111617282542.jpg +summary: 在世间众多确定性不断被摧毁的情况下,坚信教育能让人变好、笃信人无论处于哪个阶段都需要折节进学,几乎是我们无名之辈改变人生的最后希望。 +--- + + + +孔子一向被中国人视为至圣先师,不仅才能广大,在道德上更是完人,但这样一位圣人所教的弟子中,却出了帮助鲁国贵族季氏聚敛民财的冉有、恶意低毁同门的公伯寮。 + +东汉大儒郑玄,也是学问与道德上的典范,为世人所重,黄巾军起,烧杀抢掠无所顾忌,但会刻意不去骚扰郑玄的故乡。郑玄有一个弟子叫郗虑,却做出了令人大跌眼镜的事:充当起曹操的枪手,罗织罪名将正直之士孔融置于死地。 + +冉有、郗虑等人所受的是当世最好的教育,犹且如此。这基本可以得出一个结论:良好的教育,不一定能让人变得更好。不过,如果就此否定教育的作用,显然会走向反智仇学的极端,典型表现就是读书无用论。 + +别以为在互联网高度发达的今日,读书无用论已丧失市场,其实抱持这种看法的人多得很,尤其是那些做成一些事、赚到一些钱的人,他们大概曾经笃信教育对人有良好作用,然而在做事过程中发现此前学的东西根本不敷用,于是举起大棒,把昔日信奉的理念捶了个粉碎。 + +如果这些人听说冉有、郗虑的故事,肯定喜出望外,因为那些案例正是他们鄙薄教育的有力证据。至于孔子、郑玄教出了众多杰出弟子,后市受孔子、郑玄影响的英伟士人不可胜数,这些事实就被他们选择性地无视了。 + +即使如此,我们也不能骤然判决读书无用论者是错误的。毕竟他们也是根据自己鲜活的生命经验得出的结论,这是任何人都不能被夺的。有人试图说服他们,其实当你一旦有这个想法,就已陷入极度被动之中:既然你笃信教育的良好作用,那么你必须是个取得一定成就的人,同时你所信奉的教育与你的成就须有因果关系。整个链条都做得完美无瑕了,才有可能说服对方。 + +所以,与其付出巨大说服成本去做一件收益低微的事情,还不如自问一下:假如自己也跟他们一样被所受过的教育狠狠伤害过,自己还会不会笃信教育的作用?要想没有恨意,其实是非常难的。这意味着,我们在受教育之初就需要管理自己对教育的预期。 + +在这种时候,冉有、郗虑等事例的非凡意义就凸显了,他们能让我们降低对教育的期望值,还可以帮助我们审视如下思想:生而为人,能不能帮权贵压榨百姓?可不可以陷害别人?假如结论是斩钉截铁的“不能”,那么孔门教育就是有希望的,因为这就是孔子所提倡的士人理念“行己有耻”。 + +最近与一些大学学生网聊,我告诉他们,大家从小地方来到大城市,但凡生活过一段时间就能发现,世界是非常复杂的,一些事项甚至会挑战你的基础认知:勤劳未必致富、学识带不来效益、敬业难以上位。凡此种种,会令笃信“能者居之”的你痛苦不堪。更有甚者,还会罗织各种“案例”,告诉你寒门难出贵子、阶层逐渐固化,希望你赶紧向命运跪下磕头并就此躺平。 + +动物都护食,人也一样。所以我们从书卷缝隙看到,无论在什么时候,利益壁垒都无处不在,这是人性使然。出身平凡的我们,在大城市奋斗得头破血流,才能喝上一碗肉汤——在小地方,也许只能换来一碗白粥。 + +但这又如何?古今中外一大美景,不就是无数出身寒微的人,无论外界怎样想方设法暗示他们前路没有希望,他们都能不为所动,奋力冲破各种壁垒,从而活出了一种坚姿吗? + +所以,在世间众多确定性不断被摧毁的情况下,坚信教育能让人变好、笃信人无论处于哪个阶段都需要折节进学,几乎是我们无名之辈改变人生的最后希望。 + + diff --git a/src/content/posts/2020/2020-11-17-peter-pan-in-my-heart.mdx b/src/content/posts/2020/2020-11-17-peter-pan-in-my-heart.mdx new file mode 100644 index 0000000..b74789c --- /dev/null +++ b/src/content/posts/2020/2020-11-17-peter-pan-in-my-heart.mdx @@ -0,0 +1,43 @@ +--- +title: 每个人的心里都住着一个彼得·潘 +slug: peter-pan-in-my-heart +date: 2020-11-17 06:03:10 +updated: 2020-11-19 18:58:31 +category: 杂谈 +cover: /images/2020/11/2020111917590021.jpg +summary: 我们每个人都会渐渐长大,不管我们有多么的不情愿。我们不再是没心没肺,无忧无虑的孩子,我们只能在心里保存着关于儿时的记忆。 +--- + + + +你有没有过这种时候? + +以前经常哼唱的一首歌,却突然忘了是什么音调。以前很喜欢的一部电影,却忘了是什么情节。以前很喜欢的一件衣服,却在衣柜最底层找到。以前经常会玩的游戏,却模糊了游戏规则。以前默默喜欢的一个人,却渐渐淡忘了她的模样…… + +“或许有过这种时候吧。”你可能会这样说。但是,你知道这是为什么吗? + +因为我们在时间的洪流中不可避免的长大了。所以我们不会再唱《种太阳》,我们不再看《大风车》,我们不再玩丢手绢,我们不再拉着手去上下课…… + +可是,当看到坐在小车里目光清澈的孩子时,你不禁会想,我小时候也坐着这种小车呢。当走在街上,路边的音像店传来熟悉的旋律时,你不禁跟着轻声附和。当回到家,发现现在的小孩依然在看你小时候看过的一本书,比如《小鲁的问题》时,你不禁暗自思忖外加一点点自嘲,小鲁还真是红啊! + +那么,在这些时候,在你也会时不时的说“我小时候”“我上小学的时候”“我以前”甚至“想当年……”的时候,你会不会想,要是我还没有长大该多好。 + +在这个世界上,真的可以有人长不大,那就是小小的彼得·潘。他永远都只有4、5岁的样子,他长着一口乳牙,他会飞,他住在冒险岛,他有点骄傲,有点爱吹嘘,有点小脾气,但是他真的很善良,哪个孩子去了天堂,他会陪他们一段路,因为怕他们一个人会害怕…… + +不要说你不认识他,因为在你的小时候,很小很小的时候,说不定你就见过他,在你的梦境里,在你的故事里,因为温蒂就是这样。在她小时候,她经常会梦到彼得·潘,后来的某天夜里,彼得就真的来了,他教会温蒂飞行,然后把她和他的两个弟弟带到岛上。他们并没有因为陌生的环境感到害怕,反而他们觉得好像在哪里见过。他们在岛上经历了很多很多事。后来,彼得凭借自己的聪明智慧带领大家打败了大海盗胡克。 + +温蒂要回家了,她知道妈妈会把那扇窗子一直开着,那扇窗子正是他们飞走时经过的那扇。他们回到家,彼得却依然固执地要留在冒险岛,但是他不想和温蒂就这样分开,于是他征得温蒂妈妈的同意,每年都会要来接温蒂和他回去做春季大扫除。就这样温蒂和他去过几次,可是后来,彼得总是忘记来接她。再后来,温蒂长大了,并有了自己的女儿简,女儿总是想知道更多的关于彼得·潘的事情,就在某天夜里,他真的来了,他来接温蒂和他回去做大扫除,可是温蒂此时已经长大了,她不再会飞,她现在的样子吓到了彼得,因为彼得还是和她初见时的样子。最后,彼得带着简飞走了…… + +后来的后来,简也长大,也有了自己的孩子,可是彼得总也长不大,但他还是会到这里来,领着新的孩子和他飞去冒险岛。 + +你回想起来了吗?温蒂经历的事情你是不是也似乎经历过呢? + +你会不会羡慕彼得·潘,那个永远也长不大的孩子呢? + +你会不会希望能和他一起飞,有一段难忘的经历呢? + +我们每个人都会渐渐长大,不管我们有多么的不情愿。我们不再是没心没肺,无忧无虑的孩子,我们只能在心里保存着关于儿时的记忆。但是,我觉得,我们每个人的心里都住着一个彼得·潘,尽管他有点小小的骄傲,但是他依然那么善良可爱,单纯顽皮,依然会让我们感受到爱的存在。 + +彼得·潘那个永远也长不大的孩子,总是带给我们最多的感动和感悟。 + + diff --git a/src/content/posts/2020/2020-11-19-afternoon-rhapsody.mdx b/src/content/posts/2020/2020-11-19-afternoon-rhapsody.mdx new file mode 100644 index 0000000..54ef229 --- /dev/null +++ b/src/content/posts/2020/2020-11-19-afternoon-rhapsody.mdx @@ -0,0 +1,39 @@ +--- +title: 午后随想曲 +slug: afternoon-rhapsody +date: 2020-11-19 07:14:35 +updated: 2020-11-22 07:19:31 +category: 杂思 +cover: /images/2020/11/2020111918235219.jpg +summary: 真想一个人,就这样一直静静地,静静地坐着,慢慢地想,慢慢地写…… +--- + + + +此刻是一个很平常的秋日的午后,不一样的是睡沉沉的办公室里只我一个人醒着。 + +今天进入十一月份下旬,终于到了月末,总觉得这个十一月似乎过得很慢。早已是过了立冬,可在深圳还是盛夏般炎热,我坐在靠窗的位置,有阳光射进来照亮了整个桌面,笔尖在纸上投下暗影。这阳光并没有给我带来多少温度,却照的眼睛睁不开了,渐渐习惯了这束亮光,再看办公室其他地方,才感觉原来光线照不到的地方是如此昏暗,明明是白天,却仿佛已是阴天。 + +今天是少有的蓝天白云,大朵大朵的云彩在天空中变幻着不同的形状,终于不再是灰蒙蒙的天空了,所以抬头看天的时候不再会感到压抑。 + +此时的东湖公园已经开满了菊花,它们开的那么繁盛,地上散落着许多花瓣。那么,是不是繁盛到极致的同时也昭示着将要衰败?是不是所有美好的事物都有陨落的那么一天呢?绽放的花朵傲立在枝头,仿佛在向世人宣告:“我努力绽放过了,这对我来说已经足够。”是啊,只要活出自己就好了,只要认真经历过就足够了。 + +其实有时候还是会怀念以前,所有的课都只在一个教室上,很简单的教室,有多媒体却及少用。老师认真地在讲台上课,有一节粉笔就够了,怀念粉笔与黑板不断发出的撞击声,听了会觉得让人很踏实。有些老师以前会觉得很严厉,可是毕业之后再相见,他们总会笑着询问你的近况,没有任何距离感。 + +项斯微说:“所谓的幸福,其实是能够耐心的接受每一个人的进入和离开。”生活中确实会不断的有人进入或者离开,当有人离开的时候,我总是会感到一阵阵的失落与难过,总会想本来好好的,怎么能连个招呼也不打就一声不响地走掉呢? + +生活还在继续着,我们还是会认识其他的人,于是又有人走了进来。虽然有人离开,可是曾经的美好回忆却留了下来。我们应该感谢每一个出现在我们生命里的人,他们扩充了我们的精神财富,帮助我们成长。 + +有人离开的时候还是会难过,但看过这句活之后难过的程度会减轻一些。“那些我来不及珍惜的人,请你们珍惜自己;那些来不及珍惜我的人,请好好珍惜身边的人吧!” + +“旅行中,看沿途的风景,稍纵即逝,忽然发现,我也只是你眼中的那道风景。”也许每个人都会是某些人身边的过客。所以要好好珍惜身边的人,因为并不是你想回到过去就能回到过去的。 + +坐在窗户旁边,我清晰的听到了风声,太阳时不时地被云彩遮住,光线四下逃窜,睡醒的闹钟再次响起,一切又恢复平静…… + +天空中时常有飞机飞过,有时会听到飞行时的轰鸣。却很少见到飞翔的小鸟,或许是我在高层办公的缘故吧。 + +《诗经》中有一篇农事诗《邶风·七月》,其中有这么一句:“九月筑场圃,十月纳禾稼。黍稷重穋,禾麻菽麦。嗟我农夫,我稼既同,上入执宫功。昼尔于茅,宵尔索綯。亟其乘屋,其始播百谷。”现在或许已经秋收结束,有耕种才会有收获,很简单易懂的道理,却只有肯努力肯付出的人才能真正体会其中的喜悦。 + +真想一个人,就这样一直静静地,静静地坐着,慢慢地想,慢慢地写…… + + diff --git a/src/content/posts/2020/2020-11-19-memory-of-diary-letter-and-notes.mdx b/src/content/posts/2020/2020-11-19-memory-of-diary-letter-and-notes.mdx new file mode 100644 index 0000000..9b76d6d --- /dev/null +++ b/src/content/posts/2020/2020-11-19-memory-of-diary-letter-and-notes.mdx @@ -0,0 +1,81 @@ +--- +title: 关于日记、信以及小纸条 +slug: memory-of-diary-letter-and-notes +date: 2020-11-18 16:32:18 +updated: 2020-11-22 07:26:32 +category: 杂思 +cover: /images/2020/11/2020111816301059.jpg +summary: 你记得你某年某月的某一天,在哪里,做过什么吗?你记得你曾经喜欢过什么,讨厌过什么,心里想些什么吗?你记得你的朋友在你失落或生病的时候,对你说过什么,做过什么吗? +--- + + + +你记得你某年某月的某一天,在哪里,做过什么吗? + +你记得你曾经喜欢过什么,讨厌过什么,心里想些什么吗? + +你记得你的朋友在你失落或生病的时候,对你说过什么,做过什么吗? + +…… + +## 关于日记 + +我家写字台的一个抽屉里,曾存放着我满满的记忆,关于童年、关于青春、关于很多人、关于很多事。 + +很长一段时间我没有翻阅以前的东西,但我会时不时的打开抽屉看看。躺在抽屉里的信,封面已经褪色;日记本整齐地罗列在抽屉里,侧边已经泛黄;放在袋子里的纸条,我看了几眼但始终没有拿出来。明明我有足够多时间,但却没有打开信封,没有翻开日记本。大多数时候,只看到信封,看到日记本的封面我就已经很满足很温暖了,也就迟迟没有翻看。 + +十一在家,闲来无事,先是拿出小学的两小本日记看。呵呵,小时候的字写得还挺好的,都是我妈从小让我练字的结果。 + +> **1999年3月28日 星期六 晴** +> +> 今天,我们要can加演讲比sai,我很高兴。我们现在教室里等了一会儿,张老师(小学语文老师)来了,她先让演讲的同学讲了一遍。dai老师(数学老师兼班主任)来了以后,就让我们拿着小deng子出去排队。到了操场,我们就坐在小deng子上听。该我们班的同学上台讲了,我就认真地听,老师说得分的时候我很激动。最后老师说第一名有我们班的同学时我就更加激动了。啊!这一次演讲比sai我真快乐! + +这是我二年级的时候写的,还有挺多不会写的字,不过看来我从小就有集体荣誉感,哈哈。 + +小学的时候写日记并非出于自愿,是老师布置的作业,一周最少两篇。虽然当时很不情愿,但现在看来要谢谢老师,让我可以拥有许多关于童年的美好回忆。 + +上初中之后一开始老师要求写周记,不知怎么,后来老师没有再要求,写日记的习惯也就没有继续坚持下去。 + +高中是日记写的最多的时候,很多当时很认真写下的东西,现在看起来却有点幼稚和可笑。高中三年,你带给我最多的记忆,那些单纯而美好的日子我都记得,那些你曾唱给我听的歌,尽管不再流行,但我还是会听。谢谢你,带给我许多感动的画面和温暖的记忆。 + +我有一个很喜欢的日记本,却很久很久没有打开,因为密码不知何时已被我遗忘,试了几次都是无果而终。我记不得里面写了些什么,但没有关系,它还在就好。 + +“时间像沙一样埋没了曾经,我用笔尖在纸上写下记忆。关于我的日记,记录我生活的部分。写关于天上的星、写关于地上的虫、写关于篮球弄伤了手指头、写关于拿着朋友买的甜筒、写关于老师、写关于朋友、写关于滴落的眼泪、写脸上的笑容、写关于昨天晚上的梦、写关于树上叶落的轨迹。无数关于,关于我的生活。” + +其实日记就是这样,零零散散,毫无章法,但串联起来,就是我们的生活。 + +## 关于信 + +我有大约二十几封信,不算多,但都很珍贵。 + +我记得每周五的时候都会有人去班级的信箱拿信,便会习惯在那天期待,收到信的那一刻更是无比激动。然后会用最快的速度把信拆开,仔细看。然后去买信封和邮票,准备回信。呵呵,学校到我家的路上有一个邮箱,我不知投放过多少次,那种心情真的挺奇妙。 + +现在很少有人会写信了吧,不管相隔多远,一通电话,一个短信就可以及时联系。但我还是会怀念写信的日子,那种期待的奇妙的心情,现在再也体会不到。 + +## 关于纸条 + +我想很多人都有过传纸条的经历,自习课上甚至老师讲课的时候,既想快点送达目的地又怕老师发现,那种心情既有点焦灼不安,又有点兴奋。 + +记得高一下学期的时候,我和你之间形成了传纸条专线。你在第二排我在倒数第三排,不过好歹是在一竖列,路途不至于很遥远。 + +那些信和纸条我都保存着,现在再看,依然觉得很感动。 + +我看到有一个纸条上面都是笑话,那一定是我不开心你写给我的,每一封最后你都会写上 blow you a kiss,让我每当看到它都很温暖。看到那一张张纸条 一封封信我仿佛又看到了你们灿烂的笑脸,我也不自觉地笑了起来。 + +> 放假了 春天来了 雪都消融了 +> +> 在夜深人静的时候 听那花儿破苞绽放的声音 +> +> 一边想去年的邂逅 +> +> 冬天已经结束 春天也会到来 +> +> 年年如此 年复一年 +> +> 但那度冬待春的人 却不同 +> +> 是我们无力挽留那离去的身影 + +现在传纸条的人都不知道哪里去了,虽然不常联系但还是一直默默地关注你,那些纸条和你们写的信我都保留着,知道我的身边曾有你们陪伴也就足够了。 + +我想我很富有,起码在精神上。 diff --git a/src/content/posts/2020/2020-12-14-the-middle-age.mdx b/src/content/posts/2020/2020-12-14-the-middle-age.mdx new file mode 100644 index 0000000..d05baa8 --- /dev/null +++ b/src/content/posts/2020/2020-12-14-the-middle-age.mdx @@ -0,0 +1,45 @@ +--- +title: 中年的世界 +slug: the-middle-age +date: 2020-12-14 15:23:20 +updated: 2020-12-14 18:24:05 +tags: + - 中年 +category: 杂谈 +cover: /images/2020/12/2020121415223435.jpg +summary: 中年以后的人常有这种寂寞之感,觉得睁开眼来,全是依靠他的人,而没有一个人是可以依靠的,连一个可以商量商量的人都没有。 +--- + + + +十一月中旬适逢老友结婚,大学的一帮朋友难得地聚在一起。 + +酒后聊天,大都是面临“30岁危机”的人,工作不上不下,家庭有上有下,平常时节压力难以排解。就如张爱玲所言:“中年以后的人常有这种寂寞之感,觉得睁开眼来,全是依靠他的人,而没有一个人是可以依靠的,连一个可以商量商量的人都没有。” + +更何况,我们面对的,可能还是人类有史以来对中年人最不友好的时代。 + +这得从中年时期在当下的功能错位说起。剑桥大学动物学家大卫・布里斯班发现,动物是没有“中年”这个概念的,在生育期之后,就迅速走向死亡。人类这个物种,之所以有中年这个漫长的阶段,是有着特殊任务的。 + +这个任务被称为“亲本投资,简单说就是,人到了某个阶段,比如更年期,生育能力会下降乃至停止,这时候人的主要任务,一方面是给孩子提供食物及合适的生存环境,另一方面则是要把人类过往的各种信息,比如知识、技术、价值观等,传递给下一代。 + +别小看这种经验和技术的传递,这在人类的演化中起到至关重要的作用,这种不断叠加的信息积累,会带来认知上的复利效应,沉淀出了人类的文化和智慧。 + +也因为承担了这种传递经验的演化任务,中年人会变得更哆嗦,更喜欢跟年轻人分享自己的意见。 + +但现代社会,跟狩猎和农耕社会的相对静态不同,技术变革的速度如此之快,社会结构和生活方式都发生了巨变,很多过去的经验难以适用,反而变成负担,这时候再对年轻人指指点点,只会显得“爹味”十足。 + +雪上加霜的是,人到中年后,“亲本投资”比生育更加重要,所以原本承担着吸引配偶功能的外表,这时候就不再受演化规律的眷顾。没有了资源倾斜,所谓的老态就开始出现了,比如毛发变白或脱落、皮肤松弛,也让中年人更容易招来油腻、不自律的恶评。 + +这么说来,活在这年代的中年人,真就一无是处么? + +当然不是。布里斯班的研究很能抚慰人,他的结论是:中年才是人生的巅峰。这个巅峰,指的是认知能力。 + +大脑核磁共振结果显示,中年人前额叶皮层的活动,明显比年轻人更活跃。前额叶皮层负责的,就是层级很高的认知功能,比如抽象能力。 + +大脑的另一个变化是,年青时在认知、记忆时,会优先单独使用左脑或右脑,中年人的大脑皮层更倾向让两边协作,让情绪和认知更加平衡,既能储存大量信息,也能退后思考全局,不被细节迷惑。所以,中年人在洞察力、目标感和效能方面,都会表现更好,也更有自制力。 + +布里斯班提到的中年,是在40~60岁之间。这样看来,我们的30岁焦虑,多少有些过度反应。问题当然会不断出现,但我们见招拆招的能力总是有的。 + +要知道,在前面等着我们的,可是“已知的宇宙中最聪明的动物达到认知的巅峰”。 + + diff --git a/src/content/posts/2021/2021-02-28-a-letter-for-myself-after-ten-years.mdx b/src/content/posts/2021/2021-02-28-a-letter-for-myself-after-ten-years.mdx new file mode 100644 index 0000000..fdb9788 --- /dev/null +++ b/src/content/posts/2021/2021-02-28-a-letter-for-myself-after-ten-years.mdx @@ -0,0 +1,45 @@ +--- +title: 写给十年后的自己 +slug: a-letter-for-myself-after-ten-years +date: 2021-02-28 05:37:01 +comments: true +tags: + - 回忆 +category: 杂思 +summary: 现在的我是永远回不到过去了……倘若有机会,我更愿意在这么一个场景中写一封寄给18岁的我的信,告诫那时的我不要荒废青春,好好学习。 +cover: /images/2022/02/2022022821542418.jpg +--- + + +现在的我是永远回不到过去了…… + +倘若有机会,我更愿意在这么一个场景中写一封寄给18岁的我的信,告诫那时的我不要荒废青春,好好学习。好想身处于《星际穿越》中的黑洞空间,周围环绕的是我的种种过去。我可以拨动命运的琴弦,将一封包含珍重和期望的信塞到过去的自己手中,让过去的自己读上那么几遍。 + +然而,这样的场景终究只是奢望,写给过去,更多的是对现在的不满意,对以前不努力的惋惜。写给未来,我想更多的是梦想和期望。 + +<MusicPlayer netease={27571001} /> + +晚上写完代码,我看着键盘。毫无疑问,我们显然已经熟到无话可说了。 + +程序员的生活是一种极致乏味的体现,每天的代码和调试的过程更像是某种洗脑的措施。终于会在某一天,你想要做点别的,可是发现生活平淡到了甚至连做梦都没了素材。工作八年后的我,已经习惯了某种节奏——开机写代码,关机睡觉…… + +就像是今晚,突然闲下来时,会茫然无措,不知道做什么好。也罢,就让我将这封去年就开始写的未完之信写完吧。 + +对于过去,我有种种不满。对于未来,虽有期待但觉得忘不着边际。 + +学生时代会有的一些梦想,都随着时间的洗刷慢慢变得不现实。就好比曾经喜欢的化学,最后遗憾放弃。选择从事软件,可以说是自己的爱好,也是一种未想到的必然。在二十岁的我看来,未来似乎无法预计,我看着自己的目标,朝着它一步步走去,却发现,自己走的可能是下坡路,离梦想越来越远。 + +未来谁能说清呢?六年前的我还在抱怨房价太高,还在为楼市的一夜暴富愤慨,现在我已经成为房奴大军一员,开始为还贷奔波。 + +生活的重担越来越麻木自己,工作工作,睡觉越来越晚,要 resolve 的 issue 却从未变少。精神越来越麻木,仿佛永不停歇的机器人,按照相同的指令重复劳动。于是对于周边的许多事情,开始漠视,开始冷血。有时想要自己哭一下发泄情感,却突然发现,现在的自己,连一滴眼泪都流不出来了。 + +晚上渐渐开始睡不着,只好爬起来看书学习,却慢慢发现自己所懂的知识只是这软件体系中极细微的一丝。技术迭代越来越快,去年还在火还在流行的技术,今年会有人告诉你,这东西过时了,这仅会一丝也岌岌可危。于是,越来越重的学习任务、工作任务、经济压力,似乎就像是一个不断恶化的怪圈,我在这里面蒙着眼睛,却不知如何出逃。 + +> 10年後の私へ、今は幸せでしょうか?それとも悲しみで、泣いているのでしょうか? +> けどあなたの傍に、変わらないものがあり。気付いていないだけで、守られていませんか。 +> 過ぎし日々に 想いを预け、時間だけ ただ追いかけてく。 +> 背に寄り添った 誰かの夢に?振り向ける日がいつか来るのかな。 + +希望十年后的自己看到此文时,依旧能像过去的自己一样。依然为那些简单纯粹感动,依然相信这个世界会变得美好,依然能热泪盈眶。 + + diff --git a/src/content/posts/2023/2023-11-28-basic-terms-in-book-binding.mdx b/src/content/posts/2023/2023-11-28-basic-terms-in-book-binding.mdx new file mode 100644 index 0000000..e0ac3a3 --- /dev/null +++ b/src/content/posts/2023/2023-11-28-basic-terms-in-book-binding.mdx @@ -0,0 +1,67 @@ +--- +title: 不可不知的图书装帧术语 +slug: basic-terms-in-book-binding +date: 2023-11-28 06:29:09 +updated: 2023-12-01 16:31:00 +tags: + - 装帧 +category: 杂谈 +summary: 本文不过是强调一下有关精装本和特装本的一些术语,比如书籍各部分的名称,以及怎么来保养这些已经处于书籍手工装帧天花板的宝物。 +cover: /images/2023/12/2023120116264095.jpg +--- + + + +很多爱买书的小伙伴对于西式装帧的精装本或特装本(以下简称精装本或特装书)的一些特点和其收藏价值已然烂熟于胸。本文不过是强调一下有关精装本和特装本的一些术语,比如书籍各部分的名称,以及怎么来保养这些已经处于书籍手工装帧天花板的宝物。本人学识浅薄,难免指鹿为马,甚而“饭店门前摆粥摊”,还望各位方家指正。 + +在当下中国大陆的图书市场,精装本基本上都是在印刷厂流水线操作,而特装本则是手工制作。它的书芯过去也是来源于用手工纸手工印刷,从纸到书整个过程都在书籍上留下了工匠们的 DNA。所以,一本纯手工制作的书籍是有“生命”的。 + +现在的特装本其内芯使用手工制作的也很少,基本上是利用已有的平装本或者是精装本,然后再替它人工加装皮制书衣、起脊、刷边等等。当然,也有里里外外都纯粹用手工制作的特装书,数量不会很多。因为其中必然牵涉到手工印刷书籍的全部文字和图案,就像中国的雕版古籍一样。谁能从制作一张白纸开始纯粹用手工精制出一本英文精装本或者中文的排字本、特装本呢? + +中国传统古籍倒是不折不扣的用手工制作,但现在也开始用印刷机来印制宣纸书页,然后再手工装订,只能算半手工制作。过去古籍上市可称其为“梨枣新雕”[^1],现在充其量只能算是徒有其表的线装古籍,和“梨枣”没啥关系。 + +用雕版刻字,然后用上等宣纸,加持全套传统工艺制作的古籍也有。刻的字不会太多,因为雕版制作太累也费功夫。但有没有人想过抛开用电脑扫描排版,把铅字工艺再捡起来,用铅字或者其他质地的活字来印制一本汉字排版书? + +和中国古籍相对应,我们现在购买和收藏的平装本、精装本和特装本,其装帧方式都来源于西方。就是平装精装这种俗称也有斟酌的余地。现在简单聊聊一些关于精装本特装本的术语。 + + + +Uncut:毛边本。精装毛边本有些是翻口毛边,有些是三面书口都是毛边。一些外文书尤其是廉价的平装本只是翻口毛边,买家不懂的话就给卖家一个差评,原因就是翻口没切,书品太差,简直就是次品! + + + +Unopened:未裁本。每本书的内容都是先印在一整张一整张的纸上,然后折叠成相应大小的书页再装订。未裁本就是指这些一整张的纸印好后按序折叠成书页,但并没有裁开就装订成的书籍。 + + + +Whole binding:全皮装帧。一本书除了书芯之外全部使用皮革装帧。Half binding ,半皮装帧。Extra binding,特精装帧,“特装书”这个名词即由此而来。 + + + +Register:签带。书中用作书签的绸带。 + + + +Squares:飘口。精装本的封面或者封底靠近书页切口的边沿,并超出书页的那部分就是飘口。 + + + +Top-edge gilt (T.E.G.):顶口刷金,或者顶口烫金。书页的顶端谓之顶口,书页的下端谓之底口。 + + + +Head band:堵头布。缝在或粘贴在书脊上下两端的布带或者绸带。 + + + +Bands:竹节。先在装订护封前的书脊上按一定的距离放上一段段的小书绳,然后再装订护封。护封装订完毕后,埋在护封下面的书绳会凸起于皮制或硬制的书脊上,酷似竹节。 + +精装本特装书还要注重保养。首先是摆放时不能太紧也不能太密,书不能松垮垮地单独立放,要把书不紧不松地挤在一起竖放。书柜的玻璃最好是深色或者茶色的; + +其次是要注意防湿。放书架的屋子其湿度不能太大,必须时刻注意防霉,书架里再防一些胡椒粉防虫。 + +书籍装帧常用到的皮革包括:山羊皮、小牛皮、绵羊皮、猪皮、海豹皮等等。首选是山羊皮。全皮或者半皮装帧的书可以用石蜡和蓖麻油混合后的制剂来涂抹外封定期保养。 + +最后,如果要掸掉书籍上的灰尘的话,书要倒着拿从书根往书顶方向用鸡毛掸子轻掸即可。 + +[^1]: (梨枣是雕版印刷的版,古代印书的木刻板,多用梨木或枣木刻成。) diff --git a/src/content/posts/2024/2024-04-07-switch-blog-to-nextjs.mdx b/src/content/posts/2024/2024-04-07-switch-blog-to-nextjs.mdx new file mode 100644 index 0000000..a05425a --- /dev/null +++ b/src/content/posts/2024/2024-04-07-switch-blog-to-nextjs.mdx @@ -0,0 +1,79 @@ +--- +title: 弃用 WordPress 了,但我相当“后悔” +slug: switch-blog-to-nextjs +date: 2024-04-07 16:09:09 +updated: 2024-05-22 18:12:00 +tags: + - 博客 +category: 编程 +summary: 如你所见,当你访问这篇文章的时候,我已经把写了 13 年的博客程序从 WordPress 迁移到了自己用 Next.js 写的程序,这可能是我第 N 次尝试使用其他的方式写博客,但我想绝对不会是最后一次。 +cover: /images/2024/04/2024040719182310.jpg +--- + + + +如你所见,当你访问这篇文章的时候,我已经把写了 13 年的博客程序从 WordPress 迁移到了自己用 Next.js 写的程序。这可能是我第 N 次尝试使用其他的方式写博客,但我想绝对不会是最后一次。 + +第一次接触类博客的平台还是 20 年前,初一同学在课间说道:“我开通了 QQ 空间,快去给我踩一踩。”正儿八经地写作,还要追溯到 15 年前,那时的我是那么多愁善感,什么东西都想要“为赋新词强说愁”。我的足迹遍布各类 SNS 平台,在上面书写各种现在看来相当幼稚的话语。 + +因为专业的原因,在大学期间接触到了独立博客和 WordPress,当时的我就被这种独立而又个性的写作方式惊到了。那时还属于独立博客的黄金年代,QQ 雷锋群里群英荟萃,我那孱弱的前端知识就是通过此类途径习得。而我没想到的是,[当初的开博宣言](/posts/the-beginning-of-blog/)竟然一写就是 13 年。 + +年龄真是个好东西,因为其增长,我们能不断地丰富自己的阅历,也能见证所谓的“历史”。兜兜转转,写博客的人来来去去。有些相识数载至今还是好友,有些已经消失再无音讯。而我,对这 WordPress 也是又爱又恨,这期间换过太多的平台。有简单的 Hexo、Hugo,也有同样基于 LAMP 平台的 Typecho、Emlog、Z-Blog,还有之前很时髦的 Ghost。很多文章评论都放在了多说、Disqus 上,因为这来来回回的“搬迁”遗失大半。到头来,竟然还是这 WordPress 最好用,如同家里的“黄脸婆”,阅尽世间百态,才发现老婆是真爱。虽然至今还是不会写 WordPress 主题,但好在漂亮的主题数不胜数,凭着钞能力也能基本解决。 + +但,我还不甘心。 + +这十几年来前端风起云涌,每天都有新的东西诞生。13 年前博客用个 jQuery 就很了不起了,很多页面还使用表格布局,为了 IE6 要写一堆 Hack,那个时候声称不兼容 IE 的网站都属于“珍惜动物”。而如今 IE 早已不复存在,继任者 Edge 也把自己变成了 Chrome 的模样。前端相关的框架更是层出不穷,光打包工具我就完完整整地经历了 Grunt、Gulp、Webpack、Rollup、Vite、SWC 等,更别提其他的了。在这些技术的背景下,我这基于 jQuery 的 WordPress 就显得稍微有点 old school 了。 + +上周和 Tison 聊天,发现他正好准备基于 Astro 弄个[新的博客](https://github.com/tisonkun/dacapo)。沉眠于心中多年的想法终于浮起,既然用了这么多博客平台都不满意,为何不能自己写一个。Next.js 这么时髦,其 App Router 还能用最新的 React Server Component,我都眼馋很久了。于是说干就干,趁着正好清明放假,我把几乎所有的时间都投入在了这一“浩大”的造博运动中。 + +## Logo 设计 + + + +对我而言,技术牛逼与否并不是最重要的,最重要的是颜值。如果不好看,那就直接 pass。所以还没写博客,第一步,我就在考虑重新设计自己的博客 logo。对于之前用的 logo,其实问题并不大,主要的问题是矢量化。绘制这个 logo 的时候还是 6 年前,像素被限制在了 65px,在 PSD 底稿和对应字体都丢失的当下,想要放大适应视网膜屏幕等就显得有些困难。于是我借着这个机会,学习使用 [sketch](https://sketch.com) 来绘制矢量图形。这当中最大的绘制难点就是 logo 中那两个不规则的半圆环,我画了两个圆去叠加,然后合并后一点点拖拽曲线。才调整到和以前相似的形状。 + +绘制“帆”字的时候已经稍微熟悉,就直接使用钢笔工具一个个锚点描边,再稍微调整曲线就好,但是没想到还是在和圆环合并上栽了大跟头。弄了半天才发现是路径曲线的闭合问题,这其中的曲折大概就像是以前在微博上看到的[这张长图](/images/2024/04/2024040719234718.jpg)所描绘的景象。不过万幸的是,最终圆满地达成了我想要的效果。 + +在绘制 logo 的同时,我也一并绘制了黑白两种形态,为日后主题支持黑白模式准备,同时也绘制了 Github Poster 放在 `README.md` 上用于展示。这当中最有意思的事情,就是对以膨胀色与收缩色的概念的复习。以前自学设计的时候,觉得这东西很抽象。这次设计黑色 logo 的时候,发现明明是同样的大小,但是黑色的 logo 在屏幕上就是显得大上一圈。我不得不微调曲线,向内收缩一圈才在视觉的保持了 logo 的大小一致,相当有趣。 + +## 字体使用 + + + +字体选择上分为博客正文字体和图片字体。以前并不懂版权,不知道字体很多是需要授权才能在一些公开媒介上使用的,这次特意选择了商业免费可用的字体。 + +正文字体使用的是 [OPPO Sans 3.0](https://www.coloros.com/article/A00000050/),5 年前在字谈字畅的 [PodCasts](https://thetype.com/typechat/ep-113/) 得知此字体的公布,当即就喜欢上了。虽然和阿里普惠体、微软雅黑体等一众“汉仪兄弟们”师出同门,但是其变化是最讨喜的。它去掉了自冬青黑体时代就有的大喇叭口,字形更加方正,在笔画转弯处也更加刚正。其家族字体设计更多的是为传统非视网膜屏幕服务,所以夸张的笔锋搭配上抗锯齿就能有较好的观感。这种设计,放在当今连手机都是视网膜屏幕的年代,就显得很难看。所以 OPPO Sans 的设计,在当下很长一段时间,将成为我的首选字体。 + +Logo 部分的字体,主要是基于 [M+A1](https://booth.pm/ja/items/2347968) 进行制作。虽然此字体是日本人制作,但是不同于在日本起绝对统治地位的明朝体,此字体是一款明朗的黑体,而且同时免费提供了多种粗细字型,简直感动到哭。最有意思的就是细款字形的笔画末端都有一定的隆起,结合之前学习到的[光陷阱](https://www.thetype.com/2021/06/21723/),想必此款字体在打印机下也能有极好的显示效果。 + +## 技术选型 + +技术选型上这次有点激进,相比已经成熟很好用的 VitePress 等动静结合的生成工具,我义无反顾地选用了 Next.js 的 App Router,运行环境选用了更快的 Bun。至于其他方面,基本是照着 [leerob](https://leerob.io) 的博客进行仿写。所以文章格式不再是常见的 Markdown,而是能插入动态内容的 MDX。对于历史的评论,我还是舍不得丢弃,毕竟有 3000 多条。所以再三对比之下,我选择使用 [Artalk](https://artalk.js.org) 进行存储。有了多说的经历后,我也不敢使用任何第三方的 SaaS 服务存储评论,毕竟数据在自己手里才最安全。 + +博客以前最喜欢的音乐播放器是 Hermit-X,对应的作者荒野无灯已经神隐很久,获取网易音乐信息的 [Meting API](https://github.com/metowolf/Meting) 也没持续更新。而 APlayer 更是不知道 [DIYgod](https://diygod.cc) 什么时候能来“扫墓”,上次 APlayer 的诈尸还只是更新了个 License。所以在新博客环境只有 [Aplayer React](https://aplayer-react.js.org) 这个名为 APlayer 实则是借着其样式用 React 完全重写的播放器可用,其在 RSC 下有点小问题,但估计短时间内作者也没时间修复。(谁叫我是前端菜鸟呢) + +MDX 一开始是手动使用 `fs` 加载,使用 `grey-matter` 解析 `matter` 后再用 `next-mdx-remote` 渲染。但是鉴于自己太菜,很多页面的渲染都需要全量读取博文解析。后面改成了[推友推荐](https://twitter.com/ilovek8s/status/1776809454790676827)的 `contentlayer` 先渲染静态化,再进行加载。但瞅着 `contentlayer` 这半死不活的状态,未来大概率还是要弃。😭 + +## Update 2024/04/14 + +没错,一周后我又来屁颠屁颠地更新博客啦,一周过去后,我的博客也发生了不少变化。首先是搜索终于支持了,使用的是 fuse.js。前文提到的 Contentlayer 也被我废弃,换成了更好用的 Velite。 + +## Update 2024/05/22 + +今天,我把博客从 Next.js 迁移到了 Astro,重写了部分代码的实现,优化了部分设计。Next.js 版本的博客,内容管理和生成工具使用的是 Velite.js,它的设计很有想法,作者也很有经验。但是对应的 Next.js 与其集成后,却给我带来了很多解决不了的问题。首当其中的就是 Next.js 默认是 SSR,我在 MDX 中生成的内容,部分需要 inline 到 Client 端使用 JS 去动态执行,结果无法实现。其次就是 Astro 先天的在内容管理与编写上下了不少功夫。基于上述理由,我花了两天多一点的时间,就轻松把博客用 Astro 重写了。 + +重写之后发现 Astro 其实还是比较不成熟,很多东西文档并不清楚,还是要看源码来理清其设计想法。比如 `Astro:content` 的设计原理和其使用的细节问题,再比如 `Astro:assert` 这个特定的 import.meta 的使用问题。整体上而言,很多细节问题其实是 Astro 变化太快,对应的文档还没有来得及讲清楚。但是最让我失望的是,Astro 的 SSR 并不完善,它的 inline CSS 和 JS 的实现,其实是靠 Vite 整合 Rollup 提供的能力。所以在 SSR 上,如果你在一个 Astro Component 里面 `is:inline` 去定义 JS,很有可能会遇到因为模块重用而导致的坑。 + +另一个我很失望的缺陷就是 Astro 对于 MDX 的支持问题。当前的版本对于 MDX,还是无法实现预渲染来全文输出 RSS。当然,我知道这并非 Astro 自己的问题,主要和 MDX 的复杂和生态息息相关。 + +迁移到 Astro 的同时,也将博客的 Comment 系统 Artalk 的数据库从 MySQL 切换成了 Postgres,对应的数据库查询相关的代码完全废弃重写,顺带着使用 DrizzleORM 来完成了相关的查询的编写。整体上的使用比想象中愉悦。 + +~~希望这是我最后一次重写博客吧。~~ + +--- + +写此文章前,本有一肚子关于清明三天折腾的坎坷想要倾诉。真正写下来的时候,却又没多少。一来是年龄的增长,很多东西不再像以前那么过激。二来,大部分问题基本解决。数数上次更新博客的时间,已经不知道是猴年马月。希望自己在未来的年月里,能笔耕不辍,多记录一点自己的生活。 + +至于博客载体,那都是浮云啦。 + + diff --git a/src/content/posts/2024/2024-04-11-about-hefei.mdx b/src/content/posts/2024/2024-04-11-about-hefei.mdx new file mode 100644 index 0000000..539c491 --- /dev/null +++ b/src/content/posts/2024/2024-04-11-about-hefei.mdx @@ -0,0 +1,46 @@ +--- +title: 关于合肥这个“依壁雕凿”的城市 +slug: about-hefei +date: 2024-04-11 22:58:55 +updated: 2024-04-11 23:15:12 +tags: + - 生活 + - 合肥 +category: 杂谈 +summary: 不知不觉已经在合肥生活了快一年了,记得才来合肥工作时还是绵长又琐碎的雨季,天空总是阴沉沉的。 +cover: /images/2024/04/2024041123031132.jpg +--- + + + +<MusicPlayer netease={26209670} /> + +## 缘起 + +不知不觉已经在合肥生活了快一年了,记得才来合肥工作时还是绵长又琐碎的雨季,天空总是阴沉沉的。那时虽已是六月,但合肥还下着淅淅沥沥的小雨,我一边撑着伞,一边按照导航去寻找可以租房的地方。对于已经在家办公了 2 年多的我而言,就像是回到了刚毕业的那时,情绪略显奇妙。 + +得益于这些年移动互联网的普及,大家对合肥的称呼已经从两个胖子、霸都、到现在的“赌城”,合肥在安徽以外的人群中声誉还行。而这种还行,对于我而言却是矛盾的。我从小就生长在芜湖,坐车买东西啥的去南京更方便,合肥更像是一个可有可无的省会,对于它的了解仅限于大人聊天时提及的家里某个亲戚在此处云云。 + +所以某种意义上来说,我来合肥工作,既是巧合,也是运气。2020 年底,我和相恋 2 年的妻子步入婚姻殿堂,次年的 3 月我便从深圳腾讯离职回到芜湖居家办公。那个时候的我,在拥有的多份工作机会中,选择了居家办公的方式。因为我当时特别想要小孩,如果不离开腾讯,我和妻子天南海北不知何年才能瓜熟蒂落。 + +居家工作第三个年头,累计两年时,我的生活发生了翻天覆地的变化。没错,我失业了。我依稀记得去年三月的那天早上,既是我入职 StreamNative 刚满 2 周年的日子,也是我生日的前一天。HR 晓冰和我说:“雨帆,一会有个会你一定要在线。我们有重大的事项要向你宣布。”那个时候,我的心突然就咯噔了一下,那么生疼。后面的流程,仿佛就像做梦一样,CEO 像念稿一样把裁员的通知读完,问我有什么问题。随后还没超过 5 分钟,陪我 2 年的 MacBook 就开始重启,里面的数据消失得干干净净,仿佛一切的一切从未发生过一样。 + +三月的芜湖冷冷清清的,一如那个时候我的心情,既沮丧又充满了不自信。彼时的招聘市场,就像是一滩死水,毫无生机可言。一边和父母说着赔偿了不少钱,生活很长一段时间不用发愁,一边又捡起书本复习很多忘记的知识点,开始刷题。 + +此后的面试机会虽然不多,但每周也能有个一两次,直到成功面进了现在的公司。我与合肥的不解之缘,就此开始。 + +## 生活 + +合肥和芜湖虽然只有一江之隔,但按照地理上的说法早已是南北之分。初到合肥时的第一感受,就是人多又杂。这里说什么口音的人都有,早上步行上班的路上,几乎都是自行车和电瓶车这样的代步工具,叮叮当当挤满了整个人行道。已经 2 年没有怎么走出家门的我,在这时,才真正感受到了一丝活在人间的烟火气。 + +合肥的道路很怪,这种怪体现在各种地方。虽然这些年合肥没少大兴土木高架林立,但市区很多主干路还是破破烂烂,我住的地方地铁通了两年,地铁口还没开通。而很多地方,刚下高架,就来个 4 分钟起步的红绿灯。这样矛盾的交通配置,就有了超级拥堵的早晚高峰。前些天团建和同事聊起在合肥开车,同事说道:“在合肥啊,你就别想按照交规老老实实地开,那样你一定会被欺负得很惨。比方说变道,你就不要打灯,你这转向灯就是隔壁汽车的涡轮增压器,打了灯,你就别想变道了。合肥的道路,只要没有监控,所有的实线,所有的双黄线,都可以越线……” + +这种感觉既好玩又无奈,但也侧面说明了一件事情,那就是合肥的发展太快,因为太快,导致它的配套等其实并没有跟上。与这快速发展相对应的,是那背后数不清的社畜们。没错,合肥这里的打工人真的多。每次节假日的回芜,都像是一场冒险,从进站到安检,一路都是“蹒跚而行”。妻子问我,芜湖这么近,为何不开车来上班。我说,开车更难。有一次我堵在节前最后一天晚上下班后的绕城高速上,窗户上朦朦胧胧布满水汽,我打开车窗,才发现窗外同样是看不清的远方。 + +这样的看不清伴随着我直到现在,伴随着我每天工作生活。很坦诚地说,我并不享受合肥的工作生活,这里看似安利,实则处处机锋充满压力。引用南京老表的话,这是个一笔吊糟的城市。妻子曾经问我,既然谈不上喜欢,房贷结清又没啥经济压力,为何还要留在合肥? + +我想了想,却又不知道该如何回答。14 年起毕业的我已经辗转了太多太多的城市,各类大厂也都去工作过。与我而言,这些过往精彩绝伦,风起云涌。而今铅华散尽,不想在工作上卷的时候,合肥工作竟成为我当下不多的好选择。 + +所以哪怕这个城市有再多的不堪,再多的不满,未来很长的一段时间,我都将在这里老去。 + + diff --git a/src/content/posts/2024/2024-04-12-algo-find-the-lowest-costs.mdx b/src/content/posts/2024/2024-04-12-algo-find-the-lowest-costs.mdx new file mode 100644 index 0000000..efb58db --- /dev/null +++ b/src/content/posts/2024/2024-04-12-algo-find-the-lowest-costs.mdx @@ -0,0 +1,168 @@ +--- +title: 一道无趣的面试编程题 +slug: algo-find-the-lowest-costs +date: 2024-04-13 15:42:12 +updated: 2024-04-13 23:15:12 +tags: + - 算法 + - 面试 +category: 编程 +summary: 最近经济大环境依旧没能从疫情中走出来,身边有不少小伙伴被裁员或者是公司倒闭失业。好友群里讨论最多的话题就是面试,自然少不了讨论面试题。 +cover: /images/2024/04/2024041405050511.png +--- + + + +最近经济大环境依旧没能从疫情中走出来,身边有不少小伙伴被裁员或者是公司倒闭失业。好友群里讨论最多的话题就是面试,自然少不了讨论面试题。昨天一位相识多年的好友向我求助,他当时正好在面试,需要现场编程。 + +当时刚好不忙就看了一下题目,感觉很无趣,但还是耐着性子文字给他讲了讲,顺带着画了张简图,可是他还是没懂。原题如下: + +> 一个城市可以近似看成 n \* m 的网格图,A 公司有 k 个维修点,每个维修点有固定的坐标,城市里面有 h 个客户需要修理手机,客户有固定的坐标。维修员在地图上只能上下左右走,不能斜着走,每走一个格子需要 2 块钱的花费。每个维修点拥有无数个员工,每个员工可以被派去为一个客户服务。城市里面有 z 个地方在修理管道,这些地方是不能走的。可能有一些客户是被隔离的(上下左右都在修管道),这里是不需要派员工去修理手机了。A 公司为了节省财力,想找到最小的花费。 +> +> **输入**: +> +> 第一行给出两个正整数 n, m (0 \< n \< 1000, 0 \< m \< 1000)。 +> 第二行给出 k(0 \< k \< 20)以及 k 个维修点的坐标。 +> 第三行给出 z(0 \< z \< 100)以及 z 个坐标。 +> 第四行给出 h(O \< h \< 100)以及 h 个坐标。 +> 保证客户,维修点以及修理管道都在 n \* m 的地图里面。 +> +> **输出**:最小的花费。 + +样例 + +```java +输入样例 +100 100 +411223344 +100 +3 99 99 88 88 7777 + +输出样例 +1008 +``` + +这道题乍一看,看起来很唬人字很多,又是还有拦路虎,要找最短路径啥的,但其实是一道阅读理解题。一般现场编程面试,主要看你现场的反应和理解力,算法或者数据结构的东西,反而涉及不会太多。 + +这也使得这道题在弄懂原理后相当无趣,但考虑我这朋友确实经验尚浅,所以我还是给他继续讲下去,顺带着给了代码实现。这篇博客便是当时内容的摘录整理。 + +<img src={'/images/recaps/algo-minimal-costs/step1.svg'} width={400} height={400} alt={'Step 1'} /> + +<center> + 做任何算法题,第一步是理解题意,第二步是设想最简单的情况,再慢慢推导到复杂情况。首先,我们先不考虑存在阻塞的情况。最简单场景里,顾客和维修点在一个 + 1 x 1 的格子的一条边上,这个时候他们间的最短距离为 1。 +</center> + +<img src={'/images/recaps/algo-minimal-costs/step2.svg'} width={400} height={400} alt={'Step 2'} /> + +<center>然后我们更进一步,如果他们在一个格子的对角线上呢?他们间的最短路径有两条,为 2。</center> + +<img src={'/images/recaps/algo-minimal-costs/step3.svg'} width={400} height={400} alt={'Step 3'} /> + +<center> + 结合初中的几何学知识,我们首先知道一个基本知识,两点之间,直线最短。所以,维修点和顾客在同一条直线上时,他们之间的距离就是直线距离。 +</center> + +<img src={'/images/recaps/algo-minimal-costs/step4.svg'} width={800} height={400} alt={'Step 4'} /> + +<center>然后我们再稍微复杂一点,此时顾客和维修点之间是田字格,最短路径就有三条,距离为 3。</center> + +<img src={'/images/recaps/algo-minimal-costs/step5.svg'} width={800} height={400} alt={'Step 5'} /> + +<center> + 等到田字格的时候,相信聪明的你已经发现了规律。那就是顾客到维修点的最短距离,等于他们所形成的矩形的横纵两条边边长的总和。按照上面右侧图片所示的箭头所行走的距离都等于这个最短路径。 +</center> + +一般情况下,面试场景的编码题已经可以开始写了。对应的编程思路就是,从维修点出发,在与顾客构成的矩形边界里面,不断逼近,只要能走通那么我们之间就有了最短距离。再把不同维修点到顾客的最短距离排序,选出最小的距离来进行计算费用。 + +<img src={'/images/recaps/algo-minimal-costs/step6.svg'} width={800} height={400} alt={'Step 6'} /> + +倘若以上面的推论作为最终编码的方式,虽然不能说完全错误,但是在当下这个面试很卷的时代,还是有可能被 PASS,为什么呢?因为我们还没有引入阻塞的概念。我们随便画两种阻塞的情况,并且假定这里都属于在当时条件下的最短路径,那么阁下又该如何应对?😆 + + + +某种意义上说,我们的确需要从头来审视这道题目。从前面的分析和题目中,我们得出两个结论。 + +1. 最短的距离永远是尽量在水平和垂直距离上向目标靠近的走法。 +2. 用户每次前进,在没有阻塞的时候,其实可以最多可以往四个方向去走。 + +以此为基础,我们就可以稍微来复习一下大学的算法知识了,贪心算法(贪婪算法)。贪心算法的定义网上随随便便都能找到,这里就不再复述,我们更多地是需要去思考在这个场景的贪心算法如何使用。 + +<img src={'/images/recaps/algo-minimal-costs/step7.svg'} width={800} height={400} alt={'Step 7'} /> + +贪心算法的第一步,就是找寻从顾客开始,所有可能能行走方向距离为 1 的点有哪些(图中蓝色的点)。接着,我们可以以这些距离为 1 的点为基础,去找寻所有距离为 2 的点(图中绿色的点)。以此类推,直到所有的点都没有下一个可以行走的点了。而每计算一次距离为 N 的点的时候,都可以尝试看看里面是否有对应的维修点,如果有,那么终止检索,这个 N 便是最短距离。 + +<img src={'/images/recaps/algo-minimal-costs/step8.svg'} width={800} height={400} alt={'Step 8'} /> + +如上图所示,在我们查找距离为 4 的点的时候,我们就能找到目标维修店,那么我们可以认定,起最短距离就是 4。 + +下面就可以考虑编码了,倘若是在算法竞赛里面(这种题连算竞入门题都不算啦),首先需要考虑的是时空效率。我们首先定义一个二维数组,并在上面放上维修店,假定魔力数字 -1。然后放上所有阻塞的点,假定魔力数字为 -2。数组里面数字为 0 的地方代表没有走过的点,为 1 的值则代表走过的点。 + +那么此检索最短路径的算法大概应该类似如下内容,类伪代码,不代表最终能运行品质: + +```java +int[][] routines = new int[x][y]; + +public record Point(int x, int y) {} + +public record SearchResult(boolean found, List<Point> next) {} + +public int findMinimalRoutine(int[][] routines, Point customer) { + List<Point> next = Collections.singleton(customer); + int minimalPath = 1; + + do { + result = findNextPoints(routines, next); + if (result.found) { + return minimalPath; + } + minimalPath += 1; + next = result.next; + } while (next != null && !next.isEmpty()); + + return 0; +} + +public SearchResult findNextPoints(int[][] routines, List<Point> currentPoints) { + List<Point> resultPoints = new ArraryList<>(); + + for (Point currentPoint : currentPoints) { + List<Point> nextPoints = findNextPoints(routines, currentPoint); + + for (Point nextPoint : nextPoints) { + if (routines[nextPoint.x][nextPoint.y] == -1) { + return new SearchResult(true, Collections.emptyList()); + } + + routines[nextPoint.x][nextPoint.y] = 1; + } + + resultPoints.addAll(nextPoints); + } + + return new SearchResult(false, resultPoints); +} + +public List<Point> findNextPoints(int[][] routines, Point point) { + List<Point> nextPoints = new ArraryList<>(4); + + if (availablePoint(routines, point.x - 1, point.y)) { + nextPoints.add(new Point(point.x - 1, point.y)); + } + if (availablePoint(routines, point.x, point.y - 1)) { + nextPoints.add(new Point(point.x, point.y - 1)); + } + if (availablePoint(routines, point.x + 1, point.y)) { + nextPoints.add(new Point(point.x + 1, point.y)); + } + if (availablePoint(routines, point.x, point.y + 1)) { + nextPoints.add(new Point(point.x, point.y + 1)); + } + + return nextPoints; +} + +private boolean availablePoint(int[][] routines, int x, int y) { + return x >= 0 && x < routines.length && y >= 0 && y <= routines[0].length && (routines[x][y] == 0 || routines[x][y] == -1); +} +``` diff --git a/src/content/posts/2024/2024-05-29-gossip-on-reading.mdx b/src/content/posts/2024/2024-05-29-gossip-on-reading.mdx new file mode 100644 index 0000000..51c4814 --- /dev/null +++ b/src/content/posts/2024/2024-05-29-gossip-on-reading.mdx @@ -0,0 +1,29 @@ +--- +title: 谈读书 +slug: gossip-on-reading +date: 2024-05-29 22:42:12 +updated: 2024-05-29 23:15:12 +tags: + - 读书 +category: 杂谈 +summary: 藏书如山积,读书如水流。山形有限度,水流无时休。 +cover: /images/2024/05/2024052912190600.jpg +--- + + + +“藏书如山积,读书如水流。山形有限度,水流无时休。”这幅画是丰子恺一九三五年画赠钱君匋的,我非常喜欢,遂借花献佛与同好分享。 + +有人说读书是人世间第一等美事,是精神生活的不二首选,我深以为然。然“天上浮云如白衣,斯须变幻如苍狗”。就好比谈读书,喜欢读书,却没有时间读,可叹也。喜欢读书,也有时间读书,但就是不读,可惜也。而不喜欢读书,那也就谈不上有时间没时间读了,可悲也。 + +喜欢读书,却找不到心仪的书读,缺少可用资源,颇可叹也。喜欢读书,也喜欢藏书,却不知道读什么书,徒占着丰富的资源,任其荒废着,犹可惜也。既不喜欢读书、也不喜欢藏书,无所事事,任光阴付水流,最可悲也。 + +人生苦短,如白驹过隙,忙忙碌碌到处奔波,再回首就是高堂明镜悲白发,人老不能转少年。故此,何不趁着“春风得意马蹄急”的黄金时光,来“一日看尽长安花”呢。 + +中国古籍浩浩荡荡,累累皇皇,何之尽也。尽管历经秦始皇焚书、文革浩劫以及兵灾火燹的毁损消耗,而今存世的图书古籍,仍然是苍茫云水间,无边无岸。各类珍奇好玩之书,比比皆是。只要你喜欢读书,在当下高度发达的信息时代,就会应有尽有,无需远涉它求。一旦养成良好的读书习惯,就能跻身高雅之殿堂,就能忝列高贵之门墙,何乐而不为? + +书籍是文明之载体,无价瑰宝,古今中外无数先贤在其上留下了无尽宝藏,等我们去挖掘探索,还有鲜为人知的奇技淫巧,靠我们去研发传承。再退一步说,至少也能陶冶情操,增加城府,提升厚度,完善操守,不虚此生矣。 + +生命诚可贵,光阴太无情,我们在善待身体健康的同时,宜珍爱幸福美好的太平盛世,珍惜稍纵即逝的大好时光。品读圣贤书,只走康庄路,尽享精神生活之快乐,乃人生正道耳。 + + diff --git a/src/content/posts/2024/2024-06-13-data-oriented-programming-in-java.mdx b/src/content/posts/2024/2024-06-13-data-oriented-programming-in-java.mdx new file mode 100644 index 0000000..d3ff80c --- /dev/null +++ b/src/content/posts/2024/2024-06-13-data-oriented-programming-in-java.mdx @@ -0,0 +1,12 @@ +--- +title: 使用 Java 进行面向对象编程 +slug: data-oriented-programming-in-java +date: 2024-05-29 22:42:12 +updated: 2024-05-29 23:15:12 +tags: + - 读书 +category: 杂谈 +summary: 藏书如山积,读书如水流。山形有限度,水流无时休。 +cover: /images/2024/05/2024052912190600.jpg +published: false +--- diff --git a/src/content/tags/index.yml b/src/content/tags/index.yml new file mode 100644 index 0000000..44cacaf --- /dev/null +++ b/src/content/tags/index.yml @@ -0,0 +1,566 @@ +- name: 装帧 + slug: 'book-binding' +- name: 回忆 + slug: 'recollection' +- name: 中年 + slug: 'middle-age' +- name: 时光 + slug: 'moment' +- name: 烟花 + slug: 'fireworks' +- name: 思考 + slug: 'thinking' +- name: 编码 + slug: 'encoding' +- name: 编程 + slug: 'programming' +- name: 晴天娃娃 + slug: 'teruteru' +- name: 小简 + slug: 'xiao-jian' +- name: 代码 + slug: 'code' +- name: 人生 + slug: 'life' +- name: 抉择 + slug: 'choice' +- name: 北漂 + slug: 'work-in-beijing' +- name: 工作总结 + slug: 'work-summary' +- name: 学习 + slug: 'study' +- name: 总结 + slug: 'summary' +- name: 数据库 + slug: 'database' +- name: 存储 + slug: 'storage' +- name: 雨 + slug: 'rain' +- name: 碎碎念 + slug: 'sui-sui-nian' +- name: 工作室 + slug: 'workshop' +- name: 游戏 + slug: 'game' +- name: 菲莉丝 + slug: 'firis' +- name: Spring + slug: 'spring' +- name: 演讲 + slug: 'speech' +- name: 梦想 + slug: 'dream' +- name: 日文 + slug: 'japanese' +- name: Scala + slug: 'scala' +- name: 奥运会 + slug: 'olympics' +- name: 前端 + slug: 'front-end' +- name: 随笔 + slug: 'random-thoughts' +- name: 工作 + slug: 'work' +- name: Kong + slug: 'kong' +- name: 饮食 + slug: 'diet' +- name: 败家 + slug: 'squandering' +- name: 软件 + slug: 'software' +- name: 雨季 + slug: 'rainy-season' +- name: 慢生活 + slug: 'slow-life' +- name: 爱情 + slug: 'loveness' +- name: 影评 + slug: 'movie-review' +- name: Java + slug: 'java' +- name: 图灵 + slug: 'turing' +- name: Linux + slug: 'linux' +- name: 毕业 + slug: 'graduation' +- name: 山大 + slug: 'shan-da' +- name: 黑历史 + slug: 'dark-history' +- name: 怀旧 + slug: 'nostalgia' +- name: 信笺 + slug: 'letterhead' +- name: Android + slug: 'android' +- name: 看见 + slug: 'see' +- name: 心路历程 + slug: 'journey-of-heart' +- name: 中秋 + slug: 'mid-autumn' +- name: 思乡 + slug: 'homesickness' +- name: 死亡 + slug: 'death' +- name: 思念是一首诗 + slug: 'missing-is-a-poem' +- name: 迷茫 + slug: 'confused' +- name: 实训 + slug: 'practical-training' +- name: 青春 + slug: 'youth' +- name: 言叶之庭 + slug: 'garden-of-words' +- name: CSS + slug: 'css' +- name: HTML + slug: 'html' +- name: 济南 + slug: 'ji-nan' +- name: 春天 + slug: 'springtime' +- name: 琐碎 + slug: 'trivial' +- name: 朴树 + slug: 'pu-shu' +- name: 温情 + slug: 'warmth' +- name: 家人 + slug: 'family' +- name: 现实 + slug: 'reality' +- name: 文字 + slug: 'text' +- name: 忧郁 + slug: 'melancholy' +- name: 年度总结 + slug: 'annual-summary' +- name: 笔耕不辍 + slug: 'persistent-writing' +- name: 秘密 + slug: 'secret' +- name: 心事 + slug: 'concerns' +- name: 情感 + slug: 'emotion' +- name: 时光机 + slug: 'time-machine' +- name: 独立 + slug: 'independence' +- name: '90后' + slug: '90s-generation' +- name: 孤独 + slug: 'loneliness' +- name: 三年 + slug: 'three-years' +- name: 动漫 + slug: 'anime' +- name: 小樱 + slug: 'xiao-ying' +- name: 记忆 + slug: 'memory' +- name: 旅行 + slug: 'travel' +- name: 香味 + slug: 'fragrance' +- name: 自然 + slug: 'nature' +- name: 爱 + slug: 'love' +- name: 眼泪 + slug: 'tears' +- name: 未来 + slug: 'future' +- name: 明天 + slug: 'tomorrow' +- name: 花儿 + slug: 'flowers' +- name: 乡音 + slug: 'hometown-sound' +- name: 故乡 + slug: 'hometown' +- name: 博客 + slug: 'blog' +- name: 写作 + slug: 'writing' +- name: 恋爱 + slug: 'amativeness' +- name: 童年 + slug: 'childhood' +- name: 悠久之翼 + slug: 'eternal-wing' +- name: 同人 + slug: 'fandom' +- name: 哲学 + slug: 'philosophy' +- name: 再见 + slug: 'goodbye' +- name: 成长 + slug: 'growth' +- name: 约定 + slug: 'promise' +- name: 父亲 + slug: 'father' +- name: 汐阳 + slug: 'xi-yang' +- name: 日光 + slug: 'sunlight' +- name: 心灵的鸡汤 + slug: 'chicken-soup-for-the-soul' +- name: SHMILY + slug: 'shmily' +- name: 幸福 + slug: 'happiness' +- name: 心烦 + slug: 'annoyed' +- name: 生活 + slug: 'living' +- name: 黄昏 + slug: 'dusk' +- name: 郭敬明 + slug: 'guo-jing-ming' +- name: 小时代 + slug: 'hour-age' +- name: 感想 + slug: 'thoughts' +- name: 呆瓜 + slug: 'melon' +- name: 笨蛋 + slug: 'fool' +- name: 傻瓜 + slug: 'idiot' +- name: 夜 + slug: 'night' +- name: 转载 + slug: 'reprint' +- name: 烦恼 + slug: 'trouble' +- name: 那朵花 + slug: 'that-flower' +- name: 音画 + slug: 'sound-and-picture' +- name: 夏影 + slug: 'summer-shadow' +- name: 观铃 + slug: 'guan-ling' +- name: 上海 + slug: 'shanghai' +- name: 游记 + slug: 'travelogue' +- name: 亲情 + slug: 'family-affection' +- name: 爷爷 + slug: 'grandfather' +- name: 暖春 + slug: 'warm-spring' +- name: 樱花 + slug: 'cherry-blossom' +- name: 母亲节 + slug: 'mother-day' +- name: 妈妈 + slug: 'mother' +- name: 小说 + slug: 'novel' +- name: 外婆 + slug: 'grandmother' +- name: 西门 + slug: 'xi-men' +- name: 主机 + slug: 'host' +- name: 主机格调 + slug: 'host-style' +- name: 书信 + slug: 'letter' +- name: 忙碌 + slug: 'busy' +- name: 三角梅 + slug: 'bougainvillea' +- name: 高中 + slug: 'high-school' +- name: 轮回 + slug: 'cycle' +- name: 纳兰性德 + slug: 'na-lan-xing-de' +- name: 情思 + slug: 'affection' +- name: 随想 + slug: 'reflection' +- name: 伤口 + slug: 'wound' +- name: 情境 + slug: 'situation' +- name: 陌生 + slug: 'stranger' +- name: 灵魂 + slug: 'soul' +- name: 过去 + slug: 'past' +- name: 老屋 + slug: 'old-house' +- name: 火车 + slug: 'train' +- name: 金粉世家 + slug: 'golden-family' +- name: 读者 + slug: 'reader' +- name: 杂思 + slug: 'miscellaneous-thoughts' +- name: 目标 + slug: 'goal' +- name: 时间 + slug: 'time' +- name: 图片时光 + slug: 'image-time' +- name: 蓝色土耳其 + slug: 'blue-turkey' +- name: 伤感 + slug: 'sadness' +- name: 候鸟 + slug: 'migratory-bird' +- name: 回家 + slug: 'go-home' +- name: 史铁生 + slug: 'shi-tie-sheng' +- name: 生与死 + slug: 'life-and-death' +- name: 刘若英 + slug: 'liu-ruo-ying' +- name: '听,是谁在唱歌' + slug: 'listen-who-is-singing' +- name: 老歌 + slug: 'old-song' +- name: 百日 + slug: 'hundred-days' +- name: 纪念 + slug: 'commemorate' +- name: 那些年 + slug: 'those-years' +- name: 相思 + slug: 'love-sickness' +- name: 思念 + slug: 'missing' +- name: 冷山 + slug: 'cold-mountain' +- name: 茶 + slug: 'tea' +- name: 品悟 + slug: 'appreciation' +- name: 雪 + slug: 'snow' +- name: 起点 + slug: 'starting-point' +- name: 开始 + slug: 'start' +- name: 更新 + slug: 'update' +- name: 琥珀 + slug: 'amber' +- name: 薰衣草 + slug: 'lavender' +- name: 感触 + slug: 'touch' +- name: 生日石 + slug: 'birthstone' +- name: 雨后 + slug: 'after-rain' +- name: 晴天 + slug: 'sunny-day' +- name: 文化 + slug: 'culture' +- name: 手写 + slug: 'handwriting' +- name: 键盘 + slug: 'keyboard' +- name: 网络 + slug: 'network' +- name: 平板 + slug: 'tablet' +- name: 梅雨 + slug: 'plum-rain' +- name: 坦然 + slug: 'calm' +- name: 面对 + slug: 'face' +- name: 挫折 + slug: 'setback' +- name: 平淡 + slug: 'plain' +- name: 高考 + slug: 'college-entrance-exam' +- name: 拼搏 + slug: 'struggle' +- name: 亮剑 + slug: 'bright-sword' +- name: 剑客 + slug: 'swordsman' +- name: 江湖 + slug: 'rivers-and-lakes' +- name: 风 + slug: 'wind' +- name: 街道 + slug: 'street' +- name: 恋恋 + slug: 'love-love' +- name: 笔记本 + slug: 'notebook' +- name: 前言 + slug: 'preface' +- name: 记事 + slug: 'remember' +- name: 校庆 + slug: 'school-anniversary' +- name: 无聊 + slug: 'bored' +- name: 思想 + slug: 'thought' +- name: 人性 + slug: 'human-nature' +- name: 男女 + slug: 'male-female' +- name: 性别 + slug: 'gender' +- name: 流年 + slug: 'passing-years' +- name: 花开 + slug: 'flower-blooming' +- name: 初中 + slug: 'junior-high-school' +- name: 回首 + slug: 'look-back' +- name: 瞬间 + slug: 'instant' +- name: 美好 + slug: 'glorious' +- name: 父母 + slug: 'parents' +- name: '点滴,情感' + slug: 'drops-emotion' +- name: 光阴 + slug: 'time-flies' +- name: 故事 + slug: 'story' +- name: 方大同 + slug: 'khalil-fong' +- name: 我与狗狗的十个约定 + slug: 'my-ten-promises-with-dogs' +- name: 感伤 + slug: 'touching' +- name: 十年 + slug: 'ten-years' +- name: 梦断 + slug: 'dream-broken' +- name: 逆流河 + slug: 'countercurrent-river' +- name: 李献计 + slug: 'li-xian-ji' +- name: 遗失 + slug: 'lost' +- name: 寂寞 + slug: 'lonely' +- name: 浅浅 + slug: 'shallow' +- name: 想念 + slug: 'miss' +- name: 黑夜 + slug: 'dark-night' +- name: 花季 + slug: 'flower-season' +- name: 魔法 + slug: 'magic' +- name: 哈利波特 + slug: 'harry-potter' +- name: 散场 + slug: 'fin' +- name: 碎花 + slug: 'broken-flower' +- name: 布裙 + slug: 'skirt' +- name: 年华 + slug: 'years' +- name: 懵懂 + slug: 'ignorance' +- name: 爱恋 + slug: 'love-affair' +- name: 记录 + slug: 'record' +- name: 洗澡 + slug: 'shower' +- name: 澡堂 + slug: 'bathhouse' +- name: 新旧交替 + slug: 'alternation-of-new-and-old' +- name: 展望 + slug: 'outlook' +- name: 疼痛 + slug: 'pain' +- name: 无奈 + slug: 'helpless' +- name: 安静 + slug: 'quiet' +- name: 且听风吟 + slug: 'listen-to-the-wind' +- name: 旧书 + slug: 'old-book' +- name: 联想 + slug: 'association' +- name: 碎片 + slug: 'fragment' +- name: 余秋雨 + slug: 'yu-qiu-yu' +- name: 文化苦旅 + slug: 'cultural-tour-of-suffering' +- name: 雨夜 + slug: 'rainy-night' +- name: 随感 + slug: 'impression' +- name: 点滴 + slug: 'drop' +- name: 青春期 + slug: 'adolescence' +- name: 烦躁 + slug: 'irritability' +- name: 告别 + slug: 'farewell' +- name: 月台 + slug: 'platform' +- name: 离别 + slug: 'leaving' +- name: 重聚 + slug: 'reunion' +- name: 相逢 + slug: 'meet' +- name: 小四 + slug: 'xiao-si' +- name: 花谢 + slug: 'flower-fall' +- name: 结束 + slug: 'end' +- name: 美丽 + slug: 'beautiful' +- name: 天鹅 + slug: 'swan' +- name: 厦门 + slug: 'amoy' +- name: 凤凰花 + slug: 'poinciana' +- name: 成功 + slug: 'success' +- name: 合肥 + slug: hefei +- name: 算法 + slug: algorithm +- name: 面试 + slug: interview +- name: 阿里 + slug: alibaba +- name: 腾讯 + slug: tencent +- name: 读书 + slug: reading diff --git a/src/env.d.ts b/src/env.d.ts new file mode 100644 index 0000000..204abbc --- /dev/null +++ b/src/env.d.ts @@ -0,0 +1,4 @@ +/// <reference path="../.astro/env.d.ts" /> +/// <reference path="../.astro/types.d.ts" /> +/// <reference types="astro/client" /> +/// <reference types="vite-plugin-arraybuffer/types" /> diff --git a/src/helpers/db/pool.ts b/src/helpers/db/pool.ts new file mode 100644 index 0000000..45c6a59 --- /dev/null +++ b/src/helpers/db/pool.ts @@ -0,0 +1,27 @@ +import * as schema from '@/helpers/db/schema'; +import { getSecret } from 'astro:env/server'; +import { drizzle } from 'drizzle-orm/node-postgres'; +import pg from 'pg'; + +/** + * Cache the database connection in development. This avoids creating a new connection on every HMR update. + */ +const globalForDb = globalThis as unknown as { + conn: pg.Pool | undefined; +}; + +const conn = + globalForDb.conn ?? + new pg.Pool({ + host: getSecret('POSTGRES_HOST'), + port: getSecret('POSTGRES_PORT'), + user: getSecret('POSTGRES_USERNAME'), + password: getSecret('POSTGRES_PASSWORD'), + database: getSecret('POSTGRES_DATABASE'), + keepAlive: true, + }); + +// Cache the connection. +globalForDb.conn = conn; + +export const db = drizzle(conn, { schema: schema, logger: false }); diff --git a/src/helpers/db/query.ts b/src/helpers/db/query.ts new file mode 100644 index 0000000..ab9028b --- /dev/null +++ b/src/helpers/db/query.ts @@ -0,0 +1,119 @@ +import { db } from '@/helpers/db/pool'; +import { atk_comments, atk_likes, atk_pages, atk_users } from '@/helpers/db/schema'; +import { options } from '@/helpers/schema'; +import { makeToken, urlJoin } from '@/helpers/tools'; +import { and, desc, eq, isNull, notInArray, sql } from 'drizzle-orm'; + +export interface Comment { + title: string; + author: string; + authorLink: string; + permalink: string; +} + +export const latestComments = async (): Promise<Comment[]> => { + const results = await db + .select({ + id: atk_comments.id, + page: atk_comments.page_key, + title: atk_pages.title, + author: atk_users.name, + authorLink: atk_users.link, + }) + .from(atk_comments) + .leftJoin(atk_pages, eq(atk_comments.page_key, atk_pages.key)) + .leftJoin(atk_users, eq(atk_comments.user_id, atk_users.id)) + .where(and(notInArray(atk_comments.user_id, options.settings.comments.admins), eq(atk_comments.is_pending, false))) + .orderBy(desc(atk_comments.created_at)) + .limit(options.settings.sidebar.comment); + + return results.map(({ title, author, authorLink, page, id }) => { + let trimTitle = title ?? ''; + if (trimTitle.includes(` - ${options.title}`)) { + trimTitle = trimTitle.substring(0, trimTitle.indexOf(` - ${options.title}`)); + } + return { + title: trimTitle, + author: author ?? '', + authorLink: authorLink ?? '', + permalink: `${page}#atk-comment-${id}`, + }; + }); +}; + +const generateKey = (slug: string): string => urlJoin(options.website, '/posts', slug, '/'); + +export const increaseLikes = async (slug: string): Promise<{ likes: number; token: string }> => { + const pageKey = generateKey(slug); + const token = makeToken(250); + // Save the token + await db.insert(atk_likes).values({ + token: token, + page_key: pageKey, + created_at: new Date(), + updated_at: new Date(), + }); + + // Bump the likes + await db + .update(atk_pages) + .set({ + vote_up: sql`${atk_pages.vote_up} + 1`, + }) + .where(eq(atk_pages.key, sql`${pageKey}`)); + + return { likes: await queryLikes(slug), token: token }; +}; + +export const decreaseLikes = async (slug: string, token: string) => { + const pageKey = generateKey(slug); + const results = await db + .select({ id: atk_likes.id }) + .from(atk_likes) + .where(and(eq(atk_likes.token, token), eq(atk_likes.page_key, pageKey), isNull(atk_likes.deleted_at))) + .limit(1); + + // No need to dislike + if (results.length <= 0) { + return; + } + + const id = results[0].id; + // Remove the token + await db + .update(atk_likes) + .set({ + updated_at: new Date(), + deleted_at: new Date(), + }) + .where(eq(atk_likes.id, id)); + // Decrease the likes + await db + .update(atk_pages) + .set({ + vote_up: sql`${atk_pages.vote_up} - 1`, + }) + .where(eq(atk_pages.key, sql`${pageKey}`)); +}; + +export const queryLikes = async (slug: string): Promise<number> => { + const pageKey = generateKey(slug); + const results = await db + .select({ like: atk_pages.vote_up }) + .from(atk_pages) + .where(eq(atk_pages.key, sql`${pageKey}`)) + .limit(1); + + return results.length > 0 ? results[0].like ?? 0 : 0; +}; + +export const queryLikesAndViews = async (slug: string): Promise<[number, number]> => { + const pageKey = generateKey(slug); + const results = await db + .select({ like: atk_pages.vote_up, view: atk_pages.pv }) + .from(atk_pages) + .where(eq(atk_pages.key, sql`${pageKey}`)) + .limit(1); + + return results.length > 0 ? [results[0].like ?? 0, results[0].view ?? 0] : [0, 0]; +}; diff --git a/src/helpers/db/schema.ts b/src/helpers/db/schema.ts new file mode 100644 index 0000000..181fc94 --- /dev/null +++ b/src/helpers/db/schema.ts @@ -0,0 +1,113 @@ +import { bigint, bigserial, boolean, index, pgTable, text, timestamp, varchar } from 'drizzle-orm/pg-core'; + +export const atk_pages = pgTable( + 'atk_pages', + { + id: bigserial('id', { mode: 'bigint' }).primaryKey().notNull(), + created_at: timestamp('created_at', { withTimezone: true, mode: 'date' }), + updated_at: timestamp('updated_at', { withTimezone: true, mode: 'date' }), + deleted_at: timestamp('deleted_at', { withTimezone: true, mode: 'date' }), + key: varchar('key', { length: 255 }), + title: text('title'), + admin_only: boolean('admin_only'), + site_name: varchar('site_name', { length: 255 }), + // You can use { mode: "bigint" } if numbers are exceeding js number limitations + vote_up: bigint('vote_up', { mode: 'number' }), + // You can use { mode: "bigint" } if numbers are exceeding js number limitations + vote_down: bigint('vote_down', { mode: 'number' }), + // You can use { mode: "bigint" } if numbers are exceeding js number limitations + pv: bigint('pv', { mode: 'number' }), + }, + (table) => { + return { + idx_atk_pages_site_name: index('idx_atk_pages_site_name').on(table.site_name), + idx_atk_pages_key: index('idx_atk_pages_key').on(table.key), + idx_atk_pages_deleted_at: index('idx_atk_pages_deleted_at').on(table.deleted_at), + }; + }, +); + +export const atk_likes = pgTable( + 'atk_likes', + { + id: bigserial('id', { mode: 'bigint' }).primaryKey().notNull(), + created_at: timestamp('created_at', { withTimezone: true, mode: 'date' }), + updated_at: timestamp('updated_at', { withTimezone: true, mode: 'date' }), + deleted_at: timestamp('deleted_at', { withTimezone: true, mode: 'date' }), + token: varchar('token', { length: 255 }), + page_key: varchar('page_key', { length: 255 }), + }, + (table) => { + return { + idx_atk_likes_token: index('idx_atk_likes_token').on(table.token), + }; + }, +); + +export const atk_users = pgTable( + 'atk_users', + { + id: bigserial('id', { mode: 'bigint' }).primaryKey().notNull(), + created_at: timestamp('created_at', { withTimezone: true, mode: 'date' }), + updated_at: timestamp('updated_at', { withTimezone: true, mode: 'date' }), + deleted_at: timestamp('deleted_at', { withTimezone: true, mode: 'date' }), + name: varchar('name', { length: 255 }), + email: varchar('email', { length: 255 }), + link: text('link'), + password: text('password'), + badge_name: text('badge_name'), + badge_color: text('badge_color'), + last_ip: text('last_ip'), + last_ua: text('last_ua'), + is_admin: boolean('is_admin'), + receive_email: boolean('receive_email').default(true), + token_valid_from: timestamp('token_valid_from', { withTimezone: true, mode: 'date' }), + is_in_conf: boolean('is_in_conf'), + }, + (table) => { + return { + idx_atk_users_email: index('idx_atk_users_email').on(table.email), + idx_atk_users_name: index('idx_atk_users_name').on(table.name), + idx_atk_users_deleted_at: index('idx_atk_users_deleted_at').on(table.deleted_at), + }; + }, +); + +export const atk_comments = pgTable( + 'atk_comments', + { + id: bigserial('id', { mode: 'bigint' }).primaryKey().notNull(), + created_at: timestamp('created_at', { withTimezone: true, mode: 'date' }), + updated_at: timestamp('updated_at', { withTimezone: true, mode: 'date' }), + deleted_at: timestamp('deleted_at', { withTimezone: true, mode: 'date' }), + content: text('content'), + page_key: varchar('page_key', { length: 255 }), + site_name: varchar('site_name', { length: 255 }), + // You can use { mode: "bigint" } if numbers are exceeding js number limitations + user_id: bigint('user_id', { mode: 'number' }), + is_verified: boolean('is_verified').default(false), + ua: text('ua'), + ip: text('ip'), + // You can use { mode: "bigint" } if numbers are exceeding js number limitations + rid: bigint('rid', { mode: 'number' }), + is_collapsed: boolean('is_collapsed').default(false), + is_pending: boolean('is_pending').default(false), + is_pinned: boolean('is_pinned').default(false), + // You can use { mode: "bigint" } if numbers are exceeding js number limitations + vote_up: bigint('vote_up', { mode: 'number' }), + // You can use { mode: "bigint" } if numbers are exceeding js number limitations + vote_down: bigint('vote_down', { mode: 'number' }), + // You can use { mode: "bigint" } if numbers are exceeding js number limitations + root_id: bigint('root_id', { mode: 'number' }), + }, + (table) => { + return { + idx_atk_comments_root_id: index('idx_atk_comments_root_id').on(table.root_id), + idx_atk_comments_rid: index('idx_atk_comments_rid').on(table.rid), + idx_atk_comments_user_id: index('idx_atk_comments_user_id').on(table.user_id), + idx_atk_comments_site_name: index('idx_atk_comments_site_name').on(table.site_name), + idx_atk_comments_page_key: index('idx_atk_comments_page_key').on(table.page_key), + idx_atk_comments_deleted_at: index('idx_atk_comments_deleted_at').on(table.deleted_at), + }; + }, +); diff --git a/src/helpers/formatter.ts b/src/helpers/formatter.ts new file mode 100644 index 0000000..53f7d75 --- /dev/null +++ b/src/helpers/formatter.ts @@ -0,0 +1,60 @@ +import { options, type Post } from '@/helpers/schema'; +import { DateTime } from 'luxon'; + +export const slicePosts = ( + posts: Post[], + pageNum: number, + pageSize: number, +): { currentPosts: Post[]; totalPage: number } | undefined => { + const totalPage = Math.ceil(posts.length / pageSize); + if (totalPage >= pageNum) { + return { + currentPosts: + pageNum === totalPage + ? posts.slice((pageNum - 1) * pageSize) + : posts.slice((pageNum - 1) * pageSize, pageNum * pageSize), + totalPage, + }; + } +}; + +export const formatShowDate = (date: Date) => { + const source = date ? +new Date(date) : +new Date(); + const now = +new Date(); + const diff = now - source > 0 ? now - source : 60 * 1000; + const oneSeconds = 1000; + const oneMinute = oneSeconds * 60; + const oneHour = oneMinute * 60; + const oneDay = oneHour * 24; + const oneWeek = oneDay * 7; + const oneMonth = oneDay * 30; + const oneYear = oneDay * 365; + + // Formatter for different types of date. + if (diff < oneDay) { + return '今天'; + } + if (diff < oneWeek) { + return `${Math.floor(diff / oneDay)} 天前`; + } + if (diff < oneMonth) { + return `${Math.floor(diff / oneWeek)} 周前`; + } + if (diff < oneYear) { + const months = Math.floor(diff / oneMonth); + if (months > 0) { + return `${months} 月前`; + } + } + + const years = Math.floor(diff / oneYear); + if (years > 0 && years < 3) { + return `${years} 年前`; + } + + // Format the post's date with time zone support. + return DateTime.fromJSDate(date) + .setZone(options.settings.timeZone) + .setLocale(options.settings.locale) + .toFormat(options.settings.timeFormat); +}; diff --git a/src/helpers/images.ts b/src/helpers/images.ts new file mode 100644 index 0000000..dde65d2 --- /dev/null +++ b/src/helpers/images.ts @@ -0,0 +1,76 @@ +import fs from 'node:fs/promises'; +import { join } from 'node:path'; + +export interface Image { + /** + * public url of the image + */ + src: string; + /** + * image width + */ + width: number; + /** + * image height + */ + height: number; + /** + * blurDataURL of the image + */ + blurDataURL: string; + /** + * blur image width + */ + blurWidth: number; + /** + * blur image height + */ + blurHeight: number; +} + +export const openGraphWidth = 1200; + +export const openGraphHeight = 768; + +// Copied and modified from https://github.com/vercel/next.js/blob/canary/packages/next/src/shared/lib/image-blur-svg.ts +const blurImage = ({ width, height, blurWidth, blurHeight, blurDataURL }: Image): string => { + const std = 20; + const svgWidth = blurWidth ? blurWidth * 40 : width; + const svgHeight = blurHeight ? blurHeight * 40 : height; + + const viewBox = svgWidth && svgHeight ? `viewBox='0 0 ${svgWidth} ${svgHeight}'` : ''; + + return `%3Csvg xmlns='http://www.w3.org/2000/svg' ${viewBox}%3E%3Cfilter id='b' color-interpolation-filters='sRGB'%3E%3CfeGaussianBlur stdDeviation='${std}'/%3E%3CfeColorMatrix values='1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 100 -1' result='s'/%3E%3CfeFlood x='0' y='0' width='100%25' height='100%25'/%3E%3CfeComposite operator='out' in='s'/%3E%3CfeComposite in2='SourceGraphic'/%3E%3CfeGaussianBlur stdDeviation='${std}'/%3E%3C/filter%3E%3Cimage width='100%25' height='100%25' x='0' y='0' preserveAspectRatio='xMidYMid slice' style='filter: url(%23b);' href='${blurDataURL}'/%3E%3C/svg%3E`; +}; + +export const blurStyle = (image: Image) => ({ + backgroundSize: 'cover', + backgroundPosition: '50% 50%', + backgroundRepeat: 'no-repeat', + backgroundImage: `url("data:image/svg+xml;charset=utf-8,${blurImage({ ...image })}")`, +}); + +// Copied and modified https://github.com/zce/velite/blob/main/src/assets.ts +export const imageMetadata = async (publicPath: string): Promise<Image> => { + // Load for sharp on demand for avoiding the resolver issues in production. + const { default: sharp } = await import('sharp'); + + if (!publicPath.startsWith('/')) { + throw new Error('We only support image path in public direct. It should start with "/".'); + } + + const root = join(process.cwd(), 'public'); + const buffer = await fs.readFile(join(root, publicPath)); + const img = sharp(buffer); + const { width, height } = await img.metadata(); + if (width == null || height == null) { + throw new Error(`Invalid image path: ${publicPath}`); + } + const aspectRatio = width / height; + const blurWidth = 8; + const blurHeight = Math.round(blurWidth / aspectRatio); + const blurImage = await img.resize(blurWidth, blurHeight).webp({ quality: 1 }).toBuffer(); + const blurDataURL = `data:image/webp;base64,${blurImage.toString('base64')}`; + + return { src: publicPath, height, width, blurDataURL, blurWidth, blurHeight }; +}; diff --git a/src/helpers/og.ts b/src/helpers/og.ts new file mode 100644 index 0000000..96a1f73 --- /dev/null +++ b/src/helpers/og.ts @@ -0,0 +1,175 @@ +/** + * Generate the open graph. + * It's highly inspired by the code from https://github.com/yuaanlin/yual.in/blob/main/pages/og_image/%5Bslug%5D.tsx + * The original open source code don't have any license. + * But I have get the approvement to use them here by asking the author https://twitter.com/yuaanlin. + */ +import { openGraphHeight, openGraphWidth } from '@/helpers/images'; +import { options } from '@/helpers/schema'; +import { Canvas, GlobalFonts, Image, type SKRSContext2D } from '@napi-rs/canvas'; +import { readFile } from 'node:fs/promises'; +import { join } from 'node:path'; +import font from '../asserts/og/NotoSansSC-Bold.ttf?arraybuffer'; +import logoDark from '../asserts/og/logo-dark.png?arraybuffer'; + +const getStringWidth = (text: string, fontSize: number) => { + let result = 0; + for (let idx = 0; idx < text.length; idx++) { + if (text.charCodeAt(idx) > 255) { + result += fontSize; + } else { + result += fontSize * 0.5; + } + } + return result; +}; + +// Print text on SKRSContext with wrapping +const printAt = ( + context: SKRSContext2D, + text: string, + x: number, + y: number, + lineHeight: number, + fitWidth: number, + fontSize: number, +) => { + // Avoid invalid fitWidth. + const width = fitWidth || 0; + + if (width <= 0) { + context.fillText(text, x, y); + return; + } + + for (let idx = 1; idx <= text.length; idx++) { + const str = text.substring(0, idx); + if (getStringWidth(str, fontSize) > width) { + context.fillText(text.substring(0, idx - 1), x, y); + printAt(context, text.substring(idx - 1), x, y + lineHeight, lineHeight, width, fontSize); + return; + } + } + context.fillText(text, x, y); +}; + +// Modified snippet from https://stackoverflow.com/questions/21961839/simulation-background-size-cover-in-canvas +const drawImageProp = ( + ctx: SKRSContext2D, + img: Image, + x: number, + y: number, + w: number, + h: number, + offsetX: number, + offsetY: number, +) => { + // keep bounds [0.0, 1.0] + let ox = offsetX; + if (offsetX < 0) ox = 0; + if (offsetX > 1) ox = 1; + let oy = offsetY; + if (offsetY < 0) oy = 0; + if (offsetY > 1) oy = 1; + + const iw = img.width; + const ih = img.height; + const r = Math.min(w / iw, h / ih); + + // new prop.width + let nw = iw * r; + // new prop.height + let nh = ih * r; + let ar = 1; + + // decide which gap to fill + if (nw < w) ar = w / nw; + if (Math.abs(ar - 1) < 1e-14 && nh < h) ar = h / nh; // updated + nw *= ar; + nh *= ar; + + // calc source rectangle + let cw = iw / (nw / w); + let ch = ih / (nh / h); + + let cx = (iw - cw) * ox; + let cy = (ih - ch) * oy; + + // make sure source rectangle is valid + if (cx < 0) cx = 0; + if (cy < 0) cy = 0; + if (cw > iw) cw = iw; + if (ch > ih) ch = ih; + + // fill image in dest. rectangle + ctx.drawImage(img, cx, cy, cw, ch, x, y, w, h); +}; + +const fetchCover = async (cover: string): Promise<Buffer> => { + if (cover.startsWith('http')) { + return Buffer.from(await (await fetch(cover)).arrayBuffer()); + } + + const coverPath = join(process.cwd(), 'public', cover); + return await readFile(coverPath); +}; + +export { default as defaultOpenGraph } from '../asserts/og/open-graph.png?arraybuffer'; + +export interface OpenGraphProps { + title: string; + summary: string; + cover: string; +} + +export const drawOpenGraph = async ({ title, summary, cover }: OpenGraphProps) => { + // Register the font if it doesn't exist + if (!GlobalFonts.has('NotoSansSC-Bold')) { + const fontBuffer = Buffer.from(font); + GlobalFonts.register(fontBuffer, 'NotoSansSC-Bold'); + } + + // Fetch the cover image as the background + const coverImage = new Image(); + coverImage.src = await fetchCover(cover); + + // Generate the logo image + const logoImage = new Image(); + logoImage.src = Buffer.from(logoDark); + + // Mark sure the summary length is small enough to fit in + const description = `${summary + .replace(/<[^>]+>/g, '') + .slice(0, 80) + .trim()} ...`; + + // Start drawing the open graph + const canvas = new Canvas(openGraphWidth, openGraphHeight); + const ctx = canvas.getContext('2d'); + drawImageProp(ctx, coverImage, 0, 0, openGraphWidth, openGraphHeight, 0.5, 0.5); + ctx.fillStyle = 'rgba(0,0,0,0.6)'; + ctx.fillRect(0, 0, openGraphWidth, openGraphHeight); + ctx.save(); + + // Add website title + ctx.fillStyle = '#e0c2bb'; + ctx.font = '800 64px NotoSansSC-Bold'; + printAt(ctx, options.title, 96, 180, 96, openGraphWidth, 64); + + // Add website logo + ctx.drawImage(logoImage, 940, 120, 160, 160); + + // Add article title + ctx.fillStyle = '#fff'; + ctx.font = '800 48px NotoSansSC-Bold'; + printAt(ctx, title, 96, openGraphHeight / 2 - 64, 96, openGraphWidth - 192, 64); + + // Add article summary + ctx.font = '800 36px NotoSansSC-Bold'; + ctx.fillStyle = 'rgba(255,255,255,0.5)'; + printAt(ctx, description, 96, openGraphHeight - 200, 48, openGraphWidth - 192, 36); + + ctx.restore(); + + return await canvas.encode('png'); +}; diff --git a/src/helpers/schema.ts b/src/helpers/schema.ts new file mode 100644 index 0000000..e901186 --- /dev/null +++ b/src/helpers/schema.ts @@ -0,0 +1,148 @@ +import { defaultCover } from '@/content/config.ts'; +import { getCollection, getEntryBySlug, type Render } from 'astro:content'; + +// Import the collections from the astro content. +const categoriesCollection = await getCollection('categories'); +const friendsCollection = await getCollection('friends'); +const optionsCollection = await getCollection('options'); +const pagesCollection = await getCollection('pages'); +const postsCollection = await getCollection('posts'); +const tagsCollection = await getCollection('tags'); + +// Redefine the types from the astro content. +export type Category = (typeof categoriesCollection)[number]['data'] & { counts: number; permalink: string }; +export type Friend = (typeof friendsCollection)[number]['data'][number]; +export type Options = (typeof optionsCollection)[number]['data']; +export type Page = (typeof pagesCollection)[number]['data'] & { + slug: string; + permalink: string; + render: () => Render['.mdx']; +}; +export type Post = (typeof postsCollection)[number]['data'] & { + slug: string; + permalink: string; + render: () => Render['.mdx']; + raw: () => Promise<string>; +}; +export type Tag = (typeof tagsCollection)[number]['data'][number] & { counts: number; permalink: string }; + +// Translate the Astro content into the original content for dealing with different configuration types. +export const friends: Friend[] = friendsCollection[0].data; +export const options: Options = optionsCollection[0].data; +// Override the website for local debugging +export const pages: Page[] = pagesCollection + .filter((page) => page.data.published || !import.meta.env.PROD) + .map((page) => ({ + slug: page.slug, + permalink: `/${page.slug}`, + render: async () => { + const entry = await getEntryBySlug('pages', page.slug); + return entry.render(); + }, + ...page.data, + })); +export const posts: Post[] = postsCollection + .filter((post) => post.data.published || !import.meta.env.PROD) + .map((post) => ({ + slug: post.slug, + permalink: `/posts/${post.slug}`, + render: async () => { + const entry = await getEntryBySlug('posts', post.slug); + return entry.render(); + }, + raw: async () => { + const entry = await getEntryBySlug('posts', post.slug); + return entry.body; + }, + ...post.data, + })) + .sort((left: Post, right: Post) => { + const a = left.date.getTime(); + const b = right.date.getTime(); + return options.settings.post.sort === 'asc' ? a - b : b - a; + }); +export const categories: Category[] = categoriesCollection.map((cat) => ({ + counts: posts.filter((post) => post.category === cat.data.name).length, + permalink: `/cats/${cat.data.slug}`, + ...cat.data, +})); +export const tags: Tag[] = tagsCollection[0].data.map((tag) => ({ + counts: posts.filter((post) => post.tags.includes(tag.name)).length, + permalink: `/tags/${tag.slug}`, + ...tag, +})); + +// Find the missing categories from posts. +const missingCategories: string[] = posts + .map((post) => post.category) + .filter((c) => !categories.find((cat) => cat.name === c)); +if (missingCategories.length > 0) { + throw new Error(`The bellowing categories has not been configured:\n$${missingCategories.join('\n')}`); +} + +// Find the missing tags from posts. +const missingTags: string[] = posts.flatMap((post) => post.tags).filter((tag) => !tags.find((t) => t.name === tag)); +if (missingTags.length > 0) { + throw new Error(`The bellowing tags has not been configured:\n$${missingTags.join('\n')}`); +} + +// Find the missing covers from posts. +const missingCovers = posts + .filter((post) => post.cover.src === defaultCover) + .map((post) => ({ title: post.title, slug: post.slug })); +if (!import.meta.env.PROD && missingCovers.length > 0) { + // We only warn here for this is a known improvement. + console.warn(`The following ${missingCovers.length} posts don't have a cover.`); + console.warn(missingCovers); +} + +// Validate the posts and pages' slug. They should be unique globally. +const postsSlugs = new Set<string>(); +for (const post of posts) { + if (postsSlugs.has(post.slug)) { + throw new Error(`Duplicate post slug: ${post.slug}`); + } + postsSlugs.add(post.slug); +} +for (const page of pages) { + if (postsSlugs.has(page.slug)) { + throw new Error(`Page and post share same slug: ${page.slug}`); + } +} + +// Validate feature posts option. +const featurePosts: string[] = options.settings.post.feature ?? []; +const invalidFeaturePosts = featurePosts.filter((slug) => !postsSlugs.has(slug)); +if (invalidFeaturePosts.length > 0) { + throw new Error(`The bellowing feature posts are invalid:\n$${invalidFeaturePosts.join('\n')}`); +} + +// Validate pinned categories. +const pinnedCategories: string[] = options.settings.post.category ?? []; +const invalidPinnedCategories = pinnedCategories.filter((c) => categories.find((e) => e.name === c)); +if (invalidPinnedCategories.length > 0) { + throw new Error(`The bellowing pinned categories are invalid:\n$${invalidPinnedCategories.join('\n')}`); +} + +// Validate the options with the Astro configuration. +if (import.meta.env.PROD && import.meta.env.SITE !== options.website) { + throw new Error( + `Invalid configuration in options.website: ${options.website} with astro site: ${import.meta.env.SITE}`, + ); +} + +export const getPost = (slug: string): Post | undefined => { + return posts.find((post) => post.slug === slug); +}; + +export const getPage = (slug: string): Page | undefined => { + return pages.find((page) => page.slug === slug); +}; + +export const getCategory = (name?: string, slug?: string): Category | undefined => { + return categories.find((c) => c.name === name || c.slug === slug); +}; + +export const getTag = (name?: string, slug?: string): Tag | undefined => { + return tags.find((tag) => tag.name === name || tag.slug === slug); +}; diff --git a/src/helpers/search.ts b/src/helpers/search.ts new file mode 100644 index 0000000..0db3c2b --- /dev/null +++ b/src/helpers/search.ts @@ -0,0 +1,22 @@ +import { posts } from '@/helpers/schema'; +import Fuse from 'fuse.js'; + +interface PostItem { + title: string; + slug: string; + raw: string; + tags: string[]; +} + +const allPosts = await Promise.all( + posts.map(async (post) => ({ + title: post.title, + slug: post.slug, + raw: await post.raw(), + tags: post.tags, + })), +); +const indexes = Fuse.createIndex<PostItem>(['title', 'raw', 'tags'], allPosts); +const search = new Fuse<PostItem>(allPosts, { includeScore: true, keys: ['title', 'raw', 'tags'] }, indexes); + +export const searchPosts = (query: string): string[] => search.search<PostItem>(query).map((post) => post.item.slug); diff --git a/src/helpers/seo.ts b/src/helpers/seo.ts new file mode 100644 index 0000000..621f0d8 --- /dev/null +++ b/src/helpers/seo.ts @@ -0,0 +1,163 @@ +// This file is copied from https://github.com/flexdinesh/blogster/blob/main/packages/shared/src/seo.ts +// I just modified it for my personal needs. + +type PageOgMeta = { + title: string; + description?: string; + type: 'website'; + url?: string; + image?: string; + imageAlt?: string; + imageWidth?: string; + imageHeight?: string; +}; + +type PageTwitterMeta = { + title: string; + description?: string; + card: 'summary_large_image'; + site?: string; + creator?: string; + image?: string; + imageAlt?: string; +}; + +type PostOgMeta = { + title: string; + description?: string; + type: 'article'; + url?: string; + author?: string; + siteName?: string; + publishDate: string; + image?: string; + imageAlt?: string; + imageWidth?: string; + imageHeight?: string; +}; + +type PostTwitterMeta = { + title: string; + description?: string; + card: 'summary_large_image'; + site?: string; + creator?: string; + image?: string; + imageAlt?: string; +}; + +export function getPageMeta({ + title: pageTitle, + description, + baseUrl, + ogImageAbsoluteUrl, + ogImageAltText, + ogImageWidth, + ogImageHeight, + siteOwnerTwitterHandle, + contentAuthorTwitterHandle, +}: { + title: string; + description: string; + baseUrl?: string; + ogImageAbsoluteUrl?: string; // should always be absolute + ogImageAltText?: string; + ogImageWidth?: number; + ogImageHeight?: number; + siteOwnerTwitterHandle?: string; + contentAuthorTwitterHandle?: string; +}): { og: PageOgMeta; twitter: PageTwitterMeta } { + if (!pageTitle) { + throw Error('title is required for page SEO'); + } + if (ogImageAbsoluteUrl) { + ogImageAltText = !ogImageAltText ? `Preview image for ${pageTitle}` : ogImageAltText; + } + + const og: PageOgMeta = { + title: pageTitle, + description: description, + type: 'website', + url: baseUrl, + image: ogImageAbsoluteUrl, + imageAlt: ogImageAltText, + imageWidth: ogImageWidth ? String(ogImageWidth) : undefined, + imageHeight: ogImageHeight ? String(ogImageHeight) : undefined, + }; + + const twitter: PageTwitterMeta = { + title: pageTitle, + description: description, + card: 'summary_large_image', + site: siteOwnerTwitterHandle, + creator: contentAuthorTwitterHandle || siteOwnerTwitterHandle, + image: ogImageAbsoluteUrl, + imageAlt: ogImageAltText, + }; + + return { + og, + twitter, + }; +} + +export function getBlogPostMeta({ + title: pageTitle, + description, + pageUrl, + authorName, + publishDate, + ogImageAbsoluteUrl, + ogImageAltText, + ogImageWidth, + ogImageHeight, + siteOwnerTwitterHandle, + contentAuthorTwitterHandle, +}: { + title: string; + description: string; + pageUrl?: string; + authorName?: string; + publishDate: string; + ogImageAbsoluteUrl?: string; // should always be absolute + ogImageAltText?: string; + ogImageWidth?: number; + ogImageHeight?: number; + siteOwnerTwitterHandle?: string; + contentAuthorTwitterHandle?: string; +}): { og: PostOgMeta; twitter: PostTwitterMeta } { + if (!pageTitle) { + throw Error('title is required for page SEO'); + } + if (ogImageAbsoluteUrl && !ogImageAltText) { + ogImageAltText = `Preview image for ${pageTitle}`; + } + + const og: PostOgMeta = { + title: pageTitle, + description: description, + type: 'article', + url: pageUrl, + author: authorName, + publishDate: publishDate, + image: ogImageAbsoluteUrl, + imageAlt: ogImageAltText, + imageWidth: ogImageWidth ? String(ogImageWidth) : undefined, + imageHeight: ogImageHeight ? String(ogImageHeight) : undefined, + }; + + const twitter: PostTwitterMeta = { + title: pageTitle, + description: description, + card: 'summary_large_image', + site: siteOwnerTwitterHandle, + creator: contentAuthorTwitterHandle || siteOwnerTwitterHandle, + image: ogImageAbsoluteUrl, + imageAlt: ogImageAltText, + }; + + return { + og, + twitter, + }; +} diff --git a/src/helpers/tools.ts b/src/helpers/tools.ts new file mode 100644 index 0000000..b69cc84 --- /dev/null +++ b/src/helpers/tools.ts @@ -0,0 +1,19 @@ +export const makeToken = ( + length: number, + characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789', +) => { + let result = ''; + const charactersLength = characters.length; + let counter = 0; + while (counter < length) { + result += characters.charAt(Math.floor(Math.random() * charactersLength)); + counter += 1; + } + return result; +}; + +export const urlJoin = (base: string, ...paths: string[]): string => { + return Array.from([base, ...paths]) + .reduce((left, right) => left + (left.endsWith('/') || right.startsWith('/') ? '' : '/') + right) + .replace(/([^:]\/)\/+/g, '$1'); +}; diff --git a/src/layouts/BaseLayout.astro b/src/layouts/BaseLayout.astro new file mode 100644 index 0000000..1dee01b --- /dev/null +++ b/src/layouts/BaseLayout.astro @@ -0,0 +1,63 @@ +--- +// tslint:disable:ordered-imports +import 'bootstrap/dist/css/bootstrap.min.css'; +import '@/asserts/styles/opposans/opposans.css'; +import '@/asserts/styles/iconfont/iconfont.css'; +import '@/asserts/styles/reset.css'; +import '@/asserts/styles/globals.css'; + +import Footer from '@/components/footer/Footer.astro'; +import GoTop from '@/components/footer/GoTop.astro'; +import Header from '@/components/header/Header.astro'; +import PageMeta from '@/components/meta/PageMeta.astro'; +import { options } from '@/helpers/schema'; + +interface Props { + title?: string; + description?: string; +} + +const title = + Astro.props.title === undefined + ? `${options.title} - ${options.description}` + : `${Astro.props.title} - ${options.title}`; +const description = Astro.props.description || options.description; +--- + +<!doctype html> +<html lang="zh-CN"> + <head> + <meta charset="UTF-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <title>{title}</title> + <meta name="title" content={title} /> + <meta name="description" content={description} /> + <meta name="generator" content={Astro.generator} /> + <meta name="author" content={options.author.name} /> + <link rel="author" href={options.author.url} /> + <meta name="keywords" content={options.keywords.join(',')} /> + <slot name="og"> + <PageMeta {title} {description} /> + </slot> + <meta name="robots" content="index, follow" /> + <meta name="googlebot" content="index, follow, max-video-preview:-1, max-image-preview:large, max-snippet:-1" /> + <link rel="alternate" type="application/rss+xml" title="且听书吟" href="/feed" /> + <link rel="icon" href="/favicon.ico" sizes="32x32" /> + <link rel="icon" href="/favicon.svg" type="image/svg+xml" /> + <link rel="apple-touch-icon" href="/apple-touch-icon.png" /> + <link rel="manifest" href="/manifest.webmanifest" /> + </head> + <body class="home blog"> + <div class="site-layout"> + <Header /> + <main class="site-main"> + <slot /> + <Footer /> + </main> + <GoTop /> + </div> + <script> + import '../asserts/scripts/yufan.me.js'; + </script> + </body> +</html> diff --git a/src/layouts/PageLayout.astro b/src/layouts/PageLayout.astro new file mode 100644 index 0000000..4dde6f9 --- /dev/null +++ b/src/layouts/PageLayout.astro @@ -0,0 +1,40 @@ +--- +import ArtalkComment from '@/components/comment/Artalk.astro'; +import Image from '@/components/image/Image.astro'; +import PageMeta from '@/components/meta/PageMeta.astro'; +import FriendLinks from '@/components/page/friend/FriendLinks.astro'; +import MusicPlayer from '@/components/player/MusicPlayer.astro'; +import { options, type Page } from '@/helpers/schema'; +import { urlJoin } from '@/helpers/tools'; +import BaseLayout from '@/layouts/BaseLayout.astro'; + +interface Props { + page: Page; +} + +const { page } = Astro.props; +const { Content } = await page.render(); +--- + +<BaseLayout title={page.title}> + <PageMeta slot="og" title={page.title} ogImageUrl={urlJoin(import.meta.env.SITE, `/og/${page.slug}.png`)} /> + + <div class="px-lg-2 px-xxl-5 py-3 py-md-4 py-xxl-5"> + <div class="container"> + <div class="post"> + <h1 class="post-title mb-3 mb-xl-4">{page.title}</h1> + <div class="post-content"> + <div class="nc-light-gallery"> + <Content components={{ MusicPlayer: MusicPlayer, Image: Image }} /> + </div> + </div> + {page.friend && <FriendLinks />} + { + page.comments && ( + <ArtalkComment commentKey={urlJoin(options.website, page.permalink, '/')} title={page.title} /> + ) + } + </div> + </div> + </div> +</BaseLayout> diff --git a/src/layouts/PostLayout.astro b/src/layouts/PostLayout.astro new file mode 100644 index 0000000..09cadb2 --- /dev/null +++ b/src/layouts/PostLayout.astro @@ -0,0 +1,64 @@ +--- +import ArtalkComment from '@/components/comment/Artalk.astro'; +import Image from '@/components/image/Image.astro'; +import LikeButton from '@/components/like/LikeButton.astro'; +import Share from '@/components/like/Share.astro'; +import PostMeta from '@/components/meta/PostMeta.astro'; +import MusicPlayer from '@/components/player/MusicPlayer.astro'; +import Sidebar from '@/components/sidebar/Sidebar.astro'; +import { formatShowDate } from '@/helpers/formatter'; +import { options, posts, tags, type Post } from '@/helpers/schema'; +import { urlJoin } from '@/helpers/tools'; +import BaseLayout from '@/layouts/BaseLayout.astro'; + +interface Props { + post: Post; +} + +const { post } = Astro.props; +const { Content } = await post.render(); +--- + +<BaseLayout title={post.title}> + <PostMeta + slot="og" + title={post.title} + description={post.summary} + publishDate={post.date.toISOString()} + requestPath={post.permalink} + ogImageUrl={urlJoin(import.meta.env.SITE, `/og/${post.slug}.png`)} + ogImageAltText={post.title} + /> + <div class="px-lg-2 px-xxl-5 py-3 py-md-4 py-xxl-5"> + <div class="container"> + <div class="row"> + <div class="content-wrapper col-12 col-xl-9"> + <div class="post card card-md"> + <div class="card-body"> + <h1 class="post-title">{post.title}</h1> + <div class="post-meta text-sm text-muted mt-3 mb-4"> + <time>{formatShowDate(post.date)}</time> + </div> + <div class="post-content"> + <div class="nc-light-gallery"> + <Content components={{ MusicPlayer: MusicPlayer, Image: Image }} /> + </div> + <nav class="post-in-navigation navigation pagination font-number" role="navigation"> + <div class="nav-links"></div> + </nav> + </div> + <LikeButton {post} /> + <Share {post} /> + { + post.comments && ( + <ArtalkComment commentKey={urlJoin(options.website, post.permalink, '/')} title={post.title} /> + ) + } + </div> + </div> + </div> + <Sidebar {posts} {tags} /> + </div> + </div> + </div> +</BaseLayout> diff --git a/src/layouts/posts/CategoryLayout.astro b/src/layouts/posts/CategoryLayout.astro new file mode 100644 index 0000000..e9e544c --- /dev/null +++ b/src/layouts/posts/CategoryLayout.astro @@ -0,0 +1,38 @@ +--- +import Pagination from '@/components/page/pagination/Pagination.astro'; +import PostSquare from '@/components/page/post/PostSquare.astro'; +import { slicePosts } from '@/helpers/formatter'; +import { options, type Category, type Post } from '@/helpers/schema'; +import BaseLayout from '@/layouts/BaseLayout.astro'; + +interface Props { + category: Category; + posts: Post[]; + pageNum: number; +} + +const { category, posts, pageNum } = Astro.props; +const results = slicePosts(posts, pageNum, options.settings.pagination.category); +if (!results) { + return Astro.redirect('/404'); +} + +const { currentPosts, totalPage } = results; +--- + +<BaseLayout title={category.name}> + <div class="px-lg-2 px-xxl-5 py-3 py-md-4 py-xxl-5"> + <div class="container"> + <div class="mb-3 mb-lg-4"> + <h1>{category.name}</h1> + <div class="text-muted mt-1">{category.description}</div> + </div> + <div class="row g-2 g-md-3 g-xxl-4 list-grouped"> + {currentPosts.map((post, index) => <PostSquare post={post} first={index === 0} />)} + </div> + <div class="mt-4 mt-lg-5"> + <Pagination current={pageNum} total={totalPage} rootPath={category.permalink} /> + </div> + </div> + </div> +</BaseLayout> diff --git a/src/layouts/posts/PostsLayout.astro b/src/layouts/posts/PostsLayout.astro new file mode 100644 index 0000000..b5c3cce --- /dev/null +++ b/src/layouts/posts/PostsLayout.astro @@ -0,0 +1,37 @@ +--- +import PinnedCategories from '@/components/page/category/PinnedCategories.astro'; +import FeaturePosts from '@/components/page/post/FeaturePosts.astro'; +import PostPagination from '@/components/page/post/PostPagination.astro'; +import Sidebar from '@/components/sidebar/Sidebar.astro'; +import type { Post, Tag } from '@/helpers/schema'; + +import BaseLayout from '../BaseLayout.astro'; + +interface Props { + posts: Post[]; + pageNum: number; + tags: Tag[]; +} + +const { posts, pageNum, tags } = Astro.props; + +// Redirect to the homepage. +if (pageNum < 1) { + return Astro.redirect('/'); +} +--- + +<!-- This is the layout for listing all the blogs by using pagination. --> +<BaseLayout title={pageNum > 1 ? `第 ${pageNum} 页` : undefined}> + <div class="px-lg-2 px-xxl-5 py-3 py-md-4 py-xxl-5"> + <FeaturePosts {posts} /> + <div class="container"> + <div class="row"> + <PostPagination {pageNum} {posts} /> + <Sidebar {posts} {tags} /> + </div> + <PinnedCategories /> + </div> + </div> + <slot /> +</BaseLayout> diff --git a/src/layouts/posts/SearchLayout.astro b/src/layouts/posts/SearchLayout.astro new file mode 100644 index 0000000..91d5fa2 --- /dev/null +++ b/src/layouts/posts/SearchLayout.astro @@ -0,0 +1,39 @@ +--- +import PostSquare from '@/components/page/post/PostSquare.astro'; +import type { Post } from '@/helpers/schema'; +import BaseLayout from '@/layouts/BaseLayout.astro'; + +interface Props { + title: string; + posts: Post[]; +} + +const { title, posts } = Astro.props; +--- + +<BaseLayout {title}> + <div class="px-lg-2 px-xxl-5 py-3 py-md-4 py-xxl-5"> + <div class="container"> + <div class="mb-3 mb-lg-4"> + <h1>{title}</h1> + </div> + { + posts.length === 0 ? ( + <div class="data-null"> + <div class="my-auto"> + <i class="svg-404" /> + <h1 class="font-number">404</h1> + <div>抱歉,没有你要找的内容...</div> + </div> + </div> + ) : ( + <div class="row g-2 g-md-3 g-xxl-4 list-grouped"> + {posts.map((post, index) => ( + <PostSquare post={post} first={index === 0} /> + ))} + </div> + ) + } + </div> + </div> +</BaseLayout> diff --git a/src/layouts/posts/TagLayout.astro b/src/layouts/posts/TagLayout.astro new file mode 100644 index 0000000..460af55 --- /dev/null +++ b/src/layouts/posts/TagLayout.astro @@ -0,0 +1,35 @@ +--- +import Pagination from '@/components/page/pagination/Pagination.astro'; +import PostSquare from '@/components/page/post/PostSquare.astro'; +import { slicePosts } from '@/helpers/formatter'; +import { options, type Post, type Tag } from '@/helpers/schema'; +import BaseLayout from '@/layouts/BaseLayout.astro'; + +interface Props { + tag: Tag; + posts: Post[]; + pageNum: number; +} + +const { tag, posts, pageNum } = Astro.props; +const results = slicePosts(posts, pageNum, options.settings.pagination.tags); +if (!results) { + return Astro.redirect('/404'); +} + +const { currentPosts, totalPage } = results; +--- + +<BaseLayout title={`标签 “${tag.name}”`}> + <div class="container"> + <div class="mb-3 mb-lg-4"> + <h1>{tag.name}</h1> + </div> + <div class="row g-2 g-md-3 g-xxl-4 list-grouped"> + {currentPosts.map((post, index) => <PostSquare post={post} first={index === 0} />)} + </div> + <div class="mt-4 mt-lg-5"> + <Pagination current={pageNum} total={totalPage} rootPath={tag.permalink} /> + </div> + </div> +</BaseLayout> diff --git a/src/middleware.ts b/src/middleware.ts new file mode 100644 index 0000000..49e82e0 --- /dev/null +++ b/src/middleware.ts @@ -0,0 +1,16 @@ +import { posts } from '@/helpers/schema'; +import { urlJoin } from '@/helpers/tools'; +import { defineMiddleware } from 'astro:middleware'; + +const mappings = new Map<string, string>(posts.map((post) => [urlJoin('/', post.slug), post.permalink])); + +export const onRequest = defineMiddleware(({ request: { method }, url: { pathname }, redirect }, next) => { + // This is used for redirect my old blog posts to a new mapping. + const newTarget = mappings.get(pathname); + if (method === 'GET' && newTarget !== undefined) { + return redirect(newTarget, 301); + } + + // return a Response or the result of calling `next()` + return next(); +}); diff --git a/src/pages/404.astro b/src/pages/404.astro new file mode 100644 index 0000000..d21abb7 --- /dev/null +++ b/src/pages/404.astro @@ -0,0 +1,13 @@ +--- +import BaseLayout from '@/layouts/BaseLayout.astro'; +--- + +<BaseLayout title="未找到页面"> + <div class="data-null"> + <div class="my-auto"> + <i class="svg-404"></i> + <h1 class="font-number">404</h1> + <div>抱歉,没有你要找的内容...</div> + </div> + </div> +</BaseLayout> diff --git a/src/pages/500.astro b/src/pages/500.astro new file mode 100644 index 0000000..314f4b5 --- /dev/null +++ b/src/pages/500.astro @@ -0,0 +1,12 @@ +--- +import BaseLayout from '@/layouts/BaseLayout.astro'; +--- + +<BaseLayout title="内部错误"> + <div class="data-null"> + <div class="my-auto"> + <h1 class="font-number">❌500</h1> + <div>抱歉,网站系统出现内部错误。请刷新页面重试,或者返回上一页。</div> + </div> + </div> +</BaseLayout> diff --git a/src/pages/[slug].astro b/src/pages/[slug].astro new file mode 100644 index 0000000..5124110 --- /dev/null +++ b/src/pages/[slug].astro @@ -0,0 +1,16 @@ +--- +import { getPage } from '@/helpers/schema'; +import PageLayout from '@/layouts/PageLayout.astro'; + +const { slug } = Astro.params; +if (!slug) { + return Astro.redirect('/404'); +} + +const page = getPage(slug); +if (!page) { + return Astro.redirect('/404'); +} +--- + +<PageLayout {page} /> diff --git a/src/pages/cats/[slug]/index.astro b/src/pages/cats/[slug]/index.astro new file mode 100644 index 0000000..3fa2d97 --- /dev/null +++ b/src/pages/cats/[slug]/index.astro @@ -0,0 +1,20 @@ +--- +import { getCategory, posts, type Category, type Post } from '@/helpers/schema'; +import CategoryLayout from '@/layouts/posts/CategoryLayout.astro'; + +interface Props { + category: Category; + posts: Post[]; +} + +const { slug } = Astro.params; +const category = getCategory(undefined, slug); + +if (!category) { + return Astro.redirect('/404'); +} + +const filteredPosts = posts.filter((post) => post.category === category.name); +--- + +<CategoryLayout posts={filteredPosts} {category} pageNum={1} /> diff --git a/src/pages/cats/[slug]/page/[num].astro b/src/pages/cats/[slug]/page/[num].astro new file mode 100644 index 0000000..58be7f8 --- /dev/null +++ b/src/pages/cats/[slug]/page/[num].astro @@ -0,0 +1,26 @@ +--- +import { getCategory, options, posts } from '@/helpers/schema'; +import CategoryLayout from '@/layouts/posts/CategoryLayout.astro'; + +const { slug, num } = Astro.params; +const category = getCategory(undefined, slug); + +if (!category || !num) { + return Astro.redirect('/404'); +} + +const pageNum = Number.parseInt(num); +if (pageNum <= 1) { + return Astro.redirect(category.permalink); +} + +const filteredPosts = posts.filter((post) => post.category === category.name); +const pageSize = options.settings.pagination.category; +const total = Math.ceil(filteredPosts.length / pageSize); + +if (pageNum > total) { + return Astro.redirect('/404'); +} +--- + +<CategoryLayout posts={filteredPosts} {category} {pageNum} /> diff --git a/src/pages/cats/[slug]/page/index.astro b/src/pages/cats/[slug]/page/index.astro new file mode 100644 index 0000000..f48d767 --- /dev/null +++ b/src/pages/cats/[slug]/page/index.astro @@ -0,0 +1,3 @@ +--- +return Astro.redirect('/'); +--- diff --git a/src/pages/cats/index.astro b/src/pages/cats/index.astro new file mode 100644 index 0000000..f48d767 --- /dev/null +++ b/src/pages/cats/index.astro @@ -0,0 +1,3 @@ +--- +return Astro.redirect('/'); +--- diff --git a/src/pages/feed.ts b/src/pages/feed.ts new file mode 100644 index 0000000..279b2bf --- /dev/null +++ b/src/pages/feed.ts @@ -0,0 +1,119 @@ +import PostContent from '@/components/page/post/PostContent.astro'; +import { options, posts, type Post } from '@/helpers/schema'; +import { urlJoin } from '@/helpers/tools'; +import { getContainerRenderer } from '@astrojs/mdx'; +import rss from '@astrojs/rss'; +import type { AstroRenderer, SSRLoadedRenderer } from 'astro'; +import { experimental_AstroContainer as AstroContainer } from 'astro/container'; +import { ELEMENT_NODE, TEXT_NODE, transform, walk, type TextNode } from 'ultrahtml'; +import sanitize from 'ultrahtml/transformers/sanitize'; + +const cleanupContent = async (html: string) => { + const content = html.startsWith('<!DOCTYPE html>') ? html.slice(15) : html; + + return await transform(content, [ + async (node) => { + await walk(node, (node) => { + if (node.type === ELEMENT_NODE) { + // Make sure images are absolute, some readers are not smart enough to figure it out + if (node.name === 'img' && node.attributes.src?.startsWith('/')) { + node.attributes.src = urlJoin(import.meta.env.SITE, node.attributes.src); + } + + // Make sure links are absolute, some readers are not smart enough to figure it out + if (node.name === 'a' && node.attributes.href?.startsWith('/')) { + node.attributes.href = urlJoin(import.meta.env.SITE, node.attributes.href); + } + + // Remove favicon images, some readers don't know they should be inline and it ends up being a broken image + if ('data-favicon' in node.attributes || 'data-favicon-span' in node.attributes) { + const favicon = node as unknown as TextNode; + favicon.type = TEXT_NODE; + favicon.value = ''; + } + + // Remove EC buttons + if (node.attributes['data-code']) { + const code = node as unknown as TextNode; + code.type = TEXT_NODE; + code.value = ''; + } + } + }); + + return node; + }, + sanitize({ + dropAttributes: { + class: ['*'], + 'data-astro-source': ['*'], + 'data-astro-source-loc': ['*'], + 'data-astro-source-file': ['*'], + 'data-favicon': ['*'], + 'data-image-component': ['img'], + }, + }), + ]); +}; + +// Copy from astro source code. I don't know why this virtual vite module didn't works. +export async function loadRenderers(renderers: AstroRenderer[]) { + const loadedRenderers = await Promise.all( + renderers.map(async (renderer) => { + const mod = await import(/* @vite-ignore */ renderer.serverEntrypoint); + if (typeof mod.default !== 'undefined') { + return { + ...renderer, + ssr: mod.default, + } as SSRLoadedRenderer; + } + return undefined; + }), + ); + + return loadedRenderers.filter((r): r is SSRLoadedRenderer => Boolean(r)); +} + +const renderPostsContent = async (feedPosts: Post[]): Promise<Map<string, string>> => { + const contents = new Map<string, string>(); + + if (options.settings.feed.full) { + const renderers = await loadRenderers([getContainerRenderer()]); + const container = await AstroContainer.create({ renderers: renderers }); + const promises = feedPosts.map(async (post) => ({ + key: post.slug, + value: await container.renderToString(PostContent, { + params: { + slug: post.slug, + }, + }), + })); + + for (const { key, value } of await Promise.all(promises)) { + contents.set(key, await cleanupContent(value)); + } + } + + return contents; +}; + +export const GET = async () => { + const feedPosts = posts.length < options.settings.feed.size ? posts : posts.slice(0, options.settings.feed.size); + const contents = await renderPostsContent(feedPosts); + + return rss({ + title: options.title, + description: options.description, + stylesheet: '/feed.xsl', + site: import.meta.env.SITE, + items: feedPosts.map((post) => ({ + link: urlJoin(import.meta.env.SITE, post.permalink), + title: post.title, + pubDate: post.date, + description: post.summary, + author: options.author.name, + content: contents.get(post.slug) ?? post.summary, + categories: [post.category, ...post.tags], + })), + }); +}; diff --git a/src/pages/index.astro b/src/pages/index.astro new file mode 100644 index 0000000..19ce9f9 --- /dev/null +++ b/src/pages/index.astro @@ -0,0 +1,6 @@ +--- +import { posts, tags } from '@/helpers/schema'; +import PostsLayout from '@/layouts/posts/PostsLayout.astro'; +--- + +<PostsLayout pageNum={1} {posts} {tags} /> diff --git a/src/pages/og/[slug].png.ts b/src/pages/og/[slug].png.ts new file mode 100644 index 0000000..40f04d2 --- /dev/null +++ b/src/pages/og/[slug].png.ts @@ -0,0 +1,53 @@ +import { defaultOpenGraph, drawOpenGraph } from '@/helpers/og'; +import { getPage, getPost, pages, posts } from '@/helpers/schema'; +import type { APIRoute } from 'astro'; + +const fallback = () => + new Response(defaultOpenGraph, { + headers: { 'Content-Type': 'image/png' }, + }); + +export const prerender = true; + +export const GET: APIRoute = async ({ params }) => { + const slug = params.slug; + if (!slug) { + return fallback(); + } + + let title: string; + let summary: string; + let cover: string; + + // Query the post + const post = getPost(slug); + if (!post) { + // Fallback to query from pages + const page = getPage(slug); + if (!page) { + return fallback(); + } + + title = page.title; + summary = ''; + cover = page.cover.src; + } else { + title = post.title; + summary = post.summary; + cover = post.cover.src; + } + + // Fetch the cover image as the background + const buffer = await drawOpenGraph({ title, summary, cover }); + + return new Response(buffer, { + headers: { 'Content-Type': 'image/png' }, + }); +}; + +export async function getStaticPaths() { + return [ + ...posts.map((post) => ({ params: { slug: post.slug } })), + ...pages.map((page) => ({ params: { slug: page.slug } })), + ]; +} diff --git a/src/pages/page/[num].astro b/src/pages/page/[num].astro new file mode 100644 index 0000000..5bc8d25 --- /dev/null +++ b/src/pages/page/[num].astro @@ -0,0 +1,18 @@ +--- +import { posts, tags } from '@/helpers/schema'; +import PostsLayout from '@/layouts/posts/PostsLayout.astro'; + +const { num } = Astro.params; + +if (!num) { + Astro.response.status = 500; + throw new Error('No such page num existed.'); +} + +const pageNum = Number.parseInt(num); +if (pageNum <= 1) { + return Astro.redirect('/'); +} +--- + +<PostsLayout {posts} {pageNum} {tags} /> diff --git a/src/pages/page/index.astro b/src/pages/page/index.astro new file mode 100644 index 0000000..f48d767 --- /dev/null +++ b/src/pages/page/index.astro @@ -0,0 +1,3 @@ +--- +return Astro.redirect('/'); +--- diff --git a/src/pages/posts/[slug]/index.astro b/src/pages/posts/[slug]/index.astro new file mode 100644 index 0000000..c5899bb --- /dev/null +++ b/src/pages/posts/[slug]/index.astro @@ -0,0 +1,16 @@ +--- +import { getPost } from '@/helpers/schema'; +import PostLayout from '@/layouts/PostLayout.astro'; + +const { slug } = Astro.params; +if (!slug) { + return Astro.redirect('/404'); +} + +const post = getPost(slug); +if (!post) { + return Astro.redirect('/404'); +} +--- + +<PostLayout {post} /> diff --git a/src/pages/posts/[slug]/likes.ts b/src/pages/posts/[slug]/likes.ts new file mode 100644 index 0000000..6ea3c86 --- /dev/null +++ b/src/pages/posts/[slug]/likes.ts @@ -0,0 +1,30 @@ +import { decreaseLikes, increaseLikes, queryLikes } from '@/helpers/db/query'; +import type { APIRoute } from 'astro'; + +export const POST: APIRoute = async ({ params, request }) => { + const { slug } = params; + const resp = await request.json(); + + // Increase. + if (resp.action === 'increase') { + if (typeof slug === 'undefined') { + return new Response(JSON.stringify({ likes: 0, token: '' })); + } + + const { likes, token } = await increaseLikes(slug); + return new Response(JSON.stringify({ likes: likes, token: token })); + } + + // Decrease. + if (resp.action === 'decrease' && resp.token !== '') { + if (typeof slug === 'undefined') { + return new Response(JSON.stringify({ likes: 0 })); + } + + await decreaseLikes(slug, resp.token); + const likes = await queryLikes(slug); + return new Response(JSON.stringify({ likes: likes })); + } + + return new Response(JSON.stringify({ likes: 0 })); +}; diff --git a/src/pages/posts/index.astro b/src/pages/posts/index.astro new file mode 100644 index 0000000..f48d767 --- /dev/null +++ b/src/pages/posts/index.astro @@ -0,0 +1,3 @@ +--- +return Astro.redirect('/'); +--- diff --git a/src/pages/search/index.astro b/src/pages/search/index.astro new file mode 100644 index 0000000..3656935 --- /dev/null +++ b/src/pages/search/index.astro @@ -0,0 +1,19 @@ +--- +import { options, posts } from '@/helpers/schema'; +import { searchPosts } from '@/helpers/search'; +import SearchLayout from '@/layouts/posts/SearchLayout.astro'; + +const query = Astro.url.searchParams.get('q') || ''; +if (query === '') { + return Astro.redirect('/'); +} + +const title = `${query} 查询结果`; + +const searchResults = searchPosts(query) + .map((slug) => posts.find((post) => post.slug === slug)) + .flatMap((post) => (post == null ? [] : [post])) + .slice(0, options.settings.pagination.search); +--- + +<SearchLayout {title} posts={searchResults} /> diff --git a/src/pages/sitemap.xml.ts b/src/pages/sitemap.xml.ts new file mode 100644 index 0000000..ad94c2b --- /dev/null +++ b/src/pages/sitemap.xml.ts @@ -0,0 +1,29 @@ +import { pages, posts } from '@/helpers/schema'; +import { urlJoin } from '@/helpers/tools'; + +export const prerender = true; + +export async function GET() { + const result = ` +<?xml version="1.0" encoding="UTF-8"?> +<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> + <url><loc>${import.meta.env.SITE}/</loc></url> + ${posts + .map((post) => { + return `<url><loc>${urlJoin(import.meta.env.SITE, post.permalink)}</loc><lastmod>${post.date.toISOString()}</lastmod></url>`; + }) + .join('\n')} + ${pages + .map((page) => { + return `<url><loc>${urlJoin(import.meta.env.SITE, page.permalink)}</loc><lastmod>${page.date.toISOString()}</lastmod></url>`; + }) + .join('\n')} +</urlset> + `.trim(); + + return new Response(result, { + headers: { + 'Content-Type': 'application/xml', + }, + }); +} diff --git a/src/pages/tags/[slug]/index.astro b/src/pages/tags/[slug]/index.astro new file mode 100644 index 0000000..fba595a --- /dev/null +++ b/src/pages/tags/[slug]/index.astro @@ -0,0 +1,15 @@ +--- +import { getTag, posts } from '@/helpers/schema'; +import TagLayout from '@/layouts/posts/TagLayout.astro'; + +const { slug } = Astro.params; +const tag = getTag(undefined, slug); + +if (!tag) { + return Astro.redirect('/404'); +} + +const filteredPosts = posts.filter((post) => post.tags.includes(tag.name)); +--- + +<TagLayout posts={filteredPosts} {tag} pageNum={1} /> diff --git a/src/pages/tags/[slug]/page/[num].astro b/src/pages/tags/[slug]/page/[num].astro new file mode 100644 index 0000000..9cc89e5 --- /dev/null +++ b/src/pages/tags/[slug]/page/[num].astro @@ -0,0 +1,26 @@ +--- +import { getTag, options, posts } from '@/helpers/schema'; +import TagLayout from '@/layouts/posts/TagLayout.astro'; + +const { slug, num } = Astro.params; +const tag = getTag(undefined, slug); + +if (!tag || !num) { + return Astro.redirect('/404'); +} + +const pageNum = Number.parseInt(num); +if (pageNum <= 1) { + return Astro.redirect(tag.permalink); +} + +const filteredPosts = posts.filter((post) => post.tags.includes(tag.name)); +const pageSize = options.settings.pagination.tags; +const total = Math.ceil(filteredPosts.length / pageSize); + +if (pageNum > total) { + return Astro.redirect('/404'); +} +--- + +<TagLayout posts={filteredPosts} {tag} {pageNum} /> diff --git a/src/pages/tags/[slug]/page/index.astro b/src/pages/tags/[slug]/page/index.astro new file mode 100644 index 0000000..f48d767 --- /dev/null +++ b/src/pages/tags/[slug]/page/index.astro @@ -0,0 +1,3 @@ +--- +return Astro.redirect('/'); +--- diff --git a/src/pages/tags/index.astro b/src/pages/tags/index.astro new file mode 100644 index 0000000..f48d767 --- /dev/null +++ b/src/pages/tags/index.astro @@ -0,0 +1,3 @@ +--- +return Astro.redirect('/'); +--- diff --git a/tools/.gitignore b/tools/.gitignore new file mode 100644 index 0000000..cf33ab3 --- /dev/null +++ b/tools/.gitignore @@ -0,0 +1,2 @@ +# The Golang binary file. +tools diff --git a/tools/Makefile b/tools/Makefile new file mode 100644 index 0000000..5c6162f --- /dev/null +++ b/tools/Makefile @@ -0,0 +1,14 @@ +help: ## Display this help + @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m<target>\033[0m\n\nTargets:\n"} \ + /^[a-zA-Z_-]+:.*?##/ { printf " \033[36m%-10s\033[0m %s\n", $$1, $$2 }' $(MAKEFILE_LIST) + +clean: ## Clean up build files. + rm -rf tools + +deps: ## Update vendor. + go mod verify + go mod tidy -v + go get -u ./... + +build: ## Build executable files + go build -o tools main.go diff --git a/tools/README.md b/tools/README.md new file mode 100644 index 0000000..702f6b7 --- /dev/null +++ b/tools/README.md @@ -0,0 +1,21 @@ +# Blog Tools + +This is a directory for serving the useful tools for my weblog writing. + +## Tools list + +Image process with resize, compress and convert to JPG. + +``` +tools image -h +A tool for processing images to my desired format, size and naming + +Usage: + tools image [flags] + +Flags: + -h, --help help for image + --output string The output path + --source string The image file path (absolute of relative) that you want to process + --width int The compressed width for the given image (default 1280) +``` diff --git a/tools/cmd/image.go b/tools/cmd/image.go new file mode 100644 index 0000000..0f85117 --- /dev/null +++ b/tools/cmd/image.go @@ -0,0 +1,69 @@ +package cmd + +import ( + "fmt" + "github.com/disintegration/imaging" + "github.com/spf13/cobra" + "log" + "os" + "path/filepath" + "regexp" + "time" +) + +// imageCmd represents the image command +var ( + imageCmd = &cobra.Command{ + Use: "image", + Short: "A tool for processing images to my desired format, size and naming", + Run: func(cmd *cobra.Command, args []string) { + if source == "" { + log.Fatalf("The source should be provided") + } + if !localDatePattern.Match([]byte(localDate)) { + log.Fatalf("This is an invalid local date format %s", localDate) + } + + process() + }, + } + + width = 1280 + source = "" + output = executablePath() + localDate = time.Now().Format("20060102") + localDatePattern = regexp.MustCompile("^\\d{8}$") +) + +func init() { + imageCmd.Flags().StringVarP(&source, "source", "", "", "The image file path (absolute of relative) that you want to process") + imageCmd.Flags().StringVarP(&output, "output", "", output, "The output path") + imageCmd.Flags().IntVarP(&width, "width", "", 1280, "The compressed width for the given image") + imageCmd.Flags().StringVarP(&localDate, "local", "", localDate, "The local date time, in yyyyMMdd format") + + rootCmd.AddCommand(imageCmd) +} + +func executablePath() string { + ex, _ := os.Executable() + return filepath.Dir(ex) +} + +func process() { + // Open a test image. + src, err := imaging.Open(source) + if err != nil { + log.Fatalf("failed to open image: %v", err) + } + + // Resize the cropped image to width = 200px preserving the aspect ratio. + src = imaging.Resize(src, width, 0, imaging.Lanczos) + + // Save the resulting image as JPEG. + target := localDate + time.Now().Format("150405") + fmt.Sprintf("%02d", time.Now().Nanosecond()%100) + ".jpg" + + err = imaging.Save(src, filepath.Join(output, target)) + if err != nil { + log.Fatalf("failed to save image: %v", err) + } +} diff --git a/tools/cmd/root.go b/tools/cmd/root.go new file mode 100644 index 0000000..2febe2a --- /dev/null +++ b/tools/cmd/root.go @@ -0,0 +1,23 @@ +package cmd + +import ( + "github.com/spf13/cobra" + "os" +) + +// rootCmd represents the base command when called without any subcommands +var rootCmd = &cobra.Command{ + Use: "tools", + Short: "A set of useful tools for writing in weblog", +} + +func Execute() { + err := rootCmd.Execute() + if err != nil { + os.Exit(1) + } +} + +func init() { + rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") +} diff --git a/tools/go.mod b/tools/go.mod new file mode 100644 index 0000000..b7e240d --- /dev/null +++ b/tools/go.mod @@ -0,0 +1,14 @@ +module tools + +go 1.22 + +require ( + github.com/disintegration/imaging v1.6.2 + github.com/spf13/cobra v1.8.0 +) + +require ( + github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/spf13/pflag v1.0.5 // indirect + golang.org/x/image v0.16.0 // indirect +) diff --git a/tools/go.sum b/tools/go.sum new file mode 100644 index 0000000..e5f0c55 --- /dev/null +++ b/tools/go.sum @@ -0,0 +1,16 @@ +github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c= +github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= +github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.16.0 h1:9kloLAKhUufZhA12l5fwnx2NZW39/we1UhBesW433jw= +golang.org/x/image v0.16.0/go.mod h1:ugSZItdV4nOxyqp56HmXwH0Ry0nBCpjnZdpDaIHdoPs= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/tools/main.go b/tools/main.go new file mode 100644 index 0000000..9f582e3 --- /dev/null +++ b/tools/main.go @@ -0,0 +1,7 @@ +package main + +import "tools/cmd" + +func main() { + cmd.Execute() +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..4674518 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,15 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig.json", + "extends": "astro/tsconfigs/strict", + "compilerOptions": { + "baseUrl": ".", + "strict": true, + "target": "ESNext", + "module": "ESNext", + "strictNullChecks": true, + "paths": { + "@/*": ["src/*"] + }, + "types": ["vite-plugin-arraybuffer/types"] + } +}