Compare commits
53 Commits
jekyll
...
gh-actions
Author | SHA1 | Date | |
---|---|---|---|
ca831cec40 | |||
2a2a39f4a7 | |||
fac6f1c2f7 | |||
6cb2442786 | |||
073368e311 | |||
6176227dfa | |||
d807a0407f | |||
4fc8f4c77b | |||
1816f001a3 | |||
0164e25b69 | |||
8b685bca52 | |||
20cd435743 | |||
e7e72727ae | |||
7b900d92b2 | |||
fc40162d5e | |||
2d10c0ca80 | |||
35dd54ca45 | |||
40251a91ba | |||
4f6717ef32 | |||
8e1de3f1ec | |||
78d820858a | |||
996f07c1bf | |||
acf6719ad2 | |||
a7084414b6 | |||
8b0111450b | |||
4e9aacfab8 | |||
02b0c290ae | |||
1d28855a12 | |||
087a185136 | |||
|
d9ca754951 | ||
3bdacc82e6 | |||
97de2db989 | |||
42c316a1fa | |||
051caa7790 | |||
67f0d6c485 | |||
803242dde8 | |||
0e8270cfad | |||
0c5f705b27 | |||
66b6186296 | |||
fcd16cd8cf | |||
e9771f6b7e | |||
325f206d15 | |||
1ace2f62ea | |||
fc140b995c | |||
a66fc37c03 | |||
c5db049494 | |||
2afd947660 | |||
ac0d966308 | |||
af9fde3fa9 | |||
396b7e5683 | |||
eecd97a8d3 | |||
cc1d8047ab | |||
039bac5e09 |
@@ -1,2 +0,0 @@
|
|||||||
node_modules
|
|
||||||
vendor
|
|
@@ -1,31 +1,28 @@
|
|||||||
---
|
---
|
||||||
new_page_extension: md
|
new_page_extension: md
|
||||||
auto_deploy: false
|
auto_deploy: false
|
||||||
admin_path: ''
|
admin_path: ""
|
||||||
webhook_url:
|
webhook_url:
|
||||||
sections:
|
sections:
|
||||||
- type: jekyll-posts
|
- type: directory
|
||||||
|
path: source/_posts
|
||||||
label: Posts
|
label: Posts
|
||||||
create: documents
|
create: documents
|
||||||
templates:
|
match: "**/*"
|
||||||
- blog-post
|
|
||||||
- type: directory
|
- type: directory
|
||||||
path: _pages
|
path: source/_pages
|
||||||
label: Pages
|
label: Pages
|
||||||
create: documents
|
create: documents
|
||||||
match: "**/*"
|
match: "**/*"
|
||||||
upload_dir: _uploads
|
upload_dir: source/uploads
|
||||||
public_path: "/uploads"
|
public_path: "/uploads"
|
||||||
front_matter_path: ''
|
front_matter_path: ""
|
||||||
use_front_matter_path: false
|
use_front_matter_path: false
|
||||||
file_template: ":filename:"
|
file_template: ":filename:"
|
||||||
build:
|
build:
|
||||||
preview_env:
|
preview_output_directory: public
|
||||||
- JEKYLL_ENV=staging
|
install_dependencies_command: npm i
|
||||||
preview_output_directory: _site
|
|
||||||
install_dependencies_command: bundle install --path vendor/bundle
|
|
||||||
preview_docker_image: forestryio/ruby:2.6
|
preview_docker_image: forestryio/ruby:2.6
|
||||||
mount_path: "/srv"
|
mount_path: "/srv"
|
||||||
working_dir: "/srv"
|
working_dir: "/srv"
|
||||||
instant_preview_command: bundle exec jekyll serve --drafts --unpublished --future
|
instant_preview_command: yarn server
|
||||||
--port 8080 --host 0.0.0.0 -d _site
|
|
||||||
|
17
.github/dependabot.yml
vendored
Normal file
17
.github/dependabot.yml
vendored
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
version: 2
|
||||||
|
updates:
|
||||||
|
- package-ecosystem: npm
|
||||||
|
directory: "/"
|
||||||
|
schedule:
|
||||||
|
interval: monthly
|
||||||
|
time: "20:00"
|
||||||
|
timezone: Asia/Tokyo
|
||||||
|
open-pull-requests-limit: 10
|
||||||
|
ignore:
|
||||||
|
- dependency-name: textlint
|
||||||
|
versions:
|
||||||
|
- 11.7.7
|
||||||
|
- 11.8.1
|
||||||
|
- dependency-name: textlint-rule-no-dropping-the-ra
|
||||||
|
versions:
|
||||||
|
- 2.0.0
|
45
.github/workflows/ci.yml
vendored
Normal file
45
.github/workflows/ci.yml
vendored
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
# https://hexo.io/docs/github-pages.html
|
||||||
|
# https://github.com/docker/build-push-action/blob/master/docs/advanced/cache.md#github-cache
|
||||||
|
name: ci
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
buildAndPush:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
# - name: Set up QEMU
|
||||||
|
# uses: docker/setup-qemu-action@v1
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v1
|
||||||
|
|
||||||
|
- name: Login to GitHub Container Registry
|
||||||
|
uses: docker/login-action@v1
|
||||||
|
with:
|
||||||
|
registry: ghcr.io
|
||||||
|
username: ${{ github.repository_owner }}
|
||||||
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Build and push
|
||||||
|
id: docker_build
|
||||||
|
uses: docker/build-push-action@v2
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
push: true
|
||||||
|
tags: ghcr.io/uetchy/uechi.io:latest
|
||||||
|
cache-from: type=gha
|
||||||
|
cache-to: type=gha,mode=max
|
||||||
|
|
||||||
|
- name: Image digest
|
||||||
|
run: echo ${{ steps.docker_build.outputs.digest }}
|
||||||
|
|
||||||
|
- name: Trigger Watchtower Update
|
||||||
|
run: |
|
||||||
|
curl -s -H "Authorization: Bearer ${{ secrets.WATCHTOWER_TOKEN }}" https://watchtower.uechi.dev/v1/update
|
12
.gitignore
vendored
12
.gitignore
vendored
@@ -1,9 +1,11 @@
|
|||||||
/.vscode
|
/.vscode
|
||||||
/_site
|
|
||||||
/.sass-cache
|
/.sass-cache
|
||||||
/node_modules/
|
/node_modules/
|
||||||
/npm-debug.log
|
/npm-debug.log
|
||||||
/.jekyll-metadata
|
.DS_Store
|
||||||
/images/crushed
|
Thumbs.db
|
||||||
/.bundle
|
db.json
|
||||||
/vendor/bundle/
|
*.log
|
||||||
|
public/
|
||||||
|
.deploy*/
|
||||||
|
yarn.lock
|
2
.prettierignore
Normal file
2
.prettierignore
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
scaffolds/*
|
||||||
|
*.ejs
|
@@ -1,10 +1,8 @@
|
|||||||
{
|
{
|
||||||
"rules": {
|
"rules": {
|
||||||
"max-ten": true,
|
|
||||||
"no-start-duplicated-conjunction": {
|
"no-start-duplicated-conjunction": {
|
||||||
"interval": 2
|
"interval": 2
|
||||||
},
|
},
|
||||||
"no-dropping-the-ra": true,
|
|
||||||
"common-misspellings": true,
|
"common-misspellings": true,
|
||||||
"preset-japanese": {
|
"preset-japanese": {
|
||||||
"sentence-length": false
|
"sentence-length": false
|
||||||
@@ -12,9 +10,7 @@
|
|||||||
},
|
},
|
||||||
"filters": {
|
"filters": {
|
||||||
"whitelist": {
|
"whitelist": {
|
||||||
"allow": [
|
"allow": ["/{%.+?%}/"]
|
||||||
"/{%.+?%}/"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +0,0 @@
|
|||||||
language: node_js
|
|
||||||
node_js: stable
|
|
||||||
notifications:
|
|
||||||
email:
|
|
||||||
on_success: never
|
|
||||||
on_failure: change
|
|
19
Dockerfile
Normal file
19
Dockerfile
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
FROM node:15 as build
|
||||||
|
|
||||||
|
# https://github.com/jgm/pandoc/releases
|
||||||
|
RUN curl -LO https://github.com/jgm/pandoc/releases/download/2.14.0.1/pandoc-2.14.0.1-1-amd64.deb
|
||||||
|
RUN dpkg -i pandoc-2.14.0.1-1-amd64.deb
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
COPY package.json /app/
|
||||||
|
RUN yarn install
|
||||||
|
|
||||||
|
COPY themes /app/themes
|
||||||
|
COPY source /app/source
|
||||||
|
COPY _config.yml /app/
|
||||||
|
RUN yarn build
|
||||||
|
|
||||||
|
FROM nginx:stable-alpine as runtime
|
||||||
|
|
||||||
|
COPY nginx.conf /etc/nginx/nginx.conf
|
||||||
|
COPY --from=build /app/public /var/www/html/
|
3
Gemfile
3
Gemfile
@@ -1,3 +0,0 @@
|
|||||||
source 'https://rubygems.org'
|
|
||||||
|
|
||||||
gem 'github-pages', group: :jekyll_plugins # workaround https://github.com/github/pages-gem#usage
|
|
258
Gemfile.lock
258
Gemfile.lock
@@ -1,258 +0,0 @@
|
|||||||
GEM
|
|
||||||
remote: https://rubygems.org/
|
|
||||||
specs:
|
|
||||||
activesupport (6.0.3.3)
|
|
||||||
concurrent-ruby (~> 1.0, >= 1.0.2)
|
|
||||||
i18n (>= 0.7, < 2)
|
|
||||||
minitest (~> 5.1)
|
|
||||||
tzinfo (~> 1.1)
|
|
||||||
zeitwerk (~> 2.2, >= 2.2.2)
|
|
||||||
addressable (2.7.0)
|
|
||||||
public_suffix (>= 2.0.2, < 5.0)
|
|
||||||
coffee-script (2.4.1)
|
|
||||||
coffee-script-source
|
|
||||||
execjs
|
|
||||||
coffee-script-source (1.11.1)
|
|
||||||
colorator (1.1.0)
|
|
||||||
commonmarker (0.17.13)
|
|
||||||
ruby-enum (~> 0.5)
|
|
||||||
concurrent-ruby (1.1.7)
|
|
||||||
dnsruby (1.61.4)
|
|
||||||
simpleidn (~> 0.1)
|
|
||||||
em-websocket (0.5.2)
|
|
||||||
eventmachine (>= 0.12.9)
|
|
||||||
http_parser.rb (~> 0.6.0)
|
|
||||||
ethon (0.12.0)
|
|
||||||
ffi (>= 1.3.0)
|
|
||||||
eventmachine (1.2.7)
|
|
||||||
execjs (2.7.0)
|
|
||||||
faraday (1.0.1)
|
|
||||||
multipart-post (>= 1.2, < 3)
|
|
||||||
ffi (1.13.1)
|
|
||||||
forwardable-extended (2.6.0)
|
|
||||||
gemoji (3.0.1)
|
|
||||||
github-pages (207)
|
|
||||||
github-pages-health-check (= 1.16.1)
|
|
||||||
jekyll (= 3.9.0)
|
|
||||||
jekyll-avatar (= 0.7.0)
|
|
||||||
jekyll-coffeescript (= 1.1.1)
|
|
||||||
jekyll-commonmark-ghpages (= 0.1.6)
|
|
||||||
jekyll-default-layout (= 0.1.4)
|
|
||||||
jekyll-feed (= 0.13.0)
|
|
||||||
jekyll-gist (= 1.5.0)
|
|
||||||
jekyll-github-metadata (= 2.13.0)
|
|
||||||
jekyll-mentions (= 1.5.1)
|
|
||||||
jekyll-optional-front-matter (= 0.3.2)
|
|
||||||
jekyll-paginate (= 1.1.0)
|
|
||||||
jekyll-readme-index (= 0.3.0)
|
|
||||||
jekyll-redirect-from (= 0.15.0)
|
|
||||||
jekyll-relative-links (= 0.6.1)
|
|
||||||
jekyll-remote-theme (= 0.4.1)
|
|
||||||
jekyll-sass-converter (= 1.5.2)
|
|
||||||
jekyll-seo-tag (= 2.6.1)
|
|
||||||
jekyll-sitemap (= 1.4.0)
|
|
||||||
jekyll-swiss (= 1.0.0)
|
|
||||||
jekyll-theme-architect (= 0.1.1)
|
|
||||||
jekyll-theme-cayman (= 0.1.1)
|
|
||||||
jekyll-theme-dinky (= 0.1.1)
|
|
||||||
jekyll-theme-hacker (= 0.1.1)
|
|
||||||
jekyll-theme-leap-day (= 0.1.1)
|
|
||||||
jekyll-theme-merlot (= 0.1.1)
|
|
||||||
jekyll-theme-midnight (= 0.1.1)
|
|
||||||
jekyll-theme-minimal (= 0.1.1)
|
|
||||||
jekyll-theme-modernist (= 0.1.1)
|
|
||||||
jekyll-theme-primer (= 0.5.4)
|
|
||||||
jekyll-theme-slate (= 0.1.1)
|
|
||||||
jekyll-theme-tactile (= 0.1.1)
|
|
||||||
jekyll-theme-time-machine (= 0.1.1)
|
|
||||||
jekyll-titles-from-headings (= 0.5.3)
|
|
||||||
jemoji (= 0.11.1)
|
|
||||||
kramdown (= 2.3.0)
|
|
||||||
kramdown-parser-gfm (= 1.1.0)
|
|
||||||
liquid (= 4.0.3)
|
|
||||||
mercenary (~> 0.3)
|
|
||||||
minima (= 2.5.1)
|
|
||||||
nokogiri (>= 1.10.4, < 2.0)
|
|
||||||
rouge (= 3.19.0)
|
|
||||||
terminal-table (~> 1.4)
|
|
||||||
github-pages-health-check (1.16.1)
|
|
||||||
addressable (~> 2.3)
|
|
||||||
dnsruby (~> 1.60)
|
|
||||||
octokit (~> 4.0)
|
|
||||||
public_suffix (~> 3.0)
|
|
||||||
typhoeus (~> 1.3)
|
|
||||||
html-pipeline (2.14.0)
|
|
||||||
activesupport (>= 2)
|
|
||||||
nokogiri (>= 1.4)
|
|
||||||
http_parser.rb (0.6.0)
|
|
||||||
i18n (0.9.5)
|
|
||||||
concurrent-ruby (~> 1.0)
|
|
||||||
jekyll (3.9.0)
|
|
||||||
addressable (~> 2.4)
|
|
||||||
colorator (~> 1.0)
|
|
||||||
em-websocket (~> 0.5)
|
|
||||||
i18n (~> 0.7)
|
|
||||||
jekyll-sass-converter (~> 1.0)
|
|
||||||
jekyll-watch (~> 2.0)
|
|
||||||
kramdown (>= 1.17, < 3)
|
|
||||||
liquid (~> 4.0)
|
|
||||||
mercenary (~> 0.3.3)
|
|
||||||
pathutil (~> 0.9)
|
|
||||||
rouge (>= 1.7, < 4)
|
|
||||||
safe_yaml (~> 1.0)
|
|
||||||
jekyll-avatar (0.7.0)
|
|
||||||
jekyll (>= 3.0, < 5.0)
|
|
||||||
jekyll-coffeescript (1.1.1)
|
|
||||||
coffee-script (~> 2.2)
|
|
||||||
coffee-script-source (~> 1.11.1)
|
|
||||||
jekyll-commonmark (1.3.1)
|
|
||||||
commonmarker (~> 0.14)
|
|
||||||
jekyll (>= 3.7, < 5.0)
|
|
||||||
jekyll-commonmark-ghpages (0.1.6)
|
|
||||||
commonmarker (~> 0.17.6)
|
|
||||||
jekyll-commonmark (~> 1.2)
|
|
||||||
rouge (>= 2.0, < 4.0)
|
|
||||||
jekyll-default-layout (0.1.4)
|
|
||||||
jekyll (~> 3.0)
|
|
||||||
jekyll-feed (0.13.0)
|
|
||||||
jekyll (>= 3.7, < 5.0)
|
|
||||||
jekyll-gist (1.5.0)
|
|
||||||
octokit (~> 4.2)
|
|
||||||
jekyll-github-metadata (2.13.0)
|
|
||||||
jekyll (>= 3.4, < 5.0)
|
|
||||||
octokit (~> 4.0, != 4.4.0)
|
|
||||||
jekyll-mentions (1.5.1)
|
|
||||||
html-pipeline (~> 2.3)
|
|
||||||
jekyll (>= 3.7, < 5.0)
|
|
||||||
jekyll-optional-front-matter (0.3.2)
|
|
||||||
jekyll (>= 3.0, < 5.0)
|
|
||||||
jekyll-paginate (1.1.0)
|
|
||||||
jekyll-readme-index (0.3.0)
|
|
||||||
jekyll (>= 3.0, < 5.0)
|
|
||||||
jekyll-redirect-from (0.15.0)
|
|
||||||
jekyll (>= 3.3, < 5.0)
|
|
||||||
jekyll-relative-links (0.6.1)
|
|
||||||
jekyll (>= 3.3, < 5.0)
|
|
||||||
jekyll-remote-theme (0.4.1)
|
|
||||||
addressable (~> 2.0)
|
|
||||||
jekyll (>= 3.5, < 5.0)
|
|
||||||
rubyzip (>= 1.3.0)
|
|
||||||
jekyll-sass-converter (1.5.2)
|
|
||||||
sass (~> 3.4)
|
|
||||||
jekyll-seo-tag (2.6.1)
|
|
||||||
jekyll (>= 3.3, < 5.0)
|
|
||||||
jekyll-sitemap (1.4.0)
|
|
||||||
jekyll (>= 3.7, < 5.0)
|
|
||||||
jekyll-swiss (1.0.0)
|
|
||||||
jekyll-theme-architect (0.1.1)
|
|
||||||
jekyll (~> 3.5)
|
|
||||||
jekyll-seo-tag (~> 2.0)
|
|
||||||
jekyll-theme-cayman (0.1.1)
|
|
||||||
jekyll (~> 3.5)
|
|
||||||
jekyll-seo-tag (~> 2.0)
|
|
||||||
jekyll-theme-dinky (0.1.1)
|
|
||||||
jekyll (~> 3.5)
|
|
||||||
jekyll-seo-tag (~> 2.0)
|
|
||||||
jekyll-theme-hacker (0.1.1)
|
|
||||||
jekyll (~> 3.5)
|
|
||||||
jekyll-seo-tag (~> 2.0)
|
|
||||||
jekyll-theme-leap-day (0.1.1)
|
|
||||||
jekyll (~> 3.5)
|
|
||||||
jekyll-seo-tag (~> 2.0)
|
|
||||||
jekyll-theme-merlot (0.1.1)
|
|
||||||
jekyll (~> 3.5)
|
|
||||||
jekyll-seo-tag (~> 2.0)
|
|
||||||
jekyll-theme-midnight (0.1.1)
|
|
||||||
jekyll (~> 3.5)
|
|
||||||
jekyll-seo-tag (~> 2.0)
|
|
||||||
jekyll-theme-minimal (0.1.1)
|
|
||||||
jekyll (~> 3.5)
|
|
||||||
jekyll-seo-tag (~> 2.0)
|
|
||||||
jekyll-theme-modernist (0.1.1)
|
|
||||||
jekyll (~> 3.5)
|
|
||||||
jekyll-seo-tag (~> 2.0)
|
|
||||||
jekyll-theme-primer (0.5.4)
|
|
||||||
jekyll (> 3.5, < 5.0)
|
|
||||||
jekyll-github-metadata (~> 2.9)
|
|
||||||
jekyll-seo-tag (~> 2.0)
|
|
||||||
jekyll-theme-slate (0.1.1)
|
|
||||||
jekyll (~> 3.5)
|
|
||||||
jekyll-seo-tag (~> 2.0)
|
|
||||||
jekyll-theme-tactile (0.1.1)
|
|
||||||
jekyll (~> 3.5)
|
|
||||||
jekyll-seo-tag (~> 2.0)
|
|
||||||
jekyll-theme-time-machine (0.1.1)
|
|
||||||
jekyll (~> 3.5)
|
|
||||||
jekyll-seo-tag (~> 2.0)
|
|
||||||
jekyll-titles-from-headings (0.5.3)
|
|
||||||
jekyll (>= 3.3, < 5.0)
|
|
||||||
jekyll-watch (2.2.1)
|
|
||||||
listen (~> 3.0)
|
|
||||||
jemoji (0.11.1)
|
|
||||||
gemoji (~> 3.0)
|
|
||||||
html-pipeline (~> 2.2)
|
|
||||||
jekyll (>= 3.0, < 5.0)
|
|
||||||
kramdown (2.3.0)
|
|
||||||
rexml
|
|
||||||
kramdown-parser-gfm (1.1.0)
|
|
||||||
kramdown (~> 2.0)
|
|
||||||
liquid (4.0.3)
|
|
||||||
listen (3.2.1)
|
|
||||||
rb-fsevent (~> 0.10, >= 0.10.3)
|
|
||||||
rb-inotify (~> 0.9, >= 0.9.10)
|
|
||||||
mercenary (0.3.6)
|
|
||||||
mini_portile2 (2.4.0)
|
|
||||||
minima (2.5.1)
|
|
||||||
jekyll (>= 3.5, < 5.0)
|
|
||||||
jekyll-feed (~> 0.9)
|
|
||||||
jekyll-seo-tag (~> 2.1)
|
|
||||||
minitest (5.14.2)
|
|
||||||
multipart-post (2.1.1)
|
|
||||||
nokogiri (1.10.10)
|
|
||||||
mini_portile2 (~> 2.4.0)
|
|
||||||
octokit (4.18.0)
|
|
||||||
faraday (>= 0.9)
|
|
||||||
sawyer (~> 0.8.0, >= 0.5.3)
|
|
||||||
pathutil (0.16.2)
|
|
||||||
forwardable-extended (~> 2.6)
|
|
||||||
public_suffix (3.1.1)
|
|
||||||
rb-fsevent (0.10.4)
|
|
||||||
rb-inotify (0.10.1)
|
|
||||||
ffi (~> 1.0)
|
|
||||||
rexml (3.2.4)
|
|
||||||
rouge (3.19.0)
|
|
||||||
ruby-enum (0.8.0)
|
|
||||||
i18n
|
|
||||||
rubyzip (2.3.0)
|
|
||||||
safe_yaml (1.0.5)
|
|
||||||
sass (3.7.4)
|
|
||||||
sass-listen (~> 4.0.0)
|
|
||||||
sass-listen (4.0.0)
|
|
||||||
rb-fsevent (~> 0.9, >= 0.9.4)
|
|
||||||
rb-inotify (~> 0.9, >= 0.9.7)
|
|
||||||
sawyer (0.8.2)
|
|
||||||
addressable (>= 2.3.5)
|
|
||||||
faraday (> 0.8, < 2.0)
|
|
||||||
simpleidn (0.1.1)
|
|
||||||
unf (~> 0.1.4)
|
|
||||||
terminal-table (1.8.0)
|
|
||||||
unicode-display_width (~> 1.1, >= 1.1.1)
|
|
||||||
thread_safe (0.3.6)
|
|
||||||
typhoeus (1.4.0)
|
|
||||||
ethon (>= 0.9.0)
|
|
||||||
tzinfo (1.2.7)
|
|
||||||
thread_safe (~> 0.1)
|
|
||||||
unf (0.1.4)
|
|
||||||
unf_ext
|
|
||||||
unf_ext (0.0.7.7)
|
|
||||||
unicode-display_width (1.7.0)
|
|
||||||
zeitwerk (2.4.0)
|
|
||||||
|
|
||||||
PLATFORMS
|
|
||||||
ruby
|
|
||||||
|
|
||||||
DEPENDENCIES
|
|
||||||
github-pages
|
|
||||||
|
|
||||||
BUNDLED WITH
|
|
||||||
2.1.4
|
|
2
LICENSE
2
LICENSE
@@ -1,6 +1,6 @@
|
|||||||
The MIT License (MIT)
|
The MIT License (MIT)
|
||||||
|
|
||||||
Copyright (c) 2019 Yasuaki Uechi (https://uechi.io)
|
Copyright (c) 2021 Yasuaki Uechi (https://uechi.io)
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
8
Makefile
Normal file
8
Makefile
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
build:
|
||||||
|
docker-compose build --pull
|
||||||
|
|
||||||
|
push:
|
||||||
|
docker-compose push
|
||||||
|
|
||||||
|
deploy: build
|
||||||
|
docker-compose -f docker-compose.production.yml up -d
|
13
README.md
13
README.md
@@ -1,19 +1,12 @@
|
|||||||
# uechi.io
|
# uechi.io
|
||||||
|
|
||||||
[](https://travis-ci.org/uetchy/uechi.io)
|
[](https://github.com/uetchy/uechi.io/actions?query=pages)
|
||||||
|
|
||||||
## Build
|
## Build
|
||||||
|
|
||||||
```
|
```
|
||||||
docker-compose run web bundle install
|
n 15
|
||||||
docker-compose up --build
|
yarn build
|
||||||
```
|
|
||||||
|
|
||||||
## Test
|
|
||||||
|
|
||||||
```
|
|
||||||
npm install
|
|
||||||
npm test
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Publish
|
## Publish
|
||||||
|
186
_config.yml
186
_config.yml
@@ -1,47 +1,145 @@
|
|||||||
---
|
# Hexo Configuration
|
||||||
|
## Docs: https://hexo.io/docs/configuration.html
|
||||||
|
## Source: https://github.com/hexojs/hexo/
|
||||||
|
|
||||||
|
# Site
|
||||||
title: uechi.io
|
title: uechi.io
|
||||||
timezone: Asia/Tokyo
|
subtitle: ""
|
||||||
collections:
|
description: "Random posts from U"
|
||||||
posts:
|
keywords:
|
||||||
title: Posts
|
author: Yasuaki Uechi
|
||||||
output: true
|
language: en
|
||||||
uploads:
|
timezone: "Asia/Tokyo"
|
||||||
title: Uploads
|
|
||||||
output: true
|
excerpt:
|
||||||
defaults:
|
depth: 1
|
||||||
- scope:
|
|
||||||
path: ''
|
|
||||||
type: posts
|
|
||||||
values:
|
|
||||||
layout: post
|
|
||||||
permalink: "/blog/:title"
|
|
||||||
description: Random posts from @uetchy.
|
|
||||||
url: https://uechi.io
|
|
||||||
email: y@uechi.io
|
|
||||||
twitter:
|
|
||||||
username: uechz
|
|
||||||
github:
|
github:
|
||||||
username: uetchy
|
username: uetchy
|
||||||
logo: "/images/icon.png"
|
twitter:
|
||||||
excerpt_separator: "#"
|
username: uechz
|
||||||
google_analytics: UA-28919359-12
|
|
||||||
plugins:
|
umami:
|
||||||
- jekyll-redirect-from
|
host: analytics.uechi.io
|
||||||
- jekyll-sitemap
|
id: 2739f9aa-b8d5-45fa-8972-07a5bbb87e8a
|
||||||
- jekyll-seo-tag
|
|
||||||
- jekyll-feed
|
node_sass:
|
||||||
- jemoji
|
outputStyle: nested
|
||||||
include:
|
precision: 5
|
||||||
- _pages
|
sourceComments: false
|
||||||
exclude:
|
|
||||||
- README.md
|
# URL
|
||||||
- LICENSE
|
## If your site is put in a subdirectory, set url as 'http://example.com/child' and root as '/child/'
|
||||||
- CNAME
|
url: https://uechi.io
|
||||||
- Gemfile
|
root: /
|
||||||
- Gemfile.lock
|
permalink: /blog/:name/
|
||||||
- package.json
|
permalink_defaults:
|
||||||
- node_modules
|
pretty_urls:
|
||||||
- script
|
trailing_index: true # Set to false to remove trailing 'index.html' from permalinks
|
||||||
- vendor
|
trailing_html: true # Set to false to remove trailing '.html' from permalinks
|
||||||
- docker-compose.yml
|
|
||||||
- Dockerfile
|
# Directory
|
||||||
|
source_dir: source
|
||||||
|
public_dir: public
|
||||||
|
tag_dir: tags
|
||||||
|
archive_dir: archives
|
||||||
|
category_dir: categories
|
||||||
|
code_dir: downloads/code
|
||||||
|
i18n_dir: :lang
|
||||||
|
skip_render:
|
||||||
|
|
||||||
|
# Writing
|
||||||
|
new_post_name: :title.md # File name of new posts
|
||||||
|
default_layout: post
|
||||||
|
titlecase: false # Transform title into titlecase
|
||||||
|
external_link:
|
||||||
|
enable: true # Open external links in new tab
|
||||||
|
field: site # Apply to the whole site
|
||||||
|
exclude: ""
|
||||||
|
filename_case: 0
|
||||||
|
render_drafts: false
|
||||||
|
relative_link: false
|
||||||
|
future: true
|
||||||
|
post_asset_folder: true
|
||||||
|
marked:
|
||||||
|
prependRoot: true
|
||||||
|
postAsset: true
|
||||||
|
|
||||||
|
# Math
|
||||||
|
mathjax:
|
||||||
|
tags: none # or 'ams' or 'all'
|
||||||
|
single_dollars: true # enable single dollar signs as in-line math delimiters
|
||||||
|
cjk_width: 0.9 # relative CJK char width
|
||||||
|
normal_width: 0.6 # relative normal (monospace) width
|
||||||
|
append_css: true # add CSS to pages rendered by MathJax
|
||||||
|
every_page: true # if true, every page will be rendered by MathJax regardless the `mathjax` setting in Front-matter
|
||||||
|
|
||||||
|
# Highlight
|
||||||
|
highlight:
|
||||||
|
enable: true
|
||||||
|
line_number: false
|
||||||
|
auto_detect: false
|
||||||
|
tab_replace: ""
|
||||||
|
wrap: false
|
||||||
|
hljs: true
|
||||||
|
prismjs:
|
||||||
|
enable: false
|
||||||
|
|
||||||
|
# Home page setting
|
||||||
|
# path: Root path for your blogs index page. (default = '')
|
||||||
|
# per_page: Posts displayed per page. (0 = disable pagination)
|
||||||
|
# order_by: Posts order. (Order by date descending by default)
|
||||||
|
index_generator:
|
||||||
|
path: ""
|
||||||
|
per_page: 20
|
||||||
|
order_by: -date
|
||||||
|
|
||||||
|
# Category & Tag
|
||||||
|
default_category: uncategorized
|
||||||
|
category_map:
|
||||||
|
tag_map:
|
||||||
|
|
||||||
|
# Metadata elements
|
||||||
|
## https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta
|
||||||
|
meta_generator: true
|
||||||
|
|
||||||
|
# Date / Time format
|
||||||
|
## Hexo uses Moment.js to parse and display date
|
||||||
|
## You can customize the date format as defined in
|
||||||
|
## http://momentjs.com/docs/#/displaying/format/
|
||||||
|
date_format: YYYY-MM-DD
|
||||||
|
time_format: HH:mm:ss
|
||||||
|
## updated_option supports 'mtime', 'date', 'empty'
|
||||||
|
updated_option: "mtime"
|
||||||
|
|
||||||
|
# Pagination
|
||||||
|
## Set per_page to 0 to disable pagination
|
||||||
|
per_page: 20
|
||||||
|
pagination_dir: page
|
||||||
|
|
||||||
|
# Include / Exclude file(s)
|
||||||
|
## include:/exclude: options only apply to the 'source/' folder
|
||||||
|
# include:
|
||||||
|
# exclude:
|
||||||
|
ignore:
|
||||||
|
|
||||||
|
# Extensions
|
||||||
|
## Plugins: https://hexo.io/plugins/
|
||||||
|
## Themes: https://hexo.io/themes/
|
||||||
|
theme: uio
|
||||||
|
|
||||||
|
# Feed
|
||||||
|
feed:
|
||||||
|
limit: 20
|
||||||
|
order_by: "-date"
|
||||||
|
tag_dir: "tag"
|
||||||
|
category_dir: "category"
|
||||||
|
rss:
|
||||||
|
enable: false
|
||||||
|
jsonFeed:
|
||||||
|
enable: true
|
||||||
|
output: "feed.json"
|
||||||
|
atom:
|
||||||
|
enable: true
|
||||||
|
output: "feed.xml"
|
||||||
|
|
||||||
|
@@ -1,12 +0,0 @@
|
|||||||
---
|
|
||||||
title: Deconvolutionと呼ぶのはもうやめよう
|
|
||||||
date: 2017-03-05 13:44:00 +09:00
|
|
||||||
---
|
|
||||||
|
|
||||||
深層学習において、Convolutional Layer (畳み込み層)とは、あるシェイプのテンソルをそれ以下のサイズに縮約する性質のレイヤーです。一方で Deconvolution Layer (逆畳み込み層)とは、[Jonathan Long, et al](https://arxiv.org/abs/1411.4038)の論文で提案されたレイヤーで、あるシェイプのテンソルをそれ以上のサイズに拡大する性質を持ちます。
|
|
||||||
|
|
||||||
ところが実際のところ、このレイヤーは Transposed Convolution Layer (転置畳み込み層)と呼ぶべきです。なぜかを以下に示します。
|
|
||||||
|
|
||||||
> Upsampling is backwards strided convolution. (アップサンプリングは
|
|
||||||
|
|
||||||
[Stack Exchange](http://datascience.stackexchange.com/questions/6107/what-are-deconvolutional-layers)での議論を踏まえると
|
|
@@ -1,11 +0,0 @@
|
|||||||
---
|
|
||||||
title: 'gst: a powerful pal for ghq'
|
|
||||||
date: 2017-06-02 23:02:00 +09:00
|
|
||||||
---
|
|
||||||
|
|
||||||
[gst](https://github.com/uetchy/gst) is tiny and simple but powerful pal for [ghq](https://github.com/motemen/ghq).
|
|
||||||
|
|
||||||
Have you ever imagined what if you know which commits are unpushed or which changes are uncommitted yet, for all of the repositories you have cloned on your machine?
|
|
||||||
|
|
||||||
You might want to check out my ongoing project `gst`:
|
|
||||||
it might help you to know what ongoing changes are remained to be committed or pushed among entire your local repositories.
|
|
@@ -1,46 +0,0 @@
|
|||||||
---
|
|
||||||
date: 2020-03-16 18:19:11 +0900
|
|
||||||
title: pixiv SPRING BOOT CAMP 2020
|
|
||||||
---
|
|
||||||
|
|
||||||
[pixiv SPRING BOOT CAMP 2020](https://www.pixiv.co.jp/news/recruit/article/8728/)に参加した。インターン自体が初めてということもあり、普段とは種類の異なる様々な知見を得ることができたので共有したい。
|
|
||||||
|
|
||||||
## 選考
|
|
||||||
|
|
||||||
選考は Google Hangout Meet を用いたオンラインセッションで実施された。質問内容は以下の通りである。
|
|
||||||
|
|
||||||
- 自己紹介
|
|
||||||
- コースの希望とその理由
|
|
||||||
- 簡単なコーディングテスト
|
|
||||||
|
|
||||||
フロントエンドを希望したため、コーディングテストは JavaScript を用いてフォーム画面を設計するという内容になっていた。
|
|
||||||
React を用いて MVP を実装し、それからインタビュワーのツッコミを打ち返すという形式であった。
|
|
||||||
|
|
||||||
選考結果は次の日に通知された。選考に関するフローは洗練されており、よく設計されているように感じた。
|
|
||||||
|
|
||||||
## オリエンテーション
|
|
||||||
|
|
||||||
- NDA
|
|
||||||
- ラジオ体操
|
|
||||||
- 自己紹介
|
|
||||||
|
|
||||||
## 業務
|
|
||||||
|
|
||||||
- iMac
|
|
||||||
- YubiKey
|
|
||||||
- 課題 1. psd.js の TypeScript 移植
|
|
||||||
- 課題 2. 通知 API の JSON API 化+React 化
|
|
||||||
- 同人誌入稿画面のレスポンシブ化
|
|
||||||
- 新しい入稿フローの提案
|
|
||||||
|
|
||||||
### ランチ
|
|
||||||
|
|
||||||
- タコライス
|
|
||||||
- LINE Pay
|
|
||||||
- PayPay
|
|
||||||
|
|
||||||
## 成果発表
|
|
||||||
|
|
||||||
## 感想
|
|
||||||
|
|
||||||
### 社風
|
|
@@ -1,14 +0,0 @@
|
|||||||
---
|
|
||||||
date: 2020-02-13 16:22:05 +0900
|
|
||||||
title: 静寂を得る方法
|
|
||||||
|
|
||||||
---
|
|
||||||
聴覚過敏であったり、そうでなくとも周りの音がパフォーマンスに悪影響となる人のために、静寂を得る方法を紹介します。
|
|
||||||
|
|
||||||
## EARIN M-2
|
|
||||||
|
|
||||||
[EARIN](https://earin.com/) は左右分離型Bluetoothイヤホンです。付属のイヤホンの代わりに自分の耳にフィットするComplyのイヤーチップと付け替えます。
|
|
||||||
|
|
||||||
## Moldex
|
|
||||||
|
|
||||||
Moldex は使い捨て耳栓のメーカーであり、各種遮音レベルに分かれた多様なラインナップを提供しています。
|
|
@@ -1,25 +0,0 @@
|
|||||||
<!-- Google Analytics -->
|
|
||||||
<script>
|
|
||||||
;(function(i, s, o, g, r, a, m) {
|
|
||||||
i['GoogleAnalyticsObject'] = r
|
|
||||||
;(i[r] =
|
|
||||||
i[r] ||
|
|
||||||
function() {
|
|
||||||
;(i[r].q = i[r].q || []).push(arguments)
|
|
||||||
}),
|
|
||||||
(i[r].l = 1 * new Date())
|
|
||||||
;(a = s.createElement(o)), (m = s.getElementsByTagName(o)[0])
|
|
||||||
a.async = 1
|
|
||||||
a.src = g
|
|
||||||
m.parentNode.insertBefore(a, m)
|
|
||||||
})(
|
|
||||||
window,
|
|
||||||
document,
|
|
||||||
'script',
|
|
||||||
'https://www.google-analytics.com/analytics.js',
|
|
||||||
'ga'
|
|
||||||
)
|
|
||||||
|
|
||||||
ga('create', '{{ site.google_analytics }}', 'auto')
|
|
||||||
ga('send', 'pageview')
|
|
||||||
</script>
|
|
@@ -1,53 +0,0 @@
|
|||||||
<head>
|
|
||||||
<meta charset="UTF-8" />
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
||||||
|
|
||||||
<link rel="shortcut icon" href="{{ site.baseurl }}/images/favicon.ico" />
|
|
||||||
<link
|
|
||||||
rel="apple-touch-icon"
|
|
||||||
sizes="180x180"
|
|
||||||
href="{{ site.baseurl }}/images/apple-touch-icon.png"
|
|
||||||
/>
|
|
||||||
<link
|
|
||||||
rel="icon"
|
|
||||||
type="image/png"
|
|
||||||
href="{{ site.baseurl }}/images/favicon-32x32.png"
|
|
||||||
sizes="32x32"
|
|
||||||
/>
|
|
||||||
<link
|
|
||||||
rel="icon"
|
|
||||||
type="image/png"
|
|
||||||
href="{{ site.baseurl }}/images/favicon-16x16.png"
|
|
||||||
sizes="16x16"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<link
|
|
||||||
rel="mask-icon"
|
|
||||||
href="{{ site.baseurl }}/images/safari-pinned-tab.svg"
|
|
||||||
color="#5bbad5"
|
|
||||||
/>
|
|
||||||
|
|
||||||
{% seo %} {% feed_meta %}
|
|
||||||
|
|
||||||
<!-- Normalize -->
|
|
||||||
<link
|
|
||||||
rel="stylesheet"
|
|
||||||
href="https://cdnjs.cloudflare.com/ajax/libs/normalize/7.0.0/normalize.min.css"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!-- Share -->
|
|
||||||
<script
|
|
||||||
defer
|
|
||||||
src="https://connect.facebook.net/en_US/sdk.js#xfbml=1&version=v2.8"
|
|
||||||
id="facebook-jssdk"
|
|
||||||
></script>
|
|
||||||
<script
|
|
||||||
defer
|
|
||||||
src="https://platform.twitter.com/widgets.js"
|
|
||||||
id="twitter-wjs"
|
|
||||||
></script>
|
|
||||||
|
|
||||||
<!-- Styles -->
|
|
||||||
<link rel="stylesheet" href="{{ site.baseurl }}/css/index.css" />
|
|
||||||
</head>
|
|
@@ -1,9 +0,0 @@
|
|||||||
---
|
|
||||||
layout: default
|
|
||||||
---
|
|
||||||
|
|
||||||
<section>
|
|
||||||
<article class="article">
|
|
||||||
<div class="article__content">{{ content }}</div>
|
|
||||||
</article>
|
|
||||||
</section>
|
|
@@ -1,10 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
{% include head.html %}
|
|
||||||
|
|
||||||
<body>
|
|
||||||
{% include header.html %}
|
|
||||||
{{ content }}
|
|
||||||
{% include footer.html %}
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@@ -1,26 +0,0 @@
|
|||||||
---
|
|
||||||
title: Page Not Found
|
|
||||||
permalink: "/404.html"
|
|
||||||
excerpt: ''
|
|
||||||
---
|
|
||||||
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
{% include head.html %}
|
|
||||||
<style>
|
|
||||||
h1 {
|
|
||||||
font-size: 12em;
|
|
||||||
font-weight: 100;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<body>
|
|
||||||
{% include header.html %}
|
|
||||||
<section class='page-section error-page'>
|
|
||||||
<div class='container-narrow text-center py-md-8'>
|
|
||||||
<h1>404</h1>
|
|
||||||
<p class="lead">This page could not be found</p>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@@ -1,53 +0,0 @@
|
|||||||
---
|
|
||||||
permalink: "/"
|
|
||||||
layout:
|
|
||||||
---
|
|
||||||
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
{% include head.html %}
|
|
||||||
<body>
|
|
||||||
<div class="metro">
|
|
||||||
<h1 class="logo">
|
|
||||||
<img src="{{ site.baseurl }}/images/logo.svg" style="height: 50px" />
|
|
||||||
</h1>
|
|
||||||
<nav>
|
|
||||||
<ul class="menu">
|
|
||||||
<li class="menu__item">
|
|
||||||
<a href="/me">Me</a>
|
|
||||||
</li>
|
|
||||||
<li class="menu__item">
|
|
||||||
<a href="https://github.com/{{ site.github.username }}">GitHub</a>
|
|
||||||
</li>
|
|
||||||
<li class="menu__item">
|
|
||||||
<a href="https://twitter.com/{{ site.twitter.username }}"
|
|
||||||
>Twitter</a
|
|
||||||
>
|
|
||||||
</li>
|
|
||||||
<li class="menu__item">
|
|
||||||
<a href="/wallpaper">Wallpaper</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</nav>
|
|
||||||
</div>
|
|
||||||
<section>
|
|
||||||
{% for post in site.posts %}
|
|
||||||
<article class="article-list__item">
|
|
||||||
<h2 class="article-list__item__title">
|
|
||||||
<a href="{{ post.url | prepend: site.baseurl }}">{{ post.title }}</a>
|
|
||||||
</h2>
|
|
||||||
<!-- <time class="article-list__item__pubdate" pubdate>{{ post.date | date: '%B %d, %Y' }}</time> -->
|
|
||||||
<article class="article-list__item__excerpt">
|
|
||||||
{{ post.excerpt | strip_html | truncate: 140, "..." }}
|
|
||||||
</article>
|
|
||||||
<a
|
|
||||||
class="article-list__item__button"
|
|
||||||
href="{{ post.url | prepend: site.baseurl }}"
|
|
||||||
>Read more</a
|
|
||||||
>
|
|
||||||
</article>
|
|
||||||
{% endfor %}
|
|
||||||
</section>
|
|
||||||
{% include footer.html %}
|
|
||||||
</body>
|
|
||||||
</html>
|
|
48
_pages/me.md
48
_pages/me.md
@@ -1,48 +0,0 @@
|
|||||||
---
|
|
||||||
title: Yasuaki Uechi
|
|
||||||
permalink: "/me"
|
|
||||||
layout: article
|
|
||||||
---
|
|
||||||
|
|
||||||
<style>
|
|
||||||
img {
|
|
||||||
width: auto !important;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
# README
|
|
||||||
|
|
||||||
> I'm **Yasuaki Uechi**, a graduate student studying about recurrent neural networks. I was born in Okinawa, Japan in 1994 and have been living in Kanagawa.
|
|
||||||
|
|
||||||
# Contact
|
|
||||||
|
|
||||||
Reach me at `y@uechi.io` (recommended) or [@uechz](https://twitter.com/uechz) on Twitter. Beware that I'm not a person of quick reply so if you are in urgent need of a lightning response better bomb my inbox with reminders so I can prioritize your email than any other emails.
|
|
||||||
|
|
||||||
## GPG Key
|
|
||||||
|
|
||||||
Get [GPG Key](https://github.com/uetchy.gpg) on GitHub.
|
|
||||||
|
|
||||||
# Facts
|
|
||||||
|
|
||||||
- play violin, tin whistle, piano, and bodhrán. Logic Pro user.
|
|
||||||
- overall interests: ux/graphic design, webdev, machine learning (mainly nlp and generative design), behavioral economics, organization government, irish music, coffee, puzzle game
|
|
||||||
- dev interests: react, nodejs, rust, docker
|
|
||||||
- have confidence in: javascript (incl. nodejs and typescript), python, ux design, baremetal server, english
|
|
||||||
- have no confidence in: normal life stuff
|
|
||||||
- have some experience in: swift, go, ruby, rust, c++, pytorch
|
|
||||||
- language skills:
|
|
||||||
- Japanese: native
|
|
||||||
- English: TOEIC 940, TOEFL 78
|
|
||||||
- Chinese, Korean, Indonesian, German, Russian: current objectives still n00b though
|
|
||||||
- typeface fanatic
|
|
||||||
|
|
||||||
# Publishing
|
|
||||||
|
|
||||||
- [Open Source @ GitHub](https://github.com/uetchy)
|
|
||||||
- [Technical Note (English) @ dev.to](https://dev.to/uetchy)
|
|
||||||
- [Technical Note (Japanese) @ Qiita](https://qiita.com/uetchy)
|
|
||||||
- [Design Portfolio @ Behance](https://www.behance.net/uechi)
|
|
||||||
|
|
||||||
# Current Activity
|
|
||||||
|
|
||||||
- Seeking for a job
|
|
@@ -1,60 +0,0 @@
|
|||||||
---
|
|
||||||
title: Pay
|
|
||||||
permalink: "/pay"
|
|
||||||
layout: default
|
|
||||||
---
|
|
||||||
|
|
||||||
<div id="pay">
|
|
||||||
<section>
|
|
||||||
<p>
|
|
||||||
送金方法はオススメ順に並んでいます。いずれか都合の良い方法で送金または請求してください。
|
|
||||||
</p>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<h1>Kyash</h1>
|
|
||||||
<p>
|
|
||||||
QRコードをスキャンするか、Kyash ID
|
|
||||||
<span class="monospace">uechi</span> 宛に送金・請求してください。
|
|
||||||
</p>
|
|
||||||
<img src="/images/payment/kyash.png" width="200" height="200" />
|
|
||||||
<a class="button" href="kyash://qr/u/7175222723044580164">Kyashを開く</a>
|
|
||||||
<br />
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<h1>LINE Pay</h1>
|
|
||||||
<p>LINE宛に送金・請求してください。</p>
|
|
||||||
<a class="button" href="https://line.me/ja/pay">LINE Payについて</a>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<h1>Revolut</h1>
|
|
||||||
<p><span class="monospace">yasuakpnqg</span> 宛にお送りください。</p>
|
|
||||||
<a class="button" href="https://pay.revolut.com/profile/yasuakpnqg"
|
|
||||||
>Revolutを開く</a
|
|
||||||
>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<h1>Amazon ギフトカード</h1>
|
|
||||||
<p>
|
|
||||||
メッセージアプリ経由で、または
|
|
||||||
<span class="monospace">y@uechi.io</span> 宛にお送りください。
|
|
||||||
</p>
|
|
||||||
<a class="button" href="https://www.amazon.co.jp/gp/product/B004N3APGO/"
|
|
||||||
>Amazonを開く</a
|
|
||||||
>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<h1>PayPay</h1>
|
|
||||||
<p>QRコードをスキャンして送金してください。</p>
|
|
||||||
<img src="/images/payment/paypay.png" width="200" height="200" />
|
|
||||||
<a class="button" href="https://paypay.ne.jp/">PayPayについて</a> <br />
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<h1>PayPal</h1>
|
|
||||||
<p>
|
|
||||||
PayPalで
|
|
||||||
<span class="monospace">y@uechi.io</span> 宛に送金・請求してください。
|
|
||||||
</p>
|
|
||||||
<a class="button" href="https://paypal.me/uetchy">PayPalを開く</a>
|
|
||||||
<br />
|
|
||||||
</section>
|
|
||||||
</div>
|
|
@@ -1,48 +0,0 @@
|
|||||||
---
|
|
||||||
title: Wallpapers
|
|
||||||
permalink: "/wallpaper"
|
|
||||||
layout: post
|
|
||||||
---
|
|
||||||
|
|
||||||
Right-click and choose **Save Image** to download my wallpapers. All following pictures are my own work and are published on Creative Commons BY-NC-SA.
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
<div style="display: flex; flex-direction: row">
|
|
||||||
<div><img src="{{ site.baseurl }}/images/wallpaper/vertex.png" /></div>
|
|
||||||
<div style="margin-left: 20px"><img src="{{ site.baseurl }}/images/wallpaper/vertex2.png" /></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
## Monochrome
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||

|
|
@@ -1,83 +0,0 @@
|
|||||||
---
|
|
||||||
title: 生活の自動化
|
|
||||||
date: 2018-08-05 00:00:00 +09:00
|
|
||||||
redirect_from: "/blog/2018/08/05/life-automation"
|
|
||||||
---
|
|
||||||
|
|
||||||
生活にオートメーションを上手く取り入れ、本当にやりたいことや、やるべきことに集中できる環境をつくろう。
|
|
||||||
|
|
||||||
# 洗濯の自動化
|
|
||||||
|
|
||||||
Panasonic のドラム洗濯乾燥機を使っている。威力を最大限に享受するため、タンブラー乾燥向けの普段着を揃えておくことも重要だ。
|
|
||||||
洗剤は粉と液体とが一体化したジェルボール洗剤が便利。ドラムの底にひとつ置くだけでよく、計量する必要がない。
|
|
||||||
|
|
||||||
# 食器洗いの自動化
|
|
||||||
|
|
||||||
Panasonic NC-TCR2 という一人暮らし用のコンパクト食洗乾燥機が便利。
|
|
||||||
洗濯機と同じく食洗機専用のジェルボール洗剤を使えば計量する手間を省ける。
|
|
||||||
|
|
||||||
# 照明の自動化
|
|
||||||
|
|
||||||
Hue はインターネット経由で明るさや色相をコントロールすることができる電球である。
|
|
||||||
|
|
||||||
- 「家から離れたら消灯」
|
|
||||||
- 「家に近付いたら点灯」
|
|
||||||
- 「日が暮れたら暖色系に切り替える」
|
|
||||||
- 「23 時になったら消灯」
|
|
||||||
|
|
||||||
など多様なルールを作ることができる。
|
|
||||||
家では外の明るさに合わせて照明の明るさを調整して、概日リズムが崩れにくいようにルールを決めている。
|
|
||||||
|
|
||||||
# 空調の自動化
|
|
||||||
|
|
||||||
Nature Remo でエアコンの操作を自動化した。
|
|
||||||
|
|
||||||
- 「湿度が高ければドライに変更」
|
|
||||||
- 「家から離れたら電源オフ」
|
|
||||||
- 「朝になったら冷房へ切り替え」
|
|
||||||
|
|
||||||
など多様なルールを作ることができる。
|
|
||||||
|
|
||||||
Nature Remo 自体はエアコン専用ではなく、赤外線で操作出来るデバイスであればなんでも操作できる。家ではテレビもこれで操作している。
|
|
||||||
|
|
||||||
ちなみに[Nature Remo を NodeJS で操作することができるライブラリ](https://github.com/uetchy/nature-remo)を作ったので、是非使ってみて欲しい。ライブラリ経由で温度・湿度・明度のセンサー値を取得したり、指定したモードにエアコンを切り替えることができる。
|
|
||||||
|
|
||||||
# 自動施錠・自動開錠
|
|
||||||
|
|
||||||
Qrio Lock をドアに取り付けることでオートロックとオートアンロックができるようになった。
|
|
||||||
|
|
||||||
# 睡眠記録の自動化
|
|
||||||
|
|
||||||
Withings 改め Nokia の Sleep を使っている。
|
|
||||||
睡眠を計測する際、身体にウェアラブルデバイスを身につける必要がないという点で、Nokia Sleep は Apple Watch や Fitbit よりも優れている。
|
|
||||||
|
|
||||||
機能としては、入眠・起床検知、心拍数記録、睡眠深度解析、いびき検出、IFTTT 連携がある。
|
|
||||||
|
|
||||||
# 体重記録の自動化
|
|
||||||
|
|
||||||
Withings の Wi-Fi Scale を使っている。体重と体脂肪率、心拍数、BMI を Wi-Fi 経由でクラウドに自動記録し、Apple Health などで推移を確認できる。
|
|
||||||
|
|
||||||
Wi-Fi Scale には CO2 センサーもついており、部屋の二酸化炭素濃度を記録してくれる。
|
|
||||||
|
|
||||||
# コーヒー豆のサブスクリプション
|
|
||||||
|
|
||||||
珈琲きゃろっとのサブスクリプションを利用している。
|
|
||||||
|
|
||||||
# オンラインスーパー
|
|
||||||
|
|
||||||
イトーヨーカドーのオンラインスーパーを使っている。お気に入りリストへ牛乳、オレンジ、ベーコン、卵など毎回買うものを登録しておくことで、慣れれば 5 分程度で注文が完了する。あとは指定した時間に家へ商品を届けてくれる。
|
|
||||||
|
|
||||||
# 自動家計簿
|
|
||||||
|
|
||||||
MoneyForward を使っている。支出を自動で食費、趣味、日用品などに仕分けてくれる。
|
|
||||||
無現金縛りプレイと相性が良い。
|
|
||||||
|
|
||||||
# 自炊の効率化
|
|
||||||
|
|
||||||
最近 COMP で食事を置き換え始めた。まだ評価は出来ないが少なくとも味は悪くなく(薄いきな粉のような味)、不足しがちなビタミンや鉄分を補える点では良い製品だと思う。
|
|
||||||
|
|
||||||
# 気になる製品
|
|
||||||
|
|
||||||
## ルンバ
|
|
||||||
|
|
||||||
ルンバは気になるが、絨毯を取り除くわけにもいかないので二の足を踏んでいる。ルンバについては[KainokiKaede's diary](http://kainokikaede.hatenablog.com/entry/2018/07/24/185452)の素晴らしい記事を読んで欲しい。
|
|
15
docker-compose.production.yml
Normal file
15
docker-compose.production.yml
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
version: "3.0"
|
||||||
|
|
||||||
|
services:
|
||||||
|
web:
|
||||||
|
image: ghcr.io/uetchy/uechi.io
|
||||||
|
container_name: uechi.io
|
||||||
|
environment:
|
||||||
|
VIRTUAL_HOST: uechi.io
|
||||||
|
LETSENCRYPT_HOST: uechi.io
|
||||||
|
labels:
|
||||||
|
com.centurylinklabs.watchtower.enable: "true"
|
||||||
|
networks:
|
||||||
|
default:
|
||||||
|
name: webproxy
|
||||||
|
external: true
|
8
docker-compose.yml
Normal file
8
docker-compose.yml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
version: "3.0"
|
||||||
|
|
||||||
|
services:
|
||||||
|
web:
|
||||||
|
image: ghcr.io/uetchy/uechi.io
|
||||||
|
build: .
|
||||||
|
ports:
|
||||||
|
- "8080:80"
|
46
nginx.conf
Normal file
46
nginx.conf
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
worker_processes auto;
|
||||||
|
|
||||||
|
error_log /var/log/nginx/error.log warn;
|
||||||
|
pid /var/run/nginx.pid;
|
||||||
|
|
||||||
|
events {
|
||||||
|
worker_connections 1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
http {
|
||||||
|
include /etc/nginx/mime.types;
|
||||||
|
default_type application/octet-stream;
|
||||||
|
|
||||||
|
access_log /var/log/nginx/access.log;
|
||||||
|
|
||||||
|
sendfile on;
|
||||||
|
keepalive_timeout 65;
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
|
||||||
|
root /var/www/html;
|
||||||
|
error_page 404 /404.html;
|
||||||
|
|
||||||
|
location /404.html {
|
||||||
|
internal;
|
||||||
|
}
|
||||||
|
|
||||||
|
location = /robots.txt {
|
||||||
|
allow all;
|
||||||
|
log_not_found off;
|
||||||
|
access_log off;
|
||||||
|
}
|
||||||
|
|
||||||
|
location / {
|
||||||
|
index index.html;
|
||||||
|
try_files $uri $uri.html $uri/index.html =404;
|
||||||
|
}
|
||||||
|
|
||||||
|
location = / {
|
||||||
|
if ($http_user_agent ~ curl) {
|
||||||
|
rewrite / /TERMINAL last;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
41
package.json
41
package.json
@@ -1,19 +1,42 @@
|
|||||||
{
|
{
|
||||||
"name": "uechi.io",
|
"name": "hexo-site",
|
||||||
|
"version": "0.0.0",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"fix-typo": "textlint _posts/*.md _pages/*.md --fix --dry-run -f diff",
|
"build": "hexo generate",
|
||||||
"build": "bundle exec jekyll build",
|
"clean": "hexo clean",
|
||||||
"start": "bundle exec jekyll serve --host 0.0.0.0 --port 4000 --baseurl '' --force_polling --drafts --unpublished --incremental",
|
"deploy": "hexo deploy",
|
||||||
"test": "textlint _posts/*.md _pages/*.md -f pretty-error"
|
"start": "yarn clean && hexo server --debug",
|
||||||
|
"test": "lint-staged"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"hexo": "^6.0.0",
|
||||||
|
"hexo-excerpt": "^1.2.1",
|
||||||
|
"hexo-feed": "^1.1.0",
|
||||||
|
"hexo-filter-mathjax": "^0.8.0",
|
||||||
|
"hexo-generator-archive": "^1.0.0",
|
||||||
|
"hexo-generator-category": "^1.0.0",
|
||||||
|
"hexo-generator-index": "^2.0.0",
|
||||||
|
"hexo-generator-tag": "^1.0.0",
|
||||||
|
"hexo-renderer-ejs": "^2.0.0",
|
||||||
|
"hexo-renderer-pandoc": "^0.3.0",
|
||||||
|
"hexo-renderer-sass": "^0.4.0",
|
||||||
|
"hexo-renderer-stylus": "^2.0.0",
|
||||||
|
"hexo-server": "^3.0.0",
|
||||||
|
"hexo-theme-landscape": "^0.0.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"textlint": "^11.7.6",
|
"lint-staged": "^10.5.4",
|
||||||
|
"textlint": "^11.9.0",
|
||||||
"textlint-filter-rule-whitelist": "^2.0.0",
|
"textlint-filter-rule-whitelist": "^2.0.0",
|
||||||
"textlint-rule-common-misspellings": "^1.0.1",
|
"textlint-rule-common-misspellings": "^1.0.1",
|
||||||
"textlint-rule-max-ten": "^2.0.4",
|
|
||||||
"textlint-rule-no-dropping-the-ra": "^1.1.3",
|
|
||||||
"textlint-rule-no-start-duplicated-conjunction": "^2.0.2",
|
"textlint-rule-no-start-duplicated-conjunction": "^2.0.2",
|
||||||
"textlint-rule-preset-japanese": "^5.0.0"
|
"textlint-rule-preset-japanese": "^6.0.1"
|
||||||
|
},
|
||||||
|
"lint-staged": {
|
||||||
|
"*.md": "textlint"
|
||||||
|
},
|
||||||
|
"hexo": {
|
||||||
|
"version": "5.4.0"
|
||||||
},
|
},
|
||||||
"private": true
|
"private": true
|
||||||
}
|
}
|
||||||
|
4
scaffolds/draft.md
Normal file
4
scaffolds/draft.md
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
title: {{ title }}
|
||||||
|
tags:
|
||||||
|
---
|
3
scaffolds/page.md
Normal file
3
scaffolds/page.md
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
---
|
||||||
|
title: {{ title }}
|
||||||
|
---
|
5
scaffolds/post.md
Normal file
5
scaffolds/post.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
title: {{ title }}
|
||||||
|
date: {{ date }}
|
||||||
|
tags:
|
||||||
|
---
|
7
source/404.md
Normal file
7
source/404.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
title: Page Not Found
|
||||||
|
permalink: "/404"
|
||||||
|
---
|
||||||
|
|
||||||
|
> `404`
|
||||||
|
> This page could not be found
|
8
source/TERMINAL
Normal file
8
source/TERMINAL
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
|
||||||
|
░█░█░█▀▀░█▀▀░█░█░▀█▀░░░░▀█▀░█▀█
|
||||||
|
░█░█░█▀▀░█░░░█▀█░░█░░░░░░█░░█░█
|
||||||
|
░▀▀▀░▀▀▀░▀▀▀░▀░▀░▀▀▀░▀░░▀▀▀░▀▀▀
|
||||||
|
|
||||||
|
GitHub: https://github.com/uetchy
|
||||||
|
Twitter: https://twitter.com/uechz
|
||||||
|
Wallpaper: https://uechi.io/wallpaper
|
@@ -132,7 +132,7 @@ Notes.app に移行しました。
|
|||||||
|
|
||||||
## Flash
|
## Flash
|
||||||
|
|
||||||
ニコニコ動画が見れなくなるので泣く泣く導入していましたが、公式で HTML5 に対応したので不要になりました。
|
ニコニコ動画が見られなくなるので泣く泣く導入していましたが、公式で HTML5 に対応したので不要になりました。
|
||||||
|
|
||||||
## [VirtualBox](https://www.virtualbox.org)
|
## [VirtualBox](https://www.virtualbox.org)
|
||||||
|
|
@@ -4,9 +4,19 @@ date: 2017-06-16 00:00:00 +09:00
|
|||||||
redirect_from: "/blog/2017/06/16/x11forward"
|
redirect_from: "/blog/2017/06/16/x11forward"
|
||||||
---
|
---
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
## Ubuntu 16.04
|
# Installation
|
||||||
|
|
||||||
|
## Remote
|
||||||
|
|
||||||
|
### Arch Linux
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pacman -S xorg-xauth xorg-fonts-100dpi xorg-xeyes
|
||||||
|
```
|
||||||
|
|
||||||
|
### Ubuntu 16.04
|
||||||
|
|
||||||
Make sure you have installed SSH, X11 and xAuth on a remote server.
|
Make sure you have installed SSH, X11 and xAuth on a remote server.
|
||||||
|
|
||||||
@@ -16,12 +26,12 @@ sudo sed -i '/ForwardX11/s/.*/ForwardX11 yes/' /etc/ssh/sshd_config
|
|||||||
sudo service ssh restart
|
sudo service ssh restart
|
||||||
```
|
```
|
||||||
|
|
||||||
## macOS Sierra
|
## Client (macOS Big Sur)
|
||||||
|
|
||||||
You also need to have X11 on your local machine.
|
You also need to have X11 on your local machine.
|
||||||
|
|
||||||
```
|
```
|
||||||
brew cask install xquartz # install X11
|
brew install xquartz # install X11
|
||||||
ssh -X <remote>
|
ssh -X <remote>
|
||||||
$ xeyes # verify you have X11
|
$ xeyes # verify you have X11
|
||||||
```
|
```
|
@@ -1,7 +1,8 @@
|
|||||||
---
|
---
|
||||||
title: 初キャンプに必要な機材
|
title: 初キャンプに必要な機材
|
||||||
date: 2018-04-13 14:26:00 +09:00
|
date: 2018-04-13 14:26:00 +09:00
|
||||||
redirect_from: "/blog/2018/04/13/camping"
|
redirect_from:
|
||||||
|
- "/blog/2018/04/13/camping"
|
||||||
---
|
---
|
||||||
|
|
||||||
先月、大洗で初めてのキャンプ泊をした。
|
先月、大洗で初めてのキャンプ泊をした。
|
@@ -3,11 +3,11 @@ title: Know your deps on package.json in seconds
|
|||||||
date: 2018-09-02 03:23:00 +09:00
|
date: 2018-09-02 03:23:00 +09:00
|
||||||
---
|
---
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
How do you know what packages that project/library depend on and what exactly are that packages doing for?
|
How do you know what packages that project/library depend on and what exactly are that packages doing for?
|
||||||
You'll want to quickly survey on them. So [npm-deps-list](https://github.com/uetchy/npm-deps-list) is here for.
|
You'll want to quickly survey on them. So [npm-deps-list](https://github.com/uetchy/npm-deps-list) is here for.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
You can install them using `npm` or `yarn`.
|
You can install them using `npm` or `yarn`.
|
||||||
|
|
||||||
```bash
|
```bash
|
84
source/_posts/2018/life-automation.md
Normal file
84
source/_posts/2018/life-automation.md
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
---
|
||||||
|
title: 生活の自動化
|
||||||
|
date: 2018-08-05 00:00:00 +09:00
|
||||||
|
redirect_from: "/blog/2018/08/05/life-automation"
|
||||||
|
---
|
||||||
|
|
||||||
|
生活にオートメーションを上手く取り入れ、本当にやりたいことに集中できる環境をつくりましょう。
|
||||||
|
|
||||||
|
# 洗濯の自動化
|
||||||
|
|
||||||
|
Panasonic のドラム洗濯乾燥機を使っています。威力を最大限に享受するため、タンブラー乾燥向けの普段着を揃えておくことも重要です。
|
||||||
|
|
||||||
|
洗剤は粉と液体とが一体化したジェルボール洗剤が便利です。ドラムの底にひとつ置くだけでよく、計量する必要がありません。
|
||||||
|
|
||||||
|
# 食器洗いの自動化
|
||||||
|
|
||||||
|
Panasonic の一人暮らし用コンパクト食洗乾燥機を使っています。
|
||||||
|
洗濯機と同じく、食洗機専用のジェルボール洗剤を使えば計量する手間を省けます。
|
||||||
|
|
||||||
|
# 照明の自動化
|
||||||
|
|
||||||
|
Philips Hue はインターネット経由で明るさや色相をコントロールすることができる電球です。
|
||||||
|
|
||||||
|
- 「家から離れたら消灯」
|
||||||
|
- 「家に近付いたら点灯」
|
||||||
|
- 「日が暮れたら暖色系に切り替える」
|
||||||
|
- 「23 時になったら消灯」
|
||||||
|
|
||||||
|
など多様なルールを作ることができます。外の明るさに合わせて照明の明るさを調整して、概日リズムが崩れにくいようルールを決めています。
|
||||||
|
|
||||||
|
# 空調の自動化
|
||||||
|
|
||||||
|
Nature Remo でエアコンの操作を自動化しました。
|
||||||
|
|
||||||
|
- 「湿度が高ければドライに変更」
|
||||||
|
- 「家から離れたら電源オフ」
|
||||||
|
- 「朝になったら冷房へ切り替え」
|
||||||
|
|
||||||
|
など多様なルールを作ることができます。
|
||||||
|
|
||||||
|
Nature Remo 自体はエアコン専用ではなく、赤外線で操作出来るデバイスであればなんでも操作できます。家ではテレビの電源・音量もこれで操作しています。
|
||||||
|
|
||||||
|
[Nature Remo を NodeJS で操作するライブラリ](https://github.com/uetchy/nature-remo)を作ったので触ってみてください。ライブラリ経由で温度・湿度・明度のセンサー値を取得したり、指定したモードにエアコンを切り替えることができます。
|
||||||
|
|
||||||
|
# 自動施錠・自動開錠
|
||||||
|
|
||||||
|
Qrio Lock をドアに取り付けることでオートロック・アンロックができるようになりました。
|
||||||
|
|
||||||
|
エントランスのドアに関しては、インターホンに Switch Bot を貼り付けて Shortcuts で解錠できるようにしておき、それを iPhone の背面トリプルタップで呼び出せるよう設定することでキーレスエントリー化しています。
|
||||||
|
|
||||||
|
# ホームアシスタント
|
||||||
|
|
||||||
|
Raspberry Pi に Home Assistant をインストールし、スマート家電を取りまとめるアシスタントとして使っています。Nature Remo や Hue、Switch Bot に紐づいているデバイスを Home Assistant のアプリからまとめて操作できます。
|
||||||
|
|
||||||
|
Apple Home より柔軟な自動化ルールを作ることができ、例えば「朝になったら照明とエアコンをつける(気温が高くかつ誰かが家にいる場合のみ)」といった気の利いた自動化ができます。
|
||||||
|
|
||||||
|
# 睡眠記録の自動化
|
||||||
|
|
||||||
|
Withings 改め Nokia 改め Withings の Sleep を使っています。
|
||||||
|
寝るとき身体にウェアラブルデバイスを身につけたくないので、マットレスの下に敷いておくだけで自動計測してくれるのはありがたいです。
|
||||||
|
|
||||||
|
機能としては、入眠・起床検知、心拍数記録、睡眠深度解析、いびき検出等があります。
|
||||||
|
|
||||||
|
# 体重記録の自動化
|
||||||
|
|
||||||
|
Withings の Wi-Fi Scale を使っています。体重と体脂肪率、心拍数、BMI を Wi-Fi 経由でクラウドに自動記録し、アプリで推移を確認できます。
|
||||||
|
|
||||||
|
Wi-Fi Scale には CO2 センサーもついており、部屋の二酸化炭素濃度を記録してくれます。
|
||||||
|
|
||||||
|
# オンラインスーパー
|
||||||
|
|
||||||
|
普段は業務スーパーを使いつつ、重くて量のある商品に関してはイトーヨーカドーのオンラインスーパーに頼っています。
|
||||||
|
|
||||||
|
お気に入りリストへ水、米、卵、かぼちゃなど毎回買うものを登録しておくことで、慣れれば 5 分程度で注文が完了します。あとは指定した時間に家へ商品を届けてくれます。
|
||||||
|
|
||||||
|
# 自動家計簿
|
||||||
|
|
||||||
|
Moneytree を使っています。支出を自動で食費、趣味、日用品などに仕分けてくれるため、使いすぎに気付きやすいです。無現金縛りプレイと相性が良いです。
|
||||||
|
|
||||||
|
# 気になる製品
|
||||||
|
|
||||||
|
## ルンバ
|
||||||
|
|
||||||
|
絨毯を取り除くわけにもいかないので二の足を踏んでいます。ルンバについては[KainokiKaede's diary](http://kainokikaede.hatenablog.com/entry/2018/07/24/185452)の記事を読んでください。
|
@@ -2,8 +2,10 @@
|
|||||||
title: 英語メモ
|
title: 英語メモ
|
||||||
date: 2019-01-17T10:31:00.000+00:00
|
date: 2019-01-17T10:31:00.000+00:00
|
||||||
redirect_from: "/blog/2019/01/17/english-note"
|
redirect_from: "/blog/2019/01/17/english-note"
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
雑多なメモです。
|
||||||
|
|
||||||
- spin up - 立ち上げる
|
- spin up - 立ち上げる
|
||||||
- woe - 悲しみ
|
- woe - 悲しみ
|
||||||
- a little too - 少し〜すぎる
|
- a little too - 少し〜すぎる
|
||||||
@@ -94,8 +96,6 @@ redirect_from: "/blog/2019/01/17/english-note"
|
|||||||
|
|
||||||
> It uses the definite article before "majority of the students", as if referring to a known group.
|
> It uses the definite article before "majority of the students", as if referring to a known group.
|
||||||
|
|
||||||
> Next piece is gonna be a super mega holy shit giantess 👍👍👍
|
|
||||||
|
|
||||||
> This sentence uses the indefinite article before the "majority of the students". This has the effect of introducing this group of students to the reader or the listener.
|
> This sentence uses the indefinite article before the "majority of the students". This has the effect of introducing this group of students to the reader or the listener.
|
||||||
|
|
||||||
> It may give a hint that the exact number of the students that will vote is uncertain: it could be 51%, but then it could be 88%.
|
> It may give a hint that the exact number of the students that will vote is uncertain: it could be 51%, but then it could be 88%.
|
||||||
@@ -125,7 +125,7 @@ redirect_from: "/blog/2019/01/17/english-note"
|
|||||||
|
|
||||||
> learning foreign languages is for me lifelong hobby. knowledge likely to requires much time to acquiring but it never decays.
|
> learning foreign languages is for me lifelong hobby. knowledge likely to requires much time to acquiring but it never decays.
|
||||||
|
|
||||||
> *sees client, whistles loudly*
|
> _sees client, whistles loudly_
|
||||||
|
|
||||||
> weston comes out of nowhere running on all fours like a gorilla towards client
|
> weston comes out of nowhere running on all fours like a gorilla towards client
|
||||||
|
|
@@ -4,16 +4,18 @@ date: 2019-01-14 00:00:00 +09:00
|
|||||||
redirect_from: "/blog/2019/01/14/padsize"
|
redirect_from: "/blog/2019/01/14/padsize"
|
||||||
---
|
---
|
||||||
|
|
||||||
|
padStart における padSize の求め方です。
|
||||||
|
|
||||||
$$
|
$$
|
||||||
\textrm{padSize} = \lceil \log_{10}(\mathbf{arraySize} + 1) \rceil
|
\textrm{padSize} = \lceil \log_{10}(\mathbf{arraySize} + 1) \rceil
|
||||||
$$
|
$$
|
||||||
|
|
||||||
```js
|
```js
|
||||||
const padSize = Math.ceil(Math.log10(arr.length + 1))
|
const padSize = Math.ceil(Math.log10(arr.length + 1));
|
||||||
|
|
||||||
arr.forEach((item, index) => {
|
arr.forEach((item, index) => {
|
||||||
console.log(`${index.padStart(padSize, '0')}: ${item}`)
|
console.log(`${index.padStart(padSize, "0")}: ${item}`);
|
||||||
})
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
結果は以下のようになる。
|
結果は以下のようになる。
|
@@ -21,14 +21,14 @@ electron-builder を利用して macOS 向け Electron アプリをコード署
|
|||||||
コード署名済みのアプリを[electron-notarize](https://github.com/electron-userland/electron-notarize)を使用して Apple Notary Service に提出します。
|
コード署名済みのアプリを[electron-notarize](https://github.com/electron-userland/electron-notarize)を使用して Apple Notary Service に提出します。
|
||||||
|
|
||||||
```js
|
```js
|
||||||
const { notarize } = require('electron-notarize')
|
const { notarize } = require("electron-notarize");
|
||||||
notarize({
|
notarize({
|
||||||
appBundleId,
|
appBundleId,
|
||||||
appPath,
|
appPath,
|
||||||
appleId,
|
appleId,
|
||||||
appleIdPassword,
|
appleIdPassword,
|
||||||
ascProvider,
|
ascProvider,
|
||||||
})
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
- **appBundleId**: アプリの Bundle ID です。`package.json`の`build.appId`と同じものを使います。
|
- **appBundleId**: アプリの Bundle ID です。`package.json`の`build.appId`と同じものを使います。
|
||||||
@@ -44,33 +44,33 @@ electron-builder の afterSign フックを使用して、コード署名が済
|
|||||||
フックスクリプトを`./scripts/after-sign-mac.js`に置きます。
|
フックスクリプトを`./scripts/after-sign-mac.js`に置きます。
|
||||||
|
|
||||||
```js
|
```js
|
||||||
const path = require('path')
|
const path = require("path");
|
||||||
const { notarize } = require('electron-notarize')
|
const { notarize } = require("electron-notarize");
|
||||||
|
|
||||||
const appleId = process.env.APPLE_ID
|
const appleId = process.env.APPLE_ID;
|
||||||
const appleIdPassword = process.env.APPLE_PASSWORD
|
const appleIdPassword = process.env.APPLE_PASSWORD;
|
||||||
const ascProvider = process.env.ASC_PROVIDER
|
const ascProvider = process.env.ASC_PROVIDER;
|
||||||
|
|
||||||
const configPath = path.resolve(__dirname, '../package.json')
|
const configPath = path.resolve(__dirname, "../package.json");
|
||||||
const appPath = path.resolve(__dirname, '../dist/mac/App.app')
|
const appPath = path.resolve(__dirname, "../dist/mac/App.app");
|
||||||
const config = require(configPath)
|
const config = require(configPath);
|
||||||
const appBundleId = config.build.appId
|
const appBundleId = config.build.appId;
|
||||||
|
|
||||||
async function notarizeApp() {
|
async function notarizeApp() {
|
||||||
console.log(`afterSign: Notarizing ${appBundleId} in ${appPath}`)
|
console.log(`afterSign: Notarizing ${appBundleId} in ${appPath}`);
|
||||||
await notarize({
|
await notarize({
|
||||||
appBundleId,
|
appBundleId,
|
||||||
appPath,
|
appPath,
|
||||||
appleId,
|
appleId,
|
||||||
appleIdPassword,
|
appleIdPassword,
|
||||||
ascProvider,
|
ascProvider,
|
||||||
})
|
});
|
||||||
console.log('afterSign: Notarized')
|
console.log("afterSign: Notarized");
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.default = async () => {
|
exports.default = async () => {
|
||||||
await notarizeApp()
|
await notarizeApp();
|
||||||
}
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
`package.json`の`build`に`afterSign`を追加してコード署名が終わった後にスクリプトが実行されるようにします。
|
`package.json`の`build`に`afterSign`を追加してコード署名が終わった後にスクリプトが実行されるようにします。
|
@@ -7,9 +7,7 @@ date: 2019-10-03 17:21:00 +09:00
|
|||||||
|
|
||||||
ベンチマーク用の TypeScript プログラムを用意します。
|
ベンチマーク用の TypeScript プログラムを用意します。
|
||||||
|
|
||||||
#### `a.ts`
|
```ts a.ts
|
||||||
|
|
||||||
```ts
|
|
||||||
function a() {
|
function a() {
|
||||||
const noise = Math.random() - 0.5;
|
const noise = Math.random() - 0.5;
|
||||||
const offset = 1.0;
|
const offset = 1.0;
|
||||||
@@ -19,9 +17,7 @@ function a() {
|
|||||||
a();
|
a();
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `b.ts`
|
```ts b.ts
|
||||||
|
|
||||||
```ts
|
|
||||||
function b() {
|
function b() {
|
||||||
const noise = Math.random() - 0.5;
|
const noise = Math.random() - 0.5;
|
||||||
const offset = 2.0;
|
const offset = 2.0;
|
||||||
@@ -37,9 +33,9 @@ b();
|
|||||||
hyperfine 'ts-node a.ts' 'ts-node b.ts' -r 50 --warmup 3 --export-json ab.json
|
hyperfine 'ts-node a.ts' 'ts-node b.ts' -r 50 --warmup 3 --export-json ab.json
|
||||||
```
|
```
|
||||||
|
|
||||||
`result.json`の中身以下のようになります。
|
`result.json`の中身は以下のようになります。
|
||||||
|
|
||||||
```json
|
```json result.json
|
||||||
{
|
{
|
||||||
"results": [
|
"results": [
|
||||||
{
|
{
|
||||||
@@ -87,8 +83,8 @@ hyperfine 'ts-node a.ts' 'ts-node b.ts' -r 50 --warmup 3 --export-json ab.json
|
|||||||
この`result.json`の`times`配列を受け取り、2 つの分布間に有意差があるかどうかを判定します。
|
この`result.json`の`times`配列を受け取り、2 つの分布間に有意差があるかどうかを判定します。
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
import fs from 'fs';
|
import fs from "fs";
|
||||||
import {jStat} from 'jstat';
|
import { jStat } from "jstat";
|
||||||
|
|
||||||
const log = console.log;
|
const log = console.log;
|
||||||
|
|
||||||
@@ -127,7 +123,7 @@ const Y = result.results[1].times;
|
|||||||
const p = ttest(X, Y);
|
const p = ttest(X, Y);
|
||||||
log(`p = ${p}`);
|
log(`p = ${p}`);
|
||||||
log(`p < 0.05 = ${p < 0.05}`);
|
log(`p < 0.05 = ${p < 0.05}`);
|
||||||
log(p < 0.05 ? 'Possibly some difference there' : 'No difference');
|
log(p < 0.05 ? "Possibly some difference there" : "No difference");
|
||||||
```
|
```
|
||||||
|
|
||||||
ここで`X_mu`は分布 X の平均、`X_sigma`は分布 X の不偏分散です。
|
ここで`X_mu`は分布 X の平均、`X_sigma`は分布 X の不偏分散です。
|
@@ -1,8 +1,8 @@
|
|||||||
---
|
---
|
||||||
title: Securing Local Dev Server
|
title: Securing Local Dev Server
|
||||||
date: 2020-02-07 00:00:00 +0900
|
date: 2020-02-07 00:00:00 +0900
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
Sometimes you want to interact with a local webserver with https support because of some browser APIs that are only available in an https environment.
|
Sometimes you want to interact with a local webserver with https support because of some browser APIs that are only available in an https environment.
|
||||||
|
|
||||||
You can easily create a self-signed TLS cert for development purposes with [`mkcert`](https://github.com/FiloSottile/mkcert).
|
You can easily create a self-signed TLS cert for development purposes with [`mkcert`](https://github.com/FiloSottile/mkcert).
|
155
source/_posts/2021/affinity-thumbnail.md
Normal file
155
source/_posts/2021/affinity-thumbnail.md
Normal file
@@ -0,0 +1,155 @@
|
|||||||
|
---
|
||||||
|
title: Distill Thumbnail from .afphoto and .afdesign
|
||||||
|
date: 2021-02-14T13:30:00
|
||||||
|
---
|
||||||
|
|
||||||
|
Nextcloud does not have support for generating thumbnails from Affinity Photo and Affinity Design. Fine, I'll do it myself.
|
||||||
|
|
||||||
|
# Digging Binary
|
||||||
|
|
||||||
|
Glancing at `.afphoto` and `.afdesign` in Finder, I noticed that it has a QuickLook support and an ability to show the thumbnail image. So these files should have thumbnail image somewhere inside its binary.
|
||||||
|
|
||||||
|
I wrote a piece of Node.js script to seek for [PNG signature](https://www.w3.org/TR/PNG/) inside a binary and save it as an image file.
|
||||||
|
|
||||||
|
```js afthumb.js
|
||||||
|
const fs = require("fs");
|
||||||
|
|
||||||
|
// png spec: https://www.w3.org/TR/PNG/
|
||||||
|
const PNG_SIG = Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]);
|
||||||
|
const IEND_SIG = Buffer.from([73, 69, 78, 68]);
|
||||||
|
|
||||||
|
function extractThumbnail(buf) {
|
||||||
|
const start = buf.indexOf(PNG_SIG);
|
||||||
|
const end = buf.indexOf(IEND_SIG, start) + IEND_SIG.length * 2; // IEND + CRC
|
||||||
|
return buf.subarray(start, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
function generateThumbnail(input, output) {
|
||||||
|
const buf = fs.readFileSync(input);
|
||||||
|
const thumbBuf = extractThumbnail(buf);
|
||||||
|
fs.writeFileSync(output, thumbBuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
generateThumbnail(process.argv[2], process.argv[3] || "output.png");
|
||||||
|
```
|
||||||
|
|
||||||
|
That's right. This script just scrapes a binary file and distill a portion of which starts with `PNG` signature and ends with `IEND`.
|
||||||
|
|
||||||
|
Now I can generate a thumbnail image from arbitrary `.afphoto` and `.afdesign` file. Let's move on delving into Nextcloud source code.
|
||||||
|
|
||||||
|
# Tweaking Nextcloud
|
||||||
|
|
||||||
|
I have a bit of experience in tweaking Nextcloud source code before, where I implemented thumbnail generator for PDFs, so it should be easier this time, hopefully.
|
||||||
|
|
||||||
|
Long story short, I got Nextcloud generates thumbnail images for Affinity files by implementing `ProviderV2` class.
|
||||||
|
|
||||||
|
```php lib/private/Preview/Affinity.php
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace OC\Preview;
|
||||||
|
|
||||||
|
use OCP\Files\File;
|
||||||
|
use OCP\IImage;
|
||||||
|
use OCP\ILogger;
|
||||||
|
|
||||||
|
class Affinity extends ProviderV2 {
|
||||||
|
public function getMimeType(): string {
|
||||||
|
return '/application\/x-affinity-(?:photo|design)/';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getThumbnail(File $file, int $maxX, int $maxY): ?IImage {
|
||||||
|
$tmpPath = $this->getLocalFile($file);
|
||||||
|
|
||||||
|
$handle = fopen($tmpPath, 'rb');
|
||||||
|
$fsize = filesize($tmpPath);
|
||||||
|
$contents = fread($handle, $fsize);
|
||||||
|
$start = strrpos($contents, "\x89PNG");
|
||||||
|
$end = strrpos($contents, "IEND", $start);
|
||||||
|
$subarr = substr($contents, $start, $end - $start + 8 );
|
||||||
|
|
||||||
|
fclose($handle);
|
||||||
|
$this->cleanTmpFiles();
|
||||||
|
|
||||||
|
$image = new \OC_Image();
|
||||||
|
$image->loadFromData($subarr);
|
||||||
|
$image->scaleDownToFit($maxX, $maxY);
|
||||||
|
|
||||||
|
return $image->valid() ? $image : null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```patch lib/private/PreviewManager.php
|
||||||
|
@@ -363,6 +365,8 @@
|
||||||
|
$this->registerCoreProvider(Preview\Krita::class, '/application\/x-krita/');
|
||||||
|
$this->registerCoreProvider(Preview\MP3::class, '/audio\/mpeg/');
|
||||||
|
$this->registerCoreProvider(Preview\OpenDocument::class, '/application\/vnd.oasis.opendocument.*/');
|
||||||
|
+ $this->registerCoreProvider(Preview\Affinity::class, '/application\/x-affinity-(?:photo|design)/');
|
||||||
|
|
||||||
|
// SVG, Office and Bitmap require imagick
|
||||||
|
if (extension_loaded('imagick')) {
|
||||||
|
```
|
||||||
|
|
||||||
|
```patch lib/composer/composer/autoload_static.php
|
||||||
|
@@ -1226,6 +1226,7 @@
|
||||||
|
'OC\\OCS\\Result' => __DIR__ . '/../../..' . '/lib/private/OCS/Result.php',
|
||||||
|
'OC\\PreviewManager' => __DIR__ . '/../../..' . '/lib/private/PreviewManager.php',
|
||||||
|
'OC\\PreviewNotAvailableException' => __DIR__ . '/../../..' . '/lib/private/PreviewNotAvailableException.php',
|
||||||
|
+ 'OC\\Preview\\Affinity' => __DIR__ . '/../../..' . '/lib/private/Preview/Affinity.php',
|
||||||
|
'OC\\Preview\\BMP' => __DIR__ . '/../../..' . '/lib/private/Preview/BMP.php',
|
||||||
|
'OC\\Preview\\BackgroundCleanupJob' => __DIR__ . '/../../..' . '/lib/private/Preview/BackgroundCleanupJob.php',
|
||||||
|
'OC\\Preview\\Bitmap' => __DIR__ . '/../../..' . '/lib/private/Preview/Bitmap.php',
|
||||||
|
```
|
||||||
|
|
||||||
|
```patch lib/composer/composer/autoload_classmap.php
|
||||||
|
@@ -1197,6 +1197,7 @@
|
||||||
|
'OC\\OCS\\Result' => $baseDir . '/lib/private/OCS/Result.php',
|
||||||
|
'OC\\PreviewManager' => $baseDir . '/lib/private/PreviewManager.php',
|
||||||
|
'OC\\PreviewNotAvailableException' => $baseDir . '/lib/private/PreviewNotAvailableException.php',
|
||||||
|
+ 'OC\\Preview\\Affinity' => $baseDir . '/lib/private/Preview/Affinity.php',
|
||||||
|
'OC\\Preview\\BMP' => $baseDir . '/lib/private/Preview/BMP.php',
|
||||||
|
'OC\\Preview\\BackgroundCleanupJob' => $baseDir . '/lib/private/Preview/BackgroundCleanupJob.php',
|
||||||
|
'OC\\Preview\\Bitmap' => $baseDir . '/lib/private/Preview/Bitmap.php',
|
||||||
|
```
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Easy-peasy!
|
||||||
|
|
||||||
|
# Bonus: PDF thumbnail generator
|
||||||
|
|
||||||
|
Install `ghostscript` on your server to make it work.
|
||||||
|
|
||||||
|
```php lib/private/Preview/PDF.php
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace OC\Preview;
|
||||||
|
|
||||||
|
use OCP\Files\File;
|
||||||
|
use OCP\IImage;
|
||||||
|
|
||||||
|
class PDF extends ProviderV2 {
|
||||||
|
public function getMimeType(): string {
|
||||||
|
return '/application\/pdf/';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getThumbnail(File $file, int $maxX, int $maxY): ?IImage {
|
||||||
|
$tmpPath = $this->getLocalFile($file);
|
||||||
|
$outputPath = \OC::$server->getTempManager()->getTemporaryFile();
|
||||||
|
|
||||||
|
$gsBin = \OC_Helper::findBinaryPath('gs');
|
||||||
|
$cmd = $gsBin . " -o " . escapeshellarg($outputPath) . " -sDEVICE=jpeg -sPAPERSIZE=a4 -dLastPage=1 -dPDFFitPage -dJPEGQ=90 -r144 " . escapeshellarg($tmpPath);
|
||||||
|
shell_exec($cmd);
|
||||||
|
|
||||||
|
$this->cleanTmpFiles();
|
||||||
|
|
||||||
|
$image = new \OC_Image();
|
||||||
|
$image->loadFromFile($outputPath);
|
||||||
|
$image->scaleDownToFit($maxX, $maxY);
|
||||||
|
|
||||||
|
unlink($outputPath);
|
||||||
|
|
||||||
|
return $image->valid() ? $image : null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
BIN
source/_posts/2021/affinity-thumbnail/afphoto.png
Normal file
BIN
source/_posts/2021/affinity-thumbnail/afphoto.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 437 KiB |
18
source/_posts/2021/braille.md
Normal file
18
source/_posts/2021/braille.md
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
---
|
||||||
|
title: 点字の表現力
|
||||||
|
date: 2021-02-13T01:00:00
|
||||||
|
---
|
||||||
|
|
||||||
|
「n 種類の文字を表現できる点字を作らないといけなくなったらどうしよう」
|
||||||
|
|
||||||
|
例としてドット が 3 つの点字を用意した。
|
||||||
|
|
||||||
|
- 組み合わせ数は 3P3 + 3P2 + 3P1
|
||||||
|
- $f(N) = \sum_{K=N → 1} N P K$
|
||||||
|
- 2 の n 乗っぽい
|
||||||
|
- べき集合の濃度?
|
||||||
|
- 2 進数のブール配列と考えればわかりやすくなった
|
||||||
|
- ということは X 個の表現をするために必要なブール配列の長さは $\lceil\log_2 (X)\rceil$
|
||||||
|
- 例えばアルファベットなら 6 ドットの点字で表現できる
|
||||||
|
- だから英語の点字は 6 つの点で構成されている
|
||||||
|
- 点字を 18 ドットに拡張すれば Unicode 13.0 の文字すべてを表現できる
|
128
source/_posts/2021/human-anatomy-atlas.md
Normal file
128
source/_posts/2021/human-anatomy-atlas.md
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
---
|
||||||
|
title: 解剖学アトラス
|
||||||
|
date: 2021-06-08T00:00:00
|
||||||
|
---
|
||||||
|
|
||||||
|
いつもの幅優先探索癖。アトラスの用途は美術解剖と消化器系の構造理解。
|
||||||
|
|
||||||
|
# ノート
|
||||||
|
|
||||||
|
肉眼解剖学はアプローチの違いから局所解剖学と系統解剖学に分けられる。
|
||||||
|
|
||||||
|
体表解剖は解剖学的構造と体表の特徴との関連を視覚的に理解するための節。
|
||||||
|
微視的レベルで観察する組織学—又の名を顕微鏡解剖学—が肉眼解剖学に対置する。
|
||||||
|
|
||||||
|
他にも、胚からの成長過程に着目する発生学、部位の機能を明らかにする生理学、物質代謝の機序に興味をおく生化学等が周辺にある。
|
||||||
|
|
||||||
|
テキスト、アトラス、カラーアトラスが一冊ずつあれば事足りそう。
|
||||||
|
個人的には『グレイ解剖学』、『ネッター解剖学アトラス』、『解剖学カラーアトラス』。
|
||||||
|
余裕があれば『プロメテウス解剖学アトラス 胸部/腹部・骨盤部』。
|
||||||
|
|
||||||
|
# 教科書
|
||||||
|
|
||||||
|
## グレイ解剖学 原著第 4 版
|
||||||
|
|
||||||
|
2019(原著 2018)
|
||||||
|
|
||||||
|
- 腹膜と腸間膜の節に限ってみても、筆者の「絶対にわからせる」という強い意志を感じさせる説明によって圧倒的にわからされてしまう
|
||||||
|
- 各章は概観、局所解剖、体表解剖、臨床症例から構成されている、肉眼解剖学に的を絞った本
|
||||||
|
- 腹腔・腹膜・腸間膜関連はプロメテウスより詳しい(特に一部腸管が二次的に腹膜後器官になる過程等)
|
||||||
|
- Meckel 憩室の臨床症例が写真とともに載っている
|
||||||
|
|
||||||
|
# アトラス
|
||||||
|
|
||||||
|
## ネッター解剖学アトラス 原著第 6 版
|
||||||
|
|
||||||
|
2016(原著 2014)
|
||||||
|
|
||||||
|
- 元々ノバルティスの販促のために描かれたイラストをまとめ上げたもの
|
||||||
|
- 組織と筋肉、血管、神経がまとまって描かれており、位置関係がわかりやすい
|
||||||
|
- 断面解剖の CT と図譜両方がある(プロメテウスは CT のみ)
|
||||||
|
- グラントと比べてカラフル
|
||||||
|
|
||||||
|
## グラント解剖学図譜 第 7 版
|
||||||
|
|
||||||
|
2016(原著 2013)
|
||||||
|
|
||||||
|
- イラストは立体感を把握しやすいタッチ
|
||||||
|
|
||||||
|
## プロメテウス解剖学アトラス 解剖学総論/運動器系 第 3 版
|
||||||
|
|
||||||
|
2017(原著 2014)
|
||||||
|
|
||||||
|
- 全身の骨格から筋肉、血管、神経、リンパ系が一通り概説されている
|
||||||
|
- ポージングの参考になる関節力学の知見が豊富
|
||||||
|
- 消化器系は解説なし
|
||||||
|
- 病例と診断方法、その施術指南が特徴
|
||||||
|
|
||||||
|
## プロメテウス解剖学アトラス 口腔・頭頸部 第 2 版
|
||||||
|
|
||||||
|
2018(原著 2015)
|
||||||
|
|
||||||
|
- 脳、頭部、口腔、頸部に絞って解説
|
||||||
|
- 口腔から食道、胃までの部分に関する記述が非常に豊富
|
||||||
|
- 歯科臨床を意識した紙面構成
|
||||||
|
- 口腔・頭頸部以外の部位についての説明もざっくりされている
|
||||||
|
|
||||||
|
## プロメテウス解剖学アトラス 胸部/腹部・骨盤部 第 3 版
|
||||||
|
|
||||||
|
2020(原著 2015)
|
||||||
|
|
||||||
|
- 胸部から腹部にかけて発生学・解剖学の図説が中心
|
||||||
|
- 食道の筋の機能的構造の図解など、グレイ解剖学には載っていない内容も多い
|
||||||
|
|
||||||
|
## プロメテウス解剖学 コアアトラス 第 3 版
|
||||||
|
|
||||||
|
2016
|
||||||
|
|
||||||
|
- プロメテウス 3 巻を一冊にまとめた本で、部位ごとに内容が集約されている
|
||||||
|
- 胃の解説に 2 ページしか割かれていないなど、情報が広く浅い
|
||||||
|
|
||||||
|
# カラーアトラス
|
||||||
|
|
||||||
|
## 解剖学カラーアトラス 第 8 版 A Photographic Atlas
|
||||||
|
|
||||||
|
2016(原著 2016)
|
||||||
|
|
||||||
|
- ほとんどがリアルな解剖写真
|
||||||
|
- 写真と共に図解イラストが対照されており理解が捗る
|
||||||
|
- 図とアノテーションしか無いため、機能理解は他の本に頼る必要がある
|
||||||
|
- ユニークな点として、胎児の矢状断面図が掲載されている
|
||||||
|
|
||||||
|
## 人体解剖カラーアトラス 原著第 8 版 Clinical Atlas of Human Anatomy
|
||||||
|
|
||||||
|
- こちらも基本的にアノテーションのみだが、注釈的説明が若干多め
|
||||||
|
- 解剖学カラーアトラスと比べて 140 ページ少ない
|
||||||
|
- 腹膜のヒダの写真はこちらにしか載っていない
|
||||||
|
|
||||||
|
# アプリ
|
||||||
|
|
||||||
|
## Human Anatomy Atlas
|
||||||
|
|
||||||
|
https://apps.apple.com/jp/app/human-anatomy-atlas-2021/id1117998129?l=en
|
||||||
|
|
||||||
|
- 毎年 11 月から 12 月頃にセールをしている
|
||||||
|
|
||||||
|
# Web サイト
|
||||||
|
|
||||||
|
- 1 年生の解剖学辞典 - https://anatomy1.net/
|
||||||
|
- 医学生の教科書 - https://store.isho.jp/
|
||||||
|
|
||||||
|
# 知見
|
||||||
|
|
||||||
|
- 食道は腰椎と胸大動脈の前方、気管と心臓の後方を通る
|
||||||
|
- 横隔膜のすぐ上方に心臓、すぐ下方に胃がある
|
||||||
|
- 食道の正常な内径は 20mm
|
||||||
|
- 食道には縦走ヒダが走っているが、Z 線を超えると胃底となり模様が変化する
|
||||||
|
- 噴門括約筋は横隔膜食道裂孔の筋肉が代行しており、ジグザグ状であるので Z 線と呼ばれている(リング状に筋肉が縮まるのではなく、ジグザグ状の縦筋が縮まることで噴門を締め上げている)→ プロメテウス胸部 p. 168
|
||||||
|
- 心臓はわずかに左にずれているため、左肺は右肺より小さい
|
||||||
|
- 憩室といえば大腸だと思っていたが、食道にも発生する → プロメテウス胸部 p. 169
|
||||||
|
- 「滑り説」筋収縮のメカニズムの学説のひとつ
|
||||||
|
|
||||||
|
# 用語
|
||||||
|
|
||||||
|
- 翻転(ほんてん) - 組織をひっくりかえすこと
|
||||||
|
- 腋窩(えきか)
|
||||||
|
- 網嚢孔(もうのうこう)
|
||||||
|
- 横紋筋(おうもんきん)と平滑筋(へいかつきん)
|
||||||
|
- 蠕動運動(ぜんどう—)
|
869
source/_posts/2021/installing-arch-linux.md
Normal file
869
source/_posts/2021/installing-arch-linux.md
Normal file
@@ -0,0 +1,869 @@
|
|||||||
|
---
|
||||||
|
title: Comprehensive Guide for Setting Up Arch Linux
|
||||||
|
date: 2021-02-12T00:00:00
|
||||||
|
---
|
||||||
|
|
||||||
|
This note includes all commands I typed when I set up Arch Linux on my new server.
|
||||||
|
|
||||||
|
> PSA: I published a toolchain for building AUR packages in a clean-room docker container
|
||||||
|
> <https://github.com/uetchy/archpkgs>
|
||||||
|
|
||||||
|
# Setup
|
||||||
|
|
||||||
|
## Wipe whole disk
|
||||||
|
|
||||||
|
```bash
|
||||||
|
wipefs -a /dev/sda
|
||||||
|
```
|
||||||
|
|
||||||
|
## Create partition
|
||||||
|
|
||||||
|
```bash
|
||||||
|
parted
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
select /dev/sda
|
||||||
|
mktable gpt
|
||||||
|
mkpart EFI fat32 0 512MB # EFI
|
||||||
|
mkpart Arch ext4 512MB 100% # Arch
|
||||||
|
set 1 esp on # flag partition 1 as ESP
|
||||||
|
quit
|
||||||
|
```
|
||||||
|
|
||||||
|
## Install file-system
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mkfs.vfat -F 32 /dev/sda1 # EFI
|
||||||
|
mkfs.ext4 /dev/sda2 # Arch
|
||||||
|
|
||||||
|
e2fsck -cc -C 0 /dev/sda2 # fsck
|
||||||
|
```
|
||||||
|
|
||||||
|
## Mount disk
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mkdir -p /mnt/boot
|
||||||
|
mount /dev/sda2 /mnt
|
||||||
|
mount /dev/sda1 /mnt/boot
|
||||||
|
```
|
||||||
|
|
||||||
|
## Install base & Linux kernel
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# choose between 'linux' or 'linux-lts'
|
||||||
|
pacstrap /mnt base linux-lts linux-firmware
|
||||||
|
genfstab -U /mnt >> /mnt/etc/fstab
|
||||||
|
arch-chroot /mnt
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pacman -S reflector
|
||||||
|
reflector --protocol https --latest 30 --sort rate --save /etc/pacman.d/mirrorlist --verbose # optimize mirror list
|
||||||
|
```
|
||||||
|
|
||||||
|
## Install essentials
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pacman -S vim man-db man-pages git base-devel
|
||||||
|
```
|
||||||
|
|
||||||
|
## Locales
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
|
||||||
|
hwclock --systohc
|
||||||
|
vim /etc/locale.gen & locale-gen
|
||||||
|
echo "LANG=en_US.UTF-8" > /etc/locale.conf
|
||||||
|
```
|
||||||
|
|
||||||
|
## add fstab entries
|
||||||
|
|
||||||
|
```ini /etc/fstab
|
||||||
|
# backup
|
||||||
|
UUID=<UUID> /mnt/backup ext4 defaults 0 2
|
||||||
|
|
||||||
|
# archive (do not prevent boot even if fsck fails)
|
||||||
|
UUID=<UUID> /mnt/archive ext4 defaults,nofail,x-systemd.device-timeout=4 0 2
|
||||||
|
```
|
||||||
|
|
||||||
|
Find `<UUID>` from the output of `lsblk -f`.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
findmnt --verify --verbose # verify fstab
|
||||||
|
```
|
||||||
|
|
||||||
|
## Install bootloader
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pacman -S \
|
||||||
|
grub \
|
||||||
|
efibootmgr \
|
||||||
|
amd-ucode # AMD microcode
|
||||||
|
grub-install --target=x86_64-efi --efi-directory=/boot --bootloader-id=GRUB
|
||||||
|
|
||||||
|
vim /etc/default/grub
|
||||||
|
# GRUB_TIMEOUT=3
|
||||||
|
# GRUB_DISABLE_SUBMENU=y
|
||||||
|
grub-mkconfig -o /boot/grub/grub.cfg
|
||||||
|
```
|
||||||
|
|
||||||
|
- [GRUB/Tips and tricks - ArchWiki](https://wiki.archlinux.org/title/GRUB/Tips_and_tricks)
|
||||||
|
|
||||||
|
## Setup network
|
||||||
|
|
||||||
|
```bash
|
||||||
|
hostnamectl set-hostname takos
|
||||||
|
hostnamectl set-chassis server
|
||||||
|
```
|
||||||
|
|
||||||
|
```ini /etc/hosts
|
||||||
|
127.0.0.1 localhost
|
||||||
|
::1 localhost
|
||||||
|
127.0.0.1 takos
|
||||||
|
```
|
||||||
|
|
||||||
|
See https://systemd.network/systemd.network.html and https://wiki.archlinux.org/title/Systemd-networkd, and <https://blog.ivansmirnov.name/set-up-pihole-using-docker-macvlan-network/>.
|
||||||
|
|
||||||
|
```ini /etc/systemd/network/wired.network
|
||||||
|
[Match]
|
||||||
|
Name=enp5s0
|
||||||
|
|
||||||
|
[Network]
|
||||||
|
#DHCP=yes
|
||||||
|
Address=10.0.1.2/24
|
||||||
|
Gateway=10.0.1.1
|
||||||
|
DNS=10.0.1.100 # self-hosted DNS resolver
|
||||||
|
DNS=1.1.1.1 # Cloudflare for the fallback DNS server
|
||||||
|
MACVLAN=dns-shim # to handle local dns lookup to 10.0.1.100 which is managed by Docker macvlan driver
|
||||||
|
```
|
||||||
|
|
||||||
|
```ini /etc/systemd/network/dns-shim.netdev
|
||||||
|
# to handle local dns lookup to 10.0.1.100
|
||||||
|
[NetDev]
|
||||||
|
Name=dns-shim
|
||||||
|
Kind=macvlan
|
||||||
|
|
||||||
|
[MACVLAN]
|
||||||
|
Mode=bridge
|
||||||
|
```
|
||||||
|
|
||||||
|
```ini /etc/systemd/network/dns-shim.network
|
||||||
|
# to handle local dns lookup to 10.0.1.100
|
||||||
|
[Match]
|
||||||
|
Name=dns-shim
|
||||||
|
|
||||||
|
[Network]
|
||||||
|
IPForward=yes
|
||||||
|
|
||||||
|
[Address]
|
||||||
|
Address=10.0.1.103/32
|
||||||
|
Scope=link
|
||||||
|
|
||||||
|
[Route]
|
||||||
|
Destination=10.0.1.100/30
|
||||||
|
```
|
||||||
|
|
||||||
|
`ip` equivalent to the above config:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ip link add dns-shim link enp5s0 type macvlan mode bridge # add macvlan shim interface
|
||||||
|
ip a add 10.0.1.103/32 dev dns-shim # assign the interface an ip address
|
||||||
|
ip link set dns-shim up # enable the interface
|
||||||
|
ip route add 10.0.1.100/30 dev dns-shim # route macvlan subnet (.100 - .103) to the interface
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
systemctl enable --now systemd-networkd
|
||||||
|
networkctl status
|
||||||
|
ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf
|
||||||
|
|
||||||
|
# for self-hosted dns resolver
|
||||||
|
sed -r -i -e 's/#?DNSStubListener=yes/DNSStubListener=no/g' -e 's/#DNS=/DNS=10.0.1.100/g' /etc/systemd/resolved.conf
|
||||||
|
|
||||||
|
systemctl enable --now systemd-resolved
|
||||||
|
resolvectl status
|
||||||
|
resolvectl query ddg.gg
|
||||||
|
drill ddg.gg
|
||||||
|
```
|
||||||
|
|
||||||
|
If `networkctl` keep showing `enp5s0` as `degraded`, then run `ip addr add 10.0.1.2/24 dev enp5s0 ` to manually assign static IP address for the workaround.
|
||||||
|
|
||||||
|
## Finalize
|
||||||
|
|
||||||
|
```bash
|
||||||
|
exit # leave chroot
|
||||||
|
umount -R /mnt
|
||||||
|
reboot
|
||||||
|
```
|
||||||
|
|
||||||
|
## NTP
|
||||||
|
|
||||||
|
```bash
|
||||||
|
timedatectl set-ntp true
|
||||||
|
timedatectl status
|
||||||
|
```
|
||||||
|
|
||||||
|
## Shell
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pacman -S zsh
|
||||||
|
chsh -s /bin/zsh
|
||||||
|
git clone https://github.com/uetchy/dotfiles ~/.dotfiles
|
||||||
|
yay -S ruby pyenv exa antibody direnv fd ripgrep fzy peco ghq-bin hub neofetch tmux git-delta lazygit jq lostfiles ncdu htop rsync youtube-dl prettier tree age informant
|
||||||
|
usermod -aG informant <user>
|
||||||
|
cd ~/.dotfiles
|
||||||
|
./dot link zsh -f
|
||||||
|
reload
|
||||||
|
```
|
||||||
|
|
||||||
|
## Setup operator user (i.e. user without superuser privilege)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
passwd # change root passwd
|
||||||
|
|
||||||
|
useradd -m -s /bin/zsh <user> # add local user
|
||||||
|
passwd <user> # change local user password
|
||||||
|
|
||||||
|
userdbctl # verify users
|
||||||
|
userdbctl group # verify groups
|
||||||
|
|
||||||
|
pacman -S sudo
|
||||||
|
echo "%sudo ALL=(ALL) NOPASSWD:/usr/bin/pacman" > /etc/sudoers.d/pacman # allow users in sudo group to run pacman without password (optional)
|
||||||
|
groupadd sudo
|
||||||
|
usermod -aG sudo <user> # add local user to sudo group
|
||||||
|
visudo -c
|
||||||
|
```
|
||||||
|
|
||||||
|
## SSH
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pacman -S openssh
|
||||||
|
vim /etc/ssh/sshd_config
|
||||||
|
systemctl enable --now sshd
|
||||||
|
```
|
||||||
|
|
||||||
|
on the host machine:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ssh-copy-id <user>@<ip>
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash:$HOME/.ssh/rc
|
||||||
|
if [ ! -S ~/.ssh/ssh_auth_sock ] && [ -S "$SSH_AUTH_SOCK" ]; then
|
||||||
|
ln -sf $SSH_AUTH_SOCK ~/.ssh/ssh_auth_sock
|
||||||
|
fi
|
||||||
|
```
|
||||||
|
|
||||||
|
See also: [Happy ssh agent forwarding for tmux/screen · Reboot and Shine](https://werat.dev/blog/happy-ssh-agent-forwarding/)
|
||||||
|
|
||||||
|
## AUR
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://aur.archlinux.org/yay.git
|
||||||
|
cd yay
|
||||||
|
makepkg -si
|
||||||
|
```
|
||||||
|
|
||||||
|
## S.M.A.R.T.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pacman -S smartmontools
|
||||||
|
systemctl enable --now smartd
|
||||||
|
|
||||||
|
smartctl -t short /dev/sda
|
||||||
|
smartctl -l selftest /dev/sda
|
||||||
|
```
|
||||||
|
|
||||||
|
## NVIDIA drivers
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pacman -S nvidia-lts # 'nvidia' for 'linux' package
|
||||||
|
reboot
|
||||||
|
nvidia-smi # test runtime
|
||||||
|
```
|
||||||
|
|
||||||
|
## Docker
|
||||||
|
|
||||||
|
https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/arch-overview.html
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pacman -S docker docker-compose
|
||||||
|
yay -S nvidia-container-runtime
|
||||||
|
systemctl enable --now docker
|
||||||
|
```
|
||||||
|
|
||||||
|
```json /etc/docker/daemon.json
|
||||||
|
{
|
||||||
|
"log-driver": "json-file",
|
||||||
|
"log-opts": {
|
||||||
|
"max-size": "10m", // default: -1 (unlimited)
|
||||||
|
"max-file": "3" // default: 1
|
||||||
|
},
|
||||||
|
"runtimes": {
|
||||||
|
// for docker-compose
|
||||||
|
"nvidia": {
|
||||||
|
"path": "/usr/bin/nvidia-container-runtime",
|
||||||
|
"runtimeArgs": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
systemctl restart docker
|
||||||
|
|
||||||
|
usermod -aG docker <user>
|
||||||
|
|
||||||
|
# to create mandatory device files on /dev
|
||||||
|
docker run --gpus all nvidia/cuda:10.2-cudnn7-runtime nvidia-smi
|
||||||
|
|
||||||
|
GPU_OPTS=(--gpus all --device /dev/nvidia0 --device /dev/nvidiactl --device /dev/nvidia-modeset --device /dev/nvidia-uvm --device /dev/nvidia-uvm-tools)
|
||||||
|
docker run --rm -it ${GPU_OPTS} nvidia/cuda:10.2-cudnn7-runtime nvidia-smi
|
||||||
|
docker run --rm -it ${GPU_OPTS} tensorflow/tensorflow:1.14.0-gpu-py3 bash
|
||||||
|
|
||||||
|
docker create network webproxy
|
||||||
|
```
|
||||||
|
|
||||||
|
### Use `journald` log driver in Docker Compose
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
services:
|
||||||
|
web:
|
||||||
|
logging:
|
||||||
|
driver: "journald"
|
||||||
|
options:
|
||||||
|
tag: "{{.ImageName}}/{{.Name}}/{{.ID}}" # default: "{{.ID}}"
|
||||||
|
```
|
||||||
|
|
||||||
|
- [Configure logging drivers | Docker Documentation](https://docs.docker.com/config/containers/logging/configure/)
|
||||||
|
|
||||||
|
# Additional setup
|
||||||
|
|
||||||
|
## Fail2ban
|
||||||
|
|
||||||
|
```
|
||||||
|
pacman -S fail2ban
|
||||||
|
```
|
||||||
|
|
||||||
|
```ini /etc/fail2ban/filter.d/bad-auth.conf
|
||||||
|
[INCLUDES]
|
||||||
|
before = common.conf
|
||||||
|
|
||||||
|
[Definition]
|
||||||
|
failregex = .* client login failed: .+ client:\ <HOST>
|
||||||
|
ignoreregex =
|
||||||
|
```
|
||||||
|
|
||||||
|
```ini /etc/fail2ban/jail.local
|
||||||
|
[DEFAULT]
|
||||||
|
ignoreip = 127.0.0.1/8 10.0.1.0/24
|
||||||
|
|
||||||
|
[sshd]
|
||||||
|
enabled = true
|
||||||
|
port = 22,10122
|
||||||
|
bantime = 1h
|
||||||
|
mode = aggressive
|
||||||
|
|
||||||
|
# https://github.com/Mailu/Mailu/blob/master/docs/faq.rst#do-you-support-fail2ban
|
||||||
|
[mailu]
|
||||||
|
enabled = true
|
||||||
|
backend = systemd
|
||||||
|
journalmatch = CONTAINER_NAME=mail_front_1
|
||||||
|
filter = bad-auth
|
||||||
|
findtime = 1h
|
||||||
|
maxretry = 3
|
||||||
|
bantime = 1w
|
||||||
|
chain = DOCKER-USER
|
||||||
|
banaction = iptables-allports
|
||||||
|
```
|
||||||
|
|
||||||
|
```patch /etc/systemd/system/fail2ban.service
|
||||||
|
- After=network.target iptables.service firewalld.service ip6tables.service ipset.service nftables.service
|
||||||
|
+ After=network.target iptables.service firewalld.service ip6tables.service ipset.service nftables.service docker.service
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
systemctl enable --now fail2ban
|
||||||
|
fail2ban-client status sshd
|
||||||
|
```
|
||||||
|
|
||||||
|
## Telegraf
|
||||||
|
|
||||||
|
```bash
|
||||||
|
yay -S telegraf
|
||||||
|
```
|
||||||
|
|
||||||
|
```ini /etc/telegraf/telegraf.conf
|
||||||
|
# Global tags can be specified here in key="value" format.
|
||||||
|
[global_tags]
|
||||||
|
|
||||||
|
# Configuration for telegraf agent
|
||||||
|
[agent]
|
||||||
|
interval = "15s"
|
||||||
|
round_interval = true
|
||||||
|
metric_batch_size = 1000
|
||||||
|
metric_buffer_limit = 10000
|
||||||
|
collection_jitter = "0s"
|
||||||
|
flush_interval = "10s"
|
||||||
|
flush_jitter = "0s"
|
||||||
|
precision = ""
|
||||||
|
hostname = ""
|
||||||
|
omit_hostname = false
|
||||||
|
|
||||||
|
# Read InfluxDB-formatted JSON metrics from one or more HTTP endpoints
|
||||||
|
[[outputs.influxdb]]
|
||||||
|
urls = ["http://127.0.0.1:8086"]
|
||||||
|
database = "<db>"
|
||||||
|
username = "<user>"
|
||||||
|
password = "<password>"
|
||||||
|
|
||||||
|
# Read metrics about cpu usage
|
||||||
|
[[inputs.cpu]]
|
||||||
|
percpu = true
|
||||||
|
totalcpu = true
|
||||||
|
collect_cpu_time = false
|
||||||
|
report_active = false
|
||||||
|
|
||||||
|
# Read metrics about disk usage by mount point
|
||||||
|
[[inputs.disk]]
|
||||||
|
ignore_fs = ["tmpfs", "devtmpfs", "devfs", "iso9660", "overlay", "aufs", "squashfs"]
|
||||||
|
|
||||||
|
# Read metrics about disk IO by device
|
||||||
|
[[inputs.diskio]]
|
||||||
|
|
||||||
|
# Get kernel statistics from /proc/stat
|
||||||
|
[[inputs.kernel]]
|
||||||
|
|
||||||
|
# Read metrics about memory usage
|
||||||
|
[[inputs.mem]]
|
||||||
|
|
||||||
|
# Get the number of processes and group them by status
|
||||||
|
[[inputs.processes]]
|
||||||
|
|
||||||
|
# Read metrics about system load & uptime
|
||||||
|
[[inputs.system]]
|
||||||
|
|
||||||
|
# Read metrics about network interface usage
|
||||||
|
[[inputs.net]]
|
||||||
|
interfaces = ["enp5s0"]
|
||||||
|
|
||||||
|
# Read metrics about docker containers
|
||||||
|
[[inputs.docker]]
|
||||||
|
endpoint = "unix:///var/run/docker.sock"
|
||||||
|
perdevice = false
|
||||||
|
total = true
|
||||||
|
|
||||||
|
[[inputs.fail2ban]]
|
||||||
|
interval = "15m"
|
||||||
|
use_sudo = true
|
||||||
|
|
||||||
|
# Pulls statistics from nvidia GPUs attached to the host
|
||||||
|
[[inputs.nvidia_smi]]
|
||||||
|
timeout = "30s"
|
||||||
|
|
||||||
|
[[inputs.http_response]]
|
||||||
|
interval = "5m"
|
||||||
|
urls = [
|
||||||
|
"https://example.com"
|
||||||
|
]
|
||||||
|
|
||||||
|
# Monitor sensors, requires lm-sensors package
|
||||||
|
[[inputs.sensors]]
|
||||||
|
interval = "60s"
|
||||||
|
remove_numbers = false
|
||||||
|
|
||||||
|
# Run executable as long-running input plugin
|
||||||
|
[[inputs.execd]]
|
||||||
|
interval = "15s"
|
||||||
|
command = ["/metrics.sh"]
|
||||||
|
name_override = "metrics"
|
||||||
|
signal = "STDIN"
|
||||||
|
restart_delay = "20s"
|
||||||
|
data_format = "logfmt"
|
||||||
|
```
|
||||||
|
|
||||||
|
```ini /etc/sudoers.d/telegraf
|
||||||
|
Cmnd_Alias FAIL2BAN = /usr/bin/fail2ban-client status, /usr/bin/fail2ban-client status *
|
||||||
|
telegraf ALL=(root) NOEXEC: NOPASSWD: FAIL2BAN
|
||||||
|
Defaults!FAIL2BAN !logfile, !syslog, !pam_session
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
chmod 440 /etc/sudoers.d/telegraf
|
||||||
|
usermod -aG docker telegraf
|
||||||
|
telegraf -config /etc/telegraf/telegraf.conf -test
|
||||||
|
systemctl enable --now telegraf
|
||||||
|
```
|
||||||
|
|
||||||
|
## cfddns
|
||||||
|
|
||||||
|
Dynamic DNS for Cloudflare.
|
||||||
|
|
||||||
|
> Start [the GitHub repo](https://github.com/uetchy/cfddns) if you like :)
|
||||||
|
|
||||||
|
```
|
||||||
|
yay -S cfddns sendmail
|
||||||
|
```
|
||||||
|
|
||||||
|
```yml /etc/cfddns/cfddns.yml
|
||||||
|
token: <token>
|
||||||
|
notification:
|
||||||
|
enabled: true
|
||||||
|
from: cfddns@localhost
|
||||||
|
to: me@example.com
|
||||||
|
```
|
||||||
|
|
||||||
|
```ini /etc/cfddns/domains
|
||||||
|
example.com
|
||||||
|
dev.example.com
|
||||||
|
example.org
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
systemctl enable --now cfddns
|
||||||
|
```
|
||||||
|
|
||||||
|
## Backup
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pacman -S restic
|
||||||
|
```
|
||||||
|
|
||||||
|
```ini /etc/backup/restic.service
|
||||||
|
[Unit]
|
||||||
|
Description=Daily Backup Service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
Nice=19
|
||||||
|
IOSchedulingClass=2
|
||||||
|
IOSchedulingPriority=7
|
||||||
|
ExecStart=/etc/backup/run.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
```ini /etc/backup/restic.timer
|
||||||
|
[Unit]
|
||||||
|
Description=Daily Backup Timer
|
||||||
|
|
||||||
|
[Timer]
|
||||||
|
WakeSystem=false
|
||||||
|
OnCalendar=*-*-* 14:00
|
||||||
|
RandomizedDelaySec=5min
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=timers.target
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash /etc/backup/run.sh
|
||||||
|
#!/bin/bash -ue
|
||||||
|
# usage: run.sh
|
||||||
|
# https://restic.readthedocs.io/en/latest/040_backup.html#
|
||||||
|
|
||||||
|
export RESTIC_REPOSITORY=/path/to/backup
|
||||||
|
export RESTIC_PASSWORD=<passphrase>
|
||||||
|
export RESTIC_PROGRESS_FPS=1
|
||||||
|
|
||||||
|
# system
|
||||||
|
restic backup --tag system -v \
|
||||||
|
--one-file-system \
|
||||||
|
--exclude .cache \
|
||||||
|
--exclude .venv \
|
||||||
|
--exclude .vscode-server \
|
||||||
|
--exclude .vscode-server-insiders \
|
||||||
|
--exclude TabNine \
|
||||||
|
--exclude node_modules \
|
||||||
|
--exclude /var/lib/docker/overlay2 \
|
||||||
|
/ /boot
|
||||||
|
|
||||||
|
# data
|
||||||
|
restic backup --tag data -v \
|
||||||
|
--exclude 'appdata_*/preview' \ # nextcloud cache
|
||||||
|
--exclude 'appdata_*/dav-photocache' \ # nextcloud cache
|
||||||
|
/mnt/data
|
||||||
|
|
||||||
|
# prune
|
||||||
|
restic forget --prune --group-by tags \
|
||||||
|
--keep-within-daily 7d \
|
||||||
|
--keep-within-weekly 1m \
|
||||||
|
--keep-within-monthly 3m
|
||||||
|
|
||||||
|
# verify
|
||||||
|
restic check
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash /etc/backup/show.sh
|
||||||
|
#!/bin/bash
|
||||||
|
# usage: show.sh <file|directory>
|
||||||
|
# https://restic.readthedocs.io/en/latest/050_restore.html
|
||||||
|
|
||||||
|
export RESTIC_REPOSITORY=/path/to/backup
|
||||||
|
export RESTIC_PASSWORD=<passphrase>
|
||||||
|
export RESTIC_PROGRESS_FPS=1
|
||||||
|
|
||||||
|
TARGET=${1:-$(pwd)}
|
||||||
|
MODE="ls -l"
|
||||||
|
if [[ -f $TARGET ]]; then
|
||||||
|
TARGET=$(realpath ${TARGET})
|
||||||
|
MODE=dump
|
||||||
|
fi
|
||||||
|
|
||||||
|
TAG=$(restic snapshots --json | jq -r '[.[].tags[0]] | unique| .[]' | fzy)
|
||||||
|
ID=$(restic snapshots --tag $TAG --json | jq -r ".[] | [.time, .short_id] | @tsv" | fzy | awk '{print $2}')
|
||||||
|
|
||||||
|
>&2 echo "Command: restic ${MODE} ${ID} ${TARGET}"
|
||||||
|
|
||||||
|
restic $MODE $ID ${TARGET}
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash /etc/backup/restore.sh
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# https://restic.readthedocs.io/en/latest/050_restore.html
|
||||||
|
|
||||||
|
export RESTIC_REPOSITORY=/path/to/backup
|
||||||
|
export RESTIC_PASSWORD=<passphrase>
|
||||||
|
export RESTIC_PROGRESS_FPS=1
|
||||||
|
|
||||||
|
TARGET=${1:?Specify TARGET}
|
||||||
|
TARGET=$(realpath ${TARGET})
|
||||||
|
|
||||||
|
TAG=$(restic snapshots --json | jq -r '[.[].tags[0]] | unique | .[]' | fzy)
|
||||||
|
ID=$(restic snapshots --tag $TAG --json | jq -r ".[] | [.time, .short_id] | @tsv" | fzy | awk '{print $2}')
|
||||||
|
|
||||||
|
>&2 echo "Command: restic restore ${ID} -i ${TARGET} -t /"
|
||||||
|
|
||||||
|
read -p "Press enter to continue"
|
||||||
|
|
||||||
|
restic restore $ID -i ${TARGET} -t /
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
chmod 700 /etc/backup/{run,show}.sh
|
||||||
|
ln -sf /etc/backup/restic.{service,timer} /etc/systemd/system/
|
||||||
|
systemctl enable --now restic
|
||||||
|
```
|
||||||
|
|
||||||
|
## Kubernetes
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pacman -S minikube kubectl
|
||||||
|
minikube start --cpus=max
|
||||||
|
kubectl taint nodes --all node-role.kubernetes.io/master- # to allow allocating pods to the master node
|
||||||
|
|
||||||
|
minikube ip
|
||||||
|
kubectl cluster-info
|
||||||
|
kubectl get cm -n kube-system kubeadm-config -o yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
- [Kubernetes - ArchWiki](https://wiki.archlinux.org/index.php/Kubernetes)
|
||||||
|
- [Kubernetes Ingress Controller with NGINX Reverse Proxy and Wildcard SSL from Let's Encrypt - Shogan.tech](https://www.shogan.co.uk/kubernetes/kubernetes-ingress-controller-with-nginx-reverse-proxy-and-wildcard-ssl-from-lets-encrypt/)
|
||||||
|
|
||||||
|
## Audio
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pacman -S alsa-utils # maybe requires rebooting system
|
||||||
|
usermod -aG audio <user>
|
||||||
|
|
||||||
|
# list devices as root
|
||||||
|
aplay -l
|
||||||
|
arecord -L
|
||||||
|
cat /proc/asound/cards
|
||||||
|
|
||||||
|
# test speaker
|
||||||
|
speaker-test -c2
|
||||||
|
|
||||||
|
# test mic
|
||||||
|
arecord -vv -Dhw:2,0 -fS32_LE mic.wav
|
||||||
|
aplay mic.wav
|
||||||
|
|
||||||
|
# gui mixer
|
||||||
|
alsamixer
|
||||||
|
|
||||||
|
# for Mycroft.ai
|
||||||
|
pacman -S pulseaudio pulsemixer
|
||||||
|
pulseaudio --start
|
||||||
|
pacmd list-cards
|
||||||
|
```
|
||||||
|
|
||||||
|
```conf /etc/pulse/default.pa
|
||||||
|
# INPUT/RECORD
|
||||||
|
load-module module-alsa-source device="default" tsched=1
|
||||||
|
# OUTPUT/PLAYBACK
|
||||||
|
load-module module-alsa-sink device="default" tsched=1
|
||||||
|
# Accept clients -- very important
|
||||||
|
load-module module-native-protocol-unix
|
||||||
|
load-module module-native-protocol-tcp
|
||||||
|
```
|
||||||
|
|
||||||
|
```conf /etc/asound.conf
|
||||||
|
pcm.mic {
|
||||||
|
type hw
|
||||||
|
card M96k
|
||||||
|
rate 44100
|
||||||
|
format S32_LE
|
||||||
|
}
|
||||||
|
|
||||||
|
pcm.speaker {
|
||||||
|
type plug
|
||||||
|
slave {
|
||||||
|
pcm "hw:1,0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pcm.!default {
|
||||||
|
type asym
|
||||||
|
capture.pcm "mic"
|
||||||
|
playback.pcm "speaker"
|
||||||
|
}
|
||||||
|
|
||||||
|
#defaults.pcm.card 1
|
||||||
|
#defaults.ctl.card 1
|
||||||
|
```
|
||||||
|
|
||||||
|
- [PulseAudio as a minimal unintrusive dumb pipe to ALSA](https://wiki.archlinux.org/title/PulseAudio/Examples#PulseAudio_as_a_minimal_unintrusive_dumb_pipe_to_ALSA)
|
||||||
|
- [SoundcardTesting - AlsaProject](https://www.alsa-project.org/main/index.php/SoundcardTesting)
|
||||||
|
- [Advanced Linux Sound Architecture/Troubleshooting - ArchWiki](https://wiki.archlinux.org/index.php/Advanced_Linux_Sound_Architecture/Troubleshooting#Microphone)
|
||||||
|
- [ALSA project - the C library reference: PCM (digital audio) plugins](https://www.alsa-project.org/alsa-doc/alsa-lib/pcm_plugins.html)
|
||||||
|
- [Asoundrc - AlsaProject](https://www.alsa-project.org/wiki/Asoundrc)
|
||||||
|
|
||||||
|
## Firewall
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pacman -S firewalld
|
||||||
|
systemctl enable --now firewalld
|
||||||
|
```
|
||||||
|
|
||||||
|
See [Introduction to Netfilter – To Linux and beyond !](https://home.regit.org/netfilter-en/netfilter/).
|
||||||
|
|
||||||
|
# Maintenance
|
||||||
|
|
||||||
|
## Quick checkups
|
||||||
|
|
||||||
|
```bash
|
||||||
|
htop # show task overview
|
||||||
|
systemctl --failed # show failed units
|
||||||
|
free -h # show memory usage
|
||||||
|
lsblk -f # show disk usage
|
||||||
|
networkctl status # show network status
|
||||||
|
userdbctl # show users
|
||||||
|
nvidia-smi # verify nvidia cards
|
||||||
|
ps aux | grep "defunct" # find zombie processes
|
||||||
|
```
|
||||||
|
|
||||||
|
## Delve into system logs
|
||||||
|
|
||||||
|
```bash
|
||||||
|
journalctl -p err -b-1 -r # show error logs from previous boot in reverse order
|
||||||
|
journalctl -u sshd -f # tail logs from sshd unit
|
||||||
|
journalctl --no-pager -n 25 -k # show latest 25 logs from the kernel without pager
|
||||||
|
journalctl --since=yesterday --until "2020-07-10 15:10:00" # show logs within specific time range
|
||||||
|
journalctl CONTAINER_NAME=service_web_1 # show error from docker container named 'service_web_1'
|
||||||
|
journalctl _PID=2434 -e # filter logs based on PID and jump to the end of the logs
|
||||||
|
journalctl -g 'timed out' # filter logs based on regular expression. if the pattern is all lowercase, matching is case insensitive
|
||||||
|
```
|
||||||
|
|
||||||
|
- g - go to the first line
|
||||||
|
- G - go to the last line
|
||||||
|
- / - search for the string
|
||||||
|
|
||||||
|
## Force overriding installation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pacman -S <pkg> --overwrite '*'
|
||||||
|
```
|
||||||
|
|
||||||
|
## Check memory modules
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pacman -S lshw dmidecode
|
||||||
|
|
||||||
|
lshw -short -C memory # lists installed mems
|
||||||
|
dmidecode # shows configured clock speed
|
||||||
|
```
|
||||||
|
|
||||||
|
## File-system related issues checklist
|
||||||
|
|
||||||
|
```bash
|
||||||
|
smartctl -H /dev/sdd
|
||||||
|
|
||||||
|
# umount the drive before this ops
|
||||||
|
e2fsck -C 0 -p /dev/sdd1 # preen
|
||||||
|
e2fsck -C 0 -cc /dev/sdd1 # badblocks
|
||||||
|
```
|
||||||
|
|
||||||
|
# Common issues
|
||||||
|
|
||||||
|
## Longer SSH login (D-bus glitch)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
systemctl restart systemd-logind
|
||||||
|
systemctl restart polkit
|
||||||
|
```
|
||||||
|
|
||||||
|
- [A comprehensive guide to fixing slow SSH logins – JRS Systems: the blog](https://jrs-s.net/2017/07/01/slow-ssh-logins/)
|
||||||
|
|
||||||
|
## Annoying `systemd-homed is not available` log messages
|
||||||
|
|
||||||
|
Move `pam_unix` before `pam_systemd_home`.
|
||||||
|
|
||||||
|
```ini /etc/pam.d/system-auth
|
||||||
|
#%PAM-1.0
|
||||||
|
|
||||||
|
auth required pam_faillock.so preauth
|
||||||
|
# Optionally use requisite above if you do not want to prompt for the password
|
||||||
|
# on locked accounts.
|
||||||
|
auth [success=2 default=ignore] pam_unix.so try_first_pass nullok
|
||||||
|
-auth [success=1 default=ignore] pam_systemd_home.so
|
||||||
|
auth [default=die] pam_faillock.so authfail
|
||||||
|
auth optional pam_permit.so
|
||||||
|
auth required pam_env.so
|
||||||
|
auth required pam_faillock.so authsucc
|
||||||
|
# If you drop the above call to pam_faillock.so the lock will be done also
|
||||||
|
# on non-consecutive authentication failures.
|
||||||
|
|
||||||
|
account [success=1 default=ignore] pam_unix.so
|
||||||
|
-account required pam_systemd_home.so
|
||||||
|
account optional pam_permit.so
|
||||||
|
account required pam_time.so
|
||||||
|
|
||||||
|
password [success=1 default=ignore] pam_unix.so try_first_pass nullok shadow
|
||||||
|
-password required pam_systemd_home.so
|
||||||
|
password optional pam_permit.so
|
||||||
|
|
||||||
|
session required pam_limits.so
|
||||||
|
session required pam_unix.so
|
||||||
|
session optional pam_permit.so
|
||||||
|
```
|
||||||
|
|
||||||
|
- [[solved] pam fails to find unit dbus-org.freedesktop.home1.service / Newbie Corner / Arch Linux Forums](https://bbs.archlinux.org/viewtopic.php?id=258297)
|
||||||
|
|
||||||
|
## Annoying systemd-journald-audit log
|
||||||
|
|
||||||
|
```ini /etc/systemd/journald.conf
|
||||||
|
Audit=no
|
||||||
|
```
|
||||||
|
|
||||||
|
## Missing `/dev/nvidia-{uvm*,modeset}`
|
||||||
|
|
||||||
|
This occurs after updating linux kernel.
|
||||||
|
|
||||||
|
- Run `docker run --rm --gpus all --device /dev/nvidia0 --device /dev/nvidiactl --device /dev/nvidia-modeset --device /dev/nvidia-uvm --device /dev/nvidia-uvm-tools -it nvidia/cuda:10.2-cudnn7-runtime nvidia-smi` once.
|
||||||
|
|
||||||
|
## `[sudo] Incorrect password` while password is correct
|
||||||
|
|
||||||
|
```bash
|
||||||
|
faillock --reset
|
||||||
|
```
|
||||||
|
|
||||||
|
# Useful links
|
||||||
|
|
||||||
|
- [General recommendations](https://wiki.archlinux.org/index.php/General_recommendations#Users_and_groups)
|
||||||
|
- [System maintenance](https://wiki.archlinux.org/index.php/System_maintenance)
|
||||||
|
- [Improving performance](https://wiki.archlinux.org/index.php/Improving_performance#Know_your_system)
|
||||||
|
- [General troubleshooting - ArchWiki](https://wiki.archlinux.org/title/General_troubleshooting)
|
||||||
|
- [Stress testing - ArchWiki](https://wiki.archlinux.org/title/Stress_testing#Stressing_memory)
|
||||||
|
- [udev - ArchWiki](https://wiki.archlinux.org/title/Udev#Debug_output)
|
||||||
|
- [[HOWTO] Repair Broken system, system without a kernel / Forum & Wiki discussion / Arch Linux Forums](https://bbs.archlinux.org/viewtopic.php?id=18066)
|
||||||
|
- [Archboot - ArchWiki](https://wiki.archlinux.org/title/Archboot)
|
||||||
|
- [Restic Documentation — restic 0.12.1 documentation](https://restic.readthedocs.io/en/stable/)
|
102
source/_posts/2021/oauth-jwt-rfcs.md
Normal file
102
source/_posts/2021/oauth-jwt-rfcs.md
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
---
|
||||||
|
title: OAuth 2.0 と JWT 関連 RFC
|
||||||
|
date: 2021-02-11
|
||||||
|
---
|
||||||
|
|
||||||
|
個人的な調査のために OAuth 2.0 と JWT 関連 RFC を発行日順に並べた。
|
||||||
|
|
||||||
|
## [RFC6749](https://tools.ietf.org/html/rfc6749) — The OAuth 2.0 Authorization Framework
|
||||||
|
|
||||||
|
2012 年 10 月
|
||||||
|
|
||||||
|
OAuth 1.0a に代わる新たな認証基盤 OAuth 2.0 のコアを規定しており、特筆すべき点がいくつかある。
|
||||||
|
|
||||||
|
- `access_token` の内容は規定されておらず、ベンダーに委ねられている
|
||||||
|
- JWS でもなんでもいい
|
||||||
|
- リソースサーバーに `access_token` を渡す方法は規定されていない(同月発行の RFC6750 で規定された)
|
||||||
|
|
||||||
|
### Authorization Grant
|
||||||
|
|
||||||
|
トークンエンドポイントで`access_token`を発行してもらう際に使用できる Grant (許可証)は、提案中の拡張仕様を含めて 5 つある。
|
||||||
|
|
||||||
|
1. Authorization Code Grant: [RFC6749 – Section 1.3.1](https://tools.ietf.org/html/rfc6749#section-1.3.1)
|
||||||
|
1. `grant_type=authorization_code`
|
||||||
|
2. Authorization Code Grant with PKCE
|
||||||
|
2. Implicit Flow: [RFC6749 – Section 1.3.2](https://tools.ietf.org/html/rfc6749#section-1.3.2)
|
||||||
|
1. もともと CORS (Cross Origin Resource Sharing) が登場する以前の SPA で、POST リクエストを回避しつつ Access Token を得る"妥協案"として策定された
|
||||||
|
2. CSRF 耐性が無い ([RFC6819 - Section 4.4.2.5](https://tools.ietf.org/html/rfc6819#section-4.4.2.5))ため、使うべきではない
|
||||||
|
3. Resource Owner Password Credentials Grant: [RFC6749 – Section 1.3.3](https://tools.ietf.org/html/rfc6749#section-1.3.3)
|
||||||
|
1. 直接パスワードで認証する形式
|
||||||
|
4. Client Credentials Grant: [RFC6749 – Section 1.3.4](https://tools.ietf.org/html/rfc6749#section-1.3.4)
|
||||||
|
1. クライアントシークレットでトークンを取得する形式。
|
||||||
|
5. Device Grant: [RFC Draft — OAuth 2.0 Device Authorization Grant](https://tools.ietf.org/html/draft-ietf-oauth-device-flow-15)
|
||||||
|
1. 入力機器が無い場合もある組み込みデバイス向けの認証フロー
|
||||||
|
|
||||||
|
## [RFC6750](https://tools.ietf.org/html/rfc6750) — The OAuth 2.0 Authorization Framework: Bearer Token Usage
|
||||||
|
|
||||||
|
2012 年 10 月
|
||||||
|
|
||||||
|
OAuth 2.0 において、`access_token`をリソースサーバーに渡す手法を規定する。OAuth 2.0 JWT Bearer Token Flow**ではない**。
|
||||||
|
|
||||||
|
手法として 3 つが挙げられている。
|
||||||
|
|
||||||
|
1. Bearer Token (**SHOULD**)
|
||||||
|
2. Form Encoded Parameters (SHOULD NOT)
|
||||||
|
3. URI Query Parameters (SHOULD NOT)
|
||||||
|
|
||||||
|
## [OICD](https://openid.net/specs/openid-connect-core-1_0.html) — OpenID Connect Core 1.0
|
||||||
|
|
||||||
|
2014 年 11 月
|
||||||
|
|
||||||
|
OAuth 2.0 の上にいくつか仕様を足したサブセット。
|
||||||
|
|
||||||
|
## [RFC7515](https://tools.ietf.org/html/rfc7515) — JSON Web Signature (JWS)
|
||||||
|
|
||||||
|
2015 年 5 月
|
||||||
|
|
||||||
|
JSON ベースの署名プロトコル。
|
||||||
|
|
||||||
|
## [RFC7516](https://tools.ietf.org/html/rfc7516) — JSON Web Encryption (JWE)
|
||||||
|
|
||||||
|
2015 年 5 月
|
||||||
|
|
||||||
|
JSON ベースの暗号化プロトコル。
|
||||||
|
|
||||||
|
## [RFC7517](https://tools.ietf.org/html/rfc7517) — JSON Web Key (JWK)
|
||||||
|
|
||||||
|
2015 年 5 月
|
||||||
|
|
||||||
|
JWT の署名チェックに用いる公開鍵を配信するためのプロトコル。
|
||||||
|
|
||||||
|
## [RFC7518](https://tools.ietf.org/html/rfc7518) — JSON Web Algorithms (JWA)
|
||||||
|
|
||||||
|
2015 年 5 月
|
||||||
|
|
||||||
|
JWS、JWE、JWK で利用されるアルゴリズム (alg)やその他プロパティを規定する。
|
||||||
|
|
||||||
|
## [RFC7519](https://tools.ietf.org/html/rfc7519) — JSON Web Token (JWT)
|
||||||
|
|
||||||
|
2015 年 5 月
|
||||||
|
|
||||||
|
JWT は JSON を利用して Assertion を生成するための仕様。
|
||||||
|
|
||||||
|
## [RFC7521](https://tools.ietf.org/html/rfc7521) — Assertion Framework for OAuth 2.0 Client Authentication and Authorization Grants
|
||||||
|
|
||||||
|
2015 年 5 月
|
||||||
|
|
||||||
|
任意の Assertion を OAuth 2.0 Client Authentication の Client Credentials として使ったり、あるいは Authorization Grant として Access Token と交換するための仕様。
|
||||||
|
|
||||||
|
トークンエンドポイントに強化されたクライアント認証を付与する。続く RFC で、それぞれ SAML と JWT を使用したパターンを規定している。
|
||||||
|
|
||||||
|
**OAuth 2.0 JWT Bearer Token Flow**とも呼ばれている。
|
||||||
|
|
||||||
|
- [RFC7522](https://tools.ietf.org/html/rfc7522) — Security Assertion Markup Language (**SAML**) 2.0 Profile for OAuth 2.0 Client Authentication and Authorization Grants (2015 年 5 月)
|
||||||
|
- [RFC7523](https://tools.ietf.org/html/rfc7523) — JSON Web Token (**JWT**) Profile for OAuth 2.0 Client Authentication and Authorization Grants (2015 年 5 月)
|
||||||
|
|
||||||
|
2015 年 5 月 https://tools.ietf.org/html/rfc7523
|
||||||
|
|
||||||
|
## [RFC Draft](https://tools.ietf.org/html/draft-ietf-oauth-access-token-jwt-02) — JSON Web Token (JWT) Profile for OAuth 2.0 Access Tokens
|
||||||
|
|
||||||
|
2019 年 7 月
|
||||||
|
|
||||||
|
リソースサーバーへ渡す Access Token に JWT を使用することを定めている。
|
26
source/_posts/2021/parseint-magic.md
Normal file
26
source/_posts/2021/parseint-magic.md
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
---
|
||||||
|
title: "[].map(parseInt)"
|
||||||
|
date: 2021-02-14T11:30:00
|
||||||
|
---
|
||||||
|
|
||||||
|
Fun fact: `[0xa, 0xa, 0xa].map(parseInt)` yields `[10, NaN, 2]`.
|
||||||
|
|
||||||
|
# Why
|
||||||
|
|
||||||
|
```js
|
||||||
|
parseInt(0xa, 0, [0xa, 0xa, 0xa]);
|
||||||
|
```
|
||||||
|
|
||||||
|
The second argument is `0` so the first argument going to be treated as decimal number becoming `10`.
|
||||||
|
|
||||||
|
```js
|
||||||
|
parseInt(0xa, 1, [0xa, 0xa, 0xa]);
|
||||||
|
```
|
||||||
|
|
||||||
|
The second argument is `1` which is invalid as a radix, so the result ends up with `NaN`.
|
||||||
|
|
||||||
|
```js
|
||||||
|
parseInt(0xa, 2, [0xa, 0xa, 0xa]);
|
||||||
|
```
|
||||||
|
|
||||||
|
The second argument is `2` meaning the first argument going to be handled as a binary number. `0xa` is `10` in binary, which results in `2` in decimal form.
|
70
source/_posts/2021/server-2020.md
Normal file
70
source/_posts/2021/server-2020.md
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
---
|
||||||
|
title: 新しい自宅サーバーの構成
|
||||||
|
date: 2021-02-13T00:00:00
|
||||||
|
---
|
||||||
|
|
||||||
|
10 年ぶりにサーバーを更新した。初めての AMD、初めての DDR4、初めての NVM Express!
|
||||||
|
|
||||||
|
# 用途
|
||||||
|
|
||||||
|
- 各種セルフホスト (Docker)
|
||||||
|
- Docker Swarm / K8s のマスター
|
||||||
|
- 計算実験
|
||||||
|
- VS Code Remote SSH のホストマシン
|
||||||
|
- VPN 他
|
||||||
|
|
||||||
|
# スペック
|
||||||
|
|
||||||
|
重いタスクを並列してやらせたいので最優先は CPU とメモリ。メモリは[DDR4-3200 32GBx2](https://shop.tsukumo.co.jp/goods/4582353591719/) を、CPU は昨今のライブラリのマルチコア対応を勘案して [Ryzen 9 3950X](https://www.amd.com/en/products/cpu/amd-ryzen-9-3950x) を選んだ。CPU クーラーは静音性を考えて Noctua の [NH-D15 Black](https://noctua.at/en/nh-d15) 。
|
||||||
|
|
||||||
|
> 結果から言うとメモリは 64GB では足りなかった。巨大な Pandas データフレームを並列処理したり、DeepSpeed でモデルの重みをオフロードするたびに OOM が発動してしまう。最終的に 128GB まで増やす羽目になった。
|
||||||
|
|
||||||
|
> 追記: メモリ異常を起因とするシステム誤動作により、`/sbin` 以下がゼロ上書きされカーネルが起動しなくなる災害が起きた。後日 ECC 付きのメモリに交換してからは、現在に至るまでメモリ関連の異常は発生していない。常時稼働するサーバーには最初から ECC メモリを選ぼう。
|
||||||
|
|
||||||
|
GPU は古いサーバーに突っ込んでいた NVIDIA GeForce GTX TITAN X (Maxwell)を流用した。グラフィックメモリが 12GB ちょっとしかないが、最大ワークロード時でも 5GB は残るので今のところ十分。
|
||||||
|
|
||||||
|
> 結果から言うと GPT-J や Megatron-LM を始めとした億パラメータ級のモデルを学習・推論させるには、DeepSpeed の助けがあったとしても最低 16GB の VRAM が必要だった。
|
||||||
|
|
||||||
|
記憶装置は WD HDD 3TB 2 台と Samsung 970 EVO Plus 500GB M.2 PCIe、そして古いサーバーから引っこ抜いた Samsung 870 EVO Plus 500GB SSD 。NVMe メモリは OS 用、SSD/HDD はデータとバックアップ用にする。
|
||||||
|
|
||||||
|
マザーボードは、X570 と比較して実装されているコンデンサーやパーツがサーバー向きだと感じた[ASRock B550 Taichi](https://www.asrock.com/mb/AMD/B550%20Taichi/) にした。
|
||||||
|
|
||||||
|
電源は今後 GPU を追加することを考えて [Seasonic PRIME TX 850](https://seasonic.com/prime-tx) を選んだ。実際にサーバーを稼働させながら使用電力を計測したところ、アイドル時に 180W 前後、フル稼働時でも 350W を超えない程度だった。
|
||||||
|
|
||||||
|
ケースは Fractal Design の [Meshify 2](https://www.fractal-design.com/products/cases/meshify/meshify-2/Black/) 。
|
||||||
|
|
||||||
|
OS は長年付き合ってきた Ubuntu と袂を分かち、[Arch Linux](https://archlinux.org/) を選んだ。ミニマルと実用の間のバランスが取れていて好み。
|
||||||
|
|
||||||
|
Arch Linux のセットアップは[個別に記事](https://uechi.io/blog/installing-arch-linux/)を書いた。
|
||||||
|
|
||||||
|
また、AUR (Arch User Repository)にパッケージを公開したい人向けに、Docker 自動ビルド・テストツールを[GitHub で公開](https://github.com/uetchy/archpkgs)した。
|
||||||
|
|
||||||
|
# パーツ選定時のポイント
|
||||||
|
|
||||||
|
- [WikiChip](https://en.wikichip.org/wiki/WikiChip)で CPU のモデルやスペックを調査する
|
||||||
|
- [PCPartPicker](https://jp.pcpartpicker.com/)でパーツのコスト計算をする
|
||||||
|
- [Bottleneck Calculator](https://pc-builds.com/calculator/)で CPU と GPU の組み合わせを選び、そのうちどちらが性能のボトルネックになるか調べる
|
||||||
|
- [UserBenchmark](https://www.userbenchmark.com/)でユーザーが投稿したベンチマーク結果を眺める
|
||||||
|
- [Linux Hardware Database](https://linux-hardware.org/) を見て、インストールする予定の Linux ディストリとパーツの相性をチェックする
|
||||||
|
- CPU クーラーは大口径の方が静か
|
||||||
|
- PSU は Seasonic が評判良い
|
||||||
|
- 東芝 D01 が HGST の系譜
|
||||||
|
- [B550](https://www.amd.com/en/chipsets/b550) は長期運用に向いている(らしい)
|
||||||
|
- B520 は廉価版
|
||||||
|
- TSUKUMO eX. の自作 PC コーナーのスタッフはガチ勢なので信頼できる
|
||||||
|
- 不明な部分があれば根掘り葉掘り聞く
|
||||||
|
|
||||||
|
# 組立ての勘所
|
||||||
|
|
||||||
|
- 少なくとも 1 年間はすべての箱・書類を取っておく(特にメモリは箱自体が保証書代わりになっている場合がある)
|
||||||
|
- 筐体は無視してまずマザボ、CPU、クーラー、(オンボードグラフィックが無い CPU なら)グラボ、そして電源を繋いで通電・動作テストをする
|
||||||
|
- [MemTest86](https://www.memtest86.com/)でメモリの動作テストを最後までやる(エラーが出たら交換依頼)
|
||||||
|
- USB ブートで OS の起動確認
|
||||||
|
- Ethernet が死んでいる場合は USB-Ethernet アダプターでまずネットを確保する
|
||||||
|
- ほとんどの場合 Linux カーネルのバージョンを上げると(デバイスドライバーも新しくなり)直る
|
||||||
|
- Arch Linux の場合: `linux-lts`が駄目なら`linux`に切り替えて試す
|
||||||
|
- Ubuntu の場合: [kernel.ubuntu.com](https://kernel.ubuntu.com/~kernel-ppa/mainline/?C=N;O=D) から探してアップデートする([https://itsfoss.com/upgrade-linux-kernel-ubuntu/](https://itsfoss.com/upgrade-linux-kernel-ubuntu/))
|
||||||
|
- 駄目ならマザボまたはアダプターメーカーからアップデートを探す
|
||||||
|
- 安い筐体のネジは柔いことがあるため、強く押し込みながら少しずつ回す
|
||||||
|
- 山が潰れてきたらゴムシートを挟む
|
||||||
|
- すべて動いたら、[Linux Hardware Database に Probe を送信](https://linux-hardware.org/index.php?view=howto)して貢献
|
148
source/_posts/2021/split-bill.md
Normal file
148
source/_posts/2021/split-bill.md
Normal file
@@ -0,0 +1,148 @@
|
|||||||
|
---
|
||||||
|
title: 最小送金回数で精算する割り勘アルゴリズム
|
||||||
|
date: 2021-02-14T00:00:00
|
||||||
|
---
|
||||||
|
|
||||||
|
大人数で旅行を楽しんだあとに待っているのは耐え難き精算・送金処理だ。
|
||||||
|
次回から楽をするためにも、送金回数を最小化する制約で精算表を作る方法を考えよう。
|
||||||
|
|
||||||
|
# tl;dr
|
||||||
|
|
||||||
|
アイディアは「最も支払わなかった人が最も支払った人に払えるだけ払う ⇢ 債権を再計算して繰り返す」
|
||||||
|
|
||||||
|
1. 全員の出費を算出(払い過ぎは正、払わなさすぎは負の数)
|
||||||
|
2. 降順でソート(出費過多が先頭)
|
||||||
|
3. リストの最後(最大債務者, 出費=L)がリストの最初(最大債権者, F)に $\min(F, |L|)$ を支払ってバランスを再計算
|
||||||
|
4. 全員のバランスが 0 になるまで 2-3 を繰り返す
|
||||||
|
|
||||||
|
# 実験
|
||||||
|
|
||||||
|
実際にコードを書いて本当に望んでいる結果が得られるのかを検証する。
|
||||||
|
|
||||||
|
```js split-bill.js
|
||||||
|
const history = [
|
||||||
|
{
|
||||||
|
amount: 121,
|
||||||
|
payer: "A",
|
||||||
|
involves: ["A", "B", "C"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
amount: 98,
|
||||||
|
payer: "B",
|
||||||
|
involves: ["A", "B", "C"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
amount: 10,
|
||||||
|
payer: "C",
|
||||||
|
involves: ["A", "B", "C"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
amount: 10,
|
||||||
|
payer: "C",
|
||||||
|
involves: ["A", "B"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
amount: 50,
|
||||||
|
payer: "C",
|
||||||
|
involves: ["A"], // meaning C lent A 50
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
// calculate balance sheet
|
||||||
|
const init = { balance: 0, consumption: 0 };
|
||||||
|
Map.prototype.fetch = function (id) {
|
||||||
|
return (
|
||||||
|
this.get(id) || this.set(id, Object.assign({ name: id }, init)).get(id)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const data = new Map();
|
||||||
|
|
||||||
|
for (const { payer, amount, involves } of history) {
|
||||||
|
const record = data.fetch(payer);
|
||||||
|
record.balance += amount;
|
||||||
|
const debt = Math.ceil(amount / involves.length);
|
||||||
|
// actual payer should not owe extra debt coming from rounded up numbers
|
||||||
|
const payerDebt = amount - debt * (involves.length - 1);
|
||||||
|
for (const debtor of involves.map((i) => data.fetch(i))) {
|
||||||
|
const cost = Math.round(amount / involves.length);
|
||||||
|
debtor.balance -= cost;
|
||||||
|
debtor.consumption += cost;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(data);
|
||||||
|
|
||||||
|
// calculate transaction table
|
||||||
|
const transaction = [];
|
||||||
|
let paidTooMuch, paidLess;
|
||||||
|
while (true) {
|
||||||
|
for (const [_, tbl] of data) {
|
||||||
|
if (tbl.balance >= (paidTooMuch?.balance || 0)) {
|
||||||
|
paidTooMuch = tbl;
|
||||||
|
}
|
||||||
|
if (tbl.balance <= (paidLess?.balance || 0)) {
|
||||||
|
paidLess = tbl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (paidLess.balance == 0 || paidTooMuch.balance == 0) break;
|
||||||
|
|
||||||
|
const amount = Math.min(paidTooMuch.balance, Math.abs(paidLess.balance));
|
||||||
|
|
||||||
|
transaction.push({
|
||||||
|
sender: paidLess.name,
|
||||||
|
receiver: paidTooMuch.name,
|
||||||
|
amount,
|
||||||
|
});
|
||||||
|
|
||||||
|
paidTooMuch.balance -= amount;
|
||||||
|
paidLess.balance += amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("Settled");
|
||||||
|
|
||||||
|
console.log("\n# Transaction table");
|
||||||
|
for (const ev of transaction) {
|
||||||
|
console.log(`${ev.sender} owes ${ev.receiver} ¥${ev.amount}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("\n# History");
|
||||||
|
for (const { payer, amount, involves } of history) {
|
||||||
|
if (involves.length === 1) {
|
||||||
|
console.log(`${payer} lent ¥${amount} to ${involves[0]}`);
|
||||||
|
} else {
|
||||||
|
console.log(`${payer} paid ¥${amount} for ${involves.join(", ")}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("\n# Expenses");
|
||||||
|
for (const [_, { name, consumption }] of data) {
|
||||||
|
console.log(`${name} virtually paid ¥${consumption} in total`);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
`history`に支払い履歴を書き込んで実行すると、「送金表」「履歴」「実質支払総額」が得られる。
|
||||||
|
|
||||||
|
```md
|
||||||
|
# Transaction table
|
||||||
|
|
||||||
|
A owes B ¥10
|
||||||
|
C owes B ¥6
|
||||||
|
|
||||||
|
# History
|
||||||
|
|
||||||
|
A paid ¥121 for A, B, C
|
||||||
|
B paid ¥98 for A, B, C
|
||||||
|
C paid ¥10 for A, B, C
|
||||||
|
C paid ¥10 for A, B
|
||||||
|
C lent ¥50 to A
|
||||||
|
|
||||||
|
# Expenses
|
||||||
|
|
||||||
|
A virtually paid ¥131 in total
|
||||||
|
B virtually paid ¥81 in total
|
||||||
|
C virtually paid ¥76 in total
|
||||||
|
```
|
||||||
|
|
||||||
|
プログラムに落とし込むことができたら、あとはスプレッドシートのマクロにするなり自由だ。面倒なことは全部コンピューターにやらせよう!
|
77
source/_posts/2021/uco-oil-lantern.md
Normal file
77
source/_posts/2021/uco-oil-lantern.md
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
---
|
||||||
|
title: 手のひらサイズのオイルランタン
|
||||||
|
date: 2021-06-08T00:00:00
|
||||||
|
---
|
||||||
|
|
||||||
|
UCO キャンドルランタンを改造して手のひらサイズのオイルランタンを作った。
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
# 特徴
|
||||||
|
|
||||||
|
- 手のひらサイズのオイルランタン
|
||||||
|
- ロウソクより大きい炎
|
||||||
|
- 暗所でもオイル残量が見やすい
|
||||||
|
- 揺らしてもオイルが漏れない
|
||||||
|
- 瓶を入れたまま仕舞える
|
||||||
|
|
||||||
|
# 材料
|
||||||
|
|
||||||
|
ほとんどのパーツはドラッグストアやホームセンターで調達できる。
|
||||||
|
|
||||||
|
1. 大正漢方胃腸薬(30 ml)
|
||||||
|

|
||||||
|
2. C タイプアンカー M8(ステンレス)
|
||||||
|
3. 袋ナット M8(ステンレス)
|
||||||
|
4. ハードロックボルト M8(ステンレス)
|
||||||
|
5. [ゴムパッキン 直径 28x 内径 23x 厚さ 2mm](https://www.amazon.co.jp/gp/product/B003PHKRZS)(耐熱ではないけど今のところ耐えている)
|
||||||
|
6. [3mm グラスファイバー芯](https://www.amazon.co.jp/gp/product/B07X1VZFGB)
|
||||||
|
7. 隙間テープ(ダイソー)
|
||||||
|
|
||||||
|
# 手順
|
||||||
|
|
||||||
|
1. M8 アンカーのネジ部分を金属ノコギリで切断して断面をヤスリで整える
|
||||||
|
2. キャップに印字されているラベルをヤスリで削りとる(任意)
|
||||||
|
3. キャップの裏に張り付いている液漏れ防止シールを剥がす(熱で溶解するため)
|
||||||
|
4. キャップの内側からドリルで穴をあけ、棒やすりでネジが入るサイズまで広げる
|
||||||
|
5. ネジをキャップに差し込む
|
||||||
|
6. ゴムパッキンをキャップの裏にはめ込む
|
||||||
|
7. ハードロックボルトでネジの両側を固定する(レンチ等を使用して強く固定する)
|
||||||
|
8. 芯をボルトの中に通す(テープで芯の先を固定するとやりやすい)
|
||||||
|
9. 袋ネジで封をする
|
||||||
|
10. 切断した隙間テープをランタンの底面キャップに巻きつける
|
||||||
|
11. 瓶をランタンに差し込み底面キャップを締める
|
||||||
|
|
||||||
|
# 使用法
|
||||||
|
|
||||||
|
1. パラフィンオイルを 4/5 ほど入れてキャップを締め、オイルが芯の先に浸透するまで 15 分以上放置する
|
||||||
|
2. 芯の焦げている部分を 1mm 前後、それ以外の部分を 1mm ほど露出させてほぐす
|
||||||
|
3. 芯に火を付けてホヤを上げる
|
||||||
|
4. 使わないときはオイルを抜く(オイルが入ったままだと毛細管現象で染み出してくる)
|
||||||
|
|
||||||
|
## 🔥 燃焼時間
|
||||||
|
|
||||||
|
- 3-4cm の炎で 2-3 時間
|
||||||
|
- 最大 3 時間 47 分
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
# 製作メモ
|
||||||
|
|
||||||
|
## UCO キャンドルランタンの寸法 (mm)
|
||||||
|
|
||||||
|
| 筒の経 | 筒の長さ | 筒口(上) | 土台経 | キャップ内径 | 筒露出長 |
|
||||||
|
| ------ | -------- | ---------- | ------ | ------------ | -------- |
|
||||||
|
| 35.0 | 92.45 | 20.0 | 32.5 | 41.7 | 9.0 |
|
||||||
|
|
||||||
|
## やってみたい
|
||||||
|
|
||||||
|
- **内径が 18 ~ 21、太さが 2mm 程度**で耐油性のあるパッキンを試す
|
||||||
|
- M8 ボルトが通り、外径がガラス内径に近い低めの瓶を探す
|
||||||
|
- ガスケットで密封?
|
||||||
|
|
||||||
|
## 失敗例: M6 ボルトは微妙
|
||||||
|
|
||||||
|
ネットで広く紹介されている M6 ボルトを使う方法だと、炎がロウソク並に小さくなってしまった。あまりオススメできない。
|
||||||
|
|
||||||
|

|
BIN
source/_posts/2021/uco-oil-lantern/comparison.jpeg
Executable file
BIN
source/_posts/2021/uco-oil-lantern/comparison.jpeg
Executable file
Binary file not shown.
After Width: | Height: | Size: 838 KiB |
BIN
source/_posts/2021/uco-oil-lantern/lantern.jpeg
Executable file
BIN
source/_posts/2021/uco-oil-lantern/lantern.jpeg
Executable file
Binary file not shown.
After Width: | Height: | Size: 1.3 MiB |
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user