OmniAICreator/Qiita-1.07M huggingface dataset:
getUserMediaでマイク音量を調整する

Chrome上でgetUserMedia()するときに、マイク音量を調整するメモ。
https://github.com/khwada/getusermedia_gain_microphone

## Audio録音
https://khwada.github.io/getusermedia_gain_microphone/gain_microphone_audio.html

getUserMedia()で取得したstreamをgainNodeを通して変換したstreamを録音する。
録音中にスライダーを触ってgainを変更しても、そこから音量変更が反映される。

```microphone_gain_audio.html

            const audioContext = new AudioContext();
            const gainNode = audioContext.createGain();
            const microphoneLevel = document.getElementById('microphoneLevel');
            const microphoneLevelText = document.getElementById('microphoneLevelText');
            microphoneLevel.addEventListener('change', (e) => {
                const value = e.target.value;
                console.log(`gain: ${value}`);
                gainNode.gain.value = value;
                microphoneLevelText.innerText = value;
            });
            microphoneLevel.value = gainNode.gain.value;
            const changeEvent = new Event('change');
            microphoneLevel.dispatchEvent(changeEvent);

            const record = document.getElementById('record');
            const stop = document.getElementById('stop');
            stop.disabled = true;
            let chunks = [];
            navigator.mediaDevices.getUserMedia({audio: true}).then((stream) => {
                const source = audioContext.createMediaStreamSource(stream);
                const audioDestination = audioContext.createMediaStreamDestination();
                source.connect(gainNode);
                gainNode.connect(audioDestination);
                const mediaRecorder = new MediaRecorder(audioDestination.stream);
                .....
```

## Video録画
https://khwada.github.io/getusermedia_gain_microphone/gain_microphone_video.html

同様にgainNodeを通したAudioと、getUserMedia()から取得したVideoTrackとから、新たなstreamを生成して録画する。

```microphone_gain_video.html

            navigator.mediaDevices.getUserMedia({audio: true, video: true}).then((stream) => {
                const source = audioContext.createMediaStreamSource(stream);
                const destination = audioContext.createMediaStreamDestination();
                source.connect(gainNode);
                gainNode.connect(destination);
                destination.stream.addTrack(stream.getVideoTracks()[0]);
                const mediaRecorder = new MediaRecorder(destination.stream);
                .....
```

## 参考
- [Using the MediaStream Recording API
](https://developer.mozilla.org/en-US/docs/Web/API/MediaStream_Recording_API/Using_the_MediaStream_Recording_API)
- [How to set volumes in WebRTC?](https://stackoverflow.com/questions/43698961/how-to-set-volumes-in-webrtc)
- [WebRTCを試すときにオッサンが映り続ける問題に対処する](https://qiita.com/massie_g/items/5a6c4b69374d5997dc37)
iOSアプリをNuxt.js使ってPWAにしたら意外と良かった話


# 経緯

GW前に Apple Developer Program の更新のお知らせメールが届く。
iOSアプリはここ2年近く（意識が低く）何も作れておらず更新を迷っていました。
年間メンバーシップの料金は 11,800円。

*これで家族で焼肉が食べれる（冗談）*


## PWA にしてみよう！

PWA が iOS 11.3 の Safari でも対応されたこともあり、GWを使って勉強がてらiOSアプリをPWAとして作ってみます。


# 開発について
使った技術など。

## JS Framework
今回は Nuxt.js を使うことにしました。
`@nuxtjs/pwa` を使って気軽にPWA化してみようと思います。


> @nuxtjs/pwa
https://github.com/nuxt-community/pwa-module

## CSS Framework
複雑なUIではないので今回は使いませんでした。
Material Design なら Web でもよく見かけるし Android向けアプリにも相性が良いので、作る機会があれば検討してみてもいいかなと思いました。


## どんな感じの出来か
開発時間は家事の合間の空き時間（2時間くらい）をみつけて3日ほど。
進捗は60%ほど…（RSSの検索・追加とSNSシェアとStorage保存が未実装）
ホスティングは Netlify を使っています。画面はこんな感じです。

![IMG_8651.TRIM-compressor.gif](https://qiita-image-store.s3.amazonaws.com/0/29554/26c3e031-f59e-0141-6d53-c916c836ae75.gif)

*個人的にはPWAいいなと思いました*

# 思ったこと
いざ取り掛かると色々考えることがあったので備忘録。

## CORS 設定が必要
アプリで外部APIを叩く場合は CORS の設定をする必要があります。

**Feedly API を YQL APIに**
今回はRSSのJSON化するためにiOSアプリでは Feedly API を使っていたのですがCORS許可されていないので、 YQL API に変更して対応しました。

## PWAにした場合の WebView の扱い
RSSリーダーで「もっと読む」みたいな外部リンクを押した場合に、iOSアプリではWebViewで記事を表示していましたが。PWAにした場合にどう扱えばいいのか悩みました。

**代表的なPWAの動作**

- Twitter Lite の場合: Safari で開く
- Instagram の場合: Safari で開く 
- dev.to の場合: PWA内で開く

**戻るボタンがないので 「Safari で開く」が良さそう**
manifest を browser とすればブラウザの戻るボタンが表示が可能ですが、
ほとんど場合 standalone で設定してブラウザの戻るボタンを非表示とすると思うので、導線がなくならないように外部リンクは「Safari で開く」とするのが良さそうです。
ただSafariで開くと遷移が発生しまうので個人的な体験は良くないなと思いました。

## ネイティブアプリの素晴らしさ
ネイティブ機能を使うようなアプリはネイティブで実装すべきというのは当たり前ですが、RSSリーダーのようなPWAに向いてそうなアプリでもムービーの自動再生やSNSシェア、WebViewなどに関して力を入れたい場合はネイティブの方が体験としては良いなと思いました。


## 個人開発には向いてる
PWAはネットワーク回線が遅い新興国向けに向いているそうですが、個人や学生さんが開発する場合にはOSやエディタに縛られずライセンス費用もかからないので気軽に作ることが出来ると思います。

> 結局 PWA は来るの？来ないの？
https://blog.agektmr.com/2018/03/instagram-pwa.html

# 最後に
まだ完成はしていないですが以下URLで確認は出来ます。
コードはかなり汚いので優しい目で見てもらえればと思います。

>今回作ったRSSリーザー
> https://yomu.jaxx2104.info/

あとは

> Github リポジトリ
> https://github.com/jaxx2104/yomu


このアプリ自体は 「Pulse」 というアプリが LinkedIn に買収されたことでサービス自体が変わってしまい残念な感じに。なら自分で作ってみよう的なRSSリーダーです。

- Titanium Mobile でアプリ公開
- Swift が発表されたタイミングでネイティブ移行
- PWA 作成してみた <- いまここ

さあ最後のGWはたんまり休むぞー！
My Portfolioを作ってみる　＃１

#受講講座
- ドットインストール
    - HTML入門
    - CSS入門

#HTMLの発見
- ナビゲーションを示す際に用いる `nav`
- 外部サイトへのリンク設定時に`target="_blank"`で新規立ち上げ。
- `a href="mailto:○○＠○○"`でメールが送れる。画像にも適応できる。
- 別ページに飛ばすには、○○.htmlを作り、`a href="○○.html"`で飛んでいく。

#cssの発見
- スラッシュを付けてしまったために、読み込みが実行できずにいました。試行錯誤をしまくって要らないことに気付いたのは、４時間後ぐらいでした。

```html
<link rel="stylesheet" href="css/style.css">

<link rel="stylesheet" href="/css/style.css">
```
- 色の表現方法

```css

color: rgb(0, 255, 0);
```
↑red green blue の頭文字

＃oo oo ff
赤 　緑 　青

コピペに頼りすぎて知らないことばかりでした。

- aタグのプロパティ

```css
text-decoration: none;
```
リンクの下線が消える

```css
color: inherit;
```
bodyタグにfontを設定したのに反映されていない。親要素を引き継がせるため使う。見直してみて分かったけど、自分の説明の意味が理解できない笑

- border

```css
border-radius:
```
四角を丸くする


#疑問点
- [ ] marginの設定が全体的に分からない。講師はここは○○pxにしたら良いとか、topが〜　bottomが〜っていう話は頭が追い付かなかったです。marginの相殺もなんとなく理解できたけど、まだ足りない。
- [ ] floatで要素の位置を変更する所は説明の速さに付いていけなかったので、あとで使い方を確認しておく。
- [x] ~~GitHubに記録を残そうと全コピペ（linkを少し弄る）したのに、CSSが読み込まれず、色なし画像なしのポートフォリオになってしまった。~~
[GitHub MyPortfolio](https://kwateru.github.io/MyPortfolio/)


<img width="1440" alt="スクリーンショット 2018-05-05 23.45.01.png" src="https://qiita-image-store.s3.amazonaws.com/0/213734/65eaa5fc-1456-3b95-5496-64d8b01eb648.png">

太郎くんの自己紹介のところがなぜか左に寄ってしまった。真ん中にもっていこうと変更すると、「楽しいゲームです」が中央揃えになってしまった。前にも同じようなことが起きたけど、その時もよく分からず放置のままだったような気がする。


#感想
ポートフォリオを作るのにhtmlとcssで簡単に作れてしまうことに驚いた。あと、cssが有能すぎた。そんなことも出来るのか、cssは！って何度もなりました。
CentOS7にGrafanaをインストールする

# はじめに
初めてのGrafanaです。今から手探りで勉強していこうと思います。CentOSのバージョンは7.4を使います。Grafanaのほうは、まだ良く分かっていません。[公式ページのインストレーションガイド](http://docs.grafana.org/installation/rpm/)に従って進めていきます。

# インストール
yum一発でインストール完了します。パッケージが纏まっているので楽です。

```
# yum install https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-5.1.0-1.x86_64.rpm

# rpm -qa |grep grafana
grafana-5.1.0-1.x86_64
```

# 起動
```
# systemctl start grafana-server
```

起動したらしいです。

# アクセス
HTTPで3000番ポートにアクセスとあるので、ブラウザからやってみます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/126284/7516b7df-b0c1-7f80-afeb-47739eca6169.png)

出てきました。青基調で格好いいですね！
初期ユーザ、パスワードのadmin/adminでログインします。

# パスワードの変更
真っ先にやることは、デフォルトパスワードの変更です。画面左下のアイコンをクリックして、Preferencesを選びます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/126284/4a837dc3-cec3-5897-a916-73d9b921030d.png)

次の画面で、Chenge Passwordを選択。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/126284/942dc73b-c75f-d30d-28c8-d4da3090b3f9.png)

新旧パスワードを入力して変更します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/126284/504c2a49-8fcd-0edd-7f42-d76edbbe7659.png)

できました！

# おわりに
次回はデータの表示を行いたいと思います。
MAC・iTerm・bashにブランチの状態を表示して使いやすくする

~~- bashに切り替える~~
~~```$ chsh -s /usr/local/bin/fish```~~

- Xcodeをインストール 
```$ xcode-select --install```

- Homebrewをインストール
```$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"```

- wgetをインストール
```$ brew install wget```

- wgetがインストール出来ない場合
```$ xcode-select --install```

- ブランチを表示する為のシェルを取得 
```$ cd /usr/local/etc/bash_completion.d/
$ wget https://raw.github.com/git/git/master/contrib/completion/git-completion.bash
$ wget https://raw.github.com/git/git/master/contrib/completion/git-prompt.sh```

- bashrcを作成し設定（ついでにいくつかエイリアス設定）
```$ cd ~
$ vim .bashrc```

```.bashrc
source /usr/local/etc/bash_completion.d/git-prompt.sh
source /usr/local/etc/bash_completion.d/git-completion.bash
GIT_PS1_SHOWDIRTYSTATE=true

PS1="\[\033[31m\]\W\[\033[00m\]\[\033[36m\]\$(__git_ps1)\[\033[00m\]\$ "
alias ll='ls -lG'
alias p='python'
alias p3='python3'
alias d='docker'
alias dc='docker-compose'
alias g='git'
alias gdns='git diff --name-status'

#
# git-completion.bash / git-prompt.sh
#
if [ -f /path/git-completion.bash ]; then
    source /path/git-completion.bash
fi
if [ -f /path/git-prompt.sh ]; then
    source /path/git-prompt.sh
fi
GIT_PS1_SHOWDIRTYSTATE=true
GIT_PS1_SHOWUNTRACKEDFILES=true
GIT_PS1_SHOWSTASHSTATE=true
GIT_PS1_SHOWUPSTREAM=auto
```

- .bash_profileの設定

```$ vim .bash_profile```

```.bash_profile
source ~/.bashrc
```

下記のエイリアスでさらに開発効率をアップ
[よく使うgitコマンドのエイリアスを設定して開発効率をアップする](https://qiita.com/unsoluble_sugar/items/ce14e9ce20aa5ba34fe5)

プロンプトを自由に変えたい場合はこちら
[Man page of CONSOLE_CODES](https://linuxjm.osdn.jp/html/LDP_man-pages/man4/console_codes.4.html#lbAD)
[役に立つかもしれないbashプロンプトの3tips](https://techracho.bpsinc.jp/yamasita-taisuke/2014_05_09/17140)
アンチウイルスソフトの影響で ruby のインストールに失敗した

- macOS 10.12.6
- rbenv v1.1.0

という環境で ruby 2.5.0 をインストールしようとしたら次のエラーが起こった：


```
$ rbenv install 2.5.0
ruby-build: use openssl from homebrew
Downloading ruby-2.5.0.tar.bz2...
-> https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.0.tar.bz2
Installing ruby-2.5.0...
ruby-build: use readline from homebrew

BUILD FAILED (OS X 10.12.6 using ruby-build 20180424)

Inspect or clean up the working tree at /var/folders/vt/h5389jvd5gn_1wcjk_jr5h080000gn/T/ruby-build.20180525230737.6484
Results logged to /var/folders/vt/h5389jvd5gn_1wcjk_jr5h080000gn/T/ruby-build.20180525230737.6484.log

Last 10 log lines:
translating probes probes.d
compiling bignum.c
compiling class.c
compiling compar.c
error: error reading '/dev/fd/9'
1 error generated.
clang: error: unable to remove file: Operation not permitted
dtrace: failed to compile script probes.d: Preprocessor failed to process input program
make: *** [probes.h] Error 1
make: *** Waiting for unfinished jobs....
```

すかさず `error reading '/dev/fd/9'` あたりでググると Avira antivirus を無効にするとインストールできるとの噂が...

[Error while installing ruby 2.1.1 and newer versions (error reading '/dev/fd/9') · Issue #1074 · rbenv/rbenv · GitHub](https://github.com/rbenv/rbenv/issues/1074#issuecomment-387652518)

ちょうど Avira を使っていたのでメニューの「リアルタイム保護を無効にする」から無効にして、再度インストールを試したところインストールできた :tada:
（このあと再度保護を有効にすることをお忘れなく）
AWS Webアプリ公開③~IAM編~

#前説
結構前の内容になりますが、投稿し忘れていたので・・・
AWSを使っていると、ユーザーのセキュリティに気を配る必要が出てくるなあと感じるようになりました。
ここでは二重認証をすることによってセキュリティの強化に励んでみました。

#二重認証がなぜ必要か
近年では多くのサービスで二重認証が採択されているようです。二重認証を行ってると、アカウントの乗っ取りのリスクも軽減するそう。様々な企業ではもはや当たり前だそうですね。

#AWS IAM
IAMとはユーザーアクセスと暗号化キー作成を行うサービスです。
セキュリティグループやIAMユーザーを作成し、アクセス権限やロールの設定、二重認証を行ってくれます。

##二重認証

二重認証を行うことによって
- AWS ログインID
- ユーザー名
- パスワード
- MFA端末で確認できるMFA番号
が必要となるよりセキュアなログイン認証が可能になりました。

MFA認証は手元にスマートフォンにて「Authy」という認証専門アプリがおすすめです。

以下のサイトに従って設定を設定をしていくと、おそらく認証できるようになると思います。

https://qiita.com/yoshidashingo/items/cd206daca0596659b440
https://muji-house.co/it/internet/aws-mfa/

##IAMユーザー
AWSの世界には2種類の人間がいます。

一つは
AWSアカウント作成時に作成される何でもできるユーザー・・・rootユーザー

もう一つは
ある程度の権限が与えられているユーザー・・・IAMユーザー

rootユーザーがIAMユーザーに対して権限を与えていきます。

<img width="811" alt="スクリーンショット 2018-05-25 23.18.42.png" src="https://qiita-image-store.s3.amazonaws.com/0/253129/bdab8265-6034-5b80-85e6-4af8953312ff.png">

セキュリティステータスというページが出てきます。

##ルートアカウントのMFAを有効化
これは上記の設定(二重認証)をルートアカウントでも行うものです。

##個人のIAMユーザーを設定
とある権限のみを持たせるユーザーの作成(ex.VPC、 EC2のみをいじれる権限)。

<img width="1244" alt="スクリーンショット 2018-05-25 23.21.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/253129/ff51686e-7d42-622d-fd05-53b08bcce417.png">

<img width="1243" alt="スクリーンショット 2018-05-25 23.22.02.png" src="https://qiita-image-store.s3.amazonaws.com/0/253129/449fddc2-509c-07eb-b82f-23bc7c1c2cd0.png">

FullAccessを持たせるとそのサービスに関する権限を全て与えることになりますね。

##グループを利用してアクセス許可を割り当て
これは一つのグループを作成して、そのグループに属するユーザーの権限を一括管理できます。

グループを作成するのはシステム管理や企業での活用が多いのではないでしょうか。

#最後に
IAMを少し触って見て感じたことはPermission Deniedなどの権限エラーはこいつらがもしかしたら絡んでいる可能性もある。しかし、余計な権限をつけてはならない。余計な権限をもらわないことで、実際、何かトラブルが発生した際、自分の潔白を示すことができるのだと。

暇があれば続きルートアクセスキーなどの詳細も書いていこうかなと思います。
Macのデータ移行後にvirtualboxでエラー発生（Kernel driver not installed...）

Macの移行アシスタントを使ってデータを移行したら、
virtualboxでエラーが発生したので、メモ。

エラーメッセージ

```
Kernel driver not installed (rc=-1908)

Make sure the kernel module has been loaded successfully.

where: suplibOsInit what: 3 VERR_VM_DRIVER_NOT_INSTALLED (-1908) - The support driver is not installed. On linux, open returned ENOENT. 
```

カーネルドライバがインストールされていない
カーネルモジュールが正常にロードされたことを確認してください。との事。



##解決方法


同じような症状が出ている方の記事を参考にさせていただき、
試行錯誤するも、エラーは解消せず。
結局virtualboxをダウンロードし直すことで解決となりました。

virtualboxのダウンロードはこちらから
[http://www.oracle.com/technetwork/server-storage/virtualbox/downloads/index.html#vbox](http://www.oracle.com/technetwork/server-storage/virtualbox/downloads/index.html#vbox)

*もしダウンロードが出来ない場合は、システム環境設定のセキュリティーとプライバシーを確認する事！ダウンロードの許可をすれば、OK。

無事virtualboxが起動されるようになりました。

おわり。

参考：
[https://qiita.com/ottyajp/items/72febadd445ea31b934a](https://qiita.com/ottyajp/items/72febadd445ea31b934a)

[http://haiju.hatenablog.com/entry/2017/05/23/073723](http://haiju.hatenablog.com/entry/2017/05/23/073723)
高機能ホスティングサーバNetlifyが、はてなブックマークの対応をしてくれた話

Googleのrobotsは、SPA/PWSでもJavaScriptレンダリング後をチェックしてくれるので、SPA/PWAが検索結果にでないということはなくなりました。

参考：Googleのrobotsが表示してる内容を確認できる[「Fetch as Google」](https://support.google.com/webmasters/answer/6066468?hl=ja)

<img width="1110" alt="スクリーンショット 2018-05-25 22.30.16.png" src="https://qiita-image-store.s3.amazonaws.com/0/100460/c997a270-3fad-c89c-f80f-8f4803265f06.png">

また、prerenderingを使うと、FacebookのOGP/Twitterカードもちゃんと認識してくれるので、SSRせずとも、WebサイトをSPA/PWAでつくる物理的障壁はなくなったなと感じていて、WebサイトをSPA/PWAにリニューアルして気づいたのです。

**はてなブックーマはprerenderingでも認識せず、JavaScriptレンダリング前の結果が表示される。**



で、いろいろ聞いたり調べてみたところ、prerenderingはUserAgentで分岐させてレンダリング結果を返しており、その登録されてるUserAgentにはてなブックマークが入っていないようでした。



参考： https://gist.github.com/thoop/8165802#file-nginx-conf-L20



UserAgentさえいれてもらえれば・・・と希望をいだきながら、はてなさんの問い合わせ窓口にUserAgentを教えてもらったあと、Netlifyの問い合わせからUserAgentの追加をお願いしたところ、今週、追加したよと返信がありました！！

> Just notifying you that the Hatena user agent has been added to our configuration. Our system should not serve the prerendered version of your content to that bot. Thanks for your patience!

ですので、これからは、はてブボタンつけてても、Netlifyで気兼ねなくSPA/PWAできそうです。はてな社、およびNetlifyチームの皆様、ありがとうございました！！

追記　`b.hatena.ne.jp/entry/s/【追加するURL名】` は機能するものの `b.hatena.ne.jp/【account名】/add` からURLを入力したらレンダリング前の結果が返ってくる現象については、現在はてな社にこのふたつのUserAgent違うのではないかと問い合わせ中です。
stmtk徒然日記1日目

# 5 / 28 (Tue)
## Unityでルービックキューブを作ろうとした
Unityは色々噂を聞いていたのでそのうち触りたいと思いつつ、先延ばしにしてきたが、実際にいじってみるとなかなか難しい。開発者が書くソースコードの量をできる限り減らそうという意思が伝わってくる。
ルービックキューブを作ろうと思ったので6面すべて色の違う立方体が作りたかった。Cubeで普通の立方体は作れるが、色はすべて同じにしなければならないらしいので、Quadというものを6つ作りそれを組み立てる感じで作るらしいということまでわかった。
明日はQuadの色の変え方を知りたい

## brain f*ckからGoへの変換
寝る1時間ほど前にGoからbrain f*ckへ変換するためのコードを書いていたのだが、普段使わないので文法がわからず寝るまでに終わらなかった。明日はこれも完成させたい。


# 二日目(5/27(Mon))
## dockerはじめました
VMとは若干違うけど、MacでCentOSが使えるみたいな話だったのでインストールしてみた。
https://qiita.com/mks1412/items/9356187a3bcb20b64e82
https://qiita.com/wMETAw/items/b9bc643ded4b92bf6add
１時間かけて、この辺のサイトを参考にしてインストールして使ってみたもののあまり使い方がわからないので、明日は「dotinstallを使ってインストールしてみたい。

# altseedの使い方がわからない
altseedは筑波大学のOBさん達が管理をしているライブラリらしいが、とりあえずサンプルコード書いてみて動かそうと思ったもののエラーが出たのでまた明日触りたい。

# ABC098 Dの解法
本当は昨日ACさせようと思ってたが、思いの外時間がなくて書く時間がなかった。これも明日挑戦したい。

# Unityのインストール
ルービックキューブのソールバーを作りたいので、とりあえずインストールしてみた。

#1日目(5/25 (Fri))
## brain f*ck -> php

今日はYYPHPという勉強会に参加するので、２年ぶりにPHPを触ってみた。久しぶりにPHPを触っていくつか独特だなぁと思う点があった。

- phpにはrubyでいうindex Errorがない（配列の任意のインデックスに代入はできるが、まだ代入されていないインデックスの要素を取得しようとするとエラーになる）
- 配列の大きさを指定して配列のインスタンス（？）を作成できない。（調べても出てこなかった）

今まで見た中でこんな特徴があるのはPHPだけなので新鮮だった。

## YYPHP

実際に参加して驚いたのが、以外にVue.jsの話題が多かった。一応RailsやReact.jsの話もちょろっと出てきたので参加してる時にはそこまで気にならなかったが、今思い返してみると、多いと思う。もしかしたら相性がいいのかもしれない。

安いレンタルサーバが借りられるという噂なので、一つ借りて何かサービスを作って見てもいいかもしれない。

この勉強会の特徴が誰でも自由に発言できるところだと思う。よくある勉強会だと他の人の発表を聞いて満足してしまうケースが多いのでいい刺激になった
PythonJSON、辞書を取り扱う時に便利なdotmapライブラリの紹介

言葉で説明するよりコードを見てもらった方が早いのでいざ。

### 基本的な使い方

[PyPi - dotmap](https://pypi.org/project/dotmap/)

```python3:基礎
from dotmap import Dotmap

m = DotMap()

# 定義なしでメンバ変数へアクセスできるような振る舞いをする
m.name = "Mark"

print(m)
# DotMap([('name', 'Mark')])
print(m.name)
# 'Mark'

# dictのようなアクセスもできる
m["name"] = "Adam"

print(m["name"])
# 'Adam'
```

```python3:応用
# ネストされた値へのアクセスもできる
m.person.steve.age = 31

# 中身はこんな感じ
print(m)
"""
DotMap([('name', 'Adam'), 
  ('person', DotMap([('steve', DotMap([('age', 31)]))]))])
"""
```

### 具体例

[Github - Keras-Project-Template](https://github.com/Ahmkel/Keras-Project-Template)のように設定をjsonファイルに記述しておき、値を読み出す使い方が便利でしょうか。

```json:config.json
{
	"model": {
		"lerarning_rate ": 0.001,
		"momentum": 0.0,
		"decay": 0.0
	}
}
```

```python3
import json
from dotmap import Dotmap

with open("config.json", 'r') as config:
    config_dict = json.load(config)

dotmap_config_dict = Dotmap(config_dict)

print(dotmap_config_dict)
"""
DotMap([('exp',
         DotMap([('lerarning_rate', 0.001),
                 ('momentum', 0.0),
                 ('decay', 0.0)]))])
"""
```
以上です、読んで頂きありがとうございました。

# 参考
- [Github - dotmap](https://github.com/drgrib/dotmap)
- [Github - Keras-Project-Template](https://github.com/Ahmkel/Keras-Project-Template)
- [PyPi - dotmap](https://pypi.org/project/dotmap/)
html,cssでReactスピナー

cssのanimationの勉強ついでにスピナーでも作ってみようといじっていたら出来ていた。
# コード
<p data-height="265" data-theme-id="0" data-slug-hash="QrXVda" data-default-tab="css,result" data-user="kodamaparadise" data-embed-version="2" data-pen-title="QrXVda" class="codepen">See the Pen <a href="https://codepen.io/kodamaparadise/pen/QrXVda/">QrXVda</a> by kodama (<a href="https://codepen.io/kodamaparadise">@kodamaparadise</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

要素の大きさ分右に寄ってるので、中心の円の位置が目分量 :sweat_smile:
WSLを楽しく使う

## はじめに

Windows 10標準のLinux仮想環境、Windows Subsystem for Linux（以下WSL）は着実に進歩してますが、デフォルトのままだとまだまだ使い勝手が悪い部分があります。ここでは快適に楽しく使うために個人的に試したことを紹介します。

なお、試したのは Windows 10 Insider Preview Build 17672の環境です。それより古いバージョンだと動作しない場合があります。

## コマンドプロンプトからのWSLの起動

WSLを起動する方法はいくつかありますが、以下のように`wsl.exe`コマンドにディストリビューションを指定する方法を覚えておけば今後変更があってもつぶしがききそうです。

```shell-session
> wsl.exe -d distribution
```

指定可能なディストリビューションの一覧は以下のコマンドで表示されます。

```shell-session
> wslconfig.exe /l
```

ディストリビューションを省略すると規定のディストリビューションが立ち上がります。これは`wslconfig.exe`コマンドで変更できます。

詳しくは下記参照。

* [Manage Linux Distributions | Microsoft Docs](https://docs.microsoft.com/ja-jp/windows/wsl/wsl-config)

## ターミナル環境

Windows10標準のターミナルはバージョンによって日本語がうまく表示できなくなったり、コマンドによっては表示が崩れたり、使い勝手も今ひとつなので、**Hyper**というオープンソースのターミナルソフトをいれました。複数タブに対応し、ひとつのタブを水平または垂直方向に分割可能です。インストールは以下のリンクから。

* https://hyper.is/

### シェルの選択

Hyperには起動するシェルを複数登録して選択する機能はありません。そこで、シェル選択用のbatファイルを用意し、Hyper のShellとして登録しています。以下のファイルではcmd, Powershell, ubuntu, ubuntu1804, debian という5つのシェルの中から選択するようにしています。

* [hyperstart.bat](https://gist.github.com/ssugiyama/c28e10aa656e5a6aba210e7cd907cc3a)

## Windows環境とのファイル共有

### パスの変換

Windowsの `C:\User\you\Documents` というパスはWSLでは`/mnt/c/Users/you/Documents`として見えます。この変換はほとんどの場合自動で行われますが、明示的に行いたい場合WSL上に`wslpath`というコマンドが用意されてます。

```shell-session
$ wslpath 'C:\Users\you\Documents'
/mnt/c/Users/you/Documents
$ wslpath -w /mnt/c/Users/you/Documents
C:\Users\you\Documents
```

### metadata の設定

Windowsのファイルに対してLinuxのファイル属性を設定したりオーナー変更をすることができるようになりました。設定した内容は他のLinuxディストリビューションでも共有されます。mount時のオプション指定でも可能ですが、`/etc/wsl.conf`というファイルを作成して以下のように設定するのが、自動化できて便利です。

```conf
[automount]
options = "metadata"
```

WSLを再起動すると反映されます。

wsl.confの書式については下記を参照。

* [Automatically Configuring WSL – Windows Command Line Tools For Developers](https://blogs.msdn.microsoft.com/commandline/2018/02/07/automatically-configuring-wsl/)

## プロンプト設定

複数のLinuxのディストリビューションやバージョンを使い分けるときに間違いやすいので、プロンプトに表示するようにしています。以下の記述を $HOME/.bashrc に追加しました。

```shell
case "$TERM" in
    xterm-color|*-256color) color_prompt=yes;;
esac
OS=$(awk -F'=' '/PRETTY_NAME/ {print $2}' /etc/os-release | sed 's/"//g')
if [ "$color_prompt" = yes ]; then
    PS1="\033[01;32m$OS\[\033[00m:\033[01;34m\]\w\[\033[00m\]\$ "
else
    PS1="$OS:\w\$ "
fi
```

## 環境変数の受け渡し

WindowsからWSLを起動するときと、WSLからWindowsのプロセスを起動するときに環境変数を渡すしくみが用意されました。渡す環境変数のリストを`:`区切りで `WSLENV`という環境変数に指定します。たとえばWindowsの`USERPROFILE`と`USERNAME`をWSLに渡したい場合は、

```shell-session
> set WSLENV=USERPROFILE:USERNAME
```

としてからWSLを起動します。

サフィックスをつけることで、それぞれの環境変数のパスの形式を変更することもできます。詳しくは下記ページを参照。

- [Share Environment Vars between WSL and Windows – Windows Command Line Tools For Developers](https://blogs.msdn.microsoft.com/commandline/2017/12/22/share-environment-vars-between-wsl-and-windows/)



## おわりに

あとこれでWSLからGPUにアクセスできるようにしてもらえると、いったん文句ないです。
Macにastah* 6.9をインストール


バージョン7以降は商用利用不可なので6.9をインストールしたかった。

**しかし、Macではインストールしただけでは起動時にエラーで落ちる。**

[Macで、astah* バージョン 6.9が起動しない不具合](https://ja.astahblog.com/2017/09/27/6-9-no-launch-on-mac/)
こちらにある通り、追加でJavaの更新とjre入れ替えをする必要があった。

## インストール手順

1. astah* 6.9をインストール
1. JDK8をインストール
1. JDK8のjreをastahアプリのjreに上書きコピー


3の手順は以下。

```shell
JRE=`find /Library/Java -type d | grep 'jre$' | head -1` 
cp -a $JRE /Applications/astah\ community/astah\ community.app/Contents/PlugIns/JDK/Contents/Home/jre_new
cd /Applications/astah\ community/astah\ community.app/Contents/PlugIns/JDK/Contents/Home/
mv jre jre_old
mv jre_new jre
```

---
swiftでHMAC SHA256署名

クライアントだけでSHA256署名する方法に少しつまったのでメモ
仮想通貨の取引所のAPIを叩く際に必要なことが多いようなので誰かに役に立てれば。。

# 実装

こちらのライブラリを使用
[CryptoSwift](https://github.com/krzyzanowskim/CryptoSwift)

`cocoapods`で恒例のインストール

```
pod 'CryptoSwift'
```

以下のように使用

```swift
var bytes: [UInt8] = []
      
bytes += "署名したい文字列".bytes
        
let signedString = try? HMAC(key: "署名したいキー", variant: .sha256).authenticate(bytes)

```
dockerのJenkinsコンテナでエラーが発生した場合の対応

## 概要
DockerでJenkinsをお手軽に作成して使っていたら、コンテナ再作成後エラーでログインできなくなったので、調べた内容をメモしておく。

## エラー内容
下記のようなエラーが出た。

```:エラー内容
org.xmlpull.v1.XmlPullParserException: only 1.0 is supported as <?xml version not '1.1' (position: START_DOCUMENT seen <?xml version=\'1.1\'... @1:19) 
    at org.xmlpull.mxp1.MXParser.parseXmlDeclWithVersion(MXParser.java:2608)
    at org.xmlpull.mxp1.MXParser.parseXmlDecl(MXParser.java:2592)
    at org.xmlpull.mxp1.MXParser.parsePI(MXParser.java:2466)
    at org.xmlpull.mxp1.MXParser.parseProlog(MXParser.java:1447)
    at org.xmlpull.mxp1.MXParser.nextImpl(MXParser.java:1395)
    at org.xmlpull.mxp1.MXParser.next(MXParser.java:1093)
    at com.thoughtworks.xstream.io.xml.XppReader.pullNextEvent(XppReader.java:109)
　　　　　　　　　　　　　　　　　　・
　　　　　　　　　　　　　　　　　　・
　　　　　　　　　　　　　　　　　　・
```

## 原因
おそらく調子にのってJenkinsの管理画面から自動アップグレードを行ってしまったからなのか・・・。
コンテナを再作成すると、アップグレード前の状態に戻るが、設定は永続化して残しているので、そこら辺でエラーになってるのではないかと思う。

## 対処方法
config.xmlを修正すると復活できるようです。

**使っているコンテナ例)**
https://hub.docker.com/r/reflet/docker-jenkins/
※ ここでのコマンド例は、「 docker-compose up -d 」で起動しているとします。

### 1. Jenkinsコンテナへ接続
コンテナ自体は、起動しているので接続して操作する。

```bash:ターミナル
$ docker exec -it jenkins bash
```

### 2. config.xmlの修正
```bash:ターミナル
$ cd /var/jenkins_home/
$ vi config.xml

　1行目のversionを修正 (1.1 -> 1.0)
　<?xml version='1.1' encoding='UTF-8'?>

$ exit
```

### 3. Jenkins再起動
```bash:ターミナル
$ docker-compose restart jenkins
```

### 4. Jenkinsのバージョンアップ

下記URLへアクセスして、管理者権限のあるユーザーでJenkinsへログインする。

http://loalhost:8080/manage
※　管理画面でJenkinsの自動アップデートを実行して、Jenkinsを再起動する

以上


## 参考サイト
* [Jenkinsの起動後のエラー](https://teratail.com/questions/114431)
[iOS]Push通知用の証明書と秘密鍵が有効かをopensslで確認する

Apple Developerセンターから作成したpush通知用の`署名つき証明書`と`秘密鍵`で、AppleのPush通知APIへhttpsリクエストできるかを`openssl`コマンドで確認が出来る。

```-cert,-keyオプションのみで実行する.
$ openssl s_client -connect gateway.sandbox.push.apple.com:2195 -cert dev_cert.pem -key dev_pkey.pem
```

```実行結果.
+[master]
CONNECTED(00000006)
depth=1 C = US, O = "Entrust, Inc.", OU = See www.entrust.net/legal-terms, OU = "(c) 2012 Entrust, Inc. - for authorized use only", CN = Entrust Certification Authority - L1K
verify error:num=20:unable to get local issuer certificate
verify return:0
---
Certificate chain
 0 s:/C=US/ST=California/L=Cupertino/O=Apple Inc./CN=gateway.sandbox.push.apple.com
   i:/C=US/O=Entrust, Inc./OU=See www.entrust.net/legal-terms/OU=(c) 2012 Entrust, Inc. - for authorized use only/CN=Entrust Certification Authority - L1K
 1 s:/C=US/O=Entrust, Inc./OU=See www.entrust.net/legal-terms/OU=(c) 2012 Entrust, Inc. - for authorized use only/CN=Entrust Certification Authority - L1K
   i:/O=Entrust.net/OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/OU=(c) 1999 Entrust.net Limited/CN=Entrust.net Certification Authority (2048)
---
```

認証局での証明書検証が出来なかったため`verify error:num=20:unable to get local issuer certificate`とエラーメッセージが出力されている模様。
これは`-CAfile`オプションで認証局の証明書パスを指定することにより解消できる。
`openssl`ではブラウザのように認証局の証明書を取りに行かないので、手元に[ダウンロード](https://www.entrustdatacard.com/pages/root-certificates-download)し指定する必要がある。

```-CAfileオプションも付けて実行する.
$ openssl s_client -connect gateway.sandbox.push.apple.com:2195 -cert aps.pem -key app.pem -CAfile /Users/hoge/entrust_2048_ca.cer
```

```実行結果.
CONNECTED(00000006)
depth=2 O = Entrust.net, OU = www.entrust.net/CPS_2048 incorp. by ref. (limits liab.), OU = (c) 1999 Entrust.net Limited, CN = Entrust.net Certification Authority (2048)
verify return:1
depth=1 C = US, O = "Entrust, Inc.", OU = See www.entrust.net/legal-terms, OU = "(c) 2012 Entrust, Inc. - for authorized use only", CN = Entrust Certification Authority - L1K
verify return:1
depth=0 C = US, ST = California, L = Cupertino, O = Apple Inc., CN = gateway.sandbox.push.apple.com
verify return:1
---
Certificate chain
 0 s:/C=US/ST=California/L=Cupertino/O=Apple Inc./CN=gateway.sandbox.push.apple.com
   i:/C=US/O=Entrust, Inc./OU=See www.entrust.net/legal-terms/OU=(c) 2012 Entrust, Inc. - for authorized use only/CN=Entrust Certification Authority - L1K
 1 s:/C=US/O=Entrust, Inc./OU=See www.entrust.net/legal-terms/OU=(c) 2012 Entrust, Inc. - for authorized use only/CN=Entrust Certification Authority - L1K
   i:/O=Entrust.net/OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/OU=(c) 1999 Entrust.net Limited/CN=Entrust.net Certification Authority (2048)
---
```

エラーが消えた。
Win32-OpenSSHで公開鍵認証を行う

Windows環境にOpenSSHをインストールして、公開鍵認証の設定を行いました。

#使用した環境

- OpenSSHのサーバー
Windows Server 2012 R2
Win32-OpenSSH 0.0.24.0(64-bit)
PSTools 2.45

- OpenSSHのクライアント
Windows Server 2008 R2
Win32-OpenSSH 0.0.24.0(64-bit)
PSTools 2.45

たまたま使える環境がこの2台だったためOSが揃っていませんが、この組み合わせでなければいけないということはありません。

#Win32-OpenSSHのインストール
Win32-OpenSSHは、サーバー側、クライアント側の両方にインストールします。
以下の手順でインストールしました。

- 「[https://github.com/PowerShell/Win32-OpenSSH/releases](https://github.com/PowerShell/Win32-OpenSSH/releases)」から「OpenSSH-Win64.zip」をダウンロードします。
32 bit OSの場合は、「OpenSSH-Win32.zip」を使用してください。
- 「OpenSSH-Win64.zip」を展開し、任意の場所に配置します。
- Windows Powershellを管理者で起動します。
- 以下のコマンドを実行します。

```powershell
cd “OpenSSH-Win64.zipの展開先フォルダパス” 
Set-ExecutionPolicy Unrestricted
.\install-sshd.ps1
ssh-keygen.exe –A
.\FixHostFilePermissions.ps1 -Confirm:$false
Set-ExecutionPolicy Restricted
```


- Windowsサービス画面で[ssh-agent]を起動します。
- 「[https://docs.microsoft.com/ja-jp/sysinternals/downloads/pstools](https://docs.microsoft.com/ja-jp/sysinternals/downloads/pstools)」からPsToolsをダウンロードし、任意の場所に展開します。
- コマンド プロンプトを管理者で起動し、以下のコマンドを実行します。

```powershell
cd “PSTools展開先フォルダパス”
psexec.exe -i -s cmd.exe
```

- 新たに起動されたコマンド プロンプトで以下のコマンドを実行します。

```powershell
ssh-add ssh_host_dsa_key
ssh-add ssh_host_rsa_key
ssh-add ssh_host_ecdsa_key
ssh-add ssh_host_ed25519_key
```

- Windows ファイアウォールの詳細設定でsshdの受信を許可します。
- Windowsサービス画面で[ssh-agent]と[sshd]のスタートアップの種類を自動にし、サービスを開始します

#公開鍵認証の設定（クライアント側）
クライアント側のマシンに公開鍵認証の設定を行います。

- コマンド プロンプトを起動し、以下のコマンドを実行します。

```
ssh-keygen -t rsa -f id_rsa
net start ssh-agent
ssh-add id_rsa
```

1行目のssh-keygenコマンドを実行するとpassphraseを聞いてくるので、空を指定します。

#公開鍵認証の設定（サーバー側）
サーバー側のマシンに公開鍵認証の設定を行います。

- クライアント側に作成された「id_rsa.pub」ファイルをリモートサーバーにコピーします。
    - コピー元：クライアント側の「OpenSSH-Win64.zipの展開先フォルダ\id_rsa.pub」
    - コピー先：サーバー側の「%systemdrive%\Users\<user>\.ssh\authorized_keys」
- 配置した「authorized_keys」のプロパティ画面でアクセス許可に「NT Service\sshd」を追加し、[読み取り]を許可します。


**[読み取り]以外の項目を許可するとエラーになるため、[読み取り]のみを許可する必要があります！**

#確認
クライアント側のマシンでコマンド プロンプトを起動し、以下のコマンドを実行します。

```
cd “OpenSSH-Win64.zipの展開先フォルダパス” 
ssh -i .\id_rsa user@host
```

2行目のuser部分にはサーバー側の設定でコピー先パスの<user>部分に指定したユーザーを、host部分にはサーバー側のマシン名を指定します。


続けて、以下のコマンドを実行します。

```
Are you sure you want to continue connecting (yes/no)?
```

「yes」と入力して[Enter]キーを押します。

コマンド プロンプトのウィンドウタイトルが「OpenSSH SSH client」に切り替わったら、リモートログイン成功です。

#参考URL

- [https://github.com/PowerShell/Win32-OpenSSH/wiki/Install-Win32-OpenSSH#install-win32-openssh-test-release](https://github.com/PowerShell/Win32-OpenSSH/wiki/Install-Win32-OpenSSH#install-win32-openssh-test-release)

- [https://github.com/PowerShell/Win32-OpenSSH/wiki/ssh.exe-examples#login-with-ssh-keys](https://github.com/PowerShell/Win32-OpenSSH/wiki/ssh.exe-examples#login-with-ssh-keys)
Javaのお勉強 ～その5～ 定数

# 1. はじめに
今回は、変数と対極的な定数についての解説です。

変数は、値が変わる。
定数は、固定の値。

といった感じですね。
後々に値を変更することが、できないようにするのが定数です。 

# 2. 定数の宣言
では、定数の宣言方法についてみてみましょう。
また、宣言と同時に初期化する方法も紹介します。 

```java:Main.java
public class Main {
	public static void main(String[] args) {

		// 定数の宣言 & 初期化
		final int MAX_VALUE = 100;

	}
}
```

型の前に final というものをつけることで、定数として宣言していることになります。 
また、宣言と同時に値を代入し、初期化しています。

# 3. 定数を使う
定数の使い方については、代入ができないだけで、変数のように値として使うことができます。
例えば、下のように

```java:Main.java
public class Main {
	public static void main(String[] args) {

		// 「定数 MAX_VALUE」の宣言 & 初期化
		final int MAX_VALUE = 100;

		// 「変数 first」の宣言 & 初期化
		int first = 200;

		// 「変数 second」の宣言
		int second;

		// 「定数 MAX_VALUE」と「変数 first」を足した値(100 + 200)を「変数 second」に代入
		second = MAX_VALUE + first;

		// 300 と出力される
		System.out.println(second);

	}
}
```

「300」と出力されればオッケーです！

ざっくりと処理の流れは、
定数「MAX_VALUE」と変数「first」を足した値が、変数「second」に代入。
変数「second」を出力する。
といった感じでしょうか。


# 4. 定数の確認
ちなみに、本当に定数となっているか確認をしてみましょう。
以下のプログラムをコンパイルしてみると、、

```java:Main.java
public class Main {
	public static void main(String[] args) {

		// 定数の宣言 & 初期化
		final int MAX_VALUE = 100;

		// 代入する
		MAX_VALUE = 123;

	}
}
```

エラーになりますね。
定数に値を代入しようとするとコンパイル時点でエラーになってしまいます。

後から値を代入することは出来ないってことが分かりました！ﾖｼﾖｼ

# 5. おわりに
定数は、プログラムを書く際に複数箇所に同じリテラルを使うとなった場合に、宣言しておくと非常に便利になります。

例えば、100 回も円周率の 3.14 をリテラルで記述するプログラムがあったとします。

```java:Main.java
public class Main {
	public static void main(String[] args) {

		// 3.14 + n (nを100まで書きたい)
		System.out.println(3.14 + 1);
		System.out.println(3.14 + 2);

		// 中略

		System.out.println(3.14 + 99);
		System.out.println(3.14 + 100);

	}
}
```
~~ほぼありえないプログラムですけどあくまで例ということで~~

100 回も書いていれば、そのうち間違える可能性もあります。
（3.15と書いてはコンパイルエラーにもならないので、大変気付きにくい）
さらにもし、3.14159265 と桁数を増やしたくなった場合は、100 箇所修正しなくてはならなくなります。

ですので、定数として宣言しておけば、その定数を使いまわすことでミスも減らせますし、変更したくなった場合は、定数の値を変更するだけでいいので、変更に強くなります。 

```java:Main.java
public class Main {
	public static void main(String[] args) {

		// 定数「PI」の宣言
		final double PI = 3.14;

		// 3.14 + n (nを100まで書きたい)
		System.out.println(PI + 1);
		System.out.println(PI + 2);

		// 中略

		System.out.println(PI + 99);
		System.out.println(PI + 100);

	}
}
```

定数はソースコードの読みやすさ（可読性）にも関わります。
初めから決まった値だと分かっていれば、定数を使うようにしましょう。

次回は「演算子」についての記事を解説します。
以上です。

次回 →「[Javaのお勉強 ～その6～ 演算子](https://qiita.com/koukonko/items/7c94d00aed1ae1741da3)」
Pandocを用いてmarkdownからtex経由で日本語pdfを作成する方法

#はじめに
* markdown形式だと簡単に文書を書くことができる（数式，図，表を比較的容易に入れられる）
* markdown形式だとtexほどのきれいな文書はできない（微調整が効きづらい）
* markdownで作られた文章(.md)は（紙媒体にするならともかく）環境依存の形式である

#やりたいこと
* 1. markdownで文章（数式や表，図を含む）を作成する
* 2. pandocを用いてtex形式に変換する
* 3. 細かな調整をtexにて行う
* 4. pdf形式にして完成

#手順
## 1. markdownで文章（数式や表，図を含む）を作成する

* 私は普段[Visual Studio Code](https://code.visualstudio.com/download "ダウンロードページ")で作っています．

拡張機能としては以下のものを使っていますが，シンタックスハイライトとプレビューがあれば特に困ることはないかと思います．
>
* [Markdown All in One](https://marketplace.visualstudio.com/items?itemName=yzhang.markdown-all-in-one "markdown形式文書作成のサポート")
* [Markdown Preview Enhanced](https://marketplace.visualstudio.com/items?itemName=shd101wyy.markdown-preview-enhanced "リアルタイムでプレビューが見える")
* [Markdown+Math](https://marketplace.visualstudio.com/items?itemName=goessner.mdmath "数式")
>

### 注意点
作成するファイル(.md)の先頭行に

```test.md
---
header-includes:
    -   \usepackage{amsmath}
geometry: margin=1in
documentclass: article
papersize: letter
fontsize: 11pt
title: "タイトル名"
author: 著者名
date: 日付
---
```
などと入れておくと.texのプリアンブルに埋め込んでくれます．ものによってはエラーが出るかもしれないので必要最低限もので．

## 2. pandocを用いてtex形式に変換する
* [pandoc](https://pandoc.org/ "ダウンロードページ")とは，markdownなどで作られたファイルをhtml, tex, pdf, docxなどに変換してくれるソフトです．

* 左側タブの'Installing'をクリックしてダウンロードしてください．特筆すべき注意点はなかったはず

* インストールしたら起動させます．Windowsのコマンドプロンプトみたいな画面が出てきます．
* 'cd'で変換したい.mdファイルがあるディレクトリに移動して以下のように入力します．

```
pandoc xxx.md -s -o yyy.tex -V documentclass=ltjarticle
```

### 注意点

'-s'は.texから.pdfに変換する際に必要な情報を書き込むためのオプションなので**必ずつけてください**
'-V documentclass=ltjarticle'は，日本語を含む文章を変換する際に必要なオプションです．**これも必ずつけてください．**

問題がなければこれで.texの文章に変換されるはずです．

## 3. 細かな調整をtexにて行う
変換によって作られた.texファイルは'LuaLaTeX'対応（そもそもpandocからの変換に対応しているのはXeLaTeXとLuaLaTeX）なので**コンパイルする際はタイプセットを'LuaLaTeX'にしてください．**
表や図のキャプションやラベル，どうしても埋め込みたいパッケージなどをここでいれましょう．
よく使われているpLaTeXとは違うところもあるので悪しからず．

## 4. pdf形式にして完成
PDFの出来上がり


# 終わりに
日本語を入れるのって少しめんどくさい．
Goでコマンドラインツールを作った時のUnix wildcardの話

# はじめに
※[Go(Un)Conference（Goあんこ）LT大会 2kg](https://gounconference.connpass.com/event/86221/)でLTしようと思ったけど、急用が入ったので資料だけ公開しておきます。（初Qiitaスライド）

----
# Who
- name:  sssinsi（しんし）<img src="https://pbs.twimg.com/profile_images/841607367825399809/oZ6qcg7I_400x400.jpg" width="5%"/>
- hobby: 陶芸
- urls:
  - https://github.com/sssinsi
  - https://twitter.com/sssinsi
  - https://qiita.com/sssinsi

---
# テキストを等分割するツール

https://github.com/sssinsi/gohs
読み方：ごす（呉須）

→ https://www.google.co.jp/search?&q=呉須

---
#なぜ作ったか
Goツールの手始めに、簡単に作れるコマンドラインツールで勉強してみた。
（とりあえず手を動かして何かを作りたかった感）

---
#こんな感じで分割してくれる
```console
$cat a.file
1
2
3
4
5

$gohs -p a.file -c 3 -s=************
1
2
3
************
4
5
```

---
#flag
コマンドラインツールを作る時よく使う`flag`。
簡単。
https://github.com/golang/go/blob/master/src/flag/flag.go

---
#flagの使い方
オプションは`-flag=x` or `-flag x`のように指定できる。

```console
$gohs -p sample.txt -c 3 -s=************
1
2
3
************
4
5
```

---
#当然こんな使い方もできるよね

```console
$gohs -p sample.txt -c 3 -s ************
1
2
3
README.md
4
5
```
ファッ！？！？

---

#突然のREADME.md

---
#原因

```text
cmd -x *
where * is a Unix shell wildcard, ....
```

https://github.com/golang/go/blob/master/src/flag/flag.go#L46

---
#wildcard?
---
#ワイルドカード
```console
$ls
README.md	main.go		sample.txt
$ls *
README.md	main.go		sample.txt
$ls s*
sample.txt
```
そうだよね

---
#確認
`flag.parseOne()`のソースコードを読んでもどこでファイル名になっているのかわからず、試しに`fmt.Println(os.Args)`を`main.go`の先頭に仕込んで、コマンド実行。

```console
$go run main.go -p sample.txt -c 3 -s *
[/var/folders/mp/cmn3_f0s5fgd6wns0ng1tfrh0000gq
/T/go-build082551061/command-line-arguments
/_obj/exe/main -p sample.txt -c 3 
-s README.md main.go sample.txt]
...
```
---
#つまり
`flag.Parse()`する以前に、オプションにカレントディレクトリのファイル一覧が指定されているため、最初の`README.md`というファイル名を文字列として処理していた。

```console
-s README.md main.go sample.txt
```
なるほどね

---
#対策
`*`を文字列として使う場合は、`=`を使うか`"`で囲むと吉。

```console
$gohs -p sample.txt -c 3 -s=************
$gohs -p sample.txt -c 3 -s "************"
```

---
#過去を辿ってみたら
2017/12にwildcardのコメントが追加されてた、意外に最近。

https://github.com/golang/go/commit/ef544b64d7417aa58d41b50ec7f9b1134ca1d638

---
#ありがとうございました。
Raspberry Pi で Bluetooth を使う (C++)

Raspberry Pi で C++ で Bluetooth を使うプログラムです。
次のページのサンプルの simplescan.c を改造しました。
[bitsbyte/bluetooth-programming-in-c
](https://github.com/bitsbyte/bluetooth-programming-in-c/blob/master/simplescan.c)

```c++:simplescan.cpp
// -----------------------------------------------------------------------
/*
	simplescan.cpp

					May/25/2018
*/
// -----------------------------------------------------------------------
#include	<iostream>
#include	<fstream>

#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#include <bluetooth/hci_lib.h>

using namespace std;
// -----------------------------------------------------------------------
int main (int argc, char *argv[])
{
	cerr << "*** 開始 ***\n";

	char addr[19] = { 0 };
	char name[248] = { 0 };

	int dev_id = hci_get_route(NULL);
	int sock = hci_open_dev( dev_id );
	if (dev_id < 0 || sock < 0) {
	    perror("opening socket");
	    exit(1);
	}

	int len  = 8;
	int max_rsp = 255;
	int flags = IREQ_CACHE_FLUSH;
	inquiry_info *ii =  new inquiry_info[max_rsp * sizeof(inquiry_info)];
	
	int num_rsp = hci_inquiry(dev_id, len, max_rsp, NULL, &ii, flags);
	if( num_rsp < 0 ) perror("hci_inquiry");

	for (int it = 0; it < num_rsp; it++)
		{
		ba2str(&(ii + it)->bdaddr, addr);
		memset(name, 0, sizeof(name));
		if (hci_read_remote_name
			(sock, &(ii + it)->bdaddr, sizeof(name),name, 0) < 0)
			{
			strcpy(name, "[unknown]");
			}

		cout << addr << "\t";
		cout << name << "\n";
		}

	delete[] ii;
 
	close( sock );

	cerr << "*** 終了 ***\n";

	return 0;
}

// -----------------------------------------------------------------------
```

```text:Makefile
simplescan: simplescan.cpp
	clang++ -o simplescan simplescan.cpp -lbluetooth
clean:
	rm -f simplescan
```

実行結果

```text
$ ./simplescan 
*** 開始 ***
8C:25:08:41:EC:32       mishima
*** 終了 ***
```

Bluetooth の機器が周辺にあるか確認する方法

```text
$ hcitool scan
Scanning ...
        8C:25:08:41:EC:32       mishima
```
[CSS] 文章中の改行文字を反映する

# :star: 問題
- textareaなどで入力した文章をそのまま表示すると改行が反映されない問題
- 意外と知られてなさそうなので投稿してみました
- ~~CodePenを使ってみたかった~~


# :star2: 解決方法
- CSSに`white-space: pre-wrap;`を書くと改行文字で改行してくれます
- さらに、`word-wrap: break-word;`で単語の途中でも改行するようになり、文字がはみ出すのを防げます

# :pencil: デモ

<p data-height="835" data-theme-id="0" data-slug-hash="WJqEdz" data-default-tab="result" data-user="mikan3rd" data-embed-version="2" data-pen-title="CSSだけで改行を反映" class="codepen">See the Pen <a href="https://codepen.io/mikan3rd/pen/WJqEdz/">CSSだけで改行を反映</a> by hiroki-ota (<a href="https://codepen.io/mikan3rd">@mikan3rd</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
シェルスクリプト内でaliasしたコマンドを実行する

## シェルスクリプト内でaliasしたコマンドは実行できない
aliasはインタラクティブしかできない。これで小一時間はまりました。

参考になったページ
【Bash】 スクリプト中のaliasコマンドが実行できない
http://takafumi-s.hatenablog.com/entry/2017/12/12/230143

シェルスクリプト内でaliasを設定する
https://qiita.com/narumi_/items/77002a12d62585da1fbe
bundle exec ruby って入力するのもうやめませんか？？

## バイト中にふと社員さんとの会話
社員さん「このREADME.mdに書いてある『ber』ってなに？」
僕「あ....bundle exec rubyのエイリアスです...」
社員さん「なるほど」
僕「修正しておきます..というか社員さんはいつもbundle exec rubyって入力してるんですか？」
社員さん「そうだねー、でも確かに面倒かも」

## ここで、思った、「みんなbundle exec rubyってまだ入力してるの？？？」

ってことで、クソみたいなタイプミスをしないように＆業務効率化のためにこのエイリアスを登録することをオススメする。

```
$ alias ber='bundle exec ruby'
```
別にberじゃなくても良いんですけどねw
Kotlinでimportが勝手にwildCardになるのを防ぎたい

Javaの方は言及している人がいたけどもKotlinは見当たらなかったので。

![スクリーンショット 2018-05-25 18.23.39.png](https://qiita-image-store.s3.amazonaws.com/0/218207/044a9cea-afed-14f1-5166-e5096766ad2b.png)

Top-level Symbols、Java Static and Enum membersともにSingle Name Importにしましょう

ちなみに左上にある検索窓でimportで検索しても出て来ないし、Intentionsの中にそれっぽい項目がありますが関係ないです。
おかげで何度かプロジェクトのSlackを汚しました……(lintエラーがslackに流れる)すみませんでした……
CMAKE_BUILD_TYPEのUPPER CASEにご用心

# CMAKE_BUILD_TYPE とは

`cmake`を用いてビルドするとき、`-DCMAKE_BUILD_TYPE`を指定すると、（きちんと`CMakeLists.txt`が書かれているプロジェクトなら）適切なオプションを付けてビルドが行われる。

```bash
$ cmake -DCMAKE_BUILD_TYPE=Release  # -O2 とか -DNDEBUG とかが付く
$ cmake -DCMAKE_BUILD_TYPE=Debug  # -O0 とか -g とかが付く
```


https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html

ここによると、値としては`empty`, `Debug`, `Release`, `RelWithDebInfo`, `MinSizeRel`などが許されているらしい。


# 事実1: 値はcase insensitive

```bash
$ cmake -DCMAKE_BUILD_TYPE=Debug  # -g が付く
$ cmake -DCMAKE_BUILD_TYPE=debug  # -g が付く
$ cmake -DCMAKE_BUILD_TYPE=DEBUG  # -g が付く
$ cmake -DCMAKE_BUILD_TYPE=DeBuG  # -g が付く
```

大文字小文字は区別されず、`Debug`でも`DEBUG`でも通ってしまう。


# 事実2: Invalid valueに対して警告が出ない

```bash
$ cmake -DCMAKE_BUILD_TYPE=Dedug  # typoだが、警告は出ない
```

`cmake`の`-DCMAKE_BUILD_TYPE`は、`<Option>`が指定されると`CMAKE_C((XX)?)_FLAGS_<OPTION>`に含まれるオプションをコンパイルオプションに追加する。

つまり、

```cmake:CMakeLists.txt
set(CMAKE_CXX_FLAGS "-std=c++14 -Wall")
set(CMAKE_CXX_FLAGS_DEBUG "-g -O0")
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG")
```

となっていた場合、

```bash
$ cmake  # gcc <target> -std=c++14 -Wall
$ cmake -DCMAKE_BUILD_TYPE=Debug  # gcc <target> -std=c++14 -Wall -g -O0
$ cmake -DCMAKE_BUILD_TYPE=Release  # gcc <target> -std=c++14 -Wall -O3 -DNDEBUG
```

のようにオプションが決まる。

ここで、例えば

```bash
$ cmake -DCMAKE_BUILD_TYPE=Dedug  # ...?
```

のように存在しないオプションを指定した場合、`cmake`はエラーを出してはくれず、単に

```bash
$ cmake -DCMAKE_BUILD_TYPE=Dedug  # gcc <target> -std=c++14 -Wall
```

と、あたかも

```
set(CMAKE_CXX_FLAGS_DEDUG "")
```

何も指定しない変数が定義されているかのように振る舞ってくれる。


# 事実3: CMakeLists.txt 内で複雑な処理をする奴がいる

`CMakeLists.txt`内では単にコンパイル対象を指定するだけでなく、[cmake language](https://cmake.org/cmake/help/v3.0/manual/cmake-language.7.html)に従って様々な操作を行うことができる。

例えば、[pybind11](https://github.com/pybind/pybind11)の[/tools/pybind11Tools.cmake](https://github.com/pybind/pybind11/blob/master/tools/pybind11Tools.cmake)の中では、

```cmake:tools/pybind11Tools.cmake
...
  if (NOT MSVC AND NOT ${CMAKE_BUILD_TYPE} MATCHES Debug)
    # Strip unnecessary sections of the binary on Linux/Mac OS
...
```

という操作が行われている。
`${MSVC}`が`FALSE`で、かつ`${CMAKE_BUILD_TYPE}`が正規表現`Debug`にマッチしないなら、実行ファイルの`strip`を行うセクションだ。

見ると分かる通り、この部分はcase sensitiveである。`Debug`と正確に一致するかどうかのみを見ており、`DEBUG`や`debug`では通らない。


# 結果: エラーも出ないのに、`-g`も付いているのに、なぜかデバッグシンボルが付かない

```bash
$ cmake -DCMAKE_BUILD_TYPE=DEBUG
```

とすると、

+ `cmake`
    + case insensitiveなので、`-DCMAKE_BUILD_TYPE=Debug`と認識し、エラーや警告は出ない。仮にそう認識しなかったとしてもどちらにせよ`cmake`はエラーや警告を出さない。
+ `CMakeLists.txt`
    + 各自が勝手に書いているので、case sensitiveかもしれない。その場合`-DCMAKE_BUILD_TYPE=Debug`とは区別される。もちろんそんなtypoでエラーを出すような機構は基本的にない。

となって、結局想定外の挙動になってしまう。


# まとめ

`-DCMAKE_BUILD_TYPE`の値は`Debug`など、大文字から始まるcamel case。
間違えても`cmake`は怒ってはくれないし、`DEBUG`とか`debug`とか書いててもほとんどの環境で通じてしまうので、問題が発生するまで気づけない（そして問題が発生しても表面には出てこない）。
十分注意して使用してほしい。
PureComponent にインラインのアロー関数を渡してもいい場合

# 前提知識

- [[React] Component と PureComponentの違い - Qiita](https://qiita.com/wifecooky/items/23fd1da041f707c1b78b)
- [【React】 PureComponent にアロー関数を渡してはいけない - 藤 遥のブログ](https://hfuji.hatenablog.jp/entry/2017/11/03/183243)

# 本題

`PureComponent` にインラインのアロー関数を**渡してもいい**場合がある。これだ。

```jsx
class MyContainerComponent extends Component {

  render() {
    return <MyPureComponent ref={(ref) => (this.myPureElement = ref)} />
  }
}
```

こんな例，至るところで見るのでずっと疑問だったけど，冷静に考えてみて今日気づいた。

**`ref` は prop じゃない。**

どうやらこいつ， `key` に並ぶ特殊属性らしい。

- [Warning: `ref` is not a prop · Issue #2181 · JedWatson/react-select](https://github.com/JedWatson/react-select/issues/2181)
- [Warning: Element: `key` is not a prop · Issue #518 · facebook/react-devtools](https://github.com/facebook/react-devtools/issues/518)

つまり `props` オブジェクトの中に入らなければ shallowEquals の比較に何も影響は出ないので，堂々とアロー関数書いちゃってOKなのである。

今までこんな無駄なコードを書いていた・・・↓

```jsx
class MyContainerComponent extends Component {

  assignMyPureElement = (ref) => (this.myPureElement = ref)

  render() {
    return <MyPureComponent ref={this.assignMyPureElement} />
  }
}
```
Goの...で悩んでいる人に


- Goで度々出て来る`...`に悩まされている人のためにまとめていきます

## 要素数を指定しない配列宣言（例：`[...]int{1,2,3}`）
- Array型の宣言時には、ブラケットの中に要素数を書かないといけないんだけども、こうすることでいちいち要素数を書かなくても、機械に直接数えてもらえる
- `[]int{1,2,3}`とよく間違えそうになるけど、こっちはSlice型になるので注意

```go
sample1 := [...]int{1,2,3}
sample2 := []int{1,2,3}
fmt.Printf("%T %T\n", sample1, sample2)
// sample1はarray、2はslice
// => [3]int []int
```

## 関数の引数内で出て来る`...`（例：`func hoge(args ...interface{})`）
- `variadic parameter`というもの
- 関数に好きなだけ引数を渡し、関数内からはSlice型としてまとめて扱うことができるようにするもの
- `...int`などのように型を指定した場合は、その型しか渡せないが、`...interface{}`とすることで、どんな型でも渡すことができるようになる

```go
// 数字をたくさん渡せる
func mySum(nums ...int) int {
  var sum int
  // numsはslice型
  for _, val := range nums {
    sum += val
  }
  return sum
}

// なんでも渡せる
func myPrint(args ...interface{}) {
  for _, val := range args {
    fmt.Println(val)
  }
}
```

## sliceを展開する`...`
- slice型の変数の後ろに`...`をつけることで、sliceを展開することができる
- 主に先ほど出てきたような関数の引数に値を渡す時に使える

```go
slice1 := []int{1,2,3,4,5}
arr := [...]int{1,2,3,4,5}

// ok
mySum(slice1...)

// err（展開されていないsliceだから）
mySum(slice1)
// err（arrayは展開できないから）
mySum(arr...)
```
[Laravel 5.6] シンプルなCRUDアプリでレコード更新（生の HTML でフォームを作成するときの注意点）

#やりたいこと

[Laravel学習帳][link_1]さんのサイトを参考にLaravelで基本的なCRUDアプリを作成中。
ユーザー情報更新機能を実装するときに少しハマってしまったので、大まかな実装の流れを備忘録としてメモ。

![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/238891/a053b57d-91d8-0a43-6118-4923b60a3709.png)

↑こんな感じでユーザーの登録や編集、削除ができるアプリです。

[link_1]:http://laraweb.net/

#環境

CentOS: 7.4
PHP: 7.2
Laravel: 5.6

#ルーティングの設定

今回のアプリでは resouce を使ってルーティングを設定しました。

```web.php
Route::resource('/user', 'UserController');
```

この１行で以下のようなルーティングを Laravel 側が勝手に用意してくれます。
ユーザー情報の更新には PUT メソッド使います。

|Method|URI|Action|用途|
|:--|:--|:--|:--|
|GET|user|index|ユーザーの一覧表示|
|GET|user/{user}|show|ユーザーの詳細ページ|
|GET|user/create|create|ユーザー新規登録用のページ|
|POST|user|store|ユーザーの新規登録|
|GET|user/{user}/edit|edit|ユーザー情報更新用のページ|
|PUT/PATCH|user/{user}|update|ユーザー情報の更新|
|DELETE|user/{user}|destroy|ユーザーの削除|

#ビューの編集

生の HTML でフォームを作成するとき、以下のように書くとエラーになってしまいます。

```html
<form action="/user/{{$user->id}}" method="PUT">  <!-- PUT の部分に注目 -->
    <input type="text" name="name" value="{{ $user->name }}"></input>
    <input type="text"name="email" value="{{ $user->email }}"></input>
    <input type="text"name="tel" value="{{ $user->tel }}"></input>
    <button type="submit">更新</button>
</input>
```

「**レコードの更新**やから form のメソッドに PUT を指定したろ( ･´ｰ･｀)」

と思っていましたが、HTML のフォームでサポートしているのは `GET` か `POST` のみなので、上記のように書いてしまうとエラーになってしまいます。
この場合 `type="hidden"` の `input` タグを使って、メソッドが `PUT` であることを明示します。

おまけに Laravel では **CSRF 対策**がなされていない場合、エラーになってしまいますので、こちらも対策します。

最終的に、下記のようなフォームとなります。

```html
<form action="/user/{{$user->id}}" method="POST">
    @csrf  <!-- 生のTHMLを書くときは @csrf を忘れずに -->
    <input type="hidden" name="_method" value="PUT">

    <input type="text" name="name" value="{{ $user->name }}"></input>
    <input type="text"name="email" value="{{ $user->email }}"></input>
    <input type="text"name="tel" value="{{ $user->tel }}"></input>
    <button type="submit">更新</button>
</input>

```

###レコード更新処理でエラーになりやすいポイント

- `form` タグで `method="PUT"` と指定されている
- CSRF 対策用のトークンが埋め込まれていない

個人的には生の HTML を書くことが多いですが、フォームについては blade テンプレートを使用することもできます。
書き方にバリエーションがありますので興味がある方は調べてみてください。

##ちなみに

Laravel 5 では FORM ヘルパーが標準搭載されていません。
私は[こちら][link_2]を参考に導入しましたので参考まで。

[link_2]:https://laravel10.wordpress.com/2015/03/08/%E5%88%9D%E3%82%81%E3%81%A6%E3%81%AElaravel-5-16-form%E3%81%AE%E4%BD%9C%E6%88%90/

#コントローラーの処理

最後にビューから送られてきたユーザー情報でデータベースを更新する処理を実装します。
今回はユーザーの名前、メールアドレス、電話番号の３項目を更新します。

```UserController.php
public function update(Request $request, $id) {
    // 本来はここでバリデーションを実行

    // 送られてきた ID でユーザーを特定してインスタンスを生成
    $user = User::find($id);

    // 送られてきた情報を各プロパティにつっこむ
    $user->name  = $request->name;
    $user->email = $request->email;
    $user->tel   = $request->tel;

    // 保存します。
    $user->save();

    // ユーザーページへリダイレクト
    return redirect("/user/$user->id");
}
```

以上です。

間違いなどご指摘がありましたコメントをいただければと思います。
余りを求めないでFizzBuzz

# 実装
``` JavaScript
fizz = ["Fizz"]; 
buzz = ["Buzz"]; 
for(i=1; i<=100; i++) {
  fizzbuzz  = fizz[i] = fizz[i-3]||"";
  fizzbuzz += buzz[i] = buzz[i-5]||""; 
  console.log(fizzbuzz||i);
}
```

# 説明
1. 配列の要素[0]をtrueにする。
2. for()で要素[1]から[100]までループして「3つ前」「5つ前」を参照する。
3. そこがtrueなら自分もtrue。

DP(動的計画法)について調べてたら書きたくなりました。
AutoHotKeyでChromeのWebページレンダリング部分のみをスクリーンショットする

## 動機
- 一般的なアプリでChromeのスクショを撮ると、タイトルバーなどが入る。
- [Fireshot](https://chrome.google.com/webstore/detail/take-webpage-screenshots/mcbpblocgmgfnpjjppndjkmgjaogfceg?hl=ja)なりの拡張で対応はできるが、そこからローカルに保存したりSNSに投稿したりが一手間かかったり有料だったりする
- めんどうくさいので、ホットキー一発でスクショして保存なり投稿なりできるようにしたい

## AutoHotKeyで対応
では、どうやってWebページが表示されている部分のみをスクショするか。

AU3Spyで調査すると、この部分は`Chrome_RenderWidgetHostHWND1`というコントロール名が割り振られている。
よって、`ControlGetPos`コマンドで、この部分の座標情報を取得することができる。
ただし、取得できるのはアクティブウィンドウ内での相対座標であるため、`WinGetPos`でアクティブウィンドウの座標を取得し、計算してやる必要がある。

座標情報が取得できれば、座標を指定してスクショできるコマンドラインツール（例えば[NirCmd](http://www.nirsoft.net/utils/nircmd.html)）でスクショ自体は簡単にできる。

```ss.ahk
PrintScreen::
	ssDir = C:\Users\Public\Pictures\Capture
	ssFile = %ssDir%\%A_Now%.jpg ; 日時からファイル名を生成
	SetTitleMatchMode, RegEx ; ウィンドウタイトルを正規表現マッチ
	If WinActive(" - Google Chrome$ ahk_exe chrome.exe") ; Chromeブラウザがアクティブの場合
	{
		WinGetPos, ssX, ssY, , A ; アクティブウィンドウの座標を取得
		ControlGetPos, CX, CY, ssW, ssH, Chrome_RenderWidgetHostHWND1, A, , ; コントロールの相対座標および幅・高さを取得
		ssX += %CX% ; コントロールのX座標計算
		ssY += %CY% ; コントロールのY座標計算
		RunWait, "C:\apps\nircmd-x64\nircmd.exe" savescreenshot %ssFile% %ssx% %ssy% %ssw% %ssh%, ,
	}
	Else ; Chrome以外の場合、アクティブウィンドウ全体をスクショ
	{
		RunWait, "C:\apps\nircmd-x64\nircmd.exe" savescreenshotwin %ssFile%, ,
	}
	Return
#IfWinActive
```

Chromeのアクティブ判定はいろんなやり方があるが、Chromium系アプリ（Visual Studio Codeとか）や（いちおうまだ現役の）Chromeアプリ等を排除するため、実行ファイル名およびウィンドウタイトルでの判定とした。

これで正常にスクショできた。

![](https://i.imgur.com/NCcmGIN.jpg)