https://uechi.io uechi.io 2022-05-19T15:00:00.000Z https://uechi.io/blog/building-mozc-for-macos/ Building mozc for macOS <p><a href="https://github.com/google/mozc">Mozc</a> is an open-source counterpart of Google Japanese Input, a Japanese input method developed by Google.</p> <h2 id="build-environment">Build environment</h2> <pre><code class="hljs plaintext">$ sw_vers ProductName: macOS ProductVersion: 12.6.1 BuildVersion: 21G217 $ xcodebuild -version Xcode 14.1 Build version 14B47b</code></pre> <h2 id="build-mozc">Build mozc</h2> <pre><code class="hljs bash"><span class="hljs-comment"># Install dependencies</span> brew install qt@5 bazel packages <span class="hljs-comment"># Clone the repository</span> git <span class="hljs-built_in">clone</span> https://github.com/google/mozc -b master --single-branch --recursive <span class="hljs-comment"># Build</span> <span class="hljs-built_in">cd</span> mozc/src MOZC_QT_PATH=/usr/local/opt/qt@5 ANDROID_NDK_HOME= bazel build package --config macos -c opt <span class="hljs-comment"># Install</span> open bazel-bin/mac/Mozc.pkg reboot</code></pre> 2022-05-19T15:00:00.000Z https://uechi.io/blog/root-ca-in-japan/ 国内のルート認証局とACME対応状況 <blockquote> <p>本記事と関係ないが在日ウクライナ大使館に寄付をした。なぜかというと、非常にお世話になっている<a href="https://fsnot.es">FSNotes</a>の開発者が先月末から続いているウクライナ侵攻によって <a href="https://twitter.com/FSNotesApp/status/1496865592242016259">OSS 活動を無期限停止せざるを得ない状況</a>に追い込まれており、少しでも支援をしたかったからだ。<a href="https://japan.mfa.gov.ua/ja">在日ウクライナ大使館のサイト</a>にアクセスできない状態が続いているため、<a href="https://twitter.com/UKRinJPN/status/1497100158693416961">公式ツイートから寄付先を参照</a>すると良い。</p> </blockquote> <h2 id="概要">概要</h2> <p>まず断っておきたいが、ルート認証局のせいで子孫 SSL 証明書の運用に問題が生じたことは<a href="https://wiki.mozilla.org/CA/WoSign_Issues">WoSign</a>や<a href="https://www.techtarget.com/searchsecurity/news/252527174/TrustCor-under-fire-over-certificate-authority-concerns">TrustCor</a>(TrustCor は少し毛色が違うが)の例を除いてほとんどない。わざわざ高額な手数料を支払うより、同じセキュリティ強度の証明書を無料で提供してくれる Let's Encrypt (ISRG)や ZeroSSL (Sectigo) をありがたく使わせていただく、そういう意識で問題ないのである。</p> <h2 id="国内唯一のルート認証局は-secom-が所有">国内唯一のルート認証局は SECOM が所有</h2> <ul> <li>Security Communication RootCA1 (<a href="https://crt.sh/?caid=53">crt.sh</a>)</li> <li>Security Communication RootCA2 (<a href="https://crt.sh/?caid=1160">crt.sh</a>)</li> </ul> <h2 id="個人が取得可能かつ自動更新に対応しているワイルドカード証明書の年間料金">個人が取得可能かつ自動更新に対応しているワイルドカード証明書の年間料金</h2> <p>金額は 2022 年 3 月現在。</p> <ul> <li>FujiSSL (SSLStore) 19,800 円</li> <li>FujiSSL 20,350 円</li> <li>JPRS (Gonbei Domain) 16,500 円</li> <li>JPRS (さくらの SSL) 18,150 円 クレカ不可(請求書払いのみ)</li> <li>JPRS (ラット) 15,000 円</li> <li>JPRS (JPDirect) 47,960 円</li> </ul> <p>FujiSSL、JPRS のルート認証局はどちらも Security Communication RootCA2 だ。</p> <p>FujiSSL は独自の自動更新ツールを提供しているが、ホストに PHP や Apache をセットアップしなければならず、HTTP サーバーを内蔵している lego や certbot と比べてやや煩雑な印象は拭えない。独自方式なので、当然 ACME 対応クライアントは使えない。</p> <h2 id="acme">ACME</h2> <p><a href="https://tex2e.github.io/rfc-translater/html/rfc8555.html">RFC 8555 - Automatic Certificate Management Environment (ACME)</a> は自動化されたドメイン認証 SSL 証明書発行手続きを標準化しようとする一連の努力の成果である。</p> <h2 id="jprs-が-acme-に対応">JPRS が ACME に対応</h2> <p>タイミングの良いことに、JPRS が 2022/3/2 から ACME に対応した。</p> <ul> <li><a href="https://jprs.jp/pubcert/about/ACME/">ACME について | JPRS</a></li> <li><a href="https://jprs.jp/pubcert/info/repository/acme-agreement.pdf">JPRS サーバー証明書発行サービス ACME 対応版ご利用条件 (PDF)</a></li> </ul> <p><a href="https://jprs.jp/pubcert/info/repository/JPRS-CP.pdf">JPRS サーバー証明書認証局証明書ポリシー</a>に目を通してどの認証方式に対応しているのか確認しよう。</p> <h3 id="dns-change">3.2.2.4.7 DNS Change</h3> <p>DNS ゾーンに<code>_acme-challenge</code> TXT レコードを置いてドメインの所有権を確認する方式。一番簡単で制約が少ない。</p> <h3 id="agreed-upon-change-to-website-v2">3.2.2.4.18 Agreed-Upon Change to Website v2</h3> <p>HTTP/HTTPS サーバーを立ち上げて<code>.well-known/pki-validation</code>以下に置いたチャレンジトークンを PKI 側が確認する方式。しかし、</p> <blockquote> <p>2021 年 11 月 18 日以降に発行する証明書について、先頭ラベルが"*"(ワイルドカード)の FQDN に対してこの方法を適用外とする。</p> </blockquote> <p>ワイルドカード証明書の場合この方式が使えない。</p> <h3 id="agreed-upon-change-to-website---acme">3.2.2.4.19 Agreed-Upon Change to Website - ACME</h3> <blockquote> <p>先頭ラベルが"*"(ワイルドカード)の FQDN に対してこの方法を適用外とする</p> </blockquote> <p>同上</p> <h3 id="caa-レコードの確認">4.2.4 CAA レコードの確認</h3> <blockquote> <p>本 CA は、RFC 6844 に従い、申請情報の審査時に CAA レコードを確認する。CAA レコードに記載する本 CA のドメインは「jprs.jp」とする。</p> </blockquote> <p>DNS ゾーンに CAA レコードを置いて内容を<code>jprs.jp</code>にする必要がある。</p> <h2 id="acme-クライアント">ACME クライアント</h2> <p>Go 製の ACME クライアント<a href="https://github.com/go-acme/lego">lego</a>は DNS-01 認証に対応しているため、JPRS ACME 証明書の発行がスムーズにできる可能性がある。</p> <pre><div class="caption"><span>コマンド例(執筆時点では動作しない)</span></div><code class="hljs bash">CLOUDFLARE_DNS_API_TOKEN=&lt;token&gt; \ lego \ --server <span class="hljs-string">'https://acme.amecert.jprs.jp/DV/getDirectory'</span> \ --eab --kid <span class="hljs-string">'NUtfiBgcWr9oGCWmF8PQd2d499T7WrgqsnkxIOAPASE'</span> --hmac <span class="hljs-string">'Shn8-aYwhUw0esMLnqJL_o9Fg_BszfAgrRJjOtGQGGY'</span> \ --accept-tos \ --path ./certs \ --dns cloudflare \ --email <span class="hljs-string">'[email protected]'</span> \ --domains <span class="hljs-string">'*.example.jp'</span> \ run</code></pre> <p><a href="https://github.com/nginx-proxy/acme-companion/wiki">nginx-proxy/acme-companion</a>は、<code>ACME_CA_URI</code>環境変数を指定することで JPRS に対応できるが、HTTP-01 認証に依存しているため ワイルドカード証明書は発行できないだろう。<a href="https://github.com/nginx-proxy/acme-companion/issues/319">今後対応する可能性</a>はある。</p> <pre><code class="hljs bash">docker run -d \ --name your-proxied-app \ -e <span class="hljs-string">"VIRTUAL_HOST=subdomain.example.jp"</span> \ -e <span class="hljs-string">"LETSENCRYPT_HOST=subdomain.example.jp"</span> \ -e <span class="hljs-string">"ACME_CA_URI=https://acme.amecert.jprs.jp/DV/getDirectory"</span> \ nginx</code></pre> <p>JPRS に問い合わせたところ、ACME の利用には JPRS と指定事業者両方の対応が必要になるそうだ。現在どの指定事業者も対応していないため、残念ながらもう少し待たなくてはならない。今後 ACME 経由で証明書の発行を試す機会があれば記事を更新する。</p> 2022-03-04T06:00:00.000Z https://uechi.io/blog/human-anatomy-atlas/ 解剖学アトラス <p>いつもの幅優先探索癖。アトラスの用途は美術解剖と消化器系の構造理解。</p> <h1 id="ノート">ノート</h1> <p>肉眼解剖学はアプローチの違いから局所解剖学と系統解剖学に分けられる。</p> <p>体表解剖は解剖学的構造と体表の特徴との関連を視覚的に理解するための節。 微視的レベルで観察する組織学—又の名を顕微鏡解剖学—が肉眼解剖学に対置する。</p> <p>他にも、胚からの成長過程に着目する発生学、部位の機能を明らかにする生理学、物質代謝の機序に興味をおく生化学等が周辺にある。</p> <p>テキスト、アトラス、カラーアトラスが一冊ずつあれば事足りそう。 個人的には『グレイ解剖学』、『ネッター解剖学アトラス』、『解剖学カラーアトラス』。 余裕があれば『プロメテウス解剖学アトラス 胸部/腹部・骨盤部』。</p> <h1 id="教科書">教科書</h1> <h2 id="グレイ解剖学-原著第-4-版">グレイ解剖学 原著第 4 版</h2> <p>2019(原著 2018)</p> <ul> <li>腹膜と腸間膜の節に限ってみても、筆者の「絶対にわからせる」という強い意志を感じさせる説明によって圧倒的にわからされてしまう</li> <li>各章は概観、局所解剖、体表解剖、臨床症例から構成されている、肉眼解剖学に的を絞った本</li> <li>腹腔・腹膜・腸間膜関連はプロメテウスより詳しい(特に一部腸管が二次的に腹膜後器官になる過程等)</li> <li>Meckel 憩室の臨床症例が写真とともに載っている</li> </ul> <h1 id="アトラス">アトラス</h1> <h2 id="ネッター解剖学アトラス-原著第-6-版">ネッター解剖学アトラス 原著第 6 版</h2> <p>2016(原著 2014)</p> <ul> <li>元々ノバルティスの販促のために描かれたイラストをまとめ上げたもの</li> <li>組織と筋肉、血管、神経がまとまって描かれており、位置関係がわかりやすい</li> <li>断面解剖の CT と図譜両方がある(プロメテウスは CT のみ)</li> <li>グラントと比べてカラフル</li> </ul> <h2 id="グラント解剖学図譜-第-7-版">グラント解剖学図譜 第 7 版</h2> <p>2016(原著 2013)</p> <ul> <li>イラストは立体感を把握しやすいタッチ</li> </ul> <h2 id="プロメテウス解剖学アトラス-解剖学総論運動器系-第-3-版">プロメテウス解剖学アトラス 解剖学総論/運動器系 第 3 版</h2> <p>2017(原著 2014)</p> <ul> <li>全身の骨格から筋肉、血管、神経、リンパ系が一通り概説されている</li> <li>ポージングの参考になる関節力学の知見が豊富</li> <li>消化器系は解説なし</li> <li>病例と診断方法、その施術指南が特徴</li> </ul> <h2 id="プロメテウス解剖学アトラス-口腔頭頸部-第-2-版">プロメテウス解剖学アトラス 口腔・頭頸部 第 2 版</h2> <p>2018(原著 2015)</p> <ul> <li>脳、頭部、口腔、頸部に絞って解説</li> <li>口腔から食道、胃までの部分に関する記述が非常に豊富</li> <li>歯科臨床を意識した紙面構成</li> <li>口腔・頭頸部以外の部位についての説明もざっくりされている</li> </ul> <h2 id="プロメテウス解剖学アトラス-胸部腹部骨盤部-第-3-版">プロメテウス解剖学アトラス 胸部/腹部・骨盤部 第 3 版</h2> <p>2020(原著 2015)</p> <ul> <li>胸部から腹部にかけて発生学・解剖学の図説が中心</li> <li>食道の筋の機能的構造の図解など、グレイ解剖学には載っていない内容も多い</li> </ul> <h2 id="プロメテウス解剖学-コアアトラス-第-3-版">プロメテウス解剖学 コアアトラス 第 3 版</h2> <p>2016</p> <ul> <li>プロメテウス 3 巻を一冊にまとめた本で、部位ごとに内容が集約されている</li> <li>胃の解説に 2 ページしか割かれていないなど、情報が広く浅い</li> </ul> <h1 id="カラーアトラス">カラーアトラス</h1> <h2 id="解剖学カラーアトラス-第-8-版-a-photographic-atlas">解剖学カラーアトラス 第 8 版 A Photographic Atlas</h2> <p>2016(原著 2016)</p> <ul> <li>ほとんどがリアルな解剖写真</li> <li>写真と共に図解イラストが対照されており理解が捗る</li> <li>図とアノテーションしか無いため、機能理解は他の本に頼る必要がある</li> <li>ユニークな点として、胎児の矢状断面図が掲載されている</li> </ul> <h2 id="人体解剖カラーアトラス-原著第-8-版-clinical-atlas-of-human-anatomy">人体解剖カラーアトラス 原著第 8 版 Clinical Atlas of Human Anatomy</h2> <ul> <li>こちらも基本的にアノテーションのみだが、注釈的説明が若干多め</li> <li>解剖学カラーアトラスと比べて 140 ページ少ない</li> <li>腹膜のヒダの写真はこちらにしか載っていない</li> </ul> <h1 id="アプリ">アプリ</h1> <h2 id="human-anatomy-atlas">Human Anatomy Atlas</h2> <p>https://apps.apple.com/jp/app/human-anatomy-atlas-2021/id1117998129?l=en</p> <ul> <li>毎年 11 月から 12 月頃にセールをしている</li> </ul> <h1 id="web-サイト">Web サイト</h1> <ul> <li>1 年生の解剖学辞典 - https://anatomy1.net/</li> <li>医学生の教科書 - https://store.isho.jp/</li> </ul> <h1 id="知見">知見</h1> <ul> <li>食道は腰椎と胸大動脈の前方、気管と心臓の後方を通る</li> <li>横隔膜のすぐ上方に心臓、すぐ下方に胃がある</li> <li>食道の正常な内径は 20mm</li> <li>食道には縦走ヒダが走っているが、Z 線を超えると胃底となり模様が変化する</li> <li>噴門括約筋は横隔膜食道裂孔の筋肉が代行しており、ジグザグ状であるので Z 線と呼ばれている(リング状に筋肉が縮まるのではなく、ジグザグ状の縦筋が縮まることで噴門を締め上げている)→ プロメテウス胸部 p. 168</li> <li>心臓はわずかに左にずれているため、左肺は右肺より小さい</li> <li>憩室といえば大腸だと思っていたが、食道にも発生する → プロメテウス胸部 p. 169</li> <li>「滑り説」筋収縮のメカニズムの学説のひとつ</li> </ul> <h1 id="用語">用語</h1> <ul> <li>翻転(ほんてん) - 組織をひっくりかえすこと</li> <li>腋窩(えきか)</li> <li>網嚢孔(もうのうこう)</li> <li>横紋筋(おうもんきん)と平滑筋(へいかつきん)</li> <li>蠕動運動(ぜんどう—)</li> </ul> 2021-06-07T15:00:00.000Z https://uechi.io/blog/uco-oil-lantern/ 手のひらサイズのオイルランタン <p>UCO キャンドルランタンを改造して手のひらサイズのオイルランタンを作った。</p> <p><img src="lantern.jpeg"></p> <h1 id="特徴">特徴</h1> <ul> <li>手のひらサイズのオイルランタン</li> <li>ロウソクより大きい炎</li> <li>暗所でもオイル残量が見やすい</li> <li>揺らしてもオイルが漏れない</li> <li>瓶を入れたまま仕舞える</li> </ul> <h1 id="材料">材料</h1> <p>ほとんどのパーツはドラッグストアやホームセンターで調達できる。</p> <ol type="1"> <li>大正漢方胃腸薬(30 ml) <img src="taisho.png"></li> <li>C タイプアンカー M8(ステンレス)</li> <li>袋ナット M8(ステンレス)</li> <li>ハードロックボルト M8(ステンレス)</li> <li><a href="https://www.amazon.co.jp/gp/product/B003PHKRZS">ゴムパッキン 直径 28x 内径 23x 厚さ 2mm</a>(耐熱ではないけど今のところ耐えている)</li> <li><a href="https://www.amazon.co.jp/gp/product/B07X1VZFGB">3mm グラスファイバー芯</a></li> <li>隙間テープ(ダイソー)</li> </ol> <h1 id="手順">手順</h1> <ol type="1"> <li>M8 アンカーのネジ部分を金属ノコギリで切断して断面をヤスリで整える</li> <li>キャップに印字されているラベルをヤスリで削りとる(任意)</li> <li>キャップの裏に張り付いている液漏れ防止シールを剥がす(熱で溶解するため)</li> <li>キャップの内側からドリルで穴をあけ、棒やすりでネジが入るサイズまで広げる</li> <li>ネジをキャップに差し込む</li> <li>ゴムパッキンをキャップの裏にはめ込む</li> <li>ハードロックボルトでネジの両側を固定する(レンチ等を使用して強く固定する)</li> <li>芯をボルトの中に通す(テープで芯の先を固定するとやりやすい)</li> <li>袋ネジで封をする</li> <li>切断した隙間テープをランタンの底面キャップに巻きつける</li> <li>瓶をランタンに差し込み底面キャップを締める</li> </ol> <h1 id="使用法">使用法</h1> <ol type="1"> <li>パラフィンオイルを 4/5 ほど入れてキャップを締め、オイルが芯の先に浸透するまで 15 分以上放置する</li> <li>芯の焦げている部分を 1mm 前後、それ以外の部分を 1mm ほど露出させてほぐす</li> <li>芯に火を付けてホヤを上げる</li> <li>使わないときはオイルを抜く(オイルが入ったままだと毛細管現象で染み出してくる)</li> </ol> <h2 id="燃焼時間">🔥 燃焼時間</h2> <ul> <li>3-4cm の炎で 2-3 時間</li> <li>最大 3 時間 47 分</li> </ul> <p><img src="lantern2.jpg"></p> <h1 id="製作メモ">製作メモ</h1> <h2 id="uco-キャンドルランタンの寸法-mm">UCO キャンドルランタンの寸法 (mm)</h2> <table> <thead> <tr class="header"> <th>筒の経</th> <th>筒の長さ</th> <th>筒口(上)</th> <th>土台経</th> <th>キャップ内径</th> <th>筒露出長</th> </tr> </thead> <tbody> <tr class="odd"> <td>35.0</td> <td>92.45</td> <td>20.0</td> <td>32.5</td> <td>41.7</td> <td>9.0</td> </tr> </tbody> </table> <h2 id="やってみたい">やってみたい</h2> <ul> <li><strong>内径が 18 ~ 21、太さが 2mm 程度</strong>で耐油性のあるパッキンを試す</li> <li>M8 ボルトが通り、外径がガラス内径に近い低めの瓶を探す</li> <li>ガスケットで密封?</li> </ul> <h2 id="失敗例-m6-ボルトは微妙">失敗例: M6 ボルトは微妙</h2> <p>ネットで広く紹介されている M6 ボルトを使う方法だと、炎がロウソク並に小さくなってしまった。あまりオススメできない。</p> <p><img src="comparison.jpeg"></p> 2021-06-07T15:00:00.000Z https://uechi.io/blog/affinity-thumbnail/ Distill Thumbnail from .afphoto and .afdesign <p><a href="https://en.wikipedia.org/wiki/Nextcloud">Nextcloud</a> does not support generating thumbnails from <a href="https://en.wikipedia.org/wiki/Affinity_Photo">Affinity Photo</a> and <a href="https://en.wikipedia.org/wiki/Affinity_Designer">Affinity Designer</a>. Fine, I'll do it myself!</p> <h1 id="digging-binary">Digging Binary</h1> <p>Glancing at <code>.afphoto</code> and <code>.afdesign</code> in Finder, I noticed that it has a QuickLook support and an ability to show the thumbnail image. Meaning there's a chance that these files contain <strong>pre-generated thumbnail images</strong> somewhere inside its binaries, meaning I don't have to reverse-engineer their format from ground up.</p> <p>To verify this, I wrote a piece of Node.js script to seek for <a href="https://www.w3.org/TR/PNG/">PNG blob</a> inside an .afphoto/.afdesign file and save it as a normal PNG file.</p> <p>In the <a href="https://www.w3.org/TR/PNG/#11Chunks">11.2.1 General</a> of the PNG spec, they stated a valid PNG image should begin with a PNG signature and end with an <code>IEND</code> chunk.</p> <blockquote> <p>A valid PNG datastream shall begin with a PNG signature, immediately followed by an <code>IHDR</code> chunk, then one or more <code>IDAT</code> chunks, and shall end with an <code>IEND</code> chunk. Only one <code>IHDR</code> chunk and one <code>IEND</code> chunk are allowed in a PNG datastream.</p> </blockquote> <p>Conveniently, it is also guaranteed that there should be <strong>only one IEND chunk</strong> in a PNG file, so greedy search would just work.</p> <pre><div class="caption"><span>gen_thumbnail.js</span></div><code class="hljs js"><span class="hljs-keyword">const</span> fs = <span class="hljs-built_in">require</span>(<span class="hljs-string">"fs"</span>); <span class="hljs-comment">// png spec: https://www.w3.org/TR/PNG/</span> <span class="hljs-keyword">const</span> <span class="hljs-variable constant_">PNG_SIG</span> = <span class="hljs-title class_">Buffer</span>.<span class="hljs-title function_">from</span>([<span class="hljs-number">137</span>, <span class="hljs-number">80</span>, <span class="hljs-number">78</span>, <span class="hljs-number">71</span>, <span class="hljs-number">13</span>, <span class="hljs-number">10</span>, <span class="hljs-number">26</span>, <span class="hljs-number">10</span>]); <span class="hljs-keyword">const</span> <span class="hljs-variable constant_">IEND_SIG</span> = <span class="hljs-title class_">Buffer</span>.<span class="hljs-title function_">from</span>([<span class="hljs-number">73</span>, <span class="hljs-number">69</span>, <span class="hljs-number">78</span>, <span class="hljs-number">68</span>]); <span class="hljs-keyword">function</span> <span class="hljs-title function_">extractPngBlob</span>(<span class="hljs-params">buf</span>) { <span class="hljs-keyword">const</span> start = buf.<span class="hljs-title function_">indexOf</span>(<span class="hljs-variable constant_">PNG_SIG</span>); <span class="hljs-keyword">const</span> end = buf.<span class="hljs-title function_">indexOf</span>(<span class="hljs-variable constant_">IEND_SIG</span>, start) + <span class="hljs-variable constant_">IEND_SIG</span>.<span class="hljs-property">length</span> * <span class="hljs-number">2</span>; <span class="hljs-comment">// IEND + CRC</span> <span class="hljs-keyword">return</span> buf.<span class="hljs-title function_">subarray</span>(start, end); } <span class="hljs-keyword">function</span> <span class="hljs-title function_">extractThumbnail</span>(<span class="hljs-params">input, output</span>) { <span class="hljs-keyword">const</span> buf = fs.<span class="hljs-title function_">readFileSync</span>(input); <span class="hljs-keyword">const</span> pngBlob = <span class="hljs-title function_">extractPngBlob</span>(buf); fs.<span class="hljs-title function_">writeFileSync</span>(output, pngBlob); } <span class="hljs-title function_">extractThumbnail</span>(process.<span class="hljs-property">argv</span>[<span class="hljs-number">2</span>], process.<span class="hljs-property">argv</span>[<span class="hljs-number">3</span>] || <span class="hljs-string">"output.png"</span>);</code></pre> <p>That's right. This script just do <code>indexOf</code> on a <code>Buffer</code> and distill a portion of which starts with <code>PNG</code> signature and ends with <code>IEND</code> (+ CRC checksum).</p> <h1 id="crc-cyclic-redundancy-code">CRC (Cyclic Redundancy Code)</h1> <p>You may have wondered about <code>IEND_SIG.length * 2</code> part. It was to include <a href="https://en.wikipedia.org/wiki/Cyclic_redundancy_check#CRC-32_algorithm">32-bit CRC</a> (Cyclic Redundancy Code) for <code>IEND</code> to the resulting blob.</p> <p>Here, the byte-length of <code>IEND</code> chunk and its <code>CRC</code> checksum are coincidentally the same (4 bytes), so I just went with that code.</p> <p>Now I can generate a thumbnail image from arbitrary <code>.afphoto</code> and <code>.afdesign</code> file. Let's move on delving into Nextcloud source code.</p> <h1 id="tweaking-nextcloud">Tweaking Nextcloud</h1> <p>At this point, all I have to do is to rewrite the above code in PHP and make them to behave as a Nextcloud Preview Provider.</p> <pre><div class="caption"><span>lib/private/Preview/Affinity.php</span></div><code class="hljs php"><span class="hljs-meta">&lt;?php</span> <span class="hljs-keyword">namespace</span> <span class="hljs-title class_">OC</span>\<span class="hljs-title class_">Preview</span>; <span class="hljs-keyword">use</span> <span class="hljs-title">OCP</span>\<span class="hljs-title">Files</span>\<span class="hljs-title">File</span>; <span class="hljs-keyword">use</span> <span class="hljs-title">OCP</span>\<span class="hljs-title">IImage</span>; <span class="hljs-keyword">use</span> <span class="hljs-title">OCP</span>\<span class="hljs-title">ILogger</span>; <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Affinity</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">ProviderV2</span> </span>{ <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getMimeType</span>(<span class="hljs-params"></span>): <span class="hljs-title">string</span> </span>{ <span class="hljs-keyword">return</span> <span class="hljs-string">'/application\/x-affinity-(?:photo|design)/'</span>; } <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getThumbnail</span>(<span class="hljs-params">File <span class="hljs-variable">$file</span>, <span class="hljs-keyword">int</span> <span class="hljs-variable">$maxX</span>, <span class="hljs-keyword">int</span> <span class="hljs-variable">$maxY</span></span>): ?<span class="hljs-title">IImage</span> </span>{ <span class="hljs-variable">$tmpPath</span> = <span class="hljs-variable language_">$this</span>-&gt;<span class="hljs-title function_ invoke__">getLocalFile</span>(<span class="hljs-variable">$file</span>); <span class="hljs-variable">$handle</span> = <span class="hljs-title function_ invoke__">fopen</span>(<span class="hljs-variable">$tmpPath</span>, <span class="hljs-string">'rb'</span>); <span class="hljs-variable">$fsize</span> = <span class="hljs-title function_ invoke__">filesize</span>(<span class="hljs-variable">$tmpPath</span>); <span class="hljs-variable">$contents</span> = <span class="hljs-title function_ invoke__">fread</span>(<span class="hljs-variable">$handle</span>, <span class="hljs-variable">$fsize</span>); <span class="hljs-variable">$start</span> = <span class="hljs-title function_ invoke__">strrpos</span>(<span class="hljs-variable">$contents</span>, <span class="hljs-string">"\x89PNG"</span>); <span class="hljs-variable">$end</span> = <span class="hljs-title function_ invoke__">strrpos</span>(<span class="hljs-variable">$contents</span>, <span class="hljs-string">"IEND"</span>, <span class="hljs-variable">$start</span>); <span class="hljs-variable">$subarr</span> = <span class="hljs-title function_ invoke__">substr</span>(<span class="hljs-variable">$contents</span>, <span class="hljs-variable">$start</span>, <span class="hljs-variable">$end</span> - <span class="hljs-variable">$start</span> + <span class="hljs-number">8</span> ); <span class="hljs-title function_ invoke__">fclose</span>(<span class="hljs-variable">$handle</span>); <span class="hljs-variable language_">$this</span>-&gt;<span class="hljs-title function_ invoke__">cleanTmpFiles</span>(); <span class="hljs-variable">$image</span> = <span class="hljs-keyword">new</span> <span class="hljs-title class_">\OC_Image</span>(); <span class="hljs-variable">$image</span>-&gt;<span class="hljs-title function_ invoke__">loadFromData</span>(<span class="hljs-variable">$subarr</span>); <span class="hljs-variable">$image</span>-&gt;<span class="hljs-title function_ invoke__">scaleDownToFit</span>(<span class="hljs-variable">$maxX</span>, <span class="hljs-variable">$maxY</span>); <span class="hljs-keyword">return</span> <span class="hljs-variable">$image</span>-&gt;<span class="hljs-title function_ invoke__">valid</span>() ? <span class="hljs-variable">$image</span> : <span class="hljs-literal">null</span>; } }</code></pre> <p>Also make sure my component to be auto-loaded on startup.</p> <pre><div class="caption"><span>lib/private/PreviewManager.php</span></div><code class="hljs patch"><span class="hljs-meta">@@ -363,6 +365,8 @@</span> $this-&gt;registerCoreProvider(Preview\Krita::class, '/application\/x-krita/'); $this-&gt;registerCoreProvider(Preview\MP3::class, '/audio\/mpeg/'); $this-&gt;registerCoreProvider(Preview\OpenDocument::class, '/application\/vnd.oasis.opendocument.*/'); <span class="hljs-addition">+ $this-&gt;registerCoreProvider(Preview\Affinity::class, '/application\/x-affinity-(?:photo|design)/');</span> // SVG, Office and Bitmap require imagick if (extension_loaded('imagick')) {</code></pre> <pre><div class="caption"><span>lib/composer/composer/autoload_static.php</span></div><code class="hljs patch"><span class="hljs-meta">@@ -1226,6 +1226,7 @@</span> 'OC\\OCS\\Result' =&gt; __DIR__ . '/../../..' . '/lib/private/OCS/Result.php', 'OC\\PreviewManager' =&gt; __DIR__ . '/../../..' . '/lib/private/PreviewManager.php', 'OC\\PreviewNotAvailableException' =&gt; __DIR__ . '/../../..' . '/lib/private/PreviewNotAvailableException.php', <span class="hljs-addition">+ 'OC\\Preview\\Affinity' =&gt; __DIR__ . '/../../..' . '/lib/private/Preview/Affinity.php',</span> 'OC\\Preview\\BMP' =&gt; __DIR__ . '/../../..' . '/lib/private/Preview/BMP.php', 'OC\\Preview\\BackgroundCleanupJob' =&gt; __DIR__ . '/../../..' . '/lib/private/Preview/BackgroundCleanupJob.php', 'OC\\Preview\\Bitmap' =&gt; __DIR__ . '/../../..' . '/lib/private/Preview/Bitmap.php',</code></pre> <pre><div class="caption"><span>lib/composer/composer/autoload_classmap.php</span></div><code class="hljs patch"><span class="hljs-meta">@@ -1197,6 +1197,7 @@</span> 'OC\\OCS\\Result' =&gt; $baseDir . '/lib/private/OCS/Result.php', 'OC\\PreviewManager' =&gt; $baseDir . '/lib/private/PreviewManager.php', 'OC\\PreviewNotAvailableException' =&gt; $baseDir . '/lib/private/PreviewNotAvailableException.php', <span class="hljs-addition">+ 'OC\\Preview\\Affinity' =&gt; $baseDir . '/lib/private/Preview/Affinity.php',</span> 'OC\\Preview\\BMP' =&gt; $baseDir . '/lib/private/Preview/BMP.php', 'OC\\Preview\\BackgroundCleanupJob' =&gt; $baseDir . '/lib/private/Preview/BackgroundCleanupJob.php', 'OC\\Preview\\Bitmap' =&gt; $baseDir . '/lib/private/Preview/Bitmap.php',</code></pre> <p><img src="afphoto.png"></p> <p>Voilà! Now I can see beautiful thumbnails for my drawings in Nextcloud web interface.</p> <p>This is exactly why I love FOSS. It allows me to materialize <strong>any niche things</strong> I want in the FOSS without bothering its developers. This fact not only gives me confidence that I can control the functionality of the software, but it also makes me have more trust in the developers for giving me such freedom to make changes to their software.</p> <h1 id="finalized-solution">Finalized Solution</h1> <p>Enough talking, I've pushed my Nextcloud Docker setup with the above patches included on <a href="https://github.com/uetchy/docker-nextcloud">GitHub</a>. You can see the actual patch <a href="https://github.com/uetchy/docker-nextcloud/blob/master/patches/lib.patch">here</a>. Note that it also contains the patches for PDF thumbnail generator described below, and this particular patch <em>may</em> pose security implications because of the usage of Ghostscript against PDF.</p> <h1 id="bonus-pdf-thumbnail-generator">Bonus: PDF thumbnail generator</h1> <p>Install <code>ghostscript</code> on your server to make it work.</p> <pre><div class="caption"><span>lib/private/Preview/PDF.php</span></div><code class="hljs php"><span class="hljs-meta">&lt;?php</span> <span class="hljs-keyword">namespace</span> <span class="hljs-title class_">OC</span>\<span class="hljs-title class_">Preview</span>; <span class="hljs-keyword">use</span> <span class="hljs-title">OCP</span>\<span class="hljs-title">Files</span>\<span class="hljs-title">File</span>; <span class="hljs-keyword">use</span> <span class="hljs-title">OCP</span>\<span class="hljs-title">IImage</span>; <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">PDF</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">ProviderV2</span> </span>{ <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getMimeType</span>(<span class="hljs-params"></span>): <span class="hljs-title">string</span> </span>{ <span class="hljs-keyword">return</span> <span class="hljs-string">'/application\/pdf/'</span>; } <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getThumbnail</span>(<span class="hljs-params">File <span class="hljs-variable">$file</span>, <span class="hljs-keyword">int</span> <span class="hljs-variable">$maxX</span>, <span class="hljs-keyword">int</span> <span class="hljs-variable">$maxY</span></span>): ?<span class="hljs-title">IImage</span> </span>{ <span class="hljs-variable">$tmpPath</span> = <span class="hljs-variable language_">$this</span>-&gt;<span class="hljs-title function_ invoke__">getLocalFile</span>(<span class="hljs-variable">$file</span>); <span class="hljs-variable">$outputPath</span> = \OC::<span class="hljs-variable">$server</span>-&gt;<span class="hljs-title function_ invoke__">getTempManager</span>()-&gt;<span class="hljs-title function_ invoke__">getTemporaryFile</span>(); <span class="hljs-variable">$gsBin</span> = <span class="hljs-title class_">\OC_Helper</span>::<span class="hljs-title function_ invoke__">findBinaryPath</span>(<span class="hljs-string">'gs'</span>); <span class="hljs-variable">$cmd</span> = <span class="hljs-variable">$gsBin</span> . <span class="hljs-string">" -o "</span> . <span class="hljs-title function_ invoke__">escapeshellarg</span>(<span class="hljs-variable">$outputPath</span>) . <span class="hljs-string">" -sDEVICE=jpeg -sPAPERSIZE=a4 -dLastPage=1 -dPDFFitPage -dJPEGQ=90 -r144 "</span> . <span class="hljs-title function_ invoke__">escapeshellarg</span>(<span class="hljs-variable">$tmpPath</span>); <span class="hljs-title function_ invoke__">shell_exec</span>(<span class="hljs-variable">$cmd</span>); <span class="hljs-variable language_">$this</span>-&gt;<span class="hljs-title function_ invoke__">cleanTmpFiles</span>(); <span class="hljs-variable">$image</span> = <span class="hljs-keyword">new</span> <span class="hljs-title class_">\OC_Image</span>(); <span class="hljs-variable">$image</span>-&gt;<span class="hljs-title function_ invoke__">loadFromFile</span>(<span class="hljs-variable">$outputPath</span>); <span class="hljs-variable">$image</span>-&gt;<span class="hljs-title function_ invoke__">scaleDownToFit</span>(<span class="hljs-variable">$maxX</span>, <span class="hljs-variable">$maxY</span>); <span class="hljs-title function_ invoke__">unlink</span>(<span class="hljs-variable">$outputPath</span>); <span class="hljs-keyword">return</span> <span class="hljs-variable">$image</span>-&gt;<span class="hljs-title function_ invoke__">valid</span>() ? <span class="hljs-variable">$image</span> : <span class="hljs-literal">null</span>; } }</code></pre> 2021-02-14T04:30:00.000Z https://uechi.io/blog/parseint-magic/ [].map(parseInt) <p>Fun fact: <code>[0xa, 0xa, 0xa].map(parseInt)</code> yields <code>[10, NaN, 2]</code>.</p> <h1 id="why">Why</h1> <pre><code class="hljs js"><span class="hljs-built_in">parseInt</span>(<span class="hljs-number">0xa</span>, <span class="hljs-number">0</span>, [<span class="hljs-number">0xa</span>, <span class="hljs-number">0xa</span>, <span class="hljs-number">0xa</span>]);</code></pre> <p>The second argument is <code>0</code> so the first argument going to be treated as decimal number becoming <code>10</code>.</p> <pre><code class="hljs js"><span class="hljs-built_in">parseInt</span>(<span class="hljs-number">0xa</span>, <span class="hljs-number">1</span>, [<span class="hljs-number">0xa</span>, <span class="hljs-number">0xa</span>, <span class="hljs-number">0xa</span>]);</code></pre> <p>The second argument is <code>1</code> which is invalid as a radix, so the result ends up with <code>NaN</code>.</p> <pre><code class="hljs js"><span class="hljs-built_in">parseInt</span>(<span class="hljs-number">0xa</span>, <span class="hljs-number">2</span>, [<span class="hljs-number">0xa</span>, <span class="hljs-number">0xa</span>, <span class="hljs-number">0xa</span>]);</code></pre> <p>The second argument is <code>2</code> meaning the first argument going to be handled as a binary number. <code>0xa</code> is <code>10</code> in binary, which results in <code>2</code> in decimal form.</p> 2021-02-14T02:30:00.000Z https://uechi.io/blog/split-bill/ 最小送金回数で精算する割り勘アルゴリズム <p>大人数で旅行を楽しんだあとに待っているのは耐え難き精算・送金処理だ。 次回から楽をするためにも、送金回数を最小化する制約で精算表を作る方法を考えよう。</p> <h1 id="tldr">tl;dr</h1> <p>アイディアは「最も支払わなかった人が最も支払った人に払えるだけ払う ⇢ 債権を再計算して繰り返す」</p> <ol type="1"> <li>全員の出費を算出(払い過ぎは正、払わなさすぎは負の数)</li> <li>降順でソート(出費過多が先頭)</li> <li>リストの最後(最大債務者, 出費=L)がリストの最初(最大債権者, F)に <span class="math inline"><mjx-container class="MathJax" jax="SVG"><svg style="vertical-align: -0.566ex;" xmlns="http://www.w3.org/2000/svg" width="11.031ex" height="2.262ex" role="img" focusable="false" viewBox="0 -750 4875.7 1000"><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="mo"><path data-c="6D" d="M41 46H55Q94 46 102 60V68Q102 77 102 91T102 122T103 161T103 203Q103 234 103 269T102 328V351Q99 370 88 376T43 385H25V408Q25 431 27 431L37 432Q47 433 65 434T102 436Q119 437 138 438T167 441T178 442H181V402Q181 364 182 364T187 369T199 384T218 402T247 421T285 437Q305 442 336 442Q351 442 364 440T387 434T406 426T421 417T432 406T441 395T448 384T452 374T455 366L457 361L460 365Q463 369 466 373T475 384T488 397T503 410T523 422T546 432T572 439T603 442Q729 442 740 329Q741 322 741 190V104Q741 66 743 59T754 49Q775 46 803 46H819V0H811L788 1Q764 2 737 2T699 3Q596 3 587 0H579V46H595Q656 46 656 62Q657 64 657 200Q656 335 655 343Q649 371 635 385T611 402T585 404Q540 404 506 370Q479 343 472 315T464 232V168V108Q464 78 465 68T468 55T477 49Q498 46 526 46H542V0H534L510 1Q487 2 460 2T422 3Q319 3 310 0H302V46H318Q379 46 379 62Q380 64 380 200Q379 335 378 343Q372 371 358 385T334 402T308 404Q263 404 229 370Q202 343 195 315T187 232V168V108Q187 78 188 68T191 55T200 49Q221 46 249 46H265V0H257L234 1Q210 2 183 2T145 3Q42 3 33 0H25V46H41Z"></path><path data-c="69" d="M69 609Q69 637 87 653T131 669Q154 667 171 652T188 609Q188 579 171 564T129 549Q104 549 87 564T69 609ZM247 0Q232 3 143 3Q132 3 106 3T56 1L34 0H26V46H42Q70 46 91 49Q100 53 102 60T104 102V205V293Q104 345 102 359T88 378Q74 385 41 385H30V408Q30 431 32 431L42 432Q52 433 70 434T106 436Q123 437 142 438T171 441T182 442H185V62Q190 52 197 50T232 46H255V0H247Z" transform="translate(833,0)"></path><path data-c="6E" d="M41 46H55Q94 46 102 60V68Q102 77 102 91T102 122T103 161T103 203Q103 234 103 269T102 328V351Q99 370 88 376T43 385H25V408Q25 431 27 431L37 432Q47 433 65 434T102 436Q119 437 138 438T167 441T178 442H181V402Q181 364 182 364T187 369T199 384T218 402T247 421T285 437Q305 442 336 442Q450 438 463 329Q464 322 464 190V104Q464 66 466 59T477 49Q498 46 526 46H542V0H534L510 1Q487 2 460 2T422 3Q319 3 310 0H302V46H318Q379 46 379 62Q380 64 380 200Q379 335 378 343Q372 371 358 385T334 402T308 404Q263 404 229 370Q202 343 195 315T187 232V168V108Q187 78 188 68T191 55T200 49Q221 46 249 46H265V0H257L234 1Q210 2 183 2T145 3Q42 3 33 0H25V46H41Z" transform="translate(1111,0)"></path></g><g data-mml-node="mo" transform="translate(1667,0)"><path data-c="28" d="M94 250Q94 319 104 381T127 488T164 576T202 643T244 695T277 729T302 750H315H319Q333 750 333 741Q333 738 316 720T275 667T226 581T184 443T167 250T184 58T225 -81T274 -167T316 -220T333 -241Q333 -250 318 -250H315H302L274 -226Q180 -141 137 -14T94 250Z"></path></g><g data-mml-node="mi" transform="translate(2056,0)"><path data-c="1D439" d="M48 1Q31 1 31 11Q31 13 34 25Q38 41 42 43T65 46Q92 46 125 49Q139 52 144 61Q146 66 215 342T285 622Q285 629 281 629Q273 632 228 634H197Q191 640 191 642T193 659Q197 676 203 680H742Q749 676 749 669Q749 664 736 557T722 447Q720 440 702 440H690Q683 445 683 453Q683 454 686 477T689 530Q689 560 682 579T663 610T626 626T575 633T503 634H480Q398 633 393 631Q388 629 386 623Q385 622 352 492L320 363H375Q378 363 398 363T426 364T448 367T472 374T489 386Q502 398 511 419T524 457T529 475Q532 480 548 480H560Q567 475 567 470Q567 467 536 339T502 207Q500 200 482 200H470Q463 206 463 212Q463 215 468 234T473 274Q473 303 453 310T364 317H309L277 190Q245 66 245 60Q245 46 334 46H359Q365 40 365 39T363 19Q359 6 353 0H336Q295 2 185 2Q120 2 86 2T48 1Z"></path></g><g data-mml-node="mo" transform="translate(2805,0)"><path data-c="2C" d="M78 35T78 60T94 103T137 121Q165 121 187 96T210 8Q210 -27 201 -60T180 -117T154 -158T130 -185T117 -194Q113 -194 104 -185T95 -172Q95 -168 106 -156T131 -126T157 -76T173 -3V9L172 8Q170 7 167 6T161 3T152 1T140 0Q113 0 96 17Z"></path></g><g data-mml-node="mo" transform="translate(3249.7,0) translate(0 -0.5)"><path data-c="7C" d="M139 -249H137Q125 -249 119 -235V251L120 737Q130 750 139 750Q152 750 159 735V-235Q151 -249 141 -249H139Z"></path></g><g data-mml-node="mi" transform="translate(3527.7,0)"><path data-c="1D43F" d="M228 637Q194 637 192 641Q191 643 191 649Q191 673 202 682Q204 683 217 683Q271 680 344 680Q485 680 506 683H518Q524 677 524 674T522 656Q517 641 513 637H475Q406 636 394 628Q387 624 380 600T313 336Q297 271 279 198T252 88L243 52Q243 48 252 48T311 46H328Q360 46 379 47T428 54T478 72T522 106T564 161Q580 191 594 228T611 270Q616 273 628 273H641Q647 264 647 262T627 203T583 83T557 9Q555 4 553 3T537 0T494 -1Q483 -1 418 -1T294 0H116Q32 0 32 10Q32 17 34 24Q39 43 44 45Q48 46 59 46H65Q92 46 125 49Q139 52 144 61Q147 65 216 339T285 628Q285 635 228 637Z"></path></g><g data-mml-node="mo" transform="translate(4208.7,0) translate(0 -0.5)"><path data-c="7C" d="M139 -249H137Q125 -249 119 -235V251L120 737Q130 750 139 750Q152 750 159 735V-235Q151 -249 141 -249H139Z"></path></g><g data-mml-node="mo" transform="translate(4486.7,0)"><path data-c="29" d="M60 749L64 750Q69 750 74 750H86L114 726Q208 641 251 514T294 250Q294 182 284 119T261 12T224 -76T186 -143T145 -194T113 -227T90 -246Q87 -249 86 -250H74Q66 -250 63 -250T58 -247T55 -238Q56 -237 66 -225Q221 -64 221 250T66 725Q56 737 55 738Q55 746 60 749Z"></path></g></g></g></svg></mjx-container></span> を支払ってバランス(負債)を再計算</li> <li>全員のバランスが 0 になるまで 2-3 を繰り返す</li> </ol> <h1 id="実験">実験</h1> <p>実際にコードを書いて本当に望んでいる結果が得られるのかを検証する。</p> <pre><div class="caption"><span>split-bill.js</span></div><code class="hljs js"><span class="hljs-keyword">const</span> history = [ { <span class="hljs-attr">amount</span>: <span class="hljs-number">121</span>, <span class="hljs-attr">payer</span>: <span class="hljs-string">"A"</span>, <span class="hljs-attr">involves</span>: [<span class="hljs-string">"A"</span>, <span class="hljs-string">"B"</span>, <span class="hljs-string">"C"</span>], }, { <span class="hljs-attr">amount</span>: <span class="hljs-number">98</span>, <span class="hljs-attr">payer</span>: <span class="hljs-string">"B"</span>, <span class="hljs-attr">involves</span>: [<span class="hljs-string">"A"</span>, <span class="hljs-string">"B"</span>, <span class="hljs-string">"C"</span>], }, { <span class="hljs-attr">amount</span>: <span class="hljs-number">10</span>, <span class="hljs-attr">payer</span>: <span class="hljs-string">"C"</span>, <span class="hljs-attr">involves</span>: [<span class="hljs-string">"A"</span>, <span class="hljs-string">"B"</span>, <span class="hljs-string">"C"</span>], }, { <span class="hljs-attr">amount</span>: <span class="hljs-number">10</span>, <span class="hljs-attr">payer</span>: <span class="hljs-string">"C"</span>, <span class="hljs-attr">involves</span>: [<span class="hljs-string">"A"</span>, <span class="hljs-string">"B"</span>], }, { <span class="hljs-attr">amount</span>: <span class="hljs-number">50</span>, <span class="hljs-attr">payer</span>: <span class="hljs-string">"C"</span>, <span class="hljs-attr">involves</span>: [<span class="hljs-string">"A"</span>], <span class="hljs-comment">// meaning C lent A 50</span> }, ]; <span class="hljs-comment">// calculate balance sheet</span> <span class="hljs-keyword">const</span> init = { <span class="hljs-attr">balance</span>: <span class="hljs-number">0</span>, <span class="hljs-attr">consumption</span>: <span class="hljs-number">0</span> }; <span class="hljs-title class_">Map</span>.<span class="hljs-property"><span class="hljs-keyword">prototype</span></span>.<span class="hljs-property">fetch</span> = <span class="hljs-keyword">function</span> (<span class="hljs-params">id</span>) { <span class="hljs-keyword">return</span> ( <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">get</span>(id) || <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">set</span>(id, <span class="hljs-title class_">Object</span>.<span class="hljs-title function_">assign</span>({ <span class="hljs-attr">name</span>: id }, init)).<span class="hljs-title function_">get</span>(id) ); }; <span class="hljs-keyword">const</span> data = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Map</span>(); <span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> { payer, amount, involves } <span class="hljs-keyword">of</span> history) { <span class="hljs-keyword">const</span> record = data.<span class="hljs-title function_">fetch</span>(payer); record.<span class="hljs-property">balance</span> += amount; <span class="hljs-keyword">const</span> debt = <span class="hljs-title class_">Math</span>.<span class="hljs-title function_">ceil</span>(amount / involves.<span class="hljs-property">length</span>); <span class="hljs-comment">// actual payer should not owe extra debt coming from rounded up numbers</span> <span class="hljs-keyword">const</span> payerDebt = amount - debt * (involves.<span class="hljs-property">length</span> - <span class="hljs-number">1</span>); <span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> debtor <span class="hljs-keyword">of</span> involves.<span class="hljs-title function_">map</span>(<span class="hljs-function">(<span class="hljs-params">i</span>) =&gt;</span> data.<span class="hljs-title function_">fetch</span>(i))) { <span class="hljs-keyword">const</span> cost = <span class="hljs-title class_">Math</span>.<span class="hljs-title function_">round</span>(amount / involves.<span class="hljs-property">length</span>); debtor.<span class="hljs-property">balance</span> -= cost; debtor.<span class="hljs-property">consumption</span> += cost; } } <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(data); <span class="hljs-comment">// calculate transaction table</span> <span class="hljs-keyword">const</span> transaction = []; <span class="hljs-keyword">let</span> paidTooMuch, paidLess; <span class="hljs-keyword">while</span> (<span class="hljs-literal">true</span>) { <span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> [_, tbl] <span class="hljs-keyword">of</span> data) { <span class="hljs-keyword">if</span> (tbl.<span class="hljs-property">balance</span> &gt;= (paidTooMuch?.<span class="hljs-property">balance</span> || <span class="hljs-number">0</span>)) { paidTooMuch = tbl; } <span class="hljs-keyword">if</span> (tbl.<span class="hljs-property">balance</span> &lt;= (paidLess?.<span class="hljs-property">balance</span> || <span class="hljs-number">0</span>)) { paidLess = tbl; } } <span class="hljs-keyword">if</span> (paidLess.<span class="hljs-property">balance</span> == <span class="hljs-number">0</span> || paidTooMuch.<span class="hljs-property">balance</span> == <span class="hljs-number">0</span>) <span class="hljs-keyword">break</span>; <span class="hljs-keyword">const</span> amount = <span class="hljs-title class_">Math</span>.<span class="hljs-title function_">min</span>(paidTooMuch.<span class="hljs-property">balance</span>, <span class="hljs-title class_">Math</span>.<span class="hljs-title function_">abs</span>(paidLess.<span class="hljs-property">balance</span>)); transaction.<span class="hljs-title function_">push</span>({ <span class="hljs-attr">sender</span>: paidLess.<span class="hljs-property">name</span>, <span class="hljs-attr">receiver</span>: paidTooMuch.<span class="hljs-property">name</span>, amount, }); paidTooMuch.<span class="hljs-property">balance</span> -= amount; paidLess.<span class="hljs-property">balance</span> += amount; } <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">"Settled"</span>); <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">"\n# Transaction table"</span>); <span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> ev <span class="hljs-keyword">of</span> transaction) { <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">`<span class="hljs-subst">${ev.sender}</span> owes <span class="hljs-subst">${ev.receiver}</span> ¥<span class="hljs-subst">${ev.amount}</span>`</span>); } <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">"\n# History"</span>); <span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> { payer, amount, involves } <span class="hljs-keyword">of</span> history) { <span class="hljs-keyword">if</span> (involves.<span class="hljs-property">length</span> === <span class="hljs-number">1</span>) { <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">`<span class="hljs-subst">${payer}</span> lent ¥<span class="hljs-subst">${amount}</span> to <span class="hljs-subst">${involves[<span class="hljs-number">0</span>]}</span>`</span>); } <span class="hljs-keyword">else</span> { <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">`<span class="hljs-subst">${payer}</span> paid ¥<span class="hljs-subst">${amount}</span> for <span class="hljs-subst">${involves.join(<span class="hljs-string">", "</span>)}</span>`</span>); } } <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">"\n# Expenses"</span>); <span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> [_, { name, consumption }] <span class="hljs-keyword">of</span> data) { <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">`<span class="hljs-subst">${name}</span> virtually paid ¥<span class="hljs-subst">${consumption}</span> in total`</span>); }</code></pre> <p><code>history</code>に支払い履歴を書き込んで実行すると、「送金表」「履歴」「実質支払総額」が得られる。</p> <pre><code class="hljs md"><span class="hljs-section"># Transaction table</span> A owes B ¥10 C owes B ¥6 <span class="hljs-section"># History</span> 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 <span class="hljs-section"># Expenses</span> A virtually paid ¥131 in total B virtually paid ¥81 in total C virtually paid ¥76 in total</code></pre> <p>旅行中、A と B は 1 回、C は 3 回支払いを建て替えた。そのうち 3 回は普通の割り勘だが、他 2 回はそれぞれ「C が A と B の分を建て替えた」「C が A の分を建て替えた(=C が A に金を貸した)」である。</p> <p>このようなケースで一件ずつナイーブに精算しようとすると、合計 12 回のお金のやり取りが発生することになる。しかし負債を同額の債権で打ち消す操作を繰り返して最適化した結果、たった 2 回お金のやり取りをするだけで全員分の精算を完了できることがわかった。</p> <p>プログラムに落とし込むことができたら、あとはスプレッドシートのマクロにするなりスマホのアプリにするなり自由だ。面倒なことは全部コンピューターにやらせよう!</p> 2021-02-13T15:00:00.000Z https://uechi.io/blog/braille/ 点字の表現力 <p>「n 種類の文字を表現できる点字を作らないといけなくなったらどうしよう」</p> <p>例としてドット が 3 つの点字を用意した。</p> <ul> <li>組み合わせ数は 3P3 + 3P2 + 3P1</li> <li><span class="math inline"><mjx-container class="MathJax" jax="SVG"><svg style="vertical-align: -0.777ex;" xmlns="http://www.w3.org/2000/svg" width="23.191ex" height="2.474ex" role="img" focusable="false" viewBox="0 -750 10250.5 1093.3"><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="mi"><path data-c="1D453" d="M118 -162Q120 -162 124 -164T135 -167T147 -168Q160 -168 171 -155T187 -126Q197 -99 221 27T267 267T289 382V385H242Q195 385 192 387Q188 390 188 397L195 425Q197 430 203 430T250 431Q298 431 298 432Q298 434 307 482T319 540Q356 705 465 705Q502 703 526 683T550 630Q550 594 529 578T487 561Q443 561 443 603Q443 622 454 636T478 657L487 662Q471 668 457 668Q445 668 434 658T419 630Q412 601 403 552T387 469T380 433Q380 431 435 431Q480 431 487 430T498 424Q499 420 496 407T491 391Q489 386 482 386T428 385H372L349 263Q301 15 282 -47Q255 -132 212 -173Q175 -205 139 -205Q107 -205 81 -186T55 -132Q55 -95 76 -78T118 -61Q162 -61 162 -103Q162 -122 151 -136T127 -157L118 -162Z"></path></g><g data-mml-node="mo" transform="translate(550,0)"><path data-c="28" d="M94 250Q94 319 104 381T127 488T164 576T202 643T244 695T277 729T302 750H315H319Q333 750 333 741Q333 738 316 720T275 667T226 581T184 443T167 250T184 58T225 -81T274 -167T316 -220T333 -241Q333 -250 318 -250H315H302L274 -226Q180 -141 137 -14T94 250Z"></path></g><g data-mml-node="mi" transform="translate(939,0)"><path data-c="1D441" d="M234 637Q231 637 226 637Q201 637 196 638T191 649Q191 676 202 682Q204 683 299 683Q376 683 387 683T401 677Q612 181 616 168L670 381Q723 592 723 606Q723 633 659 637Q635 637 635 648Q635 650 637 660Q641 676 643 679T653 683Q656 683 684 682T767 680Q817 680 843 681T873 682Q888 682 888 672Q888 650 880 642Q878 637 858 637Q787 633 769 597L620 7Q618 0 599 0Q585 0 582 2Q579 5 453 305L326 604L261 344Q196 88 196 79Q201 46 268 46H278Q284 41 284 38T282 19Q278 6 272 0H259Q228 2 151 2Q123 2 100 2T63 2T46 1Q31 1 31 10Q31 14 34 26T39 40Q41 46 62 46Q130 49 150 85Q154 91 221 362L289 634Q287 635 234 637Z"></path></g><g data-mml-node="mo" transform="translate(1827,0)"><path data-c="29" d="M60 749L64 750Q69 750 74 750H86L114 726Q208 641 251 514T294 250Q294 182 284 119T261 12T224 -76T186 -143T145 -194T113 -227T90 -246Q87 -249 86 -250H74Q66 -250 63 -250T58 -247T55 -238Q56 -237 66 -225Q221 -64 221 250T66 725Q56 737 55 738Q55 746 60 749Z"></path></g><g data-mml-node="mo" transform="translate(2493.8,0)"><path data-c="3D" d="M56 347Q56 360 70 367H707Q722 359 722 347Q722 336 708 328L390 327H72Q56 332 56 347ZM56 153Q56 168 72 173H708Q722 163 722 153Q722 140 707 133H70Q56 140 56 153Z"></path></g><g data-mml-node="munder" transform="translate(3549.6,0)"><g data-mml-node="mo"><path data-c="2211" d="M61 748Q64 750 489 750H913L954 640Q965 609 976 579T993 533T999 516H979L959 517Q936 579 886 621T777 682Q724 700 655 705T436 710H319Q183 710 183 709Q186 706 348 484T511 259Q517 250 513 244L490 216Q466 188 420 134T330 27L149 -187Q149 -188 362 -188Q388 -188 436 -188T506 -189Q679 -189 778 -162T936 -43Q946 -27 959 6H999L913 -249L489 -250Q65 -250 62 -248Q56 -246 56 -239Q56 -234 118 -161Q186 -81 245 -11L428 206Q428 207 242 462L57 717L56 728Q56 744 61 748Z"></path></g><g data-mml-node="TeXAtom" transform="translate(1089,-285.4) scale(0.707)" data-mjx-texclass="ORD"><g data-mml-node="mi"><path data-c="1D43E" d="M285 628Q285 635 228 637Q205 637 198 638T191 647Q191 649 193 661Q199 681 203 682Q205 683 214 683H219Q260 681 355 681Q389 681 418 681T463 682T483 682Q500 682 500 674Q500 669 497 660Q496 658 496 654T495 648T493 644T490 641T486 639T479 638T470 637T456 637Q416 636 405 634T387 623L306 305Q307 305 490 449T678 597Q692 611 692 620Q692 635 667 637Q651 637 651 648Q651 650 654 662T659 677Q662 682 676 682Q680 682 711 681T791 680Q814 680 839 681T869 682Q889 682 889 672Q889 650 881 642Q878 637 862 637Q787 632 726 586Q710 576 656 534T556 455L509 418L518 396Q527 374 546 329T581 244Q656 67 661 61Q663 59 666 57Q680 47 717 46H738Q744 38 744 37T741 19Q737 6 731 0H720Q680 3 625 3Q503 3 488 0H478Q472 6 472 9T474 27Q478 40 480 43T491 46H494Q544 46 544 71Q544 75 517 141T485 216L427 354L359 301L291 248L268 155Q245 63 245 58Q245 51 253 49T303 46H334Q340 37 340 35Q340 19 333 5Q328 0 317 0Q314 0 280 1T180 2Q118 2 85 2T49 1Q31 1 31 11Q31 13 34 25Q38 41 42 43T65 46Q92 46 125 49Q139 52 144 61Q147 65 216 339T285 628Z"></path></g><g data-mml-node="mo" transform="translate(889,0)"><path data-c="3D" d="M56 347Q56 360 70 367H707Q722 359 722 347Q722 336 708 328L390 327H72Q56 332 56 347ZM56 153Q56 168 72 173H708Q722 163 722 153Q722 140 707 133H70Q56 140 56 153Z"></path></g><g data-mml-node="mi" transform="translate(1667,0)"><path data-c="1D441" d="M234 637Q231 637 226 637Q201 637 196 638T191 649Q191 676 202 682Q204 683 299 683Q376 683 387 683T401 677Q612 181 616 168L670 381Q723 592 723 606Q723 633 659 637Q635 637 635 648Q635 650 637 660Q641 676 643 679T653 683Q656 683 684 682T767 680Q817 680 843 681T873 682Q888 682 888 672Q888 650 880 642Q878 637 858 637Q787 633 769 597L620 7Q618 0 599 0Q585 0 582 2Q579 5 453 305L326 604L261 344Q196 88 196 79Q201 46 268 46H278Q284 41 284 38T282 19Q278 6 272 0H259Q228 2 151 2Q123 2 100 2T63 2T46 1Q31 1 31 10Q31 14 34 26T39 40Q41 46 62 46Q130 49 150 85Q154 91 221 362L289 634Q287 635 234 637Z"></path></g><g data-mml-node="mo" transform="translate(2555,0)"><path data-c="2192" d="M56 237T56 250T70 270H835Q719 357 692 493Q692 494 692 496T691 499Q691 511 708 511H711Q720 511 723 510T729 506T732 497T735 481T743 456Q765 389 816 336T935 261Q944 258 944 250Q944 244 939 241T915 231T877 212Q836 186 806 152T761 85T740 35T732 4Q730 -6 727 -8T711 -11Q691 -11 691 0Q691 7 696 25Q728 151 835 230H70Q56 237 56 250Z"></path></g><g data-mml-node="mn" transform="translate(3555,0)"><path data-c="31" d="M213 578L200 573Q186 568 160 563T102 556H83V602H102Q149 604 189 617T245 641T273 663Q275 666 285 666Q294 666 302 660V361L303 61Q310 54 315 52T339 48T401 46H427V0H416Q395 3 257 3Q121 3 100 0H88V46H114Q136 46 152 46T177 47T193 50T201 52T207 57T213 61V578Z"></path></g></g></g><g data-mml-node="mi" transform="translate(7722.5,0)"><path data-c="1D441" d="M234 637Q231 637 226 637Q201 637 196 638T191 649Q191 676 202 682Q204 683 299 683Q376 683 387 683T401 677Q612 181 616 168L670 381Q723 592 723 606Q723 633 659 637Q635 637 635 648Q635 650 637 660Q641 676 643 679T653 683Q656 683 684 682T767 680Q817 680 843 681T873 682Q888 682 888 672Q888 650 880 642Q878 637 858 637Q787 633 769 597L620 7Q618 0 599 0Q585 0 582 2Q579 5 453 305L326 604L261 344Q196 88 196 79Q201 46 268 46H278Q284 41 284 38T282 19Q278 6 272 0H259Q228 2 151 2Q123 2 100 2T63 2T46 1Q31 1 31 10Q31 14 34 26T39 40Q41 46 62 46Q130 49 150 85Q154 91 221 362L289 634Q287 635 234 637Z"></path></g><g data-mml-node="mi" transform="translate(8610.5,0)"><path data-c="1D443" d="M287 628Q287 635 230 637Q206 637 199 638T192 648Q192 649 194 659Q200 679 203 681T397 683Q587 682 600 680Q664 669 707 631T751 530Q751 453 685 389Q616 321 507 303Q500 302 402 301H307L277 182Q247 66 247 59Q247 55 248 54T255 50T272 48T305 46H336Q342 37 342 35Q342 19 335 5Q330 0 319 0Q316 0 282 1T182 2Q120 2 87 2T51 1Q33 1 33 11Q33 13 36 25Q40 41 44 43T67 46Q94 46 127 49Q141 52 146 61Q149 65 218 339T287 628ZM645 554Q645 567 643 575T634 597T609 619T560 635Q553 636 480 637Q463 637 445 637T416 636T404 636Q391 635 386 627Q384 621 367 550T332 412T314 344Q314 342 395 342H407H430Q542 342 590 392Q617 419 631 471T645 554Z"></path></g><g data-mml-node="mi" transform="translate(9361.5,0)"><path data-c="1D43E" d="M285 628Q285 635 228 637Q205 637 198 638T191 647Q191 649 193 661Q199 681 203 682Q205 683 214 683H219Q260 681 355 681Q389 681 418 681T463 682T483 682Q500 682 500 674Q500 669 497 660Q496 658 496 654T495 648T493 644T490 641T486 639T479 638T470 637T456 637Q416 636 405 634T387 623L306 305Q307 305 490 449T678 597Q692 611 692 620Q692 635 667 637Q651 637 651 648Q651 650 654 662T659 677Q662 682 676 682Q680 682 711 681T791 680Q814 680 839 681T869 682Q889 682 889 672Q889 650 881 642Q878 637 862 637Q787 632 726 586Q710 576 656 534T556 455L509 418L518 396Q527 374 546 329T581 244Q656 67 661 61Q663 59 666 57Q680 47 717 46H738Q744 38 744 37T741 19Q737 6 731 0H720Q680 3 625 3Q503 3 488 0H478Q472 6 472 9T474 27Q478 40 480 43T491 46H494Q544 46 544 71Q544 75 517 141T485 216L427 354L359 301L291 248L268 155Q245 63 245 58Q245 51 253 49T303 46H334Q340 37 340 35Q340 19 333 5Q328 0 317 0Q314 0 280 1T180 2Q118 2 85 2T49 1Q31 1 31 11Q31 13 34 25Q38 41 42 43T65 46Q92 46 125 49Q139 52 144 61Q147 65 216 339T285 628Z"></path></g></g></g></svg></mjx-container></span></li> <li>2 の n 乗っぽい</li> <li>べき集合の濃度?</li> <li>2 進数のブール配列と考えればわかりやすくなった</li> <li>ということは X 個の表現をするために必要なブール配列の長さは <span class="math inline"><mjx-container class="MathJax" jax="SVG"><svg style="vertical-align: -0.566ex;" xmlns="http://www.w3.org/2000/svg" width="9.576ex" height="2.262ex" role="img" focusable="false" viewBox="0 -750 4232.6 1000"><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="mo"><path data-c="2308" d="M174 734Q178 746 190 750H298H369Q400 750 411 747T422 730T411 713T372 709Q365 709 345 709T310 710H214V-235Q206 -248 196 -250Q192 -250 189 -249T184 -247T180 -244T178 -241T176 -237T174 -234V734Z"></path></g><g data-mml-node="msub" transform="translate(444,0)"><g data-mml-node="mi"><path data-c="6C" d="M42 46H56Q95 46 103 60V68Q103 77 103 91T103 124T104 167T104 217T104 272T104 329Q104 366 104 407T104 482T104 542T103 586T103 603Q100 622 89 628T44 637H26V660Q26 683 28 683L38 684Q48 685 67 686T104 688Q121 689 141 690T171 693T182 694H185V379Q185 62 186 60Q190 52 198 49Q219 46 247 46H263V0H255L232 1Q209 2 183 2T145 3T107 3T57 1L34 0H26V46H42Z"></path><path data-c="6F" d="M28 214Q28 309 93 378T250 448Q340 448 405 380T471 215Q471 120 407 55T250 -10Q153 -10 91 57T28 214ZM250 30Q372 30 372 193V225V250Q372 272 371 288T364 326T348 362T317 390T268 410Q263 411 252 411Q222 411 195 399Q152 377 139 338T126 246V226Q126 130 145 91Q177 30 250 30Z" transform="translate(278,0)"></path><path data-c="67" d="M329 409Q373 453 429 453Q459 453 472 434T485 396Q485 382 476 371T449 360Q416 360 412 390Q410 404 415 411Q415 412 416 414V415Q388 412 363 393Q355 388 355 386Q355 385 359 381T368 369T379 351T388 325T392 292Q392 230 343 187T222 143Q172 143 123 171Q112 153 112 133Q112 98 138 81Q147 75 155 75T227 73Q311 72 335 67Q396 58 431 26Q470 -13 470 -72Q470 -139 392 -175Q332 -206 250 -206Q167 -206 107 -175Q29 -140 29 -75Q29 -39 50 -15T92 18L103 24Q67 55 67 108Q67 155 96 193Q52 237 52 292Q52 355 102 398T223 442Q274 442 318 416L329 409ZM299 343Q294 371 273 387T221 404Q192 404 171 388T145 343Q142 326 142 292Q142 248 149 227T179 192Q196 182 222 182Q244 182 260 189T283 207T294 227T299 242Q302 258 302 292T299 343ZM403 -75Q403 -50 389 -34T348 -11T299 -2T245 0H218Q151 0 138 -6Q118 -15 107 -34T95 -74Q95 -84 101 -97T122 -127T170 -155T250 -167Q319 -167 361 -139T403 -75Z" transform="translate(778,0)"></path></g><g data-mml-node="mn" transform="translate(1311,-241.4) scale(0.707)"><path data-c="32" d="M109 429Q82 429 66 447T50 491Q50 562 103 614T235 666Q326 666 387 610T449 465Q449 422 429 383T381 315T301 241Q265 210 201 149L142 93L218 92Q375 92 385 97Q392 99 409 186V189H449V186Q448 183 436 95T421 3V0H50V19V31Q50 38 56 46T86 81Q115 113 136 137Q145 147 170 174T204 211T233 244T261 278T284 308T305 340T320 369T333 401T340 431T343 464Q343 527 309 573T212 619Q179 619 154 602T119 569T109 550Q109 549 114 549Q132 549 151 535T170 489Q170 464 154 447T109 429Z"></path></g></g><g data-mml-node="mo" transform="translate(2158.6,0)"><path data-c="2061" d=""></path></g><g data-mml-node="mo" transform="translate(2158.6,0)"><path data-c="28" d="M94 250Q94 319 104 381T127 488T164 576T202 643T244 695T277 729T302 750H315H319Q333 750 333 741Q333 738 316 720T275 667T226 581T184 443T167 250T184 58T225 -81T274 -167T316 -220T333 -241Q333 -250 318 -250H315H302L274 -226Q180 -141 137 -14T94 250Z"></path></g><g data-mml-node="mi" transform="translate(2547.6,0)"><path data-c="1D44B" d="M42 0H40Q26 0 26 11Q26 15 29 27Q33 41 36 43T55 46Q141 49 190 98Q200 108 306 224T411 342Q302 620 297 625Q288 636 234 637H206Q200 643 200 645T202 664Q206 677 212 683H226Q260 681 347 681Q380 681 408 681T453 682T473 682Q490 682 490 671Q490 670 488 658Q484 643 481 640T465 637Q434 634 411 620L488 426L541 485Q646 598 646 610Q646 628 622 635Q617 635 609 637Q594 637 594 648Q594 650 596 664Q600 677 606 683H618Q619 683 643 683T697 681T738 680Q828 680 837 683H845Q852 676 852 672Q850 647 840 637H824Q790 636 763 628T722 611T698 593L687 584Q687 585 592 480L505 384Q505 383 536 304T601 142T638 56Q648 47 699 46Q734 46 734 37Q734 35 732 23Q728 7 725 4T711 1Q708 1 678 1T589 2Q528 2 496 2T461 1Q444 1 444 10Q444 11 446 25Q448 35 450 39T455 44T464 46T480 47T506 54Q523 62 523 64Q522 64 476 181L429 299Q241 95 236 84Q232 76 232 72Q232 53 261 47Q262 47 267 47T273 46Q276 46 277 46T280 45T283 42T284 35Q284 26 282 19Q279 6 276 4T261 1Q258 1 243 1T201 2T142 2Q64 2 42 0Z"></path></g><g data-mml-node="mo" transform="translate(3399.6,0)"><path data-c="29" d="M60 749L64 750Q69 750 74 750H86L114 726Q208 641 251 514T294 250Q294 182 284 119T261 12T224 -76T186 -143T145 -194T113 -227T90 -246Q87 -249 86 -250H74Q66 -250 63 -250T58 -247T55 -238Q56 -237 66 -225Q221 -64 221 250T66 725Q56 737 55 738Q55 746 60 749Z"></path></g><g data-mml-node="mo" transform="translate(3788.6,0)"><path data-c="2309" d="M21 717T21 730T32 746T75 750H147H256Q266 742 269 735V-235Q262 -248 251 -250Q247 -250 244 -249T239 -247T235 -244T233 -241T231 -237T229 -234V710H133Q119 710 99 710T71 709Q43 709 32 713Z"></path></g></g></g></svg></mjx-container></span></li> <li>例えばアルファベットなら 6 ドットの点字で表現できる</li> <li>だから英語の点字は 6 つの点で構成されている</li> <li>点字を 18 ドットに拡張すれば Unicode 13.0 の文字すべてを表現できる</li> </ul> 2021-02-12T16:00:00.000Z https://uechi.io/blog/server-2020/ 新しい自宅サーバーの構成 <p>10 年ぶりにサーバーを更新した。初めての AMD、初めての DDR4、初めての NVM Express!</p> <h1 id="用途">用途</h1> <ul> <li>各種セルフホスト (Docker)</li> <li>Docker Swarm クラスターのマスターノード</li> <li>計算実験</li> <li>VS Code Remote SSH のホストマシン</li> </ul> <h1 id="スペック">スペック</h1> <p>重いタスクを並列してやらせたいので最優先は CPU とメモリ。メモリは<a href="https://shop.tsukumo.co.jp/goods/4582353591719/">DDR4-3200 32GBx2</a> を、CPU は昨今のライブラリのマルチコア対応を勘案して <a href="https://www.amd.com/en/products/cpu/amd-ryzen-9-3950x">Ryzen 9 3950X</a> を選んだ。CPU クーラーは静音性を考えて Noctua の <a href="https://noctua.at/en/nh-d15">NH-D15 Black</a> 。</p> <blockquote> <p>追記: メモリ異常を起因とするシステム誤動作により、<code>/sbin</code> 以下がゼロ上書きされカーネルが起動しなくなる災害が起きた。後日 ECC 付きのメモリに交換してからは、現在に至るまでメモリ関連の異常は発生していない。常時稼働するサーバーには最初から ECC メモリを選ぼう。</p> </blockquote> <blockquote> <p>追記 2: 結果から言うとメモリは 64GB では足りなかった。巨大な Pandas データフレームを弄ったり、10 億レコード以上ある MongoDB を走査したりするたびに OOM が発動してしまう。最終的に 128GB まで増やす羽目になった。</p> </blockquote> <blockquote> <p>追記 3: 結局 128GB でも OOM になる場面が出てきたが、スロットが埋まっていてもうこれ以上増設できないし、できたとしても Ryzen シリーズが 128GB までしかサポートしてないのでどちらにしろ詰みである。</p> <p>これから機械学習/OLAP サーバーを構築しようと考えている読者は、最初から DIMM スロットが豊富な Dual-socket (CPU が 2 つ挿せる) マザーボードと、サーバー向け CPU (EPYC または Xeon)の組み合わせを検討すべきだ。サーバー向け CPU に関しては、EOL を迎えてデータセンターから放出された 5 年ほど前のモデルが eBay で安く手に入るはず。</p> </blockquote> <blockquote> <p>追記 4: eBay で良いパーツを探すコツ</p> <ol type="1"> <li>発送時期が異様に長くない (所有しているものを出品している)</li> <li>シリアル番号が写っている現物の写真がある (偽物や Engineering Sample の可能性が低い)</li> <li>通電に加えて正常な動作確認を行っている (疑問点があれば出品者に質問を送ってしっかり言質をとっておくこと)</li> </ol> </blockquote> <p>GPU は古いサーバーに突っ込んでいた NVIDIA GeForce GTX TITAN X (Maxwell)を流用した。VRAM が 12GB ちょっとしかないが、最大ワークロード時でも 5GB は残るので今のところ十分。</p> <blockquote> <p>追記: 結果から言うと GPT-J や Megatron-LM を始めとした億パラメータ級のモデルを学習・推論させるには、DeepSpeed の助けがあったとしても最低 16GB の VRAM が必要だった。他の例を挙げると、Stable Diffusion の Fine-tuning には最低 30GB 前後の VRAM が必要になるし、OpenAI Whisper の large モデルを動かす際にも 13GB は見ておく必要がある。</p> <p>今から GPU を買うなら、2022 年 10 月現在中古市場で 10 万前後で推移している RTX 3090 (24GB)を 2 枚買う戦略が筋が良いだろう。お金持ちなら A100 を買えば良い。</p> </blockquote> <blockquote> <p>追記 2: RTX 3090 を安く仕入れることができたが、サイズが大きすぎて Meshify 2 ケースの HDD ベイに干渉してしまった。いくつか HDD を移動させることで上手く挿入できたが、かわりに 3 つ分のベイが使用できなくなった。</p> <p>これからケースを買おうとしている読者は、最初から ATX ケースを通り越して Meshify 2 XL など、E-ATX/EE-ATX 対応ケースを選ぶことをおすすめする。どちらにせよそのようなケースでないと上記の Dual-socket マザーボードは挿せないし、十分な冷却環境を確保できない。</p> </blockquote> <p>記憶装置は WD HDD 3TB 2 台と Samsung 970 EVO Plus 500GB M.2 PCIe、そして古いサーバーから引っこ抜いた Samsung 870 EVO Plus 500GB SSD 。NVMe メモリは OS とキャッシュ用、SSD/HDD はデータ用にする。</p> <p>マザーボードは、X570 と比較して実装されているコンデンサーやパーツがサーバー向きだと感じた<a href="https://www.asrock.com/mb/AMD/B550%20Taichi/">ASRock B550 Taichi</a> にした。</p> <p>電源は今後 GPU を追加することを考えて <a href="https://seasonic.com/prime-tx">Seasonic PRIME TX 850</a> を選んだ。実際にサーバーを稼働させながら使用電力を計測したところ、アイドル時に 180W 前後、フル稼働時でも 350W を超えない程度だった。</p> <p>ケースは Fractal Design の <a href="https://www.fractal-design.com/products/cases/meshify/meshify-2/Black/">Meshify 2</a> 。</p> <p>OS は長年付き合ってきた Ubuntu と袂を分かち、<a href="https://archlinux.org/">Arch Linux</a> を選んだ。ミニマルと実用の間のバランスが取れていて好み。</p> <p>Arch Linux のセットアップは<a href="https://uechi.io/blog/installing-arch-linux/">個別に記事</a>を書いた。</p> <p>また、AUR (Arch User Repository)にパッケージを公開したい人向けに、Docker 自動ビルド・テストツールを<a href="https://github.com/uetchy/archpkgs">GitHub で公開</a>した。</p> <h1 id="パーツ選定時のポイント">パーツ選定時のポイント</h1> <ul> <li><a href="https://diskprices.com/?locale=us">Disk Prices</a> でディスクの値段チェック</li> <li><a href="https://en.wikichip.org/wiki/WikiChip">WikiChip</a>で CPU のモデルやスペックを調査する</li> <li><a href="https://jp.pcpartpicker.com/">PCPartPicker</a>でパーツのコスト計算をする</li> <li><a href="https://pc-builds.com/calculator/">Bottleneck Calculator</a>で CPU と GPU の組み合わせを選び、そのうちどちらが性能のボトルネックになるか調べる</li> <li><a href="https://www.userbenchmark.com/">UserBenchmark</a>でユーザーが投稿したベンチマーク結果を眺める</li> <li><a href="https://linux-hardware.org/">Linux Hardware Database</a> を見て、インストールする予定の Linux ディストリとパーツの相性をチェックする</li> <li>CPU クーラーは大口径の方が静か</li> <li>PSU は Seasonic が評判良い</li> <li>東芝 D01 が HGST の系譜</li> <li><a href="https://www.amd.com/en/chipsets/b550">B550</a> は長期運用に向いている(らしい) <ul> <li>B520 は廉価版</li> </ul></li> <li>TSUKUMO eX. の自作 PC コーナーのスタッフはガチ勢なので信頼できる <ul> <li>不明な部分があれば根掘り葉掘り聞く</li> </ul></li> </ul> <h1 id="組立ての勘所">組立ての勘所</h1> <ul> <li>少なくとも 1 年間はすべての箱・書類を取っておく(特にメモリは箱自体が保証書代わりになっている場合がある)</li> <li>筐体は無視してまずマザボ、CPU、クーラー、(オンボードグラフィックが無い CPU なら)グラボ、そして電源を繋いで通電・動作テストをする <ul> <li><a href="https://www.memtest86.com/">MemTest86</a>でメモリのテストを最後までやる(エラーが出たら交換依頼)</li> <li>USB ブートで OS の起動確認</li> </ul></li> <li>Ethernet が死んでいる場合は USB-Ethernet アダプターでまずネットを確保する <ul> <li>ほとんどの場合 Linux カーネルのバージョンを上げると(デバイスドライバーも新しくなり)直る <ul> <li>Arch Linux の場合: <code>linux-lts</code>が駄目なら<code>linux</code>に切り替えて試す</li> <li>Ubuntu の場合: <a href="https://kernel.ubuntu.com/~kernel-ppa/mainline/?C=N;O=D">kernel.ubuntu.com</a> から探してアップデートする(<a href="https://itsfoss.com/upgrade-linux-kernel-ubuntu/">https://itsfoss.com/upgrade-linux-kernel-ubuntu/</a>)</li> </ul></li> <li>駄目ならマザボまたはアダプターメーカーからアップデートを探す</li> </ul></li> <li>安い筐体のネジは柔いことがあるため、強く押し込みながら少しずつ回す <ul> <li>山が潰れてきたらゴムシートを挟む</li> </ul></li> <li>すべて動いたら、<a href="https://linux-hardware.org/index.php?view=howto">Linux Hardware Database に Probe を送信</a>して貢献する</li> </ul> 2021-02-12T15:00:00.000Z https://uechi.io/blog/installing-arch-linux/ Installing Arch Linux on Bare-metal Server <p>This is all the commands I typed when I set up Arch Linux on my new compute server.</p> <blockquote> <p>PSA[1]: I published a toolchain for creating/testing PKGBUILD in a clean-room Docker container <a href="https://github.com/uetchy/archpkgs" class="uri">https://github.com/uetchy/archpkgs</a></p> </blockquote> <blockquote> <p>PSA[2]: Also published <a href="https://github.com/uetchy/cfddns">cfddns</a> (<a href="https://aur.archlinux.org/packages/cfddns">AUR</a>), a Cloudflare DDNS client written in Rust.</p> </blockquote> <h1 id="table-of-contents">Table of Contents</h1> <ul><li><a href="#table-of-contents">Table of Contents</a></li><li><a href="#goals">Goals</a></li><li><a href="#setup">Setup</a><ul><li><a href="#wipe-a-disk">Wipe a disk</a></li><li><a href="#create-partitions">Create partitions</a></li><li><a href="#write-file-systems">Write file systems</a></li><li><a href="#mount-partitions">Mount partitions</a></li><li><a href="#install-linux-kernel">Install Linux kernel</a></li><li><a href="#generate-fstab">Generate fstab</a></li><li><a href="#tweak-pacman">Tweak pacman</a></li><li><a href="#chroot-into-the-installation">Chroot into the installation</a></li><li><a href="#finish-structuring-file-systems">Finish structuring file systems</a><ul><li><a href="#crypttab">crypttab</a></li><li><a href="#remote-unlocking">Remote unlocking</a></li><li><a href="#periodic-trim">Periodic TRIM</a></li></ul></li><li><a href="#ssh">SSH</a></li><li><a href="#bootloader-systemd-boot">Bootloader (systemd-boot)</a></li><li><a href="#network">Network</a><ul><li><a href="#systemd-networkd">systemd-networkd</a></li><li><a href="#systemd-resolved">systemd-resolved</a></li></ul></li><li><a href="#sysctl">sysctl</a></li><li><a href="#faillock">faillock</a></li><li><a href="#nvidia-driver">NVIDIA driver</a></li><li><a href="#create-operator-user">Create operator user</a></li><li><a href="#time-and-locales">Time and locales</a></li><li><a href="#leave-chroot-and-reboot">Leave chroot and reboot</a></li><li><a href="#set-hostname">Set hostname</a></li><li><a href="#check-ups">Check-ups</a></li><li><a href="#s.m.a.r.t.">S.M.A.R.T.</a><ul><li><a href="#automated-disk-health-check-ups-and-reporting">Automated disk health check-ups and reporting</a></li><li><a href="#manual-testing">Manual testing</a></li></ul></li><li><a href="#aur-helper-yay">AUR Helper (yay)</a></li><li><a href="#docker">Docker</a><ul><li><a href="#cross-platform-build-support-buildkit-qemu">Cross-platform build support (BuildKit, QEMU)</a></li><li><a href="#tips-use-journald-log-driver-in-docker-compose">Tips: Use journald log driver in Docker Compose</a></li></ul></li><li><a href="#dns-resolver-pi-hole-unbound">DNS resolver (Pi-hole + unbound)</a></li><li><a href="#ddns-cfddns">DDNS (cfddns)</a></li><li><a href="#reverse-proxy-nginx-proxy">Reverse proxy (nginx-proxy)</a></li><li><a href="#acme-ca-step-ca">ACME CA (step-ca)</a></li><li><a href="#auth-gateway-and-identity-provider-authelia">Auth gateway and identity provider (Authelia)</a></li><li><a href="#mail-server-mailu">Mail server (Mailu)</a></li><li><a href="#nextcloud">Nextcloud</a></li><li><a href="#monitor-telegraf-influxdb-grafana">Monitor (Telegraf + InfluxDB + Grafana)</a><ul><li><a href="#grafana-influxdb-docker">Grafana + InfluxDB (Docker)</a></li><li><a href="#telegraf-host">Telegraf (Host)</a></li></ul></li><li><a href="#bruce-force-attack-mitigation-fail2ban">Bruce-force attack mitigation (fail2ban)</a></li><li><a href="#firewall-ufw">Firewall (ufw)</a></li><li><a href="#vpn-wireguard">VPN (WireGuard)</a></li><li><a href="#backup-restic">Backup (restic)</a></li></ul></li><li><a href="#miscellaneous-stuff">Miscellaneous stuff</a><ul><li><a href="#kubernetes">Kubernetes</a></li><li><a href="#install-useful-tools">Install useful tools</a></li><li><a href="#make-ssh-forwarding-work-with-tmux-sudo">Make SSH forwarding work with tmux + sudo</a></li><li><a href="#temperature-sensors">Temperature sensors</a></li><li><a href="#telegram-notifier">Telegram notifier</a></li><li><a href="#audio">Audio</a></li></ul></li><li><a href="#maintenance">Maintenance</a><ul><li><a href="#quick-checkups">Quick checkups</a></li><li><a href="#delve-into-system-logs">Delve into system logs</a></li><li><a href="#force-overriding-installation">Force overriding installation</a></li><li><a href="#check-memory-modules">Check memory modules</a></li><li><a href="#file-system-related-issues-checklist">File-system related issues checklist</a><ul><li><a href="#ext4">Ext4</a></li><li><a href="#fix-broken-file-system-headers">Fix broken file system headers</a></li></ul></li></ul></li><li><a href="#troubleshooting">Troubleshooting</a><ul><li><a href="#longer-ssh-login-d-bus-glitch">Longer SSH login (D-bus glitch)</a></li><li><a href="#annoying-systemd-homed-is-not-available-messages-flooding-journald-logs">Annoying systemd-homed is not available messages flooding journald logs</a></li><li><a href="#annoying-systemd-journald-audit-logs">Annoying systemd-journald-audit logs</a></li><li><a href="#missing-devnvidia-uvmmodeset">Missing /dev/nvidia-{uvm*,modeset}</a></li><li><a href="#sudo-incorrect-password-while-password-is-correct">[sudo] Incorrect password while password is correct</a></li></ul></li><li><a href="#useful-links">Useful links</a></li></ul> <h1 id="goals">Goals</h1> <ul> <li>/dev/sda - NVMe M.2 SSD <ul> <li>/dev/sda1 - EFI system partition mounted on /boot (systemd-boot)</li> <li>/dev/sda2 - LUKS partition contains Btrfs subvolumes <ul> <li>@ -&gt; /</li> <li><span class="citation" data-cites="home">@home</span> -&gt; /home</li> <li><span class="citation" data-cites="srv">@srv</span> -&gt; /srv <ul> <li>Docker stacks directory (nginx-proxy, Mail, Nextcloud, Minio, JupyterHub, Weights &amp; Biases, etc)</li> </ul></li> <li><span class="citation" data-cites="log">@log</span> -&gt; /var/log</li> <li><span class="citation" data-cites="cache">@cache</span> -&gt; /var/cache</li> </ul></li> </ul></li> <li>/dev/sdb - HDD for data vault <ul> <li>/dev/sdb1 - LUKS partition contains Btrfs mounted on /mnt/vault</li> </ul></li> <li>/dev/sdc - HDD for backups <ul> <li>/dev/sdc1 - Btrfs mounted on /mnt/backups</li> </ul></li> <li>/dev/sde - SSD for analytical database (intensive write-ops) <ul> <li>/dev/sde1 - XFS mounted on /mnt/analytics</li> </ul></li> </ul> <p>Why XFS for analytical database storage? Refer to <a href="https://www.mongodb.com/docs/manual/administration/production-notes/#kernel-and-file-systems">Production Notes — MongoDB Manual</a> and <a href="https://docs.scylladb.com/stable/getting-started/system-configuration.html#set-up-raid-and-filesystem">Configure Scylla | Scylla Docs</a>.</p> <h1 id="setup">Setup</h1> <h2 id="wipe-a-disk">Wipe a disk</h2> <pre><code class="hljs bash"><span class="hljs-comment"># Erase file-system magic strings (insecure but super fast, suitable when reusing a disk)</span> wipefs -a /dev/sdN <span class="hljs-comment"># or</span> <span class="hljs-comment"># Write (random then zeroes) to the device (takes longer but more secure, suitable when selling a disk)</span> <span class="hljs-built_in">shred</span> -v -n 1 -z /dev/sdN</code></pre> <h2 id="create-partitions">Create partitions</h2> <p>This command will calculate optimal sector alignments correctly. You can confirm it by running <code>sfdisk -d /dev/sda</code>.</p> <pre><code class="hljs bash"><span class="hljs-comment"># Overwrite new GPT</span> sgdisk -og /dev/sda <span class="hljs-comment"># Create 1GiB EFI system partition</span> sgdisk -n 1:0:+1G -c 1:boot -t 1:ef00 /dev/sda <span class="hljs-comment"># Fill the rest with a LUKS partition</span> sgdisk -n 2:0:0 -c 2:crypt -t 2:8308 /dev/sda <span class="hljs-comment"># Data disks</span> sgdisk -og /dev/sdb sgdisk -n 1:0:0 -c 1:vault -t 1:8308 /dev/sdb <span class="hljs-comment"># LUKS</span> sgdisk -og /dev/sdc sgdisk -n 1:0:0 -c 1:backups /dev/sdb sgdisk -og /dev/sde sgdisk -n 1:0:0 -c 1:analytics /dev/sdb <span class="hljs-comment"># Verify the result</span> sgdisk -p /dev/sdN</code></pre> <blockquote> <p>NOTE: Since my server has 128GB of physical memory, I would rather let OOM Killer do its job than creating a swap partition. Should the need for swap comes up later, consider swap file (no perf difference in general)</p> </blockquote> <ul> <li><a href="https://wiki.archlinux.org/title/GPT_fdisk">GPT fdisk - ArchWiki</a></li> <li><a href="https://wiki.archlinux.org/title/Swap#Swap_file">Swap file - ArchWiki</a></li> <li><a href="https://wiki.archlinux.org/title/btrfs#Swap_file">Swap file - Btrfs - ArchWiki</a></li> </ul> <h2 id="write-file-systems">Write file systems</h2> <pre><code class="hljs bash"><span class="hljs-comment"># VFAT32 ESP</span> mkfs.vfat -F 32 -n ESP /dev/sda1 <span class="hljs-comment"># LUKS2</span> cryptsetup luksFormat /dev/sda2 cryptsetup \ --allow-discards \ --perf-no_read_workqueue \ --perf-no_write_workqueue \ --persistent \ open /dev/sda2 crypt cryptsetup luksFormat /dev/sdb1 cryptsetup open /dev/sdb1 vault <span class="hljs-comment"># Verify the LUKS devices</span> cryptsetup luksDump /dev/sdN <span class="hljs-comment"># Dump LUKS2 header</span> dmsetup table <span class="hljs-comment"># Show flags for the currently opened devices</span> <span class="hljs-comment"># Also, backup the LUKS headers to safe storage</span> cryptsetup luksHeaderBackup /dev/sdN --header-backup-file /path/to/luks_header_sdN <span class="hljs-comment"># Btrfs for root partition</span> mkfs.btrfs -L crypt /dev/mapper/crypt mount /dev/mapper/crypt /mnt <span class="hljs-comment"># Temporary mounted to create subvolumes</span> <span class="hljs-comment"># btrfs [su]bvolume [cr]eate</span> btrfs su cr /mnt/@ btrfs su cr /mnt/@home btrfs su cr /mnt/@cache btrfs su cr /mnt/@<span class="hljs-built_in">log</span> btrfs su cr /mnt/@srv <span class="hljs-comment"># Home for Docker Compose stacks</span> btrfs su set-default 256 /mnt <span class="hljs-comment"># Required for remote unlocking</span> umount /mnt <span class="hljs-comment"># Btrfs</span> mkfs.btrfs -L vault /dev/mapper/vault mkfs.btrfs -L backups /dev/sdc1 <span class="hljs-comment"># XFS</span> mkfs.xfs -L analytics /dev/sde1</code></pre> <p>See <a href="https://wiki.archlinux.org/title/Dm-crypt/Specialties#Discard/TRIM_support_for_solid_state_drives_(SSD)">Discard/TRIM support for solid state drives (SSD) - Dm-crypt - ArchWiki</a> for the reasoning behind these <code>cryptsetup</code> flags.</p> <ul> <li><a href="https://wiki.archlinux.org/title/User:I2Oc9/Btrfs_subvolumes">User:I2Oc9/Btrfs subvolumes - ArchWiki</a></li> </ul> <h2 id="mount-partitions">Mount partitions</h2> <pre><code class="hljs bash"><span class="hljs-comment"># Root partition</span> mount /dev/mapper/crypt /mnt mount -m -o subvol=@home /dev/mapper/crypt /mnt/home mount -m -o subvol=@cache /dev/mapper/crypt /mnt/var/cache mount -m -o subvol=@<span class="hljs-built_in">log</span> /dev/mapper/crypt /mnt/var/log mount -m -o subvol=@srv /dev/mapper/crypt /mnt/srv <span class="hljs-comment"># EFI system partition</span> mount -m /dev/sda1 /mnt/boot <span class="hljs-comment"># Extra disks</span> mount -m /dev/mapper/vault /mnt/mnt/vault mount -m /dev/sde1 /mnt/mnt/analytics mount -m /dev/sdc1 /mnt/mnt/backups</code></pre> <h2 id="install-linux-kernel">Install Linux kernel</h2> <pre><code class="hljs bash"><span class="hljs-comment"># This is necessary for older Arch ISO image</span> pacman -Sy archlinux-keyring <span class="hljs-comment"># Choose between 'linux-lts' and 'linux'</span> pacstrap /mnt base linux-lts linux-firmware \ btrfs-progs xfsprogs vim man-db man-pages</code></pre> <h2 id="generate-fstab">Generate fstab</h2> <pre><code class="hljs bash"><span class="hljs-comment"># Generate fstab based on current /mnt structure</span> genfstab -U /mnt &gt;&gt; /mnt/etc/fstab</code></pre> <h2 id="tweak-pacman">Tweak pacman</h2> <pre><code class="hljs bash"><span class="hljs-comment"># Optimize mirrorlist (replace `country` params with your nearest countries)</span> pacman -S --needed pacman-contrib curl -s <span class="hljs-string">'https://archlinux.org/mirrorlist/?use_mirror_status=on&amp;protocol=https&amp;country=JP&amp;country=KR&amp;country=HK'</span> | sed -e <span class="hljs-string">'s/#//'</span> -e <span class="hljs-string">'/#/d'</span> | rankmirrors -n 10 - &gt; /mnt/etc/pacman.d/mirrorlist <span class="hljs-comment"># Colorize output</span> sed <span class="hljs-string">'/#Color/a Color'</span> -i /mnt/etc/pacman.conf <span class="hljs-comment"># Parallel downloads</span> sed <span class="hljs-string">'/#ParallelDownloads/a ParallelDownloads = 5'</span> -i /mnt/etc/pacman.conf <span class="hljs-comment"># ILoveCandy</span> sed <span class="hljs-string">'/# Misc/a ILoveCandy'</span> -i /mnt/etc/pacman.conf</code></pre> <h2 id="chroot-into-the-installation">Chroot into the installation</h2> <pre><code class="hljs bash"><span class="hljs-comment"># Chroot</span> arch-chroot /mnt <span class="hljs-comment"># Change root password</span> passwd</code></pre> <h2 id="finish-structuring-file-systems">Finish structuring file systems</h2> <pre><code class="hljs bash"><span class="hljs-comment"># Verify fstab entries</span> findmnt --verify --verbose</code></pre> <h3 id="crypttab">crypttab</h3> <pre><code class="hljs bash"><span class="hljs-built_in">echo</span> <span class="hljs-string">"crypt UUID=<span class="hljs-subst">$(blkid /dev/sda2 -s UUID -o value)</span> none luks"</span> &gt;&gt; /etc/crypttab <span class="hljs-built_in">echo</span> <span class="hljs-string">"vault UUID=<span class="hljs-subst">$(blkid /dev/sdb1 -s UUID -o value)</span> none luks"</span> &gt;&gt; /etc/crypttab <span class="hljs-built_in">cat</span> /etc/crypttab</code></pre> <h3 id="remote-unlocking">Remote unlocking</h3> <pre><code class="hljs bash">pacman -S --needed mkinitcpio-systemd-tool openssh cryptsetup tinyssh busybox mc python3 <span class="hljs-comment"># crypttab for initramfs</span> <span class="hljs-built_in">echo</span> <span class="hljs-string">"crypt UUID=<span class="hljs-subst">$(blkid /dev/sda2 -s UUID -o value)</span> none luks"</span> &gt;&gt; /etc/mkinitcpio-systemd-tool/config/crypttab <span class="hljs-comment"># [!] Add every other device whose password is different from `crypt` device</span> <span class="hljs-comment"># to make sure that all the passwords will be asked during the remote unlocking</span> <span class="hljs-comment"># fstab for initramfs</span> <span class="hljs-built_in">echo</span> <span class="hljs-string">"UUID=<span class="hljs-subst">$(blkid /dev/mapper/crypt -s UUID -o value)</span> /sysroot auto x-systemd.device-timeout=9999h 0 1"</span> &gt;&gt; /etc/mkinitcpio-systemd-tool/config/fstab <span class="hljs-comment"># Append 'systemd systemd-tool' to and remove 'udev' from mkinitcpio HOOKS</span> sed -r <span class="hljs-string">'/^HOOKS=/s/^/#/'</span> -i /etc/mkinitcpio.conf sed -r <span class="hljs-string">'/^#HOOKS=/a HOOKS=(base autodetect modconf block filesystems keyboard fsck systemd systemd-tool)'</span> -i /etc/mkinitcpio.conf <span class="hljs-comment"># Change SSH port</span> <span class="hljs-built_in">mkdir</span> -p /etc/systemd/system/initrd-tinysshd.service.d <span class="hljs-built_in">cat</span> &gt; /etc/systemd/system/initrd-tinysshd.service.d/override.conf &lt;&lt;<span class="hljs-string">EOD</span> <span class="hljs-string">[Service]</span> <span class="hljs-string">Environment=</span> <span class="hljs-string">Environment=SSHD_PORT=12345</span> <span class="hljs-string">EOD</span> <span class="hljs-comment"># Assign static IP because we are behind NAT</span> <span class="hljs-built_in">cat</span> &gt; /etc/mkinitcpio-systemd-tool/network/initrd-network.network &lt;&lt;<span class="hljs-string">EOD</span> <span class="hljs-string">[Match]</span> <span class="hljs-string"># [!] use kernel interface name, not udev name</span> <span class="hljs-string">Name=eth0</span> <span class="hljs-string"></span> <span class="hljs-string">[Network]</span> <span class="hljs-string">Address=10.0.1.2</span> <span class="hljs-string">Gateway=10.0.1.1</span> <span class="hljs-string">DNS=9.9.9.9</span> <span class="hljs-string">EOD</span> <span class="hljs-comment"># Enable required services</span> systemctl <span class="hljs-built_in">enable</span> initrd-cryptsetup.path systemctl <span class="hljs-built_in">enable</span> initrd-tinysshd systemctl <span class="hljs-built_in">enable</span> initrd-debug-progs systemctl <span class="hljs-built_in">enable</span> initrd-sysroot-mount <span class="hljs-comment"># Generate host SSH key pair</span> ssh-keygen -A <span class="hljs-comment"># Download SSH public keys to use ([!] tinysshd only supports ed25519)</span> curl -s https://github.com/&lt;username&gt;.keys &gt;&gt; /root/.ssh/authorized_keys <span class="hljs-comment"># Build initramfs</span> mkinitcpio -P <span class="hljs-comment"># Verify initramfs contents</span> lsinitcpio -l /boot/initramfs-linux-lts.img</code></pre> <ul> <li><a href="https://github.com/random-archer/mkinitcpio-systemd-tool/wiki/Case:-Complete-BTRFS-Setup-(step-by-step)">Case: Complete BTRFS Setup (step by step)</a></li> </ul> <h3 id="periodic-trim">Periodic TRIM</h3> <pre><code class="hljs bash">systemctl <span class="hljs-built_in">enable</span> fstrim.timer</code></pre> <p>Run <code>lsblk --discard</code> to see the TRIM-supported devices (it does if both <code>DISC-GRAN</code> and <code>DISC-MAX</code> have non-empty values).</p> <p><a href="https://wiki.archlinux.org/title/Solid_state_drive#Periodic_TRIM">Solid state drive - ArchWiki</a></p> <h2 id="ssh">SSH</h2> <pre><code class="hljs bash">vim /etc/ssh/sshd_config <span class="hljs-comment"># Change port</span> sed <span class="hljs-string">'/#Port /a Port 12345'</span> -i /etc/ssh/sshd_config <span class="hljs-comment"># Limit to pubkey auth</span> sed <span class="hljs-string">'/#PasswordAuthentication /a PasswordAuthentication no'</span> -i /etc/ssh/sshd_config systemctl <span class="hljs-built_in">enable</span> sshd</code></pre> <h2 id="bootloader-systemd-boot">Bootloader (systemd-boot)</h2> <p>Because GRUB's LUKS2 support is still limited (It does not support cryptsetup's default Argon2id yet. I've tested in a VM and confirmed it doesn't work).</p> <p>In the end, I end up liking systemd-boot (formerly Gummiboot) more. It's refreshingly simple and easier to understand, doesn't this sound like Arch Linux?</p> <pre><code class="hljs bash"><span class="hljs-comment"># Install AMD microcode updates (pick `intel-ucode` for Intel CPU)</span> pacman -S amd-ucode <span class="hljs-comment"># Install systemd-boot on /boot</span> bootctl install <span class="hljs-comment"># Add bootloader config</span> <span class="hljs-built_in">cat</span> &gt; /boot/loader/loader.conf &lt;&lt;<span class="hljs-string">EOD</span> <span class="hljs-string">default arch-lts.conf</span> <span class="hljs-string">timeout 3</span> <span class="hljs-string">console-mode max</span> <span class="hljs-string">editor no</span> <span class="hljs-string">EOD</span> <span class="hljs-comment"># Add an entry for `linux-lts` (omit -lts for `linux`)</span> <span class="hljs-built_in">cat</span> &gt; /boot/loader/entries/arch-lts.conf &lt;&lt;<span class="hljs-string">EOD</span> <span class="hljs-string">title Arch Linux (LTS)</span> <span class="hljs-string">initrd /amd-ucode.img</span> <span class="hljs-string">initrd /initramfs-linux-lts.img</span> <span class="hljs-string">linux /vmlinuz-linux-lts</span> <span class="hljs-string">options root=/dev/mapper/crypt</span> <span class="hljs-string">EOD</span></code></pre> <p><code>options</code> are kernel params.</p> <ul> <li><a href="https://wiki.archlinux.org/title/Systemd-boot">systemd-boot - ArchWiki</a></li> </ul> <h2 id="network">Network</h2> <h3 id="systemd-networkd">systemd-networkd</h3> <pre><div class="caption"><span>/etc/systemd/network/wired.network</span></div><code class="hljs ini"><span class="hljs-section">[Match]</span> <span class="hljs-comment"># `ip l` to find the right interface</span> <span class="hljs-attr">Name</span>=enp5s0 <span class="hljs-section">[Network]</span> <span class="hljs-attr">Address</span>=<span class="hljs-number">10.0</span>.<span class="hljs-number">1.2</span>/<span class="hljs-number">24</span> <span class="hljs-attr">Gateway</span>=<span class="hljs-number">10.0</span>.<span class="hljs-number">1.1</span> <span class="hljs-attr">MulticastDNS</span>=<span class="hljs-literal">yes</span> <span class="hljs-comment">#DHCP=yes</span></code></pre> <pre><code class="hljs bash">systemctl <span class="hljs-built_in">enable</span> systemd-networkd</code></pre> <h3 id="systemd-resolved">systemd-resolved</h3> <pre><code class="hljs bash"><span class="hljs-built_in">mkdir</span> /etc/systemd/resolved.conf.d <span class="hljs-built_in">cat</span> &gt; /etc/systemd/resolved.conf.d/dns.conf &lt;&lt;<span class="hljs-string">EOD</span> <span class="hljs-string">[Resolve]</span> <span class="hljs-string">DNS=1.1.1.1 1.0.0.1</span> <span class="hljs-string">DNSOverTLS=yes</span> <span class="hljs-string">EOD</span> systemctl <span class="hljs-built_in">enable</span> systemd-resolved</code></pre> <ul> <li><a href="https://wiki.archlinux.org/title/Systemd-networkd">ArchWiki: systemd-networkd</a></li> <li><a href="https://wiki.archlinux.org/title/Systemd-resolved">ArchWiki: systemd-resolved</a></li> <li><a href="https://systemd.network/systemd.network.html">systemd.network</a></li> <li><a href="https://blog.ivansmirnov.name/set-up-pihole-using-docker-macvlan-network/">Ivan Smirnov's blog</a>.</li> </ul> <h2 id="sysctl">sysctl</h2> <pre><code class="hljs bash"><span class="hljs-comment"># Increase max map count for Elasticsearch on Docker</span> <span class="hljs-comment"># https://www.elastic.co/guide/en/elasticsearch/reference/current/docker.html#_linux</span> <span class="hljs-built_in">echo</span> <span class="hljs-string">"vm.max_map_count=262144"</span> &gt; /etc/sysctl.d/96-map-count.conf <span class="hljs-comment"># Increase inotify limit to avoid "too many open files"</span> <span class="hljs-built_in">echo</span> <span class="hljs-string">"fs.inotify.max_user_watches=1048576"</span> &gt; /etc/sysctl.d/97-inotify.conf <span class="hljs-comment"># Auto reboot after 60s of kernel panic</span> <span class="hljs-built_in">echo</span> <span class="hljs-string">"kernel.panic=60"</span> &gt; /etc/sysctl.d/98-kernel-panic.conf <span class="hljs-comment"># Tweak swappiness value for memory-rich servers</span> <span class="hljs-comment"># https://linuxhint.com/understanding_vm_swappiness/</span> <span class="hljs-built_in">echo</span> <span class="hljs-string">"vm.swappiness=10"</span> &gt; /etc/sysctl.d/99-swappiness.conf</code></pre> <h2 id="faillock">faillock</h2> <p>Change <code>deny</code> from <code>3</code> to <code>5</code>:</p> <pre><code class="hljs plaintext">sed '/^# deny/a deny = 5' -i /etc/security/faillock.conf</code></pre> <h2 id="nvidia-driver">NVIDIA driver</h2> <pre><code class="hljs bash"><span class="hljs-comment"># 'nvidia' for 'linux'</span> pacman -S nvidia-lts</code></pre> <h2 id="create-operator-user">Create operator user</h2> <pre><code class="hljs bash"><span class="hljs-comment"># Install ZSH and sudo</span> pacman -S zsh sudo <span class="hljs-comment"># Add operator user (op) with wheel membership</span> useradd -m -s /bin/zsh -G wheel op <span class="hljs-comment"># Change operator user password</span> passwd op <span class="hljs-comment"># Populate SSH public keys</span> <span class="hljs-built_in">mkdir</span> /home/op/.ssh curl -s https://github.com/&lt;username&gt;.keys &gt;&gt; /home/op/.ssh/authorized_keys <span class="hljs-built_in">chown</span> -R op:op /home/op/.ssh <span class="hljs-comment"># [!] Don't put SSH key pairs on the server. Use SSH agent forwarding instead.</span> <span class="hljs-comment"># Grant wheel group sudo priv</span> (<span class="hljs-built_in">umask</span> 0337; <span class="hljs-built_in">echo</span> <span class="hljs-string">"%wheel ALL=(ALL) ALL"</span> &gt; /etc/sudoers.d/wheel) visudo -c <span class="hljs-comment"># Verify sudoers</span> userdbctl <span class="hljs-comment"># Verify users</span> userdbctl group <span class="hljs-comment"># Verify groups</span></code></pre> <ul> <li><a href="https://en.wikipedia.org/wiki/Umask#Octal_codes">Octal codes - umask - Wikipedia</a></li> </ul> <h2 id="time-and-locales">Time and locales</h2> <pre><code class="hljs bash"><span class="hljs-comment"># Set time zone</span> <span class="hljs-built_in">ln</span> -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime <span class="hljs-comment"># Enable NTP</span> systemctl <span class="hljs-built_in">enable</span> systemd-timesyncd <span class="hljs-comment"># Sync system time to hardware clock</span> hwclock --systohc</code></pre> <pre><code class="hljs bash">sed <span class="hljs-string">'/#en_US.UTF-8 UTF-8/s/^#//'</span> -i /etc/locale.gen locale-gen <span class="hljs-built_in">echo</span> <span class="hljs-string">"LANG=en_US.UTF-8"</span> &gt;&gt; /etc/locale.conf</code></pre> <h2 id="leave-chroot-and-reboot">Leave chroot and reboot</h2> <pre><code class="hljs bash"><span class="hljs-built_in">exit</span> <span class="hljs-comment"># leave chroot</span> <span class="hljs-comment"># Symlink stub resolver config (non-chroot required)</span> <span class="hljs-built_in">ln</span> -rsf /run/systemd/resolve/stub-resolv.conf /mnt/etc/resolv.conf umount -R /mnt <span class="hljs-comment"># unmount /mnt recursively</span> reboot</code></pre> <p><strong>[!] From now on, run all commands as the operator user (use sudo if necessary)</strong></p> <h2 id="set-hostname">Set hostname</h2> <pre><code class="hljs bash">hostnamectl set-hostname tako hostnamectl set-chassis server <span class="hljs-built_in">echo</span> <span class="hljs-string">"127.0.0.1 tako"</span> &gt;&gt; /etc/hosts</code></pre> <ul> <li><a href="https://www.rfc-editor.org/rfc/rfc1178">RFC 1178: Choosing a name for your computer</a></li> <li><a href="https://www.rfc-editor.org/rfc/rfc8117.html">RFC 8117: Current Hostname Practice Considered Harmful</a></li> </ul> <h2 id="check-ups">Check-ups</h2> <pre><code class="hljs bash"><span class="hljs-comment"># Check network status</span> networkctl status resolvectl status resolvectl query uechi.io resolvectl query -p mdns tako.local <span class="hljs-comment"># Verify time and NTP status</span> timedatectl status <span class="hljs-comment"># Verify sysctl values</span> sysctl --system</code></pre> <blockquote> <p>If <code>networkctl</code> keeps showing <code>enp5s0</code> as <code>degraded</code>, then run <code>ip addr add 10.0.1.2/24 dev enp5s0</code> to manually assign static IP address for the workaround.</p> </blockquote> <h2 id="s.m.a.r.t.">S.M.A.R.T.</h2> <pre><code class="hljs bash">pacman -S smartmontools <span class="hljs-comment"># Needed for sending email</span> pacman -S s-nail</code></pre> <h3 id="automated-disk-health-check-ups-and-reporting">Automated disk health check-ups and reporting</h3> <pre><div class="caption"><span>/etc/smartd.conf</span></div><code class="hljs ini"><span class="hljs-comment"># Scan all but removable devices and notify any test failures</span> <span class="hljs-comment"># Also, start a short self-test every day around 1-2am, and a long self test every Saturday around 3-4am</span> DEVICESCAN -a -o on -S on -n standby,q -s (S/../.././02|L/../../6/03) -m [email protected]</code></pre> <blockquote> <p>Tips: Add <code>-M test</code> immediately after <code>DEVICESCAN</code> to send test mail</p> </blockquote> <pre><code class="hljs bash">systemctl <span class="hljs-built_in">enable</span> --now smartd</code></pre> <h3 id="manual-testing">Manual testing</h3> <pre><code class="hljs bash">smartctl -t short /dev/sda smartctl -l selftest /dev/sda</code></pre> <ul> <li><a href="https://wiki.archlinux.org/title/S.M.A.R.T.">S.M.A.R.T. - ArchWiki</a></li> <li><a href="https://wiki.archlinux.org/title/S-nail">S-nail - ArchWiki</a></li> </ul> <h2 id="aur-helper-yay">AUR Helper (yay)</h2> <pre><code class="hljs bash">pacman -S base-devel git git <span class="hljs-built_in">clone</span> https://aur.archlinux.org/yay.git <span class="hljs-built_in">cd</span> yay makepkg -si</code></pre> <h2 id="docker">Docker</h2> <pre><code class="hljs bash">pacman -S docker docker-compose yay -S nvidia-container-runtime</code></pre> <pre><div class="caption"><span>/etc/docker/daemon.json</span></div><code class="hljs json"><span class="hljs-punctuation">{</span> <span class="hljs-attr">"log-driver"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"json-file"</span><span class="hljs-punctuation">,</span> <span class="hljs-comment">// default: "json-file"</span> <span class="hljs-attr">"log-opts"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span> <span class="hljs-attr">"max-size"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"10m"</span><span class="hljs-punctuation">,</span> <span class="hljs-comment">// default: -1 (unlimited)</span> <span class="hljs-attr">"max-file"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"3"</span> <span class="hljs-comment">// default: 1</span> <span class="hljs-punctuation">}</span><span class="hljs-punctuation">,</span> <span class="hljs-attr">"runtimes"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span> <span class="hljs-comment">// for Docker Compose</span> <span class="hljs-attr">"nvidia"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span> <span class="hljs-attr">"path"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"/usr/bin/nvidia-container-runtime"</span><span class="hljs-punctuation">,</span> <span class="hljs-attr">"runtimeArgs"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span><span class="hljs-punctuation">]</span> <span class="hljs-punctuation">}</span> <span class="hljs-punctuation">}</span> <span class="hljs-punctuation">}</span></code></pre> <pre><code class="hljs bash">systemctl <span class="hljs-built_in">enable</span> --now docker <span class="hljs-comment"># Allow operator user to run docker command without sudo (less secure)</span> <span class="hljs-comment"># Re-login for the changes to take effect</span> usermod -aG docker op <span class="hljs-comment"># Enable Swarm</span> docker swarm init --advertise-addr $(curl -s https://ip.seeip.org) <span class="hljs-comment"># Create overlay network for Swarm stack</span> <span class="hljs-comment"># docker network create --attachable -d overlay --subnet 10.11.0.0/24 &lt;network&gt;</span> <span class="hljs-comment"># Verify installation</span> docker run --<span class="hljs-built_in">rm</span> --gpus all nvidia/cuda:11.7.1-cudnn8-runtime-ubuntu20.04 nvidia-smi</code></pre> <ul> <li><a href="https://github.com/NVIDIA/nvidia-container-runtime">NVIDIA/nvidia-container-runtime: NVIDIA container runtime</a></li> </ul> <h3 id="cross-platform-build-support-buildkit-qemu">Cross-platform build support (BuildKit, QEMU)</h3> <pre><code class="hljs bash">docker run --<span class="hljs-built_in">rm</span> --privileged multiarch/qemu-user-static --reset --persistent <span class="hljs-built_in">yes</span> <span class="hljs-comment"># Verify</span> docker run --<span class="hljs-built_in">rm</span> --platform linux/arm64/v8 -t arm64v8/ubuntu <span class="hljs-built_in">uname</span> -m <span class="hljs-comment"># =&gt; aarch64</span></code></pre> <h3 id="tips-use-journald-log-driver-in-docker-compose">Tips: Use <code>journald</code> log driver in Docker Compose</h3> <p>This is particularly useful when you want to feed container logs to fail2ban through journald.</p> <pre><code class="hljs yaml"><span class="hljs-attr">services:</span> <span class="hljs-attr">web:</span> <span class="hljs-attr">logging:</span> <span class="hljs-attr">driver:</span> <span class="hljs-string">"journald"</span> <span class="hljs-attr">options:</span> <span class="hljs-attr">tag:</span> <span class="hljs-string">"<span class="hljs-template-variable">{{.ImageName}}</span>/<span class="hljs-template-variable">{{.Name}}</span>/<span class="hljs-template-variable">{{.ID}}</span>"</span> <span class="hljs-comment"># default: "{{.ID}}"</span></code></pre> <ul> <li><a href="https://docs.docker.com/config/containers/logging/configure/">Configure logging drivers | Docker Documentation</a></li> <li><a href="https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/arch-overview.html">Architecture Overview — NVIDIA Cloud Native Technologies documentation</a></li> </ul> <h2 id="dns-resolver-pi-hole-unbound">DNS resolver (Pi-hole + unbound)</h2> <pre><code class="hljs bash">git <span class="hljs-built_in">clone</span> https://github.com/uetchy/docker-dns /srv/dns <span class="hljs-built_in">cd</span> /srv/dns <span class="hljs-built_in">rm</span> -rf .git <span class="hljs-built_in">cp</span> .env.example .<span class="hljs-built_in">env</span> vim .<span class="hljs-built_in">env</span> <span class="hljs-built_in">mkdir</span> -p data/unbound <span class="hljs-built_in">cp</span> examples/unbound/forward-records.conf data/unbound/ vim data/unbound/forward-records.conf <span class="hljs-comment"># see below</span> docker compose up -d</code></pre> <blockquote> <p>For Quad9 resolver, I chose <a href="https://www.quad9.net/service/service-addresses-and-features/#ecssec">ECS-enabled resolver</a> because their nearest <a href="https://en.wikipedia.org/wiki/Anycast#Domain_Name_System">anycast</a> server from Tokyo is in another country (Singapore), which could confuse CDN server selection and result in higher latency.</p> <p>If your favorite DNS resolver DOES have their anycast servers near your city, you don't need ECS at all.</p> <p>If you are in Japan, I would recommend <a href="https://public.dns.iij.jp/">IIJ Public DNS</a>. They offer secure DoT/DoH resolvers (actually, they don't support "normal" unencrypted DNS queries so there's no room for the "accidental fallback to an unencrypted query in <a href="https://en.wikipedia.org/wiki/Opportunistic_TLS">Opportunistic TLS</a> configuration" scenario)</p> </blockquote> <pre><div class="caption"><span>/etc/systemd/network/dns-shim.netdev</span></div><code class="hljs ini"><span class="hljs-comment"># workaround to route local dns lookups to Docker managed MACVLAN interface</span> <span class="hljs-section">[NetDev]</span> <span class="hljs-attr">Name</span>=dns-shim <span class="hljs-attr">Kind</span>=macvlan <span class="hljs-section">[MACVLAN]</span> <span class="hljs-attr">Mode</span>=bridge</code></pre> <pre><div class="caption"><span>/etc/systemd/network/dns-shim.network</span></div><code class="hljs ini"><span class="hljs-comment"># workaround to route local dns lookups to Docker managed MACVLAN interface</span> <span class="hljs-section">[Match]</span> <span class="hljs-attr">Name</span>=dns-shim <span class="hljs-section">[Network]</span> <span class="hljs-attr">IPForward</span>=<span class="hljs-literal">yes</span> <span class="hljs-section">[Address]</span> <span class="hljs-attr">Address</span>=<span class="hljs-number">10.0</span>.<span class="hljs-number">1.103</span>/<span class="hljs-number">32</span> <span class="hljs-attr">Scope</span>=link <span class="hljs-section">[Route]</span> <span class="hljs-attr">Destination</span>=<span class="hljs-number">10.0</span>.<span class="hljs-number">1.100</span>/<span class="hljs-number">30</span></code></pre> <pre><code class="hljs bash"><span class="hljs-built_in">cat</span> &gt;&gt; /etc/systemd/network/wired.network &lt;&lt;<span class="hljs-string">EOD</span> <span class="hljs-string"># workaround to route local dns lookups to Docker managed MACVLAN interface</span> <span class="hljs-string">MACVLAN=dns-shim</span> <span class="hljs-string">EOD</span> <span class="hljs-built_in">cat</span> &gt; /etc/systemd/resolved.conf.d/dns.conf &lt;&lt;<span class="hljs-string">EOD</span> <span class="hljs-string">[Resolve]</span> <span class="hljs-string">DNS=10.0.1.100</span> <span class="hljs-string">EOD</span></code></pre> <blockquote> <p>If you want to do the same thing but using <code>ip</code>:</p> <pre><code class="hljs bash">ip <span class="hljs-built_in">link</span> add dns-shim <span class="hljs-built_in">link</span> enp5s0 <span class="hljs-built_in">type</span> macvlan mode bridge <span class="hljs-comment"># add macvlan shim interface</span> ip a add 10.0.1.103/32 dev dns-shim <span class="hljs-comment"># assign the interface an ip address</span> ip <span class="hljs-built_in">link</span> <span class="hljs-built_in">set</span> dns-shim up <span class="hljs-comment"># enable the interface</span> ip route add 10.0.1.100/30 dev dns-shim <span class="hljs-comment"># route macvlan subnet (.100 - .103) to the interface</span></code></pre> </blockquote> <h2 id="ddns-cfddns">DDNS (cfddns)</h2> <p>Dynamic DNS for Cloudflare.</p> <blockquote> <p>Star <a href="https://github.com/uetchy/cfddns">the GitHub repository</a> if you like it :)</p> </blockquote> <pre><code class="hljs bash">yay -S cfddns</code></pre> <pre><div class="caption"><span>/etc/cfddns/cfddns.yml</span></div><code class="hljs yml"><span class="hljs-attr">token:</span> <span class="hljs-string">&lt;token&gt;</span> <span class="hljs-attr">notification:</span> <span class="hljs-comment"># You'll need local mail transfer agent such as Mailu/Mailcow</span> <span class="hljs-attr">enabled:</span> <span class="hljs-literal">true</span> <span class="hljs-attr">from:</span> <span class="hljs-string">cfddns@localhost</span> <span class="hljs-attr">to:</span> <span class="hljs-string">[email protected]</span> <span class="hljs-attr">server:</span> <span class="hljs-string">localhost</span></code></pre> <pre><div class="caption"><span>/etc/cfddns/domains</span></div><code class="hljs ini">example.com dev.example.com example.org</code></pre> <pre><code class="hljs plaintext">systemctl enable --now cfddns</code></pre> <h2 id="reverse-proxy-nginx-proxy">Reverse proxy (nginx-proxy)</h2> <p>nginx-proxy serves as an ingress gateway for port 80 and 443, as well as a TLS terminal.</p> <pre><code class="hljs bash">git <span class="hljs-built_in">clone</span> --recurse-submodules https://github.com/evertramos/nginx-proxy-automation.git /srv/proxy <span class="hljs-built_in">cd</span> /srv/proxy/bin ./fresh-start.sh --<span class="hljs-built_in">yes</span> -e your_email@domain --skip-docker-image-check</code></pre> <ul> <li><a href="https://github.com/evertramos/nginx-proxy-automation/tree/master/docs">nginx-proxy-automation/docs at master · evertramos/nginx-proxy-automation · GitHub</a></li> </ul> <h2 id="acme-ca-step-ca">ACME CA (step-ca)</h2> <p>With nginx-proxy, you can generate and auto-rotate self-signed ACME certificates for private Docker containers.</p> <pre><div class="caption"><span>/srv/ca/docker-compose.yml</span></div><code class="hljs yaml"><span class="hljs-attr">version:</span> <span class="hljs-string">"3"</span> <span class="hljs-attr">services:</span> <span class="hljs-attr">step-ca:</span> <span class="hljs-attr">image:</span> <span class="hljs-string">smallstep/step-ca:0.22.1</span> <span class="hljs-attr">restart:</span> <span class="hljs-string">unless-stopped</span> <span class="hljs-attr">ports:</span> <span class="hljs-bullet">-</span> <span class="hljs-string">"9000:9000"</span> <span class="hljs-attr">environment:</span> <span class="hljs-attr">DOCKER_STEPCA_INIT_NAME:</span> <span class="hljs-string">${DOCKER_STEPCA_INIT_NAME}</span> <span class="hljs-attr">DOCKER_STEPCA_INIT_DNS_NAMES:</span> <span class="hljs-string">${DOCKER_STEPCA_INIT_DNS_NAMES}</span> <span class="hljs-attr">volumes:</span> <span class="hljs-bullet">-</span> <span class="hljs-string">"./data/step-ca:/home/step"</span> <span class="hljs-attr">dns:</span> <span class="hljs-comment"># Split horizon DNS server for private web services (also point &lt;domain&gt; to the server)</span> <span class="hljs-bullet">-</span> <span class="hljs-number">10.0</span><span class="hljs-number">.1</span><span class="hljs-number">.100</span></code></pre> <pre><div class="caption"><span>/srv/ca/.env</span></div><code class="hljs ini"><span class="hljs-attr">DOCKER_STEPCA_INIT_NAME</span>=MySign Root CA <span class="hljs-attr">DOCKER_STEPCA_INIT_DNS_NAMES</span>=localhost,&lt;hostname&gt;,&lt;domain&gt;</code></pre> <pre><code class="hljs bash">pacman -S step-cli <span class="hljs-comment"># Start step-ca</span> docker compose up -d <span class="hljs-comment"># Show CA password</span> docker compose <span class="hljs-built_in">exec</span> step-ca <span class="hljs-built_in">cat</span> secrets/password <span class="hljs-comment"># Enable ACME module</span> docker compose <span class="hljs-built_in">exec</span> step-ca step ca provisioner add acme --<span class="hljs-built_in">type</span> ACME <span class="hljs-comment"># Download root cert and CA configuration</span> CA_FINGERPRINT=$(docker compose <span class="hljs-built_in">exec</span> step-ca step certificate fingerprint certs/root_ca.crt) step-cli ca bootstrap --ca-url https://localhost:9000 --fingerprint <span class="hljs-variable">$CA_FINGERPRINT</span> <span class="hljs-comment"># Test installation</span> step-cli certificate inspect $(step-cli path)/certs/root_ca.crt step-cli certificate inspect https://&lt;domain&gt;:9000 <span class="hljs-comment"># Install root cert system-wide</span> step-cli certificate install $(step-cli path)/certs/root_ca.crt</code></pre> <h2 id="auth-gateway-and-identity-provider-authelia">Auth gateway and identity provider (Authelia)</h2> <p>Authelia acts as:</p> <ul> <li>OIDC identity provider (single sign-on)</li> <li>Auth gateway for some self-hosted web apps lacking user authentication</li> </ul> <pre><div class="caption"><span>/srv/authelia/docker-compose.yml</span></div><code class="hljs yml"><span class="hljs-attr">version:</span> <span class="hljs-string">"3.9"</span> <span class="hljs-attr">secrets:</span> <span class="hljs-attr">JWT_SECRET:</span> <span class="hljs-attr">file:</span> <span class="hljs-string">./data/authelia/secrets/JWT_SECRET</span> <span class="hljs-attr">SESSION_SECRET:</span> <span class="hljs-attr">file:</span> <span class="hljs-string">./data/authelia/secrets/SESSION_SECRET</span> <span class="hljs-attr">STORAGE_PASSWORD:</span> <span class="hljs-attr">file:</span> <span class="hljs-string">./data/authelia/secrets/STORAGE_PASSWORD</span> <span class="hljs-attr">STORAGE_ENCRYPTION_KEY:</span> <span class="hljs-attr">file:</span> <span class="hljs-string">./data/authelia/secrets/STORAGE_ENCRYPTION_KEY</span> <span class="hljs-attr">OIDC_HMAC_SECRET:</span> <span class="hljs-attr">file:</span> <span class="hljs-string">./data/authelia/secrets/OIDC_HMAC_SECRET</span> <span class="hljs-attr">PRIVATE_KEY:</span> <span class="hljs-attr">file:</span> <span class="hljs-string">./data/authelia/keys/private.pem</span> <span class="hljs-attr">services:</span> <span class="hljs-attr">server:</span> <span class="hljs-attr">container_name:</span> <span class="hljs-string">authelia</span> <span class="hljs-attr">image:</span> <span class="hljs-string">authelia/authelia:4</span> <span class="hljs-attr">restart:</span> <span class="hljs-string">unless-stopped</span> <span class="hljs-attr">networks:</span> <span class="hljs-bullet">-</span> <span class="hljs-string">default</span> <span class="hljs-bullet">-</span> <span class="hljs-string">webproxy</span> <span class="hljs-attr">secrets:</span> <span class="hljs-bullet">-</span> <span class="hljs-string">JWT_SECRET</span> <span class="hljs-bullet">-</span> <span class="hljs-string">SESSION_SECRET</span> <span class="hljs-bullet">-</span> <span class="hljs-string">STORAGE_PASSWORD</span> <span class="hljs-bullet">-</span> <span class="hljs-string">STORAGE_ENCRYPTION_KEY</span> <span class="hljs-bullet">-</span> <span class="hljs-string">OIDC_HMAC_SECRET</span> <span class="hljs-bullet">-</span> <span class="hljs-string">PRIVATE_KEY</span> <span class="hljs-attr">environment:</span> <span class="hljs-attr">AUTHELIA_JWT_SECRET_FILE:</span> <span class="hljs-string">/run/secrets/JWT_SECRET</span> <span class="hljs-attr">AUTHELIA_SESSION_SECRET_FILE:</span> <span class="hljs-string">/run/secrets/SESSION_SECRET</span> <span class="hljs-attr">AUTHELIA_STORAGE_POSTGRES_PASSWORD_FILE:</span> <span class="hljs-string">/run/secrets/STORAGE_PASSWORD</span> <span class="hljs-attr">AUTHELIA_STORAGE_ENCRYPTION_KEY_FILE:</span> <span class="hljs-string">/run/secrets/STORAGE_ENCRYPTION_KEY</span> <span class="hljs-attr">AUTHELIA_IDENTITY_PROVIDERS_OIDC_HMAC_SECRET:</span> <span class="hljs-string">/run/secrets/OIDC_HMAC_SECRET</span> <span class="hljs-attr">AUTHELIA_IDENTITY_PROVIDERS_OIDC_ISSUER_PRIVATE_KEY_FILE:</span> <span class="hljs-string">/run/secrets/PRIVATE_KEY</span> <span class="hljs-attr">VIRTUAL_PROTO:</span> <span class="hljs-string">https</span> <span class="hljs-attr">VIRTUAL_HOST:</span> <span class="hljs-string">${VIRTUAL_HOST}</span> <span class="hljs-attr">LETSENCRYPT_HOST:</span> <span class="hljs-string">${VIRTUAL_HOST}</span> <span class="hljs-attr">volumes:</span> <span class="hljs-bullet">-</span> <span class="hljs-string">./data/authelia/config:/config</span> <span class="hljs-bullet">-</span> <span class="hljs-string">${AUTHELIA_CERTS}:/certs:ro</span> <span class="hljs-attr">depends_on:</span> <span class="hljs-bullet">-</span> <span class="hljs-string">redis</span> <span class="hljs-bullet">-</span> <span class="hljs-string">postgres</span> <span class="hljs-attr">redis:</span> <span class="hljs-attr">image:</span> <span class="hljs-string">redis:7-alpine</span> <span class="hljs-attr">restart:</span> <span class="hljs-string">unless-stopped</span> <span class="hljs-attr">volumes:</span> <span class="hljs-bullet">-</span> <span class="hljs-string">./data/redis:/data</span> <span class="hljs-attr">postgres:</span> <span class="hljs-attr">image:</span> <span class="hljs-string">postgres:11-alpine</span> <span class="hljs-attr">restart:</span> <span class="hljs-string">unless-stopped</span> <span class="hljs-attr">secrets:</span> <span class="hljs-bullet">-</span> <span class="hljs-string">STORAGE_PASSWORD</span> <span class="hljs-attr">environment:</span> <span class="hljs-attr">POSTGRES_USER:</span> <span class="hljs-string">authelia</span> <span class="hljs-attr">POSTGRES_PASSWORD_FILE:</span> <span class="hljs-string">/run/secrets/STORAGE_PASSWORD</span> <span class="hljs-attr">POSTGRES_DB:</span> <span class="hljs-string">authelia</span> <span class="hljs-attr">volumes:</span> <span class="hljs-bullet">-</span> <span class="hljs-string">./data/postgres:/var/lib/postgresql/data</span> <span class="hljs-attr">networks:</span> <span class="hljs-attr">webproxy:</span> <span class="hljs-attr">external:</span> <span class="hljs-literal">true</span></code></pre> <pre><div class="caption"><span>/srv/authelia/.env</span></div><code class="hljs ini"><span class="hljs-attr">VIRTUAL_HOST</span>=auth.example.com <span class="hljs-comment"># Use nginx-proxy managed TLS cert</span> <span class="hljs-attr">AUTHELIA_CERTS</span>=/srv/proxy/data/certs/auth.example.com</code></pre> <h2 id="mail-server-mailu">Mail server (Mailu)</h2> <p>See <a href="https://mailu.io/1.9/setup.html">Setup a new Mailu server — Mailu, Docker based mail server</a></p> <h2 id="nextcloud">Nextcloud</h2> <pre><code class="hljs bash">git <span class="hljs-built_in">clone</span> https://github.com/uetchy/docker-nextcloud.git /srv/cloud <span class="hljs-built_in">cd</span> /srv/cloud <span class="hljs-built_in">cp</span> .env.example .<span class="hljs-built_in">env</span> vim .<span class="hljs-built_in">env</span> <span class="hljs-comment"># fill the blank variables</span> make <span class="hljs-comment"># pull, build, start</span> make applypatches <span class="hljs-comment"># apply custom patches (run only once after the update)</span></code></pre> <h2 id="monitor-telegraf-influxdb-grafana">Monitor (Telegraf + InfluxDB + Grafana)</h2> <h3 id="grafana-influxdb-docker">Grafana + InfluxDB (Docker)</h3> <pre><code class="hljs bash">git <span class="hljs-built_in">clone</span> https://github.com/uetchy/docker-monitor.git /srv/monitor <span class="hljs-built_in">cd</span> /srv/monitor docker compose up -d</code></pre> <h3 id="telegraf-host">Telegraf (Host)</h3> <pre><code class="hljs bash">yay -S telegraf</code></pre> <pre><div class="caption"><span>/etc/telegraf/telegraf.conf</span></div><code class="hljs ini"><span class="hljs-comment"># Global tags can be specified here in key="value" format.</span> <span class="hljs-section">[global_tags]</span> <span class="hljs-comment"># Configuration for telegraf agent</span> <span class="hljs-section">[agent]</span> <span class="hljs-attr">interval</span> = <span class="hljs-string">"15s"</span> <span class="hljs-attr">round_interval</span> = <span class="hljs-literal">true</span> <span class="hljs-attr">metric_batch_size</span> = <span class="hljs-number">1000</span> <span class="hljs-attr">metric_buffer_limit</span> = <span class="hljs-number">10000</span> <span class="hljs-attr">collection_jitter</span> = <span class="hljs-string">"0s"</span> <span class="hljs-attr">flush_interval</span> = <span class="hljs-string">"10s"</span> <span class="hljs-attr">flush_jitter</span> = <span class="hljs-string">"0s"</span> <span class="hljs-attr">precision</span> = <span class="hljs-string">""</span> <span class="hljs-attr">hostname</span> = <span class="hljs-string">"tako"</span> <span class="hljs-attr">omit_hostname</span> = <span class="hljs-literal">false</span> <span class="hljs-comment"># Read InfluxDB-formatted JSON metrics from one or more HTTP endpoints</span> <span class="hljs-section">[[outputs.influxdb]]</span> <span class="hljs-attr">urls</span> = [<span class="hljs-string">"http://127.0.0.1:8086"</span>] <span class="hljs-attr">database</span> = <span class="hljs-string">"&lt;db&gt;"</span> <span class="hljs-attr">username</span> = <span class="hljs-string">"&lt;user&gt;"</span> <span class="hljs-attr">password</span> = <span class="hljs-string">"&lt;password&gt;"</span> <span class="hljs-comment"># Read metrics about cpu usage</span> <span class="hljs-section">[[inputs.cpu]]</span> <span class="hljs-attr">percpu</span> = <span class="hljs-literal">true</span> <span class="hljs-attr">totalcpu</span> = <span class="hljs-literal">true</span> <span class="hljs-attr">collect_cpu_time</span> = <span class="hljs-literal">false</span> <span class="hljs-attr">report_active</span> = <span class="hljs-literal">false</span> <span class="hljs-comment"># Read metrics about disk usage by mount point</span> <span class="hljs-section">[[inputs.disk]]</span> <span class="hljs-attr">ignore_fs</span> = [<span class="hljs-string">"tmpfs"</span>, <span class="hljs-string">"devtmpfs"</span>, <span class="hljs-string">"devfs"</span>, <span class="hljs-string">"iso9660"</span>, <span class="hljs-string">"overlay"</span>, <span class="hljs-string">"aufs"</span>, <span class="hljs-string">"squashfs"</span>] <span class="hljs-comment"># Read metrics about disk IO by device</span> <span class="hljs-section">[[inputs.diskio]]</span> <span class="hljs-comment"># Get kernel statistics from /proc/stat</span> <span class="hljs-section">[[inputs.kernel]]</span> <span class="hljs-comment"># Read metrics about memory usage</span> <span class="hljs-section">[[inputs.mem]]</span> <span class="hljs-comment"># Get the number of processes and group them by status</span> <span class="hljs-section">[[inputs.processes]]</span> <span class="hljs-comment"># Read metrics about system load &amp; uptime</span> <span class="hljs-section">[[inputs.system]]</span> <span class="hljs-comment"># Read metrics about network interface usage</span> <span class="hljs-section">[[inputs.net]]</span> <span class="hljs-attr">interfaces</span> = [<span class="hljs-string">"enp5s0"</span>] <span class="hljs-comment"># Read metrics about docker containers, requires docker group membership for telegraf user</span> <span class="hljs-section">[[inputs.docker]]</span> <span class="hljs-attr">endpoint</span> = <span class="hljs-string">"unix:///var/run/docker.sock"</span> <span class="hljs-attr">perdevice</span> = <span class="hljs-literal">false</span> <span class="hljs-attr">total</span> = <span class="hljs-literal">true</span> <span class="hljs-section">[[inputs.fail2ban]]</span> <span class="hljs-attr">interval</span> = <span class="hljs-string">"15m"</span> <span class="hljs-attr">use_sudo</span> = <span class="hljs-literal">true</span> <span class="hljs-comment"># Pulls statistics from nvidia GPUs attached to the host</span> <span class="hljs-section">[[inputs.nvidia_smi]]</span> <span class="hljs-attr">timeout</span> = <span class="hljs-string">"30s"</span> <span class="hljs-section">[[inputs.http_response]]</span> <span class="hljs-attr">interval</span> = <span class="hljs-string">"5m"</span> <span class="hljs-attr">urls</span> = [ <span class="hljs-string">"https://example.com"</span> ] <span class="hljs-comment"># Monitor sensors, requires lm-sensors package</span> <span class="hljs-section">[[inputs.sensors]]</span> <span class="hljs-attr">interval</span> = <span class="hljs-string">"60s"</span> <span class="hljs-attr">remove_numbers</span> = <span class="hljs-literal">false</span></code></pre> <pre><div class="caption"><span>/etc/sudoers.d/telegraf</span></div><code class="hljs ini">Cmnd_Alias <span class="hljs-attr">FAIL2BAN</span> = /usr/bin/fail2ban-client status, /usr/bin/fail2ban-client status * telegraf <span class="hljs-attr">ALL</span>=(root) NOEXEC: NOPASSWD: FAIL2BAN Defaults!FAIL2BAN !logfile, !syslog, !pam_session</code></pre> <pre><code class="hljs bash"><span class="hljs-built_in">chmod</span> 440 /etc/sudoers.d/telegraf <span class="hljs-built_in">chown</span> -R telegraf /etc/telegraf usermod -aG docker telegraf <span class="hljs-comment"># Verify config</span> telegraf -config /etc/telegraf/telegraf.conf -<span class="hljs-built_in">test</span> systemctl <span class="hljs-built_in">enable</span> --now telegraf</code></pre> <h2 id="bruce-force-attack-mitigation-fail2ban">Bruce-force attack mitigation (fail2ban)</h2> <pre><code class="hljs plaintext">pacman -S fail2ban</code></pre> <pre><div class="caption"><span>/etc/fail2ban/jail.local</span></div><code class="hljs ini"><span class="hljs-section">[DEFAULT]</span> <span class="hljs-attr">ignoreip</span> = <span class="hljs-number">127.0</span>.<span class="hljs-number">0.1</span>/<span class="hljs-number">8</span> <span class="hljs-number">10.0</span>.<span class="hljs-number">1.0</span>/<span class="hljs-number">24</span> <span class="hljs-number">10.0</span>.<span class="hljs-number">10.0</span>/<span class="hljs-number">24</span> <span class="hljs-section">[sshd]</span> <span class="hljs-attr">enabled</span> = <span class="hljs-literal">true</span> <span class="hljs-attr">port</span> = <span class="hljs-number">12345</span> <span class="hljs-attr">bantime</span> = <span class="hljs-number">1</span>h <span class="hljs-attr">mode</span> = aggressive <span class="hljs-comment"># https://mailu.io/1.9/faq.html?highlight=fail2ban#do-you-support-fail2ban</span> <span class="hljs-section">[mailu]</span> <span class="hljs-attr">enabled</span> = <span class="hljs-literal">true</span> <span class="hljs-attr">backend</span> = systemd <span class="hljs-attr">filter</span> = mailu <span class="hljs-attr">action</span> = docker-action <span class="hljs-attr">findtime</span> = <span class="hljs-number">15</span>m <span class="hljs-attr">maxretry</span> = <span class="hljs-number">10</span> <span class="hljs-attr">bantime</span> = <span class="hljs-number">1</span>w <span class="hljs-section">[gitea]</span> <span class="hljs-attr">enabled</span> = <span class="hljs-literal">true</span> <span class="hljs-attr">backend</span> = systemd <span class="hljs-attr">filter</span> = gitea <span class="hljs-attr">action</span> = docker-action <span class="hljs-attr">findtime</span> = <span class="hljs-number">30</span>m <span class="hljs-attr">maxretry</span> = <span class="hljs-number">5</span> <span class="hljs-attr">bantime</span> = <span class="hljs-number">1</span>w</code></pre> <pre><div class="caption"><span>/etc/fail2ban/filter.d/mailu.conf</span></div><code class="hljs ini"><span class="hljs-section">[INCLUDES]</span> <span class="hljs-attr">before</span> = common.conf <span class="hljs-section">[Definition]</span> <span class="hljs-attr">__date</span> = \d{<span class="hljs-number">4</span>}/\d{<span class="hljs-number">2</span>}/\d{<span class="hljs-number">2</span>} \d{<span class="hljs-number">2</span>}:\d{<span class="hljs-number">2</span>}:\d{<span class="hljs-number">2</span>} <span class="hljs-attr">__mailu_prefix</span> = ^%(__prefix_line)s%(__date)s \[info\] \d+<span class="hljs-comment">#\d+: \*\d+ client login failed:</span> <span class="hljs-attr">__mailu_suffix</span> = while in http auth state, client: &lt;HOST&gt;, <span class="hljs-attr">failregex</span> = %(__mailu_prefix)s "AUTH not supported" %(__mailu_suffix)s %(__mailu_prefix)s "Authentication credentials invalid" %(__mailu_suffix)s <span class="hljs-attr">journalmatch</span> = CONTAINER_NAME=mail-front-<span class="hljs-number">1</span></code></pre> <pre><div class="caption"><span>/etc/fail2ban/filter.d/gitea.conf</span></div><code class="hljs ini"><span class="hljs-section">[INCLUDES]</span> <span class="hljs-attr">before</span> = common.conf <span class="hljs-section">[Definition]</span> <span class="hljs-attr">failregex</span> = ^%(__prefix_line)sDisconnected from invalid user \S+ &lt;HOST&gt; port \d+ \[preauth\] <span class="hljs-attr">journalmatch</span> = CONTAINER_NAME=gitea</code></pre> <pre><div class="caption"><span>/etc/fail2ban/action.d/docker-action.conf</span></div><code class="hljs ini"><span class="hljs-section">[Definition]</span> <span class="hljs-attr">actionstart</span> = iptables -N f2b-bad-auth iptables -A f2b-bad-auth -j RETURN iptables -I DOCKER-USER -p tcp -j f2b-bad-auth <span class="hljs-attr">actionstop</span> = iptables -D DOCKER-USER -p tcp -j f2b-bad-auth iptables -F f2b-bad-auth iptables -X f2b-bad-auth <span class="hljs-attr">actioncheck</span> = iptables -n -L DOCKER-USER | grep -q <span class="hljs-string">'f2b-bad-auth[ \t]'</span> <span class="hljs-attr">actionban</span> = iptables -I f2b-bad-auth <span class="hljs-number">1</span> -s &lt;ip&gt; -j DROP <span class="hljs-attr">actionunban</span> = iptables -D f2b-bad-auth -s &lt;ip&gt; -j DROP</code></pre> <pre><code class="hljs bash"><span class="hljs-comment"># Test regex pattern or specific filter against journald logs</span> fail2ban-regex systemd-journal -m <span class="hljs-string">'CONTAINER_NAME=gitea'</span> <span class="hljs-string">': Disconnected from invalid user .+ &lt;HOST&gt; port \d+ \[preauth\]'</span> fail2ban-regex systemd-journal -m <span class="hljs-string">'CONTAINER_NAME=gitea'</span> gitea --print-all-matched <span class="hljs-comment"># Test config</span> fail2ban-client --<span class="hljs-built_in">test</span> systemctl <span class="hljs-built_in">enable</span> --now fail2ban fail2ban-client status</code></pre> <ul> <li><a href="https://wiki.archlinux.org/title/fail2ban">Fail2ban - ArchWiki</a></li> <li><a href="https://www.fail2ban.org/wiki/index.php/Manual">Manual - Fail2ban</a></li> <li><a href="https://fail2ban.readthedocs.io/en/latest/filters.html#developing-filter-regular-expressions">Developing Filters — Fail2Ban documentation</a></li> <li><a href="https://docs.docker.com/config/containers/logging/journald/">Journald logging driver | Docker Documentation</a></li> </ul> <h2 id="firewall-ufw">Firewall (ufw)</h2> <pre><code class="hljs bash">pacman -S ufw systemctl <span class="hljs-built_in">enable</span> --now ufw</code></pre> <ul> <li><a href="https://wiki.archlinux.org/title/Uncomplicated_Firewall">Uncomplicated Firewall - ArchWiki</a></li> <li><a href="https://home.regit.org/netfilter-en/netfilter/">Introduction to Netfilter – To Linux and beyond !</a></li> </ul> <h2 id="vpn-wireguard">VPN (WireGuard)</h2> <pre><code class="hljs bash">pacman -S wireguard-tools <span class="hljs-comment"># gen private key</span> (<span class="hljs-built_in">umask</span> 0077; wg genkey &gt; server.key) <span class="hljs-comment"># gen public key</span> wg pubkey &lt; server.key &gt; server.pub <span class="hljs-comment"># gen preshared key for each client</span> (<span class="hljs-built_in">umask</span> 0077; wg genpsk &gt; secret1.psk) (<span class="hljs-built_in">umask</span> 0077; wg genpsk &gt; secret2.psk) ...</code></pre> <pre><div class="caption"><span>/etc/wireguard/wg0.conf</span></div><code class="hljs ini"><span class="hljs-section">[Interface]</span> <span class="hljs-attr">Address</span> = <span class="hljs-number">10.0</span>.<span class="hljs-number">10.1</span>/<span class="hljs-number">24</span> <span class="hljs-attr">ListenPort</span> = <span class="hljs-number">121212</span> <span class="hljs-attr">PrivateKey</span> = &lt;content of server.key&gt; <span class="hljs-attr">PostUp</span> = iptables -A FORWARD -i %i -j ACCEPT<span class="hljs-comment">; iptables -t nat -A POSTROUTING -o dns-shim -d 10.0.1.100/32 -j MASQUERADE; iptables -t nat -A POSTROUTING -o enp5s0 ! -d 10.0.1.100/32 -j MASQUERADE</span> <span class="hljs-attr">PostDown</span> = iptables -D FORWARD -i %i -j ACCEPT<span class="hljs-comment">; iptables -t nat -D POSTROUTING -o dns-shim -d 10.0.1.100/32 -j MASQUERADE; iptables -t nat -D POSTROUTING -o enp5s0 ! -d 10.0.1.100/32 -j MASQUERADE</span> <span class="hljs-section">[Peer]</span> <span class="hljs-attr">PublicKey</span> = &lt;public key&gt; <span class="hljs-attr">PresharedKey</span> = &lt;content of secret1.psk&gt; <span class="hljs-attr">AllowedIPs</span> = <span class="hljs-number">10.0</span>.<span class="hljs-number">10.2</span>/<span class="hljs-number">32</span> <span class="hljs-section">[Peer]</span> <span class="hljs-attr">PublicKey</span> = &lt;public key&gt; <span class="hljs-attr">PresharedKey</span> = &lt;content of secret2.psk&gt; <span class="hljs-attr">AllowedIPs</span> = <span class="hljs-number">10.0</span>.<span class="hljs-number">10.3</span>/<span class="hljs-number">32</span></code></pre> <pre><code class="hljs bash">ufw allow 121212/udp <span class="hljs-comment"># If ufw is running</span> sysctl -w net.ipv4.ip_forward=1 systemctl <span class="hljs-built_in">enable</span> --now wg-quick@wg0 <span class="hljs-comment"># Show active settings</span> wg show</code></pre> <ul> <li><a href="https://wiki.archlinux.org/title/WireGuard">https://wiki.archlinux.org/title/WireGuard</a></li> <li><a href="https://github.com/linuxserver/docker-wireguard">https://github.com/linuxserver/docker-wireguard</a></li> <li><a href="https://philipdeljanov.com/posts/2019/03/21/setting-up-a-wireguard-vpn/">https://philipdeljanov.com/posts/2019/03/21/setting-up-a-wireguard-vpn/</a></li> </ul> <h2 id="backup-restic">Backup (restic)</h2> <pre><code class="hljs bash">pacman -S restic</code></pre> <pre><div class="caption"><span>/etc/restic/systemd/restic.service</span></div><code class="hljs ini"><span class="hljs-section">[Unit]</span> <span class="hljs-attr">Description</span>=Daily Backup Service <span class="hljs-section">[Service]</span> <span class="hljs-attr">Nice</span>=<span class="hljs-number">19</span> <span class="hljs-attr">IOSchedulingClass</span>=idle <span class="hljs-attr">KillSignal</span>=SIGINT <span class="hljs-attr">ExecStart</span>=/etc/restic/cmd/run</code></pre> <pre><div class="caption"><span>/etc/restic/systemd/restic.timer</span></div><code class="hljs ini"><span class="hljs-section">[Unit]</span> <span class="hljs-attr">Description</span>=Daily Backup Timer <span class="hljs-section">[Timer]</span> <span class="hljs-attr">OnCalendar</span>=*-*-* <span class="hljs-number">0</span>,<span class="hljs-number">6</span>,<span class="hljs-number">12</span>,<span class="hljs-number">18</span>:<span class="hljs-number">0</span>:<span class="hljs-number">0</span> <span class="hljs-attr">RandomizedDelaySec</span>=<span class="hljs-number">15</span>min <span class="hljs-attr">Persistent</span>=<span class="hljs-literal">true</span> <span class="hljs-section">[Install]</span> <span class="hljs-attr">WantedBy</span>=timers.target</code></pre> <pre><div class="caption"><span>/etc/restic/cmd/config</span></div><code class="hljs bash"><span class="hljs-built_in">export</span> RESTIC_REPOSITORY=/mnt/backups/restic <span class="hljs-built_in">export</span> RESTIC_PASSWORD_FILE=/etc/restic/key <span class="hljs-comment"># a file contains password</span> <span class="hljs-built_in">export</span> RESTIC_CACHE_DIR=/var/cache/restic <span class="hljs-built_in">export</span> RESTIC_PROGRESS_FPS=1</code></pre> <pre><div class="caption"><span>/etc/restic/cmd/run</span></div><code class="hljs bash"><span class="hljs-meta">#!/bin/bash -ue</span> <span class="hljs-comment"># https://restic.readthedocs.io/en/latest/040_backup.html#</span> DIR=$(<span class="hljs-built_in">dirname</span> <span class="hljs-string">"<span class="hljs-subst">$(readlink -f <span class="hljs-string">"<span class="hljs-variable">$0</span>"</span>)</span>"</span>) <span class="hljs-built_in">source</span> <span class="hljs-string">"<span class="hljs-variable">$DIR</span>/config"</span> <span class="hljs-built_in">date</span> <span class="hljs-comment"># system</span> <span class="hljs-built_in">echo</span> <span class="hljs-string">"&gt; system"</span> restic backup --tag system -v \ --one-file-system \ --exclude .cache \ --exclude .vscode-server \ --exclude TabNine \ --exclude /swapfile \ --exclude <span class="hljs-string">"/lost+found"</span> \ --exclude <span class="hljs-string">"/var/lib/docker/overlay2/*"</span> \ / /boot /home /srv <span class="hljs-comment"># vault</span> <span class="hljs-built_in">echo</span> <span class="hljs-string">"&gt; vault"</span> restic backup --tag vault -v \ --one-file-system \ --exclude <span class="hljs-string">'appdata_*/preview'</span> \ --exclude <span class="hljs-string">'appdata_*/dav-photocache'</span> \ /mnt/vault <span class="hljs-built_in">echo</span> <span class="hljs-string">"! prune"</span> restic forget --prune --group-by tags \ --keep-last 4 \ --keep-within-daily 7d \ --keep-within-weekly 1m \ --keep-within-monthly 3m <span class="hljs-built_in">echo</span> <span class="hljs-string">"! check"</span> restic check</code></pre> <pre><div class="caption"><span>/etc/restic/cmd/show</span></div><code class="hljs bash"><span class="hljs-meta">#!/bin/bash -ue</span> DIR=$(<span class="hljs-built_in">dirname</span> <span class="hljs-string">"<span class="hljs-subst">$(readlink -f <span class="hljs-string">"<span class="hljs-variable">$0</span>"</span>)</span>"</span>) <span class="hljs-built_in">source</span> <span class="hljs-string">"<span class="hljs-variable">$DIR</span>/config"</span> TAG=<span class="hljs-variable">${TAG:-system}</span> ID=$(restic snapshots --tag <span class="hljs-variable">$TAG</span> --json | jq -r <span class="hljs-string">".[] | [.time, .short_id] | @tsv"</span> | fzy | awk <span class="hljs-string">'{print $2}'</span>) TARGET=<span class="hljs-variable">${1:-$(pwd)}</span> MODE=<span class="hljs-string">"ls -l"</span> <span class="hljs-keyword">if</span> [[ -f <span class="hljs-variable">$TARGET</span> ]]; <span class="hljs-keyword">then</span> TARGET=$(<span class="hljs-built_in">realpath</span> <span class="hljs-variable">${TARGET}</span>) MODE=dump <span class="hljs-keyword">fi</span> &gt;&amp;2 <span class="hljs-built_in">echo</span> <span class="hljs-string">"Command: restic <span class="hljs-variable">${MODE}</span> <span class="hljs-variable">${ID}</span> <span class="hljs-variable">${TARGET}</span>"</span> restic <span class="hljs-variable">$MODE</span> <span class="hljs-variable">$ID</span> <span class="hljs-variable">${TARGET}</span></code></pre> <pre><div class="caption"><span>/etc/restic/cmd/restore</span></div><code class="hljs bash"><span class="hljs-meta">#!/bin/bash -ue</span> <span class="hljs-comment"># https://restic.readthedocs.io/en/latest/050_restore.html</span> DIR=$(<span class="hljs-built_in">dirname</span> <span class="hljs-string">"<span class="hljs-subst">$(readlink -f <span class="hljs-string">"<span class="hljs-variable">$0</span>"</span>)</span>"</span>) <span class="hljs-built_in">source</span> <span class="hljs-string">"<span class="hljs-variable">$DIR</span>/config"</span> TARGET=<span class="hljs-variable">${1:?Specify TARGET}</span> TARGET=$(<span class="hljs-built_in">realpath</span> <span class="hljs-variable">${TARGET}</span>) TAG=$(restic snapshots --json | jq -r <span class="hljs-string">'[.[].tags[0]]|unique|.[]'</span> | fzy) ID=$(restic snapshots --tag <span class="hljs-variable">$TAG</span> --json | jq -r <span class="hljs-string">".[] | [.time, .short_id] | @tsv"</span> | fzy | awk <span class="hljs-string">'{print $2}'</span>) &gt;&amp;2 <span class="hljs-built_in">echo</span> <span class="hljs-string">"Command: restic restore <span class="hljs-variable">${ID}</span> -i <span class="hljs-variable">${TARGET}</span> -t /"</span> <span class="hljs-built_in">read</span> -p <span class="hljs-string">"Press enter to continue"</span> restic restore <span class="hljs-variable">$ID</span> -i <span class="hljs-variable">${TARGET}</span> -t /</code></pre> <pre><code class="hljs bash">(<span class="hljs-built_in">umask</span> 0377; <span class="hljs-built_in">echo</span> -n <span class="hljs-string">"&lt;password&gt;"</span> &gt; /etc/restic/key) <span class="hljs-built_in">chmod</span> 700 /etc/restic/cmd/config <span class="hljs-built_in">ln</span> -sf /etc/restic/systemd/restic.{service,timer} /etc/systemd/system/ systemctl <span class="hljs-built_in">enable</span> --now restic.timer systemctl status restic.timer systemctl status restic</code></pre> <ul> <li><a href="https://restic.readthedocs.io/en/stable/">Restic Documentation — restic 0.12.1 documentation</a></li> </ul> <h1 id="miscellaneous-stuff">Miscellaneous stuff</h1> <h2 id="kubernetes">Kubernetes</h2> <pre><code class="hljs bash">pacman -S minikube <span class="hljs-comment"># see https://github.com/kubernetes/minikube/issues/4172#issuecomment-1267069635</span> <span class="hljs-comment"># for the reason having `--kubernetes-version=v1.23.1`</span> minikube start \ --driver=docker \ --cpus=max \ --disable-metrics=<span class="hljs-literal">true</span> \ --subnet=10.100.0.0/16 \ --kubernetes-version=v1.23.1 <span class="hljs-built_in">alias</span> kubectl=<span class="hljs-string">"minikube kubectl --"</span> <span class="hljs-comment"># Allow the control plane to allocate pods to itself</span> kubectl taint nodes --all node-role.kubernetes.io/control-plane:NoSchedule- <span class="hljs-comment"># NGINX Ingress</span> minikube addons <span class="hljs-built_in">enable</span> ingress minikube service list <span class="hljs-comment"># Verify</span> docker network inspect minikube minikube ip <span class="hljs-comment"># =&gt; should be 10.100.0.2</span> kubectl cluster-info kubectl get cm -n kube-system kubeadm-config -o json | jq .data.ClusterConfiguration -r | yq kubectl get nodes kubectl get po -A <span class="hljs-comment"># Hello world</span> kubectl create deployment web --image=gcr.io/google-samples/hello-app:1.0 kubectl expose deployment web --<span class="hljs-built_in">type</span>=NodePort --port=8080 kubectl get service web curl $(minikube service web --url) <span class="hljs-comment"># Hello world through ingress</span> kubectl apply -f https://k8s.io/examples/service/networking/example-ingress.yaml kubectl get ingress curl -H <span class="hljs-string">"Host: hello-world.info"</span> http://$(minikube ip)</code></pre> <ul> <li><a href="https://wiki.archlinux.org/index.php/Kubernetes">Kubernetes - ArchWiki</a></li> <li><a href="https://minikube.sigs.k8s.io/docs/drivers/docker/">docker | minikube</a></li> <li><a href="https://kubernetes.io/docs/tasks/access-application-cluster/ingress-minikube/">Set up Ingress on Minikube with the NGINX Ingress Controller | Kubernetes</a></li> </ul> <h2 id="install-useful-tools">Install useful tools</h2> <pre><code class="hljs bash"><span class="hljs-comment"># Tips: to find packages that provide specific command, say `pygmentize`:</span> pacman -Fy pygmentize <span class="hljs-comment"># =&gt; python-pygments</span> yay -S --needed htop mosh tmux direnv ncdu fx jq yq fd ripgrep exa bat fzy peco fastmod rsync \ antibody-bin hub lazygit git-lfs git-delta difftastic ghq-bin ghq-gst iperf gptfdisk lsof lshw lostfiles \ ffmpeg yt-dlp prettier age gum pyenv neofetch pqrs tea</code></pre> <h2 id="make-ssh-forwarding-work-with-tmux-sudo">Make SSH forwarding work with tmux + sudo</h2> <pre><div class="caption"><span>/home/op/.ssh/rc</span></div><code class="hljs bash"><span class="hljs-keyword">if</span> [ ! -S ~/.ssh/ssh_auth_sock ] &amp;&amp; [ -S <span class="hljs-string">"<span class="hljs-variable">$SSH_AUTH_SOCK</span>"</span> ]; <span class="hljs-keyword">then</span> <span class="hljs-built_in">ln</span> -sf <span class="hljs-variable">$SSH_AUTH_SOCK</span> ~/.ssh/ssh_auth_sock <span class="hljs-keyword">fi</span></code></pre> <pre><div class="caption"><span>/home/op/.tmux.conf</span></div><code class="hljs bash"><span class="hljs-built_in">set</span> -g update-environment -r setenv -g SSH_AUTH_SOCK <span class="hljs-variable">$HOME</span>/.ssh/ssh_auth_sock</code></pre> <pre><code class="hljs bash">(<span class="hljs-built_in">umask</span> 0337; <span class="hljs-built_in">echo</span> <span class="hljs-string">"Defaults env_keep += SSH_AUTH_SOCK"</span> &gt; /etc/sudoers.d/ssh)</code></pre> <p>See also: <a href="https://werat.dev/blog/happy-ssh-agent-forwarding/">Happy ssh agent forwarding for tmux/screen · Reboot and Shine</a></p> <h2 id="temperature-sensors">Temperature sensors</h2> <pre><code class="hljs bash">pacman -S lm_sensors sensors-detect systemctl <span class="hljs-built_in">enable</span> --now lm_sensors <span class="hljs-comment"># Now you can configure htop to show the CPU temps</span> htop</code></pre> <ul> <li><a href="https://wiki.archlinux.org/title/Lm_sensors">lm_sensors - ArchWiki</a></li> </ul> <h2 id="telegram-notifier">Telegram notifier</h2> <pre><div class="caption"><span>/usr/local/bin/telegram-notifier</span></div><code class="hljs bash"><span class="hljs-meta">#!/bin/bash</span> BOT_TOKEN=&lt;your bot token&gt; CHAT_ID=&lt;your chat <span class="hljs-built_in">id</span>&gt; PAYLOAD=$(ruby -r json -e <span class="hljs-string">"print ({text: ARGF.to_a.join, chat_id: <span class="hljs-variable">$CHAT_ID</span>}).to_json"</span> &lt;/dev/stdin) OK=$(curl -s -X <span class="hljs-string">"POST"</span> \ -H <span class="hljs-string">"Content-Type: application/json; charset=utf-8"</span> \ -d <span class="hljs-string">"<span class="hljs-variable">$PAYLOAD</span>"</span> \ https://api.telegram.org/bot<span class="hljs-variable">${BOT_TOKEN}</span>/sendMessage | jq .ok) <span class="hljs-keyword">if</span> [[ <span class="hljs-variable">$OK</span> == <span class="hljs-literal">true</span> ]]; <span class="hljs-keyword">then</span> <span class="hljs-built_in">exit</span> 0 <span class="hljs-keyword">else</span> <span class="hljs-built_in">exit</span> 1 <span class="hljs-keyword">fi</span></code></pre> <h2 id="audio">Audio</h2> <pre><code class="hljs bash">pacman -S alsa-utils <span class="hljs-comment"># may require rebooting system</span> <span class="hljs-comment"># Grant op user audio priv</span> usermod -aG audio op <span class="hljs-comment"># List devices as root</span> aplay -l arecord -L <span class="hljs-built_in">cat</span> /proc/asound/cards <span class="hljs-comment"># Test speaker</span> speaker-test -c2 <span class="hljs-comment"># Test mic</span> arecord -vv -Dhw:2,0 -fS32_LE mic.wav aplay mic.wav <span class="hljs-comment"># GUI mixer</span> alsamixer <span class="hljs-comment"># For Mycroft.ai</span> pacman -S pulseaudio pulsemixer pulseaudio --start pacmd list-cards</code></pre> <pre><div class="caption"><span>/etc/pulse/default.pa</span></div><code class="hljs conf"># 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</code></pre> <pre><div class="caption"><span>/etc/asound.conf</span></div><code class="hljs 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</code></pre> <ul> <li><a href="https://wiki.archlinux.org/title/PulseAudio/Examples#PulseAudio_as_a_minimal_unintrusive_dumb_pipe_to_ALSA">PulseAudio as a minimal unintrusive dumb pipe to ALSA</a></li> <li><a href="https://www.alsa-project.org/main/index.php/SoundcardTesting">SoundcardTesting - AlsaProject</a></li> <li><a href="https://wiki.archlinux.org/index.php/Advanced_Linux_Sound_Architecture/Troubleshooting#Microphone">Advanced Linux Sound Architecture/Troubleshooting - ArchWiki</a></li> <li><a href="https://www.alsa-project.org/alsa-doc/alsa-lib/pcm_plugins.html">ALSA project - the C library reference: PCM (digital audio) plugins</a></li> <li><a href="https://www.alsa-project.org/wiki/Asoundrc">Asoundrc - AlsaProject</a></li> </ul> <h1 id="maintenance">Maintenance</h1> <h2 id="quick-checkups">Quick checkups</h2> <pre><code class="hljs bash">htop <span class="hljs-comment"># show task overview</span> systemctl --failed <span class="hljs-comment"># show failed units</span> free -h <span class="hljs-comment"># show memory usage</span> lsblk -f <span class="hljs-comment"># show disk usage</span> networkctl status <span class="hljs-comment"># show network status</span> userdbctl <span class="hljs-comment"># show users</span> nvidia-smi <span class="hljs-comment"># verify nvidia cards</span> ps aux | grep <span class="hljs-string">"defunct"</span> <span class="hljs-comment"># find zombie processes</span></code></pre> <h2 id="delve-into-system-logs">Delve into system logs</h2> <pre><code class="hljs bash">journalctl -p err -b-1 -r <span class="hljs-comment"># show error logs from previous boot in reverse order</span> journalctl -u sshd -f <span class="hljs-comment"># tail logs from sshd unit</span> journalctl --no-pager -n 25 -k <span class="hljs-comment"># show latest 25 logs from the kernel without pager</span> journalctl --since=<span class="hljs-string">"6 hours ago"</span> --until <span class="hljs-string">"2020-07-10 15:10:00"</span> <span class="hljs-comment"># show logs within specific time range</span> journalctl CONTAINER_NAME=service_web_1 <span class="hljs-comment"># show error from the docker container named 'service_web_1'</span> journalctl _PID=2434 -e <span class="hljs-comment"># filter logs based on PID and jump to the end of the logs</span> journalctl -g <span class="hljs-string">'timed out'</span> <span class="hljs-comment"># filter logs based on a regular expression. if the pattern is all lowercase, it will become case-insensitive mode</span></code></pre> <ul> <li><code>g</code> - go to the first line</li> <li><code>G</code> - go to the last line</li> <li><code>/</code> - search for the string</li> </ul> <h2 id="force-overriding-installation">Force overriding installation</h2> <pre><code class="hljs bash">pacman -S &lt;pkg&gt; --overwrite <span class="hljs-string">'*'</span></code></pre> <h2 id="check-memory-modules">Check memory modules</h2> <pre><code class="hljs bash">pacman -S lshw dmidecode lshw -short -C memory <span class="hljs-comment"># lists installed mems</span> dmidecode <span class="hljs-comment"># shows configured clock speed</span></code></pre> <h2 id="file-system-related-issues-checklist">File-system related issues checklist</h2> <pre><code class="hljs bash">smartctl -a /dev/sdN <span class="hljs-comment"># via USB bridge</span> smartctl -a -d sat /dev/sdN</code></pre> <h3 id="ext4">Ext4</h3> <pre><code class="hljs bash"><span class="hljs-comment"># e2fsck with badblocks (non-destructive read-write test) and preen enabled</span> <span class="hljs-comment"># [!] umount the drive before this ops</span> <span class="hljs-comment"># [!] Never perform this on an unmounted LUKS partition, as it may lead to data loss</span> e2fsck -vcckp /dev/sdNn</code></pre> <ul> <li><code>-v</code>: Be verbose</li> <li><code>-cc</code>: This option causes e2fsck to use badblocks(8) program to do a read-only scan of the device in order to find any bad blocks. If any bad blocks are found, they are added to the bad block inode to prevent them from being allocated to a file or directory. If this option is specified twice, then the bad block scan will be done using a non-destructive read-write test.</li> <li><code>-k</code>: When combined with the -c option, any existing bad blocks in the bad blocks list are preserved, and any new bad blocks found by running badblocks(8) will be added to the existing bad blocks list.</li> <li><code>-p</code>: Automatically repair ("preen") the file system. This option will cause e2fsck to automatically fix any file system problems that can be safely fixed without human intervention. If e2fsck discovers a problem which may require the system administrator to take additional corrective action, e2fsck will print a description of the problem and then exit with the value 4 logically or'ed into the exit code. This option is normally used by the system's boot scripts. It may not be specified at the same time as the -n or -y options.</li> </ul> <h3 id="fix-broken-file-system-headers">Fix broken file system headers</h3> <pre><code class="hljs bash">testdisk /dev/sdN</code></pre> <h1 id="troubleshooting">Troubleshooting</h1> <h2 id="longer-ssh-login-d-bus-glitch">Longer SSH login (D-bus glitch)</h2> <pre><code class="hljs bash">systemctl restart systemd-logind systemctl restart polkit</code></pre> <ul> <li><a href="https://jrs-s.net/2017/07/01/slow-ssh-logins/">A comprehensive guide to fixing slow SSH logins – JRS Systems: the blog</a></li> </ul> <h2 id="annoying-systemd-homed-is-not-available-messages-flooding-journald-logs">Annoying <code>systemd-homed is not available</code> messages flooding journald logs</h2> <p>Move <code>pam_unix</code> before <code>pam_systemd_home</code>.</p> <pre><div class="caption"><span>/etc/pam.d/system-auth</span></div><code class="hljs ini"><span class="hljs-comment">#%PAM-1.0</span> auth required pam_faillock.so preauth <span class="hljs-comment"># Optionally use requisite above if you do not want to prompt for the password</span> <span class="hljs-comment"># on locked accounts.</span> auth <span class="hljs-section">[success=2 default=ignore]</span> pam_unix.so try_first_pass nullok -auth <span class="hljs-section">[success=1 default=ignore]</span> pam_systemd_home.so auth <span class="hljs-section">[default=die]</span> pam_faillock.so authfail auth optional pam_permit.so auth required pam_env.so auth required pam_faillock.so authsucc <span class="hljs-comment"># If you drop the above call to pam_faillock.so the lock will be done also</span> <span class="hljs-comment"># on non-consecutive authentication failures.</span> account <span class="hljs-section">[success=1 default=ignore]</span> pam_unix.so -account required pam_systemd_home.so account optional pam_permit.so account required pam_time.so password <span class="hljs-section">[success=1 default=ignore]</span> 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</code></pre> <ul> <li><a href="https://bbs.archlinux.org/viewtopic.php?id=258297">[solved] pam fails to find unit dbus-org.freedesktop.home1.service / Newbie Corner / Arch Linux Forums</a></li> </ul> <h2 id="annoying-systemd-journald-audit-logs">Annoying <code>systemd-journald-audit</code> logs</h2> <pre><div class="caption"><span>/etc/systemd/journald.conf</span></div><code class="hljs ini"><span class="hljs-attr">Audit</span>=<span class="hljs-literal">no</span></code></pre> <h2 id="missing-devnvidia-uvmmodeset">Missing <code>/dev/nvidia-{uvm*,modeset}</code></h2> <p>This usually happens right after updating the Linux kernel.</p> <ul> <li>Run <code>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</code> once.</li> </ul> <h2 id="sudo-incorrect-password-while-password-is-correct"><code>[sudo] Incorrect password</code> while password is correct</h2> <pre><code class="hljs bash">faillock --reset</code></pre> <h1 id="useful-links">Useful links</h1> <ul> <li><a href="https://wiki.archlinux.org/index.php/General_recommendations#Users_and_groups">General recommendations - ArchWiki</a></li> <li><a href="https://wiki.archlinux.org/title/General_troubleshooting">General troubleshooting - ArchWiki</a></li> <li><a href="https://wiki.archlinux.org/title/Security">Security - ArchWiki</a></li> <li><a href="https://wiki.archlinux.org/index.php/Improving_performance#Know_your_system">Improving performance - ArchWiki</a></li> <li><a href="https://wiki.archlinux.org/index.php/System_maintenance">System maintenance - ArchWiki</a></li> <li><a href="https://wiki.archlinux.org/title/Stress_testing#Stressing_memory">Stress testing - ArchWiki</a></li> <li><a href="https://wiki.archlinux.org/title/Archboot">Archboot - ArchWiki</a></li> <li><a href="https://wiki.archlinux.org/title/Udev#Debug_output">udev - ArchWiki</a></li> <li><a href="https://bbs.archlinux.org/viewtopic.php?id=18066">Repair Broken system, system without a kernel / Forum &amp; Wiki discussion / Arch Linux Forums</a></li> </ul> 2021-02-11T15:00:00.000Z https://uechi.io/blog/oauth-jwt-rfcs/ OAuth 2.0 と JWT 関連 RFC <p>個人的な調査のために OAuth 2.0 と JWT 関連 RFC を発行日順に並べた。</p> <h2 id="rfc6749-the-oauth-2.0-authorization-framework"><a href="https://tools.ietf.org/html/rfc6749">RFC6749</a> — The OAuth 2.0 Authorization Framework</h2> <p>2012 年 10 月</p> <p>OAuth 1.0a に代わる新たな認証基盤 OAuth 2.0 のコアを規定しており、特筆すべき点がいくつかある。</p> <ul> <li><code>access_token</code> の内容は規定されておらず、ベンダーに委ねられている <ul> <li>JWS でもなんでもいい</li> </ul></li> <li>リソースサーバーに <code>access_token</code> を渡す方法は規定されていない(同月発行の RFC6750 で規定された)</li> </ul> <h3 id="authorization-grant">Authorization Grant</h3> <p>トークンエンドポイントで<code>access_token</code>を発行してもらう際に使用できる Grant (許可証)は、提案中の拡張仕様を含めて 5 つある。</p> <ol type="1"> <li>Authorization Code Grant: <a href="https://tools.ietf.org/html/rfc6749#section-1.3.1">RFC6749 – Section 1.3.1</a> <ol type="1"> <li><code>grant_type=authorization_code</code></li> <li>Authorization Code Grant with PKCE</li> </ol></li> <li>Implicit Flow: <a href="https://tools.ietf.org/html/rfc6749#section-1.3.2">RFC6749 – Section 1.3.2</a> <ol type="1"> <li>もともと CORS (Cross Origin Resource Sharing) が登場する以前の SPA で、POST リクエストを回避しつつ Access Token を得る"妥協案"として策定された</li> <li>CSRF 耐性が無い (<a href="https://tools.ietf.org/html/rfc6819#section-4.4.2.5">RFC6819 - Section 4.4.2.5</a>)ため、使うべきではない</li> </ol></li> <li>Resource Owner Password Credentials Grant: <a href="https://tools.ietf.org/html/rfc6749#section-1.3.3">RFC6749 – Section 1.3.3</a> <ol type="1"> <li>直接パスワードで認証する形式</li> </ol></li> <li>Client Credentials Grant: <a href="https://tools.ietf.org/html/rfc6749#section-1.3.4">RFC6749 – Section 1.3.4</a> <ol type="1"> <li>クライアントシークレットでトークンを取得する形式。</li> </ol></li> <li>Device Grant: <a href="https://tools.ietf.org/html/draft-ietf-oauth-device-flow-15">RFC Draft — OAuth 2.0 Device Authorization Grant</a> <ol type="1"> <li>入力機器が無い場合もある組み込みデバイス向けの認証フロー</li> </ol></li> </ol> <h2 id="rfc6750-the-oauth-2.0-authorization-framework-bearer-token-usage"><a href="https://tools.ietf.org/html/rfc6750">RFC6750</a> — The OAuth 2.0 Authorization Framework: Bearer Token Usage</h2> <p>2012 年 10 月</p> <p>OAuth 2.0 において、<code>access_token</code>をリソースサーバーに渡す手法を規定する。OAuth 2.0 JWT Bearer Token Flow<strong>ではない</strong>。</p> <p>手法として 3 つが挙げられている。</p> <ol type="1"> <li>Bearer Token (<strong>SHOULD</strong>)</li> <li>Form Encoded Parameters (SHOULD NOT)</li> <li>URI Query Parameters (SHOULD NOT)</li> </ol> <h2 id="oidc-openid-connect-core-1.0"><a href="https://openid.net/specs/openid-connect-core-1_0.html">OIDC</a> — OpenID Connect Core 1.0</h2> <p>2014 年 11 月</p> <p>OAuth 2.0 の上にいくつか仕様を足したサブセットで、OAuth (Authorization)に Authentication の機能を付与した画期的なプロトコル。</p> <h2 id="rfc7515-json-web-signature-jws"><a href="https://tools.ietf.org/html/rfc7515">RFC7515</a> — JSON Web Signature (JWS)</h2> <p>2015 年 5 月</p> <p>JSON ベースの署名プロトコル。</p> <h2 id="rfc7516-json-web-encryption-jwe"><a href="https://tools.ietf.org/html/rfc7516">RFC7516</a> — JSON Web Encryption (JWE)</h2> <p>2015 年 5 月</p> <p>JSON ベースの暗号化プロトコル。</p> <h2 id="rfc7517-json-web-key-jwk"><a href="https://tools.ietf.org/html/rfc7517">RFC7517</a> — JSON Web Key (JWK)</h2> <p>2015 年 5 月</p> <p>JWT の署名チェックに用いる公開鍵を配信するためのプロトコル。</p> <h2 id="rfc7518-json-web-algorithms-jwa"><a href="https://tools.ietf.org/html/rfc7518">RFC7518</a> — JSON Web Algorithms (JWA)</h2> <p>2015 年 5 月</p> <p>JWS、JWE、JWK で利用されるアルゴリズム (alg)やその他プロパティを規定する。</p> <h2 id="rfc7519-json-web-token-jwt"><a href="https://tools.ietf.org/html/rfc7519">RFC7519</a> — JSON Web Token (JWT)</h2> <p>2015 年 5 月</p> <p>JWT は JSON を利用して Assertion を生成するための仕様。</p> <h2 id="rfc7521-assertion-framework-for-oauth-2.0-client-authentication-and-authorization-grants"><a href="https://tools.ietf.org/html/rfc7521">RFC7521</a> — Assertion Framework for OAuth 2.0 Client Authentication and Authorization Grants</h2> <p>2015 年 5 月</p> <p>任意の Assertion を OAuth 2.0 Client Authentication の Client Credentials として使ったり、あるいは Authorization Grant として Access Token と交換するための仕様。</p> <p>トークンエンドポイントに強化されたクライアント認証を付与する。続く RFC で、それぞれ SAML と JWT を使用したパターンを規定している。</p> <p><strong>OAuth 2.0 JWT Bearer Token Flow</strong>とも呼ばれている。</p> <ul> <li><a href="https://tools.ietf.org/html/rfc7522">RFC7522</a> — Security Assertion Markup Language (<strong>SAML</strong>) 2.0 Profile for OAuth 2.0 Client Authentication and Authorization Grants (2015 年 5 月)</li> <li><a href="https://tools.ietf.org/html/rfc7523">RFC7523</a> — JSON Web Token (<strong>JWT</strong>) Profile for OAuth 2.0 Client Authentication and Authorization Grants (2015 年 5 月)</li> </ul> <p>2015 年 5 月 https://tools.ietf.org/html/rfc7523</p> <h2 id="rfc-draft-json-web-token-jwt-profile-for-oauth-2.0-access-tokens"><a href="https://tools.ietf.org/html/draft-ietf-oauth-access-token-jwt-02">RFC Draft</a> — JSON Web Token (JWT) Profile for OAuth 2.0 Access Tokens</h2> <p>2019 年 7 月</p> <p>リソースサーバーへ渡す Access Token に JWT を使用することを定めている。</p> 2021-02-10T15:00:00.000Z https://uechi.io/blog/secure-dev-server/ Securing Local Dev Server <p>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.</p> <p>You can easily create a self-signed TLS cert for development purposes with <a href="https://github.com/FiloSottile/mkcert"><code>mkcert</code></a>.</p> <pre><code class="hljs bash">brew install mkcert mkcert -install <span class="hljs-comment"># Install the local CA in the OS keychain</span></code></pre> <p>After installing <code>mkcert</code> and generating system-wide local CA cert, you can create a certificate for each project.</p> <pre><code class="hljs bash"><span class="hljs-built_in">cd</span> awesome-website mkcert localhost <span class="hljs-comment"># this will generate ./localhost.pem and ./localhost-key.pem</span> npm install -g serve serve --ssl-cert ./localhost.pem --ssl-key ./localhost-key.pem</code></pre> 2020-02-06T06:00:00.000Z https://uechi.io/blog/bose-noise-cancelling-headphones-700%E3%83%AC%E3%83%93%E3%83%A5%E3%83%BC/ Bose Noise Cancelling Headphones 700レビュー <p>Bose Noise Cancelling Headphones 700 を使い始めて一ヶ月が経ったので、現時点での印象をまとめる。</p> <h2 id="pros">Pros</h2> <ul> <li>ノイズキャンセリング性能の高さ</li> <li>8 台までのマルチペアリング</li> <li>2 台までのマルチポイント</li> <li>タッチコントロール</li> <li>3 段階ノイズキャンセリングレベルコントロール <ul> <li>10 段階の内 3 つをあらかじめ選んでおき、ボタンを押してローテーションできる</li> <li>QC30 は 1 段階ずつしか変更出来ずボタンを連打させられる仕様だったので、大きな改善</li> </ul></li> <li>バッテリーの持ちの良さ <ul> <li>15 時間くらいは動く</li> </ul></li> <li>有線対応 <ul> <li>有線時も ANC が働く</li> </ul></li> <li>USB-C 充電対応</li> </ul> <h2 id="cons">Cons</h2> <ul> <li>マルチポイント時の混線ノイズ <ul> <li>音楽再生中にもう一方のデバイスで何か通知音が鳴るとストリームに対して「プツプツ」ノイズが入る</li> </ul></li> <li>システムサウンドが大きすぎる(変更不可) <ul> <li>公式英語フォーラムで多くのユーザーが苦情を書き込んでいるが、完全に無視されている</li> </ul></li> <li>消耗部品の多さ <ul> <li>ヒンジ部分はケースに仕舞う度に動かなさいといけないため消耗が心配</li> <li>一般論として、可動部が多いほど故障率が上がる</li> </ul></li> <li>本体側での接続先選択が不可能 <ul> <li>QC30 では出来ていた本体側のボタンで接続先を選択できる機能が無くなっていた</li> </ul></li> <li>ボタン配置のミス <ul> <li>ボタンが手に触れやすい位置にあるため、ヘッドホンを外す度に間違って押してしまう</li> </ul></li> <li>ストリーム元とボタンの送信先が異なるバグ <ul> <li>マルチポイント接続で一方のデバイスで音楽を流している際に、再生ボタンの信号が音楽を流していない方のデバイスに送信されてしまうバグがある</li> </ul></li> </ul> 2019-10-25T01:49:01.000Z https://uechi.io/blog/welch-t-test/ プログラムの速度改善が誤差かどうかを統計的に調べる <p><strong>Welch の t 検定</strong>を用いて 2 つのベンチマークの分布の平均が等しい(速度差は誤差の範疇)か、あるいは異なる(=有意な速度改善が成されている)かどうかを判定したい。</p> <p>ベンチマーク用に TypeScript プログラムを用意した。</p> <pre><div class="caption"><span>a.ts</span></div><code class="hljs ts"><span class="hljs-keyword">function</span> <span class="hljs-title function_">a</span>(<span class="hljs-params"></span>) { <span class="hljs-keyword">const</span> noise = <span class="hljs-title class_">Math</span>.<span class="hljs-title function_">random</span>() - <span class="hljs-number">0.5</span>; <span class="hljs-keyword">const</span> offset = <span class="hljs-number">1.0</span>; <span class="hljs-keyword">const</span> t = noise * <span class="hljs-number">2</span> + offset; <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(t), t * <span class="hljs-number">1000</span>); } <span class="hljs-title function_">a</span>();</code></pre> <pre><div class="caption"><span>b.ts</span></div><code class="hljs ts"><span class="hljs-keyword">function</span> <span class="hljs-title function_">b</span>(<span class="hljs-params"></span>) { <span class="hljs-keyword">const</span> noise = <span class="hljs-title class_">Math</span>.<span class="hljs-title function_">random</span>() - <span class="hljs-number">0.5</span>; <span class="hljs-keyword">const</span> offset = <span class="hljs-number">2.0</span>; <span class="hljs-keyword">const</span> t = noise * <span class="hljs-number">2</span> + offset; <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(t), t * <span class="hljs-number">1000</span>); } <span class="hljs-title function_">b</span>();</code></pre> <p>まず<a href="https://github.com/sharkdp/hyperfine">hyperfine</a>で 2 つの プログラムのベンチマークを取り、<code>result.json</code>に保存する。</p> <pre><code class="hljs shell">hyperfine 'ts-node a.ts' 'ts-node b.ts' -r 50 --warmup 3 --export-json ab.json</code></pre> <p><code>result.json</code>の中身は以下のようになる。</p> <pre><div class="caption"><span>result.json</span></div><code class="hljs json"><span class="hljs-punctuation">{</span> <span class="hljs-attr">"results"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span> <span class="hljs-punctuation">{</span> <span class="hljs-attr">"command"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"ts-node a.ts"</span><span class="hljs-punctuation">,</span> <span class="hljs-attr">"mean"</span><span class="hljs-punctuation">:</span> <span class="hljs-number">1.9369869248950002</span><span class="hljs-punctuation">,</span> <span class="hljs-attr">"stddev"</span><span class="hljs-punctuation">:</span> <span class="hljs-number">0.6074252496423262</span><span class="hljs-punctuation">,</span> <span class="hljs-attr">"median"</span><span class="hljs-punctuation">:</span> <span class="hljs-number">2.005230080295</span><span class="hljs-punctuation">,</span> <span class="hljs-attr">"user"</span><span class="hljs-punctuation">:</span> <span class="hljs-number">1.549546345</span><span class="hljs-punctuation">,</span> <span class="hljs-attr">"system"</span><span class="hljs-punctuation">:</span> <span class="hljs-number">0.08031985000000001</span><span class="hljs-punctuation">,</span> <span class="hljs-attr">"min"</span><span class="hljs-punctuation">:</span> <span class="hljs-number">0.8807363742950001</span><span class="hljs-punctuation">,</span> <span class="hljs-attr">"max"</span><span class="hljs-punctuation">:</span> <span class="hljs-number">2.830435366295</span><span class="hljs-punctuation">,</span> <span class="hljs-attr">"times"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span> <span class="hljs-number">1.4010462692949999</span><span class="hljs-punctuation">,</span> <span class="hljs-number">2.830435366295</span><span class="hljs-punctuation">,</span> <span class="hljs-number">1.010024359295</span><span class="hljs-punctuation">,</span> <span class="hljs-number">1.159667609295</span><span class="hljs-punctuation">,</span> <span class="hljs-number">1.8311979602950001</span><span class="hljs-punctuation">,</span> ... <span class="hljs-punctuation">]</span> <span class="hljs-punctuation">}</span><span class="hljs-punctuation">,</span> <span class="hljs-punctuation">{</span> <span class="hljs-attr">"command"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"ts-node b.ts"</span><span class="hljs-punctuation">,</span> <span class="hljs-attr">"mean"</span><span class="hljs-punctuation">:</span> <span class="hljs-number">2.833931665055</span><span class="hljs-punctuation">,</span> <span class="hljs-attr">"stddev"</span><span class="hljs-punctuation">:</span> <span class="hljs-number">0.6505564501747996</span><span class="hljs-punctuation">,</span> <span class="hljs-attr">"median"</span><span class="hljs-punctuation">:</span> <span class="hljs-number">2.7373719187950005</span><span class="hljs-punctuation">,</span> <span class="hljs-attr">"user"</span><span class="hljs-punctuation">:</span> <span class="hljs-number">1.5474132649999999</span><span class="hljs-punctuation">,</span> <span class="hljs-attr">"system"</span><span class="hljs-punctuation">:</span> <span class="hljs-number">0.07978893000000001</span><span class="hljs-punctuation">,</span> <span class="hljs-attr">"min"</span><span class="hljs-punctuation">:</span> <span class="hljs-number">1.938184970295</span><span class="hljs-punctuation">,</span> <span class="hljs-attr">"max"</span><span class="hljs-punctuation">:</span> <span class="hljs-number">3.946562622295</span><span class="hljs-punctuation">,</span> <span class="hljs-attr">"times"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span> <span class="hljs-number">2.2806011012950003</span><span class="hljs-punctuation">,</span> <span class="hljs-number">2.0140897212950004</span><span class="hljs-punctuation">,</span> <span class="hljs-number">2.1835023382950003</span><span class="hljs-punctuation">,</span> <span class="hljs-number">2.304886362295</span><span class="hljs-punctuation">,</span> <span class="hljs-number">3.8122057912950003</span><span class="hljs-punctuation">,</span> ... <span class="hljs-punctuation">]</span> <span class="hljs-punctuation">}</span> <span class="hljs-punctuation">]</span> <span class="hljs-punctuation">}</span></code></pre> <blockquote> <p>t 検定はサンプルが正規分布に従っているという仮定を置いているため、大数の法則から本当はもっと試行回数を増やした方が良い。</p> </blockquote> <p>この<code>result.json</code>の<code>times</code>配列を受け取り、2 つの分布間に有意差があるかどうかを判定する。</p> <pre><code class="hljs ts"><span class="hljs-keyword">import</span> fs <span class="hljs-keyword">from</span> <span class="hljs-string">"fs"</span>; <span class="hljs-keyword">import</span> { jStat } <span class="hljs-keyword">from</span> <span class="hljs-string">"jstat"</span>; <span class="hljs-keyword">const</span> log = <span class="hljs-variable language_">console</span>.<span class="hljs-property">log</span>; <span class="hljs-keyword">const</span> <span class="hljs-title function_">sum</span> = (<span class="hljs-params">x: <span class="hljs-built_in">number</span>[]</span>) =&gt; x.<span class="hljs-title function_">reduce</span>(<span class="hljs-function">(<span class="hljs-params">a: <span class="hljs-built_in">number</span>, b: <span class="hljs-built_in">number</span></span>) =&gt;</span> a + b); <span class="hljs-comment">// 総和</span> <span class="hljs-keyword">const</span> <span class="hljs-title function_">sqsum</span> = (<span class="hljs-params">x: <span class="hljs-built_in">number</span>[], mu: <span class="hljs-built_in">number</span></span>) =&gt; x.<span class="hljs-title function_">reduce</span>(<span class="hljs-function">(<span class="hljs-params">a: <span class="hljs-built_in">number</span>, b: <span class="hljs-built_in">number</span></span>) =&gt;</span> a + (b - mu) ** <span class="hljs-number">2</span>); <span class="hljs-comment">// 自乗誤差の総和</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">ttest</span>(<span class="hljs-params">X: <span class="hljs-built_in">number</span>[], Y: <span class="hljs-built_in">number</span>[]</span>) { <span class="hljs-keyword">const</span> <span class="hljs-title class_">Xn</span> = X.<span class="hljs-property">length</span>; <span class="hljs-comment">// サンプル数</span> <span class="hljs-keyword">const</span> <span class="hljs-title class_">Yn</span> = Y.<span class="hljs-property">length</span>; <span class="hljs-title function_">log</span>(<span class="hljs-string">`Xn = <span class="hljs-subst">${Xn}</span>`</span>); <span class="hljs-title function_">log</span>(<span class="hljs-string">`Yn = <span class="hljs-subst">${Yn}</span>`</span>); <span class="hljs-keyword">const</span> X_mu = <span class="hljs-title function_">sum</span>(X) / <span class="hljs-title class_">Xn</span>; <span class="hljs-comment">// 平均</span> <span class="hljs-keyword">const</span> Y_mu = <span class="hljs-title function_">sum</span>(Y) / <span class="hljs-title class_">Yn</span>; <span class="hljs-title function_">log</span>(<span class="hljs-string">`X_mu = <span class="hljs-subst">${X_mu}</span>`</span>); <span class="hljs-title function_">log</span>(<span class="hljs-string">`Y_mu = <span class="hljs-subst">${Y_mu}</span>`</span>); <span class="hljs-keyword">const</span> X_sigma = <span class="hljs-title function_">sqsum</span>(X, X_mu) / (<span class="hljs-title class_">Xn</span> - <span class="hljs-number">1</span>); <span class="hljs-comment">// 不偏分散</span> <span class="hljs-keyword">const</span> Y_sigma = <span class="hljs-title function_">sqsum</span>(Y, Y_mu) / (<span class="hljs-title class_">Yn</span> - <span class="hljs-number">1</span>); <span class="hljs-title function_">log</span>(<span class="hljs-string">`X_sigma = <span class="hljs-subst">${X_sigma}</span>`</span>); <span class="hljs-title function_">log</span>(<span class="hljs-string">`Y_sigma = <span class="hljs-subst">${Y_sigma}</span>`</span>); <span class="hljs-keyword">const</span> t = (X_mu - Y_mu) / <span class="hljs-title class_">Math</span>.<span class="hljs-title function_">sqrt</span>(X_sigma / <span class="hljs-title class_">Xn</span> + Y_sigma / <span class="hljs-title class_">Yn</span>); <span class="hljs-comment">// t値</span> <span class="hljs-title function_">log</span>(<span class="hljs-string">`t = <span class="hljs-subst">${t}</span>`</span>); <span class="hljs-keyword">const</span> df = (X_sigma + Y_sigma) ** <span class="hljs-number">2</span> / (X_sigma ** <span class="hljs-number">2</span> / (<span class="hljs-title class_">Xn</span> - <span class="hljs-number">1</span>) + Y_sigma ** <span class="hljs-number">2</span> / (<span class="hljs-title class_">Yn</span> - <span class="hljs-number">1</span>)); <span class="hljs-comment">// 自由度</span> <span class="hljs-title function_">log</span>(<span class="hljs-string">`df = <span class="hljs-subst">${df}</span>`</span>); <span class="hljs-keyword">return</span> jStat.<span class="hljs-property">studentt</span>.<span class="hljs-title function_">cdf</span>(-<span class="hljs-title class_">Math</span>.<span class="hljs-title function_">abs</span>(t), df) * <span class="hljs-number">2.0</span>; <span class="hljs-comment">// p値</span> } <span class="hljs-keyword">const</span> filename = process.<span class="hljs-property">argv</span>.<span class="hljs-title function_">slice</span>(<span class="hljs-number">2</span>)[<span class="hljs-number">0</span>]; <span class="hljs-keyword">const</span> result = <span class="hljs-title class_">JSON</span>.<span class="hljs-title function_">parse</span>(fs.<span class="hljs-title function_">readFileSync</span>(filename).<span class="hljs-title function_">toString</span>()); <span class="hljs-keyword">const</span> X = result.<span class="hljs-property">results</span>[<span class="hljs-number">0</span>].<span class="hljs-property">times</span>; <span class="hljs-keyword">const</span> Y = result.<span class="hljs-property">results</span>[<span class="hljs-number">1</span>].<span class="hljs-property">times</span>; <span class="hljs-keyword">const</span> p = <span class="hljs-title function_">ttest</span>(X, Y); <span class="hljs-title function_">log</span>(<span class="hljs-string">`p = <span class="hljs-subst">${p}</span>`</span>); <span class="hljs-title function_">log</span>(<span class="hljs-string">`p &lt; 0.05 = <span class="hljs-subst">${p &lt; <span class="hljs-number">0.05</span>}</span>`</span>); <span class="hljs-title function_">log</span>(p &lt; <span class="hljs-number">0.05</span> ? <span class="hljs-string">"Possibly some difference there"</span> : <span class="hljs-string">"No difference"</span>);</code></pre> <p>ここで<code>X_mu</code>は分布 X の平均、<code>X_sigma</code>は分布 X の不偏分散だ。</p> <p><span class="math display"><mjx-container class="MathJax" jax="SVG" display="true"><svg style="vertical-align: -6.045ex;" xmlns="http://www.w3.org/2000/svg" width="28.419ex" height="13.221ex" role="img" focusable="false" viewBox="0 -3171.8 12561.2 5843.6"><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="mtable"><g data-mml-node="mtr" transform="translate(0,1592.2)"><g data-mml-node="mtd"><g data-mml-node="msub"><g data-mml-node="mi"><path data-c="1D707" d="M58 -216Q44 -216 34 -208T23 -186Q23 -176 96 116T173 414Q186 442 219 442Q231 441 239 435T249 423T251 413Q251 401 220 279T187 142Q185 131 185 107V99Q185 26 252 26Q261 26 270 27T287 31T302 38T315 45T327 55T338 65T348 77T356 88T365 100L372 110L408 253Q444 395 448 404Q461 431 491 431Q504 431 512 424T523 412T525 402L449 84Q448 79 448 68Q448 43 455 35T476 26Q485 27 496 35Q517 55 537 131Q543 151 547 152Q549 153 557 153H561Q580 153 580 144Q580 138 575 117T555 63T523 13Q510 0 491 -8Q483 -10 467 -10Q446 -10 429 -4T402 11T385 29T376 44T374 51L368 45Q362 39 350 30T324 12T288 -4T246 -11Q199 -11 153 12L129 -85Q108 -167 104 -180T92 -202Q76 -216 58 -216Z"></path></g><g data-mml-node="mi" transform="translate(636,-150) scale(0.707)"><path data-c="1D44B" d="M42 0H40Q26 0 26 11Q26 15 29 27Q33 41 36 43T55 46Q141 49 190 98Q200 108 306 224T411 342Q302 620 297 625Q288 636 234 637H206Q200 643 200 645T202 664Q206 677 212 683H226Q260 681 347 681Q380 681 408 681T453 682T473 682Q490 682 490 671Q490 670 488 658Q484 643 481 640T465 637Q434 634 411 620L488 426L541 485Q646 598 646 610Q646 628 622 635Q617 635 609 637Q594 637 594 648Q594 650 596 664Q600 677 606 683H618Q619 683 643 683T697 681T738 680Q828 680 837 683H845Q852 676 852 672Q850 647 840 637H824Q790 636 763 628T722 611T698 593L687 584Q687 585 592 480L505 384Q505 383 536 304T601 142T638 56Q648 47 699 46Q734 46 734 37Q734 35 732 23Q728 7 725 4T711 1Q708 1 678 1T589 2Q528 2 496 2T461 1Q444 1 444 10Q444 11 446 25Q448 35 450 39T455 44T464 46T480 47T506 54Q523 62 523 64Q522 64 476 181L429 299Q241 95 236 84Q232 76 232 72Q232 53 261 47Q262 47 267 47T273 46Q276 46 277 46T280 45T283 42T284 35Q284 26 282 19Q279 6 276 4T261 1Q258 1 243 1T201 2T142 2Q64 2 42 0Z"></path></g></g></g><g data-mml-node="mtd" transform="translate(1288.5,0)"><g data-mml-node="mi"></g><g data-mml-node="mo" transform="translate(277.8,0)"><path data-c="3D" d="M56 347Q56 360 70 367H707Q722 359 722 347Q722 336 708 328L390 327H72Q56 332 56 347ZM56 153Q56 168 72 173H708Q722 163 722 153Q722 140 707 133H70Q56 140 56 153Z"></path></g></g><g data-mml-node="mtd" transform="translate(2622.2,0)"><g data-mml-node="mfrac"><g data-mml-node="mn" transform="translate(612.7,676)"><path data-c="31" d="M213 578L200 573Q186 568 160 563T102 556H83V602H102Q149 604 189 617T245 641T273 663Q275 666 285 666Q294 666 302 660V361L303 61Q310 54 315 52T339 48T401 46H427V0H416Q395 3 257 3Q121 3 100 0H88V46H114Q136 46 152 46T177 47T193 50T201 52T207 57T213 61V578Z"></path></g><g data-mml-node="msub" transform="translate(220,-686)"><g data-mml-node="mi"><path data-c="1D45B" d="M21 287Q22 293 24 303T36 341T56 388T89 425T135 442Q171 442 195 424T225 390T231 369Q231 367 232 367L243 378Q304 442 382 442Q436 442 469 415T503 336T465 179T427 52Q427 26 444 26Q450 26 453 27Q482 32 505 65T540 145Q542 153 560 153Q580 153 580 145Q580 144 576 130Q568 101 554 73T508 17T439 -10Q392 -10 371 17T350 73Q350 92 386 193T423 345Q423 404 379 404H374Q288 404 229 303L222 291L189 157Q156 26 151 16Q138 -11 108 -11Q95 -11 87 -5T76 7T74 17Q74 30 112 180T152 343Q153 348 153 366Q153 405 129 405Q91 405 66 305Q60 285 60 284Q58 278 41 278H27Q21 284 21 287Z"></path></g><g data-mml-node="mi" transform="translate(633,-150) scale(0.707)"><path data-c="1D44B" d="M42 0H40Q26 0 26 11Q26 15 29 27Q33 41 36 43T55 46Q141 49 190 98Q200 108 306 224T411 342Q302 620 297 625Q288 636 234 637H206Q200 643 200 645T202 664Q206 677 212 683H226Q260 681 347 681Q380 681 408 681T453 682T473 682Q490 682 490 671Q490 670 488 658Q484 643 481 640T465 637Q434 634 411 620L488 426L541 485Q646 598 646 610Q646 628 622 635Q617 635 609 637Q594 637 594 648Q594 650 596 664Q600 677 606 683H618Q619 683 643 683T697 681T738 680Q828 680 837 683H845Q852 676 852 672Q850 647 840 637H824Q790 636 763 628T722 611T698 593L687 584Q687 585 592 480L505 384Q505 383 536 304T601 142T638 56Q648 47 699 46Q734 46 734 37Q734 35 732 23Q728 7 725 4T711 1Q708 1 678 1T589 2Q528 2 496 2T461 1Q444 1 444 10Q444 11 446 25Q448 35 450 39T455 44T464 46T480 47T506 54Q523 62 523 64Q522 64 476 181L429 299Q241 95 236 84Q232 76 232 72Q232 53 261 47Q262 47 267 47T273 46Q276 46 277 46T280 45T283 42T284 35Q284 26 282 19Q279 6 276 4T261 1Q258 1 243 1T201 2T142 2Q64 2 42 0Z"></path></g></g><rect width="1485.5" height="60" x="120" y="220"></rect></g><g data-mml-node="munderover" transform="translate(1892.1,0)"><g data-mml-node="mo"><path data-c="2211" d="M60 948Q63 950 665 950H1267L1325 815Q1384 677 1388 669H1348L1341 683Q1320 724 1285 761Q1235 809 1174 838T1033 881T882 898T699 902H574H543H251L259 891Q722 258 724 252Q725 250 724 246Q721 243 460 -56L196 -356Q196 -357 407 -357Q459 -357 548 -357T676 -358Q812 -358 896 -353T1063 -332T1204 -283T1307 -196Q1328 -170 1348 -124H1388Q1388 -125 1381 -145T1356 -210T1325 -294L1267 -449L666 -450Q64 -450 61 -448Q55 -446 55 -439Q55 -437 57 -433L590 177Q590 178 557 222T452 366T322 544L56 909L55 924Q55 945 60 948Z"></path></g><g data-mml-node="mi" transform="translate(600,-1084.4) scale(0.707)"><path data-c="1D456" d="M184 600Q184 624 203 642T247 661Q265 661 277 649T290 619Q290 596 270 577T226 557Q211 557 198 567T184 600ZM21 287Q21 295 30 318T54 369T98 420T158 442Q197 442 223 419T250 357Q250 340 236 301T196 196T154 83Q149 61 149 51Q149 26 166 26Q175 26 185 29T208 43T235 78T260 137Q263 149 265 151T282 153Q302 153 302 143Q302 135 293 112T268 61T223 11T161 -11Q129 -11 102 10T74 74Q74 91 79 106T122 220Q160 321 166 341T173 380Q173 404 156 404H154Q124 404 99 371T61 287Q60 286 59 284T58 281T56 279T53 278T49 278T41 278H27Q21 284 21 287Z"></path></g><g data-mml-node="TeXAtom" transform="translate(267.5,1167.1) scale(0.707)" data-mjx-texclass="ORD"><g data-mml-node="msub"><g data-mml-node="mi"><path data-c="1D45B" d="M21 287Q22 293 24 303T36 341T56 388T89 425T135 442Q171 442 195 424T225 390T231 369Q231 367 232 367L243 378Q304 442 382 442Q436 442 469 415T503 336T465 179T427 52Q427 26 444 26Q450 26 453 27Q482 32 505 65T540 145Q542 153 560 153Q580 153 580 145Q580 144 576 130Q568 101 554 73T508 17T439 -10Q392 -10 371 17T350 73Q350 92 386 193T423 345Q423 404 379 404H374Q288 404 229 303L222 291L189 157Q156 26 151 16Q138 -11 108 -11Q95 -11 87 -5T76 7T74 17Q74 30 112 180T152 343Q153 348 153 366Q153 405 129 405Q91 405 66 305Q60 285 60 284Q58 278 41 278H27Q21 284 21 287Z"></path></g><g data-mml-node="mi" transform="translate(633,-150) scale(0.707)"><path data-c="1D44B" d="M42 0H40Q26 0 26 11Q26 15 29 27Q33 41 36 43T55 46Q141 49 190 98Q200 108 306 224T411 342Q302 620 297 625Q288 636 234 637H206Q200 643 200 645T202 664Q206 677 212 683H226Q260 681 347 681Q380 681 408 681T453 682T473 682Q490 682 490 671Q490 670 488 658Q484 643 481 640T465 637Q434 634 411 620L488 426L541 485Q646 598 646 610Q646 628 622 635Q617 635 609 637Q594 637 594 648Q594 650 596 664Q600 677 606 683H618Q619 683 643 683T697 681T738 680Q828 680 837 683H845Q852 676 852 672Q850 647 840 637H824Q790 636 763 628T722 611T698 593L687 584Q687 585 592 480L505 384Q505 383 536 304T601 142T638 56Q648 47 699 46Q734 46 734 37Q734 35 732 23Q728 7 725 4T711 1Q708 1 678 1T589 2Q528 2 496 2T461 1Q444 1 444 10Q444 11 446 25Q448 35 450 39T455 44T464 46T480 47T506 54Q523 62 523 64Q522 64 476 181L429 299Q241 95 236 84Q232 76 232 72Q232 53 261 47Q262 47 267 47T273 46Q276 46 277 46T280 45T283 42T284 35Q284 26 282 19Q279 6 276 4T261 1Q258 1 243 1T201 2T142 2Q64 2 42 0Z"></path></g></g></g></g><g data-mml-node="msub" transform="translate(3502.8,0)"><g data-mml-node="mi"><path data-c="1D44B" d="M42 0H40Q26 0 26 11Q26 15 29 27Q33 41 36 43T55 46Q141 49 190 98Q200 108 306 224T411 342Q302 620 297 625Q288 636 234 637H206Q200 643 200 645T202 664Q206 677 212 683H226Q260 681 347 681Q380 681 408 681T453 682T473 682Q490 682 490 671Q490 670 488 658Q484 643 481 640T465 637Q434 634 411 620L488 426L541 485Q646 598 646 610Q646 628 622 635Q617 635 609 637Q594 637 594 648Q594 650 596 664Q600 677 606 683H618Q619 683 643 683T697 681T738 680Q828 680 837 683H845Q852 676 852 672Q850 647 840 637H824Q790 636 763 628T722 611T698 593L687 584Q687 585 592 480L505 384Q505 383 536 304T601 142T638 56Q648 47 699 46Q734 46 734 37Q734 35 732 23Q728 7 725 4T711 1Q708 1 678 1T589 2Q528 2 496 2T461 1Q444 1 444 10Q444 11 446 25Q448 35 450 39T455 44T464 46T480 47T506 54Q523 62 523 64Q522 64 476 181L429 299Q241 95 236 84Q232 76 232 72Q232 53 261 47Q262 47 267 47T273 46Q276 46 277 46T280 45T283 42T284 35Q284 26 282 19Q279 6 276 4T261 1Q258 1 243 1T201 2T142 2Q64 2 42 0Z"></path></g><g data-mml-node="mi" transform="translate(861,-150) scale(0.707)"><path data-c="1D456" d="M184 600Q184 624 203 642T247 661Q265 661 277 649T290 619Q290 596 270 577T226 557Q211 557 198 567T184 600ZM21 287Q21 295 30 318T54 369T98 420T158 442Q197 442 223 419T250 357Q250 340 236 301T196 196T154 83Q149 61 149 51Q149 26 166 26Q175 26 185 29T208 43T235 78T260 137Q263 149 265 151T282 153Q302 153 302 143Q302 135 293 112T268 61T223 11T161 -11Q129 -11 102 10T74 74Q74 91 79 106T122 220Q160 321 166 341T173 380Q173 404 156 404H154Q124 404 99 371T61 287Q60 286 59 284T58 281T56 279T53 278T49 278T41 278H27Q21 284 21 287Z"></path></g></g></g></g><g data-mml-node="mtr" transform="translate(0,-1479.6)"><g data-mml-node="mtd" transform="translate(32,0)"><g data-mml-node="msub"><g data-mml-node="mi"><path data-c="1D70E" d="M184 -11Q116 -11 74 34T31 147Q31 247 104 333T274 430Q275 431 414 431H552Q553 430 555 429T559 427T562 425T565 422T567 420T569 416T570 412T571 407T572 401Q572 357 507 357Q500 357 490 357T476 358H416L421 348Q439 310 439 263Q439 153 359 71T184 -11ZM361 278Q361 358 276 358Q152 358 115 184Q114 180 114 178Q106 141 106 117Q106 67 131 47T188 26Q242 26 287 73Q316 103 334 153T356 233T361 278Z"></path></g><g data-mml-node="mi" transform="translate(604,-150) scale(0.707)"><path data-c="1D44B" d="M42 0H40Q26 0 26 11Q26 15 29 27Q33 41 36 43T55 46Q141 49 190 98Q200 108 306 224T411 342Q302 620 297 625Q288 636 234 637H206Q200 643 200 645T202 664Q206 677 212 683H226Q260 681 347 681Q380 681 408 681T453 682T473 682Q490 682 490 671Q490 670 488 658Q484 643 481 640T465 637Q434 634 411 620L488 426L541 485Q646 598 646 610Q646 628 622 635Q617 635 609 637Q594 637 594 648Q594 650 596 664Q600 677 606 683H618Q619 683 643 683T697 681T738 680Q828 680 837 683H845Q852 676 852 672Q850 647 840 637H824Q790 636 763 628T722 611T698 593L687 584Q687 585 592 480L505 384Q505 383 536 304T601 142T638 56Q648 47 699 46Q734 46 734 37Q734 35 732 23Q728 7 725 4T711 1Q708 1 678 1T589 2Q528 2 496 2T461 1Q444 1 444 10Q444 11 446 25Q448 35 450 39T455 44T464 46T480 47T506 54Q523 62 523 64Q522 64 476 181L429 299Q241 95 236 84Q232 76 232 72Q232 53 261 47Q262 47 267 47T273 46Q276 46 277 46T280 45T283 42T284 35Q284 26 282 19Q279 6 276 4T261 1Q258 1 243 1T201 2T142 2Q64 2 42 0Z"></path></g></g></g><g data-mml-node="mtd" transform="translate(1288.5,0)"><g data-mml-node="mi"></g><g data-mml-node="mo" transform="translate(277.8,0)"><path data-c="3D" d="M56 347Q56 360 70 367H707Q722 359 722 347Q722 336 708 328L390 327H72Q56 332 56 347ZM56 153Q56 168 72 173H708Q722 163 722 153Q722 140 707 133H70Q56 140 56 153Z"></path></g></g><g data-mml-node="mtd" transform="translate(2622.2,0)"><g data-mml-node="mfrac"><g data-mml-node="mn" transform="translate(1473.9,676)"><path data-c="31" d="M213 578L200 573Q186 568 160 563T102 556H83V602H102Q149 604 189 617T245 641T273 663Q275 666 285 666Q294 666 302 660V361L303 61Q310 54 315 52T339 48T401 46H427V0H416Q395 3 257 3Q121 3 100 0H88V46H114Q136 46 152 46T177 47T193 50T201 52T207 57T213 61V578Z"></path></g><g data-mml-node="mrow" transform="translate(220,-686)"><g data-mml-node="msub"><g data-mml-node="mi"><path data-c="1D45B" d="M21 287Q22 293 24 303T36 341T56 388T89 425T135 442Q171 442 195 424T225 390T231 369Q231 367 232 367L243 378Q304 442 382 442Q436 442 469 415T503 336T465 179T427 52Q427 26 444 26Q450 26 453 27Q482 32 505 65T540 145Q542 153 560 153Q580 153 580 145Q580 144 576 130Q568 101 554 73T508 17T439 -10Q392 -10 371 17T350 73Q350 92 386 193T423 345Q423 404 379 404H374Q288 404 229 303L222 291L189 157Q156 26 151 16Q138 -11 108 -11Q95 -11 87 -5T76 7T74 17Q74 30 112 180T152 343Q153 348 153 366Q153 405 129 405Q91 405 66 305Q60 285 60 284Q58 278 41 278H27Q21 284 21 287Z"></path></g><g data-mml-node="mi" transform="translate(633,-150) scale(0.707)"><path data-c="1D44B" d="M42 0H40Q26 0 26 11Q26 15 29 27Q33 41 36 43T55 46Q141 49 190 98Q200 108 306 224T411 342Q302 620 297 625Q288 636 234 637H206Q200 643 200 645T202 664Q206 677 212 683H226Q260 681 347 681Q380 681 408 681T453 682T473 682Q490 682 490 671Q490 670 488 658Q484 643 481 640T465 637Q434 634 411 620L488 426L541 485Q646 598 646 610Q646 628 622 635Q617 635 609 637Q594 637 594 648Q594 650 596 664Q600 677 606 683H618Q619 683 643 683T697 681T738 680Q828 680 837 683H845Q852 676 852 672Q850 647 840 637H824Q790 636 763 628T722 611T698 593L687 584Q687 585 592 480L505 384Q505 383 536 304T601 142T638 56Q648 47 699 46Q734 46 734 37Q734 35 732 23Q728 7 725 4T711 1Q708 1 678 1T589 2Q528 2 496 2T461 1Q444 1 444 10Q444 11 446 25Q448 35 450 39T455 44T464 46T480 47T506 54Q523 62 523 64Q522 64 476 181L429 299Q241 95 236 84Q232 76 232 72Q232 53 261 47Q262 47 267 47T273 46Q276 46 277 46T280 45T283 42T284 35Q284 26 282 19Q279 6 276 4T261 1Q258 1 243 1T201 2T142 2Q64 2 42 0Z"></path></g></g><g data-mml-node="mo" transform="translate(1507.7,0)"><path data-c="2212" d="M84 237T84 250T98 270H679Q694 262 694 250T679 230H98Q84 237 84 250Z"></path></g><g data-mml-node="mn" transform="translate(2507.9,0)"><path data-c="31" d="M213 578L200 573Q186 568 160 563T102 556H83V602H102Q149 604 189 617T245 641T273 663Q275 666 285 666Q294 666 302 660V361L303 61Q310 54 315 52T339 48T401 46H427V0H416Q395 3 257 3Q121 3 100 0H88V46H114Q136 46 152 46T177 47T193 50T201 52T207 57T213 61V578Z"></path></g></g><rect width="3207.9" height="60" x="120" y="220"></rect></g><g data-mml-node="munderover" transform="translate(3614.6,0)"><g data-mml-node="mo"><path data-c="2211" d="M60 948Q63 950 665 950H1267L1325 815Q1384 677 1388 669H1348L1341 683Q1320 724 1285 761Q1235 809 1174 838T1033 881T882 898T699 902H574H543H251L259 891Q722 258 724 252Q725 250 724 246Q721 243 460 -56L196 -356Q196 -357 407 -357Q459 -357 548 -357T676 -358Q812 -358 896 -353T1063 -332T1204 -283T1307 -196Q1328 -170 1348 -124H1388Q1388 -125 1381 -145T1356 -210T1325 -294L1267 -449L666 -450Q64 -450 61 -448Q55 -446 55 -439Q55 -437 57 -433L590 177Q590 178 557 222T452 366T322 544L56 909L55 924Q55 945 60 948Z"></path></g><g data-mml-node="mi" transform="translate(600,-1084.4) scale(0.707)"><path data-c="1D456" d="M184 600Q184 624 203 642T247 661Q265 661 277 649T290 619Q290 596 270 577T226 557Q211 557 198 567T184 600ZM21 287Q21 295 30 318T54 369T98 420T158 442Q197 442 223 419T250 357Q250 340 236 301T196 196T154 83Q149 61 149 51Q149 26 166 26Q175 26 185 29T208 43T235 78T260 137Q263 149 265 151T282 153Q302 153 302 143Q302 135 293 112T268 61T223 11T161 -11Q129 -11 102 10T74 74Q74 91 79 106T122 220Q160 321 166 341T173 380Q173 404 156 404H154Q124 404 99 371T61 287Q60 286 59 284T58 281T56 279T53 278T49 278T41 278H27Q21 284 21 287Z"></path></g><g data-mml-node="TeXAtom" transform="translate(267.5,1167.1) scale(0.707)" data-mjx-texclass="ORD"><g data-mml-node="msub"><g data-mml-node="mi"><path data-c="1D45B" d="M21 287Q22 293 24 303T36 341T56 388T89 425T135 442Q171 442 195 424T225 390T231 369Q231 367 232 367L243 378Q304 442 382 442Q436 442 469 415T503 336T465 179T427 52Q427 26 444 26Q450 26 453 27Q482 32 505 65T540 145Q542 153 560 153Q580 153 580 145Q580 144 576 130Q568 101 554 73T508 17T439 -10Q392 -10 371 17T350 73Q350 92 386 193T423 345Q423 404 379 404H374Q288 404 229 303L222 291L189 157Q156 26 151 16Q138 -11 108 -11Q95 -11 87 -5T76 7T74 17Q74 30 112 180T152 343Q153 348 153 366Q153 405 129 405Q91 405 66 305Q60 285 60 284Q58 278 41 278H27Q21 284 21 287Z"></path></g><g data-mml-node="mi" transform="translate(633,-150) scale(0.707)"><path data-c="1D44B" d="M42 0H40Q26 0 26 11Q26 15 29 27Q33 41 36 43T55 46Q141 49 190 98Q200 108 306 224T411 342Q302 620 297 625Q288 636 234 637H206Q200 643 200 645T202 664Q206 677 212 683H226Q260 681 347 681Q380 681 408 681T453 682T473 682Q490 682 490 671Q490 670 488 658Q484 643 481 640T465 637Q434 634 411 620L488 426L541 485Q646 598 646 610Q646 628 622 635Q617 635 609 637Q594 637 594 648Q594 650 596 664Q600 677 606 683H618Q619 683 643 683T697 681T738 680Q828 680 837 683H845Q852 676 852 672Q850 647 840 637H824Q790 636 763 628T722 611T698 593L687 584Q687 585 592 480L505 384Q505 383 536 304T601 142T638 56Q648 47 699 46Q734 46 734 37Q734 35 732 23Q728 7 725 4T711 1Q708 1 678 1T589 2Q528 2 496 2T461 1Q444 1 444 10Q444 11 446 25Q448 35 450 39T455 44T464 46T480 47T506 54Q523 62 523 64Q522 64 476 181L429 299Q241 95 236 84Q232 76 232 72Q232 53 261 47Q262 47 267 47T273 46Q276 46 277 46T280 45T283 42T284 35Q284 26 282 19Q279 6 276 4T261 1Q258 1 243 1T201 2T142 2Q64 2 42 0Z"></path></g></g></g></g><g data-mml-node="mo" transform="translate(5058.6,0)"><path data-c="28" d="M94 250Q94 319 104 381T127 488T164 576T202 643T244 695T277 729T302 750H315H319Q333 750 333 741Q333 738 316 720T275 667T226 581T184 443T167 250T184 58T225 -81T274 -167T316 -220T333 -241Q333 -250 318 -250H315H302L274 -226Q180 -141 137 -14T94 250Z"></path></g><g data-mml-node="msub" transform="translate(5447.6,0)"><g data-mml-node="mi"><path data-c="1D44B" d="M42 0H40Q26 0 26 11Q26 15 29 27Q33 41 36 43T55 46Q141 49 190 98Q200 108 306 224T411 342Q302 620 297 625Q288 636 234 637H206Q200 643 200 645T202 664Q206 677 212 683H226Q260 681 347 681Q380 681 408 681T453 682T473 682Q490 682 490 671Q490 670 488 658Q484 643 481 640T465 637Q434 634 411 620L488 426L541 485Q646 598 646 610Q646 628 622 635Q617 635 609 637Q594 637 594 648Q594 650 596 664Q600 677 606 683H618Q619 683 643 683T697 681T738 680Q828 680 837 683H845Q852 676 852 672Q850 647 840 637H824Q790 636 763 628T722 611T698 593L687 584Q687 585 592 480L505 384Q505 383 536 304T601 142T638 56Q648 47 699 46Q734 46 734 37Q734 35 732 23Q728 7 725 4T711 1Q708 1 678 1T589 2Q528 2 496 2T461 1Q444 1 444 10Q444 11 446 25Q448 35 450 39T455 44T464 46T480 47T506 54Q523 62 523 64Q522 64 476 181L429 299Q241 95 236 84Q232 76 232 72Q232 53 261 47Q262 47 267 47T273 46Q276 46 277 46T280 45T283 42T284 35Q284 26 282 19Q279 6 276 4T261 1Q258 1 243 1T201 2T142 2Q64 2 42 0Z"></path></g><g data-mml-node="mi" transform="translate(861,-150) scale(0.707)"><path data-c="1D456" d="M184 600Q184 624 203 642T247 661Q265 661 277 649T290 619Q290 596 270 577T226 557Q211 557 198 567T184 600ZM21 287Q21 295 30 318T54 369T98 420T158 442Q197 442 223 419T250 357Q250 340 236 301T196 196T154 83Q149 61 149 51Q149 26 166 26Q175 26 185 29T208 43T235 78T260 137Q263 149 265 151T282 153Q302 153 302 143Q302 135 293 112T268 61T223 11T161 -11Q129 -11 102 10T74 74Q74 91 79 106T122 220Q160 321 166 341T173 380Q173 404 156 404H154Q124 404 99 371T61 287Q60 286 59 284T58 281T56 279T53 278T49 278T41 278H27Q21 284 21 287Z"></path></g></g><g data-mml-node="mo" transform="translate(6824.7,0)"><path data-c="2212" d="M84 237T84 250T98 270H679Q694 262 694 250T679 230H98Q84 237 84 250Z"></path></g><g data-mml-node="msub" transform="translate(7825,0)"><g data-mml-node="mi"><path data-c="1D707" d="M58 -216Q44 -216 34 -208T23 -186Q23 -176 96 116T173 414Q186 442 219 442Q231 441 239 435T249 423T251 413Q251 401 220 279T187 142Q185 131 185 107V99Q185 26 252 26Q261 26 270 27T287 31T302 38T315 45T327 55T338 65T348 77T356 88T365 100L372 110L408 253Q444 395 448 404Q461 431 491 431Q504 431 512 424T523 412T525 402L449 84Q448 79 448 68Q448 43 455 35T476 26Q485 27 496 35Q517 55 537 131Q543 151 547 152Q549 153 557 153H561Q580 153 580 144Q580 138 575 117T555 63T523 13Q510 0 491 -8Q483 -10 467 -10Q446 -10 429 -4T402 11T385 29T376 44T374 51L368 45Q362 39 350 30T324 12T288 -4T246 -11Q199 -11 153 12L129 -85Q108 -167 104 -180T92 -202Q76 -216 58 -216Z"></path></g><g data-mml-node="mi" transform="translate(636,-150) scale(0.707)"><path data-c="1D44B" d="M42 0H40Q26 0 26 11Q26 15 29 27Q33 41 36 43T55 46Q141 49 190 98Q200 108 306 224T411 342Q302 620 297 625Q288 636 234 637H206Q200 643 200 645T202 664Q206 677 212 683H226Q260 681 347 681Q380 681 408 681T453 682T473 682Q490 682 490 671Q490 670 488 658Q484 643 481 640T465 637Q434 634 411 620L488 426L541 485Q646 598 646 610Q646 628 622 635Q617 635 609 637Q594 637 594 648Q594 650 596 664Q600 677 606 683H618Q619 683 643 683T697 681T738 680Q828 680 837 683H845Q852 676 852 672Q850 647 840 637H824Q790 636 763 628T722 611T698 593L687 584Q687 585 592 480L505 384Q505 383 536 304T601 142T638 56Q648 47 699 46Q734 46 734 37Q734 35 732 23Q728 7 725 4T711 1Q708 1 678 1T589 2Q528 2 496 2T461 1Q444 1 444 10Q444 11 446 25Q448 35 450 39T455 44T464 46T480 47T506 54Q523 62 523 64Q522 64 476 181L429 299Q241 95 236 84Q232 76 232 72Q232 53 261 47Q262 47 267 47T273 46Q276 46 277 46T280 45T283 42T284 35Q284 26 282 19Q279 6 276 4T261 1Q258 1 243 1T201 2T142 2Q64 2 42 0Z"></path></g></g><g data-mml-node="msup" transform="translate(9113.4,0)"><g data-mml-node="mo"><path data-c="29" d="M60 749L64 750Q69 750 74 750H86L114 726Q208 641 251 514T294 250Q294 182 284 119T261 12T224 -76T186 -143T145 -194T113 -227T90 -246Q87 -249 86 -250H74Q66 -250 63 -250T58 -247T55 -238Q56 -237 66 -225Q221 -64 221 250T66 725Q56 737 55 738Q55 746 60 749Z"></path></g><g data-mml-node="mn" transform="translate(422,413) scale(0.707)"><path data-c="32" d="M109 429Q82 429 66 447T50 491Q50 562 103 614T235 666Q326 666 387 610T449 465Q449 422 429 383T381 315T301 241Q265 210 201 149L142 93L218 92Q375 92 385 97Q392 99 409 186V189H449V186Q448 183 436 95T421 3V0H50V19V31Q50 38 56 46T86 81Q115 113 136 137Q145 147 170 174T204 211T233 244T261 278T284 308T305 340T320 369T333 401T340 431T343 464Q343 527 309 573T212 619Q179 619 154 602T119 569T109 550Q109 549 114 549Q132 549 151 535T170 489Q170 464 154 447T109 429Z"></path></g></g></g></g></g></g></g></svg></mjx-container></span></p> <p>これを X と Y 両方に対して求めます。さらに以下のようにして t を求める。</p> <p><span class="math display"><mjx-container class="MathJax" jax="SVG" display="true"><svg style="vertical-align: -4.118ex;" xmlns="http://www.w3.org/2000/svg" width="15.906ex" height="6.966ex" role="img" focusable="false" viewBox="0 -1259 7030.4 3079"><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="mi"><path data-c="1D461" d="M26 385Q19 392 19 395Q19 399 22 411T27 425Q29 430 36 430T87 431H140L159 511Q162 522 166 540T173 566T179 586T187 603T197 615T211 624T229 626Q247 625 254 615T261 596Q261 589 252 549T232 470L222 433Q222 431 272 431H323Q330 424 330 420Q330 398 317 385H210L174 240Q135 80 135 68Q135 26 162 26Q197 26 230 60T283 144Q285 150 288 151T303 153H307Q322 153 322 145Q322 142 319 133Q314 117 301 95T267 48T216 6T155 -11Q125 -11 98 4T59 56Q57 64 57 83V101L92 241Q127 382 128 383Q128 385 77 385H26Z"></path></g><g data-mml-node="mo" transform="translate(638.8,0)"><path data-c="3D" d="M56 347Q56 360 70 367H707Q722 359 722 347Q722 336 708 328L390 327H72Q56 332 56 347ZM56 153Q56 168 72 173H708Q722 163 722 153Q722 140 707 133H70Q56 140 56 153Z"></path></g><g data-mml-node="mfrac" transform="translate(1694.6,0)"><g data-mml-node="mrow" transform="translate(799.7,676)"><g data-mml-node="msub"><g data-mml-node="mi"><path data-c="1D707" d="M58 -216Q44 -216 34 -208T23 -186Q23 -176 96 116T173 414Q186 442 219 442Q231 441 239 435T249 423T251 413Q251 401 220 279T187 142Q185 131 185 107V99Q185 26 252 26Q261 26 270 27T287 31T302 38T315 45T327 55T338 65T348 77T356 88T365 100L372 110L408 253Q444 395 448 404Q461 431 491 431Q504 431 512 424T523 412T525 402L449 84Q448 79 448 68Q448 43 455 35T476 26Q485 27 496 35Q517 55 537 131Q543 151 547 152Q549 153 557 153H561Q580 153 580 144Q580 138 575 117T555 63T523 13Q510 0 491 -8Q483 -10 467 -10Q446 -10 429 -4T402 11T385 29T376 44T374 51L368 45Q362 39 350 30T324 12T288 -4T246 -11Q199 -11 153 12L129 -85Q108 -167 104 -180T92 -202Q76 -216 58 -216Z"></path></g><g data-mml-node="mi" transform="translate(636,-150) scale(0.707)"><path data-c="1D44B" d="M42 0H40Q26 0 26 11Q26 15 29 27Q33 41 36 43T55 46Q141 49 190 98Q200 108 306 224T411 342Q302 620 297 625Q288 636 234 637H206Q200 643 200 645T202 664Q206 677 212 683H226Q260 681 347 681Q380 681 408 681T453 682T473 682Q490 682 490 671Q490 670 488 658Q484 643 481 640T465 637Q434 634 411 620L488 426L541 485Q646 598 646 610Q646 628 622 635Q617 635 609 637Q594 637 594 648Q594 650 596 664Q600 677 606 683H618Q619 683 643 683T697 681T738 680Q828 680 837 683H845Q852 676 852 672Q850 647 840 637H824Q790 636 763 628T722 611T698 593L687 584Q687 585 592 480L505 384Q505 383 536 304T601 142T638 56Q648 47 699 46Q734 46 734 37Q734 35 732 23Q728 7 725 4T711 1Q708 1 678 1T589 2Q528 2 496 2T461 1Q444 1 444 10Q444 11 446 25Q448 35 450 39T455 44T464 46T480 47T506 54Q523 62 523 64Q522 64 476 181L429 299Q241 95 236 84Q232 76 232 72Q232 53 261 47Q262 47 267 47T273 46Q276 46 277 46T280 45T283 42T284 35Q284 26 282 19Q279 6 276 4T261 1Q258 1 243 1T201 2T142 2Q64 2 42 0Z"></path></g></g><g data-mml-node="mo" transform="translate(1510.7,0)"><path data-c="2212" d="M84 237T84 250T98 270H679Q694 262 694 250T679 230H98Q84 237 84 250Z"></path></g><g data-mml-node="msub" transform="translate(2510.9,0)"><g data-mml-node="mi"><path data-c="1D707" d="M58 -216Q44 -216 34 -208T23 -186Q23 -176 96 116T173 414Q186 442 219 442Q231 441 239 435T249 423T251 413Q251 401 220 279T187 142Q185 131 185 107V99Q185 26 252 26Q261 26 270 27T287 31T302 38T315 45T327 55T338 65T348 77T356 88T365 100L372 110L408 253Q444 395 448 404Q461 431 491 431Q504 431 512 424T523 412T525 402L449 84Q448 79 448 68Q448 43 455 35T476 26Q485 27 496 35Q517 55 537 131Q543 151 547 152Q549 153 557 153H561Q580 153 580 144Q580 138 575 117T555 63T523 13Q510 0 491 -8Q483 -10 467 -10Q446 -10 429 -4T402 11T385 29T376 44T374 51L368 45Q362 39 350 30T324 12T288 -4T246 -11Q199 -11 153 12L129 -85Q108 -167 104 -180T92 -202Q76 -216 58 -216Z"></path></g><g data-mml-node="mi" transform="translate(636,-150) scale(0.707)"><path data-c="1D44C" d="M66 637Q54 637 49 637T39 638T32 641T30 647T33 664T42 682Q44 683 56 683Q104 680 165 680Q288 680 306 683H316Q322 677 322 674T320 656Q316 643 310 637H298Q242 637 242 624Q242 619 292 477T343 333L346 336Q350 340 358 349T379 373T411 410T454 461Q546 568 561 587T577 618Q577 634 545 637Q528 637 528 647Q528 649 530 661Q533 676 535 679T549 683Q551 683 578 682T657 680Q684 680 713 681T746 682Q763 682 763 673Q763 669 760 657T755 643Q753 637 734 637Q662 632 617 587Q608 578 477 424L348 273L322 169Q295 62 295 57Q295 46 363 46Q379 46 384 45T390 35Q390 33 388 23Q384 6 382 4T366 1Q361 1 324 1T232 2Q170 2 138 2T102 1Q84 1 84 9Q84 14 87 24Q88 27 89 30T90 35T91 39T93 42T96 44T101 45T107 45T116 46T129 46Q168 47 180 50T198 63Q201 68 227 171L252 274L129 623Q128 624 127 625T125 627T122 629T118 631T113 633T105 634T96 635T83 636T66 637Z"></path></g></g></g><g data-mml-node="msqrt" transform="translate(220,-1137.4)"><g transform="translate(1020,0)"><g data-mml-node="mfrac"><g data-mml-node="msub" transform="translate(230.3,446.1) scale(0.707)"><g data-mml-node="mi"><path data-c="1D70E" d="M184 -11Q116 -11 74 34T31 147Q31 247 104 333T274 430Q275 431 414 431H552Q553 430 555 429T559 427T562 425T565 422T567 420T569 416T570 412T571 407T572 401Q572 357 507 357Q500 357 490 357T476 358H416L421 348Q439 310 439 263Q439 153 359 71T184 -11ZM361 278Q361 358 276 358Q152 358 115 184Q114 180 114 178Q106 141 106 117Q106 67 131 47T188 26Q242 26 287 73Q316 103 334 153T356 233T361 278Z"></path></g><g data-mml-node="mi" transform="translate(604,-150) scale(0.707)"><path data-c="1D44B" d="M42 0H40Q26 0 26 11Q26 15 29 27Q33 41 36 43T55 46Q141 49 190 98Q200 108 306 224T411 342Q302 620 297 625Q288 636 234 637H206Q200 643 200 645T202 664Q206 677 212 683H226Q260 681 347 681Q380 681 408 681T453 682T473 682Q490 682 490 671Q490 670 488 658Q484 643 481 640T465 637Q434 634 411 620L488 426L541 485Q646 598 646 610Q646 628 622 635Q617 635 609 637Q594 637 594 648Q594 650 596 664Q600 677 606 683H618Q619 683 643 683T697 681T738 680Q828 680 837 683H845Q852 676 852 672Q850 647 840 637H824Q790 636 763 628T722 611T698 593L687 584Q687 585 592 480L505 384Q505 383 536 304T601 142T638 56Q648 47 699 46Q734 46 734 37Q734 35 732 23Q728 7 725 4T711 1Q708 1 678 1T589 2Q528 2 496 2T461 1Q444 1 444 10Q444 11 446 25Q448 35 450 39T455 44T464 46T480 47T506 54Q523 62 523 64Q522 64 476 181L429 299Q241 95 236 84Q232 76 232 72Q232 53 261 47Q262 47 267 47T273 46Q276 46 277 46T280 45T283 42T284 35Q284 26 282 19Q279 6 276 4T261 1Q258 1 243 1T201 2T142 2Q64 2 42 0Z"></path></g></g><g data-mml-node="msub" transform="translate(220,-345) scale(0.707)"><g data-mml-node="mi"><path data-c="1D45B" d="M21 287Q22 293 24 303T36 341T56 388T89 425T135 442Q171 442 195 424T225 390T231 369Q231 367 232 367L243 378Q304 442 382 442Q436 442 469 415T503 336T465 179T427 52Q427 26 444 26Q450 26 453 27Q482 32 505 65T540 145Q542 153 560 153Q580 153 580 145Q580 144 576 130Q568 101 554 73T508 17T439 -10Q392 -10 371 17T350 73Q350 92 386 193T423 345Q423 404 379 404H374Q288 404 229 303L222 291L189 157Q156 26 151 16Q138 -11 108 -11Q95 -11 87 -5T76 7T74 17Q74 30 112 180T152 343Q153 348 153 366Q153 405 129 405Q91 405 66 305Q60 285 60 284Q58 278 41 278H27Q21 284 21 287Z"></path></g><g data-mml-node="mi" transform="translate(633,-150) scale(0.707)"><path data-c="1D44B" d="M42 0H40Q26 0 26 11Q26 15 29 27Q33 41 36 43T55 46Q141 49 190 98Q200 108 306 224T411 342Q302 620 297 625Q288 636 234 637H206Q200 643 200 645T202 664Q206 677 212 683H226Q260 681 347 681Q380 681 408 681T453 682T473 682Q490 682 490 671Q490 670 488 658Q484 643 481 640T465 637Q434 634 411 620L488 426L541 485Q646 598 646 610Q646 628 622 635Q617 635 609 637Q594 637 594 648Q594 650 596 664Q600 677 606 683H618Q619 683 643 683T697 681T738 680Q828 680 837 683H845Q852 676 852 672Q850 647 840 637H824Q790 636 763 628T722 611T698 593L687 584Q687 585 592 480L505 384Q505 383 536 304T601 142T638 56Q648 47 699 46Q734 46 734 37Q734 35 732 23Q728 7 725 4T711 1Q708 1 678 1T589 2Q528 2 496 2T461 1Q444 1 444 10Q444 11 446 25Q448 35 450 39T455 44T464 46T480 47T506 54Q523 62 523 64Q522 64 476 181L429 299Q241 95 236 84Q232 76 232 72Q232 53 261 47Q262 47 267 47T273 46Q276 46 277 46T280 45T283 42T284 35Q284 26 282 19Q279 6 276 4T261 1Q258 1 243 1T201 2T142 2Q64 2 42 0Z"></path></g></g><rect width="1109" height="60" x="120" y="220"></rect></g><g data-mml-node="mo" transform="translate(1571.2,0)"><path data-c="2B" d="M56 237T56 250T70 270H369V420L370 570Q380 583 389 583Q402 583 409 568V270H707Q722 262 722 250T707 230H409V-68Q401 -82 391 -82H389H387Q375 -82 369 -68V230H70Q56 237 56 250Z"></path></g><g data-mml-node="mfrac" transform="translate(2571.4,0)"><g data-mml-node="msub" transform="translate(230.3,446.1) scale(0.707)"><g data-mml-node="mi"><path data-c="1D70E" d="M184 -11Q116 -11 74 34T31 147Q31 247 104 333T274 430Q275 431 414 431H552Q553 430 555 429T559 427T562 425T565 422T567 420T569 416T570 412T571 407T572 401Q572 357 507 357Q500 357 490 357T476 358H416L421 348Q439 310 439 263Q439 153 359 71T184 -11ZM361 278Q361 358 276 358Q152 358 115 184Q114 180 114 178Q106 141 106 117Q106 67 131 47T188 26Q242 26 287 73Q316 103 334 153T356 233T361 278Z"></path></g><g data-mml-node="mi" transform="translate(604,-150) scale(0.707)"><path data-c="1D44C" d="M66 637Q54 637 49 637T39 638T32 641T30 647T33 664T42 682Q44 683 56 683Q104 680 165 680Q288 680 306 683H316Q322 677 322 674T320 656Q316 643 310 637H298Q242 637 242 624Q242 619 292 477T343 333L346 336Q350 340 358 349T379 373T411 410T454 461Q546 568 561 587T577 618Q577 634 545 637Q528 637 528 647Q528 649 530 661Q533 676 535 679T549 683Q551 683 578 682T657 680Q684 680 713 681T746 682Q763 682 763 673Q763 669 760 657T755 643Q753 637 734 637Q662 632 617 587Q608 578 477 424L348 273L322 169Q295 62 295 57Q295 46 363 46Q379 46 384 45T390 35Q390 33 388 23Q384 6 382 4T366 1Q361 1 324 1T232 2Q170 2 138 2T102 1Q84 1 84 9Q84 14 87 24Q88 27 89 30T90 35T91 39T93 42T96 44T101 45T107 45T116 46T129 46Q168 47 180 50T198 63Q201 68 227 171L252 274L129 623Q128 624 127 625T125 627T122 629T118 631T113 633T105 634T96 635T83 636T66 637Z"></path></g></g><g data-mml-node="msub" transform="translate(220,-345) scale(0.707)"><g data-mml-node="mi"><path data-c="1D45B" d="M21 287Q22 293 24 303T36 341T56 388T89 425T135 442Q171 442 195 424T225 390T231 369Q231 367 232 367L243 378Q304 442 382 442Q436 442 469 415T503 336T465 179T427 52Q427 26 444 26Q450 26 453 27Q482 32 505 65T540 145Q542 153 560 153Q580 153 580 145Q580 144 576 130Q568 101 554 73T508 17T439 -10Q392 -10 371 17T350 73Q350 92 386 193T423 345Q423 404 379 404H374Q288 404 229 303L222 291L189 157Q156 26 151 16Q138 -11 108 -11Q95 -11 87 -5T76 7T74 17Q74 30 112 180T152 343Q153 348 153 366Q153 405 129 405Q91 405 66 305Q60 285 60 284Q58 278 41 278H27Q21 284 21 287Z"></path></g><g data-mml-node="mi" transform="translate(633,-150) scale(0.707)"><path data-c="1D44C" d="M66 637Q54 637 49 637T39 638T32 641T30 647T33 664T42 682Q44 683 56 683Q104 680 165 680Q288 680 306 683H316Q322 677 322 674T320 656Q316 643 310 637H298Q242 637 242 624Q242 619 292 477T343 333L346 336Q350 340 358 349T379 373T411 410T454 461Q546 568 561 587T577 618Q577 634 545 637Q528 637 528 647Q528 649 530 661Q533 676 535 679T549 683Q551 683 578 682T657 680Q684 680 713 681T746 682Q763 682 763 673Q763 669 760 657T755 643Q753 637 734 637Q662 632 617 587Q608 578 477 424L348 273L322 169Q295 62 295 57Q295 46 363 46Q379 46 384 45T390 35Q390 33 388 23Q384 6 382 4T366 1Q361 1 324 1T232 2Q170 2 138 2T102 1Q84 1 84 9Q84 14 87 24Q88 27 89 30T90 35T91 39T93 42T96 44T101 45T107 45T116 46T129 46Q168 47 180 50T198 63Q201 68 227 171L252 274L129 623Q128 624 127 625T125 627T122 629T118 631T113 633T105 634T96 635T83 636T66 637Z"></path></g></g><rect width="1064.5" height="60" x="120" y="220"></rect></g></g><g data-mml-node="mo" transform="translate(0,-32.6)"><path data-c="221A" d="M1001 1150Q1017 1150 1020 1132Q1020 1127 741 244L460 -643Q453 -650 436 -650H424Q423 -647 423 -645T421 -640T419 -631T415 -617T408 -594T399 -560T385 -512T367 -448T343 -364T312 -259L203 119L138 41L111 67L212 188L264 248L472 -474L983 1140Q988 1150 1001 1150Z"></path></g><rect width="3875.9" height="60" x="1020" y="1057.4"></rect></g><rect width="5095.9" height="60" x="120" y="220"></rect></g></g></g></svg></mjx-container></span></p> <p>t 分布の累積密度関数 (Cumlative Distribution Function; CDF) を定義する。面倒すぎたので<a href="https://github.com/jstat/jstat">jstat</a>の<code>studentt.cdf</code>を使った。コードを見ると、分子の積分は<a href="https://ja.wikipedia.org/wiki/シンプソンの公式">シンプソンの公式</a>を使って近似していた。</p> <p><span class="math display"><mjx-container class="MathJax" jax="SVG" display="true"><svg style="vertical-align: -2.387ex;" xmlns="http://www.w3.org/2000/svg" width="52.204ex" height="7.61ex" role="img" focusable="false" viewBox="0 -2308.6 23074 3363.6"><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="mtext"><path data-c="43" d="M56 342Q56 428 89 500T174 615T283 681T391 705Q394 705 400 705T408 704Q499 704 569 636L582 624L612 663Q639 700 643 704Q644 704 647 704T653 705H657Q660 705 666 699V419L660 413H626Q620 419 619 430Q610 512 571 572T476 651Q457 658 426 658Q322 658 252 588Q173 509 173 342Q173 221 211 151Q232 111 263 84T328 45T384 29T428 24Q517 24 571 93T626 244Q626 251 632 257H660L666 251V236Q661 133 590 56T403 -21Q262 -21 159 83T56 342Z"></path><path data-c="44" d="M130 622Q123 629 119 631T103 634T60 637H27V683H228Q399 682 419 682T461 676Q504 667 546 641T626 573T685 470T708 336Q708 210 634 116T442 3Q429 1 228 0H27V46H60Q102 47 111 49T130 61V622ZM593 338Q593 439 571 501T493 602Q439 637 355 637H322H294Q238 637 234 628Q231 624 231 344Q231 62 232 59Q233 49 248 48T339 46H350Q456 46 515 95Q561 133 577 191T593 338Z" transform="translate(722,0)"></path><path data-c="46" d="M128 619Q121 626 117 628T101 631T58 634H25V680H582V676Q584 670 596 560T610 444V440H570V444Q563 493 561 501Q555 538 543 563T516 601T477 622T431 631T374 633H334H286Q252 633 244 631T233 621Q232 619 232 490V363H284Q287 363 303 363T327 364T349 367T372 373T389 385Q407 403 410 459V480H450V200H410V221Q407 276 389 296Q381 303 371 307T348 313T327 316T303 317T284 317H232V189L233 61Q240 54 245 52T270 48T333 46H360V0H348Q324 3 182 3Q51 3 36 0H25V46H58Q100 47 109 49T128 61V619Z" transform="translate(1486,0)"></path></g><g data-mml-node="mo" transform="translate(2416.8,0)"><path data-c="3D" d="M56 347Q56 360 70 367H707Q722 359 722 347Q722 336 708 328L390 327H72Q56 332 56 347ZM56 153Q56 168 72 173H708Q722 163 722 153Q722 140 707 133H70Q56 140 56 153Z"></path></g><g data-mml-node="mfrac" transform="translate(3472.6,0)"><g data-mml-node="mrow" transform="translate(7016.7,1049.5)"><g data-mml-node="msubsup"><g data-mml-node="mo" transform="translate(0 0.5)"><path data-c="222B" d="M113 -244Q113 -246 119 -251T139 -263T167 -269Q186 -269 199 -260Q220 -247 232 -218T251 -133T262 -15T276 155T297 367Q300 390 305 438T314 512T325 580T340 647T361 703T390 751T428 784T479 804Q481 804 488 804T501 805Q552 802 581 769T610 695Q610 669 594 657T561 645Q542 645 527 658T512 694Q512 705 516 714T526 729T538 737T548 742L552 743Q552 745 545 751T525 762T498 768Q475 768 460 756T434 716T418 652T407 559T398 444T387 300T369 133Q349 -38 337 -102T303 -207Q256 -306 169 -306Q119 -306 87 -272T55 -196Q55 -170 71 -158T104 -146Q123 -146 138 -159T153 -195Q153 -206 149 -215T139 -230T127 -238T117 -242L113 -244Z"></path></g><g data-mml-node="TeXAtom" transform="translate(699.9,759) scale(0.707)" data-mjx-texclass="ORD"><g data-mml-node="mfrac"><g data-mml-node="mi" transform="translate(828.8,394) scale(0.707)"><path data-c="1D463" d="M173 380Q173 405 154 405Q130 405 104 376T61 287Q60 286 59 284T58 281T56 279T53 278T49 278T41 278H27Q21 284 21 287Q21 294 29 316T53 368T97 419T160 441Q202 441 225 417T249 361Q249 344 246 335Q246 329 231 291T200 202T182 113Q182 86 187 69Q200 26 250 26Q287 26 319 60T369 139T398 222T409 277Q409 300 401 317T383 343T365 361T357 383Q357 405 376 424T417 443Q436 443 451 425T467 367Q467 340 455 284T418 159T347 40T241 -11Q177 -11 139 22Q102 54 102 117Q102 148 110 181T151 298Q173 362 173 380Z"></path></g><g data-mml-node="mrow" transform="translate(220,-515.3) scale(0.707)"><g data-mml-node="msup"><g data-mml-node="mi"><path data-c="1D461" d="M26 385Q19 392 19 395Q19 399 22 411T27 425Q29 430 36 430T87 431H140L159 511Q162 522 166 540T173 566T179 586T187 603T197 615T211 624T229 626Q247 625 254 615T261 596Q261 589 252 549T232 470L222 433Q222 431 272 431H323Q330 424 330 420Q330 398 317 385H210L174 240Q135 80 135 68Q135 26 162 26Q197 26 230 60T283 144Q285 150 288 151T303 153H307Q322 153 322 145Q322 142 319 133Q314 117 301 95T267 48T216 6T155 -11Q125 -11 98 4T59 56Q57 64 57 83V101L92 241Q127 382 128 383Q128 385 77 385H26Z"></path></g><g data-mml-node="mn" transform="translate(394,289)"><path data-c="32" d="M109 429Q82 429 66 447T50 491Q50 562 103 614T235 666Q326 666 387 610T449 465Q449 422 429 383T381 315T301 241Q265 210 201 149L142 93L218 92Q375 92 385 97Q392 99 409 186V189H449V186Q448 183 436 95T421 3V0H50V19V31Q50 38 56 46T86 81Q115 113 136 137Q145 147 170 174T204 211T233 244T261 278T284 308T305 340T320 369T333 401T340 431T343 464Q343 527 309 573T212 619Q179 619 154 602T119 569T109 550Q109 549 114 549Q132 549 151 535T170 489Q170 464 154 447T109 429Z"></path></g></g><g data-mml-node="mo" transform="translate(944,0)"><path data-c="2B" d="M56 237T56 250T70 270H369V420L370 570Q380 583 389 583Q402 583 409 568V270H707Q722 262 722 250T707 230H409V-68Q401 -82 391 -82H389H387Q375 -82 369 -68V230H70Q56 237 56 250Z"></path></g><g data-mml-node="mi" transform="translate(1722,0)"><path data-c="1D463" d="M173 380Q173 405 154 405Q130 405 104 376T61 287Q60 286 59 284T58 281T56 279T53 278T49 278T41 278H27Q21 284 21 287Q21 294 29 316T53 368T97 419T160 441Q202 441 225 417T249 361Q249 344 246 335Q246 329 231 291T200 202T182 113Q182 86 187 69Q200 26 250 26Q287 26 319 60T369 139T398 222T409 277Q409 300 401 317T383 343T365 361T357 383Q357 405 376 424T417 443Q436 443 451 425T467 367Q467 340 455 284T418 159T347 40T241 -11Q177 -11 139 22Q102 54 102 117Q102 148 110 181T151 298Q173 362 173 380Z"></path></g></g><rect width="1760.6" height="60" x="120" y="220"></rect></g></g><g data-mml-node="mn" transform="translate(505,-297.3) scale(0.707)"><path data-c="30" d="M96 585Q152 666 249 666Q297 666 345 640T423 548Q460 465 460 320Q460 165 417 83Q397 41 362 16T301 -15T250 -22Q224 -22 198 -16T137 16T82 83Q39 165 39 320Q39 494 96 585ZM321 597Q291 629 250 629Q208 629 178 597Q153 571 145 525T137 333Q137 175 145 125T181 46Q209 16 250 16Q290 16 318 46Q347 76 354 130T362 333Q362 478 354 524T321 597Z"></path></g></g><g data-mml-node="mfrac" transform="translate(2331.2,0)"><g data-mml-node="msup" transform="translate(389.6,394) scale(0.707)"><g data-mml-node="mi"><path data-c="1D45F" d="M21 287Q22 290 23 295T28 317T38 348T53 381T73 411T99 433T132 442Q161 442 183 430T214 408T225 388Q227 382 228 382T236 389Q284 441 347 441H350Q398 441 422 400Q430 381 430 363Q430 333 417 315T391 292T366 288Q346 288 334 299T322 328Q322 376 378 392Q356 405 342 405Q286 405 239 331Q229 315 224 298T190 165Q156 25 151 16Q138 -11 108 -11Q95 -11 87 -5T76 7T74 17Q74 30 114 189T154 366Q154 405 128 405Q107 405 92 377T68 316T57 280Q55 278 41 278H27Q21 284 21 287Z"></path></g><g data-mml-node="TeXAtom" transform="translate(484,468.3) scale(0.707)" data-mjx-texclass="ORD"><g data-mml-node="mfrac"><g data-mml-node="mi" transform="translate(227.5,394)"><path data-c="1D463" d="M173 380Q173 405 154 405Q130 405 104 376T61 287Q60 286 59 284T58 281T56 279T53 278T49 278T41 278H27Q21 284 21 287Q21 294 29 316T53 368T97 419T160 441Q202 441 225 417T249 361Q249 344 246 335Q246 329 231 291T200 202T182 113Q182 86 187 69Q200 26 250 26Q287 26 319 60T369 139T398 222T409 277Q409 300 401 317T383 343T365 361T357 383Q357 405 376 424T417 443Q436 443 451 425T467 367Q467 340 455 284T418 159T347 40T241 -11Q177 -11 139 22Q102 54 102 117Q102 148 110 181T151 298Q173 362 173 380Z"></path></g><g data-mml-node="mn" transform="translate(220,-506)"><path data-c="32" d="M109 429Q82 429 66 447T50 491Q50 562 103 614T235 666Q326 666 387 610T449 465Q449 422 429 383T381 315T301 241Q265 210 201 149L142 93L218 92Q375 92 385 97Q392 99 409 186V189H449V186Q448 183 436 95T421 3V0H50V19V31Q50 38 56 46T86 81Q115 113 136 137Q145 147 170 174T204 211T233 244T261 278T284 308T305 340T320 369T333 401T340 431T343 464Q343 527 309 573T212 619Q179 619 154 602T119 569T109 550Q109 549 114 549Q132 549 151 535T170 489Q170 464 154 447T109 429Z"></path></g><rect width="700" height="60" x="120" y="220"></rect></g><g data-mml-node="mo" transform="translate(940,0)"><path data-c="2212" d="M84 237T84 250T98 270H679Q694 262 694 250T679 230H98Q84 237 84 250Z"></path></g><g data-mml-node="mn" transform="translate(1718,0)"><path data-c="31" d="M213 578L200 573Q186 568 160 563T102 556H83V602H102Q149 604 189 617T245 641T273 663Q275 666 285 666Q294 666 302 660V361L303 61Q310 54 315 52T339 48T401 46H427V0H416Q395 3 257 3Q121 3 100 0H88V46H114Q136 46 152 46T177 47T193 50T201 52T207 57T213 61V578Z"></path></g></g></g><g data-mml-node="msqrt" transform="translate(220,-490.2) scale(0.707)"><g transform="translate(853,0)"><g data-mml-node="mn"><path data-c="31" d="M213 578L200 573Q186 568 160 563T102 556H83V602H102Q149 604 189 617T245 641T273 663Q275 666 285 666Q294 666 302 660V361L303 61Q310 54 315 52T339 48T401 46H427V0H416Q395 3 257 3Q121 3 100 0H88V46H114Q136 46 152 46T177 47T193 50T201 52T207 57T213 61V578Z"></path></g><g data-mml-node="mo" transform="translate(500,0)"><path data-c="2212" d="M84 237T84 250T98 270H679Q694 262 694 250T679 230H98Q84 237 84 250Z"></path></g><g data-mml-node="mi" transform="translate(1278,0)"><path data-c="1D45F" d="M21 287Q22 290 23 295T28 317T38 348T53 381T73 411T99 433T132 442Q161 442 183 430T214 408T225 388Q227 382 228 382T236 389Q284 441 347 441H350Q398 441 422 400Q430 381 430 363Q430 333 417 315T391 292T366 288Q346 288 334 299T322 328Q322 376 378 392Q356 405 342 405Q286 405 239 331Q229 315 224 298T190 165Q156 25 151 16Q138 -11 108 -11Q95 -11 87 -5T76 7T74 17Q74 30 114 189T154 366Q154 405 128 405Q107 405 92 377T68 316T57 280Q55 278 41 278H27Q21 284 21 287Z"></path></g></g><g data-mml-node="mo" transform="translate(0,41.9)"><path data-c="221A" d="M95 178Q89 178 81 186T72 200T103 230T169 280T207 309Q209 311 212 311H213Q219 311 227 294T281 177Q300 134 312 108L397 -77Q398 -77 501 136T707 565T814 786Q820 800 834 800Q841 800 846 794T853 782V776L620 293L385 -193Q381 -200 366 -200Q357 -200 354 -197Q352 -195 256 15L160 225L144 214Q129 202 113 190T95 178Z"></path></g><rect width="1729" height="42.4" x="853" y="799.5"></rect></g><rect width="2025.7" height="60" x="120" y="220"></rect></g><g data-mml-node="mi" transform="translate(4596.9,0)"><path data-c="1D451" d="M366 683Q367 683 438 688T511 694Q523 694 523 686Q523 679 450 384T375 83T374 68Q374 26 402 26Q411 27 422 35Q443 55 463 131Q469 151 473 152Q475 153 483 153H487H491Q506 153 506 145Q506 140 503 129Q490 79 473 48T445 8T417 -8Q409 -10 393 -10Q359 -10 336 5T306 36L300 51Q299 52 296 50Q294 48 292 46Q233 -10 172 -10Q117 -10 75 30T33 157Q33 205 53 255T101 341Q148 398 195 420T280 442Q336 442 364 400Q369 394 369 396Q370 400 396 505T424 616Q424 629 417 632T378 637H357Q351 643 351 645T353 664Q358 683 366 683ZM352 326Q329 405 277 405Q242 405 210 374T160 293Q131 214 119 129Q119 126 119 118T118 106Q118 61 136 44T179 26Q233 26 290 98L298 109L352 326Z"></path></g><g data-mml-node="mi" transform="translate(5116.9,0)"><path data-c="1D45F" d="M21 287Q22 290 23 295T28 317T38 348T53 381T73 411T99 433T132 442Q161 442 183 430T214 408T225 388Q227 382 228 382T236 389Q284 441 347 441H350Q398 441 422 400Q430 381 430 363Q430 333 417 315T391 292T366 288Q346 288 334 299T322 328Q322 376 378 392Q356 405 342 405Q286 405 239 331Q229 315 224 298T190 165Q156 25 151 16Q138 -11 108 -11Q95 -11 87 -5T76 7T74 17Q74 30 114 189T154 366Q154 405 128 405Q107 405 92 377T68 316T57 280Q55 278 41 278H27Q21 284 21 287Z"></path></g><g data-mml-node="TeXAtom" data-mjx-texclass="ORD" transform="translate(5567.9,0)"></g></g><g data-mml-node="mrow" transform="translate(220,-710)"><g data-mml-node="mtext"><path data-c="65" d="M28 218Q28 273 48 318T98 391T163 433T229 448Q282 448 320 430T378 380T406 316T415 245Q415 238 408 231H126V216Q126 68 226 36Q246 30 270 30Q312 30 342 62Q359 79 369 104L379 128Q382 131 395 131H398Q415 131 415 121Q415 117 412 108Q393 53 349 21T250 -11Q155 -11 92 58T28 218ZM333 275Q322 403 238 411H236Q228 411 220 410T195 402T166 381T143 340T127 274V267H333V275Z"></path><path data-c="78" d="M201 0Q189 3 102 3Q26 3 17 0H11V46H25Q48 47 67 52T96 61T121 78T139 96T160 122T180 150L226 210L168 288Q159 301 149 315T133 336T122 351T113 363T107 370T100 376T94 379T88 381T80 383Q74 383 44 385H16V431H23Q59 429 126 429Q219 429 229 431H237V385Q201 381 201 369Q201 367 211 353T239 315T268 274L272 270L297 304Q329 345 329 358Q329 364 327 369T322 376T317 380T310 384L307 385H302V431H309Q324 428 408 428Q487 428 493 431H499V385H492Q443 385 411 368Q394 360 377 341T312 257L296 236L358 151Q424 61 429 57T446 50Q464 46 499 46H516V0H510H502Q494 1 482 1T457 2T432 2T414 3Q403 3 377 3T327 1L304 0H295V46H298Q309 46 320 51T331 63Q331 65 291 120L250 175Q249 174 219 133T185 88Q181 83 181 74Q181 63 188 55T206 46Q208 46 208 23V0H201Z" transform="translate(444,0)"></path><path data-c="70" d="M36 -148H50Q89 -148 97 -134V-126Q97 -119 97 -107T97 -77T98 -38T98 6T98 55T98 106Q98 140 98 177T98 243T98 296T97 335T97 351Q94 370 83 376T38 385H20V408Q20 431 22 431L32 432Q42 433 61 434T98 436Q115 437 135 438T165 441T176 442H179V416L180 390L188 397Q247 441 326 441Q407 441 464 377T522 216Q522 115 457 52T310 -11Q242 -11 190 33L182 40V-45V-101Q182 -128 184 -134T195 -145Q216 -148 244 -148H260V-194H252L228 -193Q205 -192 178 -192T140 -191Q37 -191 28 -194H20V-148H36ZM424 218Q424 292 390 347T305 402Q234 402 182 337V98Q222 26 294 26Q345 26 384 80T424 218Z" transform="translate(972,0)"></path></g><g data-mml-node="mo" transform="translate(1528,0)"><path data-c="28" d="M94 250Q94 319 104 381T127 488T164 576T202 643T244 695T277 729T302 750H315H319Q333 750 333 741Q333 738 316 720T275 667T226 581T184 443T167 250T184 58T225 -81T274 -167T316 -220T333 -241Q333 -250 318 -250H315H302L274 -226Q180 -141 137 -14T94 250Z"></path></g><g data-mml-node="mi" transform="translate(1917,0)"><path data-c="6C" d="M42 46H56Q95 46 103 60V68Q103 77 103 91T103 124T104 167T104 217T104 272T104 329Q104 366 104 407T104 482T104 542T103 586T103 603Q100 622 89 628T44 637H26V660Q26 683 28 683L38 684Q48 685 67 686T104 688Q121 689 141 690T171 693T182 694H185V379Q185 62 186 60Q190 52 198 49Q219 46 247 46H263V0H255L232 1Q209 2 183 2T145 3T107 3T57 1L34 0H26V46H42Z"></path><path data-c="6E" d="M41 46H55Q94 46 102 60V68Q102 77 102 91T102 122T103 161T103 203Q103 234 103 269T102 328V351Q99 370 88 376T43 385H25V408Q25 431 27 431L37 432Q47 433 65 434T102 436Q119 437 138 438T167 441T178 442H181V402Q181 364 182 364T187 369T199 384T218 402T247 421T285 437Q305 442 336 442Q450 438 463 329Q464 322 464 190V104Q464 66 466 59T477 49Q498 46 526 46H542V0H534L510 1Q487 2 460 2T422 3Q319 3 310 0H302V46H318Q379 46 379 62Q380 64 380 200Q379 335 378 343Q372 371 358 385T334 402T308 404Q263 404 229 370Q202 343 195 315T187 232V168V108Q187 78 188 68T191 55T200 49Q221 46 249 46H265V0H257L234 1Q210 2 183 2T145 3Q42 3 33 0H25V46H41Z" transform="translate(278,0)"></path></g><g data-mml-node="mo" transform="translate(2751,0)"><path data-c="2061" d=""></path></g><g data-mml-node="mo" transform="translate(2751,0)"><path data-c="28" d="M94 250Q94 319 104 381T127 488T164 576T202 643T244 695T277 729T302 750H315H319Q333 750 333 741Q333 738 316 720T275 667T226 581T184 443T167 250T184 58T225 -81T274 -167T316 -220T333 -241Q333 -250 318 -250H315H302L274 -226Q180 -141 137 -14T94 250Z"></path></g><g data-mml-node="mi" transform="translate(3140,0)"><path data-c="393" d="M128 619Q121 626 117 628T101 631T58 634H25V680H554V676Q556 670 568 560T582 444V440H542V444Q542 445 538 478T523 545T492 598Q454 634 349 634H334Q264 634 249 633T233 621Q232 618 232 339L233 61Q240 54 245 52T270 48T333 46H360V0H348Q324 3 182 3Q51 3 36 0H25V46H58Q100 47 109 49T128 61V619Z"></path></g><g data-mml-node="mo" transform="translate(3765,0)"><path data-c="28" d="M94 250Q94 319 104 381T127 488T164 576T202 643T244 695T277 729T302 750H315H319Q333 750 333 741Q333 738 316 720T275 667T226 581T184 443T167 250T184 58T225 -81T274 -167T316 -220T333 -241Q333 -250 318 -250H315H302L274 -226Q180 -141 137 -14T94 250Z"></path></g><g data-mml-node="mfrac" transform="translate(4154,0)"><g data-mml-node="mi" transform="translate(225.3,394) scale(0.707)"><path data-c="1D463" d="M173 380Q173 405 154 405Q130 405 104 376T61 287Q60 286 59 284T58 281T56 279T53 278T49 278T41 278H27Q21 284 21 287Q21 294 29 316T53 368T97 419T160 441Q202 441 225 417T249 361Q249 344 246 335Q246 329 231 291T200 202T182 113Q182 86 187 69Q200 26 250 26Q287 26 319 60T369 139T398 222T409 277Q409 300 401 317T383 343T365 361T357 383Q357 405 376 424T417 443Q436 443 451 425T467 367Q467 340 455 284T418 159T347 40T241 -11Q177 -11 139 22Q102 54 102 117Q102 148 110 181T151 298Q173 362 173 380Z"></path></g><g data-mml-node="mn" transform="translate(220,-345) scale(0.707)"><path data-c="32" d="M109 429Q82 429 66 447T50 491Q50 562 103 614T235 666Q326 666 387 610T449 465Q449 422 429 383T381 315T301 241Q265 210 201 149L142 93L218 92Q375 92 385 97Q392 99 409 186V189H449V186Q448 183 436 95T421 3V0H50V19V31Q50 38 56 46T86 81Q115 113 136 137Q145 147 170 174T204 211T233 244T261 278T284 308T305 340T320 369T333 401T340 431T343 464Q343 527 309 573T212 619Q179 619 154 602T119 569T109 550Q109 549 114 549Q132 549 151 535T170 489Q170 464 154 447T109 429Z"></path></g><rect width="553.6" height="60" x="120" y="220"></rect></g><g data-mml-node="mo" transform="translate(4947.6,0)"><path data-c="29" d="M60 749L64 750Q69 750 74 750H86L114 726Q208 641 251 514T294 250Q294 182 284 119T261 12T224 -76T186 -143T145 -194T113 -227T90 -246Q87 -249 86 -250H74Q66 -250 63 -250T58 -247T55 -238Q56 -237 66 -225Q221 -64 221 250T66 725Q56 737 55 738Q55 746 60 749Z"></path></g><g data-mml-node="mo" transform="translate(5336.6,0)"><path data-c="29" d="M60 749L64 750Q69 750 74 750H86L114 726Q208 641 251 514T294 250Q294 182 284 119T261 12T224 -76T186 -143T145 -194T113 -227T90 -246Q87 -249 86 -250H74Q66 -250 63 -250T58 -247T55 -238Q56 -237 66 -225Q221 -64 221 250T66 725Q56 737 55 738Q55 746 60 749Z"></path></g><g data-mml-node="mo" transform="translate(5947.8,0)"><path data-c="2B" d="M56 237T56 250T70 270H369V420L370 570Q380 583 389 583Q402 583 409 568V270H707Q722 262 722 250T707 230H409V-68Q401 -82 391 -82H389H387Q375 -82 369 -68V230H70Q56 237 56 250Z"></path></g><g data-mml-node="mi" transform="translate(6948,0)"><path data-c="6C" d="M42 46H56Q95 46 103 60V68Q103 77 103 91T103 124T104 167T104 217T104 272T104 329Q104 366 104 407T104 482T104 542T103 586T103 603Q100 622 89 628T44 637H26V660Q26 683 28 683L38 684Q48 685 67 686T104 688Q121 689 141 690T171 693T182 694H185V379Q185 62 186 60Q190 52 198 49Q219 46 247 46H263V0H255L232 1Q209 2 183 2T145 3T107 3T57 1L34 0H26V46H42Z"></path><path data-c="6E" d="M41 46H55Q94 46 102 60V68Q102 77 102 91T102 122T103 161T103 203Q103 234 103 269T102 328V351Q99 370 88 376T43 385H25V408Q25 431 27 431L37 432Q47 433 65 434T102 436Q119 437 138 438T167 441T178 442H181V402Q181 364 182 364T187 369T199 384T218 402T247 421T285 437Q305 442 336 442Q450 438 463 329Q464 322 464 190V104Q464 66 466 59T477 49Q498 46 526 46H542V0H534L510 1Q487 2 460 2T422 3Q319 3 310 0H302V46H318Q379 46 379 62Q380 64 380 200Q379 335 378 343Q372 371 358 385T334 402T308 404Q263 404 229 370Q202 343 195 315T187 232V168V108Q187 78 188 68T191 55T200 49Q221 46 249 46H265V0H257L234 1Q210 2 183 2T145 3Q42 3 33 0H25V46H41Z" transform="translate(278,0)"></path></g><g data-mml-node="mo" transform="translate(7782,0)"><path data-c="2061" d=""></path></g><g data-mml-node="mo" transform="translate(7782,0)"><path data-c="28" d="M94 250Q94 319 104 381T127 488T164 576T202 643T244 695T277 729T302 750H315H319Q333 750 333 741Q333 738 316 720T275 667T226 581T184 443T167 250T184 58T225 -81T274 -167T316 -220T333 -241Q333 -250 318 -250H315H302L274 -226Q180 -141 137 -14T94 250Z"></path></g><g data-mml-node="mi" transform="translate(8171,0)"><path data-c="393" d="M128 619Q121 626 117 628T101 631T58 634H25V680H554V676Q556 670 568 560T582 444V440H542V444Q542 445 538 478T523 545T492 598Q454 634 349 634H334Q264 634 249 633T233 621Q232 618 232 339L233 61Q240 54 245 52T270 48T333 46H360V0H348Q324 3 182 3Q51 3 36 0H25V46H58Q100 47 109 49T128 61V619Z"></path></g><g data-mml-node="mo" transform="translate(8796,0)"><path data-c="28" d="M94 250Q94 319 104 381T127 488T164 576T202 643T244 695T277 729T302 750H315H319Q333 750 333 741Q333 738 316 720T275 667T226 581T184 443T167 250T184 58T225 -81T274 -167T316 -220T333 -241Q333 -250 318 -250H315H302L274 -226Q180 -141 137 -14T94 250Z"></path></g><g data-mml-node="mn" transform="translate(9185,0)"><path data-c="30" d="M96 585Q152 666 249 666Q297 666 345 640T423 548Q460 465 460 320Q460 165 417 83Q397 41 362 16T301 -15T250 -22Q224 -22 198 -16T137 16T82 83Q39 165 39 320Q39 494 96 585ZM321 597Q291 629 250 629Q208 629 178 597Q153 571 145 525T137 333Q137 175 145 125T181 46Q209 16 250 16Q290 16 318 46Q347 76 354 130T362 333Q362 478 354 524T321 597Z"></path><path data-c="2E" d="M78 60Q78 84 95 102T138 120Q162 120 180 104T199 61Q199 36 182 18T139 0T96 17T78 60Z" transform="translate(500,0)"></path><path data-c="35" d="M164 157Q164 133 148 117T109 101H102Q148 22 224 22Q294 22 326 82Q345 115 345 210Q345 313 318 349Q292 382 260 382H254Q176 382 136 314Q132 307 129 306T114 304Q97 304 95 310Q93 314 93 485V614Q93 664 98 664Q100 666 102 666Q103 666 123 658T178 642T253 634Q324 634 389 662Q397 666 402 666Q410 666 410 648V635Q328 538 205 538Q174 538 149 544L139 546V374Q158 388 169 396T205 412T256 420Q337 420 393 355T449 201Q449 109 385 44T229 -22Q148 -22 99 32T50 154Q50 178 61 192T84 210T107 214Q132 214 148 197T164 157Z" transform="translate(778,0)"></path></g><g data-mml-node="mo" transform="translate(10463,0)"><path data-c="29" d="M60 749L64 750Q69 750 74 750H86L114 726Q208 641 251 514T294 250Q294 182 284 119T261 12T224 -76T186 -143T145 -194T113 -227T90 -246Q87 -249 86 -250H74Q66 -250 63 -250T58 -247T55 -238Q56 -237 66 -225Q221 -64 221 250T66 725Q56 737 55 738Q55 746 60 749Z"></path></g><g data-mml-node="mo" transform="translate(10852,0)"><path data-c="29" d="M60 749L64 750Q69 750 74 750H86L114 726Q208 641 251 514T294 250Q294 182 284 119T261 12T224 -76T186 -143T145 -194T113 -227T90 -246Q87 -249 86 -250H74Q66 -250 63 -250T58 -247T55 -238Q56 -237 66 -225Q221 -64 221 250T66 725Q56 737 55 738Q55 746 60 749Z"></path></g><g data-mml-node="mo" transform="translate(11463.2,0)"><path data-c="2B" d="M56 237T56 250T70 270H369V420L370 570Q380 583 389 583Q402 583 409 568V270H707Q722 262 722 250T707 230H409V-68Q401 -82 391 -82H389H387Q375 -82 369 -68V230H70Q56 237 56 250Z"></path></g><g data-mml-node="mi" transform="translate(12463.4,0)"><path data-c="6C" d="M42 46H56Q95 46 103 60V68Q103 77 103 91T103 124T104 167T104 217T104 272T104 329Q104 366 104 407T104 482T104 542T103 586T103 603Q100 622 89 628T44 637H26V660Q26 683 28 683L38 684Q48 685 67 686T104 688Q121 689 141 690T171 693T182 694H185V379Q185 62 186 60Q190 52 198 49Q219 46 247 46H263V0H255L232 1Q209 2 183 2T145 3T107 3T57 1L34 0H26V46H42Z"></path><path data-c="6E" d="M41 46H55Q94 46 102 60V68Q102 77 102 91T102 122T103 161T103 203Q103 234 103 269T102 328V351Q99 370 88 376T43 385H25V408Q25 431 27 431L37 432Q47 433 65 434T102 436Q119 437 138 438T167 441T178 442H181V402Q181 364 182 364T187 369T199 384T218 402T247 421T285 437Q305 442 336 442Q450 438 463 329Q464 322 464 190V104Q464 66 466 59T477 49Q498 46 526 46H542V0H534L510 1Q487 2 460 2T422 3Q319 3 310 0H302V46H318Q379 46 379 62Q380 64 380 200Q379 335 378 343Q372 371 358 385T334 402T308 404Q263 404 229 370Q202 343 195 315T187 232V168V108Q187 78 188 68T191 55T200 49Q221 46 249 46H265V0H257L234 1Q210 2 183 2T145 3Q42 3 33 0H25V46H41Z" transform="translate(278,0)"></path></g><g data-mml-node="mo" transform="translate(13297.4,0)"><path data-c="2061" d=""></path></g><g data-mml-node="mo" transform="translate(13297.4,0)"><path data-c="28" d="M94 250Q94 319 104 381T127 488T164 576T202 643T244 695T277 729T302 750H315H319Q333 750 333 741Q333 738 316 720T275 667T226 581T184 443T167 250T184 58T225 -81T274 -167T316 -220T333 -241Q333 -250 318 -250H315H302L274 -226Q180 -141 137 -14T94 250Z"></path></g><g data-mml-node="mi" transform="translate(13686.4,0)"><path data-c="393" d="M128 619Q121 626 117 628T101 631T58 634H25V680H554V676Q556 670 568 560T582 444V440H542V444Q542 445 538 478T523 545T492 598Q454 634 349 634H334Q264 634 249 633T233 621Q232 618 232 339L233 61Q240 54 245 52T270 48T333 46H360V0H348Q324 3 182 3Q51 3 36 0H25V46H58Q100 47 109 49T128 61V619Z"></path></g><g data-mml-node="mo" transform="translate(14311.4,0)"><path data-c="28" d="M94 250Q94 319 104 381T127 488T164 576T202 643T244 695T277 729T302 750H315H319Q333 750 333 741Q333 738 316 720T275 667T226 581T184 443T167 250T184 58T225 -81T274 -167T316 -220T333 -241Q333 -250 318 -250H315H302L274 -226Q180 -141 137 -14T94 250Z"></path></g><g data-mml-node="mfrac" transform="translate(14700.4,0)"><g data-mml-node="mi" transform="translate(225.3,394) scale(0.707)"><path data-c="1D463" d="M173 380Q173 405 154 405Q130 405 104 376T61 287Q60 286 59 284T58 281T56 279T53 278T49 278T41 278H27Q21 284 21 287Q21 294 29 316T53 368T97 419T160 441Q202 441 225 417T249 361Q249 344 246 335Q246 329 231 291T200 202T182 113Q182 86 187 69Q200 26 250 26Q287 26 319 60T369 139T398 222T409 277Q409 300 401 317T383 343T365 361T357 383Q357 405 376 424T417 443Q436 443 451 425T467 367Q467 340 455 284T418 159T347 40T241 -11Q177 -11 139 22Q102 54 102 117Q102 148 110 181T151 298Q173 362 173 380Z"></path></g><g data-mml-node="mn" transform="translate(220,-345) scale(0.707)"><path data-c="32" d="M109 429Q82 429 66 447T50 491Q50 562 103 614T235 666Q326 666 387 610T449 465Q449 422 429 383T381 315T301 241Q265 210 201 149L142 93L218 92Q375 92 385 97Q392 99 409 186V189H449V186Q448 183 436 95T421 3V0H50V19V31Q50 38 56 46T86 81Q115 113 136 137Q145 147 170 174T204 211T233 244T261 278T284 308T305 340T320 369T333 401T340 431T343 464Q343 527 309 573T212 619Q179 619 154 602T119 569T109 550Q109 549 114 549Q132 549 151 535T170 489Q170 464 154 447T109 429Z"></path></g><rect width="553.6" height="60" x="120" y="220"></rect></g><g data-mml-node="mo" transform="translate(15716.2,0)"><path data-c="2B" d="M56 237T56 250T70 270H369V420L370 570Q380 583 389 583Q402 583 409 568V270H707Q722 262 722 250T707 230H409V-68Q401 -82 391 -82H389H387Q375 -82 369 -68V230H70Q56 237 56 250Z"></path></g><g data-mml-node="mn" transform="translate(16716.4,0)"><path data-c="30" d="M96 585Q152 666 249 666Q297 666 345 640T423 548Q460 465 460 320Q460 165 417 83Q397 41 362 16T301 -15T250 -22Q224 -22 198 -16T137 16T82 83Q39 165 39 320Q39 494 96 585ZM321 597Q291 629 250 629Q208 629 178 597Q153 571 145 525T137 333Q137 175 145 125T181 46Q209 16 250 16Q290 16 318 46Q347 76 354 130T362 333Q362 478 354 524T321 597Z"></path><path data-c="2E" d="M78 60Q78 84 95 102T138 120Q162 120 180 104T199 61Q199 36 182 18T139 0T96 17T78 60Z" transform="translate(500,0)"></path><path data-c="35" d="M164 157Q164 133 148 117T109 101H102Q148 22 224 22Q294 22 326 82Q345 115 345 210Q345 313 318 349Q292 382 260 382H254Q176 382 136 314Q132 307 129 306T114 304Q97 304 95 310Q93 314 93 485V614Q93 664 98 664Q100 666 102 666Q103 666 123 658T178 642T253 634Q324 634 389 662Q397 666 402 666Q410 666 410 648V635Q328 538 205 538Q174 538 149 544L139 546V374Q158 388 169 396T205 412T256 420Q337 420 393 355T449 201Q449 109 385 44T229 -22Q148 -22 99 32T50 154Q50 178 61 192T84 210T107 214Q132 214 148 197T164 157Z" transform="translate(778,0)"></path></g><g data-mml-node="mo" transform="translate(17994.4,0)"><path data-c="29" d="M60 749L64 750Q69 750 74 750H86L114 726Q208 641 251 514T294 250Q294 182 284 119T261 12T224 -76T186 -143T145 -194T113 -227T90 -246Q87 -249 86 -250H74Q66 -250 63 -250T58 -247T55 -238Q56 -237 66 -225Q221 -64 221 250T66 725Q56 737 55 738Q55 746 60 749Z"></path></g><g data-mml-node="mo" transform="translate(18383.4,0)"><path data-c="29" d="M60 749L64 750Q69 750 74 750H86L114 726Q208 641 251 514T294 250Q294 182 284 119T261 12T224 -76T186 -143T145 -194T113 -227T90 -246Q87 -249 86 -250H74Q66 -250 63 -250T58 -247T55 -238Q56 -237 66 -225Q221 -64 221 250T66 725Q56 737 55 738Q55 746 60 749Z"></path></g><g data-mml-node="mo" transform="translate(18772.4,0)"><path data-c="29" d="M60 749L64 750Q69 750 74 750H86L114 726Q208 641 251 514T294 250Q294 182 284 119T261 12T224 -76T186 -143T145 -194T113 -227T90 -246Q87 -249 86 -250H74Q66 -250 63 -250T58 -247T55 -238Q56 -237 66 -225Q221 -64 221 250T66 725Q56 737 55 738Q55 746 60 749Z"></path></g></g><rect width="19361.4" height="60" x="120" y="220"></rect></g></g></g></svg></mjx-container></span></p> <p>CDF を用いて p 値を求める。両側検定をするので 2 を掛ける。t 分布の自由度 (degree of freedom; df) は<span class="math inline"><mjx-container class="MathJax" jax="SVG"><svg style="vertical-align: -0.186ex;" xmlns="http://www.w3.org/2000/svg" width="5.254ex" height="1.692ex" role="img" focusable="false" viewBox="0 -666 2322.4 748"><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="mi"><path data-c="1D45B" d="M21 287Q22 293 24 303T36 341T56 388T89 425T135 442Q171 442 195 424T225 390T231 369Q231 367 232 367L243 378Q304 442 382 442Q436 442 469 415T503 336T465 179T427 52Q427 26 444 26Q450 26 453 27Q482 32 505 65T540 145Q542 153 560 153Q580 153 580 145Q580 144 576 130Q568 101 554 73T508 17T439 -10Q392 -10 371 17T350 73Q350 92 386 193T423 345Q423 404 379 404H374Q288 404 229 303L222 291L189 157Q156 26 151 16Q138 -11 108 -11Q95 -11 87 -5T76 7T74 17Q74 30 112 180T152 343Q153 348 153 366Q153 405 129 405Q91 405 66 305Q60 285 60 284Q58 278 41 278H27Q21 284 21 287Z"></path></g><g data-mml-node="mo" transform="translate(822.2,0)"><path data-c="2212" d="M84 237T84 250T98 270H679Q694 262 694 250T679 230H98Q84 237 84 250Z"></path></g><g data-mml-node="mn" transform="translate(1822.4,0)"><path data-c="31" d="M213 578L200 573Q186 568 160 563T102 556H83V602H102Q149 604 189 617T245 641T273 663Q275 666 285 666Q294 666 302 660V361L303 61Q310 54 315 52T339 48T401 46H427V0H416Q395 3 257 3Q121 3 100 0H88V46H114Q136 46 152 46T177 47T193 50T201 52T207 57T213 61V578Z"></path></g></g></g></svg></mjx-container></span>なので、両分布の自由度を<span class="math inline"><mjx-container class="MathJax" jax="SVG"><svg style="vertical-align: -0.339ex;" xmlns="http://www.w3.org/2000/svg" width="12.337ex" height="1.846ex" role="img" focusable="false" viewBox="0 -666 5452.9 816"><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="msub"><g data-mml-node="mi"><path data-c="1D45B" d="M21 287Q22 293 24 303T36 341T56 388T89 425T135 442Q171 442 195 424T225 390T231 369Q231 367 232 367L243 378Q304 442 382 442Q436 442 469 415T503 336T465 179T427 52Q427 26 444 26Q450 26 453 27Q482 32 505 65T540 145Q542 153 560 153Q580 153 580 145Q580 144 576 130Q568 101 554 73T508 17T439 -10Q392 -10 371 17T350 73Q350 92 386 193T423 345Q423 404 379 404H374Q288 404 229 303L222 291L189 157Q156 26 151 16Q138 -11 108 -11Q95 -11 87 -5T76 7T74 17Q74 30 112 180T152 343Q153 348 153 366Q153 405 129 405Q91 405 66 305Q60 285 60 284Q58 278 41 278H27Q21 284 21 287Z"></path></g><g data-mml-node="mi" transform="translate(633,-150) scale(0.707)"><path data-c="1D44B" d="M42 0H40Q26 0 26 11Q26 15 29 27Q33 41 36 43T55 46Q141 49 190 98Q200 108 306 224T411 342Q302 620 297 625Q288 636 234 637H206Q200 643 200 645T202 664Q206 677 212 683H226Q260 681 347 681Q380 681 408 681T453 682T473 682Q490 682 490 671Q490 670 488 658Q484 643 481 640T465 637Q434 634 411 620L488 426L541 485Q646 598 646 610Q646 628 622 635Q617 635 609 637Q594 637 594 648Q594 650 596 664Q600 677 606 683H618Q619 683 643 683T697 681T738 680Q828 680 837 683H845Q852 676 852 672Q850 647 840 637H824Q790 636 763 628T722 611T698 593L687 584Q687 585 592 480L505 384Q505 383 536 304T601 142T638 56Q648 47 699 46Q734 46 734 37Q734 35 732 23Q728 7 725 4T711 1Q708 1 678 1T589 2Q528 2 496 2T461 1Q444 1 444 10Q444 11 446 25Q448 35 450 39T455 44T464 46T480 47T506 54Q523 62 523 64Q522 64 476 181L429 299Q241 95 236 84Q232 76 232 72Q232 53 261 47Q262 47 267 47T273 46Q276 46 277 46T280 45T283 42T284 35Q284 26 282 19Q279 6 276 4T261 1Q258 1 243 1T201 2T142 2Q64 2 42 0Z"></path></g></g><g data-mml-node="mo" transform="translate(1507.7,0)"><path data-c="2B" d="M56 237T56 250T70 270H369V420L370 570Q380 583 389 583Q402 583 409 568V270H707Q722 262 722 250T707 230H409V-68Q401 -82 391 -82H389H387Q375 -82 369 -68V230H70Q56 237 56 250Z"></path></g><g data-mml-node="msub" transform="translate(2507.9,0)"><g data-mml-node="mi"><path data-c="1D45B" d="M21 287Q22 293 24 303T36 341T56 388T89 425T135 442Q171 442 195 424T225 390T231 369Q231 367 232 367L243 378Q304 442 382 442Q436 442 469 415T503 336T465 179T427 52Q427 26 444 26Q450 26 453 27Q482 32 505 65T540 145Q542 153 560 153Q580 153 580 145Q580 144 576 130Q568 101 554 73T508 17T439 -10Q392 -10 371 17T350 73Q350 92 386 193T423 345Q423 404 379 404H374Q288 404 229 303L222 291L189 157Q156 26 151 16Q138 -11 108 -11Q95 -11 87 -5T76 7T74 17Q74 30 112 180T152 343Q153 348 153 366Q153 405 129 405Q91 405 66 305Q60 285 60 284Q58 278 41 278H27Q21 284 21 287Z"></path></g><g data-mml-node="mi" transform="translate(633,-150) scale(0.707)"><path data-c="1D44C" d="M66 637Q54 637 49 637T39 638T32 641T30 647T33 664T42 682Q44 683 56 683Q104 680 165 680Q288 680 306 683H316Q322 677 322 674T320 656Q316 643 310 637H298Q242 637 242 624Q242 619 292 477T343 333L346 336Q350 340 358 349T379 373T411 410T454 461Q546 568 561 587T577 618Q577 634 545 637Q528 637 528 647Q528 649 530 661Q533 676 535 679T549 683Q551 683 578 682T657 680Q684 680 713 681T746 682Q763 682 763 673Q763 669 760 657T755 643Q753 637 734 637Q662 632 617 587Q608 578 477 424L348 273L322 169Q295 62 295 57Q295 46 363 46Q379 46 384 45T390 35Q390 33 388 23Q384 6 382 4T366 1Q361 1 324 1T232 2Q170 2 138 2T102 1Q84 1 84 9Q84 14 87 24Q88 27 89 30T90 35T91 39T93 42T96 44T101 45T107 45T116 46T129 46Q168 47 180 50T198 63Q201 68 227 171L252 274L129 623Q128 624 127 625T125 627T122 629T118 631T113 633T105 634T96 635T83 636T66 637Z"></path></g></g><g data-mml-node="mo" transform="translate(3952.6,0)"><path data-c="2212" d="M84 237T84 250T98 270H679Q694 262 694 250T679 230H98Q84 237 84 250Z"></path></g><g data-mml-node="mn" transform="translate(4952.9,0)"><path data-c="32" d="M109 429Q82 429 66 447T50 491Q50 562 103 614T235 666Q326 666 387 610T449 465Q449 422 429 383T381 315T301 241Q265 210 201 149L142 93L218 92Q375 92 385 97Q392 99 409 186V189H449V186Q448 183 436 95T421 3V0H50V19V31Q50 38 56 46T86 81Q115 113 136 137Q145 147 170 174T204 211T233 244T261 278T284 308T305 340T320 369T333 401T340 431T343 464Q343 527 309 573T212 619Q179 619 154 602T119 569T109 550Q109 549 114 549Q132 549 151 535T170 489Q170 464 154 447T109 429Z"></path></g></g></g></svg></mjx-container></span>で与える。本当は</p> <p><span class="math display"><mjx-container class="MathJax" jax="SVG" display="true"><svg style="vertical-align: -3.513ex;" xmlns="http://www.w3.org/2000/svg" width="18.821ex" height="7.006ex" role="img" focusable="false" viewBox="0 -1543.9 8318.8 3096.8"><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="mtext"><path data-c="64" d="M376 495Q376 511 376 535T377 568Q377 613 367 624T316 637H298V660Q298 683 300 683L310 684Q320 685 339 686T376 688Q393 689 413 690T443 693T454 694H457V390Q457 84 458 81Q461 61 472 55T517 46H535V0Q533 0 459 -5T380 -11H373V44L365 37Q307 -11 235 -11Q158 -11 96 50T34 215Q34 315 97 378T244 442Q319 442 376 393V495ZM373 342Q328 405 260 405Q211 405 173 369Q146 341 139 305T131 211Q131 155 138 120T173 59Q203 26 251 26Q322 26 373 103V342Z"></path><path data-c="66" d="M273 0Q255 3 146 3Q43 3 34 0H26V46H42Q70 46 91 49Q99 52 103 60Q104 62 104 224V385H33V431H104V497L105 564L107 574Q126 639 171 668T266 704Q267 704 275 704T289 705Q330 702 351 679T372 627Q372 604 358 590T321 576T284 590T270 627Q270 647 288 667H284Q280 668 273 668Q245 668 223 647T189 592Q183 572 182 497V431H293V385H185V225Q185 63 186 61T189 57T194 54T199 51T206 49T213 48T222 47T231 47T241 46T251 46H282V0H273Z" transform="translate(556,0)"></path></g><g data-mml-node="mo" transform="translate(1139.8,0)"><path data-c="3D" d="M56 347Q56 360 70 367H707Q722 359 722 347Q722 336 708 328L390 327H72Q56 332 56 347ZM56 153Q56 168 72 173H708Q722 163 722 153Q722 140 707 133H70Q56 140 56 153Z"></path></g><g data-mml-node="mfrac" transform="translate(2195.6,0)"><g data-mml-node="mrow" transform="translate(618.1,710)"><g data-mml-node="mo"><path data-c="28" d="M94 250Q94 319 104 381T127 488T164 576T202 643T244 695T277 729T302 750H315H319Q333 750 333 741Q333 738 316 720T275 667T226 581T184 443T167 250T184 58T225 -81T274 -167T316 -220T333 -241Q333 -250 318 -250H315H302L274 -226Q180 -141 137 -14T94 250Z"></path></g><g data-mml-node="msub" transform="translate(389,0)"><g data-mml-node="mi"><path data-c="1D70E" d="M184 -11Q116 -11 74 34T31 147Q31 247 104 333T274 430Q275 431 414 431H552Q553 430 555 429T559 427T562 425T565 422T567 420T569 416T570 412T571 407T572 401Q572 357 507 357Q500 357 490 357T476 358H416L421 348Q439 310 439 263Q439 153 359 71T184 -11ZM361 278Q361 358 276 358Q152 358 115 184Q114 180 114 178Q106 141 106 117Q106 67 131 47T188 26Q242 26 287 73Q316 103 334 153T356 233T361 278Z"></path></g><g data-mml-node="mi" transform="translate(604,-150) scale(0.707)"><path data-c="1D44B" d="M42 0H40Q26 0 26 11Q26 15 29 27Q33 41 36 43T55 46Q141 49 190 98Q200 108 306 224T411 342Q302 620 297 625Q288 636 234 637H206Q200 643 200 645T202 664Q206 677 212 683H226Q260 681 347 681Q380 681 408 681T453 682T473 682Q490 682 490 671Q490 670 488 658Q484 643 481 640T465 637Q434 634 411 620L488 426L541 485Q646 598 646 610Q646 628 622 635Q617 635 609 637Q594 637 594 648Q594 650 596 664Q600 677 606 683H618Q619 683 643 683T697 681T738 680Q828 680 837 683H845Q852 676 852 672Q850 647 840 637H824Q790 636 763 628T722 611T698 593L687 584Q687 585 592 480L505 384Q505 383 536 304T601 142T638 56Q648 47 699 46Q734 46 734 37Q734 35 732 23Q728 7 725 4T711 1Q708 1 678 1T589 2Q528 2 496 2T461 1Q444 1 444 10Q444 11 446 25Q448 35 450 39T455 44T464 46T480 47T506 54Q523 62 523 64Q522 64 476 181L429 299Q241 95 236 84Q232 76 232 72Q232 53 261 47Q262 47 267 47T273 46Q276 46 277 46T280 45T283 42T284 35Q284 26 282 19Q279 6 276 4T261 1Q258 1 243 1T201 2T142 2Q64 2 42 0Z"></path></g></g><g data-mml-node="mo" transform="translate(1867.7,0)"><path data-c="2B" d="M56 237T56 250T70 270H369V420L370 570Q380 583 389 583Q402 583 409 568V270H707Q722 262 722 250T707 230H409V-68Q401 -82 391 -82H389H387Q375 -82 369 -68V230H70Q56 237 56 250Z"></path></g><g data-mml-node="msub" transform="translate(2867.9,0)"><g data-mml-node="mi"><path data-c="1D70E" d="M184 -11Q116 -11 74 34T31 147Q31 247 104 333T274 430Q275 431 414 431H552Q553 430 555 429T559 427T562 425T565 422T567 420T569 416T570 412T571 407T572 401Q572 357 507 357Q500 357 490 357T476 358H416L421 348Q439 310 439 263Q439 153 359 71T184 -11ZM361 278Q361 358 276 358Q152 358 115 184Q114 180 114 178Q106 141 106 117Q106 67 131 47T188 26Q242 26 287 73Q316 103 334 153T356 233T361 278Z"></path></g><g data-mml-node="mi" transform="translate(604,-150) scale(0.707)"><path data-c="1D44C" d="M66 637Q54 637 49 637T39 638T32 641T30 647T33 664T42 682Q44 683 56 683Q104 680 165 680Q288 680 306 683H316Q322 677 322 674T320 656Q316 643 310 637H298Q242 637 242 624Q242 619 292 477T343 333L346 336Q350 340 358 349T379 373T411 410T454 461Q546 568 561 587T577 618Q577 634 545 637Q528 637 528 647Q528 649 530 661Q533 676 535 679T549 683Q551 683 578 682T657 680Q684 680 713 681T746 682Q763 682 763 673Q763 669 760 657T755 643Q753 637 734 637Q662 632 617 587Q608 578 477 424L348 273L322 169Q295 62 295 57Q295 46 363 46Q379 46 384 45T390 35Q390 33 388 23Q384 6 382 4T366 1Q361 1 324 1T232 2Q170 2 138 2T102 1Q84 1 84 9Q84 14 87 24Q88 27 89 30T90 35T91 39T93 42T96 44T101 45T107 45T116 46T129 46Q168 47 180 50T198 63Q201 68 227 171L252 274L129 623Q128 624 127 625T125 627T122 629T118 631T113 633T105 634T96 635T83 636T66 637Z"></path></g></g><g data-mml-node="msup" transform="translate(4061.4,0)"><g data-mml-node="mo"><path data-c="29" d="M60 749L64 750Q69 750 74 750H86L114 726Q208 641 251 514T294 250Q294 182 284 119T261 12T224 -76T186 -143T145 -194T113 -227T90 -246Q87 -249 86 -250H74Q66 -250 63 -250T58 -247T55 -238Q56 -237 66 -225Q221 -64 221 250T66 725Q56 737 55 738Q55 746 60 749Z"></path></g><g data-mml-node="mn" transform="translate(422,363) scale(0.707)"><path data-c="32" d="M109 429Q82 429 66 447T50 491Q50 562 103 614T235 666Q326 666 387 610T449 465Q449 422 429 383T381 315T301 241Q265 210 201 149L142 93L218 92Q375 92 385 97Q392 99 409 186V189H449V186Q448 183 436 95T421 3V0H50V19V31Q50 38 56 46T86 81Q115 113 136 137Q145 147 170 174T204 211T233 244T261 278T284 308T305 340T320 369T333 401T340 431T343 464Q343 527 309 573T212 619Q179 619 154 602T119 569T109 550Q109 549 114 549Q132 549 151 535T170 489Q170 464 154 447T109 429Z"></path></g></g></g><g data-mml-node="mrow" transform="translate(220,-1101.8)"><g data-mml-node="mfrac"><g data-mml-node="msubsup" transform="translate(682.1,558.7) scale(0.707)"><g data-mml-node="mi"><path data-c="1D70E" d="M184 -11Q116 -11 74 34T31 147Q31 247 104 333T274 430Q275 431 414 431H552Q553 430 555 429T559 427T562 425T565 422T567 420T569 416T570 412T571 407T572 401Q572 357 507 357Q500 357 490 357T476 358H416L421 348Q439 310 439 263Q439 153 359 71T184 -11ZM361 278Q361 358 276 358Q152 358 115 184Q114 180 114 178Q106 141 106 117Q106 67 131 47T188 26Q242 26 287 73Q316 103 334 153T356 233T361 278Z"></path></g><g data-mml-node="mn" transform="translate(604,353.6) scale(0.707)"><path data-c="32" d="M109 429Q82 429 66 447T50 491Q50 562 103 614T235 666Q326 666 387 610T449 465Q449 422 429 383T381 315T301 241Q265 210 201 149L142 93L218 92Q375 92 385 97Q392 99 409 186V189H449V186Q448 183 436 95T421 3V0H50V19V31Q50 38 56 46T86 81Q115 113 136 137Q145 147 170 174T204 211T233 244T261 278T284 308T305 340T320 369T333 401T340 431T343 464Q343 527 309 573T212 619Q179 619 154 602T119 569T109 550Q109 549 114 549Q132 549 151 535T170 489Q170 464 154 447T109 429Z"></path></g><g data-mml-node="mi" transform="translate(604,-309.4) scale(0.707)"><path data-c="1D44B" d="M42 0H40Q26 0 26 11Q26 15 29 27Q33 41 36 43T55 46Q141 49 190 98Q200 108 306 224T411 342Q302 620 297 625Q288 636 234 637H206Q200 643 200 645T202 664Q206 677 212 683H226Q260 681 347 681Q380 681 408 681T453 682T473 682Q490 682 490 671Q490 670 488 658Q484 643 481 640T465 637Q434 634 411 620L488 426L541 485Q646 598 646 610Q646 628 622 635Q617 635 609 637Q594 637 594 648Q594 650 596 664Q600 677 606 683H618Q619 683 643 683T697 681T738 680Q828 680 837 683H845Q852 676 852 672Q850 647 840 637H824Q790 636 763 628T722 611T698 593L687 584Q687 585 592 480L505 384Q505 383 536 304T601 142T638 56Q648 47 699 46Q734 46 734 37Q734 35 732 23Q728 7 725 4T711 1Q708 1 678 1T589 2Q528 2 496 2T461 1Q444 1 444 10Q444 11 446 25Q448 35 450 39T455 44T464 46T480 47T506 54Q523 62 523 64Q522 64 476 181L429 299Q241 95 236 84Q232 76 232 72Q232 53 261 47Q262 47 267 47T273 46Q276 46 277 46T280 45T283 42T284 35Q284 26 282 19Q279 6 276 4T261 1Q258 1 243 1T201 2T142 2Q64 2 42 0Z"></path></g></g><g data-mml-node="mrow" transform="translate(220,-345) scale(0.707)"><g data-mml-node="msub"><g data-mml-node="mi"><path data-c="1D45B" d="M21 287Q22 293 24 303T36 341T56 388T89 425T135 442Q171 442 195 424T225 390T231 369Q231 367 232 367L243 378Q304 442 382 442Q436 442 469 415T503 336T465 179T427 52Q427 26 444 26Q450 26 453 27Q482 32 505 65T540 145Q542 153 560 153Q580 153 580 145Q580 144 576 130Q568 101 554 73T508 17T439 -10Q392 -10 371 17T350 73Q350 92 386 193T423 345Q423 404 379 404H374Q288 404 229 303L222 291L189 157Q156 26 151 16Q138 -11 108 -11Q95 -11 87 -5T76 7T74 17Q74 30 112 180T152 343Q153 348 153 366Q153 405 129 405Q91 405 66 305Q60 285 60 284Q58 278 41 278H27Q21 284 21 287Z"></path></g><g data-mml-node="mi" transform="translate(633,-150) scale(0.707)"><path data-c="1D44B" d="M42 0H40Q26 0 26 11Q26 15 29 27Q33 41 36 43T55 46Q141 49 190 98Q200 108 306 224T411 342Q302 620 297 625Q288 636 234 637H206Q200 643 200 645T202 664Q206 677 212 683H226Q260 681 347 681Q380 681 408 681T453 682T473 682Q490 682 490 671Q490 670 488 658Q484 643 481 640T465 637Q434 634 411 620L488 426L541 485Q646 598 646 610Q646 628 622 635Q617 635 609 637Q594 637 594 648Q594 650 596 664Q600 677 606 683H618Q619 683 643 683T697 681T738 680Q828 680 837 683H845Q852 676 852 672Q850 647 840 637H824Q790 636 763 628T722 611T698 593L687 584Q687 585 592 480L505 384Q505 383 536 304T601 142T638 56Q648 47 699 46Q734 46 734 37Q734 35 732 23Q728 7 725 4T711 1Q708 1 678 1T589 2Q528 2 496 2T461 1Q444 1 444 10Q444 11 446 25Q448 35 450 39T455 44T464 46T480 47T506 54Q523 62 523 64Q522 64 476 181L429 299Q241 95 236 84Q232 76 232 72Q232 53 261 47Q262 47 267 47T273 46Q276 46 277 46T280 45T283 42T284 35Q284 26 282 19Q279 6 276 4T261 1Q258 1 243 1T201 2T142 2Q64 2 42 0Z"></path></g></g><g data-mml-node="mo" transform="translate(1285.5,0)"><path data-c="2212" d="M84 237T84 250T98 270H679Q694 262 694 250T679 230H98Q84 237 84 250Z"></path></g><g data-mml-node="mn" transform="translate(2063.5,0)"><path data-c="31" d="M213 578L200 573Q186 568 160 563T102 556H83V602H102Q149 604 189 617T245 641T273 663Q275 666 285 666Q294 666 302 660V361L303 61Q310 54 315 52T339 48T401 46H427V0H416Q395 3 257 3Q121 3 100 0H88V46H114Q136 46 152 46T177 47T193 50T201 52T207 57T213 61V578Z"></path></g></g><rect width="2012.6" height="60" x="120" y="220"></rect></g><g data-mml-node="mo" transform="translate(2474.9,0)"><path data-c="2B" d="M56 237T56 250T70 270H369V420L370 570Q380 583 389 583Q402 583 409 568V270H707Q722 262 722 250T707 230H409V-68Q401 -82 391 -82H389H387Q375 -82 369 -68V230H70Q56 237 56 250Z"></path></g><g data-mml-node="mfrac" transform="translate(3475.1,0)"><g data-mml-node="msubsup" transform="translate(682.1,558.7) scale(0.707)"><g data-mml-node="mi"><path data-c="1D70E" d="M184 -11Q116 -11 74 34T31 147Q31 247 104 333T274 430Q275 431 414 431H552Q553 430 555 429T559 427T562 425T565 422T567 420T569 416T570 412T571 407T572 401Q572 357 507 357Q500 357 490 357T476 358H416L421 348Q439 310 439 263Q439 153 359 71T184 -11ZM361 278Q361 358 276 358Q152 358 115 184Q114 180 114 178Q106 141 106 117Q106 67 131 47T188 26Q242 26 287 73Q316 103 334 153T356 233T361 278Z"></path></g><g data-mml-node="mn" transform="translate(604,353.6) scale(0.707)"><path data-c="32" d="M109 429Q82 429 66 447T50 491Q50 562 103 614T235 666Q326 666 387 610T449 465Q449 422 429 383T381 315T301 241Q265 210 201 149L142 93L218 92Q375 92 385 97Q392 99 409 186V189H449V186Q448 183 436 95T421 3V0H50V19V31Q50 38 56 46T86 81Q115 113 136 137Q145 147 170 174T204 211T233 244T261 278T284 308T305 340T320 369T333 401T340 431T343 464Q343 527 309 573T212 619Q179 619 154 602T119 569T109 550Q109 549 114 549Q132 549 151 535T170 489Q170 464 154 447T109 429Z"></path></g><g data-mml-node="mi" transform="translate(604,-309.4) scale(0.707)"><path data-c="1D44C" d="M66 637Q54 637 49 637T39 638T32 641T30 647T33 664T42 682Q44 683 56 683Q104 680 165 680Q288 680 306 683H316Q322 677 322 674T320 656Q316 643 310 637H298Q242 637 242 624Q242 619 292 477T343 333L346 336Q350 340 358 349T379 373T411 410T454 461Q546 568 561 587T577 618Q577 634 545 637Q528 637 528 647Q528 649 530 661Q533 676 535 679T549 683Q551 683 578 682T657 680Q684 680 713 681T746 682Q763 682 763 673Q763 669 760 657T755 643Q753 637 734 637Q662 632 617 587Q608 578 477 424L348 273L322 169Q295 62 295 57Q295 46 363 46Q379 46 384 45T390 35Q390 33 388 23Q384 6 382 4T366 1Q361 1 324 1T232 2Q170 2 138 2T102 1Q84 1 84 9Q84 14 87 24Q88 27 89 30T90 35T91 39T93 42T96 44T101 45T107 45T116 46T129 46Q168 47 180 50T198 63Q201 68 227 171L252 274L129 623Q128 624 127 625T125 627T122 629T118 631T113 633T105 634T96 635T83 636T66 637Z"></path></g></g><g data-mml-node="mrow" transform="translate(220,-345) scale(0.707)"><g data-mml-node="msub"><g data-mml-node="mi"><path data-c="1D45B" d="M21 287Q22 293 24 303T36 341T56 388T89 425T135 442Q171 442 195 424T225 390T231 369Q231 367 232 367L243 378Q304 442 382 442Q436 442 469 415T503 336T465 179T427 52Q427 26 444 26Q450 26 453 27Q482 32 505 65T540 145Q542 153 560 153Q580 153 580 145Q580 144 576 130Q568 101 554 73T508 17T439 -10Q392 -10 371 17T350 73Q350 92 386 193T423 345Q423 404 379 404H374Q288 404 229 303L222 291L189 157Q156 26 151 16Q138 -11 108 -11Q95 -11 87 -5T76 7T74 17Q74 30 112 180T152 343Q153 348 153 366Q153 405 129 405Q91 405 66 305Q60 285 60 284Q58 278 41 278H27Q21 284 21 287Z"></path></g><g data-mml-node="mi" transform="translate(633,-150) scale(0.707)"><path data-c="1D44C" d="M66 637Q54 637 49 637T39 638T32 641T30 647T33 664T42 682Q44 683 56 683Q104 680 165 680Q288 680 306 683H316Q322 677 322 674T320 656Q316 643 310 637H298Q242 637 242 624Q242 619 292 477T343 333L346 336Q350 340 358 349T379 373T411 410T454 461Q546 568 561 587T577 618Q577 634 545 637Q528 637 528 647Q528 649 530 661Q533 676 535 679T549 683Q551 683 578 682T657 680Q684 680 713 681T746 682Q763 682 763 673Q763 669 760 657T755 643Q753 637 734 637Q662 632 617 587Q608 578 477 424L348 273L322 169Q295 62 295 57Q295 46 363 46Q379 46 384 45T390 35Q390 33 388 23Q384 6 382 4T366 1Q361 1 324 1T232 2Q170 2 138 2T102 1Q84 1 84 9Q84 14 87 24Q88 27 89 30T90 35T91 39T93 42T96 44T101 45T107 45T116 46T129 46Q168 47 180 50T198 63Q201 68 227 171L252 274L129 623Q128 624 127 625T125 627T122 629T118 631T113 633T105 634T96 635T83 636T66 637Z"></path></g></g><g data-mml-node="mo" transform="translate(1222.5,0)"><path data-c="2212" d="M84 237T84 250T98 270H679Q694 262 694 250T679 230H98Q84 237 84 250Z"></path></g><g data-mml-node="mn" transform="translate(2000.5,0)"><path data-c="31" d="M213 578L200 573Q186 568 160 563T102 556H83V602H102Q149 604 189 617T245 641T273 663Q275 666 285 666Q294 666 302 660V361L303 61Q310 54 315 52T339 48T401 46H427V0H416Q395 3 257 3Q121 3 100 0H88V46H114Q136 46 152 46T177 47T193 50T201 52T207 57T213 61V578Z"></path></g></g><rect width="1968.1" height="60" x="120" y="220"></rect></g></g><rect width="5883.2" height="60" x="120" y="220"></rect></g></g></g></svg></mjx-container></span></p> <p>で求める必要があるが、さぼって近似した。</p> <p><span class="math display"><mjx-container class="MathJax" jax="SVG" display="true"><svg style="vertical-align: -0.566ex;" xmlns="http://www.w3.org/2000/svg" width="31.829ex" height="2.262ex" role="img" focusable="false" viewBox="0 -750 14068.5 1000"><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="mi"><path data-c="1D45D" d="M23 287Q24 290 25 295T30 317T40 348T55 381T75 411T101 433T134 442Q209 442 230 378L240 387Q302 442 358 442Q423 442 460 395T497 281Q497 173 421 82T249 -10Q227 -10 210 -4Q199 1 187 11T168 28L161 36Q160 35 139 -51T118 -138Q118 -144 126 -145T163 -148H188Q194 -155 194 -157T191 -175Q188 -187 185 -190T172 -194Q170 -194 161 -194T127 -193T65 -192Q-5 -192 -24 -194H-32Q-39 -187 -39 -183Q-37 -156 -26 -148H-6Q28 -147 33 -136Q36 -130 94 103T155 350Q156 355 156 364Q156 405 131 405Q109 405 94 377T71 316T59 280Q57 278 43 278H29Q23 284 23 287ZM178 102Q200 26 252 26Q282 26 310 49T356 107Q374 141 392 215T411 325V331Q411 405 350 405Q339 405 328 402T306 393T286 380T269 365T254 350T243 336T235 326L232 322Q232 321 229 308T218 264T204 212Q178 106 178 102Z"></path></g><g data-mml-node="mo" transform="translate(780.8,0)"><path data-c="3D" d="M56 347Q56 360 70 367H707Q722 359 722 347Q722 336 708 328L390 327H72Q56 332 56 347ZM56 153Q56 168 72 173H708Q722 163 722 153Q722 140 707 133H70Q56 140 56 153Z"></path></g><g data-mml-node="mtext" transform="translate(1836.6,0)"><path data-c="43" d="M56 342Q56 428 89 500T174 615T283 681T391 705Q394 705 400 705T408 704Q499 704 569 636L582 624L612 663Q639 700 643 704Q644 704 647 704T653 705H657Q660 705 666 699V419L660 413H626Q620 419 619 430Q610 512 571 572T476 651Q457 658 426 658Q322 658 252 588Q173 509 173 342Q173 221 211 151Q232 111 263 84T328 45T384 29T428 24Q517 24 571 93T626 244Q626 251 632 257H660L666 251V236Q661 133 590 56T403 -21Q262 -21 159 83T56 342Z"></path><path data-c="44" d="M130 622Q123 629 119 631T103 634T60 637H27V683H228Q399 682 419 682T461 676Q504 667 546 641T626 573T685 470T708 336Q708 210 634 116T442 3Q429 1 228 0H27V46H60Q102 47 111 49T130 61V622ZM593 338Q593 439 571 501T493 602Q439 637 355 637H322H294Q238 637 234 628Q231 624 231 344Q231 62 232 59Q233 49 248 48T339 46H350Q456 46 515 95Q561 133 577 191T593 338Z" transform="translate(722,0)"></path><path data-c="46" d="M128 619Q121 626 117 628T101 631T58 634H25V680H582V676Q584 670 596 560T610 444V440H570V444Q563 493 561 501Q555 538 543 563T516 601T477 622T431 631T374 633H334H286Q252 633 244 631T233 621Q232 619 232 490V363H284Q287 363 303 363T327 364T349 367T372 373T389 385Q407 403 410 459V480H450V200H410V221Q407 276 389 296Q381 303 371 307T348 313T327 316T303 317T284 317H232V189L233 61Q240 54 245 52T270 48T333 46H360V0H348Q324 3 182 3Q51 3 36 0H25V46H58Q100 47 109 49T128 61V619Z" transform="translate(1486,0)"></path></g><g data-mml-node="mo" transform="translate(3975.6,0)"><path data-c="28" d="M94 250Q94 319 104 381T127 488T164 576T202 643T244 695T277 729T302 750H315H319Q333 750 333 741Q333 738 316 720T275 667T226 581T184 443T167 250T184 58T225 -81T274 -167T316 -220T333 -241Q333 -250 318 -250H315H302L274 -226Q180 -141 137 -14T94 250Z"></path></g><g data-mml-node="mo" transform="translate(4364.6,0)"><path data-c="2212" d="M84 237T84 250T98 270H679Q694 262 694 250T679 230H98Q84 237 84 250Z"></path></g><g data-mml-node="mo" transform="translate(5142.6,0) translate(0 -0.5)"><path data-c="7C" d="M139 -249H137Q125 -249 119 -235V251L120 737Q130 750 139 750Q152 750 159 735V-235Q151 -249 141 -249H139Z"></path></g><g data-mml-node="mi" transform="translate(5420.6,0)"><path data-c="1D461" d="M26 385Q19 392 19 395Q19 399 22 411T27 425Q29 430 36 430T87 431H140L159 511Q162 522 166 540T173 566T179 586T187 603T197 615T211 624T229 626Q247 625 254 615T261 596Q261 589 252 549T232 470L222 433Q222 431 272 431H323Q330 424 330 420Q330 398 317 385H210L174 240Q135 80 135 68Q135 26 162 26Q197 26 230 60T283 144Q285 150 288 151T303 153H307Q322 153 322 145Q322 142 319 133Q314 117 301 95T267 48T216 6T155 -11Q125 -11 98 4T59 56Q57 64 57 83V101L92 241Q127 382 128 383Q128 385 77 385H26Z"></path></g><g data-mml-node="mo" transform="translate(5781.6,0) translate(0 -0.5)"><path data-c="7C" d="M139 -249H137Q125 -249 119 -235V251L120 737Q130 750 139 750Q152 750 159 735V-235Q151 -249 141 -249H139Z"></path></g><g data-mml-node="mo" transform="translate(6059.6,0)"><path data-c="2C" d="M78 35T78 60T94 103T137 121Q165 121 187 96T210 8Q210 -27 201 -60T180 -117T154 -158T130 -185T117 -194Q113 -194 104 -185T95 -172Q95 -168 106 -156T131 -126T157 -76T173 -3V9L172 8Q170 7 167 6T161 3T152 1T140 0Q113 0 96 17Z"></path></g><g data-mml-node="msub" transform="translate(6504.2,0)"><g data-mml-node="mi"><path data-c="1D45B" d="M21 287Q22 293 24 303T36 341T56 388T89 425T135 442Q171 442 195 424T225 390T231 369Q231 367 232 367L243 378Q304 442 382 442Q436 442 469 415T503 336T465 179T427 52Q427 26 444 26Q450 26 453 27Q482 32 505 65T540 145Q542 153 560 153Q580 153 580 145Q580 144 576 130Q568 101 554 73T508 17T439 -10Q392 -10 371 17T350 73Q350 92 386 193T423 345Q423 404 379 404H374Q288 404 229 303L222 291L189 157Q156 26 151 16Q138 -11 108 -11Q95 -11 87 -5T76 7T74 17Q74 30 112 180T152 343Q153 348 153 366Q153 405 129 405Q91 405 66 305Q60 285 60 284Q58 278 41 278H27Q21 284 21 287Z"></path></g><g data-mml-node="mi" transform="translate(633,-150) scale(0.707)"><path data-c="1D44B" d="M42 0H40Q26 0 26 11Q26 15 29 27Q33 41 36 43T55 46Q141 49 190 98Q200 108 306 224T411 342Q302 620 297 625Q288 636 234 637H206Q200 643 200 645T202 664Q206 677 212 683H226Q260 681 347 681Q380 681 408 681T453 682T473 682Q490 682 490 671Q490 670 488 658Q484 643 481 640T465 637Q434 634 411 620L488 426L541 485Q646 598 646 610Q646 628 622 635Q617 635 609 637Q594 637 594 648Q594 650 596 664Q600 677 606 683H618Q619 683 643 683T697 681T738 680Q828 680 837 683H845Q852 676 852 672Q850 647 840 637H824Q790 636 763 628T722 611T698 593L687 584Q687 585 592 480L505 384Q505 383 536 304T601 142T638 56Q648 47 699 46Q734 46 734 37Q734 35 732 23Q728 7 725 4T711 1Q708 1 678 1T589 2Q528 2 496 2T461 1Q444 1 444 10Q444 11 446 25Q448 35 450 39T455 44T464 46T480 47T506 54Q523 62 523 64Q522 64 476 181L429 299Q241 95 236 84Q232 76 232 72Q232 53 261 47Q262 47 267 47T273 46Q276 46 277 46T280 45T283 42T284 35Q284 26 282 19Q279 6 276 4T261 1Q258 1 243 1T201 2T142 2Q64 2 42 0Z"></path></g></g><g data-mml-node="mo" transform="translate(8011.9,0)"><path data-c="2B" d="M56 237T56 250T70 270H369V420L370 570Q380 583 389 583Q402 583 409 568V270H707Q722 262 722 250T707 230H409V-68Q401 -82 391 -82H389H387Q375 -82 369 -68V230H70Q56 237 56 250Z"></path></g><g data-mml-node="msub" transform="translate(9012.1,0)"><g data-mml-node="mi"><path data-c="1D45B" d="M21 287Q22 293 24 303T36 341T56 388T89 425T135 442Q171 442 195 424T225 390T231 369Q231 367 232 367L243 378Q304 442 382 442Q436 442 469 415T503 336T465 179T427 52Q427 26 444 26Q450 26 453 27Q482 32 505 65T540 145Q542 153 560 153Q580 153 580 145Q580 144 576 130Q568 101 554 73T508 17T439 -10Q392 -10 371 17T350 73Q350 92 386 193T423 345Q423 404 379 404H374Q288 404 229 303L222 291L189 157Q156 26 151 16Q138 -11 108 -11Q95 -11 87 -5T76 7T74 17Q74 30 112 180T152 343Q153 348 153 366Q153 405 129 405Q91 405 66 305Q60 285 60 284Q58 278 41 278H27Q21 284 21 287Z"></path></g><g data-mml-node="mi" transform="translate(633,-150) scale(0.707)"><path data-c="1D44C" d="M66 637Q54 637 49 637T39 638T32 641T30 647T33 664T42 682Q44 683 56 683Q104 680 165 680Q288 680 306 683H316Q322 677 322 674T320 656Q316 643 310 637H298Q242 637 242 624Q242 619 292 477T343 333L346 336Q350 340 358 349T379 373T411 410T454 461Q546 568 561 587T577 618Q577 634 545 637Q528 637 528 647Q528 649 530 661Q533 676 535 679T549 683Q551 683 578 682T657 680Q684 680 713 681T746 682Q763 682 763 673Q763 669 760 657T755 643Q753 637 734 637Q662 632 617 587Q608 578 477 424L348 273L322 169Q295 62 295 57Q295 46 363 46Q379 46 384 45T390 35Q390 33 388 23Q384 6 382 4T366 1Q361 1 324 1T232 2Q170 2 138 2T102 1Q84 1 84 9Q84 14 87 24Q88 27 89 30T90 35T91 39T93 42T96 44T101 45T107 45T116 46T129 46Q168 47 180 50T198 63Q201 68 227 171L252 274L129 623Q128 624 127 625T125 627T122 629T118 631T113 633T105 634T96 635T83 636T66 637Z"></path></g></g><g data-mml-node="mo" transform="translate(10456.9,0)"><path data-c="2212" d="M84 237T84 250T98 270H679Q694 262 694 250T679 230H98Q84 237 84 250Z"></path></g><g data-mml-node="mn" transform="translate(11457.1,0)"><path data-c="32" d="M109 429Q82 429 66 447T50 491Q50 562 103 614T235 666Q326 666 387 610T449 465Q449 422 429 383T381 315T301 241Q265 210 201 149L142 93L218 92Q375 92 385 97Q392 99 409 186V189H449V186Q448 183 436 95T421 3V0H50V19V31Q50 38 56 46T86 81Q115 113 136 137Q145 147 170 174T204 211T233 244T261 278T284 308T305 340T320 369T333 401T340 431T343 464Q343 527 309 573T212 619Q179 619 154 602T119 569T109 550Q109 549 114 549Q132 549 151 535T170 489Q170 464 154 447T109 429Z"></path></g><g data-mml-node="mo" transform="translate(11957.1,0)"><path data-c="29" d="M60 749L64 750Q69 750 74 750H86L114 726Q208 641 251 514T294 250Q294 182 284 119T261 12T224 -76T186 -143T145 -194T113 -227T90 -246Q87 -249 86 -250H74Q66 -250 63 -250T58 -247T55 -238Q56 -237 66 -225Q221 -64 221 250T66 725Q56 737 55 738Q55 746 60 749Z"></path></g><g data-mml-node="mo" transform="translate(12568.3,0)"><path data-c="D7" d="M630 29Q630 9 609 9Q604 9 587 25T493 118L389 222L284 117Q178 13 175 11Q171 9 168 9Q160 9 154 15T147 29Q147 36 161 51T255 146L359 250L255 354Q174 435 161 449T147 471Q147 480 153 485T168 490Q173 490 175 489Q178 487 284 383L389 278L493 382Q570 459 587 475T609 491Q630 491 630 471Q630 464 620 453T522 355L418 250L522 145Q606 61 618 48T630 29Z"></path></g><g data-mml-node="mn" transform="translate(13568.5,0)"><path data-c="32" d="M109 429Q82 429 66 447T50 491Q50 562 103 614T235 666Q326 666 387 610T449 465Q449 422 429 383T381 315T301 241Q265 210 201 149L142 93L218 92Q375 92 385 97Q392 99 409 186V189H449V186Q448 183 436 95T421 3V0H50V19V31Q50 38 56 46T86 81Q115 113 136 137Q145 147 170 174T204 211T233 244T261 278T284 308T305 340T320 369T333 401T340 431T343 464Q343 527 309 573T212 619Q179 619 154 602T119 569T109 550Q109 549 114 549Q132 549 151 535T170 489Q170 464 154 447T109 429Z"></path></g></g></g></svg></mjx-container></span></p> <h2 id="結果">結果</h2> <p>異なる実行時間を示すプログラム<code>a</code>,<code>b</code>を比較すると、2 つの分布の平均が異なることが示唆された。</p> <pre><code class="hljs plaintext">❯ ts-node test.ts ab.json Xn = 10 Yn = 10 X_mu = 1.8022945422950003 Y_mu = 2.9619571628950006 X_sigma = 0.6067285795623545 Y_sigma = 0.6593856215802901 t = -3.2590814831310353 df = 17.968919419652778 -0.0001571394779906754 p = 0.004364964634417297 p &lt; 0.05 = true Possibly some difference there</code></pre> <p>p 値が 0.05 未満となり、帰無仮説「2つの分布は等しい」が棄却されたので「2つの分布は等しくない」ことがわかった。では、同じプログラム同士でベンチマークを取るとどうなるか?</p> <pre><code class="hljs plaintext">❯ ts-node test.ts aa.json Xn = 10 Yn = 10 X_mu = 1.7561671737900002 Y_mu = 1.9892996860899999 X_sigma = 0.5127362786380443 Y_sigma = 0.442053230382934 t = -0.754482245774979 df = 17.901889803947558 -27359.526584574112 p = 0.4603702896905685 p &lt; 0.05 = false No difference</code></pre> <p>p 値が 0.05 未満ではないため、帰無仮説は棄却されず、つまり「2つの分布は等しい」ことがわかった。</p> <p>ウェルチの t 検定はスチューデントの t 検定と違って等分散性(2つの分布の分散が等しいこと)を仮定しないため、とても取り扱いやすい検定だ。もちろん等分散性のある分布でも使用できるので、基本的にはウェルチの方法を使う方針で良さそうだ。</p> <h2 id="参考文献">参考文献</h2> <ul> <li><a href="https://rosettacode.org/wiki/Welch%27s_t-test">Welch's t-test - Rosetta Code</a></li> </ul> 2019-10-02T23:21:00.000Z https://uechi.io/blog/give-your-app-slick-name/ Give Your App Slick Name with namae.dev <p>Have you ever struggled with naming your new OSS project or web app? While hoping no one claimed your desired one in GitHub, npm, Homebrew, PyPI, Domains, etcetera, choosing the best name is weary work.</p> <p>That's why I created <a href="https://namae.dev">namae</a>.</p> <h1 id="namae">namae</h1> <p><img src="/uploads/np1a40lrch9m10b1s7nz.gif"> <a href="https://namae.dev">namae</a> is an inter-platform name availability checker for developers and entrepreneurs.</p> <p>Once you fill out a form with a name you want to use, namae will check through various registries and check if the name is already in use or not.</p> <p><img src="/uploads/pww3x6ycshadfiiotep9.png"></p> <h1 id="supported-platforms">Supported Platforms</h1> <p>namae supports 15 package registries and web platforms, and it's growing.</p> <ul> <li>Domains</li> <li>GitHub Organization</li> <li>npm / npm Organization</li> <li>PyPI</li> <li>RubyGems</li> <li>Rust (crates.io)</li> <li>Homebrew / Homebrew Cask</li> <li>Linux (Launchpad &amp; APT)</li> <li>Twitter</li> <li>Spectrum</li> <li>Slack</li> <li>Heroku</li> <li>ZEIT Now</li> <li>AWS S3</li> <li>js.org</li> </ul> <p>Additionally, the search result comes with a list of projects which has a similar name on <strong>GitHub</strong> and <strong>App Store</strong>.</p> <h1 id="name-suggestion">Name Suggestion</h1> <p>namae also has a unique feature called <strong>Name Suggestion</strong>. It suggests auto-generated names made up of common prefix/suffix and synonyms. Take look at some examples.</p> <p><img src="/uploads/aas52pwbrueyzrulfiae.png"></p> <p><img src="/uploads/j6jv0rq4gin28hks1ika.png"></p> <p>Clicking the suggestion, namae completes the form with it and start searching around the registries.</p> <h1 id="open-source">Open Source</h1> <p>namae is completely open-sourced and the entire source code is available at <a href="https://github.com/uetchy/namae">GitHub</a>. It consists​ of Node.js Lambda for APIs and React app for the web frontend, and is running on <a href="https://now.sh">ZEIT Now</a>.</p> <h1 id="conclusion">Conclusion</h1> <p>namae saves your time searching for a universally available name around a set of hosting providers and package registries.</p> <p>Go to <a href="https://namae.dev/">namae.dev</a> and grab a report for the availability of your future product name. If you have any suggestion, poke me on Twitter (<span class="citation" data-cites="uechz">[@uechz]</span>(https://twitter.com/uechz)).</p> 2019-08-28T09:12:00.000Z https://uechi.io/blog/sign-and-notarize-electron-app/ Electronアプリをコード署名してApple 公証 (Notary) を通過させる方法 <p>electron-builder を利用して macOS 向け Electron アプリをコード署名し、公証を通過させる。</p> <blockquote> <p><strong>tl;dr</strong>: コード署名と公証に対応した macOS アプリ Juno のリポジトリを<a href="https://github.com/uetchy/juno">GitHub で公開</a>している。</p> </blockquote> <h1 id="code-sign">Code Sign</h1> <p>アプリのコード署名は<code>electron-builder</code>によって自動で行われる。内部的には<a href="https://github.com/electron-userland/electron-osx-sign">electron-osx-sign</a>が使用される。</p> <p>リリース用のアプリにコード署名をするには、Keychain に有効な Developer ID Certificate が格納されている必要がある。macOS Developer Certificate は開発用のコード署名にしか使えないため、リリース用としては不十分だ。</p> <p>まだ証明書を発行していない場合は、<a href="https://developer.apple.com/account/resources/certificates/list">Apple Developer</a>で証明書の追加ウィザードに進み、<strong>Developer ID Application</strong>を選択して証明書を発行する。</p> <h1 id="notarize">Notarize</h1> <p>コード署名済みのアプリを<a href="https://github.com/electron-userland/electron-notarize">electron-notarize</a>を使用して Apple Notary Service に提出する。</p> <pre><code class="hljs js"><span class="hljs-keyword">const</span> { notarize } = <span class="hljs-built_in">require</span>(<span class="hljs-string">"electron-notarize"</span>); <span class="hljs-title function_">notarize</span>({ appBundleId, appPath, appleId, appleIdPassword, ascProvider, });</code></pre> <ul> <li><strong>appBundleId</strong>: アプリの Bundle ID 。<code>package.json</code>の<code>build.appId</code>と同じものを使う。</li> <li><strong>appPath</strong>: <code>.app</code>の絶対パスを指定する。</li> <li><strong>appleId</strong>: Apple Developer として登録している Apple ID を指定する。</li> <li><strong>appleIdPassword</strong>: Apple ID のパスワード。2 要素認証を必要としないパスワードが必要なので、<a href="https://appleid.apple.com/#!&amp;page=signin">Apple ID</a>にアクセスして<strong>App-specific Password</strong>を発行する。</li> <li><strong>ascProvider</strong>: Apple Developer の Membership に記載されている<strong>Team ID</strong>を指定する。</li> </ul> <h2 id="electron-builder-の-aftersign-フック">electron-builder の afterSign フック</h2> <p>electron-builder の afterSign フックを使用して、コード署名が済んだアプリを自動で Notary に提出する。</p> <p>フックスクリプトを<code>./scripts/after-sign-mac.js</code>に置く。</p> <pre><code class="hljs js"><span class="hljs-keyword">const</span> path = <span class="hljs-built_in">require</span>(<span class="hljs-string">"path"</span>); <span class="hljs-keyword">const</span> { notarize } = <span class="hljs-built_in">require</span>(<span class="hljs-string">"electron-notarize"</span>); <span class="hljs-keyword">const</span> appleId = process.<span class="hljs-property">env</span>.<span class="hljs-property">APPLE_ID</span>; <span class="hljs-keyword">const</span> appleIdPassword = process.<span class="hljs-property">env</span>.<span class="hljs-property">APPLE_PASSWORD</span>; <span class="hljs-keyword">const</span> ascProvider = process.<span class="hljs-property">env</span>.<span class="hljs-property">ASC_PROVIDER</span>; <span class="hljs-keyword">const</span> configPath = path.<span class="hljs-title function_">resolve</span>(__dirname, <span class="hljs-string">"../package.json"</span>); <span class="hljs-keyword">const</span> appPath = path.<span class="hljs-title function_">resolve</span>(__dirname, <span class="hljs-string">"../dist/mac/App.app"</span>); <span class="hljs-keyword">const</span> config = <span class="hljs-built_in">require</span>(configPath); <span class="hljs-keyword">const</span> appBundleId = config.<span class="hljs-property">build</span>.<span class="hljs-property">appId</span>; <span class="hljs-keyword">async</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">notarizeApp</span>(<span class="hljs-params"></span>) { <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">`afterSign: Notarizing <span class="hljs-subst">${appBundleId}</span> in <span class="hljs-subst">${appPath}</span>`</span>); <span class="hljs-keyword">await</span> <span class="hljs-title function_">notarize</span>({ appBundleId, appPath, appleId, appleIdPassword, ascProvider, }); <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">"afterSign: Notarized"</span>); } <span class="hljs-built_in">exports</span>.<span class="hljs-property">default</span> = <span class="hljs-keyword">async</span> () =&gt; { <span class="hljs-keyword">await</span> <span class="hljs-title function_">notarizeApp</span>(); };</code></pre> <p><code>package.json</code>の<code>build</code>に<code>afterSign</code>を追加して、コード署名が終わった後にスクリプトが実行されるようにする。</p> <pre><code class="hljs json"><span class="hljs-attr">"build"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span> <span class="hljs-attr">"afterSign"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"./scripts/after-sign-mac.js"</span> <span class="hljs-punctuation">}</span></code></pre> <h2 id="hardened-runtime-and-entitlements">Hardened Runtime and Entitlements</h2> <p>このままでは公証に失敗する。デフォルトで書き出されるバイナリでは、セキュリティの強化された<a href="https://developer.apple.com/documentation/security/hardened_runtime_entitlements">Hardened Runtime</a>が有効になっていないためだ。以下のようなエラーメッセージが帰ってくる。</p> <pre><code class="hljs json"><span class="hljs-punctuation">{</span> <span class="hljs-attr">"status"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"Invalid"</span><span class="hljs-punctuation">,</span> <span class="hljs-attr">"statusSummary"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"Archive contains critical validation errors"</span><span class="hljs-punctuation">,</span> <span class="hljs-attr">"statusCode"</span><span class="hljs-punctuation">:</span> <span class="hljs-number">4000</span><span class="hljs-punctuation">,</span> <span class="hljs-attr">"issues"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span> <span class="hljs-punctuation">{</span> <span class="hljs-attr">"severity"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"error"</span><span class="hljs-punctuation">,</span> <span class="hljs-attr">"code"</span><span class="hljs-punctuation">:</span> <span class="hljs-literal"><span class="hljs-keyword">null</span></span><span class="hljs-punctuation">,</span> <span class="hljs-attr">"path"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"App.zip/App.app/Contents/MacOS/App"</span><span class="hljs-punctuation">,</span> <span class="hljs-attr">"message"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"The executable does not have the hardened runtime enabled."</span><span class="hljs-punctuation">,</span> <span class="hljs-attr">"docUrl"</span><span class="hljs-punctuation">:</span> <span class="hljs-literal"><span class="hljs-keyword">null</span></span><span class="hljs-punctuation">,</span> <span class="hljs-attr">"architecture"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"x86_64"</span> <span class="hljs-punctuation">}</span><span class="hljs-punctuation">,</span> <span class="hljs-punctuation">}</span> <span class="hljs-punctuation">}</span></code></pre> <p>そこで、<code>package.json</code>の<code>build.mac.hardenedRuntime</code>を<code>true</code>にして Hardened Runtime を有効にする。</p> <pre><code class="hljs json"><span class="hljs-attr">"build"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span> <span class="hljs-attr">"mac"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span> <span class="hljs-attr">"hardenedRuntime"</span><span class="hljs-punctuation">:</span> <span class="hljs-literal"><span class="hljs-keyword">true</span></span> <span class="hljs-punctuation">}</span> <span class="hljs-punctuation">}</span></code></pre> <p>Hardened Runtime 下では、必要に応じて Entitlement を指定しなければならない。Electron の実行には<code>allow-unsigned-executable-memory</code> Entitlement が必要だ。そこで、<code>entitlement.plist</code>ファイルを<code>build</code>フォルダに作成し、以下のような plist を記述する。</p> <pre><code class="hljs xml"><span class="hljs-meta">&lt;?xml version=<span class="hljs-string">"1.0"</span> encoding=<span class="hljs-string">"UTF-8"</span>?&gt;</span> <span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-keyword">plist</span> <span class="hljs-keyword">PUBLIC</span> <span class="hljs-string">"-//Apple//DTD PLIST 1.0//EN"</span> <span class="hljs-string">"http://www.apple.com/DTDs/PropertyList-1.0.dtd"</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">plist</span> <span class="hljs-attr">version</span>=<span class="hljs-string">"1.0"</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">dict</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">key</span>&gt;</span>com.apple.security.cs.allow-unsigned-executable-memory<span class="hljs-tag">&lt;/<span class="hljs-name">key</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">true</span>/&gt;</span> <span class="hljs-tag">&lt;/<span class="hljs-name">dict</span>&gt;</span> <span class="hljs-tag">&lt;/<span class="hljs-name">plist</span>&gt;</span></code></pre> <p><code>package.json</code>の<code>entitlements</code>及び<code>entitlementsInherit</code>に Entitlement が記述された plist のファイルパスを指定する。</p> <pre><code class="hljs json"><span class="hljs-attr">"build"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span> <span class="hljs-attr">"mac"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span> <span class="hljs-attr">"hardenedRuntime"</span><span class="hljs-punctuation">:</span> <span class="hljs-literal"><span class="hljs-keyword">true</span></span><span class="hljs-punctuation">,</span> <span class="hljs-attr">"entitlements"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"./src/build/entitlement.plist"</span><span class="hljs-punctuation">,</span> <span class="hljs-attr">"entitlementsInherit"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"./src/build/entitlement.plist"</span> <span class="hljs-punctuation">}</span> <span class="hljs-punctuation">}</span></code></pre> <p>Hardened Runtime で Electron を実行することができるようになったので、Notary を通過できる状態になった。</p> <p>実際に<code>electron-builder</code>を実行して、すべてのプロセスが滞りなく動作することを確かめよう。</p> <h1 id="verify-notary-status">Verify Notary Status</h1> <p>ただしく公証を得られたかどうかは<code>altool</code>で調べることができる。</p> <p>公証通過後に送られてくるメールに<code>Request Identifier</code>が記載されているのでメモする。</p> <pre><code class="hljs plaintext">Dear uetchy, Your Mac software has been notarized. You can now export this software and distribute it directly to users. Bundle Identifier: &lt;Bundle ID&gt; Request Identifier: &lt;UUID&gt; For details on exporting a notarized app, visit Xcode Help or the notarization guide. Best Regards, Apple Developer Relations</code></pre> <p><code>xcrun altool --notarization-info</code>コマンドに UUID と Apple ID、パスワードを指定して公証ステータスを確認する。</p> <pre><code class="hljs plaintext">xcrun altool --notarization-info &lt;UUID&gt; -u $APPLE_ID -p $APPLE_PASSWORD</code></pre> <p>正しく公証が得られている場合は以下のようなメッセージが表示される。おめでとう!</p> <pre><code class="hljs plaintext">2019-06-05 13:51:18.236 altool[5944:261201] No errors getting notarization info. RequestUUID: &lt;UUID&gt; Date: 2019-06-05 04:45:54 +0000 Status: success LogFileURL: https://osxapps-ssl.itunes.apple.com/itunes-assets/Enigma123/v4/&lt;Log file identifier&gt; Status Code: 0 Status Message: Package Approved</code></pre> <h2 id="参考文献">参考文献</h2> <ul> <li><a href="https://developer.apple.com/documentation/security/notarizing_your_app_before_distribution/resolving_common_notarization_issues">Resolving Common Notarization Issues</a></li> <li><a href="https://kilianvalkhof.com/2019/electron/notarizing-your-electron-application/">Notarizing your Electron application</a></li> <li><a href="https://github.com/electron-userland/electron-builder/issues/3383">Feature request: Enable hardened runtime for macOS #3383</a></li> </ul> 2019-06-04T06:00:00.000Z https://uechi.io/blog/english-note/ 英語メモ <p>雑多なメモです。</p> <ul> <li>spin up - 立ち上げる</li> <li>woe - 悲しみ</li> <li>a little too - 少し〜すぎる</li> <li>all that much - それほど(否定形で) <ul> <li>family doesn't mean all that much to you.</li> </ul></li> <li>articulate - 考えをはっきり述べられる</li> <li>concordant - 調和した</li> <li>ergo - それ故に <ul> <li>かたい ergo - thus - therefore - so やわらかい</li> </ul></li> <li>endeavor - 努力 <ul> <li>I myself struggle with the endeavor of mastering the English language</li> </ul></li> <li>vis-à-vis - 〜と向かい合って、〜と比較して</li> <li>takeaway - 要点</li> <li>thoroughly - 徹底的に</li> <li>have little to do with ほとんど関係がない</li> <li>As well as I recall, - 記憶している限りでは、</li> <li>He is more of a researcher - どちらかというと研究者だ</li> <li>It is more a matter of feelings. - どちらかというと気持ちの問題だ</li> <li>more of a curse than a blessing - メリットよりデメリットが多い</li> <li>manifold — 多数の</li> <li>three-fold — 三倍</li> <li>evade — 避ける = avoid <ul> <li>a word that evades definition — 定義しにくい言葉</li> </ul></li> <li>don't be fooled by A — A に惑わされるな</li> <li>thrice — とても <ul> <li>Circuit Judge Joseph Bulone called 49-year-old Michael Drejka a “wanna-be” law enforcement officer and a self-appointed “handicapped parking space monitor.”</li> </ul></li> <li>encapsulate — 包容している</li> <li>atm — at this moment</li> <li>so far — これまで</li> <li>SMDH — Shaking My Damn Head</li> <li>micro stutter — プログラム上の細微な遅延 <ul> <li>When characters are missing from fonts, it's nice to be able to communicate to the user that this happened. — フォントに文字が欠けている場合、それをユーザーに伝えることができると便利です。</li> </ul></li> <li>for the sake of A — A の名のもとに <ul> <li>Firefox has abandoned subpixel-AA for the sake of simplicity — Firefox はシンプルさの名のもとにサブピクセル AA を棄てました。</li> <li>The entire idea behind subpixel-AA is that you are abusing how the pixels are laid out in a display. — サブピクセルアンチエイリアスは、ディスプレイにピクセルがどのように配置されているかという知識を基に成り立っています。</li> </ul></li> <li>a reasonable balance — 適度なバランス</li> <li>That said, — とはいえ、</li> <li>A with B on it — B が乗っている A</li> <li>can play a bit fast and loose with A — A を大雑把に扱える</li> <li>current iteration of A — 現行の A</li> <li>A doesn't play nice with B — B がため A が上手く動かない <ul> <li>our current iteration of search doesn't play nice with CJK characters</li> </ul></li> <li>Tried out and see what happens — 試して成り行きを見てみた</li> <li>Losing your shit — the state of being pushed over the edge of sanity and having a complete and utter freak out or mental/emotional breakdown ≒ お前は完全にイッちまうぜ</li> </ul> <blockquote> <p>And this is a Tech Forum, AND it's supposed to be a safe space. — そしてここは技術フォーラムであり、<em>かつ</em>心理的安全性が確保されているべき場所だ。 If you don't want to answer questions for "n00b", then don't answer. — "初心者"の質問に答えたくないなら、ただ口をつぐんでくれ</p> </blockquote> <blockquote> <p>Have you thought of what you’ll do after you retire? — 引退したらやりたいことについて考えたことある?</p> </blockquote> <ul> <li><p>any of those — これらどれでも (all of, every と交換可能 | 肯定文)</p></li> <li><p>there aren't any apples on the floor (否定の場合は any の後に複数形)</p></li> <li><p>you will likely do A — あなたは A することだろう</p></li> <li><p>99% of the time this is what you want to use — 99%これを使えば良い</p></li> <li><p>The one catch is that — 例外は、</p></li> <li><p>I ended up settling for this which looks incredibly anti-pattern-y but was the only option that wouldn’t explode on me — 最終的にこれに落ち着いた。アンチパターンっぽいけど僕にとっては一番安定している</p></li> <li><p>Why was that even created? — まずなぜこれが作られたの?</p></li> <li><p>Putting the main code in another function serves two purposes:</p></li> <li><p>one week cannot and should not define any team</p></li> <li><p>it go to show that A — A ということの証明となる</p></li> <li><p>A is to not have B — 「A」とは、B を持たないことである</p> <blockquote> <p>wireless charging is kinda funny because it really goes to show that the only way to get the tech industry to agree on a unified connector is to not have a connector</p> </blockquote></li> </ul> <blockquote> <p>me: it’s not that I mind freelancing, I love it. It’s just that the social interaction is pretty minimal and extremely uneven day-to-day and sometimes I wonder how that will affect me long term, you know? barista: ok are you going to order</p> </blockquote> <ul> <li>constitute, make up</li> </ul> <blockquote> <p>glad you’re happily situated elsewhere now. — あなたが他の場所で活躍しているようで嬉しい</p> </blockquote> <ul> <li>My dA account turned 10yo. In fact, I had spent 99% of the time as a lurker and six months ago finally started drawing and posting art.</li> <li>A conditional request is one that triggers if something happens, like: "If you don't quit talking, I am gonna have to ask you to leave." In this case, you can't really say, "If you don't quit talking, I have to ask you to leave." So even though it's not really conditional, using a conditional form is more polite because it's less direct.</li> <li>come to pass</li> <li>come across</li> </ul> <blockquote> <p>I would also half-expect the following sentences to contain further information on this particular group of students, like this:</p> </blockquote> <blockquote> <p>It uses the definite article before "majority of the students", as if referring to a known group.</p> </blockquote> <blockquote> <p>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.</p> </blockquote> <blockquote> <p>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%.</p> </blockquote> <blockquote> <p>Design is not just a visual thing, it's a thought process. it's a skill.</p> </blockquote> <ul> <li>at will — 意思次第で</li> <li>for asking — 望むなら</li> <li>fuck A up — A をボコボコにする</li> <li>friendly reminder - a euphemism for "this is the last warning"</li> <li>I feel attached</li> <li>I feel called out</li> </ul> <blockquote> <p>Lots of bittersweet feelings over this</p> </blockquote> <ul> <li>LRT: My favorite part of this is the upload on Youtube that's titled "Iwata vs Reggie (full fight)" like it was stitched together from multiple episodes of Naruto.</li> <li>get around to — 先延ばしにしていたことにやっと取り掛かる</li> <li>Finally got around to writing something on <span class="citation" data-cites="ThePracticalDev">@ThePracticalDev</span>, which was a really great experience!</li> <li>wordy, lengthy — 言葉の多い、冗長な</li> <li>A teenager not old to buy a six-pack — ビールも買えない年頃の子供</li> <li>It is likely that 未来形 — 〜になるだろう <ul> <li>It's likely that the affair will come to nothing — どうやら無事に治まりそうだ</li> </ul></li> <li>We will most likely do A — 我々は必ず A をするでしょう</li> <li>chirring - 虫が鳴く; bugs chirring</li> <li>what are you waiting for</li> <li>with a grain of salt — 割り引いて(考えて)</li> </ul> <blockquote> <p>learning foreign languages is for me lifelong hobby. knowledge likely to requires much time to acquiring but it never decays.</p> </blockquote> <blockquote> <p><em>sees client, whistles loudly</em></p> </blockquote> <blockquote> <p>weston comes out of nowhere running on all fours like a gorilla towards client</p> </blockquote> <blockquote> <p>I don't even understand how there can be HOURS of planned downtime for a service like this.</p> </blockquote> <blockquote> <p>And what could go wrong, in depending on the internet to keep the child warm</p> </blockquote> <blockquote> <p>the developer advocate in question understands the language barrier, it would seem; he’s not a native English speaker. regardless, his stance puts many who haven’t had a strong English education at a disadvantage. it prioritizes “getting things done” over people...</p> </blockquote> <blockquote> <p>save my dying cactus. what's wrong. cactus should have been easy stuff since they barely need water.</p> </blockquote> <blockquote> <p>higher form of something</p> </blockquote> <blockquote> <p>i hope it will inspire Americans to pursue a second language</p> </blockquote> <blockquote> <p>I love the fact that</p> </blockquote> <blockquote> <p>let's see if the result is the same (spoiler alert: it wasn't)</p> </blockquote> <blockquote> <p>Feature engineering is when we use existing features to create new features to determine if they provide new signals to predict our outcome.</p> </blockquote> <blockquote> <p>The happiest moment of my life was when I passed the entrance test.</p> </blockquote> <blockquote> <p>Controversial opinion: Every single opinion is controversial.</p> </blockquote> <ul> <li>Actually, my younger brother is a bit of a chav. — 弟はちょっとヤンキーなんだよ。</li> <li>take leap of faith 確証が持てないことを信じること(盲信とは違う)</li> <li>icky — 古めかしい</li> <li>adherence — 執着 one's adherence to A</li> <li>belief — 信念</li> <li>on principle — 道徳的見地から</li> <li>in set terms — 決まり文句で</li> <li>(Evening|Cold weather) has set in — (夜に|寒く)なった</li> </ul> <blockquote> <p>i feel like i'm most productive when i'm avoiding some other kind of responsibility</p> </blockquote> <ul> <li>be more of A — どちらかといえば A である; He is more of a researcher.</li> <li>be more of A thant B — B というよりむしろ A だ</li> <li>see less pain but also less joy — 痛みを感じることも少ないが喜びも少ない</li> <li>in term of A — A の観点から</li> </ul> <h2 id="go">Go</h2> <ul> <li>go into 何かを始める;状態に入る;費やされる</li> <li>go down 降りる;落ちる;低下する; go down on all fours — 四つん這いになる</li> <li>go easy on fellow insiders 身内に甘い;身内に手加減する</li> <li>go easy with her 彼女に優しくしろよ</li> </ul> <h2 id="get">Get</h2> <ul> <li>get over it (障害を)乗り越えろ</li> <li>get out 出て行く</li> <li>get down on A for B — B したことに大して A を批判し続ける</li> <li>get down to [verb.] — やっと始める。</li> <li>get in — 乗り込む</li> <li>too much to take - 手に負えない</li> <li>de rigueur - 慣習上必要不可欠</li> <li>utterly - 完全に</li> </ul> <blockquote> <p>make sure you know what the author expects you to know.</p> </blockquote> <ul> <li>The doom-laden feeling that this creates in us is then intensified by our inability to remember the past;</li> <li>smoke-laden 煙が立ち込めた</li> <li>doom-laden 厭世観で満ちた</li> </ul> <blockquote> <p>Thanks to his help, we managed to finish the work in time. 彼のおかげでなんとか時間内に仕事を終えることできた</p> </blockquote> <blockquote> <p>Thanks to the development of medicine, people have been able to live longer.</p> </blockquote> <blockquote> <p>Owing to the rise in oil prices, people are forced to use public transportation.</p> </blockquote> <blockquote> <p>The balloon is likely to burst at any time その風船は今にも爆発しそうだ</p> </blockquote> <blockquote> <p>It is because the air was polluted that the experiment was a failure. The experiment was a failure because the air was polluted.</p> </blockquote> <blockquote> <p>Thesis. Remote companies have less of an echo chamber since they are distributed. Thoughts?</p> </blockquote> <blockquote> <p>Obviously they should A, and B when C. Not D forever.</p> </blockquote> <ul> <li>Still - there is no A, just B.</li> </ul> <blockquote> <p>I think people are angry because Slack A, B and is C. No D, no E.</p> </blockquote> <blockquote> <p>Because he's the kind of person who likes helping others and is always gentle and kind as you described</p> </blockquote> <blockquote> <p>it was more difficult to get it wrong than guess it right! XD</p> </blockquote> <blockquote> <p>I'm pretty sure there was a lot of uproar about the Equifax thing</p> </blockquote> <h2 id="idioms">Idioms</h2> <ul> <li>Don’t make me blush XD — 恥ずかしい XD</li> <li>Think before you speak next time — 次からは考えてから話せ</li> <li>just a citation of the law they're overcompensating for — 彼らは濫用している法律の引用ただそれだけしか示してない</li> <li>repeal — 撤回する</li> <li>no respect for their users — ユーザーに対する敬意がない</li> <li>be now going the A route — 今度は A 作戦ときた</li> <li>in a blunt fashion — 露骨なやり方で</li> <li>"DM us, we'll take a look!" faux-friendly route — 偽りの友情作戦「DM で詳しく話を聞かせて!」</li> <li>reinstate — (アカウントを)復活させる</li> <li>shut the whole thing down — 全てを終わらせる</li> <li>as if, as though — 後者は話者の疑いが現れている. 仮定法過去を取る. It's as if I were a movie star.</li> <li>predominatly — 大抵は. Your costs are predominantly human labor.</li> <li>a myriad of A — 無数の A</li> <li>funnel toward 狭いところを前へと通る</li> <li>in a verifiable manner — 検証可能な方法で</li> <li>in a frigid manner — 冷たい態度で</li> <li>are expressed as — 〜として表せる</li> <li>a cup of tea — 好きなこと、得意なこと (It's not my cup of tea)</li> <li>I have a lot on my plate — やることが沢山ある</li> <li>It's a piece of cake — 朝飯前、超簡単</li> <li>can enforce fine-grained control over — 何かをきめ細かく制御することができる</li> <li>C’est la vie! — それが人生</li> <li>What’s done is done — 終わったものは仕方ない</li> <li>If you've got it, flaunt it — 良いものは隠さないで</li> <li>clench my teeth — 歯を食いしばる(って耐える)</li> </ul> <blockquote> <p>Hello, I just came across this wonderful library and was really intrigued by it :)</p> </blockquote> <blockquote> <p>When teaching, be careful not to mix up "" and "".</p> </blockquote> <ul> <li>life saver under this condition</li> <li>It turned to be such great experience, I couldn’t miss opportunity to share it</li> <li>I like Makefiles, they are simple and yet very powerful.</li> <li>To my surprise — 驚くべきことに</li> <li>I did it out of curiosity — 興味本位でやった</li> <li>If you're of the belt-and-suspenders mindset, consider setting UsePAM to 'no' as well. — 心配性な性格のこと</li> <li>you can cancel it as long as it has not been matched — 〜されていない限りいつでも</li> <li>By definition — 定義によると</li> <li>A found B C — A は B が C だと思った</li> <li>in that — という点において</li> <li>Iconoclast — 因襲打破主義者</li> </ul> <blockquote> <p>Researchers spend a great deal of time doing something — 研究者は多くの時間を〜するのに割いています。</p> </blockquote> <ul> <li>~ upon demand for ~ — <sub>の要請に応じて</sub></li> <li>Granularity — 粒度</li> <li>in a manner — いわば、ある意味</li> <li>periodic – 定期的 &lt;=&gt; sporadic – 不定期的</li> <li>abuse — 名詞は(a)bjú:s 動詞は(a)bjú:z</li> <li>eavesdrop — 盗み聞きする</li> <li>hypernym – 上位概念 &lt;=&gt; hyponym – 下位概念</li> <li>in this case — 今回の場合</li> <li>imply, represent, mean, stand for, refer to — 意味する</li> <li>redundant — 余剰であり過剰であり不必要なもの</li> <li>appropriate, proper, reasonable — 妥当な</li> <li>barely — かろうじて、ほとんど〜ない</li> </ul> <blockquote> <p>The iPad already has external keyboard support and an external trackpad support would go a long way to making the iPad a Mac replacement.</p> </blockquote> <blockquote> <p>Countless wrong inferences could be drawn from those observation.</p> </blockquote> <ul> <li>it drives me crazy [nuts] — イライラさせられる</li> <li>describes the steps that are involved in ~ — ~に関する手順について説明する</li> <li>前置詞 in は特徴の違いを、of は程度の違いを表す</li> <li>A is in proportion to B — A は B に比例している</li> <li>A is out of proportion to B — A は B に反比例している</li> <li>受動態は不自然に手を加えられて発生した結果に付随する、能動態は自然に発生した場合に付随する — our profits were increased は不正があったかのような表現、our profits increased が正しい</li> <li>be collectively known as A — A と総称されている</li> <li>Any links to this, as to be honest nobody is providing evidence, just lip-service relying on the ignorance of most readers</li> <li>in a great hurry - 大急ぎで</li> <li>gross 名詞 — 明らかな〜, a gross oversimplification - 明らかに過度な簡略化</li> <li>among — 〜の間で — in, through で代替可能</li> <li>throw A away — A を捨てる、A を無駄にする</li> <li>throw A up — 急にやめる</li> <li>be quick to — すぐ〜する。(People are quick to alienate outsiders 人々はすぐよそ者を阻害する)</li> <li>incredulous at — 〜を容易に信じない</li> <li>lack of standards for — 〜に対するけじめの無さ</li> <li>ludicrous, ridiculous — 馬鹿げた</li> <li>derogatory — 差別的な</li> <li>A that it was B — A だったので、B , 便利な接続詞</li> <li>After (p.p.), He (p.) — 〜の後、彼は〜した</li> <li>vicious — 凶悪な</li> <li>relentless, ruthless — しつこく、in の時は徹底的な</li> <li>mercilessly — 無慈悲に</li> <li>reckless — 無謀な</li> <li>profound — 心理的影響が重大な、深刻な(物理的には deep が適切)</li> </ul> <blockquote> <p>I felt like a coward hiding this from people — それを隠すことで自分が臆病者に思えた</p> </blockquote> <blockquote> <p>While training for the marathon, she was relentless in following the same schedule — マラソンの練習の間、彼女は同じスケジュールをしつこいほど守った。</p> </blockquote> <ul> <li>His history of A led to B — 彼が A を繰り返したせいで B を招いた。</li> <li>hatred — 憎悪</li> <li>coarse — 粗い</li> <li>B with A everywhere — A がいたるところに散乱している B</li> <li>people, all, the crowd — 人々</li> </ul> <blockquote> <p>A was quick to spot the potential of the Internet — A はインターネットの可能性をいち早く見出した</p> </blockquote> <ul> <li>a man who's nice to be around — そばに居てくれると助かる親切な人</li> <li>His generosity knows no bounds — 彼の寛大さには限りが無い</li> <li>borad-minded — 心が広い</li> <li>in one way or the other — どのみち、ある意味 e.g. This inspired you in one way or the other これはある意味あなたをインスピレートした</li> <li>to some extent — ある程度は、e.g. Travelling only helps to some extent 旅行はある程度それを助ける</li> <li>close-knit — 密接に関係している</li> <li>hot take — 走り書き</li> <li>cost an arm and a leg — 大変な金がかかる</li> <li>person with a forgiving nature — 寛大な心の持ち主</li> <li>we are on the same page — これで我々の認識が一致しましたね</li> <li>in that — という点で。 Man differ from animals in that they can think and speak.</li> <li>That said, — とは言え。ですから。</li> </ul> <p>p.p. the present progressive form, 現在進行系</p> <ul> <li>There have long been allegations that という噂がある</li> <li>The antisocial behaviour you are naturing あなたが心に抱いている反社会的行動</li> <li>have a lot to do with ~によるところが大きい</li> </ul> <p>一般に前置詞+ who(m)は既知の情報を確認する際に, who +前置詞は新しい情報を求める際に好まれる</p> <blockquote> <p>This is sure to satisfy those who are into computers. これはコンピュータにはまっている人をきっと満足させるだろう</p> </blockquote> <blockquote> <p>I've always wanted to study abroad someday but I haven't been able to yet.</p> </blockquote> <h2 id="複文と分詞構文">複文と分詞構文</h2> <ul> <li>A typhoon hit the city, causing big destruction.</li> <li>While skiing in Hakuba, I twisted my ankle.</li> <li>Not knowing what to say, she kept silent.</li> <li>Seeing me, the man ran away. ←→ As the man saw me, he ran away.</li> <li>Written in simple English, this book is easy to understand. ←→ Since this book is written in simple English, it is easy to understand.</li> <li>Walking along the beach, I found a beautiful shell. ←→ When I was walking along the beach, I found a beautiful shell.</li> <li>and そうすれば or 然もなくば but けれども so だから、それで for というのも nor 〜もまた、〜ではない</li> <li>She is not a politician, nor is she a diplomat.</li> </ul> <h2 id="when">when</h2> <ol type="1"> <li>未来の条件を表す場合は現在形を使う When I arrive at the station, I'll call you.</li> <li>過去の時を表す場合は過去形 When I was a child, I used to like soccer.</li> <li>未来の可能性を話す場合は未来形 I don't know when he will come.</li> </ol> <ul> <li>happened to — たまたま、偶然、もしかして</li> <li>Do you happen to know if she has a boyfriend? — あの子に彼氏いるのかな?</li> </ul> <p>不定詞は名詞・形容詞・副詞的働きをする動詞ベースの詞のこと</p> <p>to 不定詞が unrealized(未実現)、-ing が realized(実現)</p> <ul> <li>I want (to eat an apple)← 名詞的</li> <li>Thank you for playing the game</li> </ul> <ol type="1"> <li>She is studying English hard to study abroad.</li> <li>She study English hard to study abroad.</li> </ol> <p>違いは?</p> <ul> <li>only to A — 思わぬ悲観的な事実を説明する clause <ul> <li>He returned after the war only to be told that his wife had left him.</li> <li>I tore open the box, only to discover that some of the parts were missing.</li> <li>I arrived only to find that the others had already left.</li> </ul></li> </ul> <h2 id="倒置法">倒置法</h2> <ul> <li>So do I — 私も!(I like apple に対して)</li> <li>So am I — 私も!(I'm twenty years old に対して)</li> <li>Here comes bus — もうバス来たよ</li> <li>Here we go — ほら行こう</li> <li>In you go — 中にお入り</li> <li>What a shitty day — なんて日だ</li> <li>How beautiful (that is) — なんて綺麗なの</li> <li>"I'm fine", said he — 大丈夫だと彼は言った</li> <li>Dark as(though) it was, I found the footprints. — 暗かったが、なんとか足跡を見つけた</li> <li>Hard though she tried, she couldn't make the deadline. — 頑張ったが間に合わなかった</li> <li>Do what you will, I won't give up — 何をされようとも諦めない</li> <li>Walk as he would, he couldn't get to the station. — どんなに歩いても駅にたどり着けなかった</li> </ul> <blockquote> <p>"We live in a world of churn, but we do not have to accept high churn rates as the only reality." from "Subscription Marketing: Strategies for Nurturing Customers in a World of Churn (English Edition)" by Anne Janzer 45 Ways To Avoid Using The Word 'Very' - Writers Write</p> </blockquote> <blockquote> <p>I still hate that "atheist" now is code for "bigoted asshole."</p> </blockquote> <blockquote> <p>Life only comes around once. So do whatever makes you happy and be with whoever makes you smile!๑╹◡╹)ノ…</p> </blockquote> <blockquote> <p>This is exactly what I thought was gonna happen when I saw those tweets, thank you…</p> </blockquote> <blockquote> <p><span class="citation" data-cites="Nodejs">@Nodejs</span> and <span class="citation" data-cites="the_jsf">@the_jsf</span> have merged to form the #OpenJSFoundation! The OpenJS Foundation is to become the central place to support collaborative development of #JavaScript and web technologies.</p> </blockquote> <blockquote> <p>I love critical thinking and I admire skepticism, but only within a framework that respects the evidence.</p> </blockquote> <blockquote> <p>In earlier versions of TypeScript, we generalized mapped types to operate differently on array-like types. This meant that a mapped type like Boxify could work on arrays and tuples alike.</p> </blockquote> <blockquote> <p>a cool thing about the last few years is that the U.S. became the leading exporter of the intellectual machinery of western fascism and one of the leading domestic debates about it is whether undergrads are treating the people behind it politely enough</p> </blockquote> <blockquote> <p>Perhaps it would be less of a debate if they were more circumspect in who/what they call fascism. The main criticism seems to be that they have a lot of false positives in their "fascist-test" and treat anyone who points this out as fascist fellow travellers</p> </blockquote> <blockquote> <p>Universities are filled with people who feel like they are competing against their colleagues. When you do this, you end up constantly looking in front of you, feeling bitter. Or looking behind you, becoming arrogant. Run your own race. — Marc Lamont Hill https://twitter.com/marclamonthill/status/1109500482500939776?s=12</p> </blockquote> <blockquote> <p>Much discussion about bias in ML due to the training dataset - this has been an active area of study for a long time in population genetics, and is still not fully resolved — Miriam Huntley https://twitter.com/iam_mir_iam/status/1108819635959418881?s=12</p> </blockquote> <blockquote> <p>Welcome to the FGO NA Twitter. If you look to your left, you'll see the salty people club that are currently sulling about not pulling Okita. If you look to your right, you'll see the angry weeb club still screeching about Emiya Alter. Please enjoy your stay.… — ℭ𝔦𝔫𝔡𝔢𝔯 𝔉𝔞𝔩𝔩 https://twitter.com/zettainverse/status/1109231751019278337?s=12</p> </blockquote> <blockquote> <p>Probably one of the most auto-bookmarkable post I've seen in a while, regardless of skill level with git: — Ben Halpern 🤗 https://twitter.com/bendhalpern/status/1135319291568562176?s=12</p> </blockquote> <blockquote> <p>Now announcing tsconfig-api 🎉 An experimental microservice for retrieving <span class="citation" data-cites="typescript">@typescript</span> compiler option details 🔎 100% open source and hosted by <span class="citation" data-cites="zeithq">@zeithq</span> Now — Matterhorn https://twitter.com/matterhorndev/status/1138610398159147008?s=12</p> </blockquote> <blockquote> <p>Amid all of the chaos, an answer could be found. There’s a special kind of joy in UI libraries when you see small primitives working. Like maybe it’s a two rectangle demo. But you’ve already learned that thanks to composition, if it worked for two rectangles, you can make it work for a whole FB/Twitter-level app. — Dan Abramov https://twitter.com/dan_abramov/status/1143911059717263360?s=12</p> </blockquote> <blockquote> <p>Yes, assuming something will work like literally every other software that has ever been created will work is subjective. Super annoying that these people are so insecure about themselves that they have to do that kind of thing.… — Kent C. Dodds https://twitter.com/kentcdodds/status/1147142716280602629?s=12</p> </blockquote> <blockquote> <p>Honest question: how does banning people from an opportunity to build a professional presence and potentially escape an oppressive regime advance human rights?… — Dan Abramov https://twitter.com/dan_abramov/status/1154871232459956224?s=12</p> </blockquote> <blockquote> <p>The national flag of Japan is a rectangular white banner bearing a crimson-red disc at its center. This flag is officially called Nisshōki (日章旗, the "sun-mark flag"), but is more commonly known in Japan as Hinomaru (日の丸, the "circle of the sun"). It embodies the country's sobriquet: Land of the Rising Sun. reading this tweet is weird because at first you're like "hahaha they're not used to how gacha works" then you realize you've just been conditioned into being ok with predatory game models You're offering subjective value assessments, not facts.… — Levi Roach https://twitter.com/DrLRoach/status/1172907254892421120?s=17</p> </blockquote> <blockquote> <p>My takeaway is that I'm starting a support group for design systems engineers across the world. 😛 We're all going through different versions of the same challenges at each of our companies and it's always encouraging to share information about where we are in this journey. — Maja Wichrowska https://twitter.com/majapw/status/1187891828189589504?s=17</p> </blockquote> 2019-01-17T01:31:00.000Z https://uechi.io/blog/padsize/ padStartにおけるpadSizeの求め方 <p><code>padStart</code> における適切な <code>padSize</code> の求め方。</p> <p><span class="math display"><mjx-container class="MathJax" jax="SVG" display="true"><svg style="vertical-align: -0.581ex;" xmlns="http://www.w3.org/2000/svg" width="33.469ex" height="2.278ex" role="img" focusable="false" viewBox="0 -750 14793.1 1006.9"><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="mtext"><path data-c="70" d="M36 -148H50Q89 -148 97 -134V-126Q97 -119 97 -107T97 -77T98 -38T98 6T98 55T98 106Q98 140 98 177T98 243T98 296T97 335T97 351Q94 370 83 376T38 385H20V408Q20 431 22 431L32 432Q42 433 61 434T98 436Q115 437 135 438T165 441T176 442H179V416L180 390L188 397Q247 441 326 441Q407 441 464 377T522 216Q522 115 457 52T310 -11Q242 -11 190 33L182 40V-45V-101Q182 -128 184 -134T195 -145Q216 -148 244 -148H260V-194H252L228 -193Q205 -192 178 -192T140 -191Q37 -191 28 -194H20V-148H36ZM424 218Q424 292 390 347T305 402Q234 402 182 337V98Q222 26 294 26Q345 26 384 80T424 218Z"></path><path data-c="61" d="M137 305T115 305T78 320T63 359Q63 394 97 421T218 448Q291 448 336 416T396 340Q401 326 401 309T402 194V124Q402 76 407 58T428 40Q443 40 448 56T453 109V145H493V106Q492 66 490 59Q481 29 455 12T400 -6T353 12T329 54V58L327 55Q325 52 322 49T314 40T302 29T287 17T269 6T247 -2T221 -8T190 -11Q130 -11 82 20T34 107Q34 128 41 147T68 188T116 225T194 253T304 268H318V290Q318 324 312 340Q290 411 215 411Q197 411 181 410T156 406T148 403Q170 388 170 359Q170 334 154 320ZM126 106Q126 75 150 51T209 26Q247 26 276 49T315 109Q317 116 318 175Q318 233 317 233Q309 233 296 232T251 223T193 203T147 166T126 106Z" transform="translate(556,0)"></path><path data-c="64" d="M376 495Q376 511 376 535T377 568Q377 613 367 624T316 637H298V660Q298 683 300 683L310 684Q320 685 339 686T376 688Q393 689 413 690T443 693T454 694H457V390Q457 84 458 81Q461 61 472 55T517 46H535V0Q533 0 459 -5T380 -11H373V44L365 37Q307 -11 235 -11Q158 -11 96 50T34 215Q34 315 97 378T244 442Q319 442 376 393V495ZM373 342Q328 405 260 405Q211 405 173 369Q146 341 139 305T131 211Q131 155 138 120T173 59Q203 26 251 26Q322 26 373 103V342Z" transform="translate(1056,0)"></path><path data-c="53" d="M55 507Q55 590 112 647T243 704H257Q342 704 405 641L426 672Q431 679 436 687T446 700L449 704Q450 704 453 704T459 705H463Q466 705 472 699V462L466 456H448Q437 456 435 459T430 479Q413 605 329 646Q292 662 254 662Q201 662 168 626T135 542Q135 508 152 480T200 435Q210 431 286 412T370 389Q427 367 463 314T500 191Q500 110 448 45T301 -21Q245 -21 201 -4T140 27L122 41Q118 36 107 21T87 -7T78 -21Q76 -22 68 -22H64Q61 -22 55 -16V101Q55 220 56 222Q58 227 76 227H89Q95 221 95 214Q95 182 105 151T139 90T205 42T305 24Q352 24 386 62T420 155Q420 198 398 233T340 281Q284 295 266 300Q261 301 239 306T206 314T174 325T141 343T112 367T85 402Q55 451 55 507Z" transform="translate(1612,0)"></path><path data-c="69" d="M69 609Q69 637 87 653T131 669Q154 667 171 652T188 609Q188 579 171 564T129 549Q104 549 87 564T69 609ZM247 0Q232 3 143 3Q132 3 106 3T56 1L34 0H26V46H42Q70 46 91 49Q100 53 102 60T104 102V205V293Q104 345 102 359T88 378Q74 385 41 385H30V408Q30 431 32 431L42 432Q52 433 70 434T106 436Q123 437 142 438T171 441T182 442H185V62Q190 52 197 50T232 46H255V0H247Z" transform="translate(2168,0)"></path><path data-c="7A" d="M42 263Q44 270 48 345T53 423V431H393Q399 425 399 415Q399 403 398 402L381 378Q364 355 331 309T265 220L134 41L182 40H206Q254 40 283 46T331 77Q352 105 359 185L361 201Q361 202 381 202H401V196Q401 195 393 103T384 6V0H209L34 1L31 3Q28 8 28 17Q28 30 29 31T160 210T294 394H236Q169 393 152 388Q127 382 113 367Q89 344 82 264V255H42V263Z" transform="translate(2446,0)"></path><path data-c="65" d="M28 218Q28 273 48 318T98 391T163 433T229 448Q282 448 320 430T378 380T406 316T415 245Q415 238 408 231H126V216Q126 68 226 36Q246 30 270 30Q312 30 342 62Q359 79 369 104L379 128Q382 131 395 131H398Q415 131 415 121Q415 117 412 108Q393 53 349 21T250 -11Q155 -11 92 58T28 218ZM333 275Q322 403 238 411H236Q228 411 220 410T195 402T166 381T143 340T127 274V267H333V275Z" transform="translate(2890,0)"></path></g><g data-mml-node="mo" transform="translate(3611.8,0)"><path data-c="3D" d="M56 347Q56 360 70 367H707Q722 359 722 347Q722 336 708 328L390 327H72Q56 332 56 347ZM56 153Q56 168 72 173H708Q722 163 722 153Q722 140 707 133H70Q56 140 56 153Z"></path></g><g data-mml-node="mo" transform="translate(4667.6,0)"><path data-c="2308" d="M174 734Q178 746 190 750H298H369Q400 750 411 747T422 730T411 713T372 709Q365 709 345 709T310 710H214V-235Q206 -248 196 -250Q192 -250 189 -249T184 -247T180 -244T178 -241T176 -237T174 -234V734Z"></path></g><g data-mml-node="msub" transform="translate(5111.6,0)"><g data-mml-node="mi"><path data-c="6C" d="M42 46H56Q95 46 103 60V68Q103 77 103 91T103 124T104 167T104 217T104 272T104 329Q104 366 104 407T104 482T104 542T103 586T103 603Q100 622 89 628T44 637H26V660Q26 683 28 683L38 684Q48 685 67 686T104 688Q121 689 141 690T171 693T182 694H185V379Q185 62 186 60Q190 52 198 49Q219 46 247 46H263V0H255L232 1Q209 2 183 2T145 3T107 3T57 1L34 0H26V46H42Z"></path><path data-c="6F" d="M28 214Q28 309 93 378T250 448Q340 448 405 380T471 215Q471 120 407 55T250 -10Q153 -10 91 57T28 214ZM250 30Q372 30 372 193V225V250Q372 272 371 288T364 326T348 362T317 390T268 410Q263 411 252 411Q222 411 195 399Q152 377 139 338T126 246V226Q126 130 145 91Q177 30 250 30Z" transform="translate(278,0)"></path><path data-c="67" d="M329 409Q373 453 429 453Q459 453 472 434T485 396Q485 382 476 371T449 360Q416 360 412 390Q410 404 415 411Q415 412 416 414V415Q388 412 363 393Q355 388 355 386Q355 385 359 381T368 369T379 351T388 325T392 292Q392 230 343 187T222 143Q172 143 123 171Q112 153 112 133Q112 98 138 81Q147 75 155 75T227 73Q311 72 335 67Q396 58 431 26Q470 -13 470 -72Q470 -139 392 -175Q332 -206 250 -206Q167 -206 107 -175Q29 -140 29 -75Q29 -39 50 -15T92 18L103 24Q67 55 67 108Q67 155 96 193Q52 237 52 292Q52 355 102 398T223 442Q274 442 318 416L329 409ZM299 343Q294 371 273 387T221 404Q192 404 171 388T145 343Q142 326 142 292Q142 248 149 227T179 192Q196 182 222 182Q244 182 260 189T283 207T294 227T299 242Q302 258 302 292T299 343ZM403 -75Q403 -50 389 -34T348 -11T299 -2T245 0H218Q151 0 138 -6Q118 -15 107 -34T95 -74Q95 -84 101 -97T122 -127T170 -155T250 -167Q319 -167 361 -139T403 -75Z" transform="translate(778,0)"></path></g><g data-mml-node="TeXAtom" transform="translate(1311,-241.4) scale(0.707)" data-mjx-texclass="ORD"><g data-mml-node="mn"><path data-c="31" d="M213 578L200 573Q186 568 160 563T102 556H83V602H102Q149 604 189 617T245 641T273 663Q275 666 285 666Q294 666 302 660V361L303 61Q310 54 315 52T339 48T401 46H427V0H416Q395 3 257 3Q121 3 100 0H88V46H114Q136 46 152 46T177 47T193 50T201 52T207 57T213 61V578Z"></path><path data-c="30" d="M96 585Q152 666 249 666Q297 666 345 640T423 548Q460 465 460 320Q460 165 417 83Q397 41 362 16T301 -15T250 -22Q224 -22 198 -16T137 16T82 83Q39 165 39 320Q39 494 96 585ZM321 597Q291 629 250 629Q208 629 178 597Q153 571 145 525T137 333Q137 175 145 125T181 46Q209 16 250 16Q290 16 318 46Q347 76 354 130T362 333Q362 478 354 524T321 597Z" transform="translate(500,0)"></path></g></g></g><g data-mml-node="mo" transform="translate(7179.7,0)"><path data-c="2061" d=""></path></g><g data-mml-node="mo" transform="translate(7179.7,0)"><path data-c="28" d="M94 250Q94 319 104 381T127 488T164 576T202 643T244 695T277 729T302 750H315H319Q333 750 333 741Q333 738 316 720T275 667T226 581T184 443T167 250T184 58T225 -81T274 -167T316 -220T333 -241Q333 -250 318 -250H315H302L274 -226Q180 -141 137 -14T94 250Z"></path></g><g data-mml-node="TeXAtom" data-mjx-texclass="ORD" transform="translate(7568.7,0)"><g data-mml-node="mi"><path data-c="1D41A" d="M64 349Q64 399 107 426T255 453Q346 453 402 423T473 341Q478 327 478 310T479 196V77Q493 63 529 62Q549 62 553 57T558 31Q558 9 552 5T514 0H497H481Q375 0 367 56L356 46Q300 -6 210 -6Q130 -6 81 30T32 121Q32 188 111 226T332 272H350V292Q350 313 348 327T337 361T306 391T248 402T194 399H189Q204 376 204 354Q204 327 187 306T134 284Q97 284 81 305T64 349ZM164 121Q164 89 186 67T238 45Q274 45 307 63T346 108L350 117V226H347Q248 218 206 189T164 121Z"></path><path data-c="1D42B" d="M405 293T374 293T324 312T305 361Q305 378 312 394Q315 397 315 399Q305 399 294 394T266 375T238 329T222 249Q221 241 221 149V62H308V0H298Q280 3 161 3Q47 3 38 0H29V62H98V210V303Q98 353 96 363T83 376Q69 380 42 380H29V442H32L118 446Q204 450 205 450H210V414L211 378Q247 449 315 449H321Q384 449 413 422T442 360Q442 332 424 313Z" transform="translate(559,0)"></path><path data-c="1D42B" d="M405 293T374 293T324 312T305 361Q305 378 312 394Q315 397 315 399Q305 399 294 394T266 375T238 329T222 249Q221 241 221 149V62H308V0H298Q280 3 161 3Q47 3 38 0H29V62H98V210V303Q98 353 96 363T83 376Q69 380 42 380H29V442H32L118 446Q204 450 205 450H210V414L211 378Q247 449 315 449H321Q384 449 413 422T442 360Q442 332 424 313Z" transform="translate(1033,0)"></path><path data-c="1D41A" d="M64 349Q64 399 107 426T255 453Q346 453 402 423T473 341Q478 327 478 310T479 196V77Q493 63 529 62Q549 62 553 57T558 31Q558 9 552 5T514 0H497H481Q375 0 367 56L356 46Q300 -6 210 -6Q130 -6 81 30T32 121Q32 188 111 226T332 272H350V292Q350 313 348 327T337 361T306 391T248 402T194 399H189Q204 376 204 354Q204 327 187 306T134 284Q97 284 81 305T64 349ZM164 121Q164 89 186 67T238 45Q274 45 307 63T346 108L350 117V226H347Q248 218 206 189T164 121Z" transform="translate(1507,0)"></path><path data-c="1D432" d="M84 -102Q84 -110 87 -119T102 -138T133 -149Q148 -148 162 -143T186 -131T206 -114T222 -95T234 -76T243 -59T249 -45T252 -37L269 0L96 382H26V444H34Q49 441 146 441Q252 441 270 444H279V382H255Q232 382 232 380L337 151L442 382H394V444H401Q413 441 495 441Q568 441 574 444H580V382H510L406 152Q298 -84 297 -87Q269 -139 225 -169T131 -200Q85 -200 54 -172T23 -100Q23 -64 44 -50T87 -35Q111 -35 130 -50T152 -92V-100H84V-102Z" transform="translate(2066,0)"></path><path data-c="1D412" d="M64 493Q64 582 120 636T264 696H272Q280 697 285 697Q380 697 454 645L480 669Q484 672 488 676T495 683T500 688T504 691T508 693T511 695T514 696T517 697T522 697Q536 697 539 691T542 652V577Q542 557 542 532T543 500Q543 472 540 465T524 458H511H505Q489 458 485 461T479 478Q472 529 449 564T393 614T336 634T287 639Q228 639 203 610T177 544Q177 517 195 493T247 457Q253 454 343 436T475 391Q574 326 574 207V200Q574 163 559 120Q517 12 389 -9Q380 -10 346 -10Q308 -10 275 -5T221 7T184 22T160 35T151 40L126 17Q122 14 118 10T111 3T106 -2T102 -5T98 -7T95 -9T92 -10T89 -11T84 -11Q70 -11 67 -4T64 35V108Q64 128 64 153T63 185Q63 203 63 211T69 223T77 227T94 228H100Q118 228 122 225T126 205Q130 125 193 88T345 51Q408 51 434 82T460 157Q460 196 439 221T388 257Q384 259 305 276T221 295Q155 313 110 366T64 493Z" transform="translate(2673,0)"></path><path data-c="1D422" d="M72 610Q72 649 98 672T159 695Q193 693 217 670T241 610Q241 572 217 549T157 525Q120 525 96 548T72 610ZM46 442L136 446L226 450H232V62H294V0H286Q271 3 171 3Q67 3 49 0H40V62H109V209Q109 358 108 362Q103 380 55 380H43V442H46Z" transform="translate(3312,0)"></path><path data-c="1D433" d="M48 262Q48 264 54 349T60 436V444H252Q289 444 336 444T394 445Q441 445 450 441T459 418Q459 406 458 404Q456 399 327 229T194 55H237Q260 56 268 56T297 58T325 65T348 77T370 98T384 128T395 170Q400 197 400 216Q400 217 431 217H462V211Q461 208 453 108T444 6V0H245Q46 0 43 2Q32 7 32 28V33Q32 41 40 52T84 112Q129 170 164 217L298 393H256Q189 392 165 380Q124 360 115 303Q110 280 110 256Q110 254 79 254H48V262Z" transform="translate(3631,0)"></path><path data-c="1D41E" d="M32 225Q32 332 102 392T272 452H283Q382 452 436 401Q494 343 494 243Q494 226 486 222T440 217Q431 217 394 217T327 218H175V209Q175 177 179 154T196 107T236 69T306 50Q312 49 323 49Q376 49 410 85Q421 99 427 111T434 127T442 133T463 135H468Q494 135 494 117Q494 110 489 97T468 66T431 32T373 5T292 -6Q181 -6 107 55T32 225ZM383 276Q377 346 348 374T280 402Q253 402 230 390T195 357Q179 331 176 279V266H383V276Z" transform="translate(4142,0)"></path></g></g><g data-mml-node="mo" transform="translate(12459.9,0)"><path data-c="2B" d="M56 237T56 250T70 270H369V420L370 570Q380 583 389 583Q402 583 409 568V270H707Q722 262 722 250T707 230H409V-68Q401 -82 391 -82H389H387Q375 -82 369 -68V230H70Q56 237 56 250Z"></path></g><g data-mml-node="mn" transform="translate(13460.1,0)"><path data-c="31" d="M213 578L200 573Q186 568 160 563T102 556H83V602H102Q149 604 189 617T245 641T273 663Q275 666 285 666Q294 666 302 660V361L303 61Q310 54 315 52T339 48T401 46H427V0H416Q395 3 257 3Q121 3 100 0H88V46H114Q136 46 152 46T177 47T193 50T201 52T207 57T213 61V578Z"></path></g><g data-mml-node="mo" transform="translate(13960.1,0)"><path data-c="29" d="M60 749L64 750Q69 750 74 750H86L114 726Q208 641 251 514T294 250Q294 182 284 119T261 12T224 -76T186 -143T145 -194T113 -227T90 -246Q87 -249 86 -250H74Q66 -250 63 -250T58 -247T55 -238Q56 -237 66 -225Q221 -64 221 250T66 725Q56 737 55 738Q55 746 60 749Z"></path></g><g data-mml-node="mo" transform="translate(14349.1,0)"><path data-c="2309" d="M21 717T21 730T32 746T75 750H147H256Q266 742 269 735V-235Q262 -248 251 -250Q247 -250 244 -249T239 -247T235 -244T233 -241T231 -237T229 -234V710H133Q119 710 99 710T71 709Q43 709 32 713Z"></path></g></g></g></svg></mjx-container></span></p> <pre><code class="hljs js"><span class="hljs-keyword">const</span> padSize = <span class="hljs-title class_">Math</span>.<span class="hljs-title function_">ceil</span>(<span class="hljs-title class_">Math</span>.<span class="hljs-title function_">log10</span>(arr.<span class="hljs-property">length</span> + <span class="hljs-number">1</span>)); arr.<span class="hljs-title function_">forEach</span>(<span class="hljs-function">(<span class="hljs-params">item, index</span>) =&gt;</span> { <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">`<span class="hljs-subst">${index.padStart(padSize, <span class="hljs-string">"0"</span>)}</span>: <span class="hljs-subst">${item}</span>`</span>); });</code></pre> <p>結果は以下のようになる。</p> <pre><code class="hljs plaintext">01: item1 02: item2 03: item3 04: item4 05: item5 06: item6 07: item7 08: item8 09: item9 10: item10</code></pre> 2019-01-13T06:00:00.000Z https://uechi.io/blog/math-api/ Math API: LaTeX Math as SVG image <p>I've always wanted to put LaTeX Math equations on a web page where MathJax is not allowed to run inside it.</p> <p>Spending some time, I made <a href="https://math.now.sh">Math API</a>, that renders LaTeX Math markup into an SVG image.</p> <p>So you can place your equation on almost everywhere on which you could put <code>&lt;img&gt;</code> or Markdown (<code>![]()</code>), such as GitHub, Jupyter Notebook or dev.to (here!).</p> <pre><code class="hljs markdown">![](<span class="hljs-link">https://math.now.sh?from=\LaTeX</span>)</code></pre> <figure> <img src="https://math.now.sh?from=%5CLaTeX" alt="Equation"><figcaption aria-hidden="true">Equation</figcaption> </figure> <pre><code class="hljs markdown">![](<span class="hljs-link">https://math.now.sh?from=\log\prod^N_{i}x_{i}=\sum^N_i\log{x_i}</span>)</code></pre> <figure> <img src="https://math.now.sh?from=%5Clog%5Cprod%5EN_%7Bi%7Dx_%7Bi%7D%3D%5Csum%5EN_i%5Clog%7Bx_i%7D" alt="Equation"><figcaption aria-hidden="true">Equation</figcaption> </figure> <h1 id="inline-image">Inline image</h1> <p><img src="/uploads/fqea9nq2wv9in15lqlf3.png.jpeg"> <img src="/uploads/43slt0h6dfhox1xwmuti.png.jpeg"></p> <p>It is possible to generate an inline equation by changing the query from <code>from</code> to <code>inline</code>.</p> <pre><code class="hljs markdown"><span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://math.now.sh?inline=\\LaTeX"</span> /&gt;</span></span></code></pre> <h1 id="online-editor">Online Editor</h1> <p>Also, there is the online editor available at https://math.now.sh.</p> <p><img src="/uploads/gg2wil3exu9lyj7ppuoy.png"></p> <h1 id="conclusion">Conclusion</h1> <p>The source code is available on <a href="https://github.com/uetchy/math-api">GitHub</a>. Give it a try and leave a comment/idea for a new feature.</p> 2018-10-22T09:19:00.000Z https://uechi.io/blog/comparing-oss-on-github/ Comparing OSS on GitHub <p>You are making a decision on which open source project you would adopt for your newly developing application.</p> <p>This time it is a little bit difficult for you because the candidates are seemingly almost the same in a functional perspective.</p> <p>So let's delve into this from a different perspective: contributors and users activities.</p> <ul> <li>More stars, forks, and watchers are the good vital sign of a vibrant project, which indicates many users getting involved with the project.</li> <li>More issues stand for both good and bad sign but basically it indicates their activeness.</li> <li>Organization owned projects are, in most cases, more stable and robust than user owned projects.</li> <li>Size of the repository have complexed meanings but in practice, simpler code is better than the massive one if both are trying to achieve the same goal.</li> </ul> <p>I made a simple tool to get you covered with the above guidelines.</p> <h1 id="gh-compare">gh-compare</h1> <p><img src="/uploads/screencast.gif"></p> <p><a href="https://github.com/uetchy/gh-compare">gh-compare</a> is a simple terminal app to explore your candidates and aggregate a result into a nice-looking report.</p> <pre><code class="hljs bash">npm install -g gh-compare gh-compare facebook/react vuejs/vue riot/riot</code></pre> <p><img src="/uploads/1xfd1gcrfntpft5bbu5s.png.jpeg"></p> <p>You will see the GitHub activities for each candidate at once. It could help you to decide which library you would adopt!</p> <p>Warmly welcome to any comments/ideas to improve <code>gh-compare</code>!</p> 2018-09-22T09:21:00.000Z