OmniAICreator/Qiita-1.07M huggingface dataset:
Boot2Dockerによる Docker Engineのインストールと　Dodker の基本的な使い方


#0.環境前提
MacOSX  virtualboxインストール済み

#1.構築する環境イメージ
![Kobito.W9tpNW.png](https://qiita-image-store.s3.amazonaws.com/0/72578/3bd528fe-042d-0afc-aef2-7afc9e2f4af8.png "Kobito.W9tpNW.png")


#2.Boot2dockerによるDocker Engineのインストール
##(1) Boot2Dockerのインストール
[Boot2Docker](http://boot2docker.io) からインストーラをダウンロードし、インストーラを実行

##(2) Boot2dockerコマンドの実行　（ターミナルで）
```bash:
#Linux仮想マシンの作成
boot2docker init

#Linux仮想マシンの起動
boot2docker start

#Linux仮想マシンの状態確認
boot2docker status
#runningと表示される

```
＊その他boot2dockerのコマンドはboot2dokcer -h で確認

##(3) 環境変数の設定
boot2docker startのコマンド実行結果で指示された通り、環境変数の設定をする。

```bash:
#boot2docker startコマンドの実行結果として表示されたexport XXX　の部分を実行し、環境変数に設定 ＊boot2docker shellinit コマンドで確認も可能

export DOCKER_CERT_PATH=XXX
export DOCKER_TLS_VERIFY=X
export DOCKER_HOST=XXXXXX

#確認
env | grep DOCKER   
```

#3.Dockerの基本的なコマンド
##(1)Dockerイメージの取得(docker pull)
Docker Hub からの Docker イメージのダウンロード
`docker pull イメージ名:タグ(バージョン)名)`

##(2)Dockerイメージの一覧表示(docker images)
`docker images`

##(2)Dockerコンテナの作成と実行(docker run)

##(3)Dockerコンテナの停止と削除

＊その他Dockerのコマンドはdokcer --help で確認

```bash:

#環境用ディレクトリの作成
mkdir lnmpr
cd lnmpr

```

#参考文書
[Dockerエキスパート養成読本](http://www.amazon.co.jp/dp/4774174416)
Backbone.jsソースコードリーディング

## `Backbone.Events`
### 構成
- Public API
    - クライアントとのI/F
- `_events`
    - コールバック、イベント、コンテキストを管理するプライベートなプロパティ
    - Backboneのイベント系メソッドは、ようするに本プロパティへの操作を抽象化したもの
- `eventsApi()`
    - `'event1 event2'`のようにイベント名が複数指定されることを考慮したイベント名パーサー兼イテレーター
    - 本メソッドにより、イベントの実処理からパーサーやイテレータを分離でき、実処理が簡潔になる
- `onApi() offApi() triggerApi()`
    - `_events`を使用して、イベントの登録・解除・発火の実処理を担う
    - 引数として`_events`を受け取って、加工後のオブジェクトを返すのでテストが容易そう

```js
// @onApi()
// `_events`が`events`に引数として渡ってくる
var handlers = events[name] || (events[name] = []);
...
// イベント名をキーとしてコールバック等を保持する
handlers.push({callback: callback, context: context, ctx: context || ctx, listening: listening});



// @eventsApi()
// 複数指定されたイベント名を分割して個別に`iteratee`(イベントの実処理)を実行する
for (names = name.split(eventSplitter); i < names.length; i++) {
  events = iteratee(events, names[i], callback, opts);
}
```

## `Backbone.Model`

## `Backbone.Collection`

## `Backbone.Router`
URLとハンドラを関連づける。

- `Backbone.History`のラッパー
    - イベントの検出やコールバック関数の実行は`Backbone.History`が担う
- URL更新はブラウザの`hashchange`イベントを検出する

## `Backbone.History`

## `Backbone.Sync`

## `Backbone.View`

## `Backbone.noConflict()`
```js
// Backbone.js読み込み前に定義されている`Backbone`を保持する
var previousBackbone = root.Backbone;

Backbone.noConflict = function() {
  root.Backbone = previousBackbone;
  // `this === Backbone`であるので、呼び出し元では戻り値をBackboneオブジェクトとしてリヨ用可能となる。
  return this;
};
```
- 事前定義している`Backbone`を`previousBackbone`に保持する
- `Backbone.noConflict()`にて、事前定義の`Backbone`を差し戻し、戻り値にBackbone.jsが定義する`Backbone`を返す
  - 事前定義の`Backbone`はそのまま参照でき、Backbone.jsが定義する`Backbone`は`Backbone.noConflict()`の戻り値から参照可能となる

## `Backbone.$`
```js
Backbone.$ = $;
```
- `Backbone`のプロパティとして`$`を保持する
- プロパティを公開扱いとして、Backboneが利用するjQueryオブジェクトを外部から変更可能とする
主要Webサービスのフリワード検索API例

# はじめに
フリーワード検索のRESTFullなAPIを作るにあたって、そういえば有名どころはみんなどんな風に作っているんだろうと思って調べた際のメモ。

# 確認したサービス
* connpass
* Spotify
* Github

# 確認のポイント
* APIエンドポイント
* 検索条件の指定方法(AND/OR/NOT)
* ソートの提供
* ページング方法
* レンジ指定での検索方法
* キーワードマッチング(対応してれば)

# connpass

## ドキュメント
https://connpass.com/about/api/

## APIエンドポイント
クエリパラメータでkeywordを指定するパータン

```
GET https://connpass.com/api/v1/event/?keyword=...
```

## 検索条件の指定方法(AND/OR/NOT)
* AND/OR毎にクエリパラメータを用意している
* AND条件での検索には「keyword」
* 
```
?keyword=value1,value2
```

* OR条件での検索には「keyword_or」
* 
```
?keyword_or=value3,value4
```

* ANDとORを組み合わせた検索条件の指定はこんな感じ

```
keyword=value1,value2&keyword_or=value3,value4
```

## ソートの提供
orderパラメータで指定し、区分値を指定して指定する。なお複数指定は不可。

```
1: 更新日時順
2: 開催日時順
3: 新着順
(初期値: 1)
```

更新日時順でソートしたい時はこんな感じで指定する

```
?order=1
```

## ページング
* countパラメータで取得数を指定
* startパラメータで検索開始位置を指定可能
* レスポンスの「results_available」に検索結果の総件数が含まれているため、この件数と取得した件数をもとにstartパラメータを使ってクライアント側でページング

## レンジ指定での検索
できない

-------

# Spotify

## ドキュメント
https://developer.spotify.com/web-api/search-item/

## APIエンドポイント
searchを別のエンドポイントとしているパターン

```
GET https://api.spotify.com/v1/search

```
search用の別のエンドポイントとしているパターン

## 検索条件の指定方法(AND/OR/NOT)
*　「q」パラメータで指定
* スペースを16進数エンコーディングした%20を利用するか、+を利用する
* ただ単語を並べた際はAND条件となる
* AND/OR/NOTのオペレータはいずれも大文字で指定する必要があり。小文字だと検索キーワードとして認識されてしまう。
* AND条件のとき

```
q=roadhouse%20blues. 

```

* NOT条件のとき


```
q=roadhouse%20NOT%20blues
```

* OR条件のとき 

```
q=roadhouse%20OR%20blues
```

## ソートの提供
ない？

## レンジ指定での検索
yearフィールとでレンジ指定が可能
q=bob%20year:2014
q=bob%20year:1980-2020


## キーワードマッチング
q=roadhouse&20blues　だと"Blues Roadhouse"と"Roadhouse of the Blues"がヒット
q="roadhouse&20blues" だと"My Roadhouse Blues"がヒットし"Roadhouse of the Blues"はヒットしない

----------

# GitHub
## ドキュメント
https://developer.github.com/v3/search/

## APIエンドポイント
searchを別のエンドポイントとしているパターン

```
GET /search/{検索対象}
```

## 検索条件の指定方法(AND/OR/NOT)
* 「q」パラメータで指定。
q=tetris+language:assembly　といった具合に、条件を繋いでいく。
* フリーワード検索部分は基本ANDで繋がっていく？
* NOT/-での除外が可能。
* 検索方法の詳細は	 別途ここにある
https://help.github.com/articles/understanding-the-search-syntax/


## ソートの提供
* sortパラメータで並び替えるフィールドを指定。デフォルトは検索マッチのスコア。
* orderパラメータで昇順か降順かを指定。asc/desc

## ページング
* ヘッダに後続のページへのリンクが入っているHETEOS形式。

## レンジ指定での検索方法
* 大なり小なり記号を利用
* ?pushed:>=2017-07-01+pushed:<2017-08-30
【PlayCanvas】ボーンアニメーションにエンティティを追従させる

この記事は [PlayCanvas Advent Calendar 2017](https://qiita.com/advent-calendar/2017/playcanvas) の14日目の記事です。
3Dモデルをアニメーションさせている際に、攻撃等の当たり判定を実装したいけど、モデルのメッシュでコライダーにしたら重いし、プリミティブで攻撃する範囲にだけコライダーを設定したい、、、みたいな需要がありますよね

そのやり方を書きます。
完成形はこんな感じ
![image.gif](http://i.imgur.com/MtGh8nD.gif)
薄緑色のボックスがコライダーです

##やり方
モデルにスクリプトをアタッチして以下コードを記載します。

```javascript:hitcheck.js
var Hitcheck = pc.createScript('hitcheck');
var skins;
// initialize code called once per entity
Hitcheck.prototype.initialize = function() {
    bones = { };
    skins = this.entity.model.model.skinInstances;

    for(var s = 0; s < skins.length; s++) {
        for(var b = 0; b < skins[s].bones.length; b++) {
            bones[skins[s].bones[b].name] = skins[s].bones[b];
        }
    }
};

```
##ボーン一覧
bonesにbones.nameの連想配列で格納されます。
console.logで出力すると以下のように格納されています
![image.png](https://qiita-image-store.s3.amazonaws.com/0/148084/2b3f3446-07e3-7871-4681-8934a963ef81.png)

##コライダーとボーンの同期
コライダー用のエンティティを用意し、スクリプトからボーンのtranslate情報を取得してsetします

```javascript:hitmodel.js
var Hitmodel = pc.createScript('hitmodel');

// initialize code called once per entity
Hitmodel.prototype.initialize = function() {
};

// update code called every frame
Hitmodel.prototype.update = function(dt) {
    this.entity.setPosition(bones.Sword_joint.getPosition());
    this.entity.setEulerAngles(bones.Sword_joint.getEulerAngles());
};
```
ボーン情報にはbones.{ボーンの名前}でアクセスします。
これでモデルに追従するエンティティが実装できます。
Ubuntu14.04 からUbuntu16.04へのアップデートエラー

# ubuntu14.04からubuntu16.04へUpdate

とりあえず，これをやる前に

```
apt-get update
apt-get upgrade 
apt-get dist-upgrade
apt-get autoremove
```

をやりましょう．

~~やらなくてもいいっぽい．~~

それから，

```
do-release-upgrade
```

を行って，updataだーーーー！！！

と思ったら，

```
.....
.....
.....

UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-10: ordinal not in range(128)
=== Command detached from window (Wed Dec 13 13:42:38 2017) ===
=== Command terminated with exit status 1 (Wed Dec 13 13:42:48 2017) ===
```

なんか，できないし...

それで，調べてみたら，

```
 LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8 LANGUAGE=en_US.UTF-8 sudo do-release-upgrade
```

どうも環境変数が設定されていないっぽい
しょうがないので，環境変数つきのコマンドを実行！！

すると，無事Updateできましたー


根本の原因は環境変数の設定なんですけど，どうやって設定すればいいんですかね？？

# 参考
- [さくらVPSのUbuntu16.04でMastodonを立てる(Docker版)](http://blogs.zealot.co.jp/archives/1030)
- [Ubuntuのフォーラム](https://ubuntuforums.org/showthread.php?t=2328729)
Vue.jsでオブジェクトにキーを追加/deleteしてもDOMに反映されない

## オブジェクトに変更を加えてもDOMに反映されない

Vue.jsではdataの変更を検知して自動的にDOMに反映されますが、オブジェクトの場合事情がことなります。


```HTML
<!- HTML ->
<div id="app">
  <div v-for='v, k in obj'>
    <p>{{ k }} is {{ v }}</p>
  </div>
  <button v-on:click='appendKey'>append</button>
  <button v-on:click='deleteKey'>delete</button>
</div>
```

```javascript
// javascript
new Vue({
  el: '#app',
  data: {
    obj: {
      'hoge': 1
    }
  },
  methods: {
    appendKey: function(){
      this.obj.fuga = 2;
    },
    deleteKey: function(){
      delete this.obj.hoge;
    }
  }
})
```

ボタンを押してもDOMに反映されない


## まんまと落とし穴に落ちる

よくある初心者の落とし穴
https://jp.vuejs.org/2016/02/06/common-gotchas/

リアクティブの探求
https://jp.vuejs.org/v2/guide/reactivity.html#変更検出の注意事項
>Vue.js はプロパティの追加または削除を検出できません

## こうやる

`$set` or `$delete`を使う

```javascript
// javascript
new Vue({
  el: '#app',
  data: {
    obj: {
      'hoge': 1
    }
  },
  methods: {
    appendKey: function(){
      this.$set(this.obj, 'fuga', 2);
    },
    deleteKey: function(){
      this.$delete(this.obj, 'fuga');
    }
  }
})
```
Square公式Node.jsライブラリがリリースされました！

SquareのWeb API、Square ConnectはRESTful APIなのでHTTPクライアントさえあれば利用できますが、それでもやはり専用ライブラリを使う方が分かりやすいでしょう。

これまで[PHP](https://github.com/square/connect-php-sdk)/[Python](https://github.com/square/connect-python-sdk)/[Ruby](https://github.com/square/connect-ruby-sdk)/[Java](https://github.com/square/connect-java-sdk)/[C#](https://github.com/square/connect-csharp-sdk)向けにSDKをリリースしてきましたが、先日[Node.js/JavaScript](https://github.com/square/connect-javascript-sdk)向けSDKがリリースされました。

こちらはそのファーストインプレッションです。

## インストール

Node.js向けなのでnpmでインストールできます。

```sh
$ npm install square-connect --save
```

## 使い方

[ロケーションAPI](https://docs.connect.squareup.com/api/connect/v2#endpoint-listlocations)を使って全店舗情報を取るサンプルです。

```javascript
const SquareConnect = require('square-connect');
SquareConnect
  .ApiClient
  .instance
  .authentications
  .oauth2
  .accessToken = 'YOUR_TOKEN';

let api = new SquareConnect.LocationsApi();
api
  .listLocations()
  .then((locations) => {
    console.log('Locations :');
    console.log(JSON.stringify(locations));
  }, (err) => {
    console.error(`Error! ${err.status}, ${err.response.text}`);
  });
```

アクセストークンは Square Developer Portal で取得できるもの、またはOAuth2を使って取得できます。トークンを適用するまでのメソッドチェーンがかなり長い印象ですね。OAuth2以外の認証をサポートするためだと思われますが。

メソッドの返り値はPromiseになりますので、よくあるネットワーク系ライブラリと同じように書けます。エラー時にはHTTPレスポンスオブジェクトがそのまま返ってきます。

処理成功時の返り値は次のような内容です。

```json
{
    "locations": [
        {
            "address": {
                "address_line_1": "中　１丁目", 
                "administrative_district_level_1": "国立市", 
                "country": "JP", 
                "locality": "東京都", 
                "postal_code": "186-0004"
            }, 
            "business_name": "ヤマモト 東京", 
            "capabilities": [
                "CREDIT_CARD_PROCESSING"
            ], 
            "id": "CBA...gAQ", 
            "merchant_id": "M1D75B5QATKAK", 
            "name": "ヤマモト 東京", 
            "status": "ACTIVE", 
            "timezone": "Asia/Tokyo", 
            "type": "PHYSICAL"
        }
    ]
}
```

---

[Squareの開発者ドキュメント](https://docs.connect.squareup.com)および[GitHubリポジトリのドキュメント](https://github.com/square/connect-javascript-sdk)はかなり充実しているので、実装したい内容がすぐに見つかるでしょう。ぜひ試してみてください。

[square/connect-javascript-sdk: Javascript client library for the Square Connect APIs https://docs.connect.squareup.com/](https://github.com/square/connect-javascript-sdk)
Cinema4dで人型モデルにスケルトンをバインドしてUnityで動かすまで

難しくないが、忘れてるのでここに書き記す。絵がなくてごめんなさい。
バインドは縛る、束ねるみたいな意味で、スケルトンが入ってない3Dのオブジェクトに、スケルトンを入れ込み機能させるみたいなこと（だと思います）。
![Kobito.glzAbd.png](https://i.gyazo.com/12d234497ceb670ff1f83a076f4d4066.gif "Kobito.glzAbd.png")

## 用語
* ジョイント
* ボーン
* スケルトン
* リグ
* エフェクタ

まず、この辺の言葉を適当に使ってると齟齬が生まれるので、ちゃんと覚えたほうがよさそう。[ここを参考にした](http://nyaa-kobayashi.tumblr.com/post/98144237408/%E3%82%B8%E3%83%A7%E3%82%A4%E3%83%B3%E3%83%88%E3%83%9C%E3%83%BC%E3%83%B3%E3%82%B9%E3%82%B1%E3%83%AB%E3%83%88%E3%83%B3%E3%83%AA%E3%82%B0%E3%81%A8%E3%81%8B%E3%81%AE%E4%BD%BF%E3%81%84%E5%88%86%E3%81%91)


## C4DからUnityで動かすまでの手順

1. 動かしたいメッシュを用意する
2. ジョイントツールを使い、メッシュに合わせたスケルトンを作成。
3. メッシュにスケルトンをバインディングする
4. FBXで書き出し、Unityで読み込む
5. FBXのインスペクタのRigという設定AnimationTypeをHumanoidにする。
6. Humanoidに対応したアニメーションを適用する。


# Cinema4dでやること

## バインドのやり方
簡単なやつと手動っぽいのがある。Unityで使うなら後者のがいいような気がしている。

* 簡単方式：キャラクターオブジェクトを使って、お手軽に作れるが、書き出した際の構造がUnityに合わない（たぶん）。
* 手動方式：ジョイントツールを使ってぼーんを生成していく、汎用性は高いかもしれない。


## ツールの使い方
* 「キャラクタ＞ジョイントツール」を使う
* ジョイントツールのオプション「ルートヌル」はオフにしといたほうがいい。余計な空オブジェクトができちゃう。
* Ctrl +クリックするとジョイントができてどんどん繋がっていく
* Shift + クリックするとボーンが２個に分かれる
* くっつけ方。　くっつけたいジョイントを選びつつ、ジョイントツールで生成。

参考にしたページ http://ameblo.jp/try-c4d/entry-11828376354.html

## ジョイントをメッシュにバインド
メッシュとジョイントを全選択（選択されてないジョイントはバインドされないので忘れず全選択）し、「キャラクタ＞コマンド＞バインド」を実行

※バインドがうまくいかないときは、ジョイントのプロパティが「ボーン＞親から」になってるのを確認


## ウェイト調整
面倒なので割愛。いつかやる。


## いちから作るのが面倒なとき
Unityで人を動かすことが目標なので、もう既にあるモデルからスケルトンだけ抜き出して、あとは位置調整＆バインドすればいい。一番手っ取り早いし、Unity上で必ずスケルトンは認識されるし


## 書き出し
fbxで書き出せば良い。


# Unityでやること

## FBXを設定
Unityに読み込んで(Asset以下に放り込んで）、rigのアニメーションタイプが、Humanoidになってることを確認。configureから、リグがちゃんと効いてるかどうか、確認できる。


## Locomotion 
キーボードでテスト的に動かしたいときは、Locomotionを使う。
https://www.assetstore.unity3d.com/jp/#!/content/7673

やり方

* Locomotionをアセットストアからダウンロードしてくる
* GameObjectのAnimationControllerに、Locomotionをつける
* スクリプトでLocomotionPlayerをつける


## 完成

![Kobito.glzAbd.png](https://i.gyazo.com/12d234497ceb670ff1f83a076f4d4066.gif "Kobito.glzAbd.png")
【PlayCanvas】ボーンアニメーションをスクリプトから制御する

この記事は [PlayCanvas Advent Calendar 2017](https://qiita.com/advent-calendar/2017/playcanvas) の13日目の記事です。
PlayCanvasでのボーンアニメーションのスクリプトからの制御方法で、ドキュメントにも載っていない方法を紹介します
#ドキュメント
[アニメーションブレンディング](https://developer.playcanvas.com/ja/tutorials/animation-blending/)
[pc.Animation | PlayCanvas API Reference](https://developer.playcanvas.com/en/api/pc.Animation.html)

#隠れたプロパティ
APIリファレンスにはduration,name,node程度しか載っていませんが、consoleで出力すると多くのプロパティが隠れています。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/148084/6a1b8fc0-cd3b-f7b6-c046-2e938fa3ee01.png)

##アニメーションの速度を変更する
```javascript
this.entity.animation.speed = 2;
```

##アニメーションを一時停止する
```javascript
this.entity.animation.playing = false;
```

##アニメーションの現在位置を取得する
```javascript
console.log(this.entity.animation.currentTime); //秒
console.log(this.entity.animation.currentTime/this.entity.animation.duration) //0 - 1
```

##アニメーションを早送り/逆再生
```javascript
this.entity.animation.currentTime++;//早送り
this.entity.animation.currentTime--;//逆再生
```

参考プロジェクト
https://playcanvas.com/project/535814/overview/animationviewer
【tmux】コマンドメモ

セッション外での操作

| Command                             | 概要 |
|:------------------------------------|:-------------|
| tmux new -s [session_name]          | セッション開始 |
| tmux list-session                   | セッション一覧の表示 |
| tmux a -t [session_name]            | セッション再入場 |
| tmux kill-session -t [session_name] | セッション削除 |

セッション内での操作

| Command                | 概要 |
|:-----------------------|:-------------|
| ctrl+B の後 shift+2(") | 水平分割 |
| ctrl+B の後 shift+5(%) | 垂直分割 |
| ctrl+B の後 O          | 分割の移動 |
| ctlr+D                 | 分割解除 |
| ctrl+B の後 D          | 動かしたままtmux修了 |
Polymer公式エレメントの紹介(app-element編)

Polymerチームによって公式に提供されるCustom Elementsの一つapp-elemnetsについて公式ドキュメントの説明を抜粋して紹介します。

## app-layout

アプリケーションのレイアウトの構築に便利なエレメントのコレクション

[公式サイトのApptoolboxの解説](https://docs.polymer-jp.org/2.0/toolbox/app-layout)にこれらのエレメントの画像付きの詳細な解説があります。実際にアプリケーションを作成する際は参考にしてください。

また、app-headerとapp-toolbarの各種オプションの実例については、以下のサイトが参考になります。
[Test Drive](http://polymerelements.github.io/app-layout/templates/test-drive/)

[DEMO & API](https://www.webcomponents.org/element/PolymerElements/app-layout)

### app-box 

`app-box`は各種スクロールエフェクトを備えたコンテナエレメントです。スクロールポジションに応じ視覚的なエフェクトが発生します。

### app-drawer

`app-drawer`は、画面の左右でスライドによって開閉されるドロワー型ナビゲーションです。

### app-drawer-layout

`app-drawer-layout`は、`app-drawer`とその他コンテンツによって構成されるエレメントのラッパーの役割を担い、drawer付きの画面レイアウトを簡単に構築できます。

### app-grid

`app-grid`は`@media`ルール内部で定義されたカスタムプロパティを利用したフラッド(fluid)グリッド式のレスポンシブレイアウトを作成するのに便利なヘルパークラスです。

### app-header

`app-header`は画面の上部にスクロールエフェクト付きの`app-toolbar`を使って画面を構成する際に使えるコンテナエレメントです。

### app-header-layout

`app-header-layout`は`app-header`とその他のコンテンツによって構成されるエレメントのラッパーの役割を担い、ヘッダー付の画面レイアウトを柔軟に構成するのに役立ちます。

### app-toolbar


## app-storage

アプリ内のデータを管理するための便利なツール群を提供するエレメント

[DEMO & API](https://www.webcomponents.org/element/PolymerElements/app-storage)

### app-indexeddb-mirror

`app-indexeddb-mirror`は、indexedDBへキャッシュを行うことで、アプリケーションデータへリードオンリーのオフラインアクセス機能を容易な実装を可能にしてくれるエレメントです。

### app-localstorage-document

`app-localstorage-document`はインメモリの値とブラウザのローカルストレージシステム内のデータを同期するためのエレメントです。これによってPolymerのデータバインディングを使いローカルストレージを活用したアプリケーションを簡単に開発できます。

## app-pouchdb

Custom ElemntsとPouchDBの連携に便利なエレメント

[DEMO & API](https://www.webcomponents.org/element/PolymerElements/app-pouchdb)

### app-pouchdb-conflict-resolution

`app-pouchdb-conflict-resolution`は宣言的な設定により、DOM内の論理的な関係によって順位づけを行うことで競合の回避を行ってくれます。

### app-pouchdb-document

`app-pouchdb-document`は`Polymer.AppStorageBehavior`の実装によって、個々のPouchDBドキュメントへの読み書きを管理するためのエレメントです。

### app-pouchdb-index

`app-pouchdb-index`はデータベースの索引づけ(indexing)を宣言的でべき等な設定によって行なってくれます。

### app-pouchdb-query

`app-pouchdb-query`はPouchDBへ宣言的でリードオンリーなクエリの発行を可能とします。

## app-route

クライアントサイドのモジジュラー式のルーティング機能を提供するエレメントです。

実際のアプリケーションでの利用例は[公式サイトのAppToolboxの解説](https://docs.polymer-jp.org/2.0/toolbox/routing)が参考になります。

[DEMO & API](https://www.webcomponents.org/element/PolymerElements/app-route)

### app-location

`app-location`はブラウザのロケーションバーとアプリケーションのステータスを同期するのに便利なエレメントです。`app-location`を一度生成すると以後、ブラウザによって管理されるグローバルロケーションの変更をアプリケーション内から自動的に管理することができます。

### app-route-converter

`app-route-converter`は、`route`オブジェクトとパスやクエリパラメーターの相互変換を行なってくれるエレメントです。

### app-route

`app-route`を使えば、ウェブアプリケーションのルーティングをエレメント自身が宣言的な記法で自己記述的に設定できるようになります。
Cinema4d で UV編集するときのメモ


## UVタグ
プリミティブなオブジェクトを編集可能にするとuvタグがついてくる。
uvタグの中にはuv情報が入っている。
無い場合は右クリックして作る。

## レイアウト
まず、レイアウトはUV Editに変更する。

## 右側のUV編集ウィンドウにテクスチャを出す
左下のマテリアルタブから、テクスチャを選択すると右側に出るっぽい。

前に編集したゴミが残ってたら、「ファイル＞保存されているテクスチャに復帰」で戻った。

## 選択ツール
* 「通常の面・点選択ツール」でオブジェクトを選択するとUV該当箇所がわかる。UV編集はできない。
* 「UVの面・点ツール」を使うとUVのほうを選択できる、移動したりできる。オブジェクトの編集はできない。

UV面ツールを選択しつつ、長方形選択とかをつかえば、いっきにUVが選べる。
UV編集上で右クリックすると拡大とか出てくる。

## 3Dペイントツール
上のツールバーの3Dってやつ。オブジェクトからも塗ることが可能。

## 投影法
右下のUVマップ＞投映法より選べる
3Dペイントが有効になっていると選べない。

## レイヤー
右下にタブがある。フォトショップみたいにテクスチャ画像のレイヤー。ペイントツールで塗ったやつをレイヤーに分けれる機能。

## 自分でテクスチャタグを作るとき
* テクスチャタグを作る
* そのテクスチャタグを選択した状態で、uvwタグを生成

## ペイントセットアップウィザード
上の３Dペイントボタンの左にあるやつ。テクスチャタグがない状態から、簡単に作れる系のやつ
ARKitで簡単ARやってみた

#はじめに
iOS11から使えるようになったARKitを使って簡単なデモを作りました。
ARKitで何ができるか詳しくは他のサイトを見てください。
この記事では「こんなに簡単にARアプリが作れるんだ！」というの紹介するので、
ぜひ「どうやって作ろうか？」に時間をかけるより「何を作ろう！」に集中して頂ければと思います。
#こういうの作る
・カメラを起動する
・画面にオブジェクト配置してみる
・水平面を検知してみる
・配置したオブジェクト動かしてみる
#作ってみる
##まずはプロジェクト作成
新規プロジェクト作成でAugmented Reality Appを選択。
これでテンプレートプロジェクトの完成です。
<img width="200" alt="プロジェクト作成.png" src="https://qiita-image-store.s3.amazonaws.com/0/204582/dc8d127a-27c0-b518-0d6e-383377bdb7a9.png">
出来上がったViewController.swiftから必要なところだけ抜粋すると、

```swift:ViewController.swift
import UIKit
import SceneKit
import ARKit

class ViewController: UIViewController, ARSCNViewDelegate {

    @IBOutlet var sceneView: ARSCNView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        sceneView.delegate = self
        sceneView.showsStatistics = true
        let scene = SCNScene(named: "art.scnassets/ship.scn")!
        sceneView.scene = scene
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        let configuration = ARWorldTrackingConfiguration()
        sceneView.session.run(configuration)
    }
    
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        sceneView.session.pause()
    }
    
} 
```

はい。たったこれだけです。
実機で起動すると、カメラが起動して、Appleがデモで用意した宇宙船のようなものがカメラ上に現れます。

これで「カメラを起動する」と「画面にオブジェクトを配置してみる」が終わりですね。

##オブジェクトを変えてみる
このままだとつまらないので、表示するオブジェクトを違うものにしてみます。
フリーで提供しているサイトがあるので、そこから3Dモデルをダウンロードします。
今回使ったのはこちらのサイト https://free3d.com/
(Xcodeでそのまま使えるのは「.dae」 「.obj」も使えるかもですが未確認です。)

プロジェクトにインポートして、「.scn」に変換して準備完了です。
(「.scn」への変換はXcodeメニューのEditor > Convert to SceneKit scene file format (.scn)でできます。)

インポートした画面がこちら。
<img width="500" alt="モデル追加_逆バージョン.png" src="https://qiita-image-store.s3.amazonaws.com/0/204582/c2335c7b-030c-8050-e3b8-9987c7f84c8d.png">


なにか逆さまになっている！
このままの状態で画面に表示されるので、少し調整
(具体的にはキャプチャの右に表示されているPosition、Eulerの値をいじります。)
調整後はこちら
<img width="500" alt="モデル追加_調整後.png" src="https://qiita-image-store.s3.amazonaws.com/0/204582/76a002f8-54cb-cf7b-01a0-37a9f5f99f4f.png">
まっすぐ向いてますね。これで後ほど平面に対して配置できるようになりました。

とりあえずこのオブジェクトを読み込んでみるように変更してみましょう。

![IMG_3578.PNG](https://qiita-image-store.s3.amazonaws.com/0/204582/dc231db8-5eb1-0c6d-f95f-4989d39ee1e9.png)
何か浮いている！
次は検知した平面の床にこのオブジェクトが置かれるようにしていきます。

##水平面を検知してみる
先ほど作ったプログラムに少し手を入れます。
水平面を感知するように設定をし、感知後にオブジェクトをその水平面に合わせて配置するようにしてみます。
はい。そうすると
![IMG_3580.PNG](https://qiita-image-store.s3.amazonaws.com/0/204582/55bb8507-39ad-59ba-a3ef-e8cef09a3c9d.png)
検知した床に対してオブジェクト(これからクマさんと呼びます)が置かれました。

実際に動かしてみます。
![マイムービー.mp4.gif](https://qiita-image-store.s3.amazonaws.com/0/204582/4bd826e9-0745-5266-7f26-5dd34d86b90d.gif)

良い感じにクマさんが鎮座してくれました。
これでいわゆる拡張現実になりましたが、さらにクマさんを動かして、色々やってみたいと思います。

##配置したオブジェクト動かしてみる
・タップしたらクマさんが動く
・ドラッグしたらクマさんが移動する
というのをやってみます。

ちょっと細かくなるので、詳しくはコードを見てもらえればと思います。
iOS開発経験があればすぐ理解できると思います。

それで完成したのがこちら
タップしたらクマさんが起き上がります！
ドラッグしたらクマさん動きます！(この機能がいまいちなので後ほどアップデートしたいと思います)
![マイムービー2.mp4.gif](https://qiita-image-store.s3.amazonaws.com/0/204582/2048659c-d4a1-adf0-f5ee-50a563400297.gif)

###今回のソースコードはこちら
https://github.com/pontake-dev/ARKitPlay

ソースコードを見てもらえればわかるかもしれませんが、本当にわずかな記述でここまでのものが作れます。
Windows10のユーザーフォルダ名変更

Windowsでプログラミングするときにうんざりするものの一つに、文字コード(テキストエンコーディング)があるとおもいます。
Windows10にアップグレードしてBash on ubuntu on Windows(以下BoW)もできて、以前のようにlinuxをデュアルブートさせてみたいなことも必要がなくなりました(PC再起動してOS切り替える手間を考えたらBoW導入したほうがラク)。


#動機
さて、本題です。
JavaScriptの勉強をしてた時に、ユーザーフォルダ名が漢字だと文字化けして絶対パスだと入らない…？
(*index.html*は相対パスでいいが、vscodeのデバッガが生成する*launch.json*は絶対パスじゃないとだめっぽい)
以前にもC言語書いてたときにもこんなことがあったような…？
じゃあ**ユーザーフォルダ名を変更**しちゃえ。
というわけで、では早速、手順の説明に入ります。
なお、本稿は相当ハゥトゥー色が強く、私も浅識ゆえ、読みにくいところがあるかと思います。
ご了承ください。
とその前に、**復元ポイントの作成**はお忘れなきよう。
#環境
OS: Windows 10 Home Insider Preview(build 17046.1000)

#手順
2通りのやり方があります。
1つは*Administrator*アカウントを必要としない方法。しかしこれはあとのファイル移動が面倒で私は**不採用**としました。(手順1)
もう1つは*Administrator*アカウントを必要とする方法。こちらはダメージが少ないので私はこちらを**採用**しました。(手順2)
###手順1
1. 「設定」→「アカウント」→「ユーザーの情報」からMicrosoftアカウントによるログインからローカルアカウントでのサインインに変更する。
2. 「設定」→「アカウント」→「家族とその他のユーザー」からその他のユーザーをこのPCに追加する。(「このユーザーのサインイン情報がありません」「Microsoft アカウントを持たないユーザーを追加する」を順にクリックして新しいユーザー名・パスワードを設定)
3. 「設定」→「アカウント」→「家族とその他のユーザー」から、新しく作ったユーザーのアイコンをクリックして「アカウントの種類の変更」から管理者権限を付与する。
4. すると管理者権限を持った新しい名前のユーザーが出来ましたね。あとは旧アカウントのユーザーフォルダからファイルを移動して完了です。

この手順だと、おそらくすべてのユーザーにインストールしていないソフトウェアは新しいユーザーでサインインした場合、スタートメニューに表示されず*ProgramFiles*を漁らないといけなくなると思います。非常に**面倒**です。
そこで手順2ではアカウントを変えずに名前だけ変えたいと思います。

###手順2
1. 「設定」→「アカウント」→「ユーザーの情報」からMicrosoftアカウントによるログインからローカルアカウントでのサインインに変更する。
2. *Windows*キー＋Xキーで表示されるメニューの中から管理者権限のコマンドプロンプトを選び、```net user administrator /active:yes```と入力しAdministratorアカウントを有効にして、スタートメニューから自分のアイコンをクリックしサインアウトした後、*Administrator*のアカウントでサインインする。
3. エクスプローラーからユーザーフォルダの名前を変更する。[^1]
4. Windowsキー＋Rキーで```regedit```と入力しレジストリエディタを起動させる。```HKEY_LOCAL_MACHINE -> SOFTWARE -> Microsoft -> Windows NT -> CurrentVersion -> ProfileList```と階層を降りていき、旧ユーザーフォルダのパスの書かれたレジストリを探して新しいユーザーフォルダのパスに書き換える。
5. PCを再起動して新しいユーザー(Administratorではない方)でサインインし、先程同様に管理者権限でコマンドプロンプトを起動させ、```net user administrator /active:no```と入力して*Administrator*アカウントを無効にして終了です。

#結果(影響)
簡潔に言えば、ユーザーフォルダ名を含む絶対パスを参照するアプリに影響が出ます。

1.iTunesの楽曲がすべて吹っ飛んだ
といっても参照できないだけで元ファイルは残っているので読み込み直しさせればいいだけです。

2.「最近表示したファイル」的なのが揃いも揃ってみんなだめ。
これは私は特に問題なかったです。

3.絶対パスで読み込ませてたTeXファイルがコンパイルできない。
当たり前ですね。そもそも相対パスで*include*させましょう。

これ以外は特に問題がなかったことに正直驚いています。フォルダのショートカットも書き換わるとかびっくりしました。

[^1]: ここが一番苦労しました。憎きWIndows Search(*SearchProtocolHost.exe*)…そうですこいつがユーザーフォルダにずっとアクセスして、フォルダ名の変更を妨げた犯人。再試行を連打しましょう。(リソースモニターからフォルダアクセスを監視しながらすると効率が良いです。)
【PlayCanvas】画面をキャプチャして外部サーバーに保存する

この記事は [PlayCanvas Advent Calendar 2017](https://qiita.com/advent-calendar/2017/playcanvas) の12日目の記事です。

[前回の記事](https://qiita.com/ryotaro_/items/6c7a3924975fb8d77fdc)の発展形です。
#やり方
toDataURL()で取得したキャンバスデータをajaxでサーバーに送信し、サーバー側のphpで保存する方法をとります。

#用意
##jQuery導入
今回はajaxの実装はjQueryを使ってやろうと思うので、jQueryをダウンロードしPlayCanvasプロジェクトにアップロードします。
http://jquery.com/download/

Script Loading orderからjQueryのライブラリを#1に持っていきます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/148084/125537f2-7625-bfbd-185d-4624659b774f.png)

##php用意
以下のphpをサーバーに保存します。

```php:saveimage.php
<?php
//canvasデータがPOSTで送信されてきた場合
$canvas = $_POST["canvasData"];

    //画像データが正しく入っていたら
    //ヘッダに「data:image/png;base64,」が付いているので、それは外す
    $canvas = preg_replace("/data:[^,]+,/i","",$canvas);
    
    //残りのデータはbase64エンコードされているので、デコードする
    $canvas = base64_decode($canvas);
    
    //まだ文字列の状態なので、画像リソース化
    $image = imagecreatefromstring($canvas);
    
    //画像として保存（ディレクトリは任意）
    imagesavealpha($image, TRUE); // 透明色の有効
    imagepng($image ,'images/image.png');
?>
```

#PlayCanvasからpost
jQueryの$.ajaxを使ってPOSTで送信します。
screenshot.jsを書き換えます。

```javascript:screenshot.js
Screenshot.prototype.takeScreenshot = function () {
    // Get application canvas element
    var canvas = document.getElementById ('application-canvas');

    // Get image data from canvas
    var imageData = canvas.toDataURL ();
    //サーバーに送信
    captureSendServer(imageData);
};

function caputureSendServer(data){
    $.ajax({
        type: "POST",
        url:"https://hogehoge.com/saveimage.php",//phpファイルのURL
        data: {
            "canvasData": data
        },
        success: function(j_data){
        },
        error: function (XMLHttpRequest, textStatus, errorThrown) {
        }
    });
}
```
これでサーバーに画像が保存されます。
canvasDataは大きいのでGETではなくPOSTで送信しています。PlayCanvasの開発環境から実行するときはエンドポイントがhttpsじゃないとだめだった気がするのでそちらは注意してください。
magento2 apache php mysql fast setup

1.すべてのパッケージインストールする。
※一括インストールOK
$ sudo yum -y install httpd24
$ sudo yum -y install php70
$ sudo yum -y install php70-mbsing
$ sudo yum -y install php70-pdo
$ sudo yum -y install php70-mysqlnd
$ sudo yum -y install php70-intl
$ sudo yum -y install php70-zip
$ sudo yum install mysql57 mysql57-server

2.httpd mysqld 起動確認
$ sudo service httpd start
$ sudo service mysqld start

3.apache配置
①etc/httpd/conf/httpd.confを編集し、以下の２行を追加
AddType application/x-httpd-php .html .htm .php .phtml
AddType application/x-htlstpd-php-source .html .htm .phps
②AllowOverride all編集
<Directory /var/www/>
 Options Indexes FollowSymLinks
 AllowOverride all
 Require all granted
</Directory>

4.mysql配置
①rootユーザパスワード修正
$ sudo service mysqld stop
$ sudo mysqld_safe --skip-grant-tables
ターミナル新規再開、rootユーザで登録
mysql>update mysql.user set authentication_string=password('root') where user='root';
$ sudo service mysqld restart
database 追加
mysql> create database magento;
②PHPにmysqlサポート追加
/etc/php.ini　に　extension=msql.so　追加

5.magentoインストール
cd /tmp/
$ wget https://github.com/magento/magento2/archive/2.0.7.tar.gz
$ tar xzvf 2.0.7.tar.gz
$ sudo mv magento2-2.0.7 /var/www/magento2/
【自動テスト】Selenium×Python導入手順を出来るだけ簡潔に分かりやすく書いてみる（Mac編）

# はじめに
最近**「自動テスト」**というワードをよく目にしますが、
導入に関する記事がネットに少なかったり記事によって内容が様々だったりで、導入のハードルが高いと感じている方もいるかと思います。

スマホ実機での自動テストとなると少々ややこしかったりするのですが、Mac のブラウザだけであれば割と簡単に導入することが可能です。

本記事では**「初期状態の PC でもこの通りにやれば上手くいく」**というレベル感を目指して書いていこうと思います。

# 前提
- 各ソフトウェアについての細かい説明は省略いたします
- ターミナルでの実行ディレクトリは、ホームディレクトリの想定といたします

# 環境
- macOS Sierra（10.12.6）
- Python（3.5.0）

筆者の環境は上記の通りです。
ある程度近い環境にしていただけるとスムーズに導入出来ると思います。
※ Python は3系でないと一部のブラウザで上手く動きませんでした

# Homebrew
## インストール
https://brew.sh/index_ja.html
以下をターミナルで実行します。

```
$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
```

# Pyenv
## インストール
以下をターミナルで実行します。

```
$ git clone git://github.com/yyuu/pyenv.git ~/.pyenv
$ brew install pyenv
```

## PATH の設定
.bash_profile ファイル（無ければ作成）に以下を追記します。

```
export PATH="$HOME/.pyenv/shims:$PATH"
```

設定した内容を反映するため、一度ターミナルを再起動するか以下をターミナルで実行します。

```
$ source .bash_profile
```

# Python
## インストール
以下をターミナルで実行します。

```
$ pyenv install 3.5.0
```

## バージョン切り替え
以下をターミナルで実行します。

```
$ pyenv global 3.5.0
$ python --version
Python 3.5.0
```

Python 3.5.0 と表示されれば OK です。

# Selenium
## インストール
以下をターミナルで実行します。

```
sudo pip install selenium
```

# WebDriver
## Chrome
以下をターミナルで実行します。

```
$ brew install chromedriver
```

## Firefox
https://github.com/mozilla/geckodriver/releases
上記ページより、末尾「macos.tar.gz」となっているファイルをダウンロードし、
内包されている「geckodriver」を「/usr/local/bin」に移します。

## Safari
Safari の「環境設定」から「詳細」タブを開き、
「メニューバーに"開発"メニューを表示」にチェックを入れます。

表示された「開発」メニューから「リモートオートメーションを許可」にチェックを入れます。

# 実行
以上で自動テストに必要な準備が整ったかと思いますので、最後に正しく動くことを確かめます。

```python:test.py
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("https://www.google.co.jp")
```

このコードをコピーして、test.py というファイルを作成します。

作成できたら、ターミナルで以下を実行します。

```
python test.py
```

上手く動けば、Chrome が立ち上がり Google に遷移されたかと思います。
また、Chrome という記述を Firefox/Safari に変更するとそれぞれのブラウザで実行できます。

今回は「指定した URL に遷移」という設定のみでしたが、その他色々なことが出来るので、以下を参考にしてみてください。
http://www.seleniumqref.com/api/webdriver_gyaku.html

# まとめ
筆者はここまでの導入でも色々なエラーに苦戦し何とか動くところまでたどり着いたので、この記事が誰かの参考になれば幸いです。

また、今回は Mac のブラウザのみでしたが、次はスマホの実機テスト手順についても書こうと思います。
（ちなみに、VirtualBox 上の Windows 環境でも動かそうと試みましたが、上手く動かなかったため詳しい方ぜひ教えてください…）
Kerasメモ：AttributeError: 'Tensor' object has no attribute '_keras_history'

#動機
Kerasでモデルを組んでいる時、タイトルのエラー "AttributeError: 'Tensor' object has no attribute '_keras_history' "が出て、困りました。

解決したので、その備忘録。

#エラーの原因
Kerasではモデルを組むとき、その計算過程のそれぞれがLayerオブジェクトである必要があるようです。Layerオブジェクトが持っているはずのattributeがないので、上記エラーが出るというわけです。

keras.layers以下に定義されているもの(DenseやActivationなど)を使う分には気にしなくてもいいのですが、Layerオブジェクトでないものを使ってオリジナルの計算過程を含めようとすると、上記のエラーが出ます。

例えば、以下のような場合です。意味をなさないコードですが...

```Python
from keras.models import Model
from keras.layers.core import Dense, Activation 
import keras.backend as K
from keras.activations import softmax

#疑似コードです
#backendはTensorflowです

output1 = Dense(100)(input1)
activated1 = Activation('softmax')(output1)

output2 = Dense(100)(input2)
activated2 = softmax(output2) #ダメ

concat = K.concatenate([activated1, activated2], axis=-1) # ダメ

model = Model([input1,input2], concat)
model.compile

```

上記のようなことをやろうとすると、ダメとコメントを入れたところでエラーが出ます。keras.backendのモジュールや、keras.activationsのモジュールを使っているためです。


#解決方法 : from keras.layers import Lambda
keras.layersにLambdaというモジュールがあります。これは、任意の計算をLayerオブジェクトとして扱えるようにするためのラッパーです。

```Python
from keras.models import Model
from keras.layers.core import Dense, Activation 
from keras.layers import Lambda
import keras.backend as K
from keras.activations import softmax

#疑似コードです
#backendはTensorflowです

output1 = Dense(100)(input1)
activated1 = Activation('softmax')(output1)

output2 = Dense(100)(input2)
activated2 = Lambda(lambda x: softmax(x))(output2)

concat = Lambda(lambda x: K.concatenate([x[0], x[1]],axis=-1))([activated1, activated2])

model = Model([input1,input2], concat)
model.compile

```
cocos2d-xテーブルビュー

##### __基本__

|クラス|説明|
|---|---|
|TableView|画面に表示される部分を担っている|
|DataSource|テーブルビューに表示させる情報をまとめている|
|Delegate|動作・操作時に呼びだされるインターフェースであり、これを経由して入力に対応した処理を行う。|
三種類のクラスを組み合わせて一つのテーブルビューが動作する。

##### 設定項目

|メソッド|説明|
|---|---|
|setDirection|スクロールする方向（垂直 or 水平）|
|setVerticalFillOrder|表示順序（上下左右のどちらから開始するか）



sample

```c++
using namespace cocos2d::extension;

TableView* table = TableView::create(/*略*/);
table->setVerticalFillOrder(TableView::VerticalFillOrder::BOTTOM_UP);
table->setDirection(ScrollView::Direction::VERTICAL);
table->setContentOffset(cocos2d::Size(0.f, 0.f));
```
Azure での Sorry サーバー考察

Azure テクノロジーソリューションプロフェッショナルの鈴木祐巳です。
普段は、企業の方々に公開ウェブサイト向けの Azure サービス使っていただけるよう頑張っています。
たまにお客様に尋ねられることに「Sorry サーバーの構築」があります。内心「クラウドなんだから、Sorryサーバーなんか準備しないで、短期的にリソース追加して、トラフィックさばけよ！」と思っているわけですが、提案依頼書(RFP)に 「Sorry サーバー準備」などの項目があると、用意しておく必要があったりするわけです。

ということで、Azure で Sorry サーバーの構築方法を考えてみます。
# Web Apps か? Azure Storage か?
Sorry サーバーは、最小限の静的コンテンツを返すことで、大量のアクセスを捌くことを目的としています。静的コンテンツを扱えればよいので、クラウドを使うのであれば、ウェブサーバーではなく、https/http でアクセスできるストレージ、Azureなら、Blob Storage をウェブサーバー代わりにつかって、配信する
いわゆる10円サーバー的な使い方で、Sorry サーバー構築を考慮されることもあると思います。実際に、最初は、Storage を使って、Sorry サーバーを構築しようと思いました。
Blob Storage を静的コンテンツ向けウェブサーバーとして利用する方法は、検索するとイロイロでてくると思うので、ここでは割愛します。が、実際に、Storage を使用すると、1つ問題があります。
# Sorry ページのステータスコードは、200? 503?
Storage をウェブサーバー代わりにつかうと、ステータスコードは、200となり、検索エンジンにキャッシュされる可能性があります。それを避けるために、Sorry ページのステータスコードは503、つまりは、Service Unavailable であるのが適切と言われています。実際には、ステータスコード200で Sorry ページを運用されている例もあるので、Storage を Sorry ページに使うのは絶対にNGという訳ではないですが、できれば、ステータスコード503を返す Sorry サーバーを構築したいところです。ということで、App Service Web Apps の出番となります。
#  Web Apps で、オリジナルな静的コンテンツをホストしつつ、ステータス 503 を返す。
独自ドメイン運用が必要な場合が多いと思いますので、Shared上のプランが必要になります。Shared プランだと、パフォーマンスの懸念を感じることもありますが、前段にCDNを配置することで、Shared での運用も、パフォーマンス的に問題にならない事も多いと思います。SLAが必要なら、Basic 以上での運用も考慮したいところですが、そうなると価格が一気にあがってきますので注意が必要です。すでに、他のサイト運用で、Basic プラン以上の App Service Plan を作成している場合には、その App Service Plan に Web Apps を追加するという運用をするのが良いと思います。
ここでは、Windows 版の Web Apps を使う前提です。ということで、IIS の設定での、カスタムページを表示しつつ、ステータスコード503を返す設定を web.config にて行います。設定例は以下の通りです。

```web.config
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <rewrite>
            <rules>
                <rule name="SiteDown" stopProcessing="true">
                    <match url=".*" />
                    <action type="CustomResponse" statusCode="503" statusReason="Down for Maintenance" statusDescription="Will be back soon" />
                </rule>
            </rules>
        </rewrite>
        <httpErrors existingResponse="Auto" errorMode="Custom" defaultResponseMode="File">
         <remove statusCode="503" subStatusCode="-1" /> 
            <error statusCode="503" path="503.html" />
     </httpErrors>
    </system.webServer>
</configuration>
```

# 運用ウェブサーバーから Sorry サーバーへの切り替え
運用ウェブサーバーと Sorry サーバーの切替は、DNS CNAMEの手動書き換えで実施してもよいのですが、Azure では、Traffic Manager を使うことで、運用サーバーがなんらかの状況で停止した際に、自動切り替えが可能です。Traffic Manager のルーティング方法の設定で「優先度」を選択肢、Sorry サーバーを最も優先度の低いサーバーとして登録することで、運用サーバーにトラブルが発生した際に、自動的に、Sorry サーバーに切り替わるようになります。
<img width="174" alt="TM.png" src="https://qiita-image-store.s3.amazonaws.com/0/3816/bd0e4da7-0182-b13f-b2cc-6965c121bbfb.png">
さくらインターネットでVue.jsの勉強会を開催したときの話

この記事は「さくらインターネット Advent Calendar 2017」の14日目の記事です。

さくらインターネットでVue.jsの勉強会を開催したときの話をします。

# 開催までの経緯
弊社についてはサーバ・インフラのイメージが強く、
「さくらインターネットのフロントエンド？」と思われる方も多いかもしれません。

ですが、実はフロントエンド開発を専門としたエンジニアも多数おり、
サービスのコントロールパネルや申し込み画面などの開発業務を日々行っております。
しかしながら、前述の通り世間一般ではあまり認知されていない・・・。

そんな状況ではありますが、
外部発信の一環として個人向け勉強会を開催したいという声があがり、
Vue.jsの勉強会が開催されることになりました。

開催にあたってはcommpassを利用して募集を行い、
先着30名の枠に加えて抽選の30名枠には45名の応募をいただけるなど、
たくさんの人に興味をもっていただけたのかな？と思います。
[さくらの夕べ　「さくらインターネットのエンジニアは Vue.js をこんな風につかってます」](https://connpass.com/event/67740/)

# Vue.js勉強会の話
本題となりますVue.jsの話。
勉強会は4名のエンジニアによるVue.jsについてのアレコレの発表がされました。
スライドが公開されているのは1・3部となるので、この記事ではそちらの紹介をさせていただきます。

### 第1部「はじめてのビュウ」
[「はじめてのビュウ」](https://www.slideshare.net/sakura_pr/ss-81230416)
[さくらのクラウド料金シミュレーション](https://cloud.sakura.ad.jp/payment/simulation/#/)
Angular1系でかかれていたものをVue.jsで作り直したお話で、

- Vue.jsの採用理由
- 開発する前におさえておきたいポイント
- 開発経験に基づいた知見

などが発表されました。


### 第3部「とにかく楽してVue.jsでTypeScriptを使いたい」
[「とにかく楽してVue.jsでTypeScriptを使いたい」](https://www.slideshare.net/sakura_pr/vuejstype-script-81228009?next_slideshow=1)
Vue.js + Typescriptで開発されたお話。
作成されたものは社内向けのログビューアなので公開はできないのですが、
実際に開発された感想や代わりとなるサンプルが公開されています。
またVue2.5よりTypescriptのサポートが強化されたことを受け、
Vue2.5 + Typescriptを試された感想も書かれております。

また勉強会に参加いただいた方が詳細なレポートを作成してくださいました、ありがとうございます！
2部と4部についても記載してくださってます:grin:
[「さくらインターネットのエンジニアは Vue.js をこんな風につかってます」レポート #さくらの夕べ](
http://yamanoku.hatenablog.com/entry/2017/10/31/%E3%80%8C%E3%81%95%E3%81%8F%E3%82%89%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%BC%E3%83%8D%E3%83%83%E3%83%88%E3%81%AE%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%AF_Vue_js_%E3%82%92%E3%81%93%E3%82%93)



# 勉強会その後
勉強会後に簡単なアンケートをとったので、そちらの紹介も少しだけさせていただきます。

> 「Vue.jsを使っていますか？」（回答35件）

- よくつかっている 22.9%
- 使ったことはある 40.0%
- 使ったことがない 37.1%

半数以上の方がVue.jsの利用経験があったようです。
一方Vue.jsを使ったことがない方の参加も多数あり、
勉強会を通じてVue.jsに挑戦していただけたら嬉しいですね。

> 「さくらインターネットのフロントエンド開発に関する印象を教えてください。」

- 自由そうで楽しそう
- 自由でカオス

この他にも自由そう、といった感想が多く寄せられました。
これについて今回は記載していないのですが、
第2部でサービス開発を担当するエンジニアがわりと好きにフレームワーク選定を行っていたため、
プロダクト毎にフレームワークが異なるといった状況が紹介されていたので、
このような印象に繋がったのかなと思いました。

- あまりしていないイメージ
- あまり聞かない、表に出ない印象

ですよねー。~~むしろこの回答を待っていました。~~:yum:

# 裏話
- 想定より出席率が高く、席がぎゅうぎゅう詰めに。（申し訳ないです）
- 想定より出席率が高く、配布用パンフレットを急遽追加作成。
- 想定より（ｒｙ、社内の人間は発表が見れなかったので、後日社内向けに再演。

たくさんのご参加ありがとうございました。

# おわり
以上で、さくらインターネットでVue.jsの勉強会を開催した時の話を終わりとさせていただきます。
Vue.js、個人的にもこれから開発するプロダクトにも利用したいと考えているので、
多くの人に興味を持ってもらってコミュニティの発展や知見の共有が進むと嬉しいですね！
無料の rest client の Insomnia で API を叩く

ツイッターのユーザー ID や ツイートの ID からその情報を引いてくるのはブラウザでは難しく API を直接叩く必要があります。

具体的には新しい API の検証を行うときなどにそういうことがしたくなります。

そんなときには Insomnia という Rest Client が便利です。

https://insomnia.rest/

最近 OAuth1 に対応したので Twitter の API も叩けるようになりました。　基本無料で使えるので最高です。

![スクリーンショット 2017-12-13 12.58.04.png](https://qiita-image-store.s3.amazonaws.com/0/17704/3975710e-623a-c0eb-c5ef-04406f3fda0e.png)
【PlayCanvas】画面をキャプチャして表示/ダウンロードする

この記事は [PlayCanvas Advent Calendar 2017](https://qiita.com/advent-calendar/2017/playcanvas) の11日目の記事です。
#やり方
HTML5 canvasのtoDataURL()を利用します。
公式サンプルがあるのでまずはそちらから
[Capturing a screenshot
](https://developer.playcanvas.com/en/tutorials/capturing-a-screenshot/)

#良く躓く落とし穴
## 設定
Setting > RENDERING > Preserve Drawing Bufferのチェックを必ず入れる必要があります(デフォルトではfalse)
これを入れないとapplication-canvasのtoDataURL()にキャンバスデータが乗りません
![image.png](https://qiita-image-store.s3.amazonaws.com/0/148084/3c4c5bf0-5a2f-00b5-64d7-665ff7f7fc2e.png)

## window.openだと開かない
この前まで動いてたんですが、突然動かなくなりました
Take ScreenShotボタンを押してもabout:blankのまま次に進みません。
[choromeでスクリーンショットが撮れません | PlayCanvasコミュニティ](https://support.playcanvas.jp/hc/ja/community/posts/115008308567)

動くブラウザと動かないブラウザがあるようなので、おそらくブラウザの問題かなーと思います。
htmlにimgを用意してsrcで流したらうまく動いたのでキャプチャはうまくいっているようです。

#画像をダウンロードする
直接ローカルにダウンロードするような実装も可能です。
screenshot.jsを以下のように書き換えます

```javascript:screenshot.js
// NOTE: THIS SCRIPT ONLY WORKS IF 'PRESERVE DRAWING BUFFER' IS ENABLED IN PROJECT SETTINGS

var Screenshot = pc.createScript('screenshot');

Screenshot.prototype.initialize = function() {
    this.app.on('ui:takeScreenshot', function () {
        this.takeScreenshot();
    }, this);
    
};

Screenshot.prototype.takeScreenshot = function () {
    // Get application canvas element
    var canvas = document.getElementById ('application-canvas');
    
    // Get image data from canvas
    var imageData = canvas.toDataURL ();
    
    var downloadElement = document.createElement("a");
    downloadElement.href = imageData;
    downloadElement.download = "image.png";
    downloadElement.click();

    // Show the image data in a new window/tab. 
    //window.open (imageData);
};
```

エレメントのdownload属性は使えるブラウザと使えないブラウザがあるので注意してください
https://caniuse.com/#search=download

発展形は[こちら](https://qiita.com/ryotaro_/items/fe342c3ed5fa405f8d87)
MavenでJUnit5が実行してできなかったのを解決したメモ。

### 環境とバージョン
Java - Java9
Eclipse - Oxygen.1a Release (4.7.1a)
JUnit - JUnit5

MavenプロジェクトでJUnit5を使用するため以下をpom.xmlに記述たあと色々設定した後、JUnitでビルドするとエラーが出たのでその内容と解決方法です。

```
  <dependencies>
    <dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter-engine</artifactId>
      <version>5.0.2</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
```

### エラー内容
<img width="522" alt="スクリーンショット 2017-12-12 20.20.17.png" src="https://qiita-image-store.s3.amazonaws.com/0/96493/998bb5d1-5510-d05b-fce6-65260e6290a0.png">



```
Could not run test

No tests found with test runner 'JUnit5'
```

### Eclipseのコンソール

```
ava.lang.NoClassDefFoundError: org/junit/platform/launcher/core/LauncherFactory
	at org.eclipse.jdt.internal.junit5.runner.JUnit5TestLoader.<init>(JUnit5TestLoader.java:31)
	at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:488)
	at java.base/java.lang.Class.newInstance(Class.java:558)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.createRawTestLoader(RemoteTestRunner.java:368)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.createLoader(RemoteTestRunner.java:363)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.defaultInit(RemoteTestRunner.java:307)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.init(RemoteTestRunner.java:222)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:206)
Caused by: java.lang.ClassNotFoundException: org.junit.platform.launcher.core.LauncherFactory
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:582)
	at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:185)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:496)
	... 11 more
```



### 解決方法
pom.xmlに以下を追加する。

```
    <dependency>
        <groupId>org.junit.platform</groupId>
        <artifactId>junit-platform-launcher</artifactId>
        <version>1.0.1</version>
        <scope>test</scope>
    </dependency>
```

JUnit5では3つのサブプロジェクトに別れたため、JUnit5のJUnit Jupiterだけを依存性の定義に追加でしただけでは足りなかったようです。

### 解決に導いてくれた記事
・[JUnit5](http://www.ne.jp/asahi/hishidama/home/tech/java/junit/5/index.html)
・[JUnit 4で消耗しているあなたに贈るJUnit 5入門](http://acro-engineer.hatenablog.com/entry/2017/12/07/120000)
WordPress バッドノウハウ　〜ダメパターン開発編

* WordPressを利用したサイト開発者初心者向けの内容です。
* サイト運営者向けは過去にスライド作ってるので参照にどうぞ（一部重複します）
    * [WordPress 初心者からの脱出 #tohokuitfes](https://www.slideshare.net/gatespace/wordpress-tohokuitfes)
    * [WordPress アカンパターン](https://www.slideshare.net/gatespace/wordpress-42292244)
* なんだかんだでダメパターンがなくならない現状なのでマサカリ覚悟の投稿
* スライドがめんどくさいのでQiitaのスライドモードにして思い出したら更新しようという腹づもり
* スライド見づらかったらごめんね！全画面モードだといい感じだよ！
* [@jim0912](https://twitter.com/jim0912), [@takayukister](https://twitter.com/takayukister) からネタ提供いただきました。thx!

- - -
# ダメその1　コアファイルの改変

* 動作結果を変えたいならフィルターフックやアクションフックを活用すべき
* 当然アップデートで上書きされる（アップデートしないのは論外）
* 第三者でも再現できるバグであれば、報告した方がみんなが幸せになる
    * https://make.wordpress.org/core/

- - -
# ダメその2　公式プラグインの改変
* 動作結果を変えたいならフィルターフックやアクションフックを活用すべき
* 当然アップデートで上書きされる（アップデートしないのは論外）
* 第三者でも再現できるバグであれば、報告した方がみんなが幸せになる
    * プラグイン掲載ページのSupport など

- - -
# ダメその3　公式テーマの改変
* [子テーマ](https://codex.wordpress.org/Child_Themes) を使おう　最低限 style.css のみでOK
* 当然アップデートで上書きされる（アップデートしないのは論外）
* 第三者でも再現できるバグであれば、報告した方がみんなが幸せになる
    * プラグイン掲載ページのSupport など

- - -
# ダメその4　 なんでもかんでも functions.php
* テーマを切り替えると **動作しなくなる機能** はプラグインにすべし
    * カスタム投稿タイプ : `register_post_type()`
    * カスタム分類（タクソノミー） : `register_taxonomy()`
    * ショートコード : `add_shortcode()`
* 機能と見た目は切り分けよう

- - -
# ダメその5　とりあえずなPHP
WordPressのテンプレートタグを使おう（一例）

| PHP                   | WordPress          |
|:---------------------:|:------------------:|
| `mb_substr()`         | `wp_trim_words()`  |
| `mail()`              | `wp_mail()`        |
| `file_get_contents()` | `wp_remote_get()`  |

* https://developer.wordpress.org/reference/functions/wp_trim_words/
* https://developer.wordpress.org/reference/functions/wp_mail/
* https://developer.wordpress.org/reference/functions/wp_remote_get/

PHPでもできるけど、他の処理も組み合わせる必要があるなら、初めからそれらが組み合わされているテンプレートタグを使ったほうが良い。

- - -
# ダメその6　いまだに `query_posts()` 使ってる
* ループちゃんと理解してる？
    * メインクエリの改変 : `pre_get_posts`
    * サブクエリ : `WP_Query` または `get_posts()`

ただし、用もないのに `pre_get_posts` 使ってメインクエリ壊しちゃダメ！

- - -
# ダメその7　サニタイズ（無害化）なにそれおいしいの？
そのまま `echo` して本当に大丈夫？
出力も入力も関数使おう
https://codex.wordpress.org/Data_Validation

- - -
# ダメその8　とりあえずなグローバル変数
安易に `$post` や `$wpdb` の中身を `echo` してませんか？

* `get_the_ID()` など投稿に関するテンプレートタグ
* `get_queried_object()`
* `get_queried_object_id()`
* `get_query_var()`

- - -
# ダメその9　PHPでタイムゾーン変えちゃう

* 9時間ずれてるからって`date_default_timezone_set( 'Asia/Tokyo' );` はやめましょう。
* `date()` ではなく WordPress の一般設定のタイムゾーンに合わせてくれる（ローカライズしてくれる）  ~~`date_i18n()`~~ `wp_date（）` を使おう
    * https://developer.wordpress.org/reference/functions/wp_date/

- - -
# ダメパターンをなくすために
* 最新の情報なのかリファレンスを確認しよう
    * https://developer.wordpress.org/reference/
* テーマやプラグインのハンドブック読もう
    * https://developer.wordpress.org/themes/
    * https://developer.wordpress.org/plugins/

現場からは以上です。
星取表に再挑戦して気づいたこと

# 星取表に再挑戦

自分は、何度もスキルアップにモチベーションを・・・スキルの可視化を・・・と思い、
いわゆる「スキルマップ」や、「星取表」に取り組んでみましたが何度も失敗してきました。

今回星取表に再挑戦してみて気づいたことを書きます。

# 過去導入時に失敗したなと思うこと
- とりあえずやってみよう、やってみなきゃわからない。って言うだけで、自分たちなりの意味づけを永遠にしなかった
- 自分のスキルを上げるためでなくチームメンバーのスキルを上げるために・・・って外側にいる感じになっていた

上記によって、
とりあえず色塗れってなったから塗りました。ってなって終わっていた。
自分ごとじゃないから、なんでやらないんだよ。。。って思って自分も活用してなかった。

# 過去スキルの洗いだしの観点で失敗したなと思うこと
- ある時は、一部の人が他社事例をそのままスキルを当てはめていた
- ある時は、とりあえず「スキル」と思うものを並べてみた

上記によって、
いろんな項目があって何からやればいいのか、何が大事なのかよくわからなくなっていた。


# 再挑戦に伴ってやってみてたこと
- 自分自身が何を伸ばしたらチームのためになるかを考え、伝える

- スキルの洗い出しは、チームで確認しながら行う
  - 会話例：今のプロダクトやチームを構成してるスキルってどれだっけ？

- チームのビジョンが実現した時の自分たちのスキルと今のスキルを逆算した時に、1ヶ月後のチームのスキルの状態がどうなっているべきか、いたいか考える
  - 会話例：ネイティブアプリや、ハイブリットアプリ作っていく方向になっていきそうなのにそこのスキル弱くない・・・？

- どうやってスキルを身につけていくとチームが効率的に学んでいけるか考える
  - 会話例：俺は幅広く知っておかないといけないよね。〇〇さんは勉強するの好きだし先に勉強して後で業務で一緒にやるってどう？とか

# やってみて起きたこと
- 自分が伸ばしたいところを表明して仕事を取ってサポートしてもらえている
- 1ヶ月後になりたい姿のために、自分がどの仕事したらいいか考えられている
- この仕事やってみたら？一緒にやろう。って会話が生まれている

# 現在の星取表
1月中旬になっていたい姿|3月終わった時になっていたい姿
---|---
<img width="510" alt="スクリーンショット 2017-12-11 18.16.57.png" src="https://qiita-image-store.s3.amazonaws.com/0/197426/794d8843-caef-f50a-7948-98bda31ae48d.png">|<img width="513" alt="スクリーンショット 2017-12-11 18.17.47.png" src="https://qiita-image-store.s3.amazonaws.com/0/197426/a4cf43ed-6b53-f8cc-42ab-c3e18f470849.png">


## この先やってみること
- 自分の伸ばしたいところのスキルが上がったと言える状態をチームメンバーと話し合い、上げる取り組みをする
- 2週間に一回の計画の時に星取り表を眺めて、スキル習得のチャンスがないか話し合う
- 一部スキルの粒度を細かくする（テストってなってる部分は広すぎてどうなってればいいかイメージしにくいため）

## 大事だなと感じていること
- 自分が、スキルを向上させることで何かの意味があると感じられているかどうか
  - 今回自分は、新しくチームにジョインしたのでどんなスキルが必要で、何が足りないのか純粋に知りたくて、何を身につけることで今のチームのためになりビジョン達成に向かうのか知りたかった

- 可視化と会話を通してスキルが上がるとワクワクしてくる感覚をチーム内につくる
  - とりあえずあげようとか、何からあげたらチームのためや自分のためになるか分からない、やる気がでない
論理削除 is evil

# 何が問題か
**「削除」じゃないじゃん！！**

おわり。

## 問題を生んだ思考。
* 「削除」じゃないものを「削除」と開き直る態度。
    * あるいは言語感覚の欠落。
* 自己矛盾に気づかないレベルの思考停止。
* もとに戻したいときに復活できるから。という諦めの悪さ。
    * そもそも「もとに戻したい」可能性があるなら削除させてはいけない。

## 「削除」を騙ることの弊害と代償
詳しくは、こちらを参照。
https://www.slideshare.net/t_wada/ronsakucasual
https://www.slideshare.net/SoudaiSone/postgre-sql-54919575

「削除」したはずデータが残っているという現実との矛盾の辻褄合わせが連鎖的に膨れ上がって、制御不可能になるということです。

**論理削除 is evil というか、 absolutely evil。**

# どうしても論理削除をしたいという、諦めの悪い人のために
ゴミ箱テーブルを用意して、delete トリガで自動バックアップをとりましょう。

これ自体は別に目新しいアイデアではありませんが、

* テーブルごとに同じカラムを持つゴミ箱テーブルや、トリガを用意する必要がある。
* 元テーブルのカラムが増減するたびに、ゴミ箱テーブルや、トリガもメンテナンスする必要がある。

という問題があります。

ですが、PostgreSQL (9.3以降)であれば各レコードをjson化する `row_to_json()` 関数でどんなカラム構造のデータでも1つのjsonbデータに変換することができるので、カラム構造の違うテーブルのレコードを同一のテーブルに収めることが可能になります。

## 定義方法

```sql
create table dustbin (
    table_name text not null,
    id integer not null,
    data jsonb not null default '{}',
    deleted_at timestamp without time zone not null default current_timestamp,

    primary key (table_name, id)
)

create function throw_in_dustbin() returns trigger as $$
    begin
    insert into dustbin (table_name, id, data) values (tg_table_name, old.id, row_to_json(old));
    return old;
    end;
$$ language plpgsql
```

あとは、論理削除をしたいテーブル個別に以下のdelete トリガを設定するだけ。

```sql
create trigger delete_<table_name> before delete on <table_name>
  for each row execute procedure throw_in_dustbin()
```

この方法であれば、元テーブルのカラムが増減しても `dustbin` テーブルや `throw_in_dustbin` 関数の内容を変更する必要がありません。

え？ データが `jsonb` だと検索が遅くて大変？
この `dustbin` テーブルを検索するのは1年に1回あるか無いのだから気にしない。（何度も検索するようであれば、delete操作が間違っている証拠。）

## 使用例

```sql
# -- 対象テーブル
# select * from addresses;
 id | name |           info
----+------+--------------------------
  1 | hoge | {"zip": "1234567"}
  2 | fuga | {"tel": "090-1234-5678"}

# -- トリガ追加
# create trigger delete_addresses before delete on addresses
  for each row execute procedure throw_in_dustbin()

# -- hogeを削除
# delete from addresses where name = 'hoge'

# -- address からはキレイに削除されている
# select * from addresses;
 id | name |           info
----+------+--------------------------
  2 | fuga | {"tel": "090-1234-5678"}

# -- 削除されたデータは dustbin に保存されている。
# select * from dustbin;
 table_name | id |                         data                          |         deleted_at
------------+----+-------------------------------------------------------+----------------------------
 addresses  |  1 | {"id": 1, "info": {"zip": "1234567"}, "name": "hoge"} | 2017-12-13 12:17:15.511607
```

## 注意事項
* delete文が遅くなりますので、本当にバックアップが必要なテーブルのみに適用しましょう。
* dustbin テーブルにはデータさ蓄積されていく一方です。
    * 大量・長期保存する必要があるならちゃんとパーティションを切りましょう。
    * これは読者への宿題とします。