OmniAICreator/Qiita-1.07M huggingface dataset:
【OpenLayers4】点と線の間の距離を求める、点が線上にあるかどうか判別する

# 前提

* 座標はすべてWebメルカトル座標系で表されているものとする。
* この記事の内容はすべてOpenLayers v4.6.5に基づき、当該バージョンで動作確認した。

# 2点間距離を求める

座標`x=1, y=2`を`[1, 2]`のように書くこととにする。
`[1, 1]`と`[2, 2]`の間の距離を求めたいとする。
OpenLayers4には2点間距離を求めるAPIは無いようである。
一方で、`ol.geom.LineString`には[getLength()](https://openlayers.org/en/v4.6.5/apidoc/ol.geom.LineString.html#getLength)というLineStringジオメトリの長さを求めるメソッドがある。
それを利用すると2点間距離を求める関数`getDistance()`を以下のように定義できる。

```javascript
// 2つの座標co1, co2を与えると、その間の距離を返す。
function getDistance(co1, co2) {
    var ls = new ol.geom.LineString([co1, co2]);
    return ls.getLength();
};

// 利用例：[1, 1]と[2, 2]の間の距離を求める。
var co1 = [1, 1];
var co2 = [2, 2];
getDistance(co1, co2);  // 1.4142135623730951

```

# 点とLineStringの最短距離を求める

`[2, -2]`、`[2, 2]`を結ぶLineStringがあったとする。
`[1, 1]`からそのLineStringへ至る最短距離を求めたいとする。（この場合、答えは1）
OpenLayers4には、点からジオメトリへの最短距離を求めるAPIは無いようである。
一方、`ol.geom.LineString`には、任意の座標を引数として与えると、そのLineString上にあり、引数として与えられた座標から最短距離となる点を返すメソッド[getClosestPoint()](https://openlayers.org/en/v4.6.5/apidoc/ol.geom.LineString.html#getClosestPoint)がある。
例えば、

```javascript
var co1 = [1, 1];
var ls = new ol.geom.LineString([[2, -2], [2, 2]]);
ls.getClosestPoint(co1);    // [2, 1]
```

のように用いることができる。
これと、先ほどの`getDistance()`関数を組み合わせると、点とLineStringの最短距離を求めることができる。


```javascript
// 座標co1とLineString lsの間の最短距離を求める。
function getMinDistance(co1, ls) {
    var co2 = ls.getClosestPoint(co1);
    var ls_tmp = new ol.geom.LineString([co1, co2]);
    return ls_tmp.getLength();
}

var co1 = [1, 1];
var ls = new ol.geom.LineString([[2, -2], [2, 2]]);
getMinDistance(co1, ls);    // 1
```

# 点がLineString上にあるかどうかを判定する。

`ol.geom.Geometry`には、点座標を与えることで、その点がジオメトリ上にあるかどうかを返すメソッド[intersectsCoordinate()](https://openlayers.org/en/v4.6.5/apidoc/ol.geom.Geometry.html)がある。
`ol.geom.LineString`も`ol.geom.Geometry`の派生クラスなので、このメソッドを持っている。
しかしながら、この関数は、引数として与えられた点座標がジオメトリの境界上にある場合はfalseを返す。
従い、点がLineString上にあるかどうかの判別には使えない。

```javascript
var ls = new ol.geom.LineString([[0, 0], [0, 2]]);
ls.intersectsCoordinate([0, 1]);    // false
```

そこで、上記の`getMinDistance()`が返す値が0であれば、点は線上にある、とみなす。

```javascript
function isPointOnLineString(co1, ls) {
    return getMinDistance(co1, ls) === 0;
}

var co1 = [1, 1];
var co2 = [2, 1];
var ls = new ol.geom.LineString([[2, -2], [2, 2]]);
isPointOnLineString(co1, ls);    // false
isPointOnLineString(co2, ls);    // true
```

# まとめ

OpenLayers4には以下を直接求めるメソッドはないが、既存のメソッドを組み合わせてそれらを求める関数を実現できる。

* 2点間距離を求めるメソッド
* ある点からLineStringに至る最短距離を求めるメソッド
* ある点がLineString上にあるかどうかを判別するメソッド
FirstVRでジェスチャを使う

## 概要

さて、今回は前回書いた「[FirstVRでHello World](https://qiita.com/edo_m18/items/c101b198e03f02625082)」に続き、FirstVRでジェスチャを使って見たのでそのメモです。

実際に動かしたデモ動画はこちら↓
<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">FirstVR使って重力系魔法使い感を出してみるｗ <a href="https://t.co/xVq574C7dS">pic.twitter.com/xVq574C7dS</a></p>&mdash; edom18@VR (@edo_m18) <a href="https://twitter.com/edo_m18/status/1066591239250669569?ref_src=twsrc%5Etfw">November 25, 2018</a></blockquote>

重力系の魔法使い感を出してみましたｗ


## ジェスチャを司るFVRGestureManager

`FVRlib`には`FVRGestureManager`という、ジェスチャを管理するクラスがあります。
このクラスにはジェスチャに関するイベント処理や状態確認ができるプロパティがあるので、今回はこれを利用して冒頭の動画のような処理を作ってみました。

なお、今回のジェスチャはこちらの開発者サイトにアップされている動画（[FirstVR SDK Tutorial 4: Gestures](https://dev.first-vr.com/)）を参考にしました。

また、`FVRGestureManager`のドキュメントはこちらです→ [FVRlib.FVRGestureManager クラス](http://reference.first-vr.com/ja/class_f_v_rlib_1_1_f_v_r_gesture_manager.html)


## イベントハンドラを設定する

`FVRGestureManager`クラスには`OnSwipeUp`などの、スワイプを検知した際の`GestureEventHandler`型のデリゲートが設定されています。
今回のデモはこれにハンドラを登録して処理を行っています。

```cs
_fvr.gestureManager.OnSwipeUp += GravityOff;
_fvr.gestureManager.OnSwipeDown += GravityOn;
```

こんな感じで、スワイプアップを検知したら重力オフ、スワイプダウンを検知したら重力オン、みたいな感じにしてます。
ただ、動画では成功したところだけを載せていますが、若干検知が遅れたりすることがあったので、これを利用したシビアなゲームはあまり適さないかもしれません。
ちょっとした演出に使う程度ならありかも？

なお、この他にも以下のイベントが購読できるようになっています。


```cs:FVRlib.FVRGestureManager
public event GestureEventHandler OnSwipeLeft;
public event GestureEventHandler OnSwipeRight;
public event GestureEventHandler OnSwipeDown;
public event GestureEventHandler OnSwipe;
public event GestureEventHandler OnShake;
public event GestureEventHandler OnFVRTap;
public event GestureEventHandler OnMSVarPeak;
public event GestureEventHandler OnSwipeUp;
```

また、イベント以外にもジェスチャオブジェクトの状態をチェックして処理を行う（`Input.GetKey`的なやつ）こともできます。


```cs:ジェスチャオブジェクト
public FVRGesture swipeD;
public FVRGesture swipeU;
public FVRGesture swipeR;
public FVRGesture swipeL;
public FVRGesture fvrTap;
```

これを利用する場合は以下のようにして、`Update`メソッド内で評価することができます。

```cs:triggeredを利用する
if (_fvr.gestureManager.swipeD.triggered)
{
    // do anything.
}
```

FirstVRのSDKには、デバイスから取得できるデータをビジュアライズしてくれるサンプルシーンがあるのでそれを使って、どんな値がどれくらい取れるかをチェックしてみると分かりやすいと思います。

SDKについているViewer↓
![Viewer](https://qiita-image-store.s3.amazonaws.com/0/5616/91194a66-8ee3-41d4-fb1a-dc16e8662b2d.png)
[JavaScript] IE11ではonStorageイベントの挙動が異なる 

JavaScriptの`onStorage`イベントはブラウザによって挙動が異なるので、紹介します。（2018年11月現在）

```Markdown:動作環境
OS: Windows 10 Pro
Google Chrome: 70.0.3538.110
Mozilla Firefox: 63.0.3
Microsoft Edge: 42.17134.1.0
Microsoft Internet Explorer: 11.407.17134.0
```

# onstorageとは
Web Storageの1つであるLocalStorageに変化が起こった場合にイベントが発生します。
https://developer.mozilla.org/ja/docs/Web/API/WindowEventHandlers/onstorage

以下のデモページをブラウザのタブを2つにしてそれぞれ表示してみてください。
[デモはこちら](https://yunbow.github.io/sample-javascript-api/onstorage/01/)
[ソースファイルはこちら](https://github.com/yunbow/sample-javascript-api/tree/master/onstorage/01/)

LocalStorageの`setItem`、`getItem`、`removeItem`、`clear` の動作が確認できます。`onStorage`を確認するためには、「input:」テキストボックスに文字を入力して「setItem」ボタンを押下してください。LocalStorageの値が変わり、別のタブの「Log:」イベントが通知されます。「abcdefg」を`setItem`にすると別のタブに以下のログが表示されます。

```Markdown:Log
onstorage: key=itemKey, oldValue=null, newValue=abcdefg
```

以下のような実装になっています。

```JavaScript:index.js
$('#setItemButton').on('click', function () {
  var itemValue = $('#itemInput').val();
  localStorage.setItem('itemKey', itemValue);
});

window.onstorage = function (e) {
  log('onstorage: key=' + e.key + ', oldValue=' + e.oldValue + ', newValue=' + e.newValue);
};
```

# ブラウザ毎のonStorageの挙動
IE11とその他のブラウザでは、onStorageイベントの挙動が異なります。IE11では、`setItem`を実行したタブとその他のタブの両方にonStorageイベントが通知されます。その他のブラウザでは、その他のタブの片方のみ通知されます。

|ブラウザ名|`setItem`を実行したタブ|その他のタブ|
|:--|:--|:--|
|Google Chrome|通知されない|通知される|
|Mozilla Firefox|通知されない|通知される|
|Microsoft Edge|通知されない|通知される|
|Microsoft Internet Explorer|***通知される***|通知される|
		
# 複数タブの同期 (onChange)
onStorageイベントを利用して、複数タブでテキストボックスの値を同期してみたいと思います。

以下のデモページをブラウザのタブを2つにしてそれぞれ表示してみてください。
[デモはこちら](https://yunbow.github.io/sample-javascript-api/onstorage/02/)
[ソースファイルはこちら](https://github.com/yunbow/sample-javascript-api/tree/master/onstorage/02/)

「input:」テキストボックスに文字を入力すると、別のタブにその内容が反映されています。テキストボックスで`onChange`イベントが通知されると`setItem`を実行しています。そのため、別タブに`onStorage`イベントが通知されて、別タブのテキストボックスに反映されます。

```JavaScript:index.js
$('#itemInput').on('change', function () {
  // テキストボックスのフォーカスが外れたタイミングで呼ばれる
  var itemValue = $('#itemInput').val();
  localStorage.setItem('itemKey', itemValue);
});

window.onstorage = function (e) {
  log('onstorage: key=' + e.key + ', oldValue=' + e.oldValue + ', newValue=' + e.newValue);
  $('#itemInput').val(e.newValue);
};
```

# 複数タブの同期 (onKeyup)
onChangeイベントと同様に、onKeyupイベントでテキストボックスの値を同期してみたいと思います。

以下のデモページをブラウザのタブを2つにしてそれぞれ表示してみてください。
[デモはこちら](https://yunbow.github.io/sample-javascript-api/onstorage/03/)
[ソースファイルはこちら](https://github.com/yunbow/sample-javascript-api/tree/master/onstorage/03/)

```JavaScript:index.js
$('#itemInput').on('keyup', function () {
  // キーボードのキーを離したタイミングで呼ばれる
  var itemValue = $('#itemInput').val();
  localStorage.setItem('itemKey', itemValue);
});

window.onstorage = function (e) {
  log('onstorage: key=' + e.key + ', oldValue=' + e.oldValue + ', newValue=' + e.newValue);
  $('#itemInput').val(e.newValue);
};
```

# 引用
[[Javascript] IE11ではonStorageイベントの挙動が異なる](https://ameblo.jp/softwaredeveloper/entry-12333519451.html)
Athrillことはじめ

 athrill(アスリル) 
https://qiita.com/kanetugu2018/items/1f2ef93c9e1fa7a29f97
を利用しようと導入を始めた。

# Windows

MinWGを導入し、
Athrillを解凍し、
実行した。

```
PS C:\Users\Administrator\Downloads\athrill-master\athrill-master\bin\windows> athrill
athrill : 用語 'athrill' は、コマンドレット、関数、スクリプト ファイル、または操作可能なプログラムの名前として認識され
ません。名前が正しく記述されていることを確認し、パスが含まれている場合はそのパスが正しいことを確認してから、再試行して
ください。
発生場所 行:1 文字:1
+ athrill
+ ~~~~~~~
    + CategoryInfo          : ObjectNotFound: (athrill:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException


Suggestion [3,General]: コマンド athrill は見つかりませんでしたが、現在の場所に存在します。Windows PowerShell は、既定では、現在の場所からコマンドを読み込みません。このコマンドを信頼する場合は、".\athrill" と入力してください。詳細については、"get-help about_Command_Precedence" と入力してヘルプを参照してください。
```

そうだった。


```
> .\athrill
> .\athrill2
```
しまった。何か手順を間違えたかも。

最初からやり直そう。

どの記事が一番簡単だろうか。

今さらなぜCPUエミュレータを自作しようとおもったのか？
https://qiita.com/kanetugu2018/items/d692e612c3d4d715c0ad

一番簡単ではなく、一番大事な記事に出会った。

「
最低，何があれば良いか？
OS 移植とは言っても，TOPPERS OS の場合は，すべてアセンブラで記述する必要はありません．C言語で書かれたところは x86 でビルド＆デバッグは可能です．なので，最低，以下をデバッグできる環境があれば良いことに気づきました．
・スタートアップルーチン
・割り込み/例外処理
・タスクディスパッチ処理
これらを PC 上で動作確認するための何かを自作すれば良いのだと思えました．
」

抽象的な概念から仕事を始めるのもいい。
理論家なら。
具体的な話から仕事を始めるのもいい。
技術者なら。


CPUの創りかた
https://www.amazon.co.jp/dp/4839909865
これは愛読書。

Verilog HDLで書かれたCPUも出ている。

自作エミュレータで学ぶx86アーキテクチャ-コンピュータが動く仕組みを徹底理解
https://www.amazon.co.jp/dp/4839954747

この本は見逃していた。

# 文書履歴(document history)
ver. 0.01 初稿
ver. 0.02 誤植訂正 20190906 
ver. 0.03 URL追記　20230302

### 最後までおよみいただきありがとうございました。

いいね　💚、フォローをお願いします。

####  Thank you very much for reading to the last sentence.

Please press the like icon 💚　and follow me for your happy life.
HTTPによるコンテンツ取得

# 概要

curl の引数にURLを与えて実行すると指定したコンテンツを取得してコンソールに表示できますが、そこでどういう処理が行われているかを説明します。

# URLのパース

URL文字列は例えば http://example.com/some/data といったものです。まずはこの文字列を解析します。このような処理をパース(parse)とかデシリアライズ(deserialize)と言いますが、例に出したURLを

* http
* example.com
* /some/data

という3つの要素に分解し、それぞれを scheme, host, path と呼びます[^1]。

[^1]: URLのフォーマットはRFC3986で規定されています

# 名前解決

次にURLから取り出した host の部分に対応するIPアドレスを取得するために getaddrinfo 関数を呼び出します。getaddrinfo 関数では、必要ならDNSサーバに host 文字列を送信してIPアドレスを取得します。

# TCP接続

対象ホストにTCP接続します。TCP接続にはIPアドレスとポート番号が必要になります。接続先のIPアドレスはhostの名前解決をすることで取得しました。URL中でポート番号が明示的に指定されていない場合、schemeに依存したデフォルトのポート番号を使用します。httpの場合は80です。

# HTTPリクエストの送信

TCP接続が確立されたら、URLのschemaパートに基づく方法でコンテンツを取得します。今回はhttpだったので、RFC7239で規定されたHTTPのお作法でコンテンツを取得します。パスとしてURLから取り出したpathを使って、HTTPリクエスト

```
GET /some/data HTTP/1.1
Host: example.com
```

をTCPソケットに書き込みます[^2]。すると、対象ホストから応答(HTTPレスポンス)が返ってきます。

[^2]: 説明の簡略化のため必須でないヘッダは省略しました。

# HTTPレスポンスのパース

HTTPレスポンスはMIME[^3]で規定されたフォーマットになっているので、それを解析して本文(body)を取り出し、標準出力に書き込みます。これにより、取得したコンテンツがコンソールに表示されます。

[^3]: RFC2045

# まとめ

HTTPによるコンテンツ取得の処理を説明しました。

WebブラウザでアドレスバーにURLを入力してページを表示する際に行われている処理も、レスポンスをパースした後の処理がもうちょっと複雑になるだけで同様の処理が行われています。処理内容を把握しておくことで、コンテンツが取得できない場合の切り分けの参考になると思い説明してみました。

`dig example.com +short`で名前解決したり、`telnet example.com 80` でTCP接続してHTTPリクエストを送信してみるとより理解が深まるかもしれません。
Emmet CSS主要プロパティ省略パターンまとめ

#１文字で展開できるプロパティ
一単語のプロパティは頭文字を省略記法とすることが多いです。

|省略文字|展開後|
|:--|:--|
| d | display: block; |
| w | width: ; |
| h | height: ; |
| m | margin: ; |
| p | padding: ; |
| c | color: #000; |
| t | top: ; |
| b | bottom: ; |
| l | left: ; |
| r | right: ; |
| z | z-index: ; |

#-（ハイフン）で繋いでいるプロパティは頭文字を一つずつ記述して展開

|省略文字|展開後|
|:--|:--|
| ff | font-family: ; |
| ta | text-align: ; |
| lh | line-height: ; |
| ls | letter-spacing: ; |
| mb | margin-bottom: ; |
| td | text-decoration: none; |

#頭文字だけでは展開できないプロパティ

|省略文字|展開後|
|:--|:--|
| fl | float: left; |
| cl | clear: both; |
| ov | overflow: ; |
| op | opacity: ; |
| pos | position: relative; |
| lis | list-style: ; |

#省略文字が不規則なプロパティ
|省略文字|展開後|
|:--|:--|
| bd | border: ; |
| bg | background: ; |
| bgc | background-color: ; |
| cnt | content: ; |
| bdrs | border-radius: ; |
| bxz | box-sizing: border-box; |
| trs | transition: prop time; |
GitLab + Jenkins + NEXUSからAWS Codeシリーズに移行した話

先日、今まではオンプレのJenkinsでCIを回していたのをAWS Codeシリーズに移行しました。

## 移行の背景
GitLab + JenkinsでCIを運用していました。

構成はこんな感じです。

![old.png](https://qiita-image-store.s3.amazonaws.com/0/214526/5a34ce80-787a-95ed-92b6-7f0a24a64db5.png)


この構成の問題

- Jenkinsサーバーのスペックが限界
  - 別ver開発のビルドが横で動くと、リリース用ビルド時間が通常の1h30minから4h程度まで増加
  - 開発者が好き勝手ジョブを追加するので、異常に重くなる場合がある(ひどい時はJenkins自体から応答が返ってこない)
  - ビルドノードを追加しようにも、物理マシンを追加する予算はない
- Jenkinsのメンテナンスが面倒
  - 定期的にディスクフルになる
- GitLabが部門共有なので、GitLab CIやwebhookを設定できない

これらを解決するために、並列でいくらでも実行できるCodeBuildへの移行の検討を開始しました。
また、今後のデプロイ自動化やコンテナの利用も見据えて、AWS上にコード管理/CIを持って行った方がよいという理由もあります。

※ちなみに、CircleCI等のSaaSを利用する選択肢は弊社では採れません。


## 現状と移行時の選択肢
太字が採用した選択肢です。
### ソースコードリポジトリ
- 現状: GitLab on 部門AWS
  - 重い
  - たまに落ちる
  - webhook禁止
- **CodeCommit**
  - フルマネージドサービス
  - CloudWatch Eventsが使える
- GitHub Enterprise on AWS
  - 高機能
  - 高い

### CI環境
ビルド制御とビルドノードの2点で考える

- 現状: Jenkins on 物理マシン + Jinekinsノード on 物理マシン
  - スペックの限界
  - 並列ビルドが発生するとすぐ死ぬ
  - メンテナンスコスト高
- **CodePipeline + CodeBuild**
  - フルマネージド
  - Jenkinsより柔軟性は下がる
  - お金さえあればいくらでも並列実行可能
- Jenkins on AWS + CodeBuild
  - Jenkinsの豊富なプラグインが利用可能
  - メンテナンスコストはCodePipelineより高くなる
  - ビルドの並列実行は問題なさそう


### アーティファクトリポジトリ
- 現状: NEXUS on Local Machine
  - ディスクフル問題
- **S3**
  - マネージドなので、メンテナンスコスト小
- NEXUS on AWS
  - CodeBuildからのアクセス経路確保に難あり
  - メンテナンスコスト高

## Codeシリーズの課題
コードシリーズに移行し、ビルドのパイプライン等を組んでみてわかってきた課題がいくつかありました。

### CodeBuildの実行結果が成功/失敗の2値しかない
Jenkinsの場合、ビルド結果はSUCCESS, UNSTABLE, FAILUREの3値で表されます。
しかし、CodeBuildの場合はSuccessとFailureの2値しかありません。

Jenkinsの場合は、ビルドには成功したが、テストには失敗した場合、UNSTABLEとして運用していましたが、これを期にテスト失敗もFailureとする運用に変えました。

**テストが通らないコードをmavenリポジトリに登録するの、ダメ、ゼッタイ！**

### 静的解析の結果が閲覧し辛い
CodeBuildには静的解析やテスト結果、カバレッジなどをS3に**Artifact**として保存する機能があります。
checkstyleやFindBugs、JUnitの結果はhtml形式で出力できるので、S3側の設定で静的サイトホスティングを使えば、結果をそのままS3から閲覧することができます。

ただ、これらの静的解析結果はgradleのサブプロジェクトごとに出力されるため、複数のリポジトリ、複数のサブプロジェクトがある場合、閲覧性が悪いです。
また、ビルド毎にS3への出力パスを変えて、各ビルド分の結果を保持しようとすると、URLがビルド毎に変わってしまうため、テスト結果等のページを開くのにも一苦労です。

そこで、今回は、ビルド後のアーティファクト格納時に、アーティファクトに加えてこれらのファイルパスを出力し、このファイルパスのみは固定のS3パスに保存するようにしました。そして、静的サイトとして作成し、S3上に保存したページから、このファイルパスが書かれたファイルを読み込み、各種リンクを表示する仕組みを作りました。

![artifact.png](https://qiita-image-store.s3.amazonaws.com/0/214526/92a5515e-2be0-4753-d160-75fbce03d9c9.png)


### ビルド -> ビルドのパイプラインが組めない
CodePipelineを使用すると、push -> build -> deployのようなパイプラインを組むことができ、簡単にCDを実現することができます。

ただ、少し使いづらいのが、ビルド -> ビルドといった設定ができない点です。
今担当している商品では、あるリポジトリのgradleプロジェクトをビルド -> それに依存するプロジェクトをビルドという感じの依存関係が多数あるため、この機能は必須でした。

リポジトリAのビルドが終わったら、リポジトリBとCのビルドを実行し、BとCの両方のビルドが終わったら、リポジトリDをビルドする、といった並列でのビルドを実現したかったので、今回はCloudWatch Events、SNS、Lambdaを利用し、独自にパイプラインを作成することにしました。

完成したパイプラインは以下のような仕組みで動いています。

![CodeBuild.png](https://qiita-image-store.s3.amazonaws.com/0/214526/9b55af9d-6d3d-08e8-59a9-fff6277e8ee6.png)

## まとめ
- Lambda使えばなんとでもなる
- プライベートなプロジェクトならGitHub + TravisCIでいいや
- お金があるならGitHub Enterprise + CircleCIでいいや
WordPressの公式Dockerをサブディレクトリで使う方法

## 概要

WordPressの公式Dockerをサブディレクトリで使いたいです。
例えば、http://example.com/blog/ でアクセスしたい。

この問題の対処法をぐぐるといくつかやり方が出て来ますが、良い方法が検索上位に来ていないので、インデックス用に記事を書きました。

## 結論

以下の方法を使うと良いです
https://github.com/docker-library/wordpress/pull/133#issuecomment-383199445

具体例 (docker-compose.yml)

```
version: '2'
services:
  blog:
    image: wordpress:4.9.8
    restart: always
    ports:
      - 8080:80
    volumes:
    - "/path/to/blog_store:/var/www/html/blog"
    working_dir: /var/www/html/blog # <- これがポイント
    links:
    - mysql:mysql-host
    environment:
      WORDPRESS_DB_HOST: mysql-host:3306
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: wordpress
  mysql:
    image: mysql:5.7
    volumes:
    - "/path/to/db_store:/var/lib/mysql"
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: somewordpress
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: wordpress
```
コミコンの出展者ブース一覧画面の表示が崩れていた

# 事象
下記サイトにiPhoneSEでアクセスしたところ表示が崩れていた。
http://tokyocomiccon.jp/booth.html
<img width="320" alt="tokyocomiccon.jp_booth.html(iPhone 5_SE) (2).png" src="https://qiita-image-store.s3.amazonaws.com/0/267707/9f742c1c-5934-5355-d652-7c06b72aa237.png">

# 原因
セルの幅を超えている英字文字列が存在するため、改行されずセル幅が広がっている。

セル幅を超えている文字列
`SUNGUTS/MAXTOY`
`TOYOTOMI CORPORATION(豊臣商事株式会社)`

#解消方法1
####英字文字列が改行によって分割されても問題ない場合

- liタグのcssに下記を追加

```css:css
word-break: break-all;
```
<img width="243" alt="スクリーンショット 2018-11-26 4.38.24.png" src="https://qiita-image-store.s3.amazonaws.com/0/267707/d2fb6ab1-e03b-3360-3d7b-1f3612ed7e54.png">



# 解消方法2
####英字文字列が改行によって分割させたくない場合

- ulタグのcssに下記を追加

```css:css
display: table;
table-layout: fixed;
word-wrap: break-word;
width: 100%;
```

- ulタグのcssから下記を削除

```css:css
display: table-cell;
```
<img width="241" alt="スクリーンショット 2018-11-26 4.42.07.png" src="https://qiita-image-store.s3.amazonaws.com/0/267707/ff5d241f-fb3b-7518-b5f7-15aef4312c66.png">
Linux on Mac でWi-Fiが使えない時の対処

今回は簡単なメモになります
MacでLinuxをデュアルブートかUSB bootしたらWi-Fiが使えなかった時の対処法です。

## 動作環境
- Macbook Air 11 Early 2015
- OSX High Sierra
- Linux Mint19
- WD黒256GB(NVMe SSD)

以下コマンドを実行

```
sudo apt update && sudo install -y firmware-b43-installer
sudo modprobe -r b43 && sudo modprobe b43
```

次にドライバマネージャを起動
![Screenshot from 2018-11-26 04-32-02.png](https://qiita-image-store.s3.amazonaws.com/0/230050/9f11aae7-6cdb-8a54-464a-e6da2e7ea2c9.png)

ラジオボタンでは上部にチェックが入ってますがこちらに切り替えて右下にある**変更の適用**を押し、再起動することで無事Wi-Fiが使えるようになりました。

オマケのスクショコマンド
`gnome-screenshot --window --delay=3`
コマンド実行後、3秒後にフォーカスしているwindowをスクショ(要はAlt + PrintScreen)

以上メモです。誤字・脱字などありましたら報告いただけると助かります。
laravelでPOSTのajax通信が上手くいかない

# 事象
POSTでajax通信しようとしたところ「419 (unknown status)」が発生した。

# 原因
laravelでPOST通信する際はパラメータにCSRFトークンを設定する必要がある。
https://readouble.com/laravel/5.5/ja/csrf.html

# 修正方法
POSTパラメータにCSRFトークンを追加するかCSRF保護から使用するURIを除外する。

#### ▼POSTパラメータにCSRFトークンを追加する
- headタグ内に下記metaタグを追加

```php:bladeファイル
<meta name="csrf-token" content="{{ csrf_token() }}">
```

- ajaxのheadersにCSRFトークンを追加

```javascript:jsファイル
$.ajax({
    url: '{URL}',
    type:'POST',
    headers: {
        'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
    },
    ⁝
})
```

#### ▼CSRF保護から使用するURIを除外する

- CSRF保護の除外リストに対象のURIを追加する。

```php:app/Http/Middleware/VerifyCsrfToken.php
<?php

namespace App\Http\Middleware;

use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;

class VerifyCsrfToken extends Middleware
{
    /**
     * The URIs that should be excluded from CSRF verification.
     *
     * @var array
     */
    protected $except = [
        // CSRF保護から除外するURIを記載
    ];
}
```
PackageManagerの上書きは途中から変更しても大丈夫なのか？

PackageManagerで管理するパッケージを独自にbranchする方法、基本は下記に書いてある通りだが、これ途中からやってもmeta壊れない？大丈夫？とおもってやってなかったが、実際にやったら大丈夫だった。

- http://tsubakit1.hateblo.jp/entry/2018/08/16/221016

とはいえ問題は残っていて、

- 大元のpackageをアップデートした場合、どっちが使われる？
    - AssemblyDefinitionはバージョン変わっても変わらんから多分平気だとは思うけど
- Unityのバージョン上げた時におこる、悪しきScript自動更新機能の対象に入る？

あたりがちょっと不安。

このへん、githubのbranch指定して、切り替えれるような仕組みが欲しい。
せっかくベースがnpmなんだしさぁ！
方眼紙ノートを分割して使って、思考を整理しよう。

文具店にて気になるノートがありました。
>『頭がいい人はなぜ、方眼ノートを使うのか？（株式会社かんき出版）』の著者。高橋政史氏監修の「ロジカル・シンクノート」。
>https://swinglogical.jp/logical-think

![images.jpg](https://qiita-image-store.s3.amazonaws.com/0/254652/3d8f4904-6217-d9c9-5965-9f2394c316da.jpeg)



買ってないけど、ノートの書き方の参考にしようと思います。
ちなみに自分のおすすめノートは「おじいちゃんの水平開き方眼NOTE」
Amazonだとセットでの販売みたいですね。
https://www.amazon.co.jp/dp/B01BUQKHBE/

## 今回おすすめするノート術
・ノート３分割法：ロジカルな思考術
・ノート４分割法：起承転結の思考術
・ノート９分割法：曼荼羅の思考術
・ノート８分割・16分割法など

## ノート３分割法：ロジカルな思考術
３分割することでロジカルに考えることができる


### 小論文術
1.序論：総論（言いたいこと）を明かして、筆者の意図や問題意識、主張や結論がわかる
2.本論：主張したいことに沿った証明を積み上げていく部分。序論で示した方向性を補強する。
3.結論：まとめ。本論で証明を積み上げ、読み手が納得できる形で書き手の主張を述べる。

### 文章術
1.主張：その文章を通じて訴えたい主張
このところ、Aが、Bしている（自分はこう思う！）

2.理由：主張を訴える理由
そこで、わたしは、Cのようなことを提案した。（なぜならば、今は、こういう状況になっているから）

3.事実：理由を補強する客観的事実（それに、過去にも同じ事例があったから）
なぜなら、Cは、Bだからだ


### ドラマの再現フィルムでも使われてる・・・！？
「春の季節、ある男の子が学校の桜の木の下で出会った女の子に恋をして、
出会った場所で告白し、見事ハッピーエンドを迎える」

1.導入（客観）：大学のキャンパス、桜の木を遠くから眺める映像
2.本編（主観）：主人公の男の子を映し、女の子との出会いの瞬間から仲良くなっていく過程を近距離で映す映像
3.結末（客観）：再び遠くから二人を捉え、告白からのハッピーエンドをナレーションやテロップで客観的に解説する

## ノート４分割法：起承転結の思考術

### 起承転結
1.起（10%）：物語の前提
2.承（40%）：事件が起こる
3.転（40%）：事件を解決する
4.結（10%）：結果

### 桃太郎
1.桃から桃太郎が生まれて
2.鬼退治のために仲間を集めて
3.鬼ヶ島に行って、鬼退治をする
4.財宝をもって帰る

### ドラえもん
1.のび太がジャイアンとスネ夫にいじめられる
2.のび太がドラえもんに頼んでひみつ道具を借りる
3.のび太、ジャイアンとスネ夫をこらしめ、調子にのる
4.のび太、逆に窮地におちいり、「ドラえも〜ん」と助けを呼ぶ（オチ）



## ノート９分割法：曼荼羅の思考術
日本ハムファイターズに所属している大谷翔平選手も高校時代に行なっていた夢を叶えるための目標設定。
目標設定だけでなく、問題解決・事業計画・商品開発・発想整理などにも利用できる。

1. 真ん中のマス（目標の設定）：「ドラフト1位で8球団から指名されること」

2. 真ん中の3×3マス（目標達成の要素）：「体づくり」「コントロール」「キレ」「メンタル」「スピード160km/h」「人間性」「運」「変化球」

3. シート外側の3×3マス：②の8つの要素を達成するための具体的な要素


![目標設定術.jpg](https://qiita-image-store.s3.amazonaws.com/0/254652/7dd6dda8-1a3e-17c3-9bdb-68af7b03bb23.jpeg)
出典：[スポーツニッポン](https://www.sponichi.co.jp/baseball/news/2013/02/02/gazo/G20130202005109500.html)

## ノート８分割法・16分割法
「so-What」 「MECE」 「Zero-based Thinking」など
・項目に対して「なぜ？」を記述する方法
・やるべきことをリスト化して、おわったらバツにしていく方法


# まとめ
いろいろな分割方法があり、それぞれにいいところがある。
自分は、下記の２つの書き方を実践してみようと思う。

1.「３分割法」で "事実・解決方法・行動" などをまとめる
2.「８分割・１６分割」で "ToDoリスト" などを作成する
Macの上でWALKを使うWindowsアプリケーションをGO言語を使って書く

Mac上でWindowsプログラムを開発しないといけなくなった場合にお役立てください。
どうしたらそんな機会があるのかはわかりませんが、実際に私がやることになったので、世の中的にはあり得ることなのではないかと思います。


# 環境

| もの | バージョン |
|:---:|:---:|
|macOS|10.14|
|Golang | 1.11 darwin/amd64 |
|wine| 3.0.2|

wineはhomebrewで適当に入れれば動くと思います。


# なぜgolangなのか

Windowsアプリのクロスコンパイラとして有名なMinGWにg++が入っているので、C++でコードを書いてしまうのも手です。
というか、初めはC++で書くつもりでいました。

が、やはり非同期処理が難しく、（C++よりかは）使い慣れているgolangでgoroutineを使って非同期処理を書きたくなったためです。

あと文字列だとかの操作が圧倒的にgolangの方が楽というのもあり…
MinGW環境でBoostを使えば文字列の扱いがもうちょっと楽になったかもですが、私の低いC++力ではMinGW + Boostまで辿り着けなかったので、今回は諦めてgolangを使います。


# ソース

[WALK](https://github.com/lxn/walk)のReadmeに載っているサンプルコードをそのまま使います。


```main.go
package main

import (
	"github.com/lxn/walk"
	. "github.com/lxn/walk/declarative"
	"strings"
)

func main() {
	var inTE, outTE *walk.TextEdit

	MainWindow{
		Title:   "SCREAMO",
		MinSize: Size{600, 400},
		Layout:  VBox{},
		Children: []Widget{
			HSplitter{
				Children: []Widget{
					TextEdit{AssignTo: &inTE},
					TextEdit{AssignTo: &outTE, ReadOnly: true},
				},
			},
			PushButton{
				Text: "SCREAM",
				OnClicked: func() {
					outTE.SetText(strings.ToUpper(inTE.Text()))
				},
			},
		},
	}.Run()
}
```

# ビルド

```
$ GOOS=windows GOARCH=386 go get -u github.com/lxn/walk
$ GOOS=windows GOARCH=386 go build main.go
```

これで `main.exe` ができます。

`go get` の際にも`GOOS` などを指定しておかないと、WALKのgetに失敗します。

# 失敗

```
$ wine main.exe
```

何も表示されないままプログラムが終了してしまいます。

# 修正

[WALKのissue](https://github.com/lxn/walk/issues/399)によると、どうやらTooltip周りのパラメータが、特定の値でないと動作しない不具合があるようです。
（おそらくwine由来のもの？）

そこで、 `$GOPATH/github.com/lxn/walk/tooltip.go` の190行目（あたり）、 `ti.CbSize` に入る数値を `42` に固定します。

```go
var ti win.TOOLINFO
ti.CbSize = 42   // <- ここ
ti.Hwnd = hwnd
```

これでもう一度ビルドを試みると、今度こそウィンドウが表示されます。

```
$ GOOS=windows GOARCH=386 go build main.go
$ wine main.exe
```


![スクリーンショット 2018-11-26 2.53.37.png](https://qiita-image-store.s3.amazonaws.com/0/41896/cfdd9c8f-a7fb-f69b-6a00-3a1d98e92d3d.png)


やりましたね！ :tada:

ちなみにこの調子で[go-winio](https://github.com/Microsoft/go-winio)など、他のWin32APIを使用するライブラリも使用可能です。

これで、Macしか持っていなくてもWindowsアプリ開発ができますね！！
~~もしWindowsアプリ開発を案件として請け負うなら素直にWindowsのPCを買った方がいいと思いますが。~~
【Angular】ngForが完了した時に処理を走らせたい

# ngForが完了した時に処理を走らせたい

`ngFor`が完了した時に何らかの処理を走らせる必要が稀にあると思います
私の場合は、アプリ内のチャットで、チャットラインのスクロールバーを最下部に移動したいため必要でした。
（新規書き込みがチャットラインの下に追加されるslackやLineのスタイルのチャットです）

こういった場合にangularのライフサイクルの`ngInit`や`ngAfterViewInit`で処理を行うと、`ngFor`の描画が完了されていないためスクロールバーが存在しておらず上手く行きません。

`ngFor`でループさせる要素を`@ViewChildren`で取得し、`QueryList`の`chagnes`を使うと完了後に処理を走らせることが出来ました

### HTML側
- `ngFor`でループさせる要素に#でテンプレート参照を定義します

```html
        <app-chat-column #chatColumns
                          *ngFor="let chatData of (chatDataArray$ | async);trackBy:trackItem;"
                          [chatData]="chatData"></app-chat-column>
```

### TypeScript側
- `@ViewChildren`でHTML側で定義したテンプレート参照から`QueryList`を取得します
- 取得した`QueryList`の`changes`で`Observable`が扱えます。`ngAfterViewInit`内で`subscribe`し、完了後の処理を実行させます


```typescript
    export class ChatLineComponent implements OnInit, AfterViewInit {
        // ngForでループさせる要素のQueryList取得
        @ViewChildren('chatColumns')
        chatColumns: QueryList<any>;

        // ～略～
 
        ngAfterViewInit() {
            this.chatColumns.changes
            .subscribe(t => {
                // 最下部にスクロール
                this.chatLineScroll.nativeElement.scrollTop = this.chatLineScroll.nativeElement.scrollHeight;
            });
        }
```

これでngFor完了後の状態で処理を実行させられ、スクロールバーを最下部に持っていくことが出来ました。
初回のみなど条件がある場合は、`subscribe`の前に`pipe`で条件の絞り込みを行います。
pyenvでpython入れたらmod_wsgiが入らない件

# 解決法

```bash
CONFIGURE_OPTS="--enable-shared" pyenv install 3.7.1
```

個人用メモでした...ｗ

#　引用

> [DjangoをApacheで動作させたいがうまくいかない【失敗編】](https://qiita.com/yoshizaki_kkgk/items/c57bca15d2804550270a)
javascript 基本

仕様

click を押すとボタンがでる

```html

 <div id="root2" onclick="change()"> click</div>
                <div id = "root" style="display:none">
                  <button type="">クリック</button>
                </div>

```

```javascript

function change(){
var aaa =  document.getElementById("root");
  aaa.style.display = "block"

}
```
SDcard + FATFS のテスト on nRF52840

「nRF52840 を Segger Embedded Studio 開発環境で First Try」からの続きです。
https://qiita.com/nanbuwks/items/dd20dc4619af1d994f2c

ターゲットの開発ボードは前回と同様に、Raytac の MDBT50Q–DB、開発環境は SEGGER Embeded Studio です。

MDBT50Q-DBにmicroSDスロットとUSBシリアルモジュールを配線しておきます。

今回の実験の後に使う、加速度センサモジュールやJ-linkとあわせてこんな感じのテストベッドを作りました。

![IMG_20181115_081432.jpg](https://qiita-image-store.s3.amazonaws.com/0/139524/a7a0e321-b31b-783c-29a0-31c19bb7c8b6.jpeg)


microSDカードのアダプタは、このようなものを加工して使っています。
![IMG_20181115_081459.jpg](https://qiita-image-store.s3.amazonaws.com/0/139524/e3f0b4a4-590d-4637-0ac3-2f7209e8a7b2.jpeg)

裏側にピンを立てて、ジャンパーケーブルを接続します。

![IMG_20181115_081300.jpg](https://qiita-image-store.s3.amazonaws.com/0/139524/87a3f108-0551-403c-4701-6b7e8db3c104.jpeg)

開発ボードへの配線。
![IMG_20181115_081342.jpg](https://qiita-image-store.s3.amazonaws.com/0/139524/09bedf25-53a4-a636-54c7-44f6fcfe36a7.jpeg)



CS　　（緑）0.23に配線
MOSI　（茶）0.14に配線
CLK　（白） 0.22に配線
MISO （紫） 0.25に配線

橙と黒はそれぞれ 3V3 (VCC) と GNDに接続しています。

サンプルプログラム

peripheral/fatfs/pca10056/blank/ses
を開きます。


```

#define SDC_SCK_PIN     ARDUINO_13_PIN  ///< SDC serial clock (SCK) pin.
#define SDC_MOSI_PIN    ARDUINO_11_PIN  ///< SDC serial data in (DI) pin.
#define SDC_MISO_PIN    ARDUINO_12_PIN  ///< SDC serial data out (DO) pin.
#define SDC_CS_PIN      ARDUINO_10_PIN  ///< SDC chip select (CS) pin.
```

となっているのを

```

#define SDC_SCK_PIN     22  ///< SDC serial clock (SCK) pin.
#define SDC_MOSI_PIN    14  ///< SDC serial data in (DI) pin.
#define SDC_MISO_PIN    25  ///< SDC serial data out (DO) pin.
#define SDC_CS_PIN      23  ///< SDC chip select (CS) pin.
```
と変更します。

ちなみに、元々の
ARDUINO_10_PINなどは、components/boards/pca10056.h
を見ると

```

#define ARDUINO_13_PIN              NRF_GPIO_PIN_MAP(1, 15)  // Digital pin 13
#define ARDUINO_12_PIN              NRF_GPIO_PIN_MAP(1, 14)  // Digital pin 12
#define ARDUINO_11_PIN              NRF_GPIO_PIN_MAP(1, 13)  // Digital pin 11
#define ARDUINO_10_PIN              NRF_GPIO_PIN_MAP(1, 12)  // Digital pin 10

```

ということらしいです。

USBシリアルアダプタをつなぎ、動作させてみると

```

<info> app: FATFS example started.
<info> app: Initializing disk 0 (SDC)...
<info> app: Capacity: 7695 MB
<info> app: Mounting volume...
<info> app: 
 Listing directory: /
   <DIR>   ______~1        0  ______~2       16  NORDIC.TXT        0  TEST.TXT<info> app: Writing to file NORDIC.TXT...
<info> app: 16 bytes written.
```

というメッセージが出てきました。
microSDカードをPCに繋ぎ直して中身を見てみます。

```

$ ls -alh /media/nanbuwks/B179-FEBB/
合計 16K
drwxr-xr-x  3 nanbuwks nanbuwks 4.0K  1月  1  1970 .
drwxr-x---+ 4 root     root     4.0K 11月 26 01:46 ..
-rw-r--r--  1 nanbuwks nanbuwks   32  1月  1  2016 NORDIC.TXT
-rw-r--r--  1 nanbuwks nanbuwks    0 11月 25 23:11 test.txt
-rw-r--r--  1 nanbuwks nanbuwks    0 11月 25 23:11 無題のドキュメント
drwxr-xr-x  2 nanbuwks nanbuwks 4.0K 11月 25 23:11 無題のフォルダー

```

「test.txt」「無題のドキュメント」「無題のフォルダー」は元々書き込んでいたものです。

```

$ cat /media/nanbuwks/B179-FEBB/NORDIC.TXT 
SD card example.SD card example.
```

同じ文章が2つ出ています。これは同じmicroSDカードに２回プログラムを実行したのでこのようになりました。
サンプルプログラム中では、ファイルハンドラを開くときに以下のようになっていて、APPENDモードとしているためです。

```

    ff_result = f_open(&file, FILE_NAME, FA_READ | FA_WRITE | FA_OPEN_APPEND);
```
neo-pythonの環境構築

# はじめに

Windows PCでNEO-pythonを動かすまでのメモです

このドキュメントのゴール
- Dockerがインストールできていること (private netへの接続に必要です)
- neoのprivate netに繋いでneo-pythonが使用できること

# NEO-PythonをWindowsに入れる方法

頑張れば動くかもしないけど大変そうなのでやめておく。
[公式ドキュメント](https://github.com/CityOfZion/neo-python)にも、このようにあります。
> Currently, you should use the Linux subsystem with Ubuntu, or a Virtual Machine with Linux. You can find more information and a guide for setting up the Linux subsystem here.

> Installing "Ubuntu" from Microsoft Store installs Ubuntu 16.04. You should install Ubuntu 18.04 from Microsoft Store found here: https://www.microsoft.com/en-us/p/ubuntu-1804/9n9tngvndl3q?activetab=pivot%3aoverviewtab

> Help needed for running natively. Installing the Python package plyvel seems to require C++ compiler support tied to Visual Studio and libraries. Refer to documentation.

# WindowsでLinuxを動かす

WindowsOS上で動かすのを諦め、Linuxの仮想環境を準備しました。
VirtualBoxでUbuntuを動かすことにしました。

## VirtualBoxでUbuntuを動かす

1. まずはBIOSで仮想化機能を有効にしました。詳しい方法については各メーカーのサポートページなどをご参照ください。
1. https://www.virtualbox.org/ からVirtualBoxをDLしてインストールします
2. https://www.ubuntulinux.jp/download から、「日本語Remixイメージをダウンロード」を選択し、イメージをDLします
3. 新規仮想マシンを作成して、DLしたUbuntuイメージを指定し、Ubuntuをインストールします

## Ubuntu上でのセットアップ

1. Ubuntuのインストールが完了したら、「端末」を起動してください
1. https://docs.docker.com/install/linux/docker-ce/ubuntu/#install-docker-ce を参考にDockerをインストールしてください

## Pythonとpipのインストール

https://github.com/CityOfZion/neo-python を参考に必要なパッケージをインストールしていきます

```
$ sudo apt-get update && sudo apt-get upgrade
$ sudo apt-get install python3.7 python3.7-dev python3.7-venv python3-pip libleveldb-dev libssl-dev g++
```

```
$ pip3 install neo-python
$ source ~/.profile
$ np-prompt
```

起動ができたら完了です！！
Kubernetes Engineでhttpからhttpsにリダイレクトする

2018年11月27日にいろいろ追記。。。

前提
----

* Ingressを導入している（2018年11月27日追記）
* GCPのロードバランサーにSSL証明書を設定している
* nginxにはSSL証明書の設定をしていない

やること
--------

Kubernetes Engineで動かすWEBサーバー(nginx)のコンテナでhttpをhttpsにリダイレクトさせる。すると、Ingressのコンテナのヘルスチェックに関する設定をしないと動かなくなるので、その設定方法を以下に。

nginxの設定
----------

`set $redirect 0;`以下がヘルスチェックのための設定。ヘルスチェックのアクセスの場合はhttpsにリダイレクトしないようにしている。ヘルスチェックかどうかの判定はX_HEALTH_CHECKヘッダーで行う（好きなヘッダー名にしても良い）。

```nginx:default.conf
server {
    listen      80;
    server_name localhost;

    set $redirect 0;

    if ($http_x_forwarded_proto = http) {
        set $recirect 1;
    }

    if ($http_x_health_check = on) {
        set $recirect 0;
    }

    if ($recirect = 1) {
        return 301 https://$host$request_uri;
    }
}
```

Deploymentの設定
---------------

`spec.template.spec.containers[].livenessProbe.httpGet.httpHeaders`に`X-Health-Check: on`の設定をしている。これでヘルスチェックにリクエストヘッダーが付与される。

前述のnginxの設定でこのヘッダーを見てリダイレクトするかどうかを判定させている。なので、両方のヘッダー名を揃えておけば好きな名前に変更しても良い。

```yaml:nginx-deployment.yaml
apiVersion: "extensions/v1beta1"
kind: "Deployment"
metadata:
  name: "nginx"
  namespace: "default"
  labels:
    app: "nginx"
spec:
  replicas: 1
  selector:
    matchLabels:
      app: "nginx"
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  minReadySeconds: 5
  template:
    metadata:
      labels:
        app: "nginx"
    spec:
      containers:
      - name: "nginx"
        image: "<IMAGE>"
        livenessProbe:
          httpGet:
            scheme: HTTP
            path: /
            port: 80
            httpHeaders:
            - name: X-Health-Check
              value: "on"
          initialDelaySeconds: 5
          periodSeconds: 10
```

おしまい。

（以下2018年11月27日追記）

としていたが、上記のようなことをしなくてもよかった。

(新)nginxの設定
----------

X_Fowarded_Protoヘッダーがある、かつ、https以外の場合はリダイレクトする。だけで良い。ヘルスチェックのリクエストにはX_Fowarded_Protoヘッダーがないため、この場合はhttpsにリダイレクトはしない。

これで、DeploymentのhttpHeaders設定はしなくて良い。

```nginx:default.conf
server {
    listen      80;
    server_name localhost;

    if ($http_x_forwarded_proto) {
      set $redirect_to_https A;
    }

    if ($http_x_forwarded_proto != https) {
      set $redirect_to_https "${redirect_to_https}B";
    }

    if ($redirect_to_https = AB) {
      return 301 https://$host$request_uri;
    }
}
```

参考
----

* [Nginxで複数条件のIF文を書く方法がすごいｗ](https://qiita.com/ukitazume/items/ab1c929783e87227e466)
Macでirbしたところ日本語入力できなかった

#はじめに
irbで"こんにちは"を入力してみたところ…

```bash
irb(main):001:0> a = "\U+FFE3\U+FFE3\U+FFE3\U+FFAB\U+FFE3\U+FFA1\U+FFE3\U+FFAF"
=> ""
```

なぁにこれぇ


# 原因
irbがコマンド入力を受け取る際に使っているMac付属のライブラリ（libedit）が日本語に対応していないのが原因らしい

# 解決
日本語対応のライブラリ（readline）に切り替える

## readlineをインストール
```bash
$ brew install readline
```
## readlineにパスを通す
```bash
$ brew link readline --force
```
## readlineを通してRubyをインストールするようにする
```bash
$ RUBY_CONFIGURE_OPTS="--with-readline-dir=$(brew --prefix readline)"
```

## Rubyの再インストール
```bash
$ rbenv uninstall 2.5.3
```
```bash
$ rbenv install 2.5.3
```

## 結果

```bash
irb(main):001:0>  a = "こんにちは"
=> "こんにちは"
```

#参考
[日本語が使えるirbにしておく - ザリガニが見ていた...。](http://d.hatena.ne.jp/zariganitosh/20140923/japanese_irb)
[rails cで日本語が通らないときの直し方]
(https://qiita.com/irohiroki/items/c82657b5cb4bdb2aaac4)
[Homebrew導入~Ruby on rails開発構築環境まとめ](https://qiita.com/stalhow/items/68898e9f0d7dd4b06f32)
「Notice:Undefined index」と「Notice:Undefined variable」の対処法 

PHPのコード入力をしていて、「Notice:Undefined index」または「Notice:Undefined variable」と表示させたことはありませんか？

今回は、この2つのエラーを解決する方法を、記述したいと思います。

#「Notice:Undefined index」の処理方法
GET送信やPOST送信したときに登場することの多い、エラーの一つです。
エラーの原因は、初回アクセスと2回目以降のアクセスの処理を切り分けができていないことが考えられます。

エラーが出る場合は、主に次のような入力をしたときです。

```php

<?php 
echo $_POST["sid"];
?>
```

この場合、対処法は、次のようにします。

```php
<?php 
if (isset($_POST["sid"])) {
echo $_POST["sid"];
}
?>
```

このように、「$_POST[sid]に値が入っているときは」という条件を与えることで、初回アクセス時は、POSTを参照しないため、エラーはなくなります。


##「Notice:Undefined variable」の処理方法
このエラーが発生する原因は、変数の定義を定めていないのに、echo表示させているからと考えられます。

例えば、次のような入力のときに、エラーが出ます。

```php
<?php 
if (data("H") >= 12) {
 $word = "こんにちは";
}
echo $word;
?>
```
これは、「12時以降は『こんにちは』」と表示させたいのですが、12時前の分が設定されていないため、エラーが表示されます。

そのため、対処法は、次のように入力します。

```php
<?php 
if (data("H") >= 12) {
 $word = "こんにちは";
} else {
 $word = "おはようございます";
}
echo $word;
?>
```

このように、「12時前は『おはようございます』」といった条件を追加すれば、エラーは解消されます。
VueがReactを抜かしてGitHubのスター数3位になった件（3大フレームワークの頂点）

## VueがついにGitHubプロジェクト3位に
ふとGitHubのスター数が高い順を見てみたいと思い検索してみたところ、、、
![image.png](https://qiita-image-store.s3.amazonaws.com/0/250125/cbd60768-d51a-1cec-9c3d-d7290fda62fe.png)
**!?!?!?!?!?!?!?!?!?**
Vueが3位になっているではありませんか。
ついに3大フレームワークの頂点に達したというのか。。。Vueよ。。。
（ちなみに筆者はAngularを書いて、[Reactビギナーズガイド](https://www.amazon.co.jp/React%E3%83%93%E3%82%AE%E3%83%8A%E3%83%BC%E3%82%BA%E3%82%AC%E3%82%A4%E3%83%89-%E2%80%95%E3%82%B3%E3%83%B3%E3%83%9D%E3%83%BC%E3%83%8D%E3%83%B3%E3%83%88%E3%83%99%E3%83%BC%E3%82%B9%E3%81%AE%E3%83%95%E3%83%AD%E3%83%B3%E3%83%88%E3%82%A8%E3%83%B3%E3%83%89%E9%96%8B%E7%99%BA%E5%85%A5%E9%96%80-Stoyan-Stefanov/dp/4873117887/ref=sr_1_4?ie=UTF8&qid=1543162006&sr=8-4&keywords=react)を積読中)

Vueを書いてみよ。
以上、Vueを書いてみようというお話でした。（違う）

## 追記（2018/11/27）
5ヶ月前に抜いていたそうです。
情報提供ありがとうございます。
https://zendev.com/2018/06/19/react-usage-beating-vue-angular.html

## おまけ
下記URLを叩くとスター順で見れます。
https://github.com/search?utf8=%E2%9C%93&q=stars%3A%3E1

### 参考
[2016年版GitHubスター数ランキング](https://qiita.com/tonkotsuboy_com/items/9db94fd1daddb0d6c957)
[Python3]リストからユニークな値を除外する

# はじめに
今日も今日とてcheckioの課題。
paizaの課題（B級）もやりましたが、あまり身になる内容ではなかったのでおかわり。

# 今日書いたコード
任意の数字のリスト（[1,2,3,4,5]のような）から、ユニークな数字を除外する。
（例えば、[1,3,1,3,2]だと2が除外されて[1,3,1,3]になる）

    from collections import Counter
    
    def checkio(data):
    
        ### 変数定義
        delete = []
        counter = Counter(data)
        c_values = list(counter.values())
        c_keys = list(counter.keys())

        ### 1つだった数値を削除リストに追加
        for i in range(len(c_values)):
            if c_values[i] == 1:
                delete.append(c_keys[i])

        ### 削除リスト内の数字を元データから削除
        for x in delete:
            try:
                data.remove(data[data.index(x)])
            except ValueError:
                pass

        return data

# 今回学んだこと
- [shiracamusさん](https://qiita.com/shiracamus)に教えてもらったCounterを使用（コメント下さりありがとうございました）
- （今回は使いませんでしたが）enumerateはリストから「値」と「インデックス番号」を取得する
- 辞書型からkeyまたはvalueのみを抽出したい場合は、それぞれkeys()とvalues()を使う
- int型を直接for文に渡すとnot iterableエラーが出る（超初歩）

（出力例）

    for i in 1:
    (中略)
    TypeError: 'int' object is not iterable

# 構文まとめ
|メソッド|説明|構文|
|:--|:--|:--|
|Counter|Counterは指定した要素がリスト内に含まれる数をカウント（結果は辞書型で格納）collectionsをインポートして使用|Counter(List1)|
|enumerate|リストから「値」と「インデックス番号」を取得する|enumerate(list1)|
|keys|辞書型からkeyを抽出してリストにする|dict1.keys()|
|values|辞書型からvalueを抽出してリストにする|dict1.values()|
|isinstance|引数を二つ受け取り、オブジェクトが指定したクラスのインスタンスであるかを確認（一致する場合はTrueを返す）|isinstance("word",str)|
某タッチパネルのmacOS Mojave対応

- 5.1.1系を入れてから6系を上書きインストールで対応可能
    - その後、リブートいるかも。
    - プロファイルで、ダミーのシリアルデバイスの設定入れないとダメかも。 
- GestureManagerが入っていると、ラグがひどいので、要設定調整。

> これ、どこかのOSアップデートでダメになった。（ファイルが破壊されてる）

というのは昔の情報、2019.4 時点では、

- 6.0.0系を入れるのが正解
- GestureManager殺すと動かないので、適切なパラメータ設定する。
- Point&Clickは罠なので、Drag&Clickモードを使う。
- 相変わらず、タッチサーバとパネル側の接続順はシビア

設定ファイルは添付のような感じ。
https://gist.github.com/karinharp/ab89f1d0affac94f8829dbcedc9087ff
USBキーボードが認識しない場合の対処法（コマンド）

# はじめに

Windows 10でOSを再起動すると、USBキーボードが認識しなくなる場合の対処法。

# 症状

BIOS設定画面ではキーボードが使えるのに、Windowsログイン画面から使えなくなる。
そのため、ログインには「スクリーンキーボード」を用いてアカウント情報を入力することになる。。
症状からして、USBポートやキーボード自体ではなく、ドライバの問題と思われる。

デバイスマネージャを見ると、USB入力デバイスに案の定「！」マークがついている。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/253760/24d570ce-f741-d696-2a13-ee5e66ea7cbd.png)

プロパティを開いてみると、「このデバイスを開始できません。(コード 10)」と表示されている。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/253760/dbd0d08d-4a4e-1416-0ed7-790b81b8e450.png)

だいたいの問題は、ドライバの削除をしてから再インストールすると直る。
が、今回遭遇した問題は例外だった。
再インストールしたその時は直るが、再起動するとまたキーボードが使えなくなる。

# 対処

根本対処がわからないため、ログイン時からキーボードが使えるように暫定対処する。

## Windows Driver Kitのインストール

https://docs.microsoft.com/ja-jp/windows-hardware/drivers/download-the-wdk から「WDK」をダウンロードし、インストールする。
※2018/11/26現在、「EWDK の Windows 10、バージョン 1809 をダウンロードします。」というリンク表示となっている。

インストールすると、インストール先フォルダのC:\Program Files (x86)\Windows Kits\10\Tools\x64にdevcon.exeがあるため、これを使用する。

## ハードウェアIDの確認

デバイスマネージャで、黄色い「！」マークがついているデバイスのプロパティで「詳細」タブを開く。
プロパティプルダウンから「ハードウェア ID」を選択し、値を確認する。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/253760/246e69a1-f08e-4833-220c-b285d85bc037.png)
ここでは、「USB\VID_0853&PID_011D」がハードウェアID。

## バッチファイルの作成

上で確認したハードウェアIDに対して、デバイスの無効→有効を行うコマンドを記述する。

```
"C:\Program Files (x86)\Windows Kits\10\Tools\x64\devcon.exe" disable "USB\VID_0853&PID_011D"
"C:\Program Files (x86)\Windows Kits\10\Tools\x64\devcon.exe" enable "USB\VID_0853&PID_011D"
```

1行目は無効化、2行目は有効化している。

## タスクスケジューラへの登録

タスクスケジューラライブラリでタスクの作成を行う。
「全般」タブでは、「ユーザーがログインしているかどうかにかかわらず実行する」を選択する。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/253760/b20290dc-dd60-3c73-d5a2-ef6f1ec1ccac.png)

「トリガー」タブでは、タスクの開始を「スタートアップ時」にしたトリガーを新規追加する。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/253760/6152a293-f00b-e02a-6e11-148945496099.png)

「操作」タブでは、先ほど作成したバッチファイルのパスを指定する。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/253760/276245ce-9cf5-6755-9dd1-0fcf16403bba.png)

最後に「OK」をクリックしてタスクを作成する。


これで、OSの再起動時にもUSBキーボードが認識されるようになる。
GameAWeek ３週目

**Game A Week３週間目です！**
前から作ってみたいなと思っていた音ゲー作ってみました四行の音ゲーにしようと思ったら六行の音ゲーになってたんです。。。。。

譜面を何曲か作りたかったのですが一曲一分で公開前に作ったやつしかできませんでした（（泣

**今回の三週間目で学んだこと**

・他スクリプトからの変数取得

・キーボードでエフェクト表示

・cubeが落ちてきてmiss,great,parfectと別れて判別しテキストに表示

など

**ダウンロード**

リンクです。　https://www.dropbox.com/s/hlrd6kcd0nnqa1p/week3_Data.zip?dl=0
![bandicam 2018-11-26 15-32-12-687.jpg](https://qiita-image-store.s3.amazonaws.com/0/311207/0df4c830-5607-be6d-0d9a-a2013ec98bae.jpeg)

**感想**

score表示まで作りたかったがいろいろと忙しかったため作ることができなかった
結果をグラフとして表示させたりもしてみたい
dspic LED点灯


はじめて使うdspicのLED点灯まで苦労したのでメモ.
dsPIC30F4012,MPLAB X ,XC16
#MPLAB Xのインストール
http://www2.kaiyodai.ac.jp/~jtahar0/posts/activity19.html
このサイトを参考にさせていただきました.
microchipのHPよりMPLAB v5.05をインストール.
![スクリーンショット (1).png](https://qiita-image-store.s3.amazonaws.com/0/256678/06d9f72a-5d96-fbea-f763-ffeb4e9a7b84.png)

#MPLAB X プログラムの作成手順
インストールしたらデスクトップ画面に出てくる"MPLAB X IDE v5.05"を起動
### 1.起動
![スクリーンショット (2).png](https://qiita-image-store.s3.amazonaws.com/0/256678/3669c008-cdb1-eb29-a619-8f00efab0093.png)
### 2.新規プロジェクトの作成
![スクリーンショット (13).png](https://qiita-image-store.s3.amazonaws.com/0/256678/42f74371-cd64-b46a-9f1f-ce55a42fa778.png)
### 3.プロジェクトの種類の選択
![スクリーンショット (14).png](https://qiita-image-store.s3.amazonaws.com/0/256678/8589d914-c938-e513-0c25-b522ed6de107.png)
### 4.使うPICの種類の選択
![スクリーンショット (15).png](https://qiita-image-store.s3.amazonaws.com/0/256678/104f44ce-dd9f-025a-699b-9da2622b577f.png)
### 5.プログラム書き込み装置の選択
![スクリーンショット (17).png](https://qiita-image-store.s3.amazonaws.com/0/256678/7dc5b7aa-8cda-f481-18e7-f90b9c94ccbe.png)
### 6.コンパイラの選択
![スクリーンショット (18).png](https://qiita-image-store.s3.amazonaws.com/0/256678/b300ddf1-473d-1282-fa7e-2470ea688ac1.png)
### 7.プロジェクトの名前、保存場所の設定
![スクリーンショット (19).png](https://qiita-image-store.s3.amazonaws.com/0/256678/d1bf9e75-2aa1-85f7-fe80-d94893c0f97a.png)
### 8.ソースファイルの作成
![スクリーンショット (20).png](https://qiita-image-store.s3.amazonaws.com/0/256678/00dd2f6b-1186-891d-8319-fb8ca8c9a0d0.png)
### 9.ファイルの種類の選択
![スクリーンショット (21).png](https://qiita-image-store.s3.amazonaws.com/0/256678/58bfa2ce-4585-8ffb-7c47-1626707b8e10.png)
### 10.ファイルの名前、保存場所の設定
![スクリーンショット (22).png](https://qiita-image-store.s3.amazonaws.com/0/256678/0b9b3183-6bd5-71e0-59a1-f85a602e2068.png)
### 11.ソースファイル「led.c」の編集,コンパイル,書き込み
![スクリーンショット (24).png](https://qiita-image-store.s3.amazonaws.com/0/256678/245c8c38-1e3b-1d1e-1a47-447d5632018f.png)


```

//********************************************************************
//ヘッダファイルをインクルード
#include "p30f4012.h"
#include <libpic30.h>   // __delay_ms()が定義されている


 
// DSPIC30F4012 Configuration Bit Settings

// 'C' source line config statements

// FOSC
_FOSC(CSW_FSCM_OFF & FRC_PLL8); 
_FWDT(WDT_OFF);
_FBORPOR(PBOR_ON & BORV20 & PWRT_64 & MCLR_EN); 
_FGS(CODE_PROT_OFF);

//メイン関数
 
int main(void)
{
 
 //===================================================================
 //変数を定義
 
 
 //===================================================================
 //入出力ポートの設定、初期化
 
 TRISCbits.TRISC13=0; //LEDポート出力

 
 //===================================================================
 //whileで回します。
 
 while(1)
 {
     LATCbits.LATC13=1;

 }
 
 return(0); 

}
 
//********************************************************************


```
##回路図
外部から電源はとっています
![LED_kairo_zu.png](https://qiita-image-store.s3.amazonaws.com/0/256678/cf595b97-a104-455a-cc7f-95dd457e6446.png)
###pin配置
![スクリーンショット (25).png](https://qiita-image-store.s3.amazonaws.com/0/256678/accd54e5-d466-ecc4-c708-21e248be6029.png)
Node Tokyo 2日目

![Capture.PNG](https://qiita-image-store.s3.amazonaws.com/0/300937/b4b4206f-828f-1996-535c-09557f3641f0.png)

こんにちは! 去年11月19日〜20日、2018年は東京ミッドタウン日比谷にNode Tokyoの会議のために行きました。ですから、今日は私のいくつか学びと経験をシェアしています。たくさんビジネスマンとブロックチェーン開発者とはブロックチェーンについてを議論しました。
Node Tokyo 2018 Conferenceは初めの会議でした。将来的には多くのNode Tokyo会議を行われる。
Node Tokyoは２種類の議論がある。
- パネルディスカッション
- キーノート
Node Tokyoの2日目の日程のために： https://nodetokyo.jp/schedule/

2日目にはトピックがいいので、パネルディスカッションにもっと興味がありました。

![Image from iOS (5).jpg](https://qiita-image-store.s3.amazonaws.com/0/300937/1e0ddaef-dd3d-5234-e5ba-2c28910fe738.jpeg)

1日目にはDanny RyanとHsiao-Wei Wang, Ethereum FoundationのCore Researcherはイーサリアム2.0を話しました。キャスパー・シャーディングについてをシェアしましたそして、彼らはイーサリアム2.0にはProof-Of-Stakeのコンセンサスを使うことを言い渡しました。
２日目にはDanny RyanとHsiao-Wei WangとAya Miyaguchiはイーサリアム2.0についてのパネルディスカッションがありました。イーサリアムの現在の具合を話しましたそして、イーサリアム2.0の開発しながら、何の問題があるも話しました。


![Image from iOS (4).jpg](https://qiita-image-store.s3.amazonaws.com/0/300937/ff868886-fe33-264c-5ef3-cfa45082078d.jpeg)


Eriko Suzuki、MistletoeのDirectorとTakashi Sano、GB Blockchain LabsのVenture PartnerとBenjamin Rameau、Binance LabsのDirectorとAlex Shin、HashedのPartnerは「ICOをこえて: ブロックチェーン領域においてVCはどう進化するか」についてパネルディスカッションがありました。彼らはブロックチェインのベンチャーキャピタリストの役割について, また何の新しベンチャーを探しましたについてを話しました。
このパネルで、Takashi Sanoはフィリピンの有名なブロックチェーンフィンテック会社、coins.phがようなベンチャーを探していると言いました。

![Image from iOS (6).jpg](https://qiita-image-store.s3.amazonaws.com/0/300937/feb12bd6-495a-cfe6-8f2e-33069828b233.jpeg)

彼らはまた、各国のブロックチェーンコミュニティについてパネルディスカッションがありました。日本、韓国、中国、ニューヨークのブロックチェーンコミュニティについてのディスカッションでした。韓国と日本からの学会は、ブロックチェーンのコミュニティで活動しています。でも、中国の政府はICOやクリプトの交流を禁止しているので、学生はブロックチェインの技術に興味を持つ少なくなっています。ですから、中国からの学会は、あまり活動していまでん。

Node Tokyo 2018 Conferenceで多くのことを学びましたそして、他のブロックチェーン開発者に会ったので、良い経験でした。ありがとうございました！
[Angular] 文脈（ルーティングしたコンポーネント）に応じたメニューバーを表示したい

意味がわからないタイトルですみません。
なんと書けば伝わるのか、なかなかわからないです。 :sweat: 

# やりたかったこと

* メニューが入ったツールバーを表示したい
* アプリケーション全体で共通のメニューをルートコンポーネントで定義したい
* ルーティング先のコンポーネントで、コンポーネント専用のメニューを定義したい

完成形はこんな感じです。

![Angular-context-menubar.mov.gif](https://qiita-image-store.s3.amazonaws.com/0/59475/9ead18a5-02c1-fd22-7b36-31e65a5a0910.gif)

Item1コンポーネントで、Item 1 Menuを定義しています。
Item2コンポーネントで、Item 2 Menuを定義しています。
それらをルートコンポーネント内で定義しているツールバー内に表示しています。

# やったこと

* ルートコンポーネントのhtml内に`*ngTemplateOutlet`を置き、外部定義されたテンプレートを表示させるようにしました。
* ルートの`activate`イベントを拾い、ルーティング先コンポーネントからhtmlを取得して上記のテンプレートに入れるようにしました。
* ルーティング先コンポーネントのhtml内で`ng-template`を用いてテンプレートを定義しました。
* ルーティング先コンポーネントで、テンプレートを公開しました。

## 実装

実際に作ったものたちです。
Angular Materialを利用しています。



### ルートコンポーネント

ルートコンポーネントのhtml内に`*ngTemplateOutlet`を置き、外部定義されたテンプレートを表示するようにします。

```html:app.component.html
      <ng-container *ngTemplateOutlet="additionalMenu"></ng-container>
```

`additionalMenu`は`TemplateRef<any>`型です。

```ts:app.component.ts
export class AppComponent {
  additionalMenu: TemplateRef<any>;
}
```

ルートの`activate`イベントを拾うようにします。

```html:app.component.html
    <router-outlet
      #routerOutlet
      (activate)="onActivate($event)"
    ></router-outlet>
```

`activate`イベントの引数は、コンポーネントのインスタンスそのものになります。
ここでテンプレートを取得して`*ngTemplateOutlet`が参照する変数へ代入しています。

```ts:app.component.ts
  onActivate(event): void {
    if (isWithTemplate(event)) {
      this.additionalMenu = event.template;
    } else {
      this.additionalMenu = undefined;
    }
  }
```

ここで使っている`isWithTemplate`は型ガードというもので、型判定とキャストを同時にやります。

```ts:app.component.ts
const isWithTemplate = (object: any): object is WithTemplate =>
  !!object.template;
```

`WithTemplate`というのは作成したインターフェースです。`TemplateRef<any>`を公開するコンポーネントであることを意味させます。

```ts:with-template.ts
import { TemplateRef } from '@angular/core';

export interface WithTemplate {
  template: TemplateRef<any>;
}
```

### ルーティング先コンポーネント

`Item1Component`と`Item2Component`を作りました。

html内で`ng-template`を用いてテンプレートを定義しました。

```html:item1.component.ts
   <ng-template #template1>
      <button mat-button [matMenuTriggerFor]="menu">Item 1 Menu</button>
      <mat-menu #menu>
        <button mat-menu-item (click)="countUp()">Count Up</button>
        <button mat-menu-item (click)="countDown()">Count Down</button>
      </mat-menu>
    </ng-template>
 ```

テンプレートを公開していることを意味する`WithTemplate`を実装し、公開しました。

```ts:item1.component.ts
export class Item1Component implements WithTemplate {
  @ViewChild('template1')
  template: TemplateRef<any>;
}
```

`Item2Component`も同じような内容なので省略します。


# ソース全体

こちらに置きました。

https://github.com/sengokyu/ex-ng-template-outlet

ちなみに、テストは失敗します。


# 感想

一応動きましたが、Angularのお作法的によいのかどうか気になります。