OmniAICreator/Qiita-1.07M huggingface dataset:
ORB-SLAM2をビルド済みコンテナーイメージを使って素早く試してみる

# はじめに

この記事ではJetson上でコンテナーイメージを使ってORB-SLAM2を実行する手順を説明します。
手順を実行すると以下のような画面が立ち上がり、ORB-SLAM2を試すことが出来ます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103795/4289d5c3-1901-f9c4-1715-885a588d6517.png)

今回は以下にあるコンテナーイメージを使用します。
ビルド済みであるため、ビルドで苦労することはありません。

今回するコンテナーイメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103795/b16f1031-b97d-2fcf-7563-07061bc0420e.png)

https://hub.docker.com/r/dustynv/ros/tags?page=1&name=slam

Dockerfileはこちらのリポジトリにあります。
https://github.com/dusty-nv/jetson-containers

# 環境
Jetson Nano 4G
Jetpack 4.6
Webカメラ：logicool C505

# 手順

## 1. Default Runtimeの設定

/etc/docker/daemon.jsonを以下のように変更します。
変更後、Jetsonを再起動（ ``sudo reboot`` ）します。

```
{
    "runtimes": {
        "nvidia": {
            "path": "nvidia-container-runtime",
            "runtimeArgs": []
        }
    },

    "default-runtime": "nvidia"
}
```

## 2. コンテナーの起動

コンテナーから画面を表示出来るようにX Windowの設定を行います。
また、Webカメラがコンテナーから参照出来るようにdeviceオプションで設定します。

```
sudo xhost +si:localuser:root
sudo docker run -it --rm --network host \
-e DISPLAY=$DISPLAY \
-v /tmp/.X11-unix/:/tmp/.X11-unix \
-v `pwd`:/scripts \
--device /dev/video0:/dev/video0:mwr \
--name orb-slam2 \
dustynv/ros:foxy-slam-l4t-r32.6.1
```

上記のコマンドを実行すると以下のようにコンテナーが起動されます。
not found librealsense2は、ここでは無視します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103795/1fbc7d71-eb0c-977b-2d5f-8649b57cefe5.png)

## 3. ORB-SLAM2を起動
コンテナーのプロンプトから以下のコマンドを実行します。

```
export LD_LIBRARY_PATH=/tmp/pangolin/build/src:/opt/ORB_SLAM2_CUDA/Thirdparty/DBoW2/lib:/opt/ORB_SLAM2_CUDA/lib:$LD_LIBRARY_PATH
ros2 run ros2_orbslam mono /opt/ORB_SLAM2_CUDA/Vocabulary/ORBvoc.txt /opt/ORB_SLAM2_CUDA/Examples/RGB-D/TUM1.yaml
```
上記のコマンドを実行すると以下のようにORB-SLAM2の画面が表示されます。
カメラ映像がまだ入力されないため、Currnet FrameのWindowは黒い状態です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103795/ef0df59c-9250-d6e7-770f-c88572080b1a.png)


## 4. Webカメラを起動
コンテナーに接続して、Webカメラ（v4l2_camera_node）を起動します。
新しいターミナルを立ち上げて、以下のようなコマンドを実行します。

```
sudo docker ps # 起動しているコンテナーを確認
sudo docker exec -it orb-slam2 bash # orb-slam2という名前のコンテナーに接続
ros2 topic list  # トピックを確認。/cameraトピックを確認出来るはず。
ros2 run v4l2_camera v4l2_camera_node -r image_raw:=camera # cameraトピックにカメラの映像をpublishするように起動する
```

コンテナーに接続して、トピックを確認すると/cameraトピックがあることを確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103795/12f2777c-0b9c-5e7a-7976-4555b2b580a4.png)

v4l2_camera_nodeを起動すると以下のような出力が出ます。
ERRORとWARNが出ていますが、カメラ映像は取得出来ているはずです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103795/5450a513-1016-89d9-f904-c19098ba9042.png)

カメラの映像がORB-SLAM2に読み込まれて処理されている様子が確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103795/a16b8e7d-a8a5-9cbc-6509-7ef2dc70a4ea.png)
Canvas#drawTextを使用している部分での「最新の絵文字のサポート」対応

2022/2からGoogle Play Storeのストア規約に「Android 絵文字ポリシー」が加わり、古い端末でも最新の絵文が表示できるようサポートすることが求められるようになります。
[Android 絵文字ポリシー](https://support.google.com/googleplay/android-developer/answer/11190644?hl=ja)

TextViewを継承しているコンポーネントを使用している部分は、AppCompat(v1.4以上)を用いたり、AppCompatを用いない場合もemoji2ライブラリを使用することでほとんど何もしなくてもorかなり簡単に対応できるよう公式のサポートがあります。 
[最新の絵文字のサポート](https://developer.android.com/guide/topics/ui/look-and-feel/emoji2?hl=ja) 

しかし、[Canvas#drawText](https://developer.android.com/reference/android/graphics/Canvas?hl=ja#drawText(java.lang.String,%20float,%20float,%20android.graphics.Paint)) を使用していている部分(例えば画面表示を元にCanvas(とBitmap)を使用してスクリーンショット風の画像ファイルを1から生成しているときや、TextViewを使わずに完全なカスタムViewでonDraw()メソッドでCnavasに直書きしているときなど)は、上記の公式サイトの内容では不十分だと思います。


そのようなシチュエーションでの最新の絵文字のサポートへの対応方法について記述しています。

# Before(最新の絵文字のサポート対応前)
```kotlin
 // canvas : 描きたい対象のCanvasインスタンス 

 // 描きたいテキスト
 val titleStr = "×××"
 val textPaint = Paint().apply {
     color = android.graphics.Color.BLACK
 }
 val rect = Rect()
 textPaint.getTextBounds(
     titleStr,
     0,
     titleStr.length,
     rect
 )
 // 描きたいテキストの描いた時の横幅を取得
 val textWidth = textPaint.measureText(titleStr) 

 // canvas の上寄せ・横方向中央寄せに描く
 
 val  textMarginTop = 8f // テキストの上方向のマージン
 canvas.drawText(
     titleStr,
     (canvas.width - textWidth) / 2,
     rect.height().toFloat() + textMarginTop,
     textPaint
  )
```

# After(最新の絵文字のサポート対応後)

- app/build.gradle　

dependenciesに`androidx.emoji2:emoji2`を追加します。

```gradle

(略)

dependencies {
    (略)
    def emojiVersion = "1.0.1"
    implementation "androidx.emoji2:emoji2:$emojiVersion"
}
```

- kotlinコード

```kotlin
 // canvas : 描きたい対象のCanvasインスタンス 


 val titleStr = "×××"

 // そのまま canvas.drawTextとすると、端末のデフォルトの絵文字が使われてしまう。
 // 最新の絵文字を表示しようとすると豆腐になった、となる可能性があるのでEmojiCompatを使用するようにする。
 val emoji = EmojiCompat.get().process(titleStr)

 val textPaint = Paint().apply {
     color = android.graphics.Color.BLACK
 }

// StaticLayout+EmojiCompatに作ってもらったCharSequenceを使用すると、Canvasに対しても最新の絵文字を描ける。
val layout = StaticLayout.Builder
    .obtain(
    emoji!!, 0, emoji.length, TextPaint(textPaint),
    canvas.width
    )
    .setAlignment(Layout.Alignment.ALIGN_CENTER) // setAlignment(Layout.Alignment.ALIGN_CENTER)で横方向中央寄せは実現
    .build()

// canvas の上寄せ・横方向中央寄せに描く

val  textMarginTop = 8f // テキストの上方向のマージン

canvas.save()
// 上寄せで上にマージンを適用するためにCanvasの原点をずらす
canvas.translate(0f, textMarginTop)
layout.draw(canvas)
canvas.restore()
```
Slackリマインダーの設定方法

# はじめに

公式ドキュメントにコマンドのサンプルがあるのでそちらを参照ください。

https://slack.com/intl/ja-jp/resources/using-slack/how-to-use-reminders-in-slack

一度設定したリマインダーは編集することができません。
変更したい場合は、削除して作成しなおす必要があります。

また、チャンネルでリマインドするように設定した場合は、`このチャンネルでこれをリマインドするよう設定しました`と自動で投稿されます。
チーム向けのリマインダーをなんどもやり直しているとチャンネルに無意味な投稿がたくさん出ちゃうので、気になる方は自分宛で検証してからチーム向けリマインダーを作成するのが良さそうです。
(リマインダー削除はログ投稿ありません)

## ダイアログ
`/remind`で呼び出せます。
1度きりのリマインドならこれで設定できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628295/9bd51eb0-1c1f-2a40-a9ca-ee37ebb97904.png)


## コマンド
定期的なリマインドや何時間後といった設定はコマンドでやります。
コマンド実行は、リマインド先に依らずどこかのチャンネルやslack bot、自分のDMなどどこでもOKです。

```
/remind リマインド先 本文 リマインドタイミング
```

### リマインド先
個人やチャンネル名を指定します

- `me` 自分自身
- `@name` 個人
- `#channel` チャンネル

### 本文
普通のスラック投稿と同様の書式が使えます。
メンションや改行、引用、リンクなども記述できます。

- `@name XXXXをやること` メンション付き

### リマインドタイミング

- `at` `on` 日時を指定するとき
- `in` 経過時間を指定するとき

**1回だけ**

- `at 10:00` 次の10時
- `at 1/12 10:00` 次の1/12 10時
- `in 3 hours` 3時間後

**定期**

- `at every Monday 10:00` 毎週月曜日10時
- `at every other Tuesday 10:00` 隔週火曜日10時
- `1/10 at every other Wednesday 10:00` 1/10からの隔週水曜日10時

定期実行は、以下の記事も参考にさせていただきました。

https://qiita.com/kamikenta/items/9c7b96b4d06d18666f1e
JestでReactのテスト中にエラー Jest Could not locate module FileName.css (mapped as identity-obj-proxy)

#背景
Reactアプリのレンダリングについてのテストとして、Jestのスナップショット機能を使用している。

テスト実行時に「Jest Could not locate module FileName.css :mapped as identity-obj-proxy」というエラーメッセージが出力されたのでその解決策をまとめた。

※「FileName.css」にはプロジェクトに存在するCSSファイル名が入る。

```
> myProject@0.0.1 test C:\Users\admin\Documents\myApp
> jest

FAIL _tests_\Home.test.js
    Test suite failed to run

    Configuration error:

    Could not locate module react-datepicker/dist/react-datepicker-cssmodules.css (mapped as identity-obj-proxy)

    Please check your ○○ for these entries:
    {
      "moduleNameMapper": {
        "/^.+\.(css|less)$/": "identity-obj-proxy"
      },
      "resolver": undefined
    }

Test Suites: 1 failed, 1 total
Tests:       0 total
Snapshots:   0 total
Time:        1.894s
Ran all test suites.
npm ERR! Test failed.  See above for more details.
```

#開発言語 (バージョン情報)
- React.js (17.0.2)
- Next.js (11.1.2)
- TypeScript (4.4.3)
- Jest (27.2.2)


#解決策

ターミナルで以下のコマンドを実行する。ただし実行はpackage.jsonのあるディレクトリでおこなう。

```
npm install --save-dev identity-obj-proxy
```


#参考
https://stackoverflow.com/questions/46107310/jest-could-not-locate-module-filename-css-mapped-as-identity-obj-proxy
【iOS × アーキテクチャ】iOSにおける、GUI/システムアーキテクチャとは？

# 目的
`GUIアーキテクチャ` `システムアーキテクチャ` についてまとめること


# 流れ
0. そもそも、アーキテクチャ とは？
1. GUIアーキテクチャ の例
2. GUIアーキテクチャ とは?
3. システムアーキテクチャ の例
4. システムアーキテクチャ とは？
5. モバイルアプリ開発における問題点
6. 5を解決するアーキテクチャ


# 0. そもそも、アーキテクチャ とは？
**アプリケーションを開発する上で、開発者同士の共通認識を行うためのもの**

開発者同士の共通認識とは？
→ 3つある

① : クラスなどの要素の関係性整理
② : 伝達順序の整理
③ : 開発の規則性
<br>

**根幹にあるものは？**
`Presentation Domain Separation : プレゼンテーション領域の分離 ` という考え。
「システム本来の関心領域(ドメイン)を、UI(プレゼンテーション)から引き離す」 ということ。
`プレゼンテーション( =View )`, `ドメイン( =Model )` を分けて考えましょうね。 というもの。
※ プレゼンテーション と ドメイン については、下の補足にて説明があります。
<br>

**種類(iOSの場合)**
一般的にiOSアプリのアーキテクチャと呼ばれているものには、2種類存在する。
`GUIアーキテクチャ` と `システムアーキテクチャ` だ。
次の章からは、GUI/システムアーキテクチャについて、採用されているアーキテクチャの例をだしながら説明していく。
(それぞれのアーキテクチャについての説明は、また後日...)


### 補足

**■ プレゼンテーション・ドメイン とは？**
`プレゼンテーション ( =View )`:
「UIに関係するロジック, ユーザーが操作する画面」
どのようにレイアウトを行い、情報を装飾するか を考えている

`ドメイン ( =Model )`:
「アプリケーションのユーザーが思い描く、"システム本来の関心領域"」
情報をどのようにモデリングし処理するか を考えている

**■ プレゼンテーション と ドメイン を分けるメリット**
・役割が分かれているため、理解しやすい
・それぞれを一つのオブジェクトとして扱えるため、コードの重複を防げる
・複数人での開発で、分業がしやすい
・テストコードが書きやすい


# 1. GUIアーキテクチャ の例
GUIアーキテクチャには以下のアーキテクチャが含まれる。<br>
`MVC :Model-View-Controller`
`Presentation Model パターン (MVC+Presentation Model)`
`MVVM :Model-View-ViewModel`
`MVP :Model-View-Presenter`
`Flux`

# 2. GUIアーキテクチャとは

Viewからの視点で、`PDS`を実践するため際の具体的なレイヤー構造をパターンとして示したもの。

### GUIアーキテクチャの "欠点"
「UIか、それ以外か」　という分け方しかできないこと
GUIアーキテクチャにおいて、「Model=UIに関係しない処理全て」となってしまう
しかし、UIに関係しない処理 の中にも様々な種類が存在する。それを分けることなく、Modelという1つにまとめて考えるのは危険。

以下の2つは、本来 プレゼンテーション・ドメイン どちらにも当てはまらない。しかし、GUIアーキテクチャでは、「ドメイン( =Model )としてひとまとめにされる」 → 役割ごとに分類を行えていない
①:サーバ API からのデータ取得を試 み、そこで発生したネットワークエラーをハンドリングする
②:データをストレージに永続化する」


# 3. システムアーキテクチャ の例
システムアーキテクチャには以下のアーキテクチャが含まれる。<br>
`レイヤードアーキテクチャ`
`Hexagonal Architecture`
`Onion Architecture`
`Clean Architecture`

# 4. システムアーキテクチャ とは？
**"GUI"アーキテクチャの汎用性を増したもの**
さらに詳しくいうと、"システム"アーキテクチャは、"GUI"アーキテクチャよりも広い、UIという単位にとらわれることなくシステム全体の構造を示せるもの。
「システムアーキテクチャ > GUIアーキテクチャ」

### なぜそう言えるのか？
GUIでは行っていない、ドメインの先をどのように分けるのか ということを考えているから。

GUIアーキテクチャは、プレゼンテーションとドメインを分けて考える。
しかし、ここでのドメインとは`UIに関係しない処理全て`となる。
「情報をどのようにモデリングし処理するか」を考えているドメイン が、このような曖昧な定義では開発を行う上で、開発者同士の混乱を招きかねない。

そこで、システムアーキテクチャでは、GUIアーキテクチャでは考えない、「ドメインの先でどのようにレイヤーを切り分けるべきか」や「システム全体をどのように接合すべきか」といったものを考える。


# 5. モバイルアプリ開発における問題点
モバイルアプリ開発における問題点は、「画面遷移」です。

1〜4 では、GUI/システムアーキテクチャについて説明を行った。
しかし、「モバイルアプリ開発においては重要であるにも関わらずどちらのアーキテクチャでもヒントを与えてくれない関心事」があります。
それが　画面遷移 です。

モバイルアプリは、Webアプリ と違い、UIコンポーネントが大きい。操作を指で行うためです。
一画面に多くの情報を載せることが難しく、画面遷移を繰り返すことで快適なユーザー体験を実現した。

しかし、「多くの画面遷移をどう設計するのか」は既存のアーキテクチャでは対処できない問題となっています。

次の章では、それを解決するためのアーキテクチャをいくつか示します。


# 6. 5を解決するアーキテクチャ
`Coordinatorパターン と MVVM-C`
`Routerパターン と VIPER`
`Micro View Contrller`


# 参考文献

『iOSアプリ設計パターン』 (電子版: 税込 3200円)

https://peaks.cc/books/iOS_architecture
（無課金で）Reactで手書き風アニメーションしたい！

## はじめに
<!-- 発端や概要を記載 -->
こんにちは！UI/UX大好き[そると](https://twitter.com/jsalt_0525)です！

突然Reactで手書き風アニメーションをしてみたくなったのでやってみました。

Reactじゃなくても使える方法なのでぜひ参考にしてみてください！

## 前提
僕のこんな突然の思いつきにお金を投資するのはもったいなので以下の条件でできる方法を探してみました。

- 課金したくない
- めんどくさくない
- カスタムできる

## 実現方法

### 1. Figmaで手書き文字を書く
Figmaとは、ブラウザ上で簡単にデザインができるツールです。フリープランがあり無料で利用できるので、誰にでも手軽に導入することができます。
タブレットとタッチペンがあれば尚よしですが、無い人も最悪マウスで書くことができます。
Figmaを起動したらメニューにあるペンマークのアイコンから「Pencil」を選択して自分が好きな文字を書きます。
![スクリーンショット 2022-01-15 17.30.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181865/b50b28d3-9cd9-67e4-5133-4a0f4cd12e94.png)
こんな感じ
↓
![スクリーンショット 2022-01-15 17.32.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181865/73d3ae07-20d8-5f29-8399-5126b0e1e23b.png)

### 2. 手書き文字をSVG形式でエクスポート
書いた文字を選択し、画面右下の「Export Group 1」をクリックしてSVG形式でエクスポートします。
![スクリーンショット 2022-01-15 17.33.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181865/aa166ee3-a4d7-eb40-e55b-c8951fcbce2b.png)

### 3. エクスポートしたSVGをプロジェクトフォルダにコピー
エクスポートしたSVGを自分のプロジェクトフォルダの好きな場所にコピーします。

### 4. vivus.jsをインストール
[vivus.js](https://maxwellito.github.io/vivus/)は簡単に手書きSVG画像をアニメーションさせることができるライブラリです。SVG画像のパスが一つひとつ線を描いているようなアニメーションを作ることができます。

```
$ npm install vivus
```

### 5. 実装
作成したSVGをインポートしてvivusを実行すれば手書き風アニメーションの完成です！

```App.js
import { useEffect } from "react";
import title from './title.svg' //手書き文字のSVG
import Vivus from "vivus";

function App() {
  
  useEffect(() => {
    // アニメーション
    new Vivus('title', {duration: 300, file: title, type: "oneByOne"});
  },[])

  return (
    <div id="title"/>
  );
}

export default App;
```

## 完成イメージ
初期起動時のローディングアニメーションとして使用しても良いですよね

https://fashion-js.web.app/

## 補足
今回はFigmaを使ってSVG画像を作成しましたが、Illustratorやその他のデザインツールを使用しても同じことができます。あくまで無課金で実現したかったのでFigmaを使用しました。
[備忘録] pdf.jsで日本語が読み込めない場合はcMapを設定する必要があった

このバージョンを使用しました。

```
        "pdfjs-dist": "^2.12.313",
```

npmでpdfjsをインストールしてelectronで使おうとしたとき、このようなエラーが出て一部の日本語がレンダリングされない問題に引っかかりました。

```
Warning: loadFont - translateFont failed: "TypeError: Failed to fetch".
Warning: Error during font loading: Failed to fetch
```

getDocumentするときにcMapフォルダがある場所を指定してやると表示されるようになりました。

```
        pdfjs.getDocument({
            url: path,
            cMapUrl:  "cmaps/",
            cMapPacked: true,
        });
```
[メモ]Kotlin ジェネリクスのin / out

## 視覚的に
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/289114/151a6020-c86c-70e5-393d-5f98a2a5de1b.png)


## out(共変)
sub1 = sub2(全く違うものに変えられてしまう)を成り立たせてしまうことになるので、変更不可。

## in(反変)
中身は自由に入れ替えてもいい代わりに、参照不可。
一都三県空き家率マップの作業進捗

#前回中間報告からの進捗報告

前回報告の進捗は、総務省統計局の住宅・土地統計調査のデータをもとに市区町村単位の空き家率を算出し、そのCSVデータを市区町村ごとの境界線データに紐付け
→Mapbox Studio上で簡易的に可視化する実装までを報告しました。

https://docs.google.com/presentation/d/1rdNYrq0WUOnIdI-mxJzm_W961YzSmf_J0hkL1oKQoCM/edit?usp=sharing


今回の中間報告ではそこからフロントのデザインを進めていましたのでその報告をしたいと思います。
前回も言っていましたが、個人的に理想とするUIは日経新聞社がMapbox Studio上で作成している「[ふるさとクリック](https://vdata.nikkei.com/newsgraphics/regional-regeneration/population-map/#)」シリーズのフロントデザインです。

実装に関しては、Mapboxのインターンでお世話になっているメンターの方と平澤さんの多大なヘルプのもと進めています。
「ふるさとクリック」を目標として実装を始めましたが課題が多く苦戦中です。。

####Mapbox Studioでの可視化について新たな課題

 - 県境の線とズームレベルの設定がうまくいかない
   - (ズームレベルをかなり上げないとCSVの値と紐付けたデータを見ることができない)
 - 年度ごとのタブを設置する、ランキング表の表示、クリック時の挙動（空き家率の推移をグラフで表示、人口データと併せて表示）などのUIの実装難易度の高さ
 -　欠損していないCSVデータがなぜか読み込まれない
 






#打開策

デザインに関して、「ふるさとクリック」の実装と同じような完成形を目指す実装レベルでは自分の技術不足で時間的に間に合うことができなそうでした。CSSに関して中身を見ることができるのでこれを参考にしようと思いましたが、日経独自のCSSで書かれているので、この中身を参考にしすぎるのは問題になるかと思われ、一からJSを書いていくことになってしまいます。

そこで、残りの日数では実装のレベルを下げて[Mapbox GL JS](https://docs.mapbox.com/jp/mapbox-gl-js/example/)のドキュメントから、実装できそうなやり方でデザインしていく方針にしました。

あまり時間がないですが大枠の形はできているのでできるところまで妥協しないように頑張りたいです。


####GitHubレポジトリはこちら
https://github.com/furuhashilab/2021gsc_YosukeKanda
【Docker】コマンドメモ

いつも必要になるたびに調べている docker のコマンドをメモしたい。
なので、自分のメモのためにこの投稿を作りました。

## イメージやコンテナの整理

コンテナを全削除する

```shell
$ docker ps -aq | xargs docker rm
```

イメージを全削除する

```shell-session
$ docker images -aq | xargs docker rmi
```

### 改行コードについて

この記事が素晴らしすぎた。

https://qiita.com/uggds/items/00a1974ec4f115616580


## そのほか自分の過去のメモ

https://qiita.com/XPT60/items/8ed0600f765c94db451d


https://qiita.com/XPT60/items/8650b1d4b674def783a8


https://qiita.com/XPT60/items/7ef151371522bd54b438

https://qiita.com/XPT60/items/e123fe88ec88a4ac2749
BigQueryのUDFをJavaScriptで定義すると、int型の引数はstring型の値としてインタープリタに渡ってくる

掲題のとおり。JSのnumber型は(多分)doubleで、仮数部が52bitしかなくて64bitの整数は表現しきれないから・・ですかね

実行例
![スクリーンショット 2022-01-15 17.28.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7973/a93286bd-47ba-daed-cf84-1fd729b6bbfe.png)
Docker　コマンドチートシート

# はじめに
自分用にチートシートっぽく書いています（勉強中なので間違った情報が記載されているかもしれません）。
随時追記するかも。。

## ビルド
Dockerfileがある階層で実行
　→　　イメージが作成される

```
% docker build .
```
## ビルド（Name&Tag付き）
```
% docker build -t {Name}:{Tag} .
```

## コンテナ情報一覧（起動コンテナ）
```
% docker ps
```
## コンテナ情報一覧（すべてのコンテナ）
```
% docker ps -a
```

### コンテナを作成+起動
```
% docker run {コンテナ名}
```

## コンテナ起動
作成済みのコンテナを起動する

```
% docker start {コンテナ名}
```

## コンテナ作成+起動（名前付き）
```
% docker run --name {名前} {イメージ名}
```
## コンテナ停止
```
% docker stop {コンテナ名}
```
## コンテナ削除
コンテナが停止していないと削除できない

```
% docker rm {コンテナ名}
```

## イメージ情報一覧
```
% docker images
```

## イメージの詳細取得
```
% docker image inspect {IMAGE_ID}
```


## イメージ削除
```
% docker rmi {IMAGE_ID}
``` 

## イメージ削除（使用されていないイメージの削除）
一括で削除される

```
% docker image prune
```

## イメージIDからコンテナ起動→停止時にコンテナ削除
コンテナを停止する際に、自動的にコンテナの削除を行なってくれる

```
% docker run --rm {IMAGE_ID}
```

## コンテナにファイル（フォルダー）を追加
```
% docker cp {追加したいファイル名} {コンテナ名}:{保存先ディレクトリー}
```


## コンテナから特定のファイル（フォルダー）を取得
```
% docker cp {コンテナ名}:{取得したいファイルのディレクトリー} {対象ファイル名} 
```

## イメージのName,Tag修正
！修正前のイメージは残る！

```
% docker tag {既存のName}:{既存のTag} {修正後のName}:{修正後のTag}
```

## ボリューム一覧
```
% docker volume ls
```

## ボリューム削除
```
% docker volume rm {ボリューム名}
```


# Docker Hub編
Docker Hubへpush・pullを行う。
予めアカウントを作成して、リポジトリを作成する（以下のコマンドの挙動確認を行うのにはFree版でOK）。

https://hub.docker.com/
## push
pushしたいイメージの{REPOSITORY名}をDocker Hub側で作成したユーザー名とリポジトリ名で合わせる必要がある
例えば、作成したユーザー名が`taro`でリポジトリ名が`test-repo`の場合はpushするイメージの{REPOSITORY名}は`taro/test-repo`である必要がある。

```
% docker login
% docker push {ユーザー名}/{リポジトリ名}
```

## pull
デフォルトでlatestがpullされる

```
% docker pull {ユーザー名}/{リポジトリ名}
```
【具体例あり】変数・定数宣言の時の論理演算子 && と || の挙動と AND, OR の結びつけ【 Javascript 】

# この記事を書いた経緯

普段このような認識で開発していたのですが、ふと気になって、何で変数・定数宣言の時の論理演算子 `&&` と `||` って何であの挙動になるのかについて調べてみました。

MDN の
・[論理積 (&&) - JavaScript | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Logical_AND)
・[論理和 (||) - JavaScript | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Logical_OR) 

を読んでみてもピンと来なかったのですが、 読んだ内容を整理して自分で色々実験してみたら、どうしてその挙動になるのかが分かりました。
同じ道を辿る方は多くいらっしゃると思うので、内容をまとめて投稿しました。

## 筆者のこれまでの状況

- 普段 `&&` と `||` は完全に `AND` と `OR` のつもりで使っている。
- 「`&&` は左側が `true` の時に右側のものが返される、 `||` は左側が `false` の時に右側のものが返される」ということ自体は知っていたけど、前述の `AND` や `OR` とは全く別の使い方だと思っていた。

結論 → 別の使い方ではありませんでした。
（むしろ、本来の用法は後者で、前者の使い方はその応用でした）

# 実験してみた

## ① `&&` の場合 ( boolean && boolean )

```javascript
true && true // 左側が true なので、右側の true が返される
```

結果 ： `true`

```javascript
true && false // 左側が true なので、右側の false が返される
```

結果 : `false`

```javascript
false && true // 左側が false なので、左側の false が返される
```

結果 : `false`

```javascript
false && false // 左側が false なので、左側の false が返される
```

結果 : `false`

## ② `||` の場合 ( boolean || boolean )

```javascript
true || true // 左側が true なので、左側の true が返される
```

結果 ： `true`

```javascript
true || false // 左側が true なので、左側の true が返される
```

結果 : `true`

```javascript
false || true // 左側が false なので、右側の true が返される
```

結果 : `true`

```javascript
false || false // 左側が false なので、右側の false が返される
```

結果 : `false`

たしかに、 `AND` と `OR` と同じ動き方しとる！！ Σ ( ゜゜)

ちなみに…

## JavaScript において、 `true` とみなされるもの、 `false` とみなされるもの

・[Truthy (真値) - MDN Web Docs 用語集: ウェブ関連用語の定義 | MDN](https://developer.mozilla.org/ja/docs/Glossary/Truthy)
こちらに書かれている通り、

```javascript
false

0

-0

0n

"" // 空の文字列。 '' や `` も当てはまる。

null

undefined

NaN
```

これらが `false` とみなされ、それ以外のものは `true` とみなされます。
なので、あまり見ない記法なのですが

```javascript
const name = 0 || 'Tomoki';
console.log(name); // Tomoki

const age = 'aiueo' && 25;
console.log(age); // 25
```

一応こんな感じにも書けます。（わざわざこう書くべき状況は思いつかないのですが）

# まとめ

- 「`&&` は左側が `true` の時に右側のものが返され、 `||` は左側が `false` の時に右側のものが返される」
- `AND` , `OR` として `&&` , `||` を使う用法は、上記を利用している。

勉強している時は何でもそうですが、ただ暗記するよりも、しつこいくらい丁寧に確かめてみて腑に落ちる状態にする & 有機的に意味や用法を結びつける事が大事だなと改めて思いました。

### 参考
・[論理積 (&&) - JavaScript | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Logical_AND)
・[論理和 (||) - JavaScript | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Logical_OR) 
・[Truthy (真値) - MDN Web Docs 用語集: ウェブ関連用語の定義 | MDN](https://developer.mozilla.org/ja/docs/Glossary/Truthy)
Flutter(Dart)の基礎知識(Errorの処理)

一般的なErrorと違ってプログラム実行中における想定内のError(Exception`例外`)が発生する箇所によく使われるのが`try`や`throw`、`finally`です。今回はそれぞれの使い方をまとめて行きたいと思います。中でも良く使われるのが`try catch`で**try内部**で発生する全ての例外に処理を実行することができます。

##try on

```dart
void main() {
  String hoge = 'hogehoge';
  try {
    print(int.parse(hoge)); // hogeをint型に変換させようとしている
  } on FormatException {  // on内部でFormatExceptioを指定して対処
    print('int型でなくString型ですよ!');
  }
} // => intでなくStringですよ!

// try {
//  例外が発生する可能性のある処理
// } on 例外名 {
//  指定した例外が発生した時の処理 
// }
```
##try catch
```dart
void main() {
  String hoge = 'hogehoge';
  try {
    print(int.parse(hoge));
  } catch (e) { // catch内部引数にすべての例外であるオブジェクトを指定
    print(e); // e => Exceptionの型情報をprintで取得 
    print('try内部で例外発生');
  }
} // => FormatException: hogehoge,  try内部で例外発生
//                       ^
// try{
//  例外が発生する可能性のある処理
// }catch(e){
//  指定した例外が発生した時の処理
// }
```
##try on catch
```dart
void main() {
  String hoge = 'hogehoge';
  try {
    print(int.parse(hoge));
  } on FormatException {
    print('例外発生'); // 最初の例外チェック、ここで指定されていた例外があれば処理を実行
  } catch (e) {
    print(e); // 指定した例外がなければこちらのcatch内部で処理を実行
    print('try内部で例外発生');
  }
} // => 例外発生

// try{
//  例外が発生する可能性のある処理
// } on 例外名 {
//  指定した例外が発生した時の処理
// }catch(e){
//  指定した例外が発生した時の処理
// }
```
##throw
```dart
void main() {
  int hoge = 500;
  try {
    if (hoge > 100) {
      throw '100より大きい'; //try内部のif文によく使われる
    }
    print(hoge); //throwが実行されるとtry内部での処理を中断してcatch内部の処理に移る
  } catch (e) {
    print(e); //throwで指定したError文を(e)で出力
    print('throwが発火して例外発生');
  }
} // => 100より大きい, throwが発火して例外発生


// try {
//  if () {
//  throw 'Error文を指定';
//  }
// } catch (e) {
//  print(e) //throwで指定したError文が出力
//  指定した例外が発生した時の処理
// }
```
##finally
```dart
void main() {
  String hoge = 'hogehoge';
  try {
    print(int.parse(hoge));
  } catch (e) {
    print(e);
    print('try内部で例外発生');
  } finally {
    print('例外の発生の有無に関わらず、最後に処理を実行');
  }
} // => FormatException: hogehoge, try内部で例外発生, 例外の発生の有無に関わらず、最後に処理を実行
//                       ^
// try {
//   例外が発生する可能性のある処理
// } catch (e) {
//   指定した例外が発生した時の処理
// } finally {
//   例外処理の最後に実行したい処理
// }
```
##rethrow
```dart
main() {
  void hogeFunc() {
    try {
      throw Exception('例外発生'); // throw Exceptionで意図的に例外を発生
    } on Exception catch (e) {
      print(e); // catch内部の引数でException型(e)を指定
      rethrow; // rethrowでtry catch finallyの外に例外を弾く（関数の外でcatch）
    } finally {
      // finally内部は例外の有無にかかわらず実行される、省略可。
      print('最後に必ず実行');
    }
  }

  try {
    hogeFunc();
  } catch (e, h) {
    // 型指定無しのcatchは、何型かわからない例外全てキャッチする
    // catchに仮引数を２つ指定すると、２つ目はStackTraceオブジェクトが入る
    print(h);
  }
}

// => Exception: 例外発生,
// 最後に必ず実行,
// #0  main.hogeFunc,
// #1  main,
// #2  _delayEntrypointInvocation.<anonymous closure>,
// #3  _RawReceivePortImpl._handleMessage
```
each.with_indexメソッド(Ruby)

Ruby３.１
<a href = "https://docs.ruby-lang.org/ja/latest/method/Enumerator/i/with_index.html"> Enumeratorクラスwith_index </a>
<a href = "https://docs.ruby-lang.org/ja/latest/method/Enumerable/i/each_with_index.html"> Enumerableモジュールeach_with_index </a>
要素にインデックスを添えて繰り返す

```ruby
a = ["a","b","c"]
a.each.with_index(2) do |s, i|
  puts "#{i}:#{s}"
end

2:a
3:b
4:c
#each.with_index(引数)とすることで、引数を受け取る。
#each_with_indexは引数を受け取らないため、添字は０から始まる
```
サイトのキャプチャや自動OGP画像生成、動的サイトのHTML取得のSaas「WebNium」を公開

# 出来ること
- WebページキャプチャAPI
- 動的HTML取得API
- OGP画像自動生成

Saasのページは下記

https://web-nium.web.app/



# 作ろうと思ったきっかけ

- 画像キャプチャや動的サイト(javascriptが動いてHTMLが生成されるサイトSPA等)のHTMLを取得したいということがよくあり、
しかし、そのためにseleniumを実行したりするのがめんどくさいなーってことで、簡単に扱えるWebApiをと思った
- SPAで動的OGPを実装したかった（後に、metaタグを切り替えられないからOGP生成が動的であっても、ページごとにOGPを設定することは不可能だと分かる）



# 技術スタック
- フロントエンド
typescript
Vue.js
Firebase Hosting

- バックエンド
python
Heroku

- データベース
Firebase RealtimeDatabase

- 認証
Firebase Authentication



# OGP画像自動生成
前述の通り本当はSPAで、各ページの画像を切り替えたかったが、出来なかった
とはいえ、OGPの画像を用意するのがダルいという場合はこれを使うとよいのかも
ただ、認証とキャッシュが未実装なのがβであるというところ・・・。
Uncaught TypeError: Cannot set properties of null (setting 'onclick')

# 前提
「クリック」の文字を押下すると「クリックされた！」が表示されるプログラムの作成。
以下のエラーがでた。

Uncaught TypeError: Cannot set properties of null (setting 'onclick')

### HTML
```
<body>
    <div id="text-button"><p id="text">クリック</p></div>
</body>
```
### Javascript
```
document.getElementById("text-button").onclick = function() {
  document.getElementById("text").innerHTML = "クリックされた！";
};
```

# 解決法
以下に変更。
### Javascript
```
window.onload = function () {
  document.getElementById("text-button").onclick = function () {
    document.getElementById("text").innerHTML = "クリックされた！";
  };
};
```

window.onload = function () とは
ページが完全に読み込まれた直後に実行させたいスクリプトを書く方法である。

# 原因
```
 <div id="text-button"><p id="text">クリック</p></div>
```

が実行される前に

```
document.getElementById("text-button").onclick = function() {
  document.getElementById("text").innerHTML = "クリックされた！";
};
```
が実行されているから
document.getElementById("text-button").onclickが
nullになり、エラーが出る。

"text-button"なんて無いって言われている。

# 終わりに
実行タイミングを理解する必要がある。
Reactでブロック崩しのボールみたいなのを作る（デザイン応用例付き）

## はじめに
<!-- 発端や概要を記載 -->
こんにちは！UI/UX大好き[そると](https://twitter.com/jsalt_0525)です！

Webページを華やかにしたかったので思いつきで作ってみました。
※ブロック崩しを作るわけではないです。

実際に下記で紹介するコンポーネントを使用して作成したWebサイトを最後に載せておりますのでお楽しみに。

## 実装

### ブロック崩しのボール的なコンポーネント
画面の横幅・縦幅いっぱいに暴れ回るボールを作成したかったので[こちら](https://ryotarch.com/javascript/react/get-window-size-with-react-hooks/)を参考に画面の横幅・縦幅を取得するカスタムフック(useWindowDimensions)を使用しております。

表示位置・動き出す方向は固定になっておりますが、引数で指定した位置・方向に動き出すことができればもっと暴れ回らせますね！

```Ball.js
import React, { useState, useEffect } from 'react';
import { useWindowDimensions } from './useWindowDimensions'
  
function Ball() {

    // 画面の縦幅・横幅取得するカスタムフック
    const { width, height } = useWindowDimensions();
    
    // 横位置
    const [x, setX] = useState(10);

    // 縦位置
    const [y, setY] = useState(10);

    // 横移動フラグ（true:右に移動、false:左に移動）
    const [moveXflag, setmoveXflag] = useState(true);

    // 縦移動フラグ（true:下に移動、false:上に移動）
    const [moveYflag, setmoveYflag] = useState(false);

    // サイズ
    const ballSize = 10;

    useEffect(() => {

        // 端に行ったら方向を逆にする
        if (y == 0) {
            setmoveYflag(true);
        }
        if (x == width - ballSize) {
            setmoveXflag(false);
        }
        if (y == height - ballSize) {
            setmoveYflag(false);
        }
        if (x == 0) {
            setmoveXflag(true);
        }

        // 移動速度
        const timeout = setTimeout(() => 
            {
                if (moveXflag) {
                    setX(x + 1);
                } else {
                    setX(x - 1);
                }
                if (moveYflag) {
                    setY(y + 1);
                } else {
                    setY(y - 1);
                }
            }
        , 10);

        return () => clearTimeout(timeout);
        
    }, [x, y])
  
    return (
        <div style={{
            position: "absolute",
            top: y,
            left: x,
            width: ballSize + "px",
            height: ballSize + "px",
            boxShadow: "0 5px 10px 0 rgba(0, 0, 0, .3)",
            borderRadius: "50px",
            background: "red"
            }}>
        </div>
    );
}

export default Ball;
```

### 使い方

```App.js
import Ball from './Ball';

function App() {
  return (
    <div>
      <Ball/>
    </div>
  );
}

export default App;
```

## デザインに落とし込んだ実例
ファッション系のなんちゃってECサイトを作りましたが、ホーム画面が寂しくなりそうだったので画面にいくつかのボール（ランダムで商品を表示）を配置してそのボールから商品詳細に遷移できるようにしました。

https://fashion-js.web.app/
bigipコマンド一覧

ホスト名取得

```
uname -n
```

便利通信状態サマリ(30秒単位)
```
bigtop -n -delay 30 -noes all
bigtop -n -delay 30 -vips all
```

バージョン確認

```
tmsh show sys version
tmsh show sys software
```

CPU使用率

```
tmsh show sys cpu
tmsh show sys host-info
```

Memory

```
tmsh show sys memory
```

時間確認

```
tmsh show sys clock
```

ltmログ確認

```
tmsh show sys log ltm
cat /var/log/ltm
```

macアドレス確認
```
tmsh show sys mac-address
```

BIG-IPが所有しているIPアドレス一覧
```
tmsh show sys ip-address
```

ハードウェア情報
```
tmsh show sys hardware
```

ipパケット情報
```
tmsh show sys ip-stat
```

エラーパケット確認？
```
tmsh show sys traffic
```



ディスク使用率

```
df -h
```

コネクション数

```
tmsh show sys performance connection
```

スループット

```
show sys performance throughput
```


ucsバックアップ

```
tmsh save sys ucs file.ucs
```



qkviewの取得

```
nice -n 19 qkview
```
サービス状態確認
```
tmsh show sys service
```

ノード状態確認
```
tmsh show ltm node
```
プール状態確認
```
tmsh show ltm pool
```

バーチャルサーバ状態確認
```
tmsh show ltm virtual
```
バーチャルアドレス状態確認
```
tmsh show ltm virtual-address
```
プロファイルの状態確認
```
tmsh show ltm profile
```
snatの状態確認
```
tmsh show ltm snat-translation
```
nodeの状態確認
```
tmsh show ltm node
```
ネットワーク情報取得
```
tmsh show net interface
```
ルーティング情報取得
```
tmsh show net route
ip r
```
macアドレステーブル情報 ※ネットワークエンジニア向き
```
tmsh show net fdb
```
ARP情報確認
```
tmsh show net arp
```
BIG-IPログイン失敗確認
```
tmsh show auth login-failures
```

BIG-IP自体の設定IPアドレス確認
```
tmsh list net self
```
BIG-IP自体のVLANアドレス確認
```
tmsh list net vlan
```
監視設定一覧
```
tmsh list ltm monitor
```
パーシステンス設定一覧
```
tmsh list ltm persistence
```

BIG-IP設定確認
```
tmsh list sys global-settings
```
iRULE設定確認
```
tmsh list ltm rule
```

ucsのバックアップ情報確認
```
tmsh list sys ucs
```

ntpの設定状態確認
```
tmsh list sys ntp
```
snmpの設定状態確認
```
tmsh list sys snmp
```

https://itengine.seesaa.net/article/440167533.html

https://www.infraeye.com/study/bigip35.html
AWS - S3の種類

クラウドプラクティショナーの勉強をしていて、S3に種類がたくさんあって覚えられないので、自身のアウトプット学習のために内容を纏める。
上が一番コストが高く、下が一番コストが低い。

#S3 標準
・頻繁にアクセスするデータ用
・最低3つのAZにデータを保存
・ウェブサイト、コンテンツ配信等、データ分析など、様々なユースケースに適している
・他のストレージクラスよりコストが高い。

#S3 標準 - 低頻度アクセス（S3 標準 - IA)
Infrequent Access = まれなアクセス
・アクセス頻度の低いデータに最適
・最低3つのAZにデータを保存
・S3標準と同じレベルの可用性
・S3標準よりもストレージ料金が低いが、取り出し料金が高い

#S3 1ゾーン - 低頻度アクセス（S3 1ゾーン - IA）
・1つのAZにデータを保存（だから1ゾーン）
・コストを節約する必要があり、AZに障害が起きても構わない場合はこれを使う
・最悪はデータが消失するので、ローカルデータなどから復元できるようにしておく必要がある

#S3 Intelligent-Tiering
Intelligent = 頭がいい
・アクセスする頻度が不明たったり、変化するデータに最適
・オブジェクトごとに月単位のモニタリング料金と、オートメーション料金が発生する
・30日間連続してアクセスのなかったオブジェクトは、S3 標準 - IAに自動で移動される
・IAに移動したオブジェクトにアクセスがあると、S3 標準に自動で移動される

#S3 Glacier
Glacier = 氷河
・データアーカイブ用に設計された低コストストレージ
・データを取り出す（開く）のに3～5時間くらい掛かる
・迅速取り出し機能というものがあるらしく、これを使えば2～5分で取り出せる

アーカイブ=ここでは古いデータの塊とかって解釈でOK

#S3 Glacier Deep Archive
・データを取り出す（開く）のに12時間くらい掛かる


以上がS3の種類。
学生とかでクラウドプラクティショナーの勉強している人は、Glacierとかどういう場面で使うか、想像つかないんじゃないかな。
会社のパソコンって、全従業員のパソコン操作ログや送受信したメールなどを数年～無期限で保管していたりして、内部不正や警察沙汰、訴訟等が起きた場合に、証拠として提示する義務があるんだよね。こういったデータってデータ量は莫大で且つ普段はアクセスする事がないので、S3 標準とかに置いとくとめちゃくちゃ無駄なコストになっちゃうのさ。

なのでGlacierとかに保管してコストを低く抑える必要があるわけ。
Alexa スキルが無効化されたら永続アトリビュートを自動削除する


いまさらですが、
[永続アトリビュート](https://developer.amazon.com/ja-JP/docs/alexa/alexa-skills-kit-sdk-for-nodejs/manage-attributes.html)を使っているスキルで、スキルが無効化されたときに、必ず永続アトリビュートに登録されているユーザーも削除するためのメモ。

永続アトリビュートを使用している場合、Amazon DynamoDB に値が格納されますが、スキルが無効化されてもこの値は削除されません。そのため無効化されたときに不要になるオブジェクトやその他もしっかり削除するようにしましょう。
再度、ユーザーがスキルを有効化したとしても、その時点で割り当てられるユーザーIDは以前使っていたものとは異なるIDが割り当てられるため、IDを残しておく必要はありません。

# スキルが無効化された事に気づくには

スキルが無効化されると、スキルは `スキル無効化イベント` を受け取ることができ、これによって無効化されたことに気づくことができます。ただし何もしないとイベントは送られてきません。

# どうすればイベントを受け取れるのか

1. スキルマニフェストに `スキル無効化イベント` を追加する
1. Lambdaにハンドラーを追加する


# 1. スキルマニフェストにイベントを追加する

これ忘れがちです。
スキルマニフェストに記載しないと、Lambdaにハンドラーを作ったとしてもイベントは送られてきません。さらにイベント関連のマニフェストは、Alexa Developer Consoleからは設定できないので SMAPI の [update-skill-manifest](https://developer.amazon.com/ja-JP/docs/alexa/smapi/ask-cli-command-reference.html#update-skill-manifest-subcommand) を使用して、マニフェストを更新します。

記載方法は以下です。

```:スキルマニフェストの一部
{
  "manifest": {
    "events": {
      "subscriptions": [
        {
          "eventName": "SKILL_DISABLED"
        }
      ],
      "endpoint": {
        "uri": "arn:aws:lambda:us-east-1:023972248338:function:ask-xxxxxx-default-1641300000000"
      }
```

# 2. Lambdaにハンドラーを追加する

以下に記載したのは、永続アトリビュートを削除するだけの処理ですが、この他にも削除するものがあれば、それらのコードも追加します。
deletePersistentAttributes は、equestEnvelope に含まれている、requestEnvelope.context.System.user.userId を使用して対象を削除しています。

```
const SkillDisabledEventHandler = {
    canHandle(handlerInput) {
        return handlerInput.requestEnvelope.request.type === 'AlexaSkillEvent.SkillDisabled';
    },
    async handle(handlerInput) {
      console.log('SkillDisabledEventHandler ');
      if (!handlerInput.attributesManager.deletePersistentAttributes) return
      await handlerInput.attributesManager.deletePersistentAttributes()
    }
};
```

`.addRequestHandlers`への追加もお忘れなく。

```
    .addRequestHandlers(
        LaunchRequestHandler,
        SkillDisabledEventHandler,  ← 追加する
            :
```

# そのほかのイベント

参考までにその他のイベントも記載しておきます。

|No.|eventName|イベント名|
|:--|:--|:--|
|1.|SKILL_ENABLED|スキル有効化イベント|
|2.|SKILL_DISABLED|スキル無効化イベント|
|3.|SKILL_PERMISSION_ACCEPTED|スキル権限付与イベント|
|4.|SKILL_PERMISSION_CHANGED|スキル権限変更イベント|
|5.|SKILL_ACCOUNT_LINKED|アカウントリンクイベント|
heapdumpとjavacore

これを実行しても停止しませんのであしからず。

ますはログイン

```
/opt/IBM/WebSphere/AppServer/profiles/Dmgr01/bin/wsadmin.sh -lang jython
```

情報取得準備

```
obj2 = AdminControl.queryNames('node=yyd2Node01,process=nodeagent,type=JVM,*')
```

ヒープダンプとjavacore、Systemダンプ取得コマンド

```
AdminControl.invoke(obj2,'generateHeapDump')
AdminControl.invoke(obj2,'dumpThreads')
AdminControl.invoke(obj2,'generateSystemDump')
```


https://www.ibm.com/docs/en/was-nd/8.5.5?topic=SSAW57_8.5.5/com.ibm.websphere.javadoc.doc/web/mbeanDocs/JVM.html
日本語入力の改善！ibus_mozcのソースをビルドする必要はなくなりました！

# はじめに
愛しのM1 Macが突然壊れてしまい、修理のため古いMacBook Airを使う必要性が出てきた。
とはいえ、2011年モデル。既に最新OSのサポート範囲外でXcodeのアップデートもできない。
いろいろ考えた末、Linux(fedora35)をインストールしてしまうことにした。

Fedoraのインストール自体は問題なく終わったが、ibus_mozcの設定関係でハマったので共有してみようと思う。

# ibus_mozcのインストール
Linux版Google IME的なMozcのインストールを行う。

```
sudo dnf install ibus-mozc
```

インストール後「設定」→「keyboard」→「入力ソース」で「日本語(Mozc)」を選択する。
Mozcが出てこない場合は一度ログアウトしてから再ログインしてシステムに読み込ませればOK。
初期状態で入っている「日本語(Anthy)」は削除して構わない。
そして、問題はここから。

このMozcはなぜか入力モードのデフォルトが「直接入力」になってしまっている。
そのため入力ソースのアイコンをクリックして「ひらがな」に変える必要がある。しかもログインをする度に…

調べると「改善するにはソースを自分でビルドする必要がある」と解説している日本語サイトが出てくる。
もとネタはmozcのgithubに投稿された[Issues](https://github.com/google/mozc/issues/381)のようだ。
しかし、よく読んでみると気になる追投稿があった。

> The latest version has the parameter to use Hiragana as the default mode.

> I added the document for the configurations.
> [https://github.com/google/mozc/blob/master/docs/configurations.md](https://github.com/google/mozc/blob/master/docs/configurations.md)

なんと、「ひらがな」入力をデフォルトに設定することができるようになったらしい！
2021年11月の投稿なので比較的最近のアップデートで対応がなされたようだ。
リンク先の内容にしたがって``~/.config/mozc/ibus_config.textproto``を修正する。

```
# `ibus write-cache; ibus restart` might be necessary to apply changes.
engines {
  name : "mozc-jp"
  longname : "Mozc"
  layout : "default"
  layout_variant : ""
  layout_option : ""
  rank : 80
}
active_on_launch: True #ここをFalseからTrueに書き換える
```
簡単だ！みなさん、ソースからビルドする必要はありませんよ。
(ソースを落としてきて中身を見たら書き換えるところがなくてコードを読み進めてしまった…というのは私だけでいいでしょう)

# ショートカットのカスタマイズ
今回利用したMacbook AirはJIS配列のキーボードのため、「英数」と「かな」キーがついている。
せっかくなのでこのキーを使用できるように設定を行う。
「設定」→「keyboard」→「キーボードショートカット」→「独自のショートカット」と進み「＋」から追加を行う。
まずは、名前を「かなキー」、コマンドを「``ibus engine 'mozc-jp'``」、ショートカットで「かな」キーを入力して右上の「追加」を押す。
続いて、名前を「英数キー」、コマンドを「``ibus engine 'xkb:jp::jpn'``」、ショートカットで「英数」キーを入力して同様に追加する。

Mozcプロパティでのキー設定ではMacの「英数」と「かな」キーが反応してくれないのと、「Command+Space」でIMEを切り替える形がデフォルトとなっているので、ゴリ押し感強めな設定となった。
欠点としてはGUI側と連携が取れておらず入力ソースのアイコンが切り替わらない点だ。「Command+Space」での切り替えはGUIと連携しているためこちらとも軽い齟齬が生じている。
誰か改善案を知っている方がいたらコメントを下さい。

以上、ibus_mozcで試行錯誤したお話でした。
【Go(Gin)✕Docker✕delve✕vsCodeでデバッグできるようにする最小構成】

## ディレクトリ構成

Goアプリケーションはapplicationディレクトリ以下にある。
*（アスタリスク）で囲んでいるファイルがポイント。

```docker
.
├── .vscode
│   └── **launch.json**
├── README.md
├── application
│   ├── **Dockerfile**
│   ├── controllers
│   ├── db
│   ├── go.mod
│   ├── go.sum
│   ├── main.go
│   ├── models
│   ├── server
│   ├── services
│   ├── **start.sh**
│   ├── tests
│   ├── tmp
│   └── vendor
├── **docker-compose.yml**
└── tmp
```

## docker-compose

- 8080:8080はもともとあったアプリケーション用のport。

- 2345:2345をデバッガ用のportとして追記。

```docker
version: '3'
services:
  api:
    ports:
      - 8080:8080
      - 2345:2345
```

## Dockerfile

```docker
FROM golang:1.16

WORKDIR /go/src/app/application

COPY go.mod ./
COPY go.sum ./

RUN go mod download

COPY . .

EXPOSE 8080

COPY start.sh /usr/local/bin/start.sh
RUN chmod 775 /usr/local/bin/start.sh
CMD ["start.sh"]
```

## start.sh

`DEBUG=dap DEBUG_PORT=2345 docker compose up -d`
このコマンドでデバッグのためのコマンドを実行してくれる。
（環境変数によって処理を分岐）
コマンドの詳しい意味は参考記事を閲覧してください。

```bash
#!/bin/bash

# DEBUG=dap DEBUG_PORT=2345 docker compose up -d  でリモート接続用コマンドを実行できる
if [ "${DEBUG}" = "dap" ];then
  go build -gcflags='all=-N -l' -o app
  dlv dap -l 0.0.0.0:${DEBUG_PORT} --log --check-go-version=false
elif [ "${DEBUG}" = "rpc" ]; then
  dlv debug --continue --check-go-version=false --accept-multiclient --headless -l 0.0.0.0:${DEBUG_PORT} main.go
else
  go run main.go
fi
```

## launch.json

参考にした記事ほど複雑な設定をせずともデバッグを開始できました。

```json
{
    "version": "0.2.0",
    "configurations": [
      {
        "name": "Launch Package",
        "type": "go",
        "request": "launch",
        "mode": "auto",
        "program": "${fileDirname}"
    }
    ]
}
```

**コンテナがしっかり立ち上がるまで待たないとビルドエラーみたいなのがでて混乱するので、コンテナ立ち上がり後はしっかり待つようにしたほうがいいです。（せっかちなので困惑しました）**

参考記事

https://zenn.dev/skanehira/articles/2021-11-26-go-remote-debug
'el' is defined but never used    no-unused-vars...のエラー解決方法。

Vue.jsでVue CLIを使った環境で学習していて、
npm run serveでサーバー立ち上げた際に問題が起こりました。

```
kushiyama_makoto@MakotonoMacBook-Air udemy-vuejs4 % npm run serve

> udemy-vuejs4@0.1.0 serve
> vue-cli-service serve

 INFO  Starting development server...
98% after emitting CopyPlugin

 ERROR  Failed to compile with 1 error                                                                                                               14:40:38

 error  in ./src/App.vue

Module Error (from ./node_modules/eslint-loader/index.js):

/Users/kushiyama_makoto/udemy-vuejs4/src/App.vue
   75:19  error  'el' is defined but never used    no-unused-vars
   89:18  error  'el' is defined but never used    no-unused-vars
   92:22  error  'el' is defined but never used    no-unused-vars
   95:19  error  'el' is defined but never used    no-unused-vars
  109:18  error  'el' is defined but never used    no-unused-vars
  112:22  error  'el' is defined but never used    no-unused-vars
  119:1   error  Irregular whitespace not allowed  no-irregular-whitespace

✖ 7 problems (7 errors, 0 warnings)


 @ ./src/main.js 6:0-28 10:13-16
 @ multi (webpack)-dev-server/client?http://192.168.11.4:8080&sockPath=/sockjs-node (webpack)/hot/dev-server.js ./src/main.js
```

![スクリーンショット 2022-01-15 15.04.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1174366/85b24e19-e099-1063-b673-53a4df2d4c7b.png)





「elが定義されてるけど、一度も使用されてない？？？」
ちょっとよくわからないので、しばらくググってましたが時間だけが過ぎました。（土日だけ勉強に当ててるので、１週間くらいかかりました。意味わからんくて寝込みました。）

ただある日、記事にたどり着いいたので紹介します。こちらです。
https://qiita.com/Nelson605/items/8b1a4cefef7a84a0dec0

こちらに記述されている部分のどこかのファイルに記述するのかな（おそらくjsonファイルかな）。。。
さらにこちらのstackOverFlowの記事にさらに細かくありました！！
https://stackoverflow.com/questions/61874994/vue-disable-no-unused-vars-error-the-simplest-fix

![スクリーンショット 2022-01-15 15.02.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1174366/c9eb9a8a-c27c-ade6-6d72-5c2e2dc29a17.png)


やはりpakage.jsonに追記するみたいです。
実際に追加しました。

![スクリーンショット 2022-01-15 15.07.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1174366/9d68dddc-de91-8d15-6a81-92cf709c4ba5.png)

動いた！！！

![スクリーンショット 2022-01-15 15.09.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1174366/bf75cb5d-c56b-330a-6d4f-ddae271141e3.png)



![スクリーンショット 2022-01-15 15.12.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1174366/39e92dbb-4201-26da-dc2f-7e46e82f0a61.png)


因みに、このような記事もありました。
https://qiita.com/blajir/items/82127aaa57e4d73a8389

原因は、
JavaScriptの構文チェックツールが動いたからですかね。
なので、今回の対応はチェックツールの`no-unused-vars`を無効することによってエラーを解消したようです。


※追記
普通にpackage.jsonに`rules`の項目あるのでここ（下記のスクショ）に追加でよかったみたいです。。。。
![スクリーンショット 2022-01-15 15.51.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1174366/3dbabdbf-7139-dbaa-275e-140ad22af99c.png)
【SwiftUI】secureFieldの枠線を下線にしてみた

本日は、SwiftUI の
**1.secureFieldの書き方
2.secureFielsの枠線スタイルを下線に変更**
の２点についてお話しします。

#実行環境
1.Swift praygrounds バージョン4.0 (1567.22)
2.SwiftUI

(XcodeバージョンVersion 13.2.1でも動くことを確認)


#secureFieldの基本的な書き方

##コード例

```　swift:secureFieldview1
import SwiftUI
import PlaygroundSupport

struct ContentView: View {
    @State var password1  = "" 
    @State var password2  = "" 
    var body: some View {
        VStack {
            SecureField ("パスワードを入力1", text: $password1, onCommit:{})
                .textFieldStyle(PlainTextFieldStyle())
                .font(.system(size: 20))
                .padding(.all)
                
            
            SecureField ("パスワードを入力2", text: $password2, onCommit:{})
                .textFieldStyle(RoundedBorderTextFieldStyle())
                .font(.system(size: 20))
                .padding(.all)

            
        }
    }
}

```

##コード説明

###secureField

第一引数は、**テキストフィールド内に表示する文字**

第二引数は、**@Stateで宣言したString型の変数**を宣言
（@Stateじゃないと中身が書き換えられないのでエラーになるという認識）

第３引数には、入力が完了した(returnがタップされた)タイミングで行いたい処理を
クロージャーで指定
（ここは自分は全くわからなかったので違うサイトの説明をそのまま引用しました。）

```
.textFieldStyle(PlainTextFieldStyle())
```
ここでは、**PlainTextFieldStyleで枠線なしスタイルを指定**

```
.textFieldStyle(RoundedBorderTextFieldStyle())
```

ここでは、**RoundedBorderTextFieldStyleで枠線スタイルを指定**

##実行結果

![スクリーンショット 2022-01-15 12.24.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2509377/b7bf90fe-10ba-338f-a0a2-6814143e98b4.png)

#secureFieldのスタイルを下線に

##コード例

```

import SwiftUI
import PlaygroundSupport

struct ContentView: View {
    @State var password3  = ""
    var body: some View {
        VStack {

            
            SecureField ("パスワードを入力3", text: $password3, onCommit:{})
                .textFieldStyle(PlainTextFieldStyle())
                .font(.system(size: 20))
                .padding(.all)
            
            Divider()
                .padding(.horizontal)
                }
    }
}

```

##コード説明
**secureFiled自体に下線スタイルは存在しません。**
そのため、**枠線なしスタイル選択し自分で下線を引**く必要があります。

そのため
secureFieldのtextFieldStyleは
**枠線なしスタイルのPlainTextFieldStyle**を使います。
その上で今回は

```
Divider()
```
を使用します。

**Dividerは区切り線**を引いてくれます。
そのためPaddingでうまく長さを調整してあげて、
VStack内でDividerを使えば
以下の実行結果のように下線スタイルにすることができます。

##実行結果
![スクリーンショット 2022-01-15 15.05.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2509377/0985d6e8-bdda-dc77-f060-f9fe02086475.png)


他にうまい下線スタイルにする方法があればコメントで教えてください。
コードや説明などの指摘もお願いいたします。

#参考記事
[【SwiftUI】SecureFieldでパスワード表示の入力欄を実装する方法を解説](https://hirauchi-genta.com/swift-swiftui-securefield/)

[SwiftUIで区切り線を引く方法【Divider】](https://www.yururiwork.net/archives/429)
GOLANDでGOプロジェクトをインストールしたら最初にやる設定

1.Go Modulesを有効にする
Go Modules=>Enable GO Modules integrationにチェック

![スクリーンショット 2022-01-15 15.03.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/388525/dc28d063-4265-febf-d756-bf815d172d70.png)

2.ルートディレクトリにモジュール群をインストール

```
cd paht/to/root-dir
go mod vendor
```

これでコードジャンプも効くようになる。
interfaceの意義

##この記事は
個人的に、interfaceが何なのかは分かっていて、書いたことはそんなに無いけども、使ったことはある。
誰かが書いたのを呼び出して色々やっているけども、書いた人がどういう意図でinterfaceを定義したのかいまいちよく分かってない。

独り言はここまでにして、要はinterfaceの意義が分からないので、それを解消する記事にしたいと思います。

なので、対象は

- interfaceの概念が分からない人
- interfaceの概念は分かるけど、何のためにあるのか分からない人

あ、ここで出てくる具体例は全て、"Kotlin"のインターフェースです。
言語とそのバージョンによって、微妙に仕様が異なる可能性があるので最初に伝えておきます。

ただ、interfaceの意義は掴めると思います。
##interfaceとは
一言で表すと「約束」。
抽象メンバを定義することが出来ます。
そして、クラスに実装する事で定義した抽象メンバを強制的にオーバーライドさせられます。

```kotlin
interface Life {
   var hitPoint: Int
   fun walk()
   fun run()
   fun eat()
   fun sleep() {
      // 中身の実装はあってもなくても良い
   }
}

class Human: Life {
   override var hitPoint: Int = 100

   override fun walk () {
      print("I walk")
   }
   override fun run() {
      print("I run")
   }

   override fun eat() {
      print("I eat rice")
   }

   override fun sleep() {
      print("I sleep")
   }
}
```

##なぜinterfaceがいるのか？
さて、本題。
ただ、調べているとよく"abstract class vs interface"と出てきます。
そのため、一応、似た概念である「抽象クラス」も触れていきます。

その為に、こんな流れで説明していきます。


1. 抽象クラスの説明
1. インターフェースと同じところ
1. インターフェースとの違い
1. インターフェースはどんな問題を解決してくれるのか？

##普通のクラスとインターフェースの違い
- 抽象メンバを持つことが出来る
- インターフェースは、コンストラクタを持つことが出来ない


##抽象クラスについて
一言で表すと「始祖」。

直接インスタンス化して実態を生成することができないこと、そして、多重継承出来ないので始祖感ありません？

抽象メソッドや抽象プロパティを定義することができると同時に、具体的なメソッドやプロパティを追加することもできます。

直接インスタンス化ができないのと抽象メンバを持てるというだけで、普通のクラスと大体同じですね。
あとあと、継承したら全てのメンバをオーバーライドしないといけないという点も抽象クラスの特徴です。（神の力ですね）

```kotlin
abstract class God(val people: Double) {
     // コンストラクタ引数も持つことができる
} 
```
###抽象メソッドとは？
一言で表すと「具無し」メソッドです。
引数と戻り値の型だけを指定して、具体的な処理は書かない。
文字通り、抽象的なメソッドです。

```kotlin
abstract fun hoge(str: String): Int
```
##抽象クラスとインターフェースの違い
インターフェースも抽象クラスも抽具メンバも定義できる点では、同じなのですがインターフェースは

- 多重継承が可能
- コンストラクタ引数を持つことができない

- バッキングフィールドを持つことができない 

```kotlin
private var _name: String = " " // _nameがバッキングフィールド

var name: String
   get() {
      return _name
   }
   set(value) {
      _name = value
   }
```

##抽象クラスとインターフェースの同じところ

- 抽象メンバを持てる
- 抽象メンバを全てオーバーライドしないといけない
- インスタンス化できない

##改めてインターフェースの意義とは？
文法的には、分かったとは思うので、

- interfaceの概念が分からない人

に向けてはOKです。
ただ、ここまで抽象クラスとインターフェースの類似点と相違点を挙げましたが、正直分からないのが正直な所。

何かの意義を感じ取るには、やはり問題となる具体例が必要だと思います。
それを引き合いに出しながら

- interfaceの概念は分かるけど、何のためにあるのか分からない人

に向けてとどめを刺したいと思います。

##インターフェースが解決してくれる問題

下記の具体例がとても分かりやすかったので、まずはこちらをご覧ください。

https://qiita.com/yutorisan/items/d28386f168f2f3ab166d#qiitapost%E3%82%AF%E3%83%A9%E3%82%B9%E3%81%A7%E8%80%83%E3%81%88%E3%81%A6%E3%81%BF%E3%82%8B

インターフェースの文法を一言で表すと「約束」。
ただし、インターフェースが解決してくれる問題を考えると、この要約だけでは微妙です。

役割としては、複数あって

- 約束
- 仲介
- 分岐

まずは、文法から理解できることで、
interfaceで定義した抽象メンバの機能をクラスが持つことを「約束」できます。

以下二つは、インターフェースの役割を考察したもの。
まず、疎結合が実現できているのは、実装クラスと呼び出し元のクラスの間に立つ「仲介」を担っているから。

そして、上記の例にあるように、Qiitaサーバーへのリクエストという共通機能を提供する中で、クラスへの安全なアクセスを実現するために、ラム専とロム専で「分岐」していました。

##まとめ
割と奥が深いインターフェース・・

大事な部分をあうとそーしんぐしてしましましたが、何とか一つの理解の形になったと思います。
間違っている箇所があれば、優しく教えてください！


##参考
https://www.baeldung.com/java-interface-vs-abstract-class

https://blog.kotlin-academy.com/abstract-class-vs-interface-in-kotlin-5ab8697c3a14
【Flutter】Widgetを使ってみる Text編

## Textを自由自在に使いたい
FlutterのTextを調べたり考えたりすることなく自由自在に使えるようになるのがゴールです。

## 調査
Textのargmentsにはどのようなものがあるかみてみます。
たくさんありますね。大変そう

```dart
 const Text(
    String this.data, {
    Key? key,
    this.style,
    this.strutStyle,
    this.textAlign,
    this.textDirection,
    this.locale,
    this.softWrap,
    this.overflow,
    this.textScaleFactor,
    this.maxLines,
    this.semanticsLabel,
    this.textWidthBasis,
    this.textHeightBehavior,
  })
```

## Text自体の見た目を変えたい
`style: TextStyle()` を使います。

```dart
Text(
  "Text",
  style: TextStyle(),
),
```

```dart
style: TextStyle(fontSize: 20)                // サイズ
style: TextStyle(color: Colors.red)           // 色
style: TextStyle(fontWeight: FontWeight.bold) // 太さ
style: TextStyle(fontStyle: FontStyle.italic) // スタイル
style: TextStyle(letterSpacing: 3)            // 文字間
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263661/70045eab-6775-4684-05eb-9678013ab479.png)

## Textの位置や表示方法を変えたい
```dart
overflow: TextOverflow.ellipsis // 末尾を...
maxLines: 2                     // 最大行数 
textAlign: TextAlign.right      // テキストの位置 
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263661/89e464f6-eb67-0f06-9711-da8027bd697f.png)
日本人がDebianで中国語を入力してみる


続くかどうかは知らないが、中国語を学び始めたのでLinuxでもキーボードで中国語を入力したい。

自分の環境

- OS: Debian GNU/Linux 11 (bullseye) x86_64 
- DE: MATE 1.24.1

## セットアップ

インプットメソッドはibusを使っていた。下記の記事でibus-rimeが良さげとの話なのでインストール。

- [日本人が Ubuntu で中国語を扱う](https://qiita.com/kws_fx/items/21ce5c3a8834ee8df8c4)

```shell
$ sudo apt-get install ibus-rime
```

これ実行した後タスクトレイのibusのアイコン右クリックして再起動。そうすると、rimeが出てくる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20634/733c43a7-c02c-292e-0822-dcb1a8cfd5a1.png)

適当に、zenkaku_hankakuボタンを入力切替にしとくといい感じ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20634/39b5a73a-1492-e1eb-b728-b56d06162c3d.png)

ピンイン入力して你好したい。できたで。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20634/762b148b-61a8-7d3a-f387-e5e0a78c3c79.png)

## 四声＋ピンイン

勉強のため、ピンイン＋四声で入力したい（ネイティブの人はピンインだけで入力するのかな？）。

- [Rime - ArchWiki](https://wiki.archlinux.jp/index.php/Rime)

以下の場所にYAMLファイルを作った後タスクトレイのibusのアイコン右クリックして再起動。

```yaml:~/.config/ibus/rime/default.custom.yaml
patch:
  schema_list:
    - schema: terra_pinyin
```

四声は以下のようなアスキー文字で指定する

```
第一声: -
第二声: /
第三声: <
第四声: \
```

你好は記号上はどちらも第三声なので「ni< hao<」と入力するといい。ピンインつきの単語をそのままコピペできたらいいのになあ

### 繁体字 (漢字) と簡体字 (汉字) を切り替え

自分の環境ではデフォルトで繁体字が使われていた。簡体字を使いたい。

>インプットメソッドの選択
>
>Rime が実行中ならいつでも、F4 で基本的なオプションを変更することができます。オプションは以下のように表示されます: 
>...
>最後のオプションは繁体字 (漢字) と簡体字 (汉字) を切り替えることが可能です。 

[Rime - ArchWiki](https://wiki.archlinux.jp/index.php/Rime)

* Rimeを起動した状態でF4を押すとなんか出てくる。「2」を選択。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20634/0961b410-a0c8-7d8b-c9f3-4855300dc17b.png)

* 「漢字 → 汉字」を選択。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20634/403e5780-0a34-db81-486a-95a3a2e6ed0e.png)

* 簡体字が出てくる、什么?

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20634/d90bbf49-3fcd-0a59-a0bd-15421891a4fc.png)

### Tips

- `儿`(ル) は `er` と入力しないと出てこない
    - `一下儿（ちょっと）` と打ちたくて、`yi-xiar` と打ち込んでも変換対象が出てこない `yi-xia er` と打てば良い


### 余談・四声の記号について

このサイトによると、

- [第一課　声調(せいちょう)について](https://www.isc.meiji.ac.jp/~katotoru/chinvu1.html)

>　中国語の4つの声調記号は、世界の他の言語でも使われているダイアクリティカル・マークを流用したものです。

mā、má、mǎ、màのやつのこと。この声調記号、単独だとコピペすると行がおかしくなるので、ascii環境だと後述のように数字で書いたほうがいいかも。


>ダイアクリティカル・マークつきのローマ字は、日本語のメールなどでは、文字フォントの関係で文字化けする可能性があります。そのため、日本語のメールで中国語のピンインを書く場合、例えば māをma1、máをma2、mǎをma3、màをma4のように、アラビア数字で声調記号を代用することもあります。

手書きなら簡単だけどパソコンで打つとなると面倒ですね。