OmniAICreator/Qiita-1.07M huggingface dataset:
Angular4 Karma Test の Uncaught Error: Missing: SyncTestZoneSpec エラー

ng test でテストを実行すると Missing: SyncTestZoneSpec エラーが発生する場合がある。

```
Uncaught Error: Missing: SyncTestZoneSpec
  at http://localhost:9876/_karma_webpack_/vendor.bundle.js:32051
```

WebStrom などでコミットする時に「Optimaze import」が有効になっていると、import の順序が書き換えられてしまうのが原因だ。

test.ts の import の順序を下記の通りにすると解決する。


```test.ts
import 'zone.js/dist/long-stack-trace-zone';
import 'zone.js/dist/proxy.js';
import 'zone.js/dist/sync-test';
import 'zone.js/dist/jasmine-patch';
import 'zone.js/dist/async-test';
import 'zone.js/dist/fake-async-test';
import { getTestBed } from '@angular/core/testing';
import {
  BrowserDynamicTestingModule,
  platformBrowserDynamicTesting
} from '@angular/platform-browser-dynamic/testing';

```
essen kilo gebrus

Salam strike untuk para pemancing, kali ini kami akan membagikan informasi dalam sebuah artikel yang berjudul Essen Kilo Gebrus atau bisa disebut harian/pelampungan. Saat ini penggunaan essen tidak hanya digunakan dalam lomba mancing di kolam kolam besar alias kolam ikan indukan/babon saja, kolam ikan dengan sistem kilo gebrus juga sudah marak menggunakan essen untuk menghasilkan lebih banyak strike.

Tidak perlu sulit-sulit untuk mencari umpan, pakai umpan yang seadanya di sekitar anda, dan berikut ada racikan umpan harian :

Racikan umpan pertama, siapkan:

        1 bungkus deho, – Paikin biru, – 3 butir telur bebek (ambil kuningnya), – 1 bungkus susu bubuk putih, – kroto seperlunya, dan Air panas.

Setelah semua bahan diatas terkumpul, haluskan paikin. Lalu campur dengan susu bubuk putih, setelah itu masukan deho dan aduk hingga rata. Kemudian Masukan kuning telur dan aduk hingga rata kembali.

Setelah itu, masukkan kroto dan aduk kembali hingga merata, lalu kukus adonan tadi selama 10-20 menit. setelah dingin umpan mancing ikan mas siap dipakai. Essen Kilo Gebrus
http://www.tukangessen.com/essen-kilo-gebrus/
JavaでXML有効文字以外をコード値指定で弾く

# はじめに
仕事でXMLを取り込む事があったんだけどその時に相手が制御コードを仕込んできた。

取り込みには下記のメソッドを使用していた。

Unmarshaller#unmarshal(XMLStreamReader reader, Class<T> declaredType)

XMLの中身を文字列として取得⇒ストリームに変換⇒オブジェクト化という流れだ。

そして下記のエラーが出る。

Message: ドキュメントの要素コンテンツに無効なXML文字(Unicode: 0x2)が見つかりました。
※無効な文字は何個かあったけど省略

で、相手側が直してくれないらしいので文字列置換で無効なXML文字を取り除くことになった。

# XMLで使える文字列

[W3C勧告文書](http://w4ard.eplusx.net/translation/W3C/REC-xml-20081126/#charsets)

上記サイトによるとXMLで使える文字のコード値は下記の６パターンとのこと

① #x9　⇒　タブ
② #xA　⇒　改行（LF）
③ #xD　⇒　改行（CR）
④ [#x20-#xD7FF]　⇒　半角スペース～ハングル
⑤ [#xE000-#xFFFD]　⇒　外字～特殊用途文字
⑥ [#x10000-#x10FFFF]　⇒　線文字B音節文字～未定義

まぁ基本的に使う文字は④に入ってると思って貰えばいい

一応、Unicodeにおける文字とコード値の表を置いておく

[Unicode一覧表](https://ja.wikipedia.org/wiki/Unicode%E4%B8%80%E8%A6%A7%E8%A1%A8)

# Javaでの表現
javaでコード値指定して置換する場合、こういう風に書く。
下記は半角スペースをブランクに置換している。
Matcherとか使ってもいいんだけどとりあえずString#replaceAllでも正規表現は使える。

```java:
String str = "XMLを文字列化したもの";
str = str.replaceAll("\\u0020", "");

```

Javaだと「\x00」で２桁の文字コードで「\u0000」で４桁の文字コードが書ける。
バックラッシュが２つ書いてあるのはエスケープです。

全部４桁で書くとこうなる
① #x9　⇒　"\\u0009"
② #xA　⇒　"\\u000A"
③ #xD　⇒　"\\u000D"
④ [#x20-#xD7FF]　⇒　"[\\u0020-\\uD7FF]"
⑤ [#xE000-#xFFFD]　⇒　"[\\uE000-\\uFFFD]"

待て・・・Unicodeだと５桁以上もあるじゃないか・・・どうやって表現すればいいんだと思ったが
正規表現で複数桁のコード値を指定する方法があった。

⑥ [#x10000-#x10FFFF]　⇒　"[\\x{10000}-\\x{10FFFF}]"

これでいいらしい。

# 合体させて拒否る
正規表現はOR判定できるのでパイプでくっつけて、全部否定する。

```java:
String str = "XMLを文字列化したもの";
str = str.replaceAll("(?!\\u0009|\\u000A|\\u000D|[\\u0020-\\uD7FF]|[\\uE000-\\uFFFD]|[\\x{10000}-\\x{10FFFF}]).", "");

```

これで使えない文字を外したうえで取り込みができた。
正規表現の部分で最後に「.」（ドット）を書かないと反応しなくてずっと悩んだけど
とりあえずこれで使えない文字を外すことはできた。

**2017/08/02追加**
コメントで指摘されたんだけどこれでもできる。
言われて気づいたが、なんでかパイプで区切っておかないといけないと勘違いしていた。

```java:
String str = "XMLを文字列化したもの";
str = str.replaceAll("[^\\u0009\\u000A\\u000D\\u0020-\\uD7FF\\uE000-\\uFFFD\\x{10000}-\\x{10FFFF}]", "");

```

# 最後に
WEBで調べた時に「含まない文字を除去」っていうのが見つからなかったので今回の記事を書きました。
含まない行を検索する方法はいっぱい出てくるんだけどね。
Visual Studio Code(for Mac)の言語設定を変更する

* コマンドパレットを開く(⇧⌘P)
* 「言語を構成する」を選択する
* 以下のように変更する（今回は英語）

```
{
	"locale":"en-US"
}
```

* Visual Studio Codeを再起動する

## 参考にしたページ

* [Visual Studio Code の言語設定](http://sh-yoshida.hatenablog.com/entry/2016/04/17/120334)
MTに独自のエディタを追加する

Movable Typeの記事編集画面にある本文のエディタはプラグインで追加できるようになっています。リッチテキストフォーマットで使えるTinyMCEも本体組み込みではなくプラグインとして実装されています。

プラグインからエディタを追加するのはとても簡単です。``config.taml``に以下を記述するだけです。

```yaml:config.yaml
id: MyEditor
name: My Editor
version: 0.00
description: The my editor.

editors:
    myeditor:
        label: My Editor
        template: editor.tmpl

text_filters:
    my_format:
        label: My format
        code: ...
```

``editors``の下にエディタの識別子を入れ、その中にエディタの名前とテンプレートのファイル名を指定します。エディタはフォーマットに結び付けられるので、必要であれば独自のフォーマットも定義しておきます。

エディタのテンプレートは入力欄の部分にはめ込まれるとかではなく、単に編集画面の先頭にインクルードされるだけです。大抵はJavaScriptを読み込むだけなので、以下のようにして独自のJSファイルを読み込む記述を追加します。

```html:tmpl/editor.tmpl
<mt:setvarblock name="js_include" append="1">
<script type="text/javascript" src="<mt:Var name="static_uri"/>plugins/MyEditor/my_editor.js"></script>
</mt:setvarblock>
```

ここからが本番です。エディタの実体はJavaScriptの``MT.Editor``を拡張したオブジェクトです。エディタオブジェクトを定義するコードを先ほどのJSファイルに記述していきます。

まずはクラスメソッド的なものを定義していきます。

```js
MT.Editor.MyEditor = function() { MT.Editor.apply(this, arguments) };

$.extend(MT.Editor.MyEditor, MT.Editor, {
    isMobileOSWYSIWYGSupported: function() {
        return false;
    },
    formats: function() {
        return ['my_format'];
    },
});
```

``isMobileOSWYSIWYGSupported``メソッドはモバイルでもWYSIWYGをサポートするかどうかを返すものです。
``formats``メソッドはこのエディタがサポートしているフォーマット郡を返すメソッドです。ここでは独自の``my_format``のみをサポートしていることにします。

続いてインスタンスメソッド的なものを定義します。

```js
$.extend(MT.Editor.MyEditor.prototype, MT.Editor.prototype, {
    initEditor: function(format) {
        console.log('initEditor:', format);

        this.$textarea = $('#' + this.id);
        this.$editorArea = this.$textarea.parent();

        this.$box = $('<div style="height:100px;border:dashed 2px #f00; text-align:center; font-size:30px">My Editor</div>').appendTo(this.$editorArea).hide();

        this.setFormat(format, true);
    },
    setFormat: function(format, calledInInit) {
        console.log('setFormat:', format, calledInInit);
        this.$textarea.hide();
        this.$box.show();
    },
    hide: function() {
        console.log('hide');
        this.$textarea.show();
        this.$box.hide();
    },
});
```

``initEditor``メソッドはエディタの初期化時に呼ばれるメソッドです。ここではテキストエリアの代わりに表示する適当な要素を用意しています。
``setFormat``メソッドは他のフォーマットから切り替えられた時に呼ばれるメソッドで、エディタの表示処理を行います。初回は``initEditor``メソッドしか呼ばれないので自分で呼び出します。
``hide``メソッドは他のエディタに切り替えられた時に自分を隠すためのメソッドです。これを実装しないと他のエディタでも表示されっぱなしになってしまいます。

最後に以下のコードで``MT.EditorManager``にエディタを登録します。

```js
MT.EditorManager.register('component', MT.Editor.MyEditor);
```
これをMTに組み込むとこんな感じになります。

![download.png](https://qiita-image-store.s3.amazonaws.com/0/42710/8536a077-e2d8-5f00-ae2b-49f36742a00b.png)

あとはエディタの機能をひたすら実装すればエディタが完成します。
Visual Studio Code をリモートから使いたい

# 概要

Vagrant の中に Visual Stuio Code をいれて、それを外からつかいたいというときの方法を調べた

# まとめ


```
apt-get install libgtk2.0-0 libxss1 libasound2
```

あとは以下の設定でつなぐ

* [Running Visual Studio Code on Linux](https://code.visualstudio.com/docs/setup/linux)

# 一旦ログインしてから起動する

```
ssh -p 2222 -AY vagrant@localhost 
code
```


# 直接起動する

`-w` がないと、すぐにウィンドウがとじてしまう（そもそも開かない？）

```
ssh -p 2222 -AY vagrant@localhost code -w
```

`-w` は

```
  -w, --wait                  Wait for the window to be closed before
                              returning.
```
AzureのパブリックIPアドレス範囲

# 概要

Microsoft AzureのパブリックIPアドレスの範囲は「[Download Microsoft Azure Datacenter IP Ranges from Official Microsoft Download Center](https://www.microsoft.com/en-us/download/details.aspx?id=41653)」でXMLファイルで配布されている。

# 詳細

Microsoft Azureで使われるパブリックIPアドレスの範囲は「[Download Microsoft Azure Datacenter IP Ranges from Official Microsoft Download Center](https://www.microsoft.com/en-us/download/details.aspx?id=41653)」で配布されている。このことは「[Azure における IP アドレスの種類 | Microsoft Docs](https://docs.microsoft.com/ja-jp/azure/virtual-network/virtual-network-ip-addresses-overview-arm#public-ip-addresses)」で下記のように説明されている。

> AzureリソースへのパブリックIPアドレス(動的/静的)の割り当てに使用するIPアドレス範囲のリストは、「[AzureデータセンターのIPアドレス範囲](https://www.microsoft.com/en-us/download/details.aspx?id=41653)」で公開されています。

## 配布形式

2017年8月1日確認時点で、配布形式はXMLファイルで、以下のような内容になっている。

    <?xml version="1.0" encoding="utf-8"?>
    <AzurePublicIpAddresses xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <Region Name="europewest">
        <IpRange Subnet="40.112.124.0/24" />
        <IpRange Subnet="65.52.128.0/19" />
        :
      </Region>
      <Region Name="japanwest">
        <IpRange Subnet="23.98.56.0/26" />
        <IpRange Subnet="23.98.56.96/28" />
        :
      </Region>
    </AzurePublicIpAddresses>

## 東日本/西日本データセンターのパブリックIPアドレス範囲

2017年8月1日確認時点で、以下になっていた。

|東日本|西日本|
|---|---|
|13.71.128.0/19|13.73.232.0/21|
|13.73.0.0/19|23.98.56.0/26|
|13.78.0.0/17|23.98.56.96/28|
|23.98.57.0/27|23.98.56.128/26|
|23.98.57.64/26|23.100.104.0/21|
|23.98.57.128/27|40.74.64.0/19|
|23.100.96.0/21|40.74.96.0/19|
|23.102.64.0/20|40.74.128.0/20|
|23.102.80.0/24|52.175.128.0/19|
|40.115.128.0/17|52.239.146.0/26|
|52.155.96.0/19|52.245.92.0/27|
|52.156.32.0/20|52.253.172.0/22|
|52.156.48.0/21|104.46.224.0/20|
|52.156.56.0/23|104.214.128.0/19|
|52.185.128.0/18|104.215.0.0/18|
|52.239.144.0/26|138.91.16.0/20|
|52.239.144.64/27|191.233.32.0/19|
|52.243.32.0/20|191.237.236.0/24|
|52.243.48.0/28|191.238.68.0/26|
|52.243.49.0/24|191.238.80.0/21|
|52.243.50.0/23|191.238.88.0/22|
|52.243.52.0/24|191.238.92.0/23|
|52.243.56.0/21|191.239.96.0/20|
|52.245.36.0/25||
|52.245.36.128/27||
|52.246.160.0/19||
|52.253.176.0/22||
|104.41.160.0/19||
|104.46.208.0/20||
|138.91.0.0/20||
|191.234.138.0/24||
|191.237.240.0/26||
|191.237.240.64/28||
|191.237.241.0/24||

# 参考

* [Download Microsoft Azure Datacenter IP Ranges from Official Microsoft Download Center](https://www.microsoft.com/en-us/download/details.aspx?id=41653)
* [Azure における IP アドレスの種類 | Microsoft Docs](https://docs.microsoft.com/ja-jp/azure/virtual-network/virtual-network-ip-addresses-overview-arm#public-ip-addresses)

----

本ページ内容は作成者の個人的なメモです。内容を保証するものではありません。また作成者の所属組織等とは一切かかわりがありません。
All About ACS: IBM i Access Client Solutions - IBM i を構成・接続する

# 接続先の IBM i を構成する
導入後にまず行うのは、 接続先の IBM i の構成です。
ACS を起動して「システム構成」を選びます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/184930/cf3df2ef-d1f8-970c-a667-b52e29823bf6.png)

「新規」でシステムを追加します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/184930/0ca3e4c0-831f-19c6-d6a3-7c1e755fdd1e.png)

「一般」タブの「システム名」でホスト名か IP アドレスを指定します。任意の名前を付け後からIPアドレスを指定することもできます。
「接続を確認」してもいいでしょう。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/184930/e8fb74f8-a278-77da-690a-4b48fdacdd8b.png)

「接続」タブでパスワード入力の方法とIPアドレスの確認方法を指定します。
自動ログインの機能を使いたいならデフォルトユーザー名の指定を選択しユーザー名を指定しておきます。
IPアドレスが解決できない「システム名」を「一般」タブに指定した場合「IPアドレスのルックアップ頻度」を「なし」にして「IPアドレス」を指定します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/184930/c14f9dd4-f767-aa2f-a3fe-55a5b10a83b0.png)

「コンソール」タブでコンソール情報を指定できます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/184930/c6068580-46f0-66a8-1ca4-72db09f279af.png)

# 接続先の IBM i を選択し機能を選ぶ
接続先の IBM i を構成すると「システム」で構成済みシステムが選択できます。
通常の利用法は、ここで対象システムを選んでおいて、処理したい機能をクリックすることになります。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/184930/da375bb9-10cd-fc4d-1709-e55bcb8ec35c.png)

# ふたつの 5250
項目に二つの 5250 があるのがわかります。
一つは「一般」の「5250エミュレーター」、もう一つは「管理」の「5250セッション管理機能」です。
**通常はセッション構成を詳細に定義し利用できる「5250セッション管理機能」を使います**。実は 接続先の IBM i を構成しないでも利用できます。
「5250エミュレーター」は選択したシステムにデフォルトの構成で接続する方法です。
導入直後は英語のホストコードページで接続しようとするなど、結局、構成が必要なので「5250セッション管理機能」で構成を行ってから接続した方がいいでしょう。

# サインオン・プロンプト
これまでのAccess for Windows と 同様、サインオン・プロンプトが表示されます。
この頻度は上記の「接続」タブで「パスワード・プロンプト」の指定に従います。
もちろん、これれまでと同様にログインを自動化することも可能です。自動ログオンの方法は[こちら](http://qiita.com/6onoda/items/369b9026edfd90a51a2b)をご覧ください。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/184930/3c385869-8d26-f456-1955-f06d50b61f9f.png)


***
「All About ACS」では IBM i に対する新しいクライアント「IBM i Access Client Solutions」の情報をいろいろ提供していきます。
[記事一覧はこちら](http://qiita.com/6onoda/items/2dc925586d8d3b8644f2)で確認いたけます。

許可の無い転載を禁じます。
この記事は筆者の個人的な責任で無保証で提供しています。
当記事に関してIBMやビジネスパートナーに問い合わせることは、固くお断りします。
***
Laravel5.4でminioに接続するときの設定メモ

# ただのメモ書きです

```php:filesystems.php
<?php

return [
    /*
    |
    | (色々省略)
    |
    */

    'disks' => [

        'local' => [
            'driver' => 'local',
            'root'   => storage_path('app'),
        ],

        'public' => [
            'driver'     => 'local',
            'root'       => storage_path('app/public'),
            'url'        => env('APP_URL').'/storage',
            'visibility' => 'public',
        ],

        's3' => [
            'driver'                  => 's3',
            'key'                     => 'AWSキー',
            'secret'                  => 'AWSシークレットキー',
            'region'                  => 'リージョン',
            'endpoint'                => 'minioのURL',
            'bucket'                  => 'Bucket名',
            'use_path_style_endpoint' => true,
        ],
    ],
];
```

`'use_path_style_endpoint' => true`
これをフレームワークとライブラリのソースから見つけ出すのに時間がかかった。
リモートからXのアプリを使えるマシンを Vagrant で作る

# 概要

リモートからXのアプリを使える仮想マシンを Vagrant で作りたい。

# まとめ

xauthを忘れずにいれる

# 実際

## 準備と起動
```
vagrant init bento/ubuntu-16.04
vagrant up
```

## 必要なソフトを入れる

```
ssh -p 2222 vagrant@localhost sudo apt-get update
ssh -p 2222 vagrant@localhost sudo apt-get install xauth x11-apps
```

`x11-apps` は、確認用

## 確認

```
ssh -p 2222 -AY vagrant@localhost xclock
```
Common Lisp (sbcl) を使って SPARQL 検索をする

## Debian に SBCL をインストール
[こちらのブログ記事](http://blog.livedoor.jp/s-koide/archives/2287418.html)に従って，SBCL をインストールし，quicklisp もインストールしてください．

github から次のようにして，cl-fuseki を quicklisp のローカルプロジェクトとしてインストールします．

    $ sudo apt-get install git
    $ git clone https://github.com/madnificent/cl-fuseki.git
    $ mv cl-fuseki quicklisp/local-projects/
    $ sbcl
    CL-USER(1): (asdf:initialize-source-registry)
    CL-USER(2): (ql:quickload :cl-fuseki)

これで drakuma，cl-ppcre，jsown が自動的にロードされ，cl-fuseki もコンパイル＆ロードされるはずです．

## DBpedia Japanese にアクセスしてみる
上記のコードに引き続いて，次のようにしてみます．

    CL-USER(5): (in-package :cl-fuseki-user)
    FUSEKI-USER(6): (defparameter *repository*
      (make-instance 'fuseki::virtuoso-repository :name "DBpedia Japanese"
                 :server (make-instance 'fuseki::virtuoso-server
                           :base-url "http://ja.dbpedia.org/sparql")))
    FUSEKI-USER(7): (setq result
     (query *repository*
         "select distinct * where { <http://ja.dbpedia.org/resource/東京都> ?p ?o .  } LIMIT 100"))

するとJSON形式の答えが得られるはずです．ロードされたパッケージの中に jsown もあるので，その機能を使って得られた結果から望みの情報を取りだすコードを書きます．

今回は一番簡単に，SBCLとquicklispに依存して virtuoso の提供するエンドポイントにアクセスしてみましたが，allegro common lisp でも cl-fuseki を使って virtuoso エンドポイントにアクセスできることを報告しておきます．
minio/minfsプラグインを使って、nginxコンテナのvolumeにminioのbucketを指定してみた

## 参考

* https://github.com/minio/minfs/tree/master/docker-plugin

## docker 1.13 以降が必要。

```bash:/etc/apt/sources.list.d/docker.list
deb https://apt.dockerproject.org/repo ubuntu-xenial main
```

```
sudo apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D
sudo apt update
sudo apt install -y docker-engine docker-compose
```

```
$ docker -v
Docker version 17.05.0-ce, build 89658be
```

## minio/minfs pluginインストール

```bash:230MBほどダウンロードする
sudo docker plugin install minio/minfs
```

----

## docker-compose.yml

```yaml:minio/minio
minio1:
  image: minio/minio
  ports:
    - "9000:9000"
  environment:
    - "MINIO_ACCESS_KEY=AKIAIOSFODNN7EXAMPLE"
    - "MINIO_SECRET_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
  volumes:
    - ./export:/export
    - ./config:/root/.minio
  command: server /export
```

```yaml:minio/minfs+nginx
version: '2'
services:
  my-test-server:
    image: nginx
    ports:
      - "80:80"
    volumes:
      - my-test-store:/usr/share/nginx/html:ro

volumes:
  my-test-store:
    driver: minio/minfs
    driver_opts:
      endpoint: "http://localhost:9000"
      access-key: "AKIAIOSFODNN7EXAMPLE"
      secret-key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
      bucket: "bucket1"
```

## 動作確認

```
cd minio1
docker-compose up -d
docker-compose logs -f
```

ACCESS_KEYとSECRET_KEYが指定したものであることを確認。

![スクリーンショット_2017-08-01_15-22-36.png](https://qiita-image-store.s3.amazonaws.com/0/25728/0bd0234c-5758-b84c-149e-df71cb672578.png)

http://localhost:9000 にアクセスし 先程の ACCESS_KEYとSECRET_KEY でログイン。右下の＋マークをクリックし
bucketを作成。名前は`bucket1`とした。
その中に index.html をupload。

![スクリーンショット_2017-08-01_15-24-47.png](https://qiita-image-store.s3.amazonaws.com/0/25728/aab7c8ad-8635-4be1-c955-c670c75ac1ed.png)

```
cd nginx
docker-compose up -d
```

http://localhost にアクセスし index.html の中身が表示されていることを確認。

![index.png](https://qiita-image-store.s3.amazonaws.com/0/25728/777023c5-9f50-880c-faa0-ba3ccb57fa95.png)
AWS ECSにdockerのローカルイメージをデプロイして、SSHでログインする。

#目次
- はじめ
- 前提条件
- 手順
    - AWS CLIの準備
    - AWS ECSの準備
    - コンテナの中で動かしてみる
- まとめ

#前提条件
-AWSコンソールにログインできる
-dockerについて理解している


#手順
1. AWS CLIの準備
2. AWS ECSの準備
3. コンテナの中で動かしてみる
4. sshで接続してみる



##AWS CLIの準備
ここはターミナルでの操作になります。まずインストールですが、これはここをみれば大体わかると思います。
http://docs.aws.amazon.com/ja_jp/streams/latest/dev/kinesis-tutorial-cli-installation.html

インストールが終わったら、今度はaws configureの設定を行いましょう。

```
$aws configure
AWS Access Key ID [None]: <自分のAccess key ID>
AWS Secret Access Key [None]: <自分のSecret Access key>
Default region name [None]: <自分の住んでいるところから近いregion　東京なら：ap-northeast-1>
Default output format [None]: json //ここはjsonのままでと思います。
```

これでいろいろ下準備はおわりですね。そして次は今回使うAWS ECS(https://aws.amazon.com/jp/ecs/　)を使っていきます。


##AWS ECSの準備
場所 : AWSコンソール → サービス → ECS

準備として、上記の場所にリポジトリメニューがあると思うので、そこから適当なリポジトリ名をつけます。
このリポジトリにローカルにある指定のイメージをpushしていきましょう。リポジトリ作ったならチュートリアルみたいのがでてるとは思います。

####1. まずdockerにログインコマンド発行
```aws ecr get-login --no-include-email --region <リージョン名>```


####2. 発行されたdockerログインコマンド(めちゃ長いやつ)を叩く


####3. dockerのtagをつける(おそらく自由に変更可能)
```docker tag test:latest 068701748150.dkr.ecr.ap-northeast-1.amazonaws.com/test:latest```


####4. タグをつけたイメージをプッシュ
```docker push 068701748150.dkr.ecr.ap-northeast-1.amazonaws.com/test:latest```

これでアップロードの過程がターミナルに出ると思います。終わったらリポジトリの準備はおわりです！


##コンテナの中で動かしてみる
次はクラスター、サービス、タスクを作成して、実際にコンテナを起動していきます。

####1. キーペアを生成する。

場所 : サービス→EC2→キーペア

キーペアはリージョンごとに違います。必ずAWSコンソールの右上が東京になっているか確認してください。
生成したあとは、任意のディレクトリに保管。


####2. タスクを定義する。

場所 : サービス→ECS→タスク定義

タスク定義名を設定し、コンテナの追加からプッシュしたリポジトリのイメージを選択する。これによって、このタスクが実行された時、ローカルと同じ内容をECS
内のコンテナに立ち上げてくれます。


####3. クラスター作成

場所 : サービス→ECS→クラスター→クラスター作成

ssh接続に必須なのはキーペアの項目です。先ほど生成したものに設定してください。
他のインスタンスタイプやVPC関連のものは適宜、必要なものに設定してください。
また原則クラスターの設定は作成した後、変更できないようなので注意したほうがいいですね。


####4.クラスターの持つサービスを生成する。

場所　：　サービス→ECS→クラスター→サービス（タブ）→作成

ここでは、サービスの持つタスク数、サービス名を登録し、どのタスクを実行するか選択しましょう。
タスク定義の項目は定義されているものがでてくるので、ちゃんと定義したものを選択しましょう。
　作成した後は、自動的にその設定されたタスクをサービスが実行してくれます。タスクタブにあるのがACTIVEになって入れば成功です。


これで、クラスター、サービス、タスクの設定は終了です。最後にsshについてです。

##ECSにsshで接続する。


####1. セキュリティグループにsshを追加
場所 : サービス→EC2→セキュリティグループ→自分のインスタンス→インバウンド→編集

sshで接続するにはそのポートを開いておかないとだめです。なので、sshの22番ポートを開いておきましょう。


####2. sshで繋ぐ
```ssh -v -i <キーペアのパス> ec2-user@<インスタンスのパブリックIPかパブリックDNS>```

先ほど保存したキーペアデータのパスとECSインスタンスのパブリックIPかパブリックDNSを末尾につけることでsshで入れます.
ユーザーはデフォルトで用意されているec2-userがあるのでそれを使いましょう。
パブリックIPかパブリックDNSはサービス→ECS→クラスター→作ったクラスター→ECSインスタンス(タブ）→自分のインスタンスを選択することで見れます。

これで無事デプロイし、sshで接続までができました！



#まとめ
EC2と違い、いきなりECSをやると混乱することもありそうです。キーペア生成の位置もEC２の方で生成するので....
なのでAWSコンソールになれるのもAWSに強くなるのには必要不可欠かもしれないですね！
レーダーチャートを試してみる (1)

[Chart.js | Open source HTML5 Charts for your website](http://www.chartjs.org/)
から、Chart.min.jsを入手して、あれこれ触ってみる。

[ドキュメント](http://www.chartjs.org/docs/)をきちんと読もう！

---

[レーダーチャート (1) | Chart.js](http://labo.project-nya.jp/chartjs/ver1/)

- チャート上の点にマウスをもっていくと、ツールチップが表示される→ヤダ
- チャート上の点が薄く表示されている→ヤダ

```js
Chart.defaults.global.tooltips.enabled = false;
Chart.defaults.global.elements.point.radius = 0;
```

- チャート上部にある凡例のフォントのサイズと色を変えたい
- 目盛りの最小値・最大値・値の間隔が自動計算されてしまうので、指定したい
- 目盛り線の色を指定したい
- 項目名のフォントのサイズと色を変えたい

```js
var options = {
	legend: {labels: {fontSize: 16, fontColor: "#333333"}}, 
	scale: {
		ticks: {min: 0, max: 5, stepSize: 1, display: false}, 
		angleLines: {color: '#CCCCCC', lineWidth: 1}, gridLines: {color: '#CCCCCC', lineWidth: 1}, 
		pointLabels: {fontSize: 16, fontColor: "#333333"}
	}
};
```
Azure Function WebAPI <-> Eventhub連携

# 概要

システムのIFとしてWeb APIはデファクトスタンダードとなっています。
今回はFunctionという短時間だけCPUリソースを使うものに対して、Azureも推奨している非同期APIを実装していきます。

HTTPの上に構築されるWebは同期的な処理です。
ここでいう同期的とはクライアントがリクエストを送り、サーバがレンスポンスを返すまでがHTTPの一つの処理であることを指します。
非同期APIとは一旦処理待ちキューに情報を追加したタイミングでレスポンスを返します。
処理の結果を気にする場合は別途用意するステータス確認API等で確認を行います。
非同期APIのメリットは時間がかかる処理も時間のかからない処理もクライアントに待ってもらう必要がなく、負担をかけません。
この方式はAzure Functionsにとっても都合が良く、基本的に低スペック・リソース上で稼働するFunctionsに重たい動作は向かず、即座にレスポンスできることに専念させるべきです。
キューにためさえすれば、後の調理方法はどうとでもなります。

それではHTTPとして情報をもらい、Eventhubに格納するまでを実装していきます。

# 実装

## Functionsの作成

まずはFunctionsを作成します。
ここでは言語をjavascriptとして話を進めます。
一番基本の形である、HTTP triggerのエンドポイントを作成します。
作成後、関数名を展開し、「統合」ページに行きます。
今回はHTTPを入り口として、出口としてEventhubに情報を送信したいので、
出力欄にある「新しい出力」をクリックします。
「イベントハブ」が選択できると思いますので、選択し接続情報を入力します。
接続情報は作成してあるEventhubに合わせて適宜入力してください。
ソースコードとして必要な情報はイベントパラメータ名です。
`context.bindings.イベントパラメータ名`としてEventhubにアクセスします。

また、固定の情報をEventhubに入れるのも変化ないので、
今回は初めから追加されている入力の「HTTP（req）」にルートテンプレートを設定して情報を追加します。
簡単に`users/{userId}`としてみます。

HTTPメソッドは作成と削除を想定し、POSTとDELETEを選択しておきます。

## ソースコード

上記設定が完了後、後はソースコードを記述していきます。
例外処理等を考えないソースコードを以下に貼ります。

```js
module.exports = function (context, req) {
    context.log(`req: ${JSON.stringify(req, null, "  ")}`);
    var event = {
        id: req.params.userId, // ルートテンプレートは`req.params`で参照できます
        type: req.method, // 'POST' or 'DELETE'
    };

    // Eventhubへの追加はイベントパラメータ名に対して、情報を代入してあげるだけでよい
    context.bindings.outputEventHubMessage = event;

    // HTTPの後処理も行う
    context.res = {
        body: event
    };
    context.log(`res: ${JSON.stringify(event, null, "  ")}`);
    context.done();
};
```

以上です。
簡単でした。
digdagのsla/fail/error/waitについてのメモ

digdag（正確にはTreasureData Workflow）の `sla` パラメータで若干ハマったのでメモ。

# slaとは

[ドキュメント](https://docs.digdag.io/scheduling_workflow.html?highlight=sla#setting-an-alert-if-a-workflow-doesn-t-finish-within-expected-time) の通りですが、一定の時間を過ぎた場合、あるいは指定の時間を超えた場合にアラートを飛ばすことができます。

こちらもドキュメントに記載してありますが、 `fail:` オプションでworkflowを失敗にすることができます。

```
* sla: parameter supports duration: HH:MM:SS syntax in addition to time: HH:MM:SS syntax.
* sla: parameter supports fail: BOOLEAN and alert: BOOLEAN options. Setting fail: true makes the workflow failed. Setting alert: true sends an notification using above notification mechanism.
```

# 実際にやってみる

僕がハマりポイントがわかりやすいように実際に動かしてみます


以下のようなワークフローを定義します。
内容としては `td_wait_table>` でテーブルを待つだけです。
SLAは10秒に設定していて、`fail: false` としています。
手動でワークフローを実行後、10秒経過してから対象のテーブルを作成しました。

```yaml:sample.dig
sla:
  duration: 00:00:10
  fail: false
  alert: false
  +notice:
    echo>: sla alert!!

+wait:
  td_wait_table>: tdwf_wait

_error:
  echo>: error!!
```

実行結果

![wf1.png](https://qiita-image-store.s3.amazonaws.com/0/48307/1067b1ef-f803-f54f-ceec-6907f327269c.png)

10秒以上経過したため、 `+notice` で定義した内容が実行されてます。
SLAは超過していますが、テーブルが作成されたので正常に終了しています。

------

次に、`fail: true`にして同じように実行してみます。

## 実行結果

![wf2.png](https://qiita-image-store.s3.amazonaws.com/0/48307/26de14ae-eca5-2fd6-fd4d-c95ba0593771.png)

同じく、10秒以上経過したため、 `+notice` で定義した内容が実行されています。
SLAは超過していますが、その後もタスクは実行され続け、テーブルを作成した時点でtd_wait_tableが正常終了で終わりますが、このタスク自体のステータスは失敗となります。
そのため、 `_error`で定義した内容も実行されているのがわかります。

個人的に勘違いしていた点として、 **`fail: true` にするとSLAを超えた時点で終了すると思っていましたが、そうではありません。**

-----

次にテーブルを作成せずに、途中でキャンセル（kill）してみます。
**キャンセルはtd_wait_tableやs3_waitで24時間以上待っても存在しない場合に発生してしまいます**

## 実行結果

![wf3.png](https://qiita-image-store.s3.amazonaws.com/0/48307/0b92429f-be5c-d0de-85c1-a890c90dbc83.png)

タスクのステータス自体はキャンセルしているので、失敗となります。
ここで注目してほしいのでは **`_error`で定義した内容が実行されない** ということです。

指定したSLAを超えた場合は`+notice`で定義した内容を実行できますが、waitのタスクで24時間を超えても対象が存在しない場合は要注意です。

# まとめ

* `fail: true`としてもタスクが中断されるわけではない
* waitのタスクで24時間超えた場合はキャンセルとなり、error処理が実行できない

`fail: true`のユースケースってあるんだろうか。。

# 備考

* TD workflow 0.9.13で実行
CentOS7.3 環境(Vagrant)に Mattermost いれたので bot から Mattermost にタイムラインしてみる（Incoming WebHooks）　その２

# あ、これがやりたかった
bot から Mattermost にタイムライン送ってみる方法、これやりたかった。
意外と簡単にできてびっくり。

> [SlackクローンのMattermostを使ってみる - 外部連携編 -（WebHooks、Hubot）](http://qiita.com/terukizm/items/4524249dd7f1298fdc06)

# 設定これだけ？
超かんたんｗ

## botの定義（内向きウェブフック）
内向きウェブフックを選択して。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/44540/5ab96281-0f8f-23ad-9f46-72861bd2aa79.png)

編集で対象のチャネルを選択して保存。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/44540/56e89d8c-f567-6c9c-5c82-7b1e0c4bc723.png)

URLが払い出されるのでそれをメモして
![image.png](https://qiita-image-store.s3.amazonaws.com/0/44540/9fff105a-ba8c-5314-ae52-af8e8417f863.png)

## とりあえずの動作確認
curl で叩いてみる。

```bash:
curl -i -X POST -d 'payload={"icon_url": "/static/emoji/1f697.png", "username": "echo", "text": "今日は\nいい天気"}' http://192.168.1.128:19191/hooks/3p9ko4zkoifk8gtkyztcaqhm4a
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/44540/20a7a00e-c371-fb18-99be-db47b7c7ddc0.png)

きたー！！！

パラメータも対した事ないし、色々とできそうな感じ。
https://docs.mattermost.com/developer/webhooks-outgoing.html#slack-compatibility
TypeScriptでaliasなパスでmoduleをimportできるように

前回、WebpackとFlowのaliasなパスで読み込むのを書いた（[webpack.resolve.aliasを設定しているプロジェクトでの.flowconfig設定](http://qiita.com/nju33/items/720e5cca222c8ab3dd4f)）けど、そのTypeScript版。

## 設定

例えば、設定前は、`../../components/button`としていたのを`components/button`としたい時、`tsconfig.json`の`baseUrl`と`rootDirs`をこんな感じで設定します。

```json:tsconfig.json
{
  "compilerOptions": {
    "baseUrl": "./",
    "paths": {
      "components/*": ["src/scripts/components/*"],
      "components": ["src/scripts/components"],
    }
  }
}
```

`/*`と書くことでマッチしたパスをそのまま後ろに付けて読み込んでくれるようになります。つまり、`components/button`は`./src/components/button`となってファイルを読み込みます。
また上記の`components`の方ですが、これがあると`./src/components/index.ts`なファイルを`components`でインポートできるようになります。

ちなみに面倒くさかったらこれで両方いけます。

```js
"components*": ["src/scripts/components*"]
```

## Webpack+[awesome-typescript-loader](https://github.com/s-panferov/awesome-typescript-loader)と一緒に

[Readme](https://github.com/s-panferov/awesome-typescript-loader#advanced-path-resolution-in-typescript-20)を見ると、`{TsConfigPathsPlugin}`を使えば解決してくれそうですが、[解決してくれません](https://github.com/s-panferov/awesome-typescript-loader/issues/402#issue-217093028)でした。

[ビルド時間増えた](https://github.com/s-panferov/awesome-typescript-loader/issues/464#issue-242302270)みたいなイシューもあったので、ひとまず`Webpack.resolve.alias`に同じようなエイリアスを設定して回避することにしました。

```js:webpack.config.js
{
  // ...
  resolve: {
    alias: {
      components: path.resolve(__dirname, '../src/components')
    }
  }
  // ...
}
```

😇
neo4jの導入メモ


## はじめに

言語学の研究のためにWordNetやSUMOのようなオントロジーデータベースを使いたいが、主に使いたいのはクラス階層とかなのでグラフ型データベースが便利かなあと思って試してみたメモ。

## インストール

neo4j本体のインストール

	brew install neo4j

ruby用のインターフェイス

	sudo gem install neography

## neo4jの起動

サーバーを起動する

	$ neo4j start

ブラウザを起動し、以下のアドレスを入力

	http://localhost:7474/

ユーザーインターフェイス的なものが表示される。ユーザー名とパスワードを聞いてくるが、初期設定はどちらも neo4j らしい。それを入力すると新しいパスワードの入力を求められるので適当に入れる。

## rubyから操作してみる

とりあえず irb から試す。

	require 'neography'

ユーザー名とパスワードを指定して接続。

	Neography.configure{|conf| conf.username = 'neo4j'; password = 'password'}
	@neo = Neography::Rest.new

ノードとリレーションを登録。

	node1 = Neography::Node.create(name: "Cat")
	node2 = Neography::Node.create(name: "Animal")
	node2.outgoing(:subclass) << node1

これだけだとブラウザで表示するときノードに文字が表示されないので、ラベルをつける。

	node1.set_label = "Cat"
	node2.set_label = "Animal"

追記: label は Cat のような識別名ではなく、Class とか Instance みたいな分類ラベル的なものを割り当てるものっぽい。ブラウザでもちゃんとname属性の方が表示される模様。

ブラウザで確認する。とりあえず左メニューの一番上にあるデータベースアイコンをクリックし、Node Labelのところの*をクリックすれば全てのノードが(LIMIT 25で)表示されるっぽい。

![Kobito.qWslta.png](https://qiita-image-store.s3.amazonaws.com/0/109010/bc6b74d8-84d4-ab89-9c30-ae0143134d0b.png "Kobito.qWslta.png")

## データベースの初期化

全てのノードとリレーションを削除するには、ブラウザのコンソールに次のように入力する。

	MATCH (n) DETACH DELETE n

とりあえずここまで。
Vue.js Devtoolsの導入方法と機能まとめ。Vue.jsを用いた開発を効率化させよう！

最近、JavaScriptフレームワークであるVue.jsの勉強をしているのですが、jQueryを用いて開発を進めるときと比べるとデバックに時間がかかってしまいます。

何か良い解決策を探してみると「**Vue.js Devtools**」というchromeブラウザの拡張機能の存在を知りました。

早速導入してみると、 **作業がとても捗った** ので、導入方法や使い方を簡単にまとめたいと思います。

## Vue.js Devtoolsとは

Vue.js Devtoolsは、Vue.jsの開発をサポートする **Chromeブラウザの拡張機能** です。これを導入するとconsoleを開かなくてもdataの中身などを確認することができるようになります。

## Vue.js Devtoolsの導入方法について
それではさっそくVue.js devtoolの導入方法について。まずは下記URLにアクセスして拡張機能を追加します。
[Vue.js Devtools/Chrome ウェブストア](https://chrome.google.com/webstore/detail/vuejs-Devtools/nhdogjmejiglipccpnnnanhbledajbpd)

![2017-08-01_131142.png](https://qiita-image-store.s3.amazonaws.com/0/146968/13950de0-67d6-fb4a-4d95-09b67a0205c4.png)

拡張機能を追加したら、拡張機能の設定画面を開き、「ファイルのURLへのアクセスを許可する」にチェックを入れます。

これをチェック入れていないと**ローカル環境で開発を進めている時にVue.js Devtoolsが使えないので必ずチェック**しましょう。

![2017-08-01_130228.png](https://qiita-image-store.s3.amazonaws.com/0/146968/ca6e425d-6250-cee3-c4ea-b99e9e4ec87d.png)

これで、Vue.jsを読み込んでいるファイルをブラウザ上で開くと、Vue.js Devtoolsのアイコンがアクティブになります。ここまできたら導入完了！

![2017-08-01_130630.png](https://qiita-image-store.s3.amazonaws.com/0/146968/5cac4017-d361-83b9-53b5-8aa25700a852.png)

デベロッパーツールを開くと、vueというタブが追加されていますね！
![2017-08-01_130411.png](https://qiita-image-store.s3.amazonaws.com/0/146968/d37aabf6-4c0b-8e26-6532-2bfac1694526.png)

## Vue.js Devtoolsの機能について
ここからは簡単にVue.js Devtoolsの機能を紹介。このツールを用いて確認できる内容は下記3つ。

- Components
- Vuex
- Events

**Componentsタブ**では、各コンポーネントの親子関係や保持しているdataの内容などを確認することが可能になります。

次に**Vuexタブ**。このタブではVuexを使っている場合、storeの中の状態を確認することが可能になります。

最後に**Eventsタブ**。このタブをみるとイベントがトリガーされた履歴を確認することが可能になります。

## まとめ
簡単に **Vue.js Devtools** の導入方法や機能についてまとめてみました。

実際に使ってみるとconsoleを記述してdataの中身を確認する手間が省けると、デバックがとても快適になると思います。

Vue.jsを開発に用いているけど、まだ使ったことがない方はぜひ利用してみて下さい！
CentOS7　インストール後の初期設定を行う

# はじめに
CentOS7 の minimal インストール直後に以下を実施します。

- 全パッケージのアップデート
- 自動アップデートの設定
- SELinux を無効化
- 時刻同期（chronyd）の設定


# 設定手順

## 全パッケージのアップデート

概要
　・インストール直後はパッケージが古いので最新版をインストールする

アップデート

~~~
yum -y update
~~~

## 自動アップデートの設定
概要
　・最新のパッケージに保つため自動アップデートを設定する

インストール

~~~
yum -y install yum-cron
~~~

設定変更
　・apply_updates を yes に変更

~~~
cp -p /etc/yum/yum-cron.conf /etc/yum/yum-cron.conf.org
vi /etc/yum/yum-cron.conf
~~~
~~~Ini:/etc/yum/yum-cron.conf
# Whether updates should be applied when they are available.  Note
# that download_updates must also be yes for the update to be applied.
apply_updates = yes
~~~

起動設定

~~~
systemctl start yum-cron
systemctl enable yum-cron
~~~

## SELinux を無効化

概要
　・セキュリティ的には有効のほうが良いが、不都合が多いため無効にする

一時的に無効化

~~~
setenforce 0
~~~

設定変更
　・SELINUX を disabled に変更

~~~
cp -p /etc/selinux/config /etc/selinux/config.org
vi /etc/selinux/config
~~~
~~~Ini:/etc/selinux/config
# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
#     enforcing - SELinux security policy is enforced.
#     permissive - SELinux prints warnings instead of enforcing.
#     disabled - No SELinux policy is loaded.
SELINUX=disabled
~~~

サーバ再起動

~~~
reboot
~~~

動作確認

~~~
getenforce
~~~
~~~text:実行結果
Disabled
~~~
※「Disabled」が表示されれば無効化されています。

## 時刻同期（chronyd）の設定

概要
　CentOS7 から chrony が標準になったようです
<br/>

- インストール

~~~
yum -y install chrony
~~~

設定変更
　・既存の server 項目をコメントアウト
　・ntp.nict.jp を使うように追加

~~~
cp -p /etc/chrony.conf /etc/chrony.conf.org
vi /etc/chrony.conf
~~~
~~~Ini:/etc/chrony.conf
# Use public servers from the pool.ntp.org project.
# Please consider joining the pool (http://www.pool.ntp.org/join.html).
#server 0.centos.pool.ntp.org iburst
#server 1.centos.pool.ntp.org iburst
#server 2.centos.pool.ntp.org iburst
#server 3.centos.pool.ntp.org iburst
server ntp.nict.jp iburst
~~~

起動設定

~~~
systemctl start chronyd
systemctl enable chronyd
~~~

動作確認

~~~
chronyc sources
~~~

~~~Text:実行結果
210 Number of sources = 1
MS Name/IP address         Stratum Poll Reach LastRx Last sample
===============================================================================
^* ntp-b3.nict.go.jp             1  10   377   644  +7955ns[  -13us] +/- 1000us
~~~
サーバ名の横に「*」か「+」が表示されれば、時刻同期が行われています。

# 次回予定
セキュリティ対策を予定
CentOS7.3 環境(Vagrant)に Mattermost いれたので php で bot を追加してみる（Outgoing WebHooks）　その１

# bot
Mattermost いれたので Hubot でも入れて遊んでみようと思ってみつつも、Hubotの設定とcoffie script 覚えるのが少し敷居が高かったので、とりあえず bot だけサクっと動作させみた。かついいお手本サイトさんがあったので参考にさせて頂きました。

# 結果的に「超簡単」ではあるんだけどね
やり方が判れば、みな「簡単だよー」って言うと思うけど、botのアイコン変わらなかったり名前が変更されなく１５分位悩みました。その他は、まあ割と手順とおりにやればいい。

# 統合機能の事前準備
まず「システムコンソール-統合機能-カスタム統合機能」を選択する。※日本語化してます
そこで下記の機能を有効に設定します。

```text:
・統合機能によるユーザー名の上書きを許可する:
・統合機能によるプロフィール画像アイコンの上書きを許可する
・統合機能の管理を管理者のみに制限する
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/44540/d1c8c12d-de82-46db-0272-601a3e4c68c5.png)

# 超簡単botを設置してみる

> [超簡単！MattermostにBOTを追加する](https://vivibit.net/mattermost_bot/)

上記を参考にしつつ進めていきます。「echo ほげ」入力すると bot から「2017/08/01 13:21:23 ほげ」って返信される機能を作ってみます。

## コールバックURL
入力された文字列を処理するための、いわゆるAPIを実装します。どこに設置してもいいですが、Mattermost は 80 ポート使っているので、Apache(8080)+php とか別ポートでAPIを動かしていればいいです。

```php:echo.php
<?php
if ($_POST['token'] != "bsfwydtxc3rgznwki35gw6s5to") { return; }
 
$text   = $_POST['text'];
$query  = preg_split('/[\s\x{3000}]/u', $text, 2);
 
echo json_encode(array("icon_url" => "/static/emoji/1f697.png", "username" => "echo", "text" => date("Y/m/d H:i:s") . " " . $query[1]));
return;
```

ここで重要なのは ```$_POST['token'] !=```の定義でトークンを判定していること。トリガーで起動されるがトークンと一致してないと処理しない判定です。定義いるのかな？


## botの定義（外向きウェブフック）
外向きウェブフックを選択して。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/44540/20c6d7a6-5ae9-7f3c-4c43-8dfc0ce5e495.png)

定義した最終結果だけだけど、ここで必要な定義は２つ。
まず「トリガーワード」は、bot が起動する条件。
あと「コールバックURL」、こちらは実際に動かすbot。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/44540/c888d191-6b8e-cd56-5f5f-cbea5fc00cc1.png)

定義をするとトークンが払い出されるのでメモするなりします。
そしてbotプログラムに反映すること。

## 動作確認してみる
「echo あああ」って入力してみる。きたーーー！！！
本当だ、超簡単だったｗｗ

![image.png](https://qiita-image-store.s3.amazonaws.com/0/44540/d5762919-75fa-25bc-c5a0-d14447620257.png)

## phpなら
phpなら簡単にDBアクセスすることできたり、スクレイピングしたりとか色々できるから便利機能をちょちょいって作れるのがいいかもね。

# 参考にさせて頂きましたサイト様
> [超簡単！MattermostにBOTを追加する](https://vivibit.net/mattermost_bot/)
> [SlackクローンのMattermostを使ってみる - 外部連携編 -（WebHooks、Hubot）](http://qiita.com/terukizm/items/4524249dd7f1298fdc06)
「値」と「参照」と「式」

[「値」と「参照」](http://qiita.com/roark/items/3eb820e63e9c810902e4)の続きです。
変数に格納される要素として**値**と**参照**以外に**式**が入るパターンもあるな、と思ったので書きました。

# 値に式が入ることもある

さらにややこしいことに、箱の中身には何かしらの「作業命令」が入っているパターンもあります。

<img width="587" alt="report__29__csv_-_OpenOffice_Calc.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/157051/e8a92b0f-fc29-7495-be09-1e93a604093a.jpeg">

上記の状態の時、「E2」の値は（文字列として解釈するなら）「C2+D2」ですが
その「C2+D2」を値でななく式として解釈すると
『「C2」の値と「D2」の値を足せ』という命令になり、結果として「23」という値を抽出することができます。
この時、「E2」の値は**式**となります。

# 上記をC++で表現

*※要c++11コンパイル*

```c++
#include <iostream>
#include <string>
using namespace std;

int c2 = 10;
int d2 = 13;
auto e2 = []{
  return c2 + d2;
};

int main()
{
  cout << to_string(e2()) << endl;
  return 0;
}
```

変数e2は値ではなく、処理自体を代入しています。
そして、e2呼び出し時に中の処理を実行し、出力内容は計算結果である「23」となります。
(Unity) インスペクタでpublicを使わずインスペクタで編集できるようにする方法

<h1>SerializeFieldでそれが可能</h1>
SerializeFieldとは、"privateフィールドを強制的にシリアライズする"ものです。
要するに、インスペクタから変数の値を変更したかったらpublicをつければいいが、[SerializeField]をつければ、privateやprotectedな変数でもインスペクタから値を変更できるようになる。

```c#:I_am_hentai.cs
    [SerializeField]
    private Vector3 initializeAngle;
```

privateつけた変数だけど、、、

<img width="410" alt="スクリーンショット 2017-08-01 13.07.38.png" src="https://qiita-image-store.s3.amazonaws.com/0/179803/e6b0e122-8e15-11c8-9b99-91a3c81a7b82.png">

private変数でもインスペクタから値を変更できるようになりました。
プレファブとかをドラッグ&ドロップするためになんでもpublicしなければいけないわけで
これは便利。これでpublicつけるデメリットが！！
Angular-cliを用いたプロジェクトの作成の仕方

#Angularのversion

```typescript:angularのversion
@angular/cli: 1.1.2
node: 6.10.2
os: win32 x64
@angular/animations: 4.3.2
@angular/common: 4.3.2
@angular/compiler: 4.3.2
@angular/core: 4.3.2
@angular/forms: 4.3.2
@angular/http: 4.3.2
@angular/platform-browser: 4.3.2
@angular/platform-browser-dynamic: 4.3.2
@angular/router: 4.3.2
@angular/cli: 1.1.2
@angular/compiler-cli: 4.3.2
@angular/language-service: 4.3.2

```

#プロジェクトの作成
今回は複数のモジュールとlessを用いるプロジェクトを作成する。

```
ng new my-project-name --routing --style less
```

--routingは複数のモジュールを作成できるようにするオプション。
--style lessはスタイルにlessを用いるように設定するオプション。

#プロジェクトの設定

```json:.angular-cli.json
 "outDir": "../static/"
```

outDirを変えることでbuildした際の出力先を変えることができる。

```json:.angular-cli.json
"defaults": {
  "styleExt": "less",
  "class": {
    "spec": false
  },
  "component": {
    "spec": false
  },
  "service": {
    "spec": false
  }
}
```

defaultsの対象の下に"spec": falseを追加することで対象を生成する際にspecファイルが生成されなくなる。
今回はspecファイルは必要ないのでclass, component, serviceを生成する際にspecファイルが生成されないようにする。

#あとがき
間違い、こうしたほうがいいなどのコメントお願いします
GNU make変数の伝播についてまとめ

# 知りたかったこと

makeを実行するときの変数の指定の仕方は

```
HOGE=env make
```

と

```
make HOGE=arg
```

がある。前者はシェルによって解釈され、後者はmake自身が解釈するのだが、実行にどう違いが出るのか？

Makefile内で変数の書き方は

```
# exportしない
HOGE=noexp
```

と

```
export HOGE=exp
```

がある。どう違うのか？

サブディレクトリ内でmakeする書き方は

```
$(MAKE) -C sub
```

と

```
$(MAKE) -e -C sub
```

がある。どう違うのか？

実際には

```
cd subdir && $(MAKE)
```

という書き方もあるが、これは`$(MAKE) -C subdir`と同じである。

これらの違いを知りたかったので、実験してみた。

# 実験結果

## 変数定義の優先順位

環境変数＜ファイル内に書いた値＜makeの引数
となる。つまり、

```Makefile
HOGE=file

all:
	echo $(HOGE)
```

と書いて

```
HOGE=env make HOGE=arg
```

で実行した場合、結果は`arg`が表示される。


```
HOGE=env make
```

で実行した場合、`file`が表示される。

Makefile内の`HOGE=file`を消して

```
HOGE=env make
```

で実行した場合、`env`が表示される。

## 親makeから子makeへの変数の伝播の仕方

- 親から子へ伝わるかどうか
- 子で定義されている変数を上書きするかどうか

を表にするとこうなる：

| |-eなし|-eあり|
|---|---|---|
|make HOGE=arg|伝わる。上書きする|伝わる。上書きする|
|HOGE=env make|伝わる。上書きしない|伝わる。上書きする|
|export HOGE=file1|伝わる。上書きしない|伝わる。上書きする|
|HOGE=file1|伝わらない。上書きしない|伝わらない。上書きしない|

# まとめ

- 変数の優先順位は、環境変数＜ファイル内に書いた値＜makeの引数
- exportした場合は環境変数と同じ扱いになる。したがって子に伝播する
- exportしない場合はシェルにおけるシェル変数と同じく、自プロセス内でのみ有効（子に伝播しない）
- 基本的に親ファイルに書いた変数は子ファイルに書いた変数を上書きしないが、`-e`をつけると上書きするようになる
- コマンドラインの引数で指定した場合（`make HOGE=arg`）は常に子ファイルの変数を上書きする
陸上短距離走用 自動タイム測定器を作ろう(1)

# 自動タイム測定器とは
自動でタイムを正確に測定する装置です。正確といっても、ビデオのコマ送りから算出されたタイムよりは正確ではないですが、少なくとも手動測定よりは正確、かつ平等になると思います。
筆者の息子は陸上クラブで短距離走を嗜んでいますが、タイムの測定は、計る人や計り方により大きくずれが生じる印象を持ちました。ということで、そこら辺で手に入る機材やスマホを利用して、自動タイム測定器を作ってみようと思った次第であります。

# 仕組み
自動タイム測定器には、2つの装置が必要になります。それぞれの役割は以下の通りです。

- ゴール判定装置
Raspberry Pi 3 に測距センサーを取り付けた装置で、ゴールラインに向けて配置します。測距した距離の値が大きく変化するとランナーが通過 (ゴール) したと判定します。ゴール後に、測定タイムをコントローラーへ送ります。

- コントローラー
「よーいドン」をするスターターが持つ Android アプリです。スタートボタンをタップすると、ゴール判定装置にスタート命令を送り、ゴール判定装置のストップウォッチをスタートします。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/153436/5cf796b5-dbe4-c0a2-9c43-9a9a79c714aa.png)


## 通信方法
この測定器の仕組みでは、コントローラーからゴール判定装置に対して、"スタート命令" をネットワーク経由で送信します。短距離走はミリ秒を競う競技であり、レイテンシーが殆どないことが望ましいので、プライベートネットワークの使用を考えていました。
しかしながら、モバイルバッテリーでも動作する省電力の Wi-Fi ルーターだと 100m の距離はまず届かない (天候条件により届く場合もあるかもしれませんが) ので、装置間通信はインターネットを経由させることにします。
こうなるとレイテンシーが大きくなることが予想されますが、現段階ではこれといった対応策は考えていません:dizzy_face: 実装していく過程で考えていこうと思います。

# 実装について
- ゴール判定装置
Raspberry Pi 3 の OS には [Windows 10 IoT Core](https://developer.microsoft.com/ja-jp/windows/iot) を使用します。
この中で動作するゴール判定のアプリは、[.Net Core](https://www.microsoft.com/net/core#windowsvs2017) (C#) で開発します。

- コントローラー
Android (6.0 Marshmallow 以降) のスマホで、アプリは [Xamarin.Android](https://developer.xamarin.com/guides/android/) (C#) で開発します。


## とりあえず用意するもの
- Android スマホ 
- Raspberry Pi 3
- microSD カード 8GB 以上 (OS インストール用)
- 開発用の PC (Windows 10 + Visual Studio 2017)

とりあえずこれだけです。他にも電子回路のパーツが必要になりますが、回路設計の記事の時に詳しく説明します。


# まとめ
今回は作りたいものの概要を説明しただけで、これと言って技術的な内容ではありませんでしたが、次回は、Raspberry Pi 3 に Windows 10 IoT Core をインストールし、作業 PC から動作確認できるようにします。

なお このシリーズは、現時点で完成品が存在せず、実際に開発しながらの不定期連載となります。なので、記事数も未定であり、そもそもモノが無事に完成するかもわかりませんが、これをご理解の上 読んでいただけるとありがたいです:bow_tone1:
ファイルシステムと大文字小文字

ファイル名の大文字小文字について、ファイルシステムの扱いがおおよそ3パタンあります:

### 1. 違いが認識･保存されるが、厳格ではない (case preserved && case insensitive)

例: NTFS, HFS (デフォルト), APFS (デフォルト)

- ファイル名 `a` で保存すると、 `a` として保存される
- ファイル `a` と `A` が同時に存在できない
- ファイル名 `a` で、ファイル `A` をアクセスできる

### 2. 違いが認識･保存される、かつ厳格 (case preserved && case sensitive)

例: HFS (オプショナル), APFS (オプショナル), ext, XFS, btrfs, zfs (デフォルト) // (Linuxのほぼ全部ファイルシステム)

- ファイル名 `a` で保存すると、 `a` として保存される。
- ファイル `a` と `A` が同時に存在できる
- ファイル名 `a` で、ファイル `A` をアクセスできない

### 3. 違いが認識･保存されない (case not preserved)

例: FAT

- ファイル名 `a` で保存すると、大文字化され `A` として保存される
- ファイルシステム上 `a` があり得ないため、"同時に存在する"問題自体がない
- ↑の同原因で、ファイル名 `a` で、ファイル `A` をアクセスできる
.netのビルドでv3.5のビルドが失敗する

#エラーの一例

```
error MSB3644: The reference assemblies for framework ".NETFramework,Version=v3.5" were not found. To resolve this, install the SDK or Targeting Pack for this framework version or retarget
```

#解決法

- dotnet コマンドではなくmsbuildを使う
- csprojectを変更する

##dotnet コマンドではなくmsbuildを使う

```dotnet build -c Release```
ではなく
```dotnet msbuild /p:Configuration=Release```
または
```msbuild /p:Configuration=Release```
を使用する

または
``` msbuild /p:Configuration=Release /p:TargetFramework=net35```

##csprojectを変更する

```
<PropertyGroup>
  <FrameworkPathOverride Condition="'$(TargetFramework)' == 'net35'">C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v3.5\Profile\Client</FrameworkPathOverride>
  <TargetFramework>net35</TargetFramework>
</PropertyGroup>
```

*FrameworkPathOverrideでパスをOverRideするのがミソ*
【AWS】AWS CLIでインスタンスの情報を抽出（InstanceID, VolumeID, SnapshotID）

#はじめに
EC2インスタンスのスナップショットをスクリプトで取得しようとした際、下記情報をコマンドで取得する必要がありました。備忘録です。
※sedコマンドとかしていますが、ダブルクォーテーションを削除するためです。

①自分自身のインスタンスID
②自分自身のボリュームID
③自分自身のボリュームから取得したスナップショットID一覧
④自分自身のTAG（Name）


#前提

- AWS CLIがインストールされていること。
- ```aws configure```コマンド実行済み。
- EC2FullAccessの権限を持った、IAMユーザーのアクセスキーとシークレットキーを取得済み。


#①自分自身のインスタンスID取得
169.254.169.254にインスタンスのメタデータがあるらしいです。

```
curl 'http://169.254.169.254/latest/meta-data/instance-id'; echo -en "\n"
```


#②自分自身のボリュームID取得
- ${AWS_REGION}: リージョンを記載する。（例：ap-northeast-1）
- ${INSTANCE_ID}: ①で取得したインスタンスIDを記載する。

```
aws ec2 describe-instances --region ${AWS_REGION} --instance-id ${INSTANCE_ID} --query 'Reservations[].Instances[].BlockDeviceMappings[].Ebs[]' | grep vol | sed 's/^.*"\(.*\)".*$/\1/'
```


#③自分自身のボリュームから取得したスナップショットID一覧取得
- ${EBS_VOLUME_ID}: ②で取得したボリュームID

```
aws ec2 describe-snapshots --filters Name=volume-id,Values=${EBS_VOLUME_ID} | grep snap- | sed 's/^.*"\(.*\)".*$/\1/'
```


#④自分自身のTAG（Name）
- ${AWS_REGION}: リージョンを記載する。（例：ap-northeast-1）
- ${INSTANCE_ID}: ①で取得したインスタンスIDを記載する。

```
aws ec2 describe-instances --region ${AWS_REGION} --instance-id ${INSTANCE_ID} --query 'Reservations[].Instances[].Tags[].Value[]' | grep [0-9a-zA-Z] | sed 's/^.*"\(.*\)".*$/\1/'
```
GitHubにJavaファイルを登録するまでの手順

初心者故にたまにど忘れするので備忘録。

#1. ローカルリポジトリを作成
Terminalを開き、登録したいJavaファイルが入っているディレクトリまでcdし、以下のコマンドを叩く。
```$ git init```

#2. .gitignoreを生成
.gitignoreとは、登録したくないファイルの種類（Javaならclassファイルとか）を指定するために書くもの。指定したファイルを、その名の通りignore（無視）してくれる。
作り方はいくつかあるが、自分はgiboを使用する。
giboは自動で.gitignoreファイルを生成してくれる優れもの。
以下のコマンドを打ち込む。
```gibo java >> .gitignore```

ローカルでの作業は一旦ここまで。

#3. リモートリポジトリをつくる
GitHubにアクセスし、新しくリポジトリを作成する。
その際.gitignoreを自動生成するオプションが選択できるが、既に作ってあるので選択しない。
リポジトリが作成できたらHTTPSのURLが発行されるので、それをコピーしておく。

#4. リモートリポジトリをローカルリポジトリに紐付ける。
以下のコマンドを打ち込む：
```$ git remote add origin URL```
URLの部分に、先程コピーしたリモートのHTTPSのURLを貼り付ける。

#5. add, commit & push!
```
$ git add .
$ git commit -m "remote upload"
$ git push -u origin master
```
###以上！
現在時刻からx日後のy時までの差分を取る。

たまに使うのでメモ。
サンプルは翌日の9時00分まで。

## デモ
https://codepen.io/negibouze/pen/PKNRpE?editors=0010

##1. Dateでやる場合

```js
const now = new Date();
const expire = new Date(now.getFullYear(), now.getMonth(), now.getDate() + 1, 9, 0, 0);
const diff = expire - now
```

##2. Moment.jsを使う場合

```js
const now = moment();
const expire = moment().add(1, 'd').set({ h: 9, m: 0, s: 0, ms: 0 });
const diff = expire.diff(now)
```
TortoiseGit メモ

TortoiseGitで行うGit操作メモ。

![TortoiseGit_logo.svg.png](https://qiita-image-store.s3.amazonaws.com/0/142172/59e7e96e-55bd-a6d6-1aea-210e4d00130d.png)

# Gitクローン作製
・プロジェクトの歴史をすべて取ってくる
・複製するものはプロジェクト全体

１．ブラウザでGitHubなどを開く
２．取り込みたいプロジェクトのHTTPSのタブを選択して、URLをコピーする
３．Gitクローンを作りたいディレクトリで右クリック  ⇒  Git Cloneを選択
　　※ディレクトリは任意
４．コピーしたURLを貼り付け ⇒ OK
　　※失敗した場合はHTTPにして再挑戦
５．ユーザーとパスワードを入れてダウンロード完了を待つ

# ブランチをチェックアウト
１．フォルダの中を選択 ⇒ 右クリック ⇒ TortoiseGit ⇒ Switch/Checkout
２．取ってきたいブランチを選択 ⇒ OK

# ブランチを作成
１．ブランチを選択 ⇒ 右クリック ⇒ TortoiseGit ⇒ Create Branch
２．ブランチ名を入力、Branchは元にしたいブランチを選択 ⇒ OK

# コミット
・修正したファイルをローカルワークブランチにコミット
・コミットしておけばブランチを切り替えても修正分がなくなったりしない

１．コミットしたいプロジェクトを選択 ⇒ 右クリック ⇒ Git Commit...
２．コミットコメント入力
３．コミットしたいファイルだけを選択
　　⇒ ファイルはダブルクリックしたら差分が見える
４．OK ⇒ Close


# マージ(変更分を今使ってるブランチに取り込む)
・マージはローカルブランチのファイルをコミットしてから行う
・ローカル間の差分の解消に使う

１．プロジェクトを ⇒ 右クリック ⇒ TortoiseGit ⇒ Merge
２．Branchはプルダウンから取り込みたいプロジェクトを選択
３．OK ⇒ Close

# ブランチの切り替え
１．プロジェクトを ⇒ 右クリック ⇒ TortoiseGit ⇒ Switch/Checkout
２．Branchはプルダウンから変更したいプロジェクトを選択
３．Create New Branchのチェックを外す
４．OK ⇒ Close

# Pull
・リモートにあるブランチの内容をローカルのブランチに取り込む
・コミット済みのブランチであること
１．プロジェクトを ⇒ 右クリック ⇒ TortoiseGit ⇒ Pull
２．下記の内容に合わせる

```
 Remote：originとかmasterとか
 Remote Branch：feature/TorikomitaiBranchMei
```

３．OK ⇒ Close


# Push
・エクスプローラでブランチに赤丸がついているとPushできない
・ローカルのワークブランチをリモートにPushする

１．Pushしたいプロジェクトを ⇒ 右クリック ⇒ TortoiseGit ⇒ Push
２．Remoteに名前を入力
　　リモートに存在する名前を入力すると、そのリモートのブランチに対してPushされる
　　存在しない名前にすると新規のブランチとしてPushできる
３．OK ⇒ Close


# 間違えてコミットしてしまった場合
・新しいブランチを作らずに修正してコミットまでしてしまった場合
・Pushではなくコミットまで
・コミットを戻した場合、修正したファイルは消えてしまうので注意

１．エクスプローラーを開く
２．戻したいプロジェクト(フォルダ)を右クリック ⇒ ログを表示
３．戻したい時点の履歴を右クリック ⇒ リセット ⇒ HARD
４．OK


# リモートのブランチに知らない間にpushされていて、ローカルの変更がpushできない
・修正中の機能をコミットしてpushしようとしたら、最新じゃないという理由で失敗した
・手元にあるブランチは最新なのにpushに失敗する

１．修正したファイルをローカルに退避する
２．ローカルのブランチを削除
３．ブランチをチェックアウトする
４．最新の内容をマージ
５．退避したファイルを入れ直す
６．pushの手順を行う

# 変更を一時退避したい
・ある機能を修正している間に別の機能を修正しなければいけなくなった
・コミットはしたくないけど、修正したファイルを全部ローカルにコピーするのは大変
・スタッシュを使うと一時退避できる

１．退避したいプロジェクトを右クリック ⇒ TortoiseGit ⇒ スタッシュへ変更を隠す
２．スタッシュメッセージに機能名やわかりやすい文言を入れておく
３．バージョン管理外のファイルを含むにチェック
４．続行 ⇒ OK

# 退避した変更を元に戻したい
・スタッシュした退避ファイルを元のブランチに戻したい
・スタッシュは複数回できるが、最後のスタッシュから順に戻していく
・スタッシュを複数回やった場合は戻す順番に注意すること

１．スタッシュした時のブランチに切り替える
２．プロジェクトを右クリック ⇒ TortoiseGit ⇒ スタッシュへ隠した変更を戻す
３．Yes

# マージもファイルの戻しもできない
・ファイルで差分が出たり、ファイルが消えたりしておかしくなった
・eclipseの置換やエクスプローラから変更の破棄などをしても失敗して元に戻せない

```html:エラー内容
fatal: Unable to create 'C:/path/to/.git/index.lock': File exists.
If no other git process is currently running, this probably means a
git process crashed in this repository earlier. Make sure no other git
process is running and remove the file manually to continue.
```

１．git/index.lock と .git/COMMIT_EDITMSG のファイルを削除
LDR終了前に移行したいRSSフィードリーダー「InoReader」


[RSSリーダー“livedoor Reader”の血脈が絶える ～“Live Dwango Reader”が終了へ](http://forest.watch.impress.co.jp/docs/news/1072231.html)

LiveDoorReaderの後継“Live Dwango Reader”が8月31日で終了するのを受けて、移行先を探してたところ、LDRの体験を再現できるサービスがブログで紹介されていたので、簡単にご紹介。

[InoreaderでLDRの購読体験を再現する方法](https://www.akiyan.com/blog/archives/2017/07/how-to-reproduce-ldr-subscription-experience-almost-in-inoreader.html)


# InoReaderは日本用のミラーサイトが存在する。

![inoreader.png](https://qiita-image-store.s3.amazonaws.com/0/2567/1055e9ec-cc49-a028-b2fd-15b32d07aa60.png)

設定で日本語に変更できる。
![inoreader_japanese.png](https://qiita-image-store.s3.amazonaws.com/0/2567/37716b46-d4cb-95e0-5940-c522ee81775e.png)

![inoreader_ja.png](https://qiita-image-store.s3.amazonaws.com/0/2567/00b299a5-514d-69ee-802d-6cba274700ae.png)

※設定で日本語に変更できるが、そもそもドメインから違うミラーサイトが存在する。

世界用→ https://www.inoreader.com/
日本用→ https://jp.inoreader.com/


本家サイトの表示が遅いなどの感想が見られるが、日本用にミラーサイトを用意してくれている。
> Is Inoreader slow for you? Try our jp.inoreader.com mirror.
> （↓翻訳）
Inoreaderは遅いですか？jp.inoreader.comミラーを試してみてください。


※クッキーの設定infoメッセージに「だが断る」の文字が。


![inoreader_nothankyou.png](https://qiita-image-store.s3.amazonaws.com/0/2567/44ccfa16-c5a3-215d-5689-c87b954450d5.png)



# 設定は各自で調整するもの
LDRが良かった人は真似するべし。LDRが悪かった人は自身で調整すべし。

Akiyan.comで紹介されている設定は以下のとおり。

- :eye_in_speech_bubble: 目玉メニュー
    - グループ化／フィードごと
    - 表示/展開ビュー
- 設定
    - 振る舞い/オートスクロールOFF






# まとめ
既に移行済みのユーザも多いようなのでお試しあれ