OmniAICreator/Qiita-1.07M huggingface dataset:
リリース間近？EC-CUBE 3.0.13の目玉を紹介

AdventCalendarも20日目。クリスマスも目前ですが、EC-CUBEの開発チームは年内でリリース予定の3.0.13のリリースに向けて追われています。

詳細は[GitHub](http://github.com/ec-cube/ec-cube) の[Issue](https://github.com/EC-CUBE/ec-cube/issues/1900) や[Milestone](https://github.com/EC-CUBE/ec-cube/milestone/21) にまとめていますが、3.0.13で特に注目の内容について簡単に紹介します。

## ひとことで言うと？

3.0.13はプラグイン開発者向けに便利な機構や細々とした機能改善が多く含まれています。

## 1) app/console にプラグインジェネレーターを搭載

まずはプラグインジェネレーターです。
PR: https://github.com/EC-CUBE/ec-cube/pull/1915

プラグインジェネレーター自体は、[開発ドキュメントサイトでも紹介](http://ec-cube.github.io/plugin_tutorial-generate)されているように、[株式会社キュール](https://cule.jp/) さんがプラグインで提供されているものがありましたが、これが3.0.13で同等のものが本体機能として採用されました。
これによりコマンドラインからプラグインの雛形が作りやすくなります。

```> php app/console  plugin:develop generate```
でプラグインの雛形が
```> php app/console  plugin:develop entity```
でプラグインのEntityの雛形が生成されます。

フォルダ構成を用意すると行ったお決まりの作業が短縮されるのは、プラグインを開発される方の効率はもちろん、プラグインをこれから作って見ようという人にも助けになるかと思います。

## 2) batchが作りやすくなります

PR: https://github.com/EC-CUBE/ec-cube/pull/1952

こちらもapp/consoleの強化ですが、プラグインからapp/console にコマンドが追加できるようになります。
これにより 夜間バッチでの商品CSVの取り込みなどのbatch開発が俄然しやすくなります。
開発ドキュメントサイトにも作り方があるのでぜひ御覧ください。
http://ec-cube.github.io/plugin_tutorial-generate

## 3) プラグインのREADMEが見やすくなります

Issue: https://github.com/EC-CUBE/ec-cube/issues/1643

プラグイン一覧でREADMEの内容を表示できるようになります。
プラグインの使い方などを簡単に確認できるようにすることで、プラグイン利用者もわかりやすくプラグイン開発者への問い合わせの減少などが期待されます。

## 4）プラグインから商品一覧のソート順を制御できるようにする

Issue: https://github.com/EC-CUBE/ec-cube/issues/1916

かなり以前から要望の多かった商品一覧のソート順の制御ですが、doctrineの不具合のためなかなか対応することができていませんでしたが、今回 doctrine2.5の内容をバックポートすることで対応いたしました。大変おまたせいたしました。

こちらの実装サンプルもかねて、優先的に表示した商品を上に並べるプラグインを1月にリリース予定です。
開発中のコードもまもなく[公開](https://github.com/EC-CUBE/product-priority-plugin)します。


## その他 約80件の改善要望・不具合修正に対応

大きくは開発者向けの機能追加・改善が中心になりますが、

+ 受注管理画面に複数対応状況の検索を追加 #1570
+ 受注登録の商品追加/会員検索モーダルダイアログにページング機能を実装 #1917 #1918
+ 新着情報のフロント表示を5件刻みにする #1654 #1291

などなど、地道な改善を多数入れております。

## リリースは年内

というわけで、リリースはおそらくクリスマス明けになるかと思いますが、年内のリリース目指して最終テスト中です。
先行してお試しされたい方は、GitHubからHerokuボタンをぽちっとな。でお試しいただけますので、ぜひ見てみてください。

### EC-CUBE 3.0.14もご意見募集中

[EC-CUBE 3.0.14についてもご意見募集](https://github.com/EC-CUBE/ec-cube/issues/1994)しておりますので、ご意見お待ちしております。
FCM用のiOSのPush通知証明書は同じCSRで開発用と本番用を作っては絶対にダメ

当たり前の話かもしれないですが
同じことで戸惑わないように起きた事象と解決法をメモ

## 起きた事象

手元でビルドしたアプリに対してはFirebaseNotificationからPUSHしても届いていたのに
ストアに公開したアプリになった途端に通知が届かなくなった

## 原因

FCMではAPNs通知(iOSのPush通知)の証明書として
「開発用 APNs 証明書」と「本番用 APNs 証明書」を設定できます。

このAPNsの証明書はAppleのDeveloper Centerから
CSRから作られた証明書の場合、同一なものと見なされてしまい
DeveloperCenterで別の証明書（.cer）を作っても、違うものとして認識されず
結果、本番用のAPNs証明書に開発用のAPNs証明書が登録されてしまい
PUSH通知やDeviceTokenの登録処理が正しく本番向けに行われない。

## 見分け方

同一の証明書がセットされている場合、有効期限が同一になっているので
その点を起点に確認すると良いです。
以下同一のものがセットされている場合のスクリーンショット
![スクリーンショット 2016-12-20 17.37.49.png](https://qiita-image-store.s3.amazonaws.com/0/15902/007f5be1-722e-a634-25be-27df0bbaddb6.png)


## 解決方法

原因にも記載したとおり、同一のCSRを使っているのが問題のため
CSRも別々の物を用意して生成すれば問題ない。

## 参考：経験談としての注意

2017年当時の挙動として記録を残しておくと
もし誤って開発用の証明書を設定した状態でDeviceTokenを受け取ってしまうと
Firebase側では開発側の証明書とDeviceTokenがセットで登録されてしまうらしく
以後再インストールしても、DeviceTokenの繋がりが有効となっており届いてしまう。
※要するにアンインストールしてもFirebase側との紐付きにおけるPush通知の設定がリセットされない様子。
Sandbox環境の運用が煩雑になってしまうので注意すること。

## 参考ページ

[プッシュ通知に必要な証明書の作り方2016 \- Qiita](http://qiita.com/natsumo/items/d5cc1d0be427ca3af1cb)
覚えておくと若干便利なGitLabショートカット

# 覚えておくと若干便利なGitLabショートカットのご紹介
[GitLab keyboard shortcuts](https://gitlab.com/help/workflow/shortcuts.md)の中からGitLabで覚えておくと少しだけ便利なショートカットを紹介します。

## ヘルプダイアログ
まずわからなくなったGitLabの画面ダイアログを出す。Keyboard:<kbd>Shift</kbd> + <kbd>?</kbd>
基本どの画面にいても出せるみたいです。閉じる時は再度Keyboard:<kbd>Shift</kbd> + <kbd>?</kbd>
<img width="860" alt="dialog.png" src="https://qiita-image-store.s3.amazonaws.com/0/151648/35ef70c3-d149-5c34-9d5d-47f82333811a.png">


## 検索エリアへのフォーカス
フォーカスがエディタ上にない時にSearchエリアにフォーカスする
Keyboard:<kbd>s</kbd>
<img width="741" alt="search.png" src="https://qiita-image-store.s3.amazonaws.com/0/151648/df40106f-377f-773d-42bc-c1f1f0ddc886.png">


## Markdown Previewの表示
issue等Markdown Previewがある時PreviewとWriteの切り替えができる
**Ma**c Keyboard: <kbd>⌘</kbd> + <kbd>shift</kbd> + <kbd>p</kbd> 
**Windows** Keyboard: <kbd>Ctrl</kbd> + <kbd>shift</kbd> + <kbd>p</kbd> 
![editpreview.gif](https://qiita-image-store.s3.amazonaws.com/0/151648/a54341a7-9132-d397-6739-2b226f37e726.gif)


## Projectでのページ遷移
プロジェクトの画面に表示している時にプロジェクト内のそれぞれのページに遷移する
特にFind Fileに行ける<kbd>t</kbd>は楽。

| Keyboard Shortcut | Description |
| ----------------- | ----------- |
| <kbd>g</kbd> + <kbd>p</kbd> | ホームに移動 |
| <kbd>g</kbd> + <kbd>e</kbd> | Activityに移動 |
| <kbd>g</kbd> + <kbd>f</kbd> | Filesに移動(Repository -> Files) |
| <kbd>g</kbd> + <kbd>c</kbd> | Commitsに移動(Repository -> Files) |
| <kbd>g</kbd> + <kbd>b</kbd> | Buildsに移動(Pipelines -> Builds) |
| <kbd>g</kbd> + <kbd>n</kbd> | Networkに移動(Repository -> Network) |
| <kbd>g</kbd> + <kbd>g</kbd> | Graphsに移動(Graphs -> Contributos) |
| <kbd>g</kbd> + <kbd>i</kbd> | Issuesに移動 |
| <kbd>g</kbd> + <kbd>m</kbd> | Mergerequestsに移動 |
| <kbd>g</kbd> + <kbd>s</kbd> | Snippetsに移動 |
| <kbd>t</kbd> | Find Fileに移動(Repository -> Find File) |
| <kbd>i</kbd> | New issue |

いろいろ用意されていますが、上記以外はあまり使う機会がないかな
GCPでServerless Architectureを実現する第一歩としてFirebase Hosting (HTTPS)を使ってみよう

## 目的

2016年はサーバレスアーキテクチャが盛り上がったし、自分自身でも何度も口にした一年だったような気がしますので、[Firebase](https://firebase.google.com/) (Hosting)を使ってServerless Architectureを実現してみましょう。また、同等のことはGoogle App Engine (GAE)を使っても実現できるでしょう。

サーバレスと言えば、AWS Lambda + API Gateway、[Azure Functions](https://azure.microsoft.com/en-us/services/functions/)という空気になっていて、[Cloud Functions](https://cloud.google.com/functions/)が現状のまま（アルファ版）だと盛り上がらないよな、ということで、GCPでもサーバレスでやっていこうと思う人に刺さればいいかなと思います。

基本的にhttps://firebase.google.com/docs/cli/ に書いてある手順通り実行すれば大丈夫です。

## はじめに
Googleアカウント(@gmail.comかG Suiteのアカウント)が必要です。

次にNode.js環境(npm)を確保しましょう。Homebrew信者の方はbrewでいいと思いますが、2017年を迎えようとする今ですから通常はDockerでいいでしょう。

```shell-session
docker run --rm -it -p 9005:9005 node:7.2.1-alpine sh
```

後ほどGoogleアカウントを用いたOAuth 2認証のため、localhostにポート9005でアクセスする必要がありますので、`-p 9005:9005`しましょう。

## firebase-toolsを用意

```shell-session
npm install -g firebase-tools
```
とするだけで、`firebase`コマンドが利用できるようになります。結構時間がかかります（分単位）。

## 認証情報を取得

```shell-session
firebase login
```

とすると、URLが提示されると思いますので、ブラウザで開き、許可しましょう。許可が完了すると、`localhost:9005`のどこかにコールバックされます。

## プロジェクト初期化

```shell-session
firebase init
```

として、Realtime DatabaseとHostingを選択できますが、今日はHostingのみ選びましょう。プロジェクトIDを訊かれますので、答えましょう。

firebase.jsonが作成されます。

```firebase.json
{
  "hosting": {
    "public": "public"
  }
}
```

## ファイル作成・編集

publicディレクトリに `index.html` と `404.html` が作成されるので、自分がアップロードしたいものにアップロードしましょう。

## アップロード

ファイルの作成などが完了したら、

```shell-session
firebase deploy
```

とすればアップロードされます。

```
=== Deploying to 'my-project'...

i  deploying hosting
✔  database: rules ready to deploy.
i  hosting: preparing public directory for upload...
⚠  Warning: Public directory does not contain index.html
✔  hosting: public folder uploaded successfully
✔  hosting: 2 files uploaded successfully
i  starting release process (may take several minutes)...

✔  Deploy complete!

Project Console: https://console.firebase.google.com/project/my-project/overview
Hosting URL: https://my-project.firebaseapp.com
```

このままでは、 https://my-project.firebaseapp.com という形式でしかアクセスできませんので、カスタムドメインを利用しましょう。

## カスタムドメイン設定

### ドメイン名の所有の確認
新規ドメインの場合は `myproject.com` の所有権の確認が必要です。APEXドメインを利用する場合でもサブドメインを利用する場合でもAPEXに `TXT` レコードを2個追加する必要があるようです。
ドメイン名管理者にメールが飛んでくるようですが、気にしなくてもいいようです。

### サブドメインのCNAME設定
推奨されているのはCNAMEですが、Aレコードもサポートされていますので、固定IPにもできるようです！すごい！

## CI化

今どきCIを使っているのが当たり前でしょう、という時代になって久しいので、各自のCI環境に組み込みましょう。

## セキュリティ

Qualysに問い合わせてみましょう。

こんな感じ。極めて普通ですね。

![firebase-hosting-qualys.png](https://qiita-image-store.s3.amazonaws.com/0/49113/1e8bd5ac-d69a-9fb7-32a7-9a2e4bb8a491.png)


## GAEと組み合わせ

- [GAE (SE)とFirebaseを組み合わせてAndroidアプリを開発](https://cloud.google.com/solutions/mobile/firebase-app-engine-android-studio)する例はGoogle Cloud Platformにも載っていますので、そちらでServerlessを実現していくとよいでしょう。
iPhoneでみずきちゃんとﾁｭｯﾁｭしたいだけの人生だった（AWS Polly + Swift）

３次元で合成音声話す女子がいたら今すぐ連絡ください。
ペッパーはだめです。

というわけでやっていきます。

## AWS Polly
いろんな言語を話してくれる音声合成AIです。AIに入るの？
CLIからの利用記事が目立ちますが、今回はどうしてもiPhoneにいれて好きな言葉を話させたかったので、swiftでラッパーを作りました。
ちなみにVersionが違うせいか[公式doc](https://github.com/awslabs/aws-sdk-ios-samples/tree/master/Polly-Sample/Swift)のままじゃ動きません。


## 手元の環境

* iOS = 10.0
* Xcode = 8.2
* Swift = 2.2


## 構築手順

* CognitoIdentityPoolをつくる  
  `enable access to unauthenticated identities` みたいなのにチェックいれとく
* サービスクラスをつくる

```swift
import Foundation
import UIKit
import AVFoundation
import AWSCore
import AWSPolly
import AWSCognito

class AudioGuidanceService: UIViewController, NSURLSessionDownloadDelegate {
    var audioPlayer = AVAudioPlayer()
    
    func say(message: String) {
        let credentialsProvider = AWSCognitoCredentialsProvider(
            regionType: .USWest2,
            identityPoolId: "作成したPoolID"
        )
        
        // 匿名で認証する
        let configuration = AWSServiceConfiguration(region: .USWest2, credentialsProvider: credentialsProvider)
        AWSServiceManager.defaultServiceManager().defaultServiceConfiguration = configuration

        // みずきちゃんフォーマットを組み立てる
        let input = AWSPollySynthesizeSpeechURLBuilderRequest()
        
        input.textType = AWSPollyTextType.Text
        input.text = message
        input.outputFormat = AWSPollyOutputFormat.Mp3
        input.voiceId = AWSPollyVoiceId.Mizuki
        
        let builder = AWSPollySynthesizeSpeechURLBuilder.defaultPollySynthesizeSpeechURLBuilder().getPreSignedURL(input)
        
        // みずきちゃん召喚！
        builder.continueWithSuccessBlock({ (awsTask: AWSTask) in
            let result = awsTask.result! as! NSURL
            
            let config: NSURLSessionConfiguration = NSURLSessionConfiguration.backgroundSessionConfigurationWithIdentifier("backgroundSession")
            let session: NSURLSession = NSURLSession(configuration: config, delegate: self, delegateQueue: nil)
            
            let url: NSURL = result
            let request: NSURLRequest = NSURLRequest(URL: url)
            let task:NSURLSessionDownloadTask = session.downloadTaskWithRequest(request)
            
            // タスクを実行.
            task.resume()
            
            return nil
        })
    }
    
    // みずきちゃん召喚後の実体に喋らせる
    func URLSession(
        session: NSURLSession,
        downloadTask: NSURLSessionDownloadTask,
        didFinishDownloadingToURL url: NSURL) {
        do {

            self.audioPlayer = try AVAudioPlayer(contentsOfURL: url)
            
            self.audioPlayer.prepareToPlay()
            self.audioPlayer.play()
        } catch let error as NSError {
            print(error)
        } catch {
            print("error")
        }
    }
}
```

* 利用する

```swift
var audio = AudioGuidanceService()
audio.say("はろーわーるど！！")
```


## 余談
swift歴２週間なので変なところがあったらご指摘ください！

ちなみに `4` の発音が疑問形っぽくなってかわいい。
Vagrantを起動してAndroidでアクセスする

Vagrantを起動した後にMacではアクセスできましたがAndroidではアクセスできなかったため、できるようになるまでにしたことのメモです。

## Vagrantの起動

[VirtualBox](https://www.virtualbox.org/)と[Vagrant](https://www.vagrantup.com/)をinstallした後に`$ vagrant up`で起動します。
起動した後にMacにて`192.168.x.x`にアクセスできました。

![スクリーンショット 2016-12-20 17.21.47.png](https://qiita-image-store.s3.amazonaws.com/0/145420/9c472047-ba7a-5729-f131-46115e70568b.png)

Androidにて同じように`192.168.x.x`でアクセスしますがアクセスできません。

![Screenshot_2016-12-20-17-25-10.png](https://qiita-image-store.s3.amazonaws.com/0/145420/b70d5a94-1e1b-0de7-d093-43910575454a.png)

## Vagrantfileの設定変更

`Vagrantfile`のネットワーク設定がデフォルトでは`config.vm.network "private_network", ip: "192.168.x.x"`になっているため変更した後に再起動します。

**public_networkにする際にはセキュリティに注意してください。**

```Vagrantfile
config.vm.network "public_network", bridge: "en1: Wi-Fi (AirPort)"
```

## Vagrant再起動

再起動した際に`private_network`とは違い以下の様に出ますので1を選びます。

```
==> default: Available bridged network interfaces:
1) en0: Wi-Fi (AirPort)
2) en1: Thunderbolt 1
3) bridge0
4) p2p0
5) awdl0
...
default: Which interface should the network bridge to? 1
```

再起動できた後にIPを調べそちらでアクセスしてみます。

```
$ vagrant ssh
$ ifconfig
```

表示されている`192.168.x.x`でMac Android共にアクセスできました。

## 原因
`Vagrantfile`のネットワーク設定が`private_network`になっていたため、Macでしか接続できなかったようです。
`public_network`に変更することでPC以外の端末からでもアクセスできるようになりましたが、その分セキュリティには気を付けましょう！
[AWS][Lambda] ローカルで Lambda 用の nodejs スクリプトを実行する

ローカルで Lambda 用に作ったスクリプトを実行してみたいことってありますよね。
簡易的にテストしたいときとか。
そんな時は、以下のような test.js を作成してやってます。

```js:test.js
var event = {
  "value1": "value1"
};

var context = {
    succeed: function(data){console.log(JSON.stringify(data,' ',4));},
    fail: function(data){console.log("fail!!\n" + JSON.stringify(data,' ',4));},
    invokedFunctionArn: 'test:development',
    functionName: 'test',
    functionVersion: '$LATEST'
};
var callback = function(){};

var myLambda = require('./index');
myLambda.handler(event, context, callback);
```

Lambda 登録用の zip ファイルには aws-sdk は含めてないと思うんで、npm install の -g オプションでグローバル領域にインストールしておきましょう。

```bash
$ npm -g install aws-sdk
```

実行する時にデフォルト以外の aws-cli に登録されている configure ファイルを指定したい場合は、以下のようにして実行します。
(例えば example ってプロファイルを使いたい場合)

```bash
$ export AWS_PROFILE='example'; node test.js
```
Cognos BI で暗号情報の再生成が必要な時の対応

Cognosのあるある話なので、困ったら参考にしてください。

Cognos BIの環境をセットアップしてから、**1年後のある日突然、Cognos BIが起動しなくなる**時があります。
また、Framework Managerも含めて、Cognos Configurationを保存しようとした時に、**「暗号情報の生成」の箇所で失敗**して、いつまでもセットアップできない時があります。


Cognos BIが起動できない件は、複数ノードに分散されたCognos環境で発生する事象で、こちらの365日の設定に起因するものですが、デフォルトで365日なので、知らずにプロジェクトを離れた後に、ある月曜日の朝に、突然Cognosが起動しなくなったと連絡を受けた方も多いのではないでしょうか。
![001.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/5bc241bd-b6b3-8540-28a4-32a9e1dd810d.png)

Framework Managerの件も、Cognos Configuration保存時のこのエラーのパターンですが、なかなかConfigurationの保存ができずに困った方も多いのではないでしょうか。
![005.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/d8d806c2-eb77-1ca2-d7fb-e29f453cd3db.png)

**どちらのケースでも暗号情報の再生成が必要となります。**
このあたりのTechnoteに記載されている再生成手順を実施してください。

**How to Regenerate Cryptographic Keys**
http://www-01.ibm.com/support/docview.wss?uid=swg21383421

**How to Regenerate Cryptographic Keys as of Cognos 10.2.2?**
http://www-01.ibm.com/support/docview.wss?uid=swg21694322

**How to regenerate cryptographic keys in Cognos Analytics 11.**
http://www-01.ibm.com/support/docview.wss?uid=swg21995088


暗号化の情報の全般的な話に関しては、なんと言ってもこのリンクが最も良くまとまっていますので、是非ご一読下さい。
**IBM Cognos 10 暗号化サービス 【CSK編】**
http://www.ibm.com/developerworks/jp/data/library/cognos/cognos10_encryption-service/
Vagrant UP時にSSH auth method: private key･･･で詰まった話

# フリーズするGitBash君･･･

新しくVagrantを立ち上げることになり、ちょー簡単なことで時間を使ってしまったので、忘れないようにメモ書き。

ソースコードをCodeCommitかCloneしてきて、Vagrantfileを作成し、いざ「vagrant up」を実行！

```
(省略)
==> default: Waiting for machine to boot. This may take a few minutes...
    default: SSH address: 127.0.0.1:2222
    default: SSH username: vagrant
    default: SSH auth method: private key
･･･
```

ここでまったく反応がなくなり、「Timed out while waiting for the machine to boot.」と表示され、タイムアウトになる。

Google先生に聞いても、「ホストマシンのBIOS設定で仮想化支援機構が無効になってるんじゃない？」とか「タイムアウトの時間を変更してみたら？」とかしか見つからず(自分の聞き方が悪かったのかな･･･)詰まってしまいました。

# 違うワードでGoogle先生に聞いてみる

もしかしたらVagrantとかVirtualBoxのバージョンの問題か？！となり調べなおしてみると、解決策を見つけることができました。

```
config.vm.provider "virtualbox" do |vb|
    vb.customize ["modifyvm", :id, "--cableconnected1", "on"]
  end
```

これをVagrantfile中に記載すればよかっただけでした。
こんなことで1時間も使ってしまうあたり、まだまだ未熟者だなと実感した次第です･･･
enebular INFOMOTIONのフィルタ機能

## 概要

enebular INFOMOTIONにはフィルタ機能があります。enebular INFOMOTION上の画面でフィルタする方法とenebular INFOMOTIONを外部に貼り付ける際にソースコードで制御する方法があります。

## enebular INFOMOTION上の画面でフィルタをかける

シンプルな棒グラフで試します。棒グラフの作り方は[enebularの標準INFOMOTION Type（BarChart, LineChart）の使い方](http://qiita.com/joeartsea/items/c7b696a8624e91572d6b
)を参照します。

グラフ左上にある以下の赤丸で囲ったアイコンをクリックするとフィルタ設定をするダイアログが開きます。

![image](https://qiita-image-store.s3.amazonaws.com/0/21109/8416fabe-e71e-df9b-93cf-86267ad856af.png)

今回は以下のように横軸を`value0`に絞り込みます。

![image](https://qiita-image-store.s3.amazonaws.com/0/21109/7a63ee7f-e845-9935-f235-4bd7c9bd947b.png)

OKをクリックすると以下のように絞りこまれます。

![image](https://qiita-image-store.s3.amazonaws.com/0/21109/9b76af4a-ef30-81ea-8bc7-cb5d962d5124.png)

## enebular INFOMOTIONを外部に貼り付けてフィルタをかける

BarChartのshareリンクをクリックして表示されるHTMLタグをローカルファイルとして保存します。

![image](https://qiita-image-store.s3.amazonaws.com/0/21109/53b1d3d8-5f2e-30bb-43d6-9e91cd7cc99e.png)

以下のようにフィルタボタンを設置してクリックでフィルタ/解除が切り替えられるようにコーディングします。

```html
<link rel="stylesheet" href="https://enebular.com/public/emi/css/style.css" />

<!-- フィルターボタンを設置 -->
<button id="filter-btn">フィルター</button><br>

<div id="enebular-daterangepicker"></div>
<div id="enebular-timeline"></div>
<div id="enebular-graph"></div>

<script src="https://cdn.mlkcca.com/v2.0.0/milkcocoa.js"></script>
<script src="https://enebular.com/public/emi/main.js"></script>
<script>
var settings = {...}
var graphData = [...]
var dateRangePicker = EnebularIntelligence.createDateRangePicker("enebular-daterangepicker");
var timeline = EnebularIntelligence.createTimeline("enebular-timeline");

// フィルタボタンとステータス
var filterBtn = document.getElementById('filter-btn');
var filterStatus = true;
var graphs = [];

EnebularIntelligence.createGraph("enebular-graph", settings, graphData, {
  dateRangePicker: dateRangePicker,
  timeline: timeline
}).then(function(g) {
  graphs.push(g); // graphsに追加（複数グラフある場合も考慮して）
  var now = new Date();
  var start = now.getTime() - 1 * 24 * 60 * 60 * 1000;
  dateRangePicker.setRange(new Date(start), now);
  console.log("loaded");
}).catch(function(err) {
  console.error(err);
});

// フィルタをかけるメソッド
function applyFilter(f) {
  graphs.forEach(function(g) {
    g.applyFilter(f);
  });
}

// フィルターボタンイベント
filterBtn.addEventListener('click', function(e) {
  if (filterStatus) {
    applyFilter({})
    filterStatus = false;
    filterBtn.textContent = "フィルター";
  } else {
    applyFilter({"id":"value0"});
    filterStatus = true;
    filterBtn.textContent = "フィルター解除";
  }
 });
</script>
```

以下のようにフィルタ/解除が切り替えられるようになります。

![infomotion.gif](https://qiita-image-store.s3.amazonaws.com/0/21109/a41d55b4-e9ed-6107-5017-5dcff07118b4.gif)
MithrilでHTMLフォームの日時入力

すでに[HTMLフォームをMithrilでそのまま使う方法](http://qiita.com/shibukawa/items/6b79d83490de24d160e5)は紹介しました。今回は日付入力フォームです。
軽く調べただけなのでツッコミ募集中です。

<img width="484" alt="スクリーンショット 2016-12-20 16.15.14.png" src="https://qiita-image-store.s3.amazonaws.com/0/6105/bfa89ed3-456f-edb7-a062-04590ec28e39.png">

日付入力は ```<input type="種類">``` で使える入力フォームです。一昔前だとjQuery UIのdatePicker()とか使っていて表示していたような入力フォームです。HTML 5ではこれから紹介するうちのdateとtimeしかありませんが、HTML 5.1では定義が追加されています。

* [W3CのHTML 5.1の日付時間のフォーマット](https://www.w3.org/TR/html51/infrastructure.html#dates-and-times)
* [W3CのHTML 5.1の日付入力フォーム](https://www.w3.org/TR/html51/sec-forms.html#date-state-typedate)

caniuseですべて調べられなかったのですが、Chrome/Edge/Operaで対応している一方、IE/Firefox/Safariでは対応していません。

* [サンプル](https://jsfiddle.net/qnamb33p/8/)

日時入力フォームの種類一覧
=============================

日時フォーム

| タイプ | 書き方 |
|:-:|:-:|:-:|
| 年-月  | ```m('input[type=month]')``` |
| 年-W週  | ```m('input[type=week]')```  |
| 年-月-日  | ```m('input[type=date]')```  |
| 時:分  | ```m('input[type=time]')```  |
| 年-月-日T時:分  | ```m('input[type=datetime-local]')```  |

Mithrilでの使い方
====================

入力フォームが扱うのは、↑の表のようなフォーマットの文字列です。valueとして与えれば初期値として設定しできるので、仮想DOMと一緒に扱うことができます。

一番簡単なmonthで紹介します。一番シンプルな例です。

```js
    controller: function() {
        this.month = m.prop(null);
    },
    view: () => {
        return m('input[type=month]', {
            onchange: m.withAttr('value', ctrl.month),
            value: ctrl.month()
        })
    }
```

入力された値は文字列形式でプロパティctrl.monthに格納されます。フォームが出力される値と入力値のフォーマットは同じなので、これで最低限動きます。

ですが、モデル上はDate型として扱いたいですよね？入力値の文字列をパースしてDate型にし、また出力時に期待されるフォーマットに変換すればOKです。

1.0ではストリームになると思いますが、プロパティ互換のインタフェースを保ったまま、内部のデータをDateにするには次のようにします。

```js
    var _month = null;
    this.month = function(str) {
        if (arguments.length > 0) {
            _month = new Date(str);
        }
        if (_month) {
            return `${('000' + _month.getFullYear()).substr(-4)}-${('0' + (_month.getMonth() + 1)).substr(-2)}`;
        }
        return null;
    };
```

2016-12みたいな文字列はDateのコンストラクタに渡せば解釈してくれるので、特に難しいことはありません。

返り値の文字列にするのがちょっと厄介で、```toLocaleFormat()```が使えたらなぁ・・・でもこれ非標準でFireFoxじゃないと動かないし・・・という感じですね。6月(データ上は5)を表現する時は、1をたさないと行けないんですが、2016-6ではエラーになってしまうのでゼロをいれなければなりません。次のコードは0を頭につけた状態にするためのコードです。これで複雑に見えているだけでそんなに難しいことはしてません。

js```
('0' + (_month.getMonth() + 1)).substr(-2)
```

datetimeもサンプルをみてもらえればコードは見にくいけどまあやっていることは難しくないと思います。

Week
====

Weekはめんどうでやってないです。すみません。2016-W30という表記から、その週の先頭の月曜日を取得する必要があります。ちなみに、1/1が月曜日でない場合は、前年のW53となります。最初の月曜日から1週目が始まります。
tex原稿のスペルチェックについて

texで英文を書いていたら、先生に英文が酷すぎると怒られてしまったので、機械的にチェックできる部分については機械に投げることにしてみた。

スペルチェックについては、aspellを使うと良い

以下のどれかをコピペしてインストール

```bash:
$ pacman -S aspell
$ brew install aspell
```

こんな感じで使える。

```bash:
$ aspell --lang=en -t -c hoge.tex
```

-tはtexモードの意味。\textbfなどのtexのコマンドなどをスペルチェックの対象から外してくれる。
-cはチェックモードの意味。-c hoge.texでhoge.texのスペルチェックをしろという意味になす。
他の環境へのインストール方法など、texwikiの[記事](https://texwiki.texjp.org/?Aspell)も詳しい。

さらに文法チェックを行いたい場合は、languagetoolがある。ルールベースで文法チェックをおこなってくれる。
ただ、数学の場合、aとanの使い分けのチェックくらいしか実用にならなかった。
languagetool自体には、aspellのようにtexコマンドを無視する機能はない。
そこで、popplerのpdftotextを組み合わせると良い。

以下のどれかでインストール

```bash:
 $ pacman -S languagetool poppler
 $ brew install poppler languagetool
```

以下のように実行。

```bash:
 $ pdftotext hoge.pdf - | languagetool -l en-US -d WHITESPACE_RULE,MORFOLOGIK_RULE_EN_US,COMMA_PARENTHESIS_WHITESPACE,DOUBLE_PUNCTUATION,UPPERCASE_SENTENCE_START,EN_UNPAIRED_BRACKETS
````
(参考:https://texwiki.texjp.org/?%E8%8B%B1%E6%96%87%E6%A0%A1%E6%AD%A3)
ymlとviewと改行

viewでtableのヘッダを改行したいって思ったけど、
ymlでうまいこと対応できないか調べたらあったのでメモ


まずは結果から

``` ja.yml
  prev_paid_html: 先月<br>入金
```

``` hoge.html.slim
  th = t('.prev_paid_html')
```

これで無事表現できました

要点としては

- ymlで名前に'_html'を付けると、htmlタグを解釈してくれる

ということ

* * *

他に試したこと

``` ja.yml
  prev_paid: |-
    先月
    入金
```

``` hoge.html.slim
  th = t('.prev_paid')
```

yml内でのは改行はできているんだけど、表示するとスペースになっちゃうだけでした
WordPressでID・パスワード認証をできなくする

# はじめに
[Gianism](https://ja.wordpress.org/plugins/gianism/)でTwitter,Facebook, Google, Instagramといった外部サービスアカウントによるログイン機能を組み込んだので、ID・パスワードでの認証を禁止にしました。

ID/PASSWORD認証がなくなれば少しはセキュアになるかなと思い。

# functions.phpを編集

認証時のフィルターでパスワード入力があったらwp_dieしています。
priorityを1つ上げています。

```
add_filter( 'authenticate', 'myplugin_auth_signon', 9, 3 );
function myplugin_auth_signon( $user, $username, $password ) {
	if (!empty($password)) {
    wp_die( 'ID・パスワードでの認証はできません' );
	}
}
```

# 最後に

他に良い方法や、抜け道などありましたらご指摘いただけると幸いです。
Swift 3.0 の String の正規表現

Swift 3.0 の `String` にはこんなメソッドが定義されています：

```swift
range(of searchString: String, options: String.CompareOptions, range: Range<String.Index>?, locale: Locale?)
```

このメソッドを使って、`options` のところに `.regularExpression` を使えば、`searchString` で正規表現を利用した文字列（例えば `"Qi+ta"` とか）が使えます。便利。

ところがこのメソッドについて公式の資料がなく、一番近い資料なら一応 [`range(of:options:)`](https://developer.apple.com/reference/foundation/nsstring/1415073-range) と [`range(of:options:range:)`](https://developer.apple.com/reference/foundation/nsstring/1415073-range)、もしくは [`localizedStandardRange(of:)`](https://developer.apple.com/reference/foundation/nsstring/1413574-localizedstandardrange) の資料ならありますが、どれも戻り値が `NSRange` となっています。

しかし実際このメソッド書いてみると分かりますが、戻り値は `Range<String.Index>` と、Swift Foundation で定義された型となっております。`String` が実際文字管理に使っているインデックスなので `NSString` とか `NSRange` が介在せず[文字を扱うライブラリの違いによるインデックスの相違](http://qiita.com/takasek/items/19438ecf7e60c8d53bbc)もきにする必要がなくなる。

ただ問題は前述の通り、公式資料にはこのメソッドが載っておらず、また Xcode からでも該当メソッドの定義にはジャンプできない。自分ではまだ試してないがもしかするとこれはプライベート API の可能性もありますので、その場合は App Store に配布するアプリにはこのメソッドが使えないのでご注意を。（公式資料がまだ更新されてないってだけならいいんだけどな…）

==========================追記==========================
@woxtu さんのおかげで[公式資料](https://developer.apple.com/reference/swift/string/1642786-range)発見しました。これで安心して使えますｗ
GulpでS3のメタデータを一括更新

S3のメタデータを一括更新する方法は色々なやり方があると思いますが、今回はGulpを使う方法を紹介します。実際は、メタデータだけでなくオブジェクトのアップロード時にメタデータも一緒に更新する方法です。

gulpの基本的なインストールは省略します。ネットで調べてください :bow: 

まずは、S3にアップロードするのに必要なgulp-awspublishをインストールします 

```shell-session:command
$ sudo npm install gulp-awspublish --save-dev
```

gulpfile.jsを作成します

```shell-session:command
$ vim gulpfile.js
```

```js:gulpfile.js
var gulp = require("gulp");
var awspublish = require('gulp-awspublish');

gulp.task("deploy", function() {
    var key       = {
       accessKeyId: "【アクセスキー】",
       secretAccessKey: "【シークレットアクセスキー】",
       region: "【リージョン名　例）ap-northeast-1】",
       params: {
         "Bucket": "【バケット名】",
       }
    };

    var publisher = awspublish.create(key);
    var headers = {
        'Cache-Control': 'max-age=604800'
    };
    var options = {
        'force': true
    };

    gulp.src( "./build/**/*")
      .pipe(publisher.publish(headers,options))
      .pipe(publisher.cache())
      .pipe(awspublish.reporter());
});
```

```js:解説1
    var key       = {
       accessKeyId: "【アクセスキー】",
       secretAccessKey: "【シークレットアクセスキー】",
       region: "【リージョン名　例）ap-northeast-1】",
       params: {
         "Bucket": "【バケット名】",
       }
    };
```
S3にアクセスするのに、必要な情報を指定します。

```js:解説2
    var headers = {
        'Cache-Control': 'max-age=604800'
    };
```

- 今回指定したい、metaデータの内容です。
- max-ageに1週間後（604800）の値を設定しています。


```js:解説3
    var options = {
        'force': true
    };
```

- こちらはオプションの設定で、通常はfalseとなっており、オブジェクトの内容に変更がない場合はアップロードは行いません。
- **true**にすると、オブジェクトの内容に関係なく、強制的にアップデートします。
- オブジェクトの内容に変更がなく、メタデータを変更したい場合は**true**に設定しておく必要があります。
- 通常は、**false**もしくは**指定なし**でよいです。

```js:解説4
    gulp.src( "./build/**/*")
```

- ./build/以下には、S3にアップロードする画像とかJS/CSSなどが入っているものとします
- ./build/\*\*/*というbuild直下のファイルだけでなく、ディレクトリが何層あっても、再帰的に読みにいくということを表しています。
- build/*の場合は直下にあるファイルのみとなります。


ファイルの作成が終わったら、以下のコマンドで実行します。

```shell-session:command
$ gulp deploy
[hoge@huga gulp]$ gulp deploy
[11:23:13] Using gulpfile ~/gulp/gulpfile.js
[11:23:13] Starting 'deploy'...
[11:23:13] Finished 'deploy' after 93 ms
[11:23:13] [update] css/core.css
[11:23:14] [update] css/core_1.css
[11:23:14] [update] css/modal.css
[11:23:14] [update] css/n_pr.css
[11:23:14] [update] css/pc_append.css
[11:23:14] [update] css/pr.css
[11:23:14] [update] css/sns.css
[11:23:14] [update] css/sp.css
[11:23:15] [update] css/sp_1.css
[11:23:15] [update] img/bg1.png
[11:23:15] [update] img/bg2.png
```

S3を確認すると、すべてmetaデータにCache-Controlが設定されています。

![スクリーンショット 2016-12-20 15.50.03.png](https://qiita-image-store.s3.amazonaws.com/0/56914/77a2cb35-ecd3-f9e1-7426-9fca1921c8a0.png)

# まとめ
- S3のメタデータを１個１個、AWSコンソールで直すのは大変ですが、gulpを使えば、一括で変更することが出来ます。
- オプションのforceは通常はfalseにしておく
- trueにすると強制的にアップロードしてくれるので、オブジェクト自体は更新していないが、メタデータを更新したい場合に使えます。
【Progate体験談】Progateに出会ってプログラミングの面白さにはまった

※こちらの記事は、プロスタ編集部がプログラミングの学習法を公開することで、皆様のお役に立ちたい意図で投稿しております。

参考サイト：[【Progate体験談②】Progateに出会ってプログラミングの面白さにはまった](http://programming-study.com/case/progate-interesting/)

#【Progate体験談】Progateに出会ってプログラミングの面白さにはまった

Progate（プロゲート）でプログラミングを学んで、Webサイトを作った20代男性の体験談です。

##Progateに出会ってプログラミングの面白さにはまった

元々、私はパソコンを使うとしてもYoutubeやWord程度しか使っていなかったのですが、Progateに出会ってプログラミングの面白さにはまり、Wｅｂサイトの作成に至るまでのスキルを得ることができました。Progateは東大生が運営しているプログラミングの学習サイトです。

##「ソーシャルネットワーク」を見て、プログラミングを始める

そもそもなぜ私が、プログラミングを始めようと思ったのかというと、ある映画の影響です。それはフェイスブックの創業者であるマークザッカ―バーグの映画「ソーシャルネットワーク」です。大学受験が終わってからビジネスに興味が出始めてから色々な映画を見るようになりました。そこで見つけたのがソーシャルネットワークでした。フェイスブックはご存知のようにプログラミングを使って成り立っているもので、パソコン一つあればあんなに素晴らしいものができるのかと感銘を受けて勉強しようと思いました。

とはいえ、私はそれまでプログラミングはおろかタイピングすらまともにできなかったので、最初は自分にできるわけないと思い込み逃げていました。しかし、一年ほどたち、やはり本格的にやろうと決意し、まずはタイピングから練習し始めました。それから一カ月ほどでブラインドタッチを習得することができ、「意外とできるものだ」と自信がついたころにProgateに出会いました。

##HTML、CSS,jQueryを学んでWebサイトを作り上げた

Progateは、実戦形式の学習サイトでインプットしたらすぐにアウトプットができるので、これなら三日坊主にならずに続けられると思い、早速取り掛かりました。Progateは６種の言語を学べるので、まずは幅広く始めてそこからWebサイトのデザインをやりたいと思ったので、HTML、CSS、jQueryについて深く勉強していきました。

プログラミングで一番苦労したことは、やはり覚えることが多かったことです。よって、どの箇所でどの言語を使えばいいのか分からなくなることが多々あり、新しい言語の勉強を始めても壁にぶつかって、すでに勉強した言語に戻って復習するということの繰り返しでした。しかし、練習していくうちにタイピングが早くなっていき、何より自分のプログラミングのレベルが上がっていくのが実感できたので挫折せずに続けることができました。

Progateを使って３カ月ほどで基礎を学んだ後に、ネットで調べながら応用の勉強をして、大体トータルで７カ月ほどでWebサイトの外観を作れるようになりました。Progateは、無料でプログラミングの基礎を一通り網羅できることがとても魅力的です。また、最近ではさらなるレベルアップを目指す人向けに有料サービスを始めています。
Windows環境においてnpm-scripts経由でchokidar-cliが正常に動かない場合の対応

地味にハマったので、メモしときます。

## よくある npm script

`chokidar-cli` を使用して `src` 以下を監視し、変更があったら `npm run build` を実行したい、という場合

```json:package.json
"scripts": {
    "build": "browserify -t babelify src/index.js > dist/bundle.js --debug",
    "watch": "chokidar 'src/**' -c 'npm run build'"
},
```

↑のようなサンプルをよく見かけますが、Windowsだと上手く動きません。
シングルクォートが無視されるようで、`-c` で指定したコマンドを実行してくれません。

## 対応策

以下のように シングルクォートの代わりにエスケープしたダブルクォートで括るようにしてください。

```json:package.json
"scripts": {
    "build": "browserify -t babelify src/index.js > dist/bundle.js --debug",
    "watch": "chokidar \"src/**\" -c \"npm run build\""
},
```

`chokidar` に限らず、Windowsで `npm-scripts` を使用する場合は気をつける必要がありますね。
Cocoapods - どうしてもimport Realmできないとき

#初心者が陥りがちなターゲット

全ての設定が正しく行われている（はず）なのに

import Realmが読み込まれないときは

もしかしたらXcodeのターゲット設定が

正しくないことがあります

例えば下記のように、どう考えてもRealmあるじゃん！

って思うのに動かないときは

「ターゲット設定」を疑ってみてください

まあ、ターゲットに関しては

参考になるURLを貼っておきます

<img width="249" alt="スクリーンショット 2016-12-20 15.52.30.png" src="https://qiita-image-store.s3.amazonaws.com/0/135794/0a4bd8dd-576e-7515-c323-133f0ce4ee92.png">

#参考になるターゲットに関するサイト

ターゲットの作業をする
https://developer.apple.com/jp/documentation/ToolsLanguages/Conceptual/Xcode_Overview/CreatingApps/WorkingwithTargets.html
Visual Studio Subscriptionsがアクティベートできない場合

# Visual Studio Subscriptionsとは
MSDN付きのVisual Studioを購入すると付いてくるMSDNの部分。
テスト環境用の各種Windowsなどがおまけで付いてくるとてもお得な機能。

なのだが。。。

## Visual Studio Subscriptionsのアクティブ化に失敗する
MSDNの申請をすると以下のようなメールが届けられる。

> サブスクリプション情報:
> 名前: Your Name
> メール: mailaddr@your.domain
> サブスクライバー ID: NNNNNNNNN
> 有効期限: 12/05/2017
>
> サブスクリプションをアクティブ化  (→)

そしてこの「サブスクリプションのアクティブ化」のリンク先からアクティベートを促されるのだが、何回入力しても「サブスクリプション データを認識できません」とエラー表示が出てアクティベートが進まない場合がある。Visual Studio Subscriptions事務局に問い合わせたところ、以下のアドレス/フォームは実は「旧システムなので新システムに移行中(なのでダメかもしれない。)」との事。

## ダメな方のMSDN
[https://msdn.microsoft.com/subscriptions/add/default.aspx](https://msdn.microsoft.com/subscriptions/add/default.aspx)

(以下のフォームが出てくるのはダメな方)
> 名: 
> 姓: 
> 電子メール アドレス: 
> サブスクライバー ID: 
> 特典アクセス番号、サブスクライバー ID、または MPN 技術担当者 ID

## ダメじゃない方のMSDN
[https://www.visualstudio.com/ja/](https://www.visualstudio.com/ja/)
この新しい方のMSDN(Visual Studio Subscriptions ポータルサイトという名前らしい)に、アクセスして以下のステップで有効にする必要がある。

1. 画面右上のsign inをクリック
2. Windows系OSの場合などは別のMicrosoftアカウントが紐づいている場合があるので、「mailaddr@your.domain」が紐づいているアカウントでログイン
    3. mailaddr@your.domainに紐づいたMicrosoftアカウントが無い場合は新規作成して再度戻ってくる
    4. 既にmailaddr@your.domainに紐づいたMicrosoftアカウントがあるのに表示されていない場合は「別のアカウントを使用する」を選択
        5. メールアドレスを入力すると「パスワードを入力する前に」画面が遷移する場合がある
        6. 「mailaddr@your.domain」は複数のアカウントで使用されているようです。使用するアカウントを選択してください。と表示される場合は「職場または学校アカウント」か「個人のアカウント」のいづれか適切な方を選択する
7. Microsoftアカウントのログイン画面に遷移するので、mailaddr@your.domainでログインする
8. ログイン後は https://app.vsaex.visualstudio.com/ に遷移するので、画面左上の「Visual Studio」バナーをクリックする
9. https://my.visualstudio.com に遷移するので、「Subscriptions」を確認し、アクティベートされていることを確認する

これでVisual Studio Subscriptionsが有効になる。
(初回ログイン時に自動アクティベートされるため、メールで送られてくるサブスクライバーIDなどを入力する必要はないらしい。)

## おまけ
DownloadsにはSubscription特典一式が、Product KeysにはSubscription特典のプロダクトキーがある。
特典の有効期限については以下参照
[よくある質問 - 利用方法について](https://msdn.microsoft.com/ja-jp/subscriptions/dd197355.aspx)
CocosCreatorを使ってHelloWorld表示


#cocos2d-xのサイトからcocos creatorダウンロード
http://www.cocos2d-x.org/download

<img width="1186" alt="スクリーンショット 2016-12-20 14.19.34.png" src="https://qiita-image-store.s3.amazonaws.com/0/76290/9c42b868-bb4c-94b3-24d2-5ffdb5fb6f6b.png">

インストール後起動するログインが求められるので、あらかじめユーザ登録するといい
http://www.cocos2d-x.org/u/login

#起動
ログイン後ダッシュボードが表示される
NewProjectを選択して、「HelloWorld」を選択してプロジェクト作成する
![スクリーンショット 2016-12-20 14.28.44.png](https://qiita-image-store.s3.amazonaws.com/0/76290/6584dff4-0747-755d-2824-e9b8d8de3db0.png)

画面が表示される
左下のAssetsからSceneのhelloworldをクリック
![スクリーンショット 2016-12-20 14.00.59のコピー.png](https://qiita-image-store.s3.amazonaws.com/0/76290/539520fa-c2de-f49f-6bd3-592fc9e0572a.png)

すると中央のSceneの部分の表示が変わる
上の▶︎をクリックすると実行されてHelloWorldが表示される
![スクリーンショット 2016-12-20 14.01.17.png](https://qiita-image-store.s3.amazonaws.com/0/76290/d11c5452-f225-5d7e-1b90-c4164d054a95.png)

![スクリーンショット 2016-12-20 14.02.29.png](https://qiita-image-store.s3.amazonaws.com/0/76290/50ea623c-eefc-242d-dabb-edb6233e29fc.png)

#テキストを変更
ちなみに、テキストを変更したい時は右側のCanvasをクリックして、
右側表示されているPropertiesから変更することができる
![スクリーンショット 2016-12-20 14.05.59.png](https://qiita-image-store.s3.amazonaws.com/0/76290/fcb5752e-3f7e-fc22-1eaf-50ddfa5c23b9.png)

![スクリーンショット 2016-12-20 14.06.11.png](https://qiita-image-store.s3.amazonaws.com/0/76290/8f0a1440-a301-0a37-a4f3-dab76cc8d386.png)
XCode 8.2 にあげた場合は Titanium SDK 6.0.1 にあげましょう

[15日の記事](http://qiita.com/yagi_/items/d216c5ce2f454d5704f3) で @yagi_ さんが親切にも警告してくださっているように、XCode 8.2 にしてしまうと、Titanium SDK 6.0.0 以下では、iOS シミュレータへのインストールが失敗する状態になります。

```:ログ
[TRACE] ** BUILD SUCCEEDED **
[INFO]  Finished building the application in 16s 518ms
[INFO]  Launching iOS Simulator
[TRACE] [ioslib] Selected iOS Simulator: iPhone 7 Plus
[TRACE] [ioslib]   UDID    = B1E64A97-DC1C-482D-BA35-CCC66CFF1479
[TRACE] [ioslib]   iOS     = 10.2
[TRACE] [ioslib] Autoselected Xcode: 8.2
[TRACE] [ioslib] Tailing iPhone 7 Plus Simulator system log: /Users/hknoechel/Library/Logs/CoreSimulator/B1E64A97-DC1C-482D-BA35-CCC66CFF1479/system.log
[TRACE] [ioslib] Running: /Applications/Xcode-beta.app/Contents/Developer/usr/bin/simctl shutdown B1E64A97-DC1C-482D-BA35-CCC66CFF1479
[TRACE] [ioslib] iPhone 7 Plus Simulator was already shutdown
[TRACE] [ioslib] Running: /Applications/Xcode-beta.app/Contents/Developer/Applications/Simulator.app/Contents/MacOS/Simulator -CurrentDeviceUDID B1E64A97-DC1C-482D-BA35-CCC66CFF1479
```

上のログのように、ビルド成功後に、iPhone シミュレータの起動判定が出来なくなり、いつまでたってもアプリがインストールされない現象がおきてしまいます。

[cb1kenobi][cb1kenobi] によると、これは、XCode 8.2 で simctl というコマンドの挙動が今までと変わってしまったことが原因のようです。

![スクリーンショット 2016-12-20 14.41.45.png](https://qiita-image-store.s3.amazonaws.com/0/13825/a4272391-5ddd-98f1-1199-67e6bb7526cf.png)
from https://jira.appcelerator.org/browse/TIMOB-24136

現在はすでに、この修正を含んだバージョン 6.0.1 がリリース済みで、公式にアナウンスも出ています。

https://www.appcelerator.com/blog/2016/12/updating-to-xcode-8-2-and-sdk-6-0-1/

[![スクリーンショット 2016-12-20 14.46.49.png](https://qiita-image-store.s3.amazonaws.com/0/13825/d7985afa-85e5-3275-7a17-4e888cddbb6b.png)](https://www.appcelerator.com/blog/2016/12/updating-to-xcode-8-2-and-sdk-6-0-1/)

XCode 8.2 系以上にあげる場合、あるいは、うっかりあげてしまった場合は、上のアナウンスにしたがって、6.0.X 系最新の SDK をダウンロードをしてビルドするようにしましょう。(ちなみに自分の環境では、`6.0.1.v20161219165108` というバージョンがインストールされて、きちんと iPhone シミュレータへのアプリのインストールが成功できました :smiley: )

[cb1kenobi]: https://github.com/cb1kenobi
postass というツールを作った

postass というツールを作成したので紹介します

# postass

ポスタスと読みます
post + sass の造語です
Sass をコンパイルした後に 後処理(CSS の変換)を行うので、この名前をつけました

https://www.npmjs.com/package/postass
https://github.com/kanatapple/postass

# 作成した経緯

社内のエンジニアから「scssファイルを1個更新するだけでビルドが終わるのに8秒かかるので助けてください！」と依頼が来たので、[この記事](http://qiita.com/joe-re/items/542b3f6fdc577cf50509)とか参考にいろいろ試したんですが、自分の環境ではなぜか高速化できませんでした
さらに、コンパイルした後に CSS に変換をかけたい(ベンダープレフィックスの付与、URL書き換えなど)という要望もあったので、「それなら、そういうツール作っちゃおう」と思ったのがきっかけです
(ちなみにこのツールを使うことで、ビルド時間が8秒 -> 0.x秒になり、残業時間も減ったそうですｗ)

# 特徴

- Sass(sass/scss) のコンパイル
- ファイル変更を検知し差分ビルド  
(ファイルの追加・削除もちゃんと検知。node-sass はこの辺がちゃんと動いてない？)
- PostCSS のプラグインが使用できる  
(現在はハードコーディングしているもののみ)
- コマンドライン、JavaScript からの使用が可能

# 使い方

## インストール

```bash
$ npm install postass
```

## JavaScript から

```js
var postass = require('postass');
postass.render({
    file: src
    [, options]
}, function(err, result) {
});
```

`postass.render` を呼ぶことで、Sass ファイルを CSS にコンパイルします
options に各種設定を渡すことができます
設定内容の詳細は[こちら](https://github.com/kanatapple/postass#options)

## コマンドラインから

コマンドラインからの使用も可能です

```bash
$ postass [options] <input.scss>
```

options に直接引数を渡すこともできますが、config ファイルで指定することも可能です
引数の内容は[こちら](https://github.com/kanatapple/postass#options-1)

config ファイルは json フォーマットで、コマンドラインに渡す引数を CamelCase にしたものです
(`postass.render` に渡す options と一緒)

# 今後の予定

今後の予定ですが、下記のようなことを考えています

- ES201x の形式で書き直す
- PostCSS のプラグインを動的に設定できるように
- テストの追加

---

初めての OSS ということもあり、いろいろ考慮できてないことが多いかもしれません
その点はご了承ください

初めて公開するというハードルは超えられたので、これからもいろいろなツールを出していきたいと思います
SORACOM × LoRaWAN実証実験中

こんにちは、SORACOM BDの大槻です。
LoRaWANやってみた系はウフル様やクラスメソッド様にBlogを書いて頂いているので、
今回はそもそもLoRaWANって何のご紹介をしたいと思います。

#LoRaWANって何だ？
みなさんLoRaWANってご存知でしょうか？
ここ半年くらいでよく耳にするようになったIoT向け無線通信規格の1つです。
一般的にはLPWAのカテゴリの1つに分類されています。
LPWA=Low Power Wide Areaの略称なので、
要するになるべく消費電力を抑えて遠くに飛ばしちゃおうという規格です。
LPWAは大きくライセンス系とアンライセンス系に分かれており、
ライセンス系は無線局免許が必要、アンライセンス系は不要になります。
前者は既存の携帯事業者さんのように総務省さんから包括免許を取得して運用しますが、
後者は不要なので比較的簡単に運用ができるんですね。LoRaWANやSIGFOXはこちらに入ります。
（"免許不要"と聞くと、よくじゃあ技適が要らないんだね！とたまに誤解される方がいらっしゃるのですが、
無線機器としての技術適合取得は全く別の議論なのでもちろん取得必須です）

![image](https://qiita-image-store.s3.amazonaws.com/0/121548/12e37061-ac92-a1cd-1455-fa0bf73419b5.png)
また、アンライセンスと言えど日本では920MHz帯域のARIB規定(T108)に準じた実装、運用が必要です。
具体的には以下について、規定範囲内で実装する必要があります。
・無線出力（空中線電力）:特定小電力無線局だと20mW以下
・周波数チャネル、帯域幅:LoRaWANの場合920.0~928.0MHz / 200kHz
・キャリアセンス:128μs以上
・送信時間制限:400msec以下
・送信休止時間:送信時間の10倍

##特徴
LoRaWANに関しては送信距離10~20kmくらい、送信時の電力は20mAくらい(待機時はさらにその1/100）なので、
低消費電力のBLEに比べて距離は100倍以上、
広域通信できる携帯電話に比べて1/10くらいの消費電力を実現できるわけです。
※現状日本で使える最大無線出力=20mWだと実測では1.5~6kmくらいになります。
　　もちろん海岸線等で飛ばせば10km以上も測定はできますが上記は各地フィールド試験を踏まえた値です。

ただしスループットは非常に低いので、低容量のデータを少しずつ送るのに向いています。
温度、湿度、加速度など各種センサーであれば数バイト程度ですし、
最近Amazonさんから出たDash Buttonなんかも面白いですね。
LoRaWANはIoT特化規格なので通信のスタートは基本的にUpliinkからスタートなのですが、
ACKを返したり、ピギーバック的にアプリケーションからのDownlinkの通信を行ってもOKです。
（ほかにもPaging的な方式等もあるのですが、詳しく知りたい方はLoRaWAN specご参照ということでw）

![image](https://qiita-image-store.s3.amazonaws.com/0/121548/38ad2f4b-4fbb-840e-7cb8-ff8f7ad97b1f.png)

##アーキテクチャ
アーキテクチャとしてはこんな感じになっていて、
主にModule-Gateway-Network Serverという３部で構成されています。
よくWiFiのようにModuleとGateway(基地局)だけあれば使えるイメージを持たれている方が多いのですが、
実際にはNetwork serverというコアネットワークがパケットのルーティングや
データの暗復号等を処理しており、ここを各ネットワーク提供事業者が管理しています。

![image](https://qiita-image-store.s3.amazonaws.com/0/121548/9f6e7fcb-c6e6-33e2-0e06-79c01f36a38f.png)

##Why SORACOM?
LoRaWANだけだとModuleに対してWireless Connectivityを提供しているだけなので、IoTではなくM2Mで終わってしまいます。
そのため、ソラコムではLoRaWANのNetwork Serverに既存のSORACOM Beam/Funnelを適用することで、LoRaWANでもHTTP(S)ベースで各種クラウドやオンプレサーバーと連携できるようにしました。

![image](https://qiita-image-store.s3.amazonaws.com/0/121548/068456be-8ba1-3a56-f6d8-4845997338e5.png)

こうすることで、Module側で取得したデータをクラウドまで送信→蓄積・可視化・各種アプリケーション連携ができるようになり、 簡単にE2EでセキュアなIoTを実現できます。
できるだけWireless agnosticに使って頂けるよう設計しているのもソラコムのポイントの１つです。

##いつからサービスやるの？
この夏からPoC(Proof Of Concept)として都内はもちろんのこと、全国各地で実証実験を進めています。
かなりデータも集まってきたので来年はいろんな発表ができると思います。乞うご期待ください！

#お問い合わせはこちらまで
https://soracom.jp/lorawan/
【Tips】Vagrant / VirtualBoxをバージョン指定でインストール

おもむろに以下のコマンドを実行しましょう。
URLは自分がインストールしたいものに置き換えてくださいね。

Vagrantの場合

```bash
$ curl -L -O https://releases.hashicorp.com/vagrant/1.9.1/vagrant_1.9.1.dmg 
$ hdiutil mount vagrant_1.9.1.dmg
$ sudo installer -pkg /Volumes/Vagrant/Vagrant.pkg -target /Volumes/Macintosh\ HD
$ hdiutil unmount /Volumes/Vagrant/
$ rm vagrant_1.9.1.dmg
```

VirtualBoxの場合

```bash
$ curl -L -O http://download.virtualbox.org/virtualbox/5.1.10/VirtualBox-5.1.10-112026-OSX.dmg
$ hdiutil mount VirtualBox-5.1.10-112026-OSX.dmg
$ sudo installer -pkg /Volumes/VirtualBox/VirtualBox.pkg -target /Volumes/Macintosh\ HD
$ hdiutil unmount /Volumes/VirtualBox
$ rm VirtualBox-5.1.10-112026-OSX.dmg
```
PHP .inc拡張子ファイルetcファイルを複数に分けるとソースがすっきりする

#ソースの整理
[わかりやすいサイト](http://wa3.i-3-i.info/word12025.html)

###設定ファイルを作る　→拡張子(.inc)
1.都道府県の配列、お問い合わせの配列、ご希望の連絡方法の配列を定義するファイルを生成する
2.そのファイルをcontact.php、confirm.php、thanks.phpの先頭でincludeする
　(ただしsession_start関数の後でincludeすること)
ソースがすっきりする上に修正があった場合楽になります

・関数のファイルを作る
設定ファイルを作ると同じです

・その他
処理するファイルと表示処理を行うファイル(テンプレート)を分けて作成する
フォームチェックだけを行うファイルを作成し、エラーチェックはそのファイルで行う
メールを送信するファイルを作成し、メール送信はそのファイルで行う

##拡張子incの設定ファイル

↓先輩が教えてくれたこと

-------------------------------------------
・配列を定義するファイルの件
これは拡張子を.incなどにした方が良いと思います
後ディレクトリを一つ作り、その中にdata.incとして保存したほうが良いと思います
(ディレクトリ名、拡張子は自由です)

作成したディレクトリ名を「conf」ファイルの拡張子を「.inc」とした場合

data.incに関してはセッションを空にする等の処理は不要です
これはWEBサーバーの設定で「conf」ディレクトリを制御します
今は気にしなくて良いです

ディレクトリ構成の例
conf━data.inc   ←配列等が記述されいる
┣ form.php      ←入力画面
┣ formCheck.php ←エラーチェックページ
┣ confirm.php   ←確認画面
┗ thanks.php    ←メール送信・完了画面

まず「http://192.168.1.30/~/data.inc」にアクセスしてみてください
おそらくdata.incの中身がテキストとして出力されると思います

次にdata.incをconfディレクトリにコピーし、「http://192.168.1.30/~/conf/data.inc」にアクセスしてみてください
※confディレクトリは私が作成しました。.htaccessというファイルは削除しないでください
おそらくブラウザが403エラーを返すと思います

confディレクトリの.htaccessというファイルで外部からのアクセスを不可するという設定をしてあります
当然ですが、PHPからはアクセスは可能です

.htaccessの中身はPHPと無関係であり、WEBサーバーの設定となるので今は気にしなくて良いです

問題点
悪意のあるユーザーが推測で「http://192.168.1.30/~takahashi/data.inc」にアクセスした場合
data.inc(設定ファイル)の中身ブラウザ上に出力されると、大問題になります
このファイルの中身がDBのID、パスワードなどの場合は本当に洒落にならなくなります


作業手順
/home/~/public_html/data.incをconfにコピーする
↓
各プログラムの以下の部分を修正
include 'data.inc';        →        include 'conf/data.inc';
↓
動作確認
↓
/home/~/public_html/data.incを削除

-------------------------------------------
adbコマンドでブラウザを立ち上げてURLを開く

例えば自分の開発マシンのIPアドレスが192.168.10.100だったとして、ポート3000でローカルWebサーバーが動いているとして、以下のコマンドを叩くとAndroid端末でブラウザが立ち上がって開発機のWebサーバーにアクセスしてくれる。

    adb shell am start http://192.168.10.100:3000

Android端末で長いURL入力するのがめんどくさい時にぜひ。

別に開発機のローカルWebサーバーでなくても、通常のWebページでも開けます。

    adb shell am start https://github.com/

Webサイト以外のURIスキームでも開けます。

    adb shell am start ovrweb:https://aframe.io/examples/showcase/sky/

↑[Carmel Developer Preview](https://www.oculus.com/experiences/gear-vr/1290985657630933/)でA-FrameのWebVRサンプルを開く例
画像をJavaScriptを使わずにいい感じのサイズで表示した話

# やりたいことはオリジナルサイズを200×200に内接リサイズしたい

<img width="384" alt="スクリーンショット 2016-12-20 13.21.51.png" src="https://qiita-image-store.s3.amazonaws.com/0/82745/d2f8ed3c-4768-4426-732c-f22b10102d45.png">

<img width="401" alt="スクリーンショット 2016-12-20 13.22.01.png" src="https://qiita-image-store.s3.amazonaws.com/0/82745/d39c915f-06aa-7b3a-aade-860f5277e119.png">


# はじめに

CSSのobject-fitってプロパティを適応しただけの話になるのですが、今まで画像のサイズを縦長なのか横長なのかによって縦に合わせて内接リサイズを行って来ました。具体的にやり方を上げると下記のようなことをしていました。

* JavaScriptで画像のサイズを適当に取得
* 縦から横の長さ引く
* 負のあたいかどうかで横長用のclass当てるか縦長用のclass当てるか決定
* JavaScriptでclass追加する

絶対無駄なことしてるCSS3ってすげーって聞いたし調べたらできるでしょ！

# 5分後

https://developer.mozilla.org/ja/docs/Web/CSS/object-fit

> CSS の object-fit プロパティは、置換要素の内容物を、自身が使用する高さおよび幅によって形作られるボックスへどのようにはめ込むかを指定します。

これじゃん!
というわけでサンプルを作ってみる
サンプル用の画像は[Placehold.jp](http://placehold.jp/)というサイトを使って生成しています。
めっちゃ便利なのでちょいちょい使わせてもらってます。ありがとうございます！
利用規約見たら神なのかしら？って思うほど優しさに溢れてます。(twitter見たら一日10万ぐらいは余裕で画像生成してるみたい)

# サンプルコード

```html:index.html
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>sample object fit</title>
    <link rel="stylesheet" type="text/css" href="main.css">
</head>
<body>
  <div>
    <h2>オリジナルサイズ</h2>
    <p>320×240サイズ<p>
    <img src="http://placehold.jp/320x240.png">
    <p>240×320サイズ<p>
    <img src="http://placehold.jp/240x320.png">
  </div>

  <div>
    <h2>200×200に内接リサイズした場合</h2>
    <p>320×240サイズ<p>
    <img class="contain" src="http://placehold.jp/320x240.png">
    <p>240×320サイズ<p>
    <img class="contain" src="http://placehold.jp/240x320.png">
  </div>
</body>
</html>
```

```css:main.css
.contain {
    object-fit: contain;
    width: 200px;
    height: 200px;
    background-color: #aaa;
}
```

# 注意点

対応ブラウザを確認しておく必要ありますよね？
http://caniuse.com/#search=object-fit

IE?Edge?知らない子ですね。。。


# まとめ

JavaScriptのコード捨てた。外接リサイズもcontainをcoverに変更するだけ。
主要なブラウザは対応しているみたいなので問題がない場合はCSSのみで内接リサイズしてしまいましょ！
Sassで色相環24色の色彩調和パターンを作ってみる

配色を調べてると「マンセル色相環」「PCCS色相環」「オストワルト色相環」...と色相にもいくつか種類があって奥深さに慄きます。
ここではPCCSの調和配色に基づき、色相差による調和配色パターンを`@function`を使って作ります。

## 6つの色彩調和
色相環を24等分割し15度を色相差１としたときの調和形式（でいいのか？語彙に自信がない）
[PCCSを用いた色彩調和の形式](http://www.sikiken.co.jp/pccs/pccs05.html) - 財団法人日本色彩研究所

- **隣接色相**: 色相差1 (+-15deg)
- **類似色相**: 色相差2,3 (+-30deg, +-45deg)
- **中差色相**: 色相差4,5,6,7 (+-60deg,+-75deg,+-90deg,+-105deg)
- **対照色相**: 色相差8,9,10 (+-120deg,+-135deg,+-150deg)
- **隣接補色色相**: 色相差11 (+-165deg)
- **補色色相**: 色相差12 (180deg)


## function

まず色彩調和の色をリストにします。
基準色を`$color`に、出したい色相差1-12を`$arg...`の可変長引数にいれます。

```scss
@function ColorHarmony($color, $arg...) {
  $slice: 24;
  $part: 360deg / $slice;
  
  $diffs1: ();
  $diffs2: ();
  @each $j in $arg {
    $diffs1: append($diffs1, $part * $j, comma);
  }
  @each $k in $arg {
    $diffs2: join(360 + (- $part * $k) , $diffs2);
  }
  $diffs: join(0, join($diffs1, $diffs2));
  
  $colors: ();
  @each $i in $diffs {
    $val: append($val, adjust-hue($color, $i), comma);
  }
  @return $colors;
}
```
色の並び順を綺麗にしたかったので、プラス値とマイナス値で分けてます。
面倒くさいことになってます。

次にリストから特定の色を指定できるようにします。
色相差も1-12と決まってるので一まとめにしたいのですが、
可変長引数使ってるせいで目が滑るため、人間が扱いやすいように２段階に分けました。

```scss
// 隣接色相:色相差1(+-15deg)
@function adjacentColor($color,$nth:null){
  $val: ColorHarmony($color,1);
  @return if($nth == null, $val, nth($val,$nth));
}

// 類似色相:色相差2,3(+-30deg, +-45deg)
@function analogyColor($color,$nth:null){
  $val: ColorHarmony($color,2,3);
  @return if($nth == null, $val, nth($val,$nth));
}

// 中差色相:色相差4,5,6,7(+-60deg 〜 +-105deg)
@function intermediateColor($color,$nth:null){
  $val: ColorHarmony($color,4,5,6,7);
  @return if($nth == null, $val, nth($val,$nth));
}

// 対照色相:色相差8,9,10(+-120deg 〜 +-150deg)
@function contrastColor($color,$nth:null){
  $val: ColorHarmony($color,8,9,10);
  @return if($nth == null, $val, nth($val,$nth));
}

// 隣接補色色相:色相差11(+-165deg)
@function split-complementaryColor($color,$nth:null){
  $val: ColorHarmony($color,11);
  @return if($nth == null, $val, nth($val,$nth));
}

// 補色色相:色相差12(180deg)
@function complementaryColor($color,$nth:null){
  //ここは+-一緒だからcomplement($color)で。
  $val: $color,complement($color);
  @return if($nth == null, $val, nth($val,$nth));
}

// color: intermediateColor(#d39);
// -> #d39, #d73, #dda233, #dc3, #c4dd33, #336edd, #34d, #4c33dd, #73d
```
https://jsfiddle.net/32fw8fog/7/
![d9abd210-5f9d-a394-bfda-52686b7c2bd7.png](https://qiita-image-store.s3.amazonaws.com/0/54497/abe44d17-dc9f-2ca7-96b2-201286f0582f.png)


円周配置したい。三角比どうしよう。

# 感想
- 空の変数作れた！！！ `$diffs1: ();` 
    - 知らなかった。クソコードしか書けなくても数こなせば得るものがあるんだなあと。
- 色の濁りが気になる。次はトーンの調整できないかやってみる。
MySQL WorkbenchのVisual Explainでのみ出てくるaccess typeの話

この記事は [MySQL Casual Advent Calendar 2016](http://qiita.com/advent-calendar/2016/mysql-casual) の20日目です。

# tl;dr

- explainはjsonで出そう
- MySQL WorkbenchのVisual Explainだとjsonを元にいい感じにビジュアライズしてくれる
- Visual Explainでのみ出て来るアクセスタイプがあるけど、単なる別名なだけな模様

# 概要

MySQL5.6からjson形式でexplain結果を出力できるようになりました。
jsonで出すことで表形式より多くの情報が得ることができます。

例えば「used_key_parts」は選択されたindexのどこまでのkeyを使ったかがわかります。
表形式だけだとkey_lengthから推測していたのが、カラム単位でわかるのでカーディナリティの低いkeyが無視されたなどもすぐわかります。

```SQL
EXPLAIN FORMAT=JSON SELECT * FROM tmp_db.user_tbl WHERE hoge_column = 5 AND var_column = 10;

----略
    "key": "index_hoge_var",
    "used_key_parts": [
      "hoge_column",
      "var_column"
    ],
----
```

さらに[MySQL Workbench](https://www-jp.mysql.com/products/workbench/)のVisual Explainを使えばjsonを元に実行計画をいい感じにビジュアライズしてくれます

# MySQL WorkbenchのVisual Explain

![explain_1.png](https://qiita-image-store.s3.amazonaws.com/0/5219/89b0edc9-710b-f3a6-1a17-cdc8b6316065.png)

Visual ExplainはExplainなしの通常のクエリから虫眼鏡のボタンを押すだけで実行できます。
表示されたboxに上にカーソルを合わせることで詳細なデータも見ることができます。
joinした場合などでも利用できてとても理解しやすくオススメです。

# Non-Unique Key Lookupとは？

Visual Explainではボックスにアクセスタイプが表示されます。
上の画像のように「Index Range Scan」などはほぼ表形式と同じなのですが、「Non-Unique Key Lookup」など微妙に聞き慣れない文言が表示されることがあります。

![explain_2.png](https://qiita-image-store.s3.amazonaws.com/0/5219/76efcf5e-9a03-327a-a28d-a91757e1fd4c.png)

ドキュメントを見てみると、これはExplainから得られるアクセスタイプに対するMySQL Workbench側の別名のようです。

[Visual Explain Plan](https://dev.mysql.com/doc/workbench/en/wb-performance-explain.html)
 
> Non-Unique Key Lookup -> REF
> Index Range Scan -> RANGE

それぞれの対応はドキュメントをご確認ください。
どっちか統一してくれればいいのになんて思わないこともないですが、、、
アクセスタイプそれぞれのコストの目安なども同時に表示されるので親切！
  
  

明日の MySQL Casual Advent Calendar 2016 は[atsuizo](http://qiita.com/atsuizo)さんです！
SSH設定あれこれ

恥ずかしながらいつも忘れてググるのでメモします。
もっと良い設定とかあれば知りたい。

```sh
$ cd ~
$ chmod 700 .ssh
$ cd .ssh
$ chmod 600 authorized_keys
$ sudo vim /etc/ssh/sshd_config
```

```txt:/etc/ssh/sshd_config
PermitRootLogin yes
-> PermitRootLogin no

#AuthorizedKeysFile     %h/.ssh/authorized_keys
-> AuthorizedKeysFile     %h/.ssh/authorized_keys

#PasswordAuthentication yes
-> PasswordAuthentication no 
```

authorized_keysはまあなんとかするとしてこんな感じだろうか。