OmniAICreator/Qiita-1.07M huggingface dataset:
Gem 'Gimei'

# Gimeiとは
日本人の名前やフリガナ、住所などを自動生成してくれるGem。
有名なGemでFakerがあるが、Fakerでは対応できないフリガナを使うことができる。
[Gimei](https://github.com/willnet/gimei)

## 使い方
開発環境とテスト環境で利用するのでgroup :development, :test doの内部でgemを指定、Gemfileを編集したらアプリケーションのディレクトリでbundle installを実行。

```ruby:Gemfile
group :development, :test do
  # 省略
  gem 'rspec-rails'
  gem 'factory_bot_rails'
  gem 'faker'
  gem 'gimei'
end
```


コンソールで実行するとこんな感じで名前が生成される。

```zsh:console
[1] pry(main)> japanese_user = Gimei.name
# 省略
[2] pry(main)> japanese_user.last.kanji
=> "島村"
[3] pry(main)> japanese_user.last.katakana
=> "シマムラ"
```


FactoryBotと組み合わせて架空のユーザーを生成する。
インスタンスを生成せずに`Gimei.name.first.kanji`などを入れると、名前とフリガナが一致しなくなる。

```ruby:factories/users.rb
FactoryBot.define do
  factory :user do
    # インスタンスを生成
    japanese_user = Gimei.name

    first_name { japanese_user.first.kanji }
    first_name_kana { japanese_user.first.katakana }
    last_name { japanese_user.last.kanji }
    last_name_kana { japanese_user.last.katakana }
  end
end
```
```zsh:console
[1] pry(main)> FactoryBot.create(:user)
# 以下実行結果が表示される。
```
”ARでキャラクターに現実の空間を歩かせたりするの呼吸、自己脅迫の型 with ML” を書こうとしましたがまだ何もできていません。代わりにMagicLeap UnityPackage 0.24.2の注意点を書いておきます。

#はじめに

この記事はMagic Leap Advent Calendar 2020の25日目です。

記事の内容がまだ白紙です。ごめんなさい。後述の理由で止まってました。恥ずかしい。
これから関係ある（？）ことをちまちま書いていきます。

#自己脅迫の型
##今年のうちにはタイトル通りの内容にします！！
これは宣言です！この宣言こそ"自己脅迫の型"です！
こうしないとまだ手についてない職は何もできない！！

#/* お　ま　け　（になればいいな） */

##◎MagicLeap UnityPackage 0.24.2はUnity2019に使えない！！！！
MagicLeapのアプリをUnityで制作するには専用のSDKとUnityPackageが必要です。2020年12月、Lumin SDK の最新は0.24.1ですが、MagicLeap UnityPackageの最新は0.24.2です。これはUnity2020への対応をしたUnityPackageとされています。

じゃあ最新版を使えばいいじゃん？別にグループでやっているプロジェクトでもないし。
私もそう思っていました。しかし、使っているUnityがUnity2019の場合は注意が必要です。

こちらがUnityPackage 0.24.2を使用したプロジェクト(Unity 2019.3.6f1)のConsoleです。
![NIGHTMARE.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504313/18352f88-8a0d-c908-49d1-9a20faa3ec10.png)
なにやらエラーが出ています。全部「スクリプトで呼び出している特定の関数が見つからない！」というエラーです。
えらいこっちゃ。何をしても解決しません。スクリプトを探してもおかしなところはないし、それどころか、*MagicLeap UnityPackageから出てきたファイルには、まだ何も触れていないのです*。
おかしい。

ここで私は気づくべきでした。MagicLeap UnityPackage **0.24.2**には
**後　方　互　換　が　な　い　ら　し　い　？　？　？　！　！　！　:scream: :scream: :scream: :scream: :scream: :scream:**

そういうことでした。これでだいぶ長いこと作業が止まっていた自分があまりにも恥ずかしい。

早速Unityを閉じて

```
Asset/MagicLeap
```

をエクスプローラーで削除します。
そしてMagicLeap UnityPackage **0.24.1**をインポートします！<details><summary>0.24.2にしちゃったらやり直しですっ！</summary>もうこんな目はいやだ～～</details>

そしたらこのようにエラーが解決します。
![NIGHTMARE2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504313/5e7c97c7-5b17-ffe5-3d16-0f2ab8adcfd1.png)
また別のエラーが発生していますが、実行はできますのでここでは無視します。<details><summary>一応、</summary>そのエラーに関するものがこのページの本題になるはずだった話題に関連します。</details>

付随して、最新ではないUnityPackage 0.24.1をインストールする方法をお伝えします。
いつもLumin SDKなどなどをインストールしているように

```
The_Lab > Project Manager
```

ここでUnityにチェックをいれて[Apply Changes]するのではなく、

```
All > Unity@ Packages > MagicLeap Unity@ Package > Available Version(s):▢
```

を選択します。すると過去のバージョンが選べるので ***0.24.1*** を選択して[ ↓ ]を押して[Apply Changes]しましょう。
あとは

```
C:Users\(User)\MagicLeap\tools\unity\v0.24.1\MagicLeap.unitypackage
```
を目的のUnity2019プロジェクトにインポートしましょう。これで問題なくLeaperライフが送れます！！

<details><summary>***結論、Unity2019でMagicLeapアプリを開発するときはMagicLeap UnityPackage 0.24.1を使いましょう。***</summary>MagicLeap UnityPackage 0.24.2はUnity2020専用と捉えた方がいいかもしれません。</details>

以上になります。
実体験のうっかりミスなのでとってもしつこくねちっこく書いてあります。本当に申し訳ございません。


#まだまだUnity経験の薄い素人の体験談になりますので、間違っているところがあればお気軽に教えてください。ご一読本当にありがとうございました。
VRChatでは *FallenAngelRK* というIDで活動しています。良ければお友達になって下さい。そしてUnity教えて下さい。
swift基礎　UITextfieldsをLabelに表示する.

#### 0.完成イメージ

https://twitter.com/kou09010901lam1/status/1334101860261662720?s=20

####1. コード

#####DeleteButton()
     player1.removeAll()
        player2.removeAll()
        player3.removeAll()
        player4.removeAll()
        player5.removeAll()
        player6.removeAll()
        JL.text = "参加者"
        JL6.text = "参加者"
        JL2.text = "参加者"
        JL3.text = "参加者"
        JL4.text = "参加者"
        JL5.text = "参加者"
        NameCount = 1

#####JNNADDButton()

       @IBAction func JNADDButton(_ sender: UIButton) {
              if  NameCount == 1 {
        NameCount = NameCount + 1
                JL.text = JNtext.text
                player1 = JNtext.text!
              }
         else if  NameCount == 2 {
                NameCount = NameCount + 1
                JL2.text = JNtext.text
              player2 = JNtext.text!
              }
         else if  NameCount == 3 {
               NameCount = NameCount + 1
                JL3.text = JNtext.text
                player3 = JNtext.text!
              }
          else if  NameCount == 4 {
              NameCount = NameCount + 1
                JL4.text = JNtext.text
                player4 = JNtext.text!
              }
          else if  NameCount == 5 {
               NameCount = NameCount + 1
                JL5.text = JNtext.text
                player5 = JNtext.text!
              }
         else if  NameCount == 6 {
                NameCount = NameCount + 1
                JL6.text = JNtext.text
                player6 = JNtext.text!
              }
        JNtext.text = ""
            }

####2.解説
1~6番までのラベルに表示するためには、Namecountで処理を6回分けることによって、実現しました。
.removeALLは削除のメソッドです
textFieldsはAnyで宣言します。actionで宣言すると、外からの処理がなぜかめんどくさかったのでやめました（何故だ？？？






####3.関連記事

[Qlita]
[Qlita]
[Qlita]
[Qlita]

####4.最後に
ラベルの文字数に制限があって文が省略される！とか細かいところは
attributes inspecter（右側のメニュー
をむちゃくちゃにいじると何故か改善し始める。などもあったので調べる前に全部いじってみる！を心がけました笑
Vue + dart-sass + Webpack でCSSモジュールを使うため設定

# アップデート

- 2021.12.11
  - fibersが非推奨になったので該当箇所消しました。
- 2021.3.7
  - 現在、cssModulesがここに書いた設定だと使えなくなっています。やり方がわかりましたら追記します。


# cssModules のオプション記述位置が違った

[公式に書かれた設定](https://vue-loader-v14.vuejs.org/ja/features/css-modules.html)だけだと css modules が実現できなかったので調べたところ、[Vue Loader v15 から色々変わった](https://vue-loader.vuejs.org/migrating.html#notable-breaking-changes)模様。
Vueのルール部分ではなく、CSSのルール部分に書くようです。

参考：[$style is undefined when I used &lt;style lang="scss" module&gt;](https://github.com/vuejs/vue-loader/issues/771)


# せっかくなので dart-sass に乗り換える（2020.12.18追記）

これまで node-sass を使っていたのですが、いい機会だから dart-sass に乗り換えます。
dart-sass のnpmは `sass` です。

```shell
$ yarn add -D sass
```



## 以前の設定

webpack.config.js の設定から cssModules を使う前のcssとscssの部分を抜粋しました。

```js
{
  module: {
    rules: [
      {
        test: /\.scss/,
        loader: 'vue-style-loader!css-loader!sass-loader',
      },
    ],
  }
}
```

## 変更後の設定

```js
{
  module: {
    rules: [
      {
        test: /\.scss/,
        use: [
          {
            loader: 'vue-style-loader',
          },
          {
            loader: 'css-loader',
            options: {
              // cssModules を使うために必要な設定
              modules: true,
            },
          },
          {
            loader: 'sass-loader',
            options: {
              // dart-sass を使うのに必要な設定
              implementation: require('sass'),
# fibers は非推奨になりました
#              sassOptions: {
#                fiber: require('fibers'),
#              },
            },
          },
        ],
      },
    ],
  }
}
```

## Vueとcss部分の抜粋

```js
{
  // 省略
  module: {
    rules: [
      {
        test: /\.vue$/,
        use: [
          {
            loader: 'vue-loader',
            options: {
              loaders: {
                js: 'babel-loader',
              },
            },
          },
        ],
      },
      {
        test: /\.scss/,
        use: [
          {
            loader: 'vue-style-loader',
          },
          {
            loader: 'css-loader',
            options: {
              // cssModules を使うために必要な設定
              modules: true,
            },
          },
          {
            loader: 'sass-loader',
            options: {
              // dart-sass を使うのに必要な設定
              implementation: require('sass'),
# fibers は非推奨になりました
#              sassOptions: {
#                fiber: require('fibers'),
#              },
            },
          },
        ],
      },
    ],
  },
}
```

webpack.config.js がどんどん長くなりますねｗ

# コンポーネント内での記述

## style の記述

こんな感じ。

```vue
<template>
  <div :class="$style.foo">hogehoge</div>
</template>

<style lang="scss" module>
.foo {
  background-color: rgba(#000, 0.6);
}
</style>
```

## 動作確認

`this.$style` に格納されているので `console.log()` で確認できます。

```vue
mounted(){
  console.log('style', this.$style);
}
```

## cssModules 以外の class も併用する

cssModules、クラス名の文字列、クラス名の入った変数を併用するなら配列で渡します。

```vue
<template>
  <div :class="[$style.foo, 'class-name', myClass]">
    hogehoge
  </div>
</template>
```
世界で最も強力な九つのアルゴリズム　鍵交換アルゴリズム


-----------
>######私たちにはほんのわずか先しかみえないが、しなければならないことがたくさんあることはわかる
>アランチューリング 


-----------
####0.はじめに
重要だと思う、部分だけをざっくり紹介しておきます。


####1.紹介された９つのアルゴリズム


- 検索エンジンのインデクシング
- ページランク
- 公開式暗号法
- 誤り訂正符号
- パターン認識
- データ圧縮
- データベース
- デジタル著名
- 決定不能性

この九つに関連するアルゴリズムがこの本では紹介されています。

今回はその中でも公開式暗号化について詳しく書いていきます。
####2.暗号化と複合化

>「暗号化」とは元となるデータに対して、特別な処理を行うことで、別のデータに変換する処理のことをいいます。それに対し、暗号化されたデータを元のデータに戻す処理のことを「復号化」と言います。

#####課題に向き合う
ラップトップからルーターにそしてamazonのサーバーにクレジットのクレジットの番号を送信するとなると、暗号化されていなければ、ルーターに接続している他のユーザーからも、番号に直接アクセスされ大変ですよね。
暗号化した番号を複合化するために、送信側と受信側で特定の秘密の符牒を使って複合化の方法を共有をすると、ルーターの覗き見は防げますが、ネット上で秘密の符牒の共有をしていれば、その秘密の共有すらも覗き見ができますよね

送信者はルーターの覗き見するものを回避しながら、受信者に送信するために暗号化を用いるが、その複合化の方法も送信しなければいけない、複合化の方法ですらも覗き見されてしまう。

解決するためには、過去に送信者がわと何らかの関係で共通の情報がある場合は加算トリックが使用することができる。しかし加算トリックには、統計的な分析によって鍵を見つけ出すことができるので、役には立ちにくいのです。

そしてこの課題を解決するためには、共有する秘密を、どう完璧に構築するかです、
#####現在のコンピューターの秘密の鍵

残念ですが、数学処理が必要になっていきます。
離散べき乗、離散対数です。数式が嫌いな方はYoutubeかGoogleにでも飛んで、好きなこと(この記事を読んだ時間は無駄になりますが、、)に没頭してください。笑
[YouTube](https://www.youtube.com/)
[Google](https://www.google.co.jp/?client=safari)

離散べき乗を理解するには二つの単純な数学概念が必要になって行きます。
時計算と累乗です。

#####時計算
時計は１２個の数字しか書かれていないのに１２を過ぎると再び１に戻ります。
10 + 4 = 2 であり　11 + 4 = 3であります。時計はMaxが１２でその後ループしています
時計算ではMaxの値を変更し、計算をおこなえます
max = 7
12 + 6 = 4 
#####累乗の記法
これ6*6*6*6*6は６を連続して5回かけているだけなので、6^5と書いていいですよね
これは先ほどの時計算とも組み合わせることができます。
3^4 = 3*3*3*3 = 81 = 4 (max = 11
7^2 = 7* 7 = 49 = 5 (max = 11

| n | 2^n | 3^n |4^n|
|:-----------|------------:|:------------:|:-------------:|
|1|2|3|6|
|2|4|9|3|
|3|8|5|7|
|4|5|4|9|
|5|10|1|10|
|6|9|3|5|
|7|7|9|8|
|8|3|5|4|
|9|6|4|2|
|10|1|1|1|
この表は2.3.6から１０乗までの値をMax11の時計算で示している。

この二つの概念が理解できれば、実際にコンピューターに使われている。秘密の鍵を共有する方法を説明できます。

>ステップ１
ゆずさんとかりんちゃんが二人で秘密の鍵を共有したいのですが、覗き見しようとする、いちごくんがいます。
ゆずさんには8、かりんちゃんには9が与えられます。いちごくんにも１０が与えられます。(秘密値)

---------
>ステップ２
時計のMaxの数字を決めます。(11)基数とゆう数字を決めます。(2)
この11と2は三人に公開されます。
ゆずさんとかりんちゃんといちごちゃんでPPNとゆう公開秘密混合値を作ります。
PPN =基数^秘密値(時計のサイズ)
ゆずPPN = 2^8 = 3　(時計のサイズ11)
かりんPPN = 2^9 = 6 (時計のサイズ11)
いちごPPN = 2^10 = 1 (時計のサイズ11)

-------
>ステップ３
共有される秘密鍵= 相手のPPN^秘密値(時計のサイズ)
ゆずとかりんで秘密鍵を作る
ゆず 6^8 = 4
かりん　3^9 = 4

この４が秘密鍵になります。
いちごくんがどれだけ頑張ってもゆず、かりんの秘密値は知ることができません。今回紹介したのは鍵交換アルゴリズムといいます。実際数字のスケールはもっと大きくなり、時計のMAXも数百桁の数字を使うので簡単にシステムは破ることができません。暗号化自体は加算トリックで行われます。そしてこの鍵交換アルゴリズムを応用するものの中で最も面白いデジタル著名については次回紹介します！
チュートリアル: Amazon S3 で AWS Lambda を使用するで、Lambda Layersを使ってみた

## やったこと
AWS公式のLambdaチュートリアルをベースに、画像変換ライブラリ"sharp"の依存関係を、Lambda Layersに切り出してみました。
Lambda Layersを使用することで、Lambda関数をマネジメントコンソール上で改修できるので便利ですね。

* チュートリアル: Amazon S3 で AWS Lambda を使用する  
https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/with-s3-example.html

※補足
チュートリアルでは、Lambda関数と画像変換ライブラリ"sharp"をデプロイパッケージで管理していて、Lambda関数をマネジメントコンソール上で改修できません  


## 本記事の概要
### 説明すること
  * Windowsで、画像変換ライブラリ"sharp"をzip圧縮する方法
  * マネジメントコンソールで、Lambda Layersにライブラリを登録して使用する方法

### 説明しないこと
  * Lambdaチュートリアルの内容
  * Lambda関数をマネジメントコンソール上で作成する手順

### 環境
* Node.js 12.x
* AWS CLI 2
* Windows10

## 説明
### Windowsで、画像変換ライブラリ"sharp"をzip圧縮する方法
１．コマンドプロンプトを起動し、任意のフォルダで`nodejs`フォルダを作成する。

```
...> mkdir nodejs
```

２．`nodejs`フォルダへ移動し、npm コマンドで 画像変換ライブラリ"sharp"を取得する。

```
.../nodejs> npm install --arch=x64 --platform=linux --target=12.13.0  sharp
```

３．`nodejs`フォルダを右クリックしてzip圧縮する。
※注意
powershellのcompress-archiveでzip圧縮した場合、Lambda Layer作成時に以下のエラーとなりました。

```
...> powershell compress-archive nodejs sharp

レイヤーバージョンを作成できませんでした: Layer conversion failed: Some directories do not have execute permissions;
```

４．sharp.zipのフォルダ構成を確認する。以下のフォルダ構造になっていればOK。

```
sharp.zip
└ nodejs
  |- package-lock.json
  |- /node_modules/sharp
  └ /node_modules/...
```

### マネジメントコンソールで、Lambda Layersにライブラリを登録して使用する方法
１．Lambda Layerに`sharp-layer`を作成し、sharp.zipをアップロードする。詳細は以下の画面イメージを参照下さい。   

![image (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676914/39bedbd7-6469-f25e-e98c-e6ff6ad7b759.png)

![image (7).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676914/6a6dbc4c-a5b1-b62e-484a-f0acead866b0.png)

２．Lambda関数にLambda Layerの`sharp-layer`を設定する。詳細は以下の画面イメージを参照下さい。   
![image (4).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676914/045d3d59-c323-5770-5b24-43d43c0e611b.png)
   
![image (5).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676914/679f6bcf-00c4-4037-6197-cbdbcc923717.png)


## 参考サイト  
* チュートリアル: Amazon S3 で AWS Lambda を使用する  
https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/with-s3-example.html  
* AWS Lambda レイヤー  
https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/configuration-layers.html
* AWS Lambda Layersでnode_modulesを使う  
https://xp-cloud.jp/blog/2019/01/12/4630/
オンプレミスでCloud9を実行する方法

# はじめに

全員で利用できる開発環境を構築してみたいと思い、ローカルPC（自分のPC）でCloud9を動作させようと思いました。

# 必要なパッケージ

動作させるにあたって、下記のパッケージをインストールする必要があります。

- node
- npm
- git

## nodeについて
下記のコマンドでバージョンを確認してください。

```bash:nodeのバージョン確認コマンド
node -v
```
バージョンが表示されていない場合は、nodeをインストールする必要があります。
[公式ページ](https://nodejs.org/ja/)からインストールしてください。

## npmについて
下記のコマンドでバージョンを確認してください。

```bash:npmのバージョン確認コマンド
npm -v
```

node.jsをインストールした際に、一緒にインストールされていると思いますので、バージョンが表示できない場合はnodeをインストールし直してください。

## git
下記のコマンドでバージョンを確認します。

```bash:gitのバージョン確認
git -v
```

バージョンが表示されていない場合は、インストールする必要があります。
[公式ページ](https://git-scm.com/book/ja/v2/%E4%BD%BF%E3%81%84%E5%A7%8B%E3%82%81%E3%82%8B-Git%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB)からインストールしてください。

# Cloud9のインストール

[Cloud9リポジトリのREADME](https://github.com/c9/core)に沿って、インストールを行います。

```bash:Cloud9のインストール
git clone https://github.com/c9/core.git c9sdk
cd c9sdk
scripts/install-sdk.sh
```

node用の必要なパッケージのインストールを行うため、しばらく時間がかかります。

```bash:完了表示
Success!
run 'node server.js -p 8080 -a :' to launch Cloud9`
```
上記の内容が表示されたら、完了です。

# Cloud9の実行
下記のコマンドを実行して一旦、アクセスしてみます。

```bash:Cloud9起動コマンド
node server.js -p 8080 -a :
```

実行したら、`Error: ENOENT: no such file or directory, open 'C:XXXXXX\.c9\standalone.settings`とエラーが表示されますが、一旦、無視して問題ありません。
[http://127.0.0.1:8080/](http://127.0.0.1:8080/)にアクセスします。

## Cloud9用のフォルダ作成
サイトにアクセスすると、下図が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401878/6b2bc799-d904-fa91-ab76-30828e999efc.png)

```text:内容
・ワークスペースにCloud9をすばやくセットアップできますか？
  Cloud9がこのSSHワークスペースで機能するには、いくつかの依存関係が必要です。
  同意する場合は、〜/ .c9フォルダーにいくつかのものをインストールします。
  これはシステムの他の部分には影響しません。完全に自己完結型です。

・後でこれを元に戻すにはどうすればよいですか？
  マシンからCloud9を完全に削除するには、〜/ .c9フォルダーを削除するだけです。 システムに何も残されません。

・これを手動でインストールできますか？
  https://github.com/c9/install を参照してください。
```

今回はすべてインストールしても問題無いので、`Always install everything`を選択し,
`Finish`をクリックします。
選択しなかった場合は下記の図のようにインストール内容を選択する事ができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401878/8392d936-ac3c-224a-17d3-c17d0b692acd.png)

# 実行時のオプション
オプションの一部です。
他のオプションを見たい場合はnodejs server.js --helpで確認できます。

## -p, --port  
Listenするポートを指定します。  
ポート8888番で待つ場合：`-p 8888`

## -a, --auth
アクセスの際にBasic認証を掛けることができます。 
ユーザ名user, パスワードpassに設定する場合：`-a user:pass`
認証をかけずにアクセスできるようにする場合：`-a :`

## -l, --listen
待ち受けるアドレスを指定します。 
全てのアドレスからのアクセスを許可する場合：`-l 0.0.0.0`
※認証を掛ける掛けない問わず、-aオプションを指定しないとローカルホスト以外で待ち受けることができません。 

## -w
Cloud9で使用するワークスペースとなるディレクトリを指定できます。 
/tmp/c9_workspaceディレクトリをワークスペースにする場合：`-w /tmp/c9_workspace`
※指定しない場合はserver.jsがあるディレクトリがワークスペースとなります。
AppleScriptでパスワード付きzipを生成してみた（AppleSilicon搭載Macでも動作）

# はじめに

今まで知ってはいたが、使ったことがなかったので
AppleScriptを勉強がてら使ってみました。

今回は、試しに暗号化zipを作るためのAutomatorワークフロー（アプリ）を
作ってみたいと思います。

※Apple Silicon搭載 MacでRosettaなしでも動作すると思います。

# ステップ

### 1. Automatorで新規アプリを作成
AutomatorはMac上の様々な操作を自動化するためのツールです。
まずは、Finderでファイル選択をさせるUIを表示します。
「ファイルとフォルダ」の「Finder項目の選択を求める」をドラッグ＆ドロップして、
左のペインに表示します。
![スクリーンショット 2020-12-08 14.38.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284780/43431d25-0037-f7ca-f470-632bb65b9ec6.png)
次に、「ユーティリティ」の「AppleScriptを実行」をドラッグ＆ドロップして、
左のペインに表示します。
![スクリーンショット 2020-12-08 14.38.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284780/4ef88c1f-9f4c-53f2-b318-0b17c8b2bbea.png)
### 2. AppleScriptを記述
「AppleScriptを実行のブロック」の中に下記のようなコードを記述します。

```applescript:zipper
on run {input, parameters}
	
	set filePath to item 1 of input
	set fileName to name of (info for filePath)
	set isFolder to folder of (info for filePath)
	
	# ダイアログを表示して、パスワード文字列の入力を受け付ける
	display dialog "zipパスワードを入力してください(記号不可)" default button 2 default answer ""
	set tmpText to result
	set passText to text returned of tmpText
	
	if isFolder then
		# フォルダの場合
		tell application "Terminal"
			activate
			set win to do script "rm -rf ~/Desktop/archive.zip && cd " & quoted form of POSIX path of filePath & " && cd ../ && zip -P='" & passText & "' -r ~/Desktop/archive.zip './" & fileName & "' && exit"
			repeat
				delay 0.1
				if not busy of win then exit repeat
			end repeat
			quit
		end tell
	else
		# ファイルの場合
		tell application "Terminal"
			activate
			set win to do script "rm -rf ~/Desktop/archive.zip && zip -j -P='" & passText & "' ~/Desktop/archive.zip '" & POSIX path of filePath & "' && exit"
			repeat
				delay 0.1
				if not busy of win then exit repeat
			end repeat
			quit
		end tell
	end if
	
	return
end run
```

### ポイント説明
#### input受け取り
「Finder項目の選択を求める」ブロックで選択されたファイル情報がAppleScriptのinputで受け取レます。
#### パスワードテキスト受け取り

```applescript:dialog
display dialog "zipパスワードを入力してください(英数字のみ、記号不可)" default button 2 default answer ""
```
この記述で、AppleScriptから簡単な入力を求めるダイアログを表示することができます。

#### コマンド呼び出し
内部ではzipコマンドを呼び出して、
ディレクトリかファイルかを判断して、それぞれ処理をしています。

# 最後に
AppleSilicon版Macでも動作確認済みです。
※Rosettaなしでも動作可能です。
### TODO
1. この方法でzipしても、Windowsで日本語文字の含まれるファイルをunzipすると文字化けします。
2. パスワード入力時の注意として、記号が使えないという点がありますが、適切にエスケープすれば、使えるようになると思います。
Laravel8にアップグレード後にfakerのseedingでTarget class [Database\Seeders\] does not existでハマる

Laravel7で開発したアプリをLaravel8にアップグレードしてFakerを使おうとしたら以下のようなエラーが出てハマりました。

```
Target class [Database\Seeders\UsersTableSeeder] does not exist
```

#seedsディレクトリ名を変更
Laravel7まではdatabase/__seeds__だったのがLaravel8ではdatabase/__seeders__になりました。そもそもエラーがTarget class [Database\ __Seeders__\] does not existですしね。
（seedsでもseedersでもどっちでもいいよと思うのは私だけ？混乱するような面倒な変更はしないで欲しい･･･）
なので、まずはディレクトリ名をseedersに変更します。

```
$ mv database/seeds database/seeders
```

#composer.jsonを修正
ディレクトリ名の変更に合わせてcomposer.jsonも変更します。

```
"autoload": {
    "psr-4": {
        "App\\": "app/",
        "Database\\Factories\\": "database/factories/",
        "Database\\Seeders\\": "database/seeders/"
    }
}
```
"classmap"は必要なくなったようなので削除します。

#Factoryを作り直す
私が使っているのはUserFactory.phpです。Laravel8ではFactoryの内容も変更になったので書き換える必要があります。
現在のUserFactory.phpを修正してもいいのですが、面倒なので元のファイルを違う名前にして保存しておき、新たにartisanコマンドで作り直します。

```
$ mv UserFactory.php UserFactory7.php 
$ php artisan make:factory UserFactory
```

新しいUserFactory.phpが出来上がったらUserFactory7.phpから必要な箇所を移植します。
気を付けなければならないのは、\$fakerは$this->fakerにしないとならないこと。

```php:database/factories/UserFactory.php
return [
    $faker->name; // ~Laravel7
    $this->faker->name; // Laravel8
];
```

*作業が終わったらUserFactory7.phpは消しておきましょう。

#モデルを修正
HasFactoryを追加します。

```php:app/User.php
use Illuminate\Notifications\Notifiable;
use Illuminate\Database\Eloquent\Factories\HasFactory; // 追加

class User extends Authenticatable
{
    use Notifiable;
    use HasFactory; // 追加
```

#DatabaseSeederを修正
namespace Database\Seedersを追加します。

```php:database/seeders/DatabaseSeeder.php
namespace Database\Seeders; // 追加

use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
```

#UsersTableSeederを修正
namespaceを追加します。また、seeder内のcreate文の書き方が変わりました。

```php:database/seeders/UsersTableSeeder.php
namespace Database\Seeders; // 追加

use Illuminate\Database\Seeder;

class UsersTableSeeder extends Seeder
{
    public function run()
    {
        // factory(App\User::class, 30)->create(); // ~Laravel7
        \App\User::factory()->count(30)->create(); // Laravel8
    }
```

#実行
最後にcomposer dump-autoloadしてからseedします。

```
$ composer dump-autoload
$ php artisan db:seed --class=UsersTableSeeder
```
【Rails】表の合計値算出方法（aggregate関数）

# はじめに
本記事は、 駆け出しエンジニアの第一歩！[AdventCalendar2020 13日目の記事](https://qiita.com/advent-calendar/2020/programming-beginner)です。
Railsで表の合計値を算出するにあたって、aggregate関数なるものが便利でスマートだったので、記事にしてみました。
# 開発環境
IDE：Cloud9
Ruby：2.6.3
Rails：5.2.4
# 実例をみてみる
## やりたいこと
このような表を作成し、下に合計値を表示したい。
![_2020-11-15_17.21.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/869111/fa64b979-99b6-d043-fa08-13a6ff49bd30.png)
## ER図
![_2020-12-08_14.20.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/869111/09d67ae6-e8ad-53b4-f7b4-75ba99e4d8b0.png)
## aggregate関数を使わない場合

```ruby:controllers/carts.rb
def new
  @carts = Cart.where(user_id: current_user.id)
end
```
例えば、たんぱく質（protain）の合計値を表示したい場合

```ruby:views/carts/new.html.rb
<% sum = 0 %>
<% @carts.each do |cart| %>
<% sum += cart.food.protain %>
<% end %>
<%= sum %>
```
これだと、1つの項目（上記の場合たんぱく質）を表示するのに、5行も必要となってしまい、見ため的にあまりスマートとはいえない。

```ruby:views/carts/new.html.rb
<td>合計</td>
<td>
	<% sum = 0 %>
	<% @carts.each do |cart| %>
	<% sum += cart.food.calorie %>
	<% end %>
	<%= sum %>
</td>
<td>
    <% sum = 0 %>
	<% @carts.each do |cart| %>
	<% sum += cart.food.protain %>
	<% end %>
	<%= sum %>
</td>
<td>
  <% sum = 0 %>
	<% @carts.each do |cart| %>
	<% sum += cart.food.fat %>
	<% end %>
	<%= sum %>
</td>
<td>
  <% sum = 0 %>
	<% @carts.each do |cart| %>
	<% sum += cart.food.carbon %>
	<% end %>
	<%= sum %>
</td>
```
表全体を表示すると、割とfat感がある。
そこでaggregate関数を用いて、もっとスマートに記述する。
## aggregate関数を使う方法
コントローラはさっきと一緒。

```ruby:controllers/carts.rb
def new
  @carts = Cart.where(user_id: current_user.id)
end
```

カートモデルに以下を記述する。

```ruby:model/cart.rb
def self.aggregate(column)
  self.all.map { |cart| cart.food[column] }.sum
end
```

```ruby:views/carts/new.html.rb
<td>合計</td>
<td>
  <%= @carts.aggregate(:calorie) %>
</td>
<td>
  <%= @carts.aggregate(:protain) %>
</td>
<td>
  <%= @carts.aggregate(:fat) %>
</td>
<td>
  <%= @carts.aggregate(:carbon) %>
</td>
```
めっちゃすまーと。
今日から始める負担にならないWAI-ARIA

# WAI-ARIAとはなにか
**「Web Accessibility Initiative - Accessible Rich Internet Applications」** の略で、 **「ウェイ・アリア」** と読みます。
WAI-ARIAをつかえば、HTMLだけでは不足している **セマンティクス（意味）** を属性で補完することができ、 **支援技術（スクリーンリーダーなど）を通じて、障害をもつ人に対し適切な情報を伝えられる** ようになります。

# WAI-ARIAの注意点
あくまでも **「必要な場合のみ使用する」** 技術です。
HTML5タグのセマンティクスで解決できるのであれば、 **HTMLで対応するのが基本** です。

# WAI-ARIAのつかいかた
決められた **「属性」** をHTMLタグに追記して使用します。
以下、すぐにでも導入が可能で効果が期待できそうな項目を挙げてみました。
（その他、詳細については[参考サイト](#参考サイト)をご覧ください。）

## ランドマーク
`role="**"`

要素の **「役割」** を定義します。
たとえば **「フレームワークの仕様でdivタグしか使えない」** といったような、適切なHTMLが使用できないときにも有効です。
まずは大きなレイアウト要素から使い始めてみるのがわかりやすいかもしれません。
設定するとスクリーンリーダーで **「ナビゲーション ランドマーク サンプル」** と読み上げられます（※`<nav>サンプル</nav>`でも同様の音声になります）。

```html:index.html
<!-- 例 -->
<div role="navigation">サンプル</div>
```

## キーボードのアクセシビリティ
`tabindex="**"`

tabindex属性を使えば、aタグやbuttonタグなどのような **キーボード操作（タブキーによるフォーカス移動など）** を可能にします。
属性値に0を指定すると、文書のソース内の順序でフォーカスを持たせることができます。

```html:index.html
<div class="btn" tabindex="0">ボタン</div>
```

## 文字列の定義
`aria-label="**"`

要素に **「ラベル付けする文字列」** を定義できます。
インラインSVGにはalt属性がないのでaltの代わりとして利用できます。

```html:index.html
<button aria-label="閉じる" class="js_btn">X</button>
<svg role="img" aria-label="画像の説明">...</svg>
```

## UIコントロール
`aria-expanded="**"`
`aria-controls="**"`
`aria-hidden="**"`
`aria-selected="**"`
`aria-checked="**"`
など

クリックやマウスオーバーで開閉するような**UI操作**時に使用します。
**JavaScript** によりユーザー操作にあわせて**aria属性値**を適宜変更します。
**「CSSと密結合」** させることにより、挙動や状態が理解しやすいコードになります。

```html:index.html
<!-- 閉じた状態 -->
<button aria-expanded="false" aria-controls="drawer">ボタン</button>
<div id="drawer" aria-hidden="true" class="drawer">ドロワー</div>
```
```html:index.html
<!-- 開いた状態 -->
<button aria-expanded="true" aria-controls="drawer">ボタン</button>
<div id="drawer" aria-hidden="false" class="drawer">ドロワー</div>
```
```css:style.css
.drawer[aria-hidden="true"] {
  display: none;
}
```

# 実装効率化の一例
jQueryの`toggleClass`のようなメソッドを用意しておくと、コードが簡略化しWAI-ARIAによる実装コストが下がります。

<p class="codepen" data-height="400" data-theme-id="dark" data-default-tab="js,result" data-user="p_toro" data-slug-hash="BazbjZK" style="height: 400px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="jQuery Plugin to  toggle WAI-ARIA .">
  <span>See the Pen <a href="https://codepen.io/p_toro/pen/BazbjZK">
  jQuery Plugin to  toggle WAI-ARIA .</a> by p_toro (<a href="https://codepen.io/p_toro">@p_toro</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://production-assets.codepen.io/assets/embed/ei.js"></script>

# WAI-ARIAのまとめ

* 支援技術（スクリーンリーダーなど）を通じて、障害をもつ人に対し適切な情報を伝えられる。
* 必要な場合のみ使用する。基本的にはHTML5のタグで対応。HTMLで対応するのが基本。
* つかいどころを理解し効率よく利用することで、それほど作業工数を上げることなく導入が可能。

それでは、WAI-ARIAを活用した良いアクセシビリティライフを！

***
###### 参考サイト
* [WAI-ARIAの基本 - ウェブ開発を学ぶ | MDN](https://developer.mozilla.org/ja/docs/Learn/Accessibility/WAI-ARIA_basics)
* [Accessible Rich Internet Applications (WAI-ARIA) 1.2 日本語訳](https://momdo.github.io/wai-aria-1.2/)
* [WAI-ARIAを活用したフロントエンド実装 | 第1回 role属性、aria属性の基礎知識 | CodeGrid](https://www.codegrid.net/articles/2016-wai-aria-1)
【Stereo Depth】SsSMnet : self-superviseでtraining

<h1>Self-Supervised Learning for Stereo Matching with Self-Improving Ability</h1>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/b7a0ccab-0a69-e33b-0cac-81809ba1d283.png)

[GC-Net](https://qiita.com/minh33/items/8f3ce0ad64035d994af6)をSelf-SuperviseでTraining出来るようにしたネットワーク。


<h1>新規性</h1>
<h2>Loss</h2>
今では一般的な方法ですが、Image warpingをする事で反対の画像をReconstructionして、Errorを計算する手法。

主に3つのLossがある
1. LR Consistency Loss
   =>右と左のDisparityの違いを計算する
2. Reconstruction Loss
   =>Reconstructした画像を入力画像と比べる。評価指標にSADやSSIMが良く使われる
3. Disparity Smoothness Loss
   =>DisparityのSmoothさを計算する。Edgeに対するmaskをするとより良い

<h1>結論</h1>
・stereo画像を使う事でGround TruthなしでもDisparity(1/depth)のLossを計算する事が出来る。


<h1>参考文献</h1>
Self-Supervised Learning for Stereo Matching with Self-Improving Ability
https://arxiv.org/pdf/1709.00930.pdf
PHP8 で Call to undefined function each() になる場合の対処法

PHP8 で [each](https://www.php.net/each) 関数が削除されたため、 `Call to undefined function each()` というエラーになります。

例えば、以下のような処理がある場合は、 `current()` と `next()` を使用した処理に書き換えます。

```php
// PHP7 までは each() 関数が使える
while (list($k, $v) = each($array)) {
    echo $k;
    echo $v;
}
```

```php
// PHP8 以降は each() 関数は使えない
while ($current = current($array)) {
    $k = key($array);
    $v = $current;
    echo $k;
    echo $v;
    next($array);
}
```

## Composer のパッケージで each() が使われている場合

Composer のパッケージで `each()` 関数が使われている場合は、直接書き換えるわけにはいきませんので、解決するためのパッケージを作成しました。

以下のコマンドで PHP8 でも `each()` 関数を使えるようになります。

```
composer require nanasess/php8-compat
```

本来は、こういった互換プログラムを使用するのはあまりよろしくないので、
1. 対応されるまで待つ
2. `each()` 関数を使わないよう修正し、 Pull Request する
などの対応をするのが良いと思います。
【React】Presentational Component と Container Component

# Component
- ReactはUIを `Component` という部品単位で扱う
- `Presentational Component` と `Container Component` に分けることで、見た目とロジックを切り分けることができる

## Presentational Component
- 表示のみに専念する
- 自分のコンポーネント以外のことについて依存しない
- 親からpropsとしてデータやコールバックを受け取る

```components/App.js
import React from 'react';

const App = ({ text: string, onButtonClick: () => void }) => (
  <div>
    <p>{text}</p>
    <button onClick={onButtonClick}>Click</button>
  </div>
);

export default App;
```

## Container Component
- ロジックのみに専念する
- Presentational Componentに具体的なデータやコールバックを渡す

```containers/App.js
import App from "../components/App";
import { connect } from "react-redux";

const mapStateToProps = state => {
  return {
    text: state.text
  };
};

const mapDispatchToProps = dispatch => {
  return {
    onButtonClick: () => {
      dispatch({ type: "CLICK" });
    }
  };
};

export default connect(mapStateToProps, mapDispatchToProps)(App);
```

# Component の分離によるメリット
- アプリケーション部分とUI部分を分離できる
- 表示するデータやボタン押下時の処理を外部から指定することができる  
-> **再利用性が上がる**
Raspberry Pi OSにPostgreSQL 13 / PostGIS 3 をインストールメモ


# Raspberry Pi OSを最新にアップデート
```bash
sudo apt update
sudo apt full-upgrade
```

念の為再起動

```
sudo reboot
```
# PostgreSQL 13のリポジトリを追加
```
wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
echo "deb http://apt.postgresql.org/pub/repos/apt/ `lsb_release -cs`-pgdg main" |sudo tee  /etc/apt/sources.list.d/pgdg.list
sudo apt update
```

```bash
sudo apt install postgresql-13 postgresql-client-13 postgresql-13-postgis-3
```

# 接続
```
sudo su - postgres
psql
```

# PostGISエクステンションの追加
```sql
postgres=# create extension postgis;
```
Rails database.ymlの記載内容の適用のされ方に関するメモ

## 記事の目的
データベースの接続の設定ファイルであるdatabase.ymlの記載内容の適用のされ方に関するメモ

```
default: &default
  adapter: mysql2
  encoding: utf8mb4
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: <%= ENV["DB_USERNAME"] %>
  password: <%= ENV["DB_PASSWORD"] %>
  host: localhost

development:
  <<: *default
  database: book_action_development


test:
  <<: *default
  database: book_action_test


production:
  <<: *default
  database: book_action_production
  username: root
  password: <%= Rails.application.credentials.db[:password] %>
  host: <%= Rails.application.credentials.db[:hostname] %>

```

###勘違い

あるエラーが起きて、
default部分に記載のusername: <%= ENV["DB_USERNAME"] %>と
productionに記載のusername: root
が競合してしまうと思っていた。

###実際
競合はせず、productionに記載のusername: rootが優先されるそう。

###まとめ
なぜそうなるかは詳しく調べられていないので、今後調べる。
ROSについてまとめてみる #1

#この記事について
ちょっとROSについてレポートすることになったので、この機会にまとめてみようと思います。
筆者のスペックは、

 - indigo, kinetic, melodicは触ったことある
 - ROS2はまだ触ってない
 - パッケージの自作等はしておらず、落としてきて使う程度
 - Pythonしか書けない
 - 文章読むの苦手

という感じ。
私自身まだまだ未熟なので、ご指摘あればお願いいたします。

ROSはとても面白そうですし、何よりコミュニティーの盛り上がりがすごく楽しそうなので、仲間にはいりたいのですが、なかなかとっつきにくいところがあります。
習得するには使えばいいわけで、業務で使うように仕事で提案すればいいわけです。

しかし、ROSの困ったところは、「ROSってどういうものなの？」って聞かれたときに**何なのかうまく説明できない**ところにあります。統合開発環境や専用の実行環境があるわけではないので、答えにくいですよね。
今回は、「ROSとは何なのか。」をちゃんと伝えられるようになるように、概要をまとめていこうと思います。
＊尚、この記事の記載内容はROS1に関するものです。

#ROSとは
公式によると、
>ROSはオープンソースで提供される, ロボット向けのメタ・オペレーティングシステムです. ハードウェア抽象化, 低レベルなデバイス制御, 一般的な機能性, プロセス間通信, そして, パッケージ管理など, 一般的なオペレーティングシステムに要求されるサービスを提供します. また, コードを複数台のコンピュータにわたって保持・ビルド・記述・実行するためのツールやライブラリも提供しています.

http://wiki.ros.org/ja/ROS/Introduction

らしいです。**なるほどわからんですね。**
こういう公式ドキュメントって、英語を愚直に日本語に直したものだったりするので、直感的に分かりづらい日本語だったりします。

この辺に関しては、オライリーの"プログラミングROS"の、まえがきにある記述が一番納得しやすかったです。

>ROS(Robot Operating System)はロボットにさまざまな動作をさせるためのオープンソースフレームワークです。ROSはロボットを作る人、使う人、それぞれに必要な共通のプラットフォームを提供することを目的としています。

https://www.oreilly.co.jp/books/9784873118093/

**なるほどですね。**
OSって書いてあるけど実はミドルウェアなんだぜ！とかって記述もよく見ます。
まぁミドルウェアであることは間違いないのですが…、実際のところ、**フレームワーク**であると認識するのが一番しっくりくる気がします。人に説明するときも、その方が伝わりやすかったり。
とりあえず、**ロボット開発に特化したフレームワークです！**と答えておけば話はスムーズに進みそうです。
では、詳しく中身を見ていきましょう。

#思想(哲学)
ROS本を見ていると、本によって様々な解釈が見られますが、どれも大まかにはこんな感じです。

##ピアツーピア
ROSは**分散システム**で構築されます。
機能ごとに**ノード**という単位で独立したプロセスを作成し、ノード同士がお互いにメッセージを送りあうことで、ジョブを実行します。
これはルーティングを行うサービスなどを介さずに直接プログラム同士で行われます。
これによってROSは堅牢性(一ヶ所バグっても多勢に影響は少ないという意味で)やプログラムの再利用性を担保しています。

##多言語対応
書籍によっては様々な言語が対応言語として挙げられていますが、その内容は時代によって異なります…
ここに関しては、公式にある、
>言語の独立性: ROSのフレームワークはどのような現代的プログラミング言語による実装も簡単です. 既にPython, C++, そして, Lispを実装しており, 実験的なJavaとLuaのライブラリもあります.

http://wiki.ros.org/ja/ROS/Introduction
これが、今現在では一番正しい見解だと思います。
要するに、ROSは上に書いたような分散システムで、ノード同士が通信を行うといったような形をとっています。これらの通信に関する部分や、その他の細々したROSの機能を使うためのライブラリが、完全に整備されているのは、現状これらの言語のみ、という理解でいいと思います。

##薄い実装
これは複数の文献でこのように書いてあるのですが…
原文には英語で"thin"とだけ書いてあるようです。
ROSでの開発の際、開発者は、まずはスタンドアローンなライブラリを作り、その上にラップする形でROSの通信部分を実装することが推奨されています。
これによって、ROS環境で開発されたコードは、他のフレームワークへの移植が容易になり、かつ他のフレームワークと結合しやすくなっています。
最近はシミュレータをUnityに置き換えたりするのが流行っていたりしますが、これができるのは、こういった思想による恩恵だと思います。

##豊富なツール
ROSには様々な開発補助ツールがあります。

- Rviz　ロボット筐体やセンサ値の可視化
- gazebo　物理シミュレータ
- Moveit!　プランナー
- catkin　ビルドツール
- ROS graph　ノードやトピックの可視化
- ROS tf　姿勢変換

などです。
これらのツールは全て独立したプログラムで作成されていて、それぞれの用途に見合った方法で実装されています。また、これらのツールもピアツーピアの思想に則って実装されているので、その都度、利用シーンに適したツールに置き換えることができます。

##無償かつオープンソース
ROSのすべてのコードは公開されており、BSDライセンスの元、使用できます。


\#2へつづく
#参考
ROS
http://wiki.ros.org/

プログラミングROS(O'Reilly Japan)
https://www.oreilly.co.jp/books/9784873118093/

ROSプログラミング(森北出版株式会社)
https://www.morikita.co.jp/books/book/3010
【Vue.js】メソッド実行した際のコンポーネントの更新・再レンダリング if編

#はじめに
例えばCRADメソッドを実行、
その後コンポーネントの一部分だけ更新したいとき。
#環境
@vue/cli 4.4.6

#解説
v-ifを使ったら、コンポーネントが再計算されます。

以下をすることで、
子コンポーネントで処理が終わったあとに、
ページ更新などをしなくても再描画されます。

**前提知識**
①emit → 子から親のメソッドをいじれたりする
②$nextTick → DOMの更新サイクル後に、子コンポーネントを再計算させる。
(単純にtrue→false→trueとやっても再描画はうまく行かない。)

```Parent.vue
<template>
  <div>
    <child v-if="showChild" @add="toggle"></child>
  </div>
</template>

<script>
import Child from "./Child.vue";

export default {
  components: {
    Child
  },
  data() {
    return {
      showChild: true
    };
  },
  methods: {
    toggle() {
      this.showChild = false;
      this.$nextTick(() => (this.showChild = true));
    }
  }
};
</script>
```

```Child.vue
<template>
    <button @click="add">追加する</button>
</template>

<script>
    export default {
        methods: {
            add(){
                //何かしらCRAD等の処理の後に↓
                this.$emit('add');
            }
        }
    }
</script>

```

#ご参考にさせていただいた記事
https://tomatoaiu.hatenablog.com/entry/2019/09/28/133319
https://qiita.com/shosho/items/b9b24a52dc0cc0fc33f5
ムービー再生中にFPSを落とさせない工夫

# はじめに

本記事は、[サムザップ #1 AdventCalendar 2020](https://qiita.com/advent-calendar/2020/sumzap1)の12/9の記事です。
昨日の記事は[@kanasaki_kenji](https://qiita.com/kanasaki_kenji)の「[最高の振動をデザインするための下準備〜UnityからCore Haptic FrameWorkを使ってみた〜](https://qiita.com/kanasaki_kenji/private/c6ef2a4b9639117e8e49)」です。

## 導入きっかけ

私は、Unityを使ったゲーム開発をしております。
インゲームなどの60FPSをキープしたい、そしてプレー中にムービーを流したいなどの要望を受けました。
私が担当したプロジェクトでは、ムービーを再生するのに利用しているプラグインとして
CRI Manaを利用していました。

CRI Manaにはムービーをシームレスで再生するという機能などいくつかありますが、
低スペックの端末だとシームレスの再生の切り替えのタイミングでコマ落ちすることが調査して判明しました。
そこで今回どうやって工夫したかを説明したいと思います。

## 対処方法

いくつか試してみてので、その時のことを書きます

* アセットバンドルとして登録されているムービーを一つに連結してしまう

>
こちらであれば簡単だなと思って実際にやってみたのですが、
これだとファイルサイズのでかいムービーデータになってしまい
ダウンロードが遅すぎるという欠点がでました

* アセットバンドルとして登録されているムービーを分割した状態で並列ダウンロードさせて連結させる

```
        /// <summary>
        /// Save(デバイスで読み書きできるパスにセーブする)
        /// </summary>
        /// <param name="index">index</param>
        /// <param name="totalbyte">分割されたファイルのトータルバイト数</param>
        /// <param name="usmFileName">ムービーファイル</param>
        /// <param name="outputFilePath">出力先ファイルパス</param>
        /// <returns></returns>
        private async UniTask Save(int index, long totalbyte, string usmFileName, string outputFilePath)
        {
            if(File.Exists(outputFilePath))
            {
                FileInfo fileInfo = new FileInfo(outputFilePath);
                // 端末のファイルとコピー元のサイズをチェック
                if(fileInfo.Length == totalbyte)
                {
                    //同じなので終了
                    return;
                }
                // 初回のチェックの場合ファイルを削除しておく
                if(index == 0)
                {
                    File.Delete(outputFilePath);
                }
            }
            TextAsset asset = assetLoader.LoadResource<TextAsset>(usmFileName);
            byte[] bytes = asset.bytes;
            // ファイル書き込み
            using (var stream = new FileStream(outputFilePath, FileMode.Append, FileAccess.Write))
            {
                stream.Write(bytes, 0, bytes.Length);
            }
        }
```

こちらのSaveメソッドをusmFileNameの数だけ回し
それらをファイルごとに書き込むという手法をとりました。
更に端末にセーブした元を比較するのにファイルサイズを比較しないとアセットの差し替えに対応できないので
チェックし初回のチェックがついているときには、元のファイルを削除しておくという対応を加えました。
変更がなければ、生成しないという手法を採用しました。

これによりムービーが再生されてしまえば、シームレスで切り替えるという処理がなくなり
60FPSをキープすることが可能なりました。

## まとめ
意外にこれするだけで、効果がかなりありました。もしも困っていたら試してみてください。
明日の記事は、[@norimatsu_yusuke](https://qiita.com/norimatsu_yusuke)です。
Herokuを実行した時のエラー

## エラー状況

Node.js(Express)をHeroku実行を試みる。

細かな手順は割愛、Herokuにpushする。

```
$ git push heroku master
```

ビルドエラー

```
remote:        ERROR in [copy-webpack-plugin] unable to locate '~~~/static' at '~~~/static'
remote:        
remote:          Build failed with errors.
```

## 環境

| | version |
|:-:|:-:|
| Node.js | v11.15.0 |
| Heroku | heroku-20 |

## 原因

プロジェクト直下にある`static`がない。

この`static`ディレクトリ、ローカルでは__見かけ__は空のディレクトリ。「いつの間にこんなディレクトリ作ったっけ？」なノリで、削除していた。また`static`ディレクトリには隠しファイル`.gitkeep`があり、消してはいけない（戒め）

## 対処

`static`と`.gitkeep`を用意してあげる。

```
$ mkdir static
$ touch static/.gitkeep
```
mac Big Surでpyenv経由でpythonをインストールした時の「zipimport.ZipImportError」の対応について

mac Big Surでpyenv経由でpythonをインストールした時に`zipimport.ZipImportError: can't decompress data; zlib not available` というエラーが出た時の対応についてのメモとなります。

## 環境
- macOS Big Sur version 11.0.1
- pyenv 1.2.21

## 対応
### やってみたこと①

- こちらの記事 [pyenv でcan't decompress data; zlib not availableが出る場合
](https://qiita.com/NierR/items/6829c0354df81b4305f3) を参考に以下のコマンドを実行。結果変わらず。。。

```
CFLAGS="-I$(xcrun --show-sdk-path)/usr/include" pyenv install 3.8.6
```

### やってみたこと②

- こちらの記事 [[MacOS Mojave]pyenvでpythonのインストールがzlibエラーで失敗した時の対応](https://qiita.com/zreactor/items/c3fd04417e0d61af0afe) を参考にしようとしたが、OSのバージョンが異なるので断念。。。

### やってみたこと③

- こちらの記事 [pyenv installで「zipimport.ZipImportError」が発生したときにやったこと（masOS Mojave）](https://dev.classmethod.jp/articles/pyenv-install-zipimport-resolve/) を参考に以下のコマンドを実行。結果変わらず。。。

```
xcode-select --install
```

### やってみたこと④
- AppStoreでXcodeをインストールしてみた。結果変わらず。。。

### やってみたこと⑤
- こちらの記事 [Python 3.8.6をpyenvを使ってmacOS BigSur にインストールする](https://qiita.com/craymaru/items/58e92fac99b5b0ec778f) を参考に以下のコマンドを実行。

```
LDFLAGS="-L$(xcrun --show-sdk-path)/usr/lib" pyenv install 3.8.6
```

できた！

Big Surの情報が少なく、苦労しましたがなんとかpyenvをインストールできました。

## 参考
- [まかあそてっく](https://makaaso-tech.com/mac-big-sur-pyenv-python-zipimporterror/)
Basic認証　Part 1

#始めに
今回は、RailsアプリケーションにBasic認証を導入する方法について説明します。練習としてデプロイしている自身のアプリに対してサーバーの負荷を増やしたくないときなどは、Basic認証を導入して閲覧できるユーザーを制限しましょう。

##Basic認証
Basic認証とは、HTTP通信の規格に備え付けられているユーザー認証の仕組みです。
サーバーと通信が可能なユーザーとパスワードをあらかじめ設定しておき、それを知っているユーザーのみがWebアプリーションを利用できるようにすることができます。

![Qiita](https://tech-master.s3.amazonaws.com/uploads/curriculums//fe1298b646df1d855ec219dc6cc15ed6.png "Qiita")

Ruby on Railsには、Basic認証を導入するためのメソッドが用意されており、簡単に実装することができます。
便利な世の中ですね(笑)

####authenticate_or_request_with_http_basic
Ruby on RailsでBasic認証を実装するためのメソッドです。
ブロックを開き、ブロック内部でusernameとpasswordを設定することでBasic認証を利用できます。

```ruby:サンプル
# 'admin'というユーザー名と、'password'というパスワードでBasic認証できるように設定
authenticate_or_request_with_http_basic do |username, password|
  username == 'admin' && password == 'password'
end
```

##Basic認証のRailsアプリケーションへの導入
authenticate_or_request_with_http_basicメソッドを利用して、開発中のRailsアプリケーションにBasic認証を導入しましょう。

###RailsアプリケーションにBasic認証を導入しよう
Basic認証によるログインの要求は、全てのコントローラで行いたいです。そこで、Basic認証の処理をapplication_controller.rbにて、private以下にメソッドとして定義し、before_actionで呼び出すように実装しましょう。

```ruby:app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  before_action :basic_auth

  private

  def basic_auth
    authenticate_or_request_with_http_basic do |username, password|
      username == 'admin' && password == '2222'
    end
  end
end
```

これで、どのページにアクセスしてもBasic認証が要求されるようになりました。今回は、adminというユーザー名と2222というパスワードでBasic認証ができるように設定しています。

###Basic認証の動作を確認しよう
application_controller.rbの記述が完了したら、実際にアプリケーションを起動し、Basic認証の動作が期待したものになっているか確認してみましょう。

'rails s'をした上で、適当なページにアクセスすると、ユーザー名とパスワードの入力を求めるポップアップウインドウが表示されます。間違ったユーザー名とパスワードではBasic認証できないことを確かめるために、あえて適当な文字を入力してみましょう。以下のGifでは、ユーザー名にhogehoge、パスワードに1111と入力しています。

![Qiita](https://tech-master.s3.amazonaws.com/uploads/curriculums//e4a8d405172ee191703b043e8430b9b9.gif "Qiita")

正しく実装できていれば、もう一度Basic認証用のポップアップウインドウが表示されます。 間違った情報ではログインできないことを確認できたので、今度は正しい情報を入力してログインできるかどうかを確かめてみましょう。ユーザー名にadmin、パスワードに2222と入力して、もう一度ログインを試みてください。

![Qiita](https://tech-master.s3.amazonaws.com/uploads/curriculums//aa57e8b021d2031211cb01379bcdc523.gif "Qiita")

ルーティングに対応したページが表示されれば、Basic認証に成功しています。

ひとまず長いので、Part２続きます。
ここまでで、問題点が２つほどあるので考えてみてくだい。
vueのstyleの上書き（親コンポーネントから子コンポーネントに対してオーバーライド）

#子コンポーネントに対してのstyleの上書き

ディープセレクタ`>>>`で繋ぐ。

```vue
<style scoped>
.親コンポーネントクラス >>> .子コンポーネントクラス {
  background-color: #fff000 !important
}
</style>
```

情報元こちらです🙏
https://blog.piyo.tech/posts/2018-10-23-vuejs-override-child-component-style/
https://vue-loader-v14.vuejs.org/ja/features/scoped-css.html
GitHubの差分確認方法(ブランチ、コミット、日付)

[GitHub実践入門](https://www.amazon.co.jp/GitHub%E5%AE%9F%E8%B7%B5%E5%85%A5%E9%96%80-Pull-Request%E3%81%AB%E3%82%88%E3%82%8B%E9%96%8B%E7%99%BA%E3%81%AE%E5%A4%89%E9%9D%A9-PRESS-plus/dp/477416366X)の「ブランチ間の差分確認方法」のあたりを読んでいて、「確かコミット間でも比較できたよな」と思い、少し調べました。備忘録として残しておきます。

なお、今回の例として使用するリポジトリは下記のnumpyリポジトリです。
https://github.com/numpy/numpy/ 

差分が大きすぎると、コミットなどが表示されるだけですが、そんなに大きくなければファイル内の細かい差分も見れました(commit間の比較部分の参考URLが分かりやすいと思います)。

# 1. ブランチ間の比較
`https://github.com/[ユーザー（組織）名]/[リポジトリ名]/compare/branch1...branch2`
例. https://github.com/numpy/numpy/compare/master...maintenance/1.1.x

# 2. コミット間の比較
`https://github.com/[ユーザー（組織）名]/[リポジトリ名]/compare/コミットハッシュ値1...コミットハッシュ値2`
例. https://github.com/numpy/numpy/compare/b01a473...4d29079

# 3. 日付での比較
## 3.1. n日前
`https://github.com/[ユーザー（組織）名]/[リポジトリ名]/compare/branch@{7.day.ago}...branch`
例. https://github.com/numpy/numpy/compare/master@{7.day.ago}...master

## 3.2. 指定日
`https://github.com/[ユーザー（組織）名]/[リポジトリ名]/compare/branch@{YYYY-MM-DD}...branch`
例. https://github.com/numpy/numpy/compare/master@{2020-12-01}...master

# 異なる分類での比較
上記のような形でURLを編集することで、ブランチとコミットの比較や日付とブランチの比較など、様々な比較が可能になっている。
試すには`compare/`以降の`...`の両端の組み合わせを変えるだけでいい。
`https://github.com/[ユーザー（組織）名]/[リポジトリ名]/compare/branch@{7.day.ago}...コミットハッシュ値`
`https://github.com/[ユーザー（組織）名]/[リポジトリ名]/compare/branch...コミットハッシュ値`
【UiPath】Advent of UiPath 2020 #1（APIからデータを取得）

この記事は、UiPath Forum で行われている [**Advent of UiPath 2020**](https://forum.uipath.com/t/advent-of-uipath-2020/273299) の紹介記事です。

# “Advent of UiPath 2020” とは何か？

- 英語版のフォーラムで投稿されています。
- RPA challenge です（＝お題を出て、みんなでRPA化してみる）
- 誰でも回答できます（フォーラムのアカウントがあれば）
- 3日おきに出題され、計8回（xmasイブまで）あります
- 回答して上位に選ばれれば、フォーラム上でスターがもらえます。
- フォーラムのスタッフが開催しているっぽいです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154139/b7547e4f-f428-1dfc-b5f3-af5ac07ab664.png)

# チャレンジ１：APIからデータを取得

https://forum.uipath.com/t/advent-challenge-1/273306

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154139/a8049991-d9da-5a56-bf91-4d78d5071c8f.png)

### お題

サンタは2019年のクリスマスが荒れていたため、今まで寝ていました。そこで彼はブリスベンで目覚めました。彼はトナカイのそりを見つけ、最初の目的地であるバンコクに向けて出発しようとしています。バンコクでは、アシスタントのジングルベルを迎えに行きます。
:christmas_tree: 問題 :christmas_tree: 
ソリは風に弱いので、サンタはバンコクへの旅の途中で、各都市の正確な風速を知る必要があります。（都市：:office: Brisbane :office: Port Douglas :office: Makassar :office: Palembang :office: Kuala Lumpur :office: Bangkok）

＜初心者向けチャレンジ＞
UiPathを使用して、上記の6つの都市の風速（m / s）を確認する方法を説明してください。確認した風速を保存する方法も説明してください。写真やワークフローを付けてクリエイティブに説明するとボーナスポイントになります。

＜上級者向けチャレンジ＞
風速を確実に取得するには「https://vejr.eu/api.php?location=London&degree=C33」 のエンドポイントを取得すると良いでしょう。「HTTPリクエスト」（Get）」アクティビティを使用してください。クリエイティブに説明するとボーナスポイントになります。

### コメント・感想

これは「APIでデータを取得して出力する」というパターンです。
APIも指定されているので「サンタにどうやって結果を届けるのか」が、
クリエイティブに魅せるポイントのようです。

回答を見てみると、課題に真面目に回答する人や、「サンタから依頼を受けたぞ」的な物語チックに回答したり、自分の好きなキャラに回答させて楽しんだり、様々です。

面白いと思った回答は

■ サンタは急いでるから、EメールじゃなくてSMSで通知
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154139/5a798c99-227a-3885-7629-d010b4a9d133.png)

■ APIが風向きをデンマーク語で帰すから、風向きは矢印で
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154139/a1b311ed-0c22-1bd9-d17c-6597d1514779.png)

■ 結果はパワポのテンプレに値をセットして、PDFにしてあげる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154139/99753a15-2721-ee3d-e954-dd32a484f6c2.png)

■ ソリの前面パネルに結果を表示してあげる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154139/dda8e62f-41a6-3687-269a-a6acf5fb3004.png)

でした。
回答には無かったですが、「SlackやTeamsでチャットボットっぽく届ける」等もありかもしれません。（3日間の時間制限でそこまで難しいですけど）


# 終わりに

RPAで課題をどうやって解決できるか？のネタとして見てみると面白いです。

チャレンジは 全8回 ありますが、英語が出来る方はチャレンジしてみてはいかがでしょうか？
[Elm]ボタンやモーダルがIE11で正常に動作しないときに試してほしい方法

# 背景
リリースに向けて実装した画面を動作確認していたところ、他のテスト者から**「Internet Explorer (IE)で、ボタンが押せないよ:bangbang:」**という報告が...！(ピンチ:ghost:)
いかんせん、普段はChromeを推奨環境してご案内し、プロダクト開発しておりまして、IEに関しては知見も経験も少ない私です。
「さすがにボタンが押せないのはマズイ！対応せねば」と調べた内容を共有します！

# どんな仕様を実現しようとしていたか？
- ボタンA (`viewButtonA`)をクリックすると、Msgが発行され、Modelを書き換えることで新たに画面を表示する。
- ボタンAは特定の条件下で表示し、それ以外の場合は何も表示しないという画面を表示する。

## 具体的なコードの例
```elm:OldButton.elm

type Msg
    = ClickedButton

viewButtonA : Bool -> Html Msg
viewButtonA isShown =
    if isShown then
        Html.button [onClick ClickedButton][Html.text "Click Me"]
    else
        Html.text ""
```


# どんなエラーが発生していたのか？
- ボタンが押せない。押すと以下のようなエラーメッセージがコンソールに表示される。:frowning2:
    - `TypeError:未定義またはNULL参照のプロパティ"j"は取得できません`
    - `(TypeError:Unable to get property 'j' of undefined or null reference)`
- ボタンが押せないので、Msgも発行されていないため、表示が変わらない。


# なぜ起こるか？
- **「何も表示しない」という実装に`text ""`を使用しているため！**
    - ※ただし、必ず起きるというものではなく、`text ""`の描画が、Dom構造の上層に近かったりすると生じることがあるみたいです。
- Virtual Domの既知のバグで、[こちら](https://github.com/elm/virtual-dom/issues/167)にもissueが存在しています。


# 対策
1. 何も表示しない画面を、`div [] [] `または `span [] [] `で表現する。
2. (特にチーム開発においては)実装者に依存し、予期せぬバグを生むため、関数として切り出し、各モジュールから利用する。

以下がサンプルのコードです。

```elm:BlankView.elm
module BlankView exposing (viewBlank)
viewBlank : Html msg
viewBlank =
-- ここは`span [] []`でもバグを回避できます。
    div [] []
```

```elm:NewButton.elm
import BlankView exposing (viewBlank)

type Msg
    = ClickedButton

viewButtonA : Bool -> Html Msg
viewButtonA isShown =
    if isShown then
        Html.button [onClick ClickedButton][Html.text "Click Me"]
    else
        viewBlank
```

# 感想
- このバグについては日本語のリソースがほとんどなかったため、Qiitaを書くことに決めました。
- 指定の条件下で何も表示しない、という仕様は結構あるので同じバグに出会ったときに役立つといいなと思ってます。:bow_tone1:
- 実はチーム内でも過去に同じようなバグを対処したことがあるみたいだったので、改めてルールや方針等の共有はとても大切です！
XAMPPについて

#<font color="blue">xamppとは？</font>#

####**どんな時に使うもの？**####
HTMLやCSS、JavaScriptといったクライアント側でも動くことができる言語（サーバーを介さず、WEBを操作している側で動くことができる）言語の動きを確認するためにはサーバーが必要ありません。

しかし**PHP**や**ruby**など、サーバー側で動かす言語についてはサーバーを立てる必要があります。
その際にそういった煩わしい作業をせずとも**xampp**を入れるだけでサーバー側で動かすための必要な設定が完了してしまうんですね。便利！！

昨日投稿した記事[herokuについて何も知らなかったので調べて分かりやすく解説してみる](https://qiita.com/kotttttun/items/5dbc3f823b0f6da104d8)との違いは、herokuは実際にサービス提供時に使用できるけど、xamppはPHPなどで開発を行う際の開発環境のために使用することが多いのかなぁと思いました。
（違っていたら突っ込んでください・・・）


####**xamppの意味**####

 - **X**　→     クロスプラットフォーム対応(Windows、Linux、Mac) ・・・OSを選ばずとも動作できるということ
 - **a**　→ Apache・・・WEBサーバーの１つです。初学者にもわかりやすく解説されています。[WEBサーバーとは？](https://wa3.i-3-i.info/word1128.html)
 - **m** →  MySQL(MariaDB)・・・データベースです
 - **p** →　PHP・・・WEBシステム開発時に使用される有名な言語のひとつですね
 - **p** →　Perl・・・こちらもスクリプト言語です。今はPHPが主流なので、使われる機会は減っているようです。

**OSは問わず使える**、WEBサーバーは**Apache**、DBは**MySQL**といった環境下で開発を行うことができるんですね。
環境構築を行ったこともありますが、（本当に開発を始めたての頃に）そんなに難しい設定等なはく初学者でもすんなりできたと記憶しています。


####**xamppを実際に使ってみよう**####
xamppのインストールについては[「XAMPPのダウンロード及びインストール」](https://www.adminweb.jp/xampp/install/index1.html)こちらのサイトがわかりやすいなぁと思いました。
これからPHPの開発とかWordPressとかやってみたいという方はぜひ参考にしてインストールしてみてください。
SVProgressHUDのimageにtintColorを反映させないようにする

## 追記（2020/12/11）

最新のmasterブランチではimageColorとtextColorの対応が反映されてました。
ので、バージョン管理がされてない場合は:gitでmasterからinstallするようにすれば解決です。

## はじめに
Qiita Advent Calendar 2020 Swift 9日目のエントリーです。

すみません、色々考えたんですが大したこと思いつかなかったので最近やったことについて。

## SVProgressHUD

業務でローディングダイアログを実装する際に[SVProgressHUD](https://github.com/SVProgressHUD/SVProgressHUD)を利用しました。

特にアニメーションの指定などなく、基本的なものでよかったのでほぼ問題なかったんですが
そのまま利用するとtintColorがimageViewにもかかって、画像をそのまま利用しつつ文字色を別のものに変えるというのができませんでした。（※できるのかもしれないのですが、自分ではわかりませんでした。。）

なのでforkしてtintColorを画像に反映されないように修正して使用しました。

![Screen Shot 2020-12-08 at 13.14.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/701264/04e1841c-cfc0-12a8-7080-d3825c9c1638.png)

## 修正内容

僕の場合はそのあと画像に色を設定する必要がなかったので
「strongSelf.imageView.tintColor = strongSelf.foregroundImageColorForStyle;」
を適用させないようにif文をざっくり削除しました。
画像にもかけたいケースもある場合は分岐の条件を変更させたり必要だと思います。

```SVProgressHUD.m
if (self.shouldTintImages) {
    if (image.renderingMode != UIImageRenderingModeAlwaysTemplate) {
        strongSelf.imageView.image = [image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
    }
    strongSelf.imageView.tintColor = strongSelf.foregroundImageColorForStyle;
} else {
    strongSelf.imageView.image = image;
}

↓

strongSelf.imageView.image = image;
```

実際に使う側での設定

```hoge.swift
// ダイアログを表示するのに使用
private var requesting: Bool = false {
     didSet {
        if requesting {
            //  R.string.localizable.progress_loading()->"読み込み中"
            SVProgressHUD.show(withStatus: R.string.localizable.progress_loading())
        } else {
            SVProgressHUD.dismiss()
        }
    }
}

private func setupSVProgressHUD() {
    SVProgressHUD.setForegroundImageColor(.primary)
    SVProgressHUD.setMinimumSize(CGSize(width: 150, height: 150))
    SVProgressHUD.setImageViewSize(CGSize(width: 60, height: 60))
    SVProgressHUD.setRingRadius(28)
    SVProgressHUD.setRingThickness(5)
    SVProgressHUD.setDefaultMaskType(.clear)
}
```