OmniAICreator/Qiita-1.07M huggingface dataset:
amazon web services 基礎からのネットワーク&サーバー構築　ひっかかったとこ

<h2>amazon web services 基礎からのネットワーク&サーバー構築　備忘録</h2>

AWS学習の良書「amazon web services 基礎からのネットワーク&サーバー構築」の内容について引っかかったとこまとめ

<h3>ssh -i my-key.pem ....</h3>
を実行するときは「my-key.pem」が置いてあるディレクトリで実効する

<h3>ssh -i my-key.pem "ec2-user"@....</h3>
のec2-userはAWS版sudoコマンド。
管理者権限で実行できる。
AWS STS とは

## 勉強前イメージ

名前からはわからん！

## 調査

### AWS STS とは

Security Token Service の略で
一時的な認証情報を発行してくれるサービスで、
IDを定義せずともAWSのリソースにアクセスできるようになり、
IDフェデレーションが可能になります。

- IDフェデレーション とは？

独自のID管理システムを持つ複数のセキュリティドメイン間で、それぞれのユーザIDをリンクさせ、
ドメインで認証を受けたエンドユーザーは、他方のドメインでもログインしないでそのリソースにアクセスすることが出来ます。

### IAM との違い

セキュリティ認証情報 という点でIAMというサービスもあるが、
以下の点で違いがある

- 使用期間が短い
- セキュリティ認証情報は保存されることなく、動的に生成される

## 勉強後イメージ

必ずしもユーザを作成しないといけない、というわけではないのか・・・
管理としては楽になる・・・のかな？

## 参考

- [AWSのIAM & STSの基礎知識](https://morizyun.github.io/blog/aws-iam-basic-amazon-web-service/)
- [一時的な認証情報の取得AWS STS](https://docs.aws.amazon.com/ja_jp/sdk-for-java/v1/developer-guide/prog-services-sts.html)
Sassについて

#SassとScssとは
CSSをより簡略化したメタ言語です！
この２つの共通点は入れ子構造で書くことです。

```index.html
<div class="header">
 <div class="header-logo">Sassについて</div>
</div>
```

```style.css
.header {
 heigth:90px;
 color:black;
}

.header-logo {
 font-size:40px;
 border-bottom:4px solid black;
}
```
と入力するとしましょう。
これが普段のcssの入力の仕方ですね👍

Sassの場合は、少し記入の仕方が変わります。

```atyle.scss
.header
 heigth:90px
 color:black
 .header-logo
  font-size:40px
  border-bottom:4px solid black
```
となります。
ちなみにScssで書く場合はこうなります。

```style.scss
.header {
 heigth:90px;
 color:black;
 .header-logo{
  font-size:40px;
  border-bottom:4px solid black;
  }
}
```
みたくなる。
HTMLの親要素と子要素に共通する書き方ですね。つまり入れ子です。
ちなみにcssであたっていない場合はデベロッパーツールで確認しますが、これら（以下sass）は、崩れて画面真っ黒、そして黒い画面でエラーを訴えてくるのですね🥲

以上がSassの説明でした。
次の記事では導入について書いていきます👍
deviseを使ってユーザーの情報をパスワードなしで変更できるようにする

https://qiita.com/akr03xxx/items/82ba45f7ef4fdbd5c702

https://qiita.com/ryokky59/items/71b5a853989721b89c6e

https://qiita.com/machamp/items/f6a7b003fcda3f04094a

https://qiita.com/1992_momotaro/items/d8a220be528a7af69deb
[Rails] view パスで条件分岐する方法　[current_page?]


#current_page?
current_page?は、表示中のページのパスを判定できるメソッドです。
これはUrlHelperとして実装されているため、ビューの中から呼び出すことができます。

###・URL

`current_page?(http://hoge.com/hoge)`

###・パス
`current_page?(/tweets/new)`

###・prefix
`current_page?(new_tweet_path)`

###・アクション指定
`current_page?(action: "new")`

###・コントローラー&アクション指定
`current_page?(controller: "tweets", action: "new")`

---

```ruby:show.html.erb
<% if current_page?(tweet_path(@tweet)) %>

<% end %>
```

のような感じで、パスで条件分岐することが可能です。

筆者は同クラスでshowページを２画面作りたくてこの書き方をしました。
あまり良くない書き方の場合は、ご指摘いただけますと幸いです。


<a href="https://qiita.com/ITmanbow/items/dc9b2e2b48f4901049f4#%E3%83%91%E3%82%B9">
  こちら</a>の記事を参照させていただきました。
MaterialDesignのComboBox HasClearButtonの大きさを変更する

#はじめに
WPF MaterialDesignは便利なのですが、時々表示が大きすぎたりとやや使い勝手に癖があります。
ComboBoxを使用した際に、選択したものをクリアするために、クリアボタンが表示させることができます。

```C#
    xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"

    <ComboBox x:Name="GenderComboBox" Width="60" 
                materialDesign:TextFieldAssist.HasClearButton="True"
                ItemsSource="{Binding ItemsGenderValue}" 
                Text="{Binding Gender.Value, UpdateSourceTrigger=PropertyChanged}" 
                materialDesign:HintAssist.Hint="性別"/>
```
以下のような表示になります
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/956246/e6dedbe6-b238-c2d9-6fc6-79706dd591fa.png)

ただ、このクリアボタンが大きくて、見栄えが良くありません。もう少し小さいほうがいいし、押し間違いしないかと思います。

#解決方法
xaml側で何とかできないかと考えましたが、スタイルをかなりいじることになりそうで面倒でした。
ということで、簡単な解決方法ですが、コードビハインドでフォームロード時に変更してしまえというものです。

まず、クリアボタンですが、これはComboBoxのPART_ClearButtonで定義されています。
これをScaleTransformでサイズを指定します。
ただ、これだとちょっと位置ずれが起きたので、クリアボタンのpaddingで調整します。
実際、標準のスタイルでもpaddingで位置調整していたので、この対策で問題ないかと思います。
で、以下が、対策後のコードとなります
ちなみに、この例では、Windowではなく、Prismを使用している関係でUserControlとなっています。

```C#
        private void UserControl_Loaded(object sender, System.Windows.RoutedEventArgs e)
        {
            // ComboBoxのClearButtonを取得します 
            Button genderComboBoxclearButton = GenderComboBox.Template.FindName("PART_ClearButton", GenderComboBox) as Button;

            // ComboBoxのClearButtonの大きさを少し小さめにします 
            ScaleTransform st = new ScaleTransform(0.75,0.75);
            genderComboBoxclearButton.RenderTransform = st;

            // ComboBoxのClearButtonの表示位置を調整します
            genderComboBoxclearButton.Padding = new System.Windows.Thickness(2, 4, -5, -4);
        }
```

修正前
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/956246/e6dedbe6-b238-c2d9-6fc6-79706dd591fa.png)
修正後
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/956246/77f1d12d-73d6-fe13-af49-ca8faa85229e.png)

ほんのちょっとの修正ですが、思ったより見やすくなったのではないかと思います。
【ミライトデザイン社内勉強会#18】「IDDD本から理解するドメイン駆動設計」輪読会~第9章「モジュール」~

### 前回の記事
[【ミライトデザイン社内勉強会#17】「IDDD本から理解するドメイン駆動設計」輪読会~第8章「ドメインイベント」~ - Qiita](https://qiita.com/tkek321/items/6cd7d5f15718119b34a4)

## [実践DDD本 第9章「モジュール」～高凝集で疎結合にまとめる～](https://codezine.jp/article/detail/10651)

### パッケージ構成を考える時に毎回迷ってしまうので、DDDに限らず、パッケージを分けるときに基準にしていることがあれば知りたい

- 言語やフレームワークによってはある程度パッケージ構成が決まっている
- マイクロサービスにするかとかアプリケーションの規模でも変わってくる
- プロジェクトや規模感、人によって違いがあるので明確な基準はないと思う
- ディレクトリの話とパッケージの話は一緒なことが多いけど、厳密には違う
    - 言語によってはパッケージとディレクトリが同じではないこともある

### アーキテクチャごと、に適したパッケージの分け方とかあるの？例えば、ヘキサゴナルアーキテクチャの時はこんな感じにした方が良いとか

- アーキテクチャとディレクトリの構成はほとんど関係ない
- 一番最初に悩むのがパッケージ構成
    - エディタのおかげでパッケージ構成を変更するのは比較的楽になっているので、見にくくなってきたらパッケージ構成を見直したりもする

### 一般的なモジュールは機能単位のイメージがあるけど、DDDにおいてはクラス群をまとめるものとしているがパッケージみたいのもの？
- 一般的にモジュールはモジュール単位で実行できるものとしているが、DDDにおいては独立しているとかは関係なく、意味ある単位で分割するものとしている（パッケージと同じ感じ）
    - モジュールを分ける基準としては、モジュールの中で簡潔する
    - ドメインオブジェクトの場合は参照の単位で分けている


##### ディレクトリ、パッケージ、モジュール、ライブラリ、プラグイン各単語の違い
- [違いが分からない？ライブラリー、プラグイン、モジュール について](https://blog.sprobe.com/difference-plugin-library-module/#outline__3)
- **ディレクトリ**
    - ただのディレクトリ
- **パッケージ**
    - モジュール、ライブラリ、プラグインとは別の話
    - [パッケージ \| IT用語辞典 \| 大塚商会](https://www.otsuka-shokai.co.jp/words/package.html#:~:text=%E9%96%A2%E9%80%A3%E3%81%99%E3%82%8B%E3%81%95%E3%81%BE%E3%81%96%E3%81%BE%E3%81%AA%E8%A6%81%E7%B4%A0,%E3%82%92%E3%80%8C%E3%83%91%E3%83%83%E3%82%B1%E3%83%BC%E3%82%B8%E3%80%8D%E3%81%A8%E5%91%BC%E3%81%B6%E3%80%82)
    - ex. ディレクトリをパッケージ化する
    - ex. パッケージ化してモジュールにする
- **モジュール**
    - [モジュール (module)とは｜「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典](https://wa3.i-3-i.info/word12243.html)
    - 少なくともモジュール単位で実行できる
    - プラグインよりは独立性がある
- **ライブラリ**
    - [ライブラリ (library)とは｜「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典](https://wa3.i-3-i.info/word1473.html)
    - 完成しているもの
    - 参照するためのレシピ
- **プラグイン**
    - [プラグイン (plug-in)とは｜「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典](https://wa3.i-3-i.info/word11533.html)
    - ある機能の拡張
    - プラグインを使用して1つの機能を作るイメージ
    - 何か親があって動くようなイメージ
    - エディタであれば、プラグイン単体では使用できない

## 次回
[【ミライトデザイン社内勉強会#19】「IDDD本から理解するドメイン駆動設計」輪読会~第10章「集約」~ - Qiita](https://qiita.com/tkek321/items/248a4203c40b96fcfa84)
【HTML/XHTML】<br>と<br />の違い

#プログラミング勉強日記
2021年3月4日

#`<br>`と`<br />`の違い
　結論から言うと、`<br>`はHTMLの書式で、`<br />`はXHTMLの書式である。XHTMLでは、省略式でもいいが終了タグも記述しないといけない。

```:xhtmlでの書き方
<br></br>
<br />
```

#HTMLとXHTMLとは
　HTMLはHyperText Markup Languageの頭文字をとったもので、コンピュータが理解できるマークアップをするための言語である。
　XHTMLはExtensible HyperText Markup Languageの略称で、HTMLとXMLの特徴を合わせたWebページを作るための言語である。<b>XHTMLは廃止されている。</b>

#参考文献
[`<br>`と`<br />`タグの違いとは](http://write-remember.com/archives/2309/)
[`<br>` と `<br />` タグの違い　【HTML と XHTML 】](https://ameblo.jp/midorieng03/entry-10929028852.html)
[【初心者向け】XHTMLとは何？HTMLとの違いは？【徹底解説】](https://web-camp.io/magazine/archives/4977)
vimの矩形選択

#目的
vimでmswin.vimを使いつつ矩形選択をする方法。

#矩形選択への推移
これは、helpにもあるが、c+qで矩形選択モードに移動できる。

#理由
通常のvimの矩形選択はc+vなのだが、これはmswinだとペーストになってしまうからである。
また、シフトを押して選択するという動作も「selectmode」というモードになっておりいわゆるvim標準の選択方法ではないから特別なキーが割り当たっている。

#問題
その後のカーソル移動がghjkしか効かなくて、十時キー（上下左右の矢印キーボード）が効かなくなっているというのが問題である。

#解決策
shift+十字キーで移動ができる。
どっかのhelpにあるんかなあ？

#利用例
 :r !dir
とかでシステムデータをコピペしたい場合は、これが有用になると思われる。

#ついでに
selectmodeで選択したのをvigual modeにするのはc+gである。これもなかなか有用。例えば、選択範囲で検索したいような場合、c+gしてから、:を押すと:`<,`>となる。
STM32F103C8のMbedでの液晶,AQM0802Aで「A」を表示


1.SCLとSDAを接続、プルアップも忘れずに
2.電源の接続
3.下記のソースコードを書き込む
4.コンパイル実行で表示されたら終了
5.おわり


```c++


#include "mbed.h"
 
#define ADDR     (0x7C) //  address
 
//I2C i2c(I2C_SDA, I2C_SCL);
I2C i2c(PB_7, PB_6);

//DigitalOut myled(LED1);
 
//Serial pc(SERIAL_TX, SERIAL_RX);
 
//volatile char TempCelsiusDisplay[] = "+abc.d C";

int main()
{
 
    char data_read[2];
  
    //init
    wait(0.2);

    data_read[0] = 0x0;

    data_read[1]=0x38;
    i2c.write(ADDR, data_read, 2);

    data_read[1]=0x39;
    i2c.write(ADDR, data_read, 2);

    data_read[1]=0x14;
    i2c.write(ADDR, data_read, 2);

    data_read[1]=0x70;
    i2c.write(ADDR, data_read, 2);

    data_read[1]=0x56;
    i2c.write(ADDR, data_read, 2);

    data_read[1]=0x6C;
    i2c.write(ADDR, data_read, 2);

    wait(0.2);

    data_read[1]=0x38;
    i2c.write(ADDR, data_read, 2);

    data_read[1]=0x0C;
    i2c.write(ADDR, data_read, 2);

    data_read[1]=0x01;
    i2c.write(ADDR, data_read, 2);

    wait(0.2);

    data_read[0]='@';
    data_read[1]='a';
    i2c.write(ADDR, data_read, 2);


    while (1) {

        // Display result
//        pc.printf("temp = %s\n", TempCelsiusDisplay);
//        myled = !myled;
        wait(2.0);

    }
 
}


```

![103_aqm0802_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/e1cf88ba-a727-7dda-d7b4-555304c01444.jpeg)
フォームの設定「reactメモ」

reactを今日から初めていく、メモとして覚えた知識をここに残す。


・フォームの設定
入れた値を表示させる



```react:react_app
 <body>
    <h1>React</h1>
    <div id="root">wait.......</div>

    <script type="text/babel">
    let dom = document.querySelector('#root');
    
    const p = {
     fontSize: "20px",
     padding: "10px",
     };

    const input = {
     fontSize: "16px",
     padding: "5px 10px",
    }

  let message= 'お名前をどうぞ：';
  let in_val = '';


   let doChange = (event)=>{
     in_val = event.target.value ;
     message = 'こんにちは、' + in_val + 'さん！！！';
   };
   
    let doAction = (event)=>{
      
      let el = (
        <div>
          <p style={p}>{message}</p>
            <div>
              <input type="text" id="input" style={input}
              onChange={doChange} />
              <button onClick={doAction} style={input}>
                Click
                </button>
              </div>
          </div>

      );
      ReactDOM.render(el, dom);
    };
    doAction();
    
    
    </script>
  
  </body>

```
【javascript】appendChildを多用するコードをスッキリと

#目的

自分用

```html:HTML
<div class="e1">
	<div class="e1-1">
		<div class="e1-1-1"></div>
		<div class="e1-1-2">
			<div class="e1-1-2-1">
		</div>
		<div class="e1-1-3"></div>
	</div>
</div>
```
javascriptで上記のような要素の生成と追加を繰り返すコードをスッキリさせたかった。
下記のように書くと上記HTMLを出力するようにしたい。

```javascript:

const c = 'className';
const elmement =
	childAppender(el('div',{[c]:'e1'}),
		siblingAppender(el('div',{[c]:'e1-1'}),
			el('div',{[c]:'e1-1-1'}),
			childAppender(el('div',{[c]:'e1-1-2'}),
				el('div',{[c]:'e1-1-2-1'})
			),
			el('div',{[c]:'e1-1-3'})
		)
	);
console.log(elmement);	//上記HTMLのような構造を出力
```

第一引数は親要素となる為、慣れないと少しややこしい。

#関数

以下の関数を用いる

```javascript:
//要素の生成
const el = (tag, attr) => {
	if (!tag) return null;
	const elm = document.createElement(tag);
	if (!attr) return elm;
	const map = Object.entries(attr);
	for (const [k,v] of map) elm[k] = v;
	return elm;
};
//nodeTypeの確認
const isElementNode = n => n ? n.nodeType===1 : false;
//子孫要素の追加
const childAppender = (...elms) => {
	const idx = elms.findIndex(x => !isElementNode(x));
	switch (idx) {
		case -1:	break;
		case 0:		return null;
		case 1:		return elms[0];
		default:	elms.slice(0, idx);	break;
	}
	for (let i=0,len=elms.length-1; i<len; i++) {
		elms[i].appendChild(elms[i + 1]);
	}
	return elms[0];
};
//兄弟要素の追加
const siblingAppender = (parent, ...elms) => {
	if (!isElementNode(parent)) return null;
	
	const available = elms.filter(isElementNode);
	for (const child of available) parent.appendChild(child);
	return parent;
	
};

```

##関数の説明

- el( tagName[, {attribute: value,...}] )
要素を生成し返す。
引数１：tagName => HTMLのタグ名
引数２：属性名をKEY、値をVALUEで組んだオブジェクト形式
　　　　elm.className = 'classname'のようなイコールで指定出来るもののみ
　　　　elm.classList.add('classname')のような指定方法のものは不可

- childAppender( element1, element2, ... )
第一引数を親要素として残りの引数を順次、直列的に子孫に追加し、親要素を返す。
nodeTypeが1でない要素が存在すると以降の要素は追加されない。

- siblingAppender( parentNode, element1, element2, ... )
第一引数を親要素として残りの引数を順次、兄弟要素として親要素の直下に追加し、親要素を返す。
nodeTypeが1でない要素は追加されないが、childAppenderと違い最後の引数まで追加される。

#感想
少し重い気がする。
【Rspecエラー】expected #<ActiveModel::DeprecationHandlingMessageArray([])> to include ~　の解決

Rspecでテストコード記入中に発生したエラーです。

spec/models/quiz_spec.rbに以下の様にテストを書いていました。

```
require 'rails_helper'
RSpec.describe Quiz, type: :model do
  include ActionDispatch::TestProcess::FixtureFile


  let(:quiz) { create(:quiz) }

  ~

  describe '投稿画像の拡張子の検証' do 
    it '正しい拡張子の画像ファイルが問題画像として有効であること' do

  ~

    it '不正な拡張子の画像ファイルが正解画像として無効であること' do
        quiz.answer_image = fixture_file_upload('/e5cb899367efb53d53e5047185f273d8.gif')
        expect(quiz.errors[:answer_image]).to include('の拡張子が間違っています')
    end

  end

end
```

これでRspecを走らせると以下の様なエラーが発生しました。

```
Failures:

  1) Quiz 投稿画像の拡張子の検証 不正な拡張子の画像ファイルが正解画像として無効であること
     Failure/Error: expect(quiz.errors[:answer_image]).to include('の拡張子が間違っています')
       expected #<ActiveModel::DeprecationHandlingMessageArray([])> to include "の拡張子が間違っています"

~
```

エラー文を読んでもよくわかりませんでしたが、対象テストを以下の様に書き換えると通りました。

```
    it '不正な拡張子の画像ファイルが正解画像として無効であること' do
      quiz.answer_image = fixture_file_upload('/e5cb899367efb53d53e5047185f273d8.gif')
      quiz.valid?
      expect(quiz.errors[:answer_image]).to include('の拡張子が間違っています')
    end
```

`quiz.valid?`を追加しています。一度バリデーションをかけないとerrorsに何も値が代入されません。
今回のエラーはバリデーションにかけていなかったためにerrorsに何も値が代入されていなかったために発生していた様です。
[419エラー]ECSでセッションが保存されていない問題

#概要
Laravel sanctumを利用してセッションベースのログイン認証を実装しており、ローカルではログインできていたのにAWS環境を使ったら419エラーが出てしまいました。

あまり情報もなく（というかAWS知識がなくてググり力が足りない）、解決するのに手間取ってしまったのでメモします。

#AWS環境
ALB経由でECS(EC2)につなげている環境

#419エラーとは
LaravelのPostする際のCSRF漏れエラーです。

#解決策
今回はEC2インスタンスにつけているターゲットグループのスティッキーセッションが無効になっているのが原因でした。

![スクリーンショット 2021-03-03 15.35.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643906/b76d6be0-5cac-4085-add7-382013fa9a84.png)

ターゲットグループ>group detailsタブのAttributesのEditをクリック
sticknessをdisabledからenabledに変更（画像は変更後です）。

#まとめ

この項目をenabledにしないとセッションが保存されないみたい？なので、今後も注意したいです。
配列に入ったvalueが重複しているオブジェクトを取り除きたい

# 目的

user_idがかぶってるやつを取り除きたい。
（あとからDBに追加されたレコードを優先したりさせなかったりしたい。）

【前提となる配列】

``` js
const items = [
  { id: 1, user_id: 1, num: 1 },
  { id: 2, user_id: 2, num: 2 },
  { id: 3, user_id: 1, num: 11 },
  { id: 4, user_id: 2, num: 12 },
  { id: 5, user_id: 3, num: 13 },
];
```

## ①idが大きいものを優先（上書き）しながら重複を取り除く

### Mapを使う方法

``` js
const updateItems = [...new Map(items.map((value) => [value.user_id, value])).values()];

console.log(updateItems);
// [ { id: 3, user_id: 1, num: 11 },
//   { id: 4, user_id: 2, num: 12 },
//   { id: 5, user_id: 3, num: 13 } ]
```

### sortとfilterを組み合わせる方法

``` js
const updateItems = items
  .sort((a, b) => {
    return b.id - a.id;
  })
  .filter((item, index, array) => {
    return array.findIndex((item2) => item.user_id === item2.user_id) === index;
  });

console.log(updateItems);
// [ { id: 5, user_id: 3, num: 13 },
//   { id: 4, user_id: 2, num: 12 },
//   { id: 3, user_id: 1, num: 11 } ]
```

## ②idが小さいものを優先しながら重複を取り除く

``` js
const updateItems = items
    .sort((a, b) => b.user_id - a.user_id)
    .filter((value, index, array) => {
      return array.findIndex((value2) => value.user_id === value2.user_id) === index;
    });

console.log(updateItems);
// [ { id: 5, user_id: 3, num: 13 },
//   { id: 2, user_id: 2, num: 2 },
//   { id: 1, user_id: 1, num: 1 } ]
```

## 他にもこんな方法があるよ！があったら是非教えていただきたいです！
定義した関数を export -f (Bash)

こんにちは。
bash では定義した関数を ```export -f``` できます（POSIX ではこの機能を持っていません）。定義した関数を xarg で使う場合には必要となります（下記例）[^1]。

```export_f_myfunc.sh
#!/bin/bash
myfunc() { myfunc0 "$1"; }
myfunc0() { echo "$1"; }
export -f myfunc myfunc0

find . -type f | xargs -I% bash -c "myfunc %"
```

[^1]: 参考記事：「[xargsにbashのfunctionを渡す方法](http://wrist.hatenablog.com/entry/20120603/1338691396)」
perl ユーザの php メモ


他人様の書いたコードのリライトが必要となったため、超絶久々に php を触った。
その際の初心者的メモ

## php のみのスクリプト

は1行目に `<?php` で始める。
最終行に`?>`を記載するのは[推奨されていない](https://www.php.net/manual/ja/language.basic-syntax.phptags.php)。

## phpタグ

リライト対象に`<?PHP`と書いてたのあったが、普通は`<?php`だよね？つか、`<?pHP`でも`<?PHp`でも良いって、、、

一応、マニュアルサイトとか大多数の記載通りに`<?php`にしとくべ[^1]

[^1]: phpの大文字小文字の仕様については、別途確認

## ワンライナー

`-r`を使う

```
$ php -r "echo 1;"
1
```
## 型

当たり前だけど、変数とかには型があるよねぇ[^2]。

[^2]: `substr`についてはリライトすべきコードの中で多用されていたのでメモ

```
$ php -r 'echo gettype("0123");'
string
$ php -r '$a = "0123" ; echo gettype($a);'
string
$ php -r '$a = "0123" ; echo gettype(substr($a, 0, 3));'
string
$ php -r 'echo gettype(0123);'
integer
$ php -r 'echo 0123;'
83
```

## で、文字列の比較

`===`を使う[^3]

[^3]: `eq`が`==`のエイリアスだなんて、、、

```
$ php -r '$a = "0123"; echo strcmp($a,"0123") == 0;'
1
$ php -r '$a = "0123"; echo $a === "0123";'
1
```
`strcmp`は、関数を呼び出す分遅くなる（と色々なところで指摘されている）ため使わない。
`===`は、型の比較が入るので、`gettype`で想定する状況を確認しながら利用する。

## elseif

`else if`でも通るが、[ブロックを使った記法でのみ](https://www.php.net/manual/ja/control-structures.elseif.php)使用できる。

ま`elseif`にリライトしとくべきか。

## unpack

リライト対象で、文字列切り出しに`substr`連発するのに切れて、(自分的にperlでは定番である)`unpack`について調べる。が、、、

戻り値が連想配列 orz...

[マニュアル](https://www.php.net/manual/ja/function.pack.php)が分かりにくい。

`unpack`の場合、連想配列のキーを各フォーマットコードの後[^4]に指定する、とか、`/`で複数のフォーマットコードを連結するとか、どこで調べるのよ。

[^4]: 適切な表現がわからん。連想配列のキーもフォーマットコードの一部だと思うが、、、

皆様、バイナリ相手にしてて、ascii相手のサンプルなんてググっても出てこないし、、、

### YYYYmmddのunpack

ということで、↓サンプル。この例だと明らかにperlより使い勝手はよい、か？

```
  $ php -r '$c = unpack("A4y/A2m/A2d", "20210303") ; print_r($c);'
  Array
  (
      [y] => 2021
      [m] => 03
      [d] => 03
  )
```

- y, m, d をキーに ascii 4文字、2文字、2文字に分割

これが、キーを指定しないと最後のフォーマットコードで取得された文字のみが連想配列になる。
しかもインデクスが1！

```
$ php -r '$c = unpack("A4/A2/A2", "20210303" ) ; print_r($c);'
Array
(
     [1] => 03
)
```

### perlでの3桁区切り
perlでの常套手段だった、`(A3)*`なんぞ、できない。

```shell-session:perlの三桁区切り
$ perl -le 'print scalar reverse join ",", unpack "(A3)*", reverse "1234567890"' 
1,234,567,890
```

## phpでの3桁区切り

`str_split`と`strrev`をつかう[^5]

[^5]: `join` は、`implode` のエイリアス。array専用だそうで。

```shell-session:phpの三桁区切り
$ php -r 'echo strrev( join(",", str_split(strrev("1234567890"),3)));'
1,234,567,890
```

## array出力の変数への代入

perl での↓コレ

```
my ( $c, $d ) = @d ;
```

phpでは、`list()`を使う

```
$ php -r '$a = array( 1,2,3) ; list( $b, $c, $d ) = $a ; echo $d ;'
3
```

二次元配列とかでも即座に対応できるのはうれしいかな。

```
$ php -r '$a = array( 1, array(2,3) ) ; list( $b, list( $c, $d ) ) = $a ; echo $d ;'
3
```

いらない要素は無視することも出来る

```
$ php -r 'list( , ,$a ) = preg_split("/\s+/", "2021 03 03") ; print $a ;'
03
```

連想配列にも対応できる[^6]。

[^6]: `=>`が、`,`のエイリアスじゃない！

```
$ php -r 'list( "y" => $y, "d" => $d ) = unpack("A4y/A2m/A2d", "20210303" ) ; echo $d ;'
03
$ php -r 'list( "1" => $d ) = unpack("x6/A2", "20210303" ) ; echo $d ;'
03
```

## 三項演算子

噂で知ってたけど、シンプルな `A ? B : C`のみの使用にとどめるべき。

## シンタックス確認

`-l`オプションを使う

```php:hoge.php
<?php
$a = "20210303" ;
list( $b ) = unpack( "A4/A2/A2y" ) 
echo $b ;
```
```
$ php -l hoge.php

Parse error: syntax error, unexpected 'echo' (T_ECHO) in hoge.php on line 4
Errors parsing hoge.php
```

こんなバギーなコードでも `;`抜けしかチェックできないから、リライト対象のバグ探しには使えない。
Todoアプリ改修とuseState

#Todoアプリ改修

https://qiita.com/ttttkkkkccccc/items/9c364fa2b5e10e17f6e9

前回行った改修の続きとして、今回は完了ボタンを押し、完了エリアへ移動するボタンの実装です。

まずは完了エリアとなる以下のようにコンポーネントを作りました。
この部分は他のコンポーネント見ながら作ったので、すぐに出来ました。

```
import React from "react";

import "../styles/style.scss";

interface TodoCompleted {
  items: { id: string; text: string }[];
  onBackTodo: (id: string, text: string) => void;
}

const CompleteTodo: React.FC<TodoCompleted> = (props) => {
  const { items, onBackTodo } = props;

  return (
    <div className="complate">
      <p className="complate-head">完了Todo</p>
      <ul>
        {items.map((todo) => (
          <li key={todo.id}>
            <span>{todo.text}</span>
            <button className="todoBack" onClick={onBackTodo.bind(null, todo.id, todo.text)}>
              戻す
            </button>
          </li>
        ))}
      </ul>
    </div>
  );
};

export default CompleteTodo;
```


次にどのように実装したら、完了エリアにTodoが行ってくれるか。。。
まずはuseStateが必要だと思い、

```
const App: React.FC = () => {
  const [todos, setTodos] = useState<Todo[]>([]);
  const [completeTodo, setCompleteTodo] = useState<Todo[]>([]);⇨追記したもの
```

上記のcompleteTodoの状態が、完了ボタンが押されたタイミングで変わっていればいいので、
次のように書いてます。
簡単にお伝えするとsetTodos関数で未完了エリアにあるTodoを削除して、
setCompleteTodoで削除されたTodoを完了エリアへ

```
const todoCompletedHandler = (todoId: string, text: string) => {
    setTodos((prevTodo) => prevTodo.filter((todo) => todo.id !== todoId));

    setCompleteTodo((prevTodo) => [
      ...prevTodo,
      { id: Math.random().toString(), text: text },
    ]);
  };
```
しっかり以下もやってます。

```
<TodoList
    items={todos}
    onDeleteTodo={todoDeleteHandler}
    onCompleteTodo={todoCompletedHandler}
/>
<CompleteTodo items={completeTodo} onBackTodo={todoBackHandler} />

```

##学んだこと
ここで学んだものは、useStateです。
例えば以下のようなuseState。

```
const [todos, setTodos] = useState<Todo[]>([]);
```

今の認識はtodosは箱でsetTodosはその箱（todos）の状態を変更する関数。
useStateの<>の部分はtodosをどういう型なのか表している。
Todo[]はインターフェースで以下のように定義済み。

```
export interface  Todo {
  id: string;
  text: string;
}
```

##ソースコード

以下のソースコード公開中です。
どうぞ見てやってください！

https://github.com/takeshi1201/React-Typescript-Todo.git


今回は以上です。
ありがとうございました。
ROSの勉強　第19弾：環境の地図作成に向けて

# #プログラミング ROS< 環境の地図作成に向けて >

##はじめに
1つの参考書に沿って，ROS(Robot Operating System)を難なく扱えるようになることが目的である．その第19弾として，「環境の地図作成に向けて」を扱う．

##環境の地図作成に向けて
ここでは，環境の地図を作成するにあたって必要な前知識を獲得する．主に，ROSにおける地図とrosbagについてである．

##ROSにおける地図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/951300/bf7e9f21-717b-4494-e1e9-e3f4ad0e7334.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/951300/097b351e-eb44-c65b-8eb1-119b519b4d55.png)

以下にYAMLファイルの一例を示す．

```map.yaml
image: map.pgm  #mapという名前で拡張子がPGMの画像データ名　ほかにもPNG, JPGなどもサポートされている
resolution: 0.1  #解像度：0.1[m]の正方形セル
origin: [0.0, 0.0, 0.0]  #原点の位置
occupied_thresh: 0.65  #障害物が占有しているとする閾値
free_thresh: 0.65  #障害物が占有していないとする閾値
negate: 1  #ROSで処理する前にセルの値を反転
```
それぞれの説明は上記に示すとおりである．最下行の``negate``を行う理由は，はじめに示したとおり，障害物が占有していないところを明るく（白），占有していないところを暗く（黒）としたいためである．デフォルトでは，逆になっている．

##rosbag
次にデータを記録する方法について学ぶ．ここで，使うのはrosbagである．以下に簡単な説明を示す．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/951300/ced49a8a-d9ba-33d4-a90b-48cd91edd502.png)

上の説明で，``-a``をつけると，配信しているトピックをすべて記録できると示したが，特にPR2のように多くのセンサを搭載したロボットでは，大量のデータを記録してしまうことになる．また，rosbagはCtrl-Cで止められるまで記録し続ける．

さらに，rosbagのファイルについては，``rosbag info``で見ることができる．
以下に一例を示す．

```yaml
~$ rosbag info laser.bag

#以下，表示結果
path:          laser.bag  #対象ファイル
version:       2.0
duration:      1:44s (104s)
start:         Mar 04 2021 10:04:13.44 (1310058253.44)
end:           Mar 04 2021 10:05:58.04 (1310058358.04)
size:          8.2 MB
messages:      2004
compression:   none [11/11 chunks]
types:         sensor_msgs/LaserScan [90c7ef2dc6895d81024acba2ac42f369]
topics:        base_scan   2004 msgs    : sensor_msgs/LaserScan
```
これにより，bagファイルに記録されている時間，記録の開始時刻と終了時刻，ファイルの大きさ，メッセージ数，メッセージ（とトピック）の内容などを知ることができる．これは，記録したbagファイルに，期待した情報が記録されているかを確認するのに便利である．

また，**rosbagは，ロボットの新しいアルゴリズムのデバッグをするときに非常に便利なツール**である．例えば，アルゴリズムのデバッグのとき，生のセンサデータを使う代わりに，rosbagで記録しておいた代表的なデータセットを再生することでアルゴリズムにセンサデータを与えるようにする．こうすることで，アルゴリズムは**毎回，まったく同じデータを処理することができるようになる**．この**再現性は，デバッグの効率を上げてくれる**．ロボットの動作の変化は，新しく観測された未知のセンサデータ入力によるものではなく，**すべてコードを変えたことによるものであることが保証される**．

##感想
今回は，まだ地図作成に入っていないが，ROSの地図について知り，rosbagという強力なツールについて学ぶことができた．地図の作成については今までに経験がないため，より慎重に理解していきたいと思う．


##参考文献
プログラミングROS Pythonによるロボットアプリケーション開発
　　　　　　　　Morgan Quigley, Brian Gerkey, William D.Smart 著
　　　　　　　　　　　　　　　　　　　　　　　河田　卓志　監訳
　　　　　　　　　　  　松田　晃一，福地　正樹，由谷　哲夫　訳
　　　　　　　　　　　　　　　　　　オイラリー・ジャパン　発行
日本語フォントでもOK！？自動カーニング（字間調整）できるCSSがすごい！

# どうも7noteです。フォントによる字間の悩みはこれで1発解決！

様々な日本語フォントがありますが、フォントによって1文字の大きさが違い、いざ実装してみるとなんだかやぼったい感じ（ダサい）の文字の並びになってしまうことが気になるあなたへ。

特にデザイナーからWEBのコーディングも始められた方は

*「cssで字間の自動調整ってできないの？」*

と思われる方もいるかも。そんな方へ**朗報**です。
デザイナーから字詰めを迫られていたコーダーの人も、**朗報**です。

## `font-feature-settings: "palt"`を使うことで、自動で字間調整してくれる。

プロポーショナルメトリクスが有効になるフォントであれば、この指定を入れるだけで一発で自動カーニングをしてくれるようです！しかもほぼ全てのブラウザで対応。

```css
.palt {
  /* プロポーショナルメトリクスと旧字体指定 */
  font-feature-settings: "palt";
}
```


[Can I use](https://caniuse.com/font-feature)で確認しても主要ブラウザは全て対応。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661092/9149f2ea-cb77-96f7-cf07-00d223a6c9c1.png)


（設定前と設定後のテキストを比較。）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661092/8df15fe7-f04c-ace5-3bd5-1b3062228ac7.png)

全体的に指定ありの方が**余分な隙間がキュッとしまった印象**になります。


## まとめ

`font-feature-settings: "palt";`の指定が使えるフォントは限られているようなので、指定しても「あれ？効かない？」と思ったら[こちら](https://ics.media/entry/14087/)のサイトに綺麗に情報がまとまっていますのでこちらを見ていただくといいかもしれません。

参考サイト：https://ics.media/entry/14087/

#### おそまつ！
~ Qiitaで毎日投稿中!! ~
[【初心者向け】WEB制作のちょいテク詰め合わせ](https://qiita.com/7note)
ラズパイ用 4G 通信モジュール 4GPi の OS イメージを SD カードに書き込む

## はじめに.

メカトラックスの @kiyonaga です。
今回は 4GPi 用の OS イメージを SD カードに書き込む方法を紹介します。
書き込みには Raspberry Pi 財団公式の Raspberry Pi Imager を使用します。

4GPi の詳細は [弊社ホームページ](https://mechatrax.com/products/4gpi/) をご参照ください。

## 実行環境
* Windows PC
* カードリーダー
* microSD カード

## 1. Raspberry Pi Imager のセットアップ

https://www.raspberrypi.org/software/
PC の OS に対応したものをダウンロード後、インストールしてください。
※ 記事公開後に Raspberry Pi Imager のバージョンが変更になる可能性があります。あらかじめご了承ください。

## 2. 4GPi 用 OS イメージをダウンロード

次のリンク先から最新（一番上）のイメージをクリックしてダウンロードします。
https://mechatrax.com/data/4gpi/

OS イメージの詳細は[ こちら ](https://github.com/mechatrax/4gpi/blob/main/os/Readme.md#os-%E3%82%A4%E3%83%A1%E3%83%BC%E3%82%B8)から

::: note info
4gpi-bullseye-lite-20220711 以降のリリースでは初期ログインユーザーが設定されていません。
ユーザーの追加が必要となります。
:::

## 3. SD カードをフォーマット

OS イメージを書き込む SD カードをあらかじめフォーマットしておきます。
次の手順で SD カードをフォーマットします

* Raspberry Pi imager を起動
* OS 項目で「Erase」を選択
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1174732/1a7edb02-151a-9d3e-163f-bb838be5c007.png">

* ストレージ項目で対象の SD カードを選択
* 「次へ」を押すとポップアップが表示される
* 「はい」を選択


## 4. 4GPi 用 OS イメージを SD カードへ書き込む

次の手順で Raspberry Pi Imager で OS イメージを書き込みます。

* Raspberry Pi Imager を起動
* Raspberry Pi デバイス項目で「No filtering」を選択
* OS 項目で「Use custom」を選択
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1174732/fb5c6347-425a-0acb-9c5a-4fef04a186d6.png">

* [2. 4GPi 用 OS イメージをダウンロード](https://qiita.com/kiyonaga/items/73fa842ddcde0e028294#2-4gpi-%E7%94%A8-os-%E3%82%A4%E3%83%A1%E3%83%BC%E3%82%B8%E3%82%92%E3%83%80%E3%82%A6%E3%83%B3%E3%83%AD%E3%83%BC%E3%83%89) で保存した OS イメージを選択
* ストレージ項目で書き込む SD カードを選択
* 「次へ」を押す
* 「設定を編集する」を選択
* 一般項目から「ユーザー名とパスワードを設定する」にチェック
* ユーザー名とパスワードを入力
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1174732/2a7850df-9619-b3e7-f9c5-d28a9d30ebe1.png">

※ その他の設定項目については [こちら](https://www.raspberrypi.com/documentation/computers/getting-started.html#advanced-options) をご参照ください。

* 保存を選択
* 「はい」を選択
* データ削除の警告ポップアップで「はい」を選択

書き込みと検証が正常に完了すると、次のようなポップアップが出て書き込み完了となります。
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1174732/5dfe23ea-6c8c-d2ba-10b1-1b2c7c61e93e.png">



念のため、ラズベリーパイの起動を確認してください。
起動できない場合は、ラズベリーパイの緑 LED の点滅パターンで判断することができます。
点滅パターンについては [こちら](https://www.raspberrypi.com/documentation/computers/configuration.html#led-warning-flash-codes) をご参照ください。

### 書き込みに失敗する場合

* ZIP ファイル場合は解凍して、中身の img ファイルを Raspberry Pi Imager で選択する
* 公式サイトの書き込み方法を試す
[こちら](https://www.raspberrypi.com/documentation/computers/getting-started.html#installing-the-operating-system) をご参照ください。

## おわりに.
今回は弊社製品の 4GPi 用 OS イメージをラズベリーパイの SD カードに書き込む方法を紹介しました。
4GPi のユーティリティソフトウェアのインストールが上手くいかない場合などにご利用ください。
【初心者】Swift UIを勉強する その①   ーーー可視化エディタ

# はじめに

**Swift UIは公表してからもう2年近くたちました。ネット上の情報量もけっこう増えたので、そろそろ本格に学習しないとと考えて本記事をはじめました。**

**初心者でも分かりやすい[Design Code](https://designcode.io/swiftui-ios14)を使ってやっていきます。**

**・Swift UIの強み**
1.自家製のリアクティブフレームワークCombine
2.最も時間がかかるUI設計はリアルタイムで確認できる
3.iOS・macOS・carOS(予想？),　すべてネイティブに

# 目次
<!-- タイトルとアンカー名を編集 -->
1. [シミュレータ編集可能](#シミュレータ編集可能)
2. [inspectorが便利](#inspectorが便利)
3. [複数のシミュレータを使う](#複数のシミュレータを使う)
4. [まとめ](#まとめ)
5. [参考文献](#reference)


<!-- 各チャプター -->
<a id="#シミュレータ編集可能"></a>
# シミュレーター編集可能
・テキストを編集する際に、コードから編集する以外に、画面と右上にあるTextから編集することも可能です。
・画面デザインのルールについて、不明点があれば[Human Interface Guidelines](https://developer.apple.com/design/human-interface-guidelines/ios/overview/themes/)を参考してください。

![截屏2021-02-13 19.52.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1065841/6b8959c5-93e7-9627-df2f-1031c4f68cdf.png)


<a id="#inspectorが便利"></a>
# inspectorが便利
・シミュレーターをクリックし、cmd+dを押せば同じテキストは下にコピーできます。
・paddingはコードから直接削除する他に、右のinspectorの✖️も削除できます。
![截屏2021-02-13 20.16.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1065841/72a3a6d5-d6e5-bee7-dbe9-4935eaca15e1.png)






・テキストとテキストのpaddingを変更したい場合は、テキストに対してpaddingを足すことではなく、VStackから行うのがおすすめです。
・シミュレーターでVstackのエリアを選択し、backgroundをinspector（Add Modifier）から追加できます。（右上の＋ボタンからもできます）
・写真を追加した後に、resizableとaspectRatioを使って大きさを決めましょう。メリットとしてはVStackの大きさによって写真の大きさは動的に変わってきます。
![截屏2021-02-13 21.00.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1065841/c0dc1a75-febd-35c7-b30f-7b155e1276cc.png)



<a id="#複数のシミュレータを使う"></a>
# 複数のシミュレータを使う
・＋ボタンを押せば、今のシミュレータがコピーされます。
・darkモードに変更したら、textの色は白に変わりました。オリジナルの色では賢く変わってくれないので、できればデフォルトの色を使いましょう。[Human Interface Guidelines](https://developer.apple.com/design/human-interface-guidelines/ios/visual-design/color/)
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1065841/39cb542e-2a62-8c1d-4af3-647d633f6b9f.png" width=40%>
・シミュレーターごとをクリックし、layoutをFixedに変えます。layoutはwidth200とheight200としたら、四角に隙間が見えます。spacerを使って、containerを全部使うことになります。写真はsafe area以外を使いきります。
![截屏2021-02-13 21.35.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1065841/0642ecc8-85fd-f603-4c7d-b6be3aac30a3.png)


・写真に対してもspacerを追加したら完成です。
![截屏2021-02-13 21.50.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1065841/db72b3e2-2791-063c-1310-47b02a6ca9fa.png)

<a id="#まとめ"></a>
# まとめ
・inspectorを使えば、どこに何を追加すべきかはわかりやすくなります。
・逆にinspectorはデザインのミスや漏れが起こりやすいデメリットもあります。

**ソースコード[Github](https://github.com/wsimple1028/swiftUI_ios14)**

<a id="#reference"></a>
# 参考文献
- [Design Code --- SwiftUI for iOS 14](https://designcode.io/swiftui-ios14)
Ubuntu の vmware player に Windows Server 2022 をインストール

Ubuntu の vmware player に Windows Server 2022 をインストールします。
![Screenshot from 2021-03-04 13-05-19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115935/ba891f3a-f09a-ec7e-3afd-e617c8022a23.png)
まず、Windows 2022 をインサイダープログラムのページよりダウンロードします（たしかマイクロソフトアカウントが必要です）。

[Download Windows Server Insider Preview ](https://www.microsoft.com/en-us/software-download/windowsinsiderpreviewserver)

今回ダウンロードするのはプロダウンメニューから

「Windows Server 2022 Preview VHDX - Build 20303」

を選択します。
この VHDX は Microsoft が得意とする Hyper-V の仮想ソフト形式になります。今回はこれを使用します。

ダウンロードに３時間くらいと非常に時間がかかりますので、のんびりと仕込むといいと思います。

次にダウンロードしたファイルを vmware が扱える形式に変換します。


まずは変換ソフトのインストール

````bash
sudo apt install -y qemu-utils ;
````

次に変換

````bash
qemu-img convert -p Windows_InsiderPreview_ServerStandard_en-us_VHDX_20303.vhdx -O vmdk Windows_InsiderPreview_ServerStandard_en-us_VHDX_20303.vmdk ;
````

これで一見終わりかと思いきやここからが vmware player で再生するためのノウハウになります。

まずは通常通り、仮想マシンを作成します。

「OSのインストールはあとで」を選択します。
![Screenshot from 2021-03-04 19-40-52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115935/59ade7a7-7c4d-4cea-1419-a1096f4fb93a.png)
一旦、通常通り作成を終えます。

その後、新規作成をした仮想マシンを編集します。

HDDを削除します。

次にHDDを追加して、ここに先程変換を行った vmdk ファイル（Windows_InsiderPreview_ServerStandard_en-us_VHDX_20303.vmdk ）を指定します。
![Screenshot from 2021-03-04 19-40-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115935/f7f5e029-2565-06a4-dd36-3941852e8b2d.png)
![Screenshot from 2021-03-04 19-40-09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115935/bb0c63dc-6add-6d8d-f5f9-f3efef186f13.png)
![Screenshot from 2021-03-04 19-40-23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115935/1d60cd77-e72b-0ddb-a224-65872898da7c.png)
これで、起動時にこのファイルをマウントして Windows2022 が起動します。
起動に失敗してDHCPから起動しようとしてしまう場合は、初期起動はさせず、最初にHDDを削除してからvmdkをマウントしてから起動すればうまくいくかと思います。

Windows 2022 を触った感触しては現行の Windows 10 にサーバー用のコントロールパネルが付いた感じてよい印象をうけました。Windows2012あたりは本当に使いづらかったので、かなり良さげです。
####参考リンク
- [Download Windows Server Insider Preview ](https://www.microsoft.com/en-us/software-download/windowsinsiderpreviewserver)
- [A Full Guide on How to Convert VHD to VMDK for Free ](https://www.nakivo.com/blog/how-to-convert-vhd-to-vmdk-a-step-by-step-guide/)
- [既存の VMDK 仮想ディスクを使用した Workstation 仮想マシンの作成 (2010196) ](https://kb.vmware.com/s/article/2010196?lang=ja)
- [software installation - How to install "qemu-img" and use it to convert a "qcow2" image to a Virtual Box one? - Ask Ubuntu ](https://askubuntu.com/questions/754127/how-to-install-qemu-img-and-use-it-to-convert-a-qcow2-image-to-a-virtual-box)
真っ新なWindowsでのZipファイル作成方法比較

## 概要

まっさらなWindows上でZipファイルを圧縮する方法として

* 対象ファイル/フォルダを右クリックし、送る→圧縮
* PowershellのCompress-Archiveコマンド
* [ZipFile.CreateFromDirectory](https://docs.microsoft.com/en-us/dotnet/api/system.io.compression.zipfile.createfromdirectory)呼出

があります。それぞれの方法の内、どれを使えばよいか考えます。

なお、**Shellオブジェクト経由のCopyHereを使用した圧縮方法**は、
公式から[非推奨な方法](https://support.microsoft.com/ja-jp/topic/copyhere-%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89%E3%81%8B%E3%82%89-zip-%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92%E5%87%A6%E7%90%86%E3%81%99%E3%82%8B%E3%81%93%E3%81%A8%E3%81%AF%E3%81%A7%E3%81%8D%E3%81%BE%E3%81%9B%E3%82%93-a393a8b4-3330-5d88-c850-d634744fdb4a)とされているため取り扱いません。

## 結論

* 更新日時を秒単位で保持したいのであれば、標準機能では実現できない
* すべてのフォルダ/ファイルを圧縮したいのであれば、ZipFile一択
* "読取専用"や"隠し"等、ファイル属性を保持したいのなら、送る→圧縮

## 理由

更新日時に関してはどの方法もZipファイルの仕様(2秒刻みの日時でしか表現できない)に従い、また拡張フィールドに細かい日時の記録もしていないようです。
FATはともかくNTFSはより細かい単位で記録されるため、圧縮前のファイルと、圧縮後展開したファイルの更新日時はほとんどの場合一致しません。

### 送る→圧縮に関して
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1172587/4302c07b-5493-ab17-23e7-3afaf8157c06.png)

「.」で始まるフォルダが複数ある場合、1個目のフォルダしか圧縮されまぜん。
例えば、下図のように「.dir」フォルダ「.dir2」フォルダを含むフォルダを圧縮すると、「.dir2」フォルダは(その中に含まれるファイルフォルダを含めて)無視されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1172587/d26573e2-4dd8-2ca7-8afd-cdf4bd75e342.png)

### PowershellのCompress-Archiveコマンド

* ファイル属性は保存されない
* 隠しファイルや隠しフォルダは無視される
* パラメータの指定方法によっては空フォルダが無視される
* 2GBの制約

### ZipFile.CreateFromDirectory

* ファイル属性は保存されない


## [おまけ] すべてのフォルダ/ファイルを圧縮するスクリプト

ファイルの属性は保存できず。また、タイムスタンプも2秒刻みですが、
以下のスクリプトなら、Win10で安全にZipファイルを作成できます。

```batchfile
@Echo Off
setlocal

Set TargetPath=%~dpnx1
Set DestPath=%~dpnx2

Rem 第2引数がセットされていないなら、第1引数から算出
If "%DestPath%" equ "" Set DestPath=%~dpn1.zip

Rem パラメタ未設定はエラー
If "%TargetPath%" equ "" Goto NoParamError

Echo 圧縮対象： %TargetPath%
Echo 圧縮ファイル： %DestPath%

Rem 圧縮ファイルが対象が既に存在するならエラー
If exist "%DestPath%" Goto AlreadyExistError

Rem 圧縮対象がファイルかフォルダかで実行コマンドを変更
If exist "%TargetPath%\" Goto DoCompressDirectory
If exist "%TargetPath%"  Goto DoCompressFile
Goto TargetNotExistError



:NoParamError
Set Message=圧縮するファイル/フォルダを入力してください。
PowerShell -Command "Write-Host -fore Red %Message%" >&2
Exit /B 1

:AlreadyExistError
Set Message=圧縮ファイルはすでに存在します。
PowerShell -Command "Write-Host -fore Red %Message%" >&2
Exit /B 2

:TargetNotExistError
Set Message=圧縮するファイル/フォルダが見つかりません。
PowerShell -Command "Write-Host -fore Red %Message%" >&2
Exit /B 3

:DoCompressFile
PowerShell -Command "Add-Type -AssemblyName System.IO.Compression ; Add-Type -AssemblyName System.IO.Compression.FileSystem ; $za=[System.IO.Compression.ZipFile]::Open('%DestPath%', [System.IO.Compression.ZipArchiveMode]::Create) ; Try{ $entryNm=[System.IO.Path]::GetFileName('%TargetPath%') ; [void][System.IO.Compression.ZipFileExtensions]::CreateEntryFromFile($za, '%TargetPath%', $entryNm) } Finally { $za.Dispose() }"
Goto Finally

:DoCompressDirectory
PowerShell -Command "Add-Type -AssemblyName System.IO.Compression.FileSystem ; [System.IO.Compression.ZipFile]::CreateFromDirectory('%TargetPath%', '%DestPath%')"
Goto Finally

:Finally
Exit /B %errorlevel%
```
【Vue.js】vue sass-loader エラー：Module build failed: TypeError: this.getResolve is not a function

# 背景
Vue.js Cliをいじっていて、Sass記述したらエラーが出た

# エラー
```
Failed to compile.
./src/index.vue?vue&type=style&index=0&id=2964abc9&scoped=true&lang=scss& (./node_modules/css-loader/dist/cjs.js??ref--8-oneOf-1-1!./node_modules/vue-loader/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/src??ref--8-oneOf-1-2!./node_modules/sass-loader/dist/cjs.js??ref--8-oneOf-1-3!./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader/lib??vue-loader-options!./src/index.vue?vue&type=style&index=0&id=2964abc9&scoped=true&lang=scss&)
Module build failed (from ./node_modules/sass-loader/dist/cjs.js):
TypeError: this.getOptions is not a function
    at Object.loader
```
が出力され、テンプレートが表示できない

## 原因１
最初「sass-loader」が入ってないと言われ、以下記事の内容を元に互換性があるwebpackとsass-loaderをnpmインストールした、がまだ解決しない→scssがコンパイルされるようにはなった
以下記事参照：

https://stackoverflow.com/questions/58546521/node-sass-and-sass-loader-module-build-failed-typeerror-this-getresolve-is-n

## 原因２

よく見たらちゃんと書いてありました^ ^;

```
Syntax Error: Error: Node Sass version 5.0.0 is incompatible with ^4.0.0.
```

## 解決

node-sassをアンインストールします

```
npm uninstall node-sass
```

次に、互換性のある、4.14.1をインストールします

```
npm install node-sass@4.14.1
```

# 参照
https://stackoverflow.com/questions/64625050/error-node-sass-version-5-0-0-is-incompatible-with-4-0-0
Jetson Xavier NXでPytorch1.7をインストールしてYOLOv5を動かす

アーキテクチャが違ったり、依存関係があったりでいろいろと苦労しましたが、
JetsonでYOLOv5を動かすことができました。

Jetpackはv4.5.1です。
OSイメージ入れ立ての状態でインストールしました。

Pytorchを入れます。

```
sudo apt-get update
wget https://nvidia.box.com/shared/static/cs3xn3td6sfgtene6jdvsxlr366m2dhq.whl -O torch-1.7.0-cp36-cp36m-linux_aarch64.whl
sudo apt-get install python3-pip libopenblas-base libopenmpi-dev
pip3 install Cython
pip3 install numpy torch-1.7.0-cp36-cp36m-linux_aarch64.whl
```



Torchvisionを入れます。バージョンは、branch基準で変えることができます。

```
sudo apt-get update
sudo apt-get install libjpeg-dev zlib1g-dev libpython3-dev libavcodec-dev libavformat-dev libswscale-dev
git clone --branch v0.8.1 https://github.com/pytorch/vision torchvision
cd torchvision
export BUILD_VERSION=0.x.0
python3 setup.py install
cd ..
pip3 install 'pillow<7'
```

(ここまで参考：https://forums.developer.nvidia.com/t/pytorch-for-jetson-version-1-7-0-now-available/72048)

以下は、scipyをインストールするために必要でした。

```
sudo apt-get install -y build-essential libatlas-base-dev
```

```
pip3 install -U pip
pip3 install -U setuptools
```

ここからは、requiment.txtのライブラリをpipでインストールしますが、
torchvisionは0.8.1が入らなかったので、0.8以上で指定をrequiments.txtを変更しました。
他にもバージョン指定を解除したものが１つ２つあったかもしれません。
pipは１つずつインストールしました。
同一オリジンポリシーの必要性を具体的にかつ感覚で理解したい

[前回のCookieのDomain属性の記事](https://qiita.com/HAYASHI-Masayuki/items/209039717c15834603d8)に引き続き、[某所](https://commew.net/)での勉強会でまた理解が怪しいことが出てきたので、考えてまとめてみました。

今回は同一オリジンポリシーです。同一オリジンポリシーがなんなのか、ということ自体は問題な理解できたのですが、なぜそれが必要なのか、ということに関してすっきり納得できるようには理解できませんでした。


# 結論

1. 攻撃者はJavaScriptによりブラウザを強制的に操作することができる。
2. それにより攻撃者のではなく、ブラウザの権限で攻撃者の意図する操作が行われる。
3. そのため同一オリジンポリシーがない場合、本来権限がないため攻撃者がアクセスできないはずの別オリジンのデータを盗み出すことができる。

というのが同一オリジンポリシーが必要な理由ではないかと思われます。


# 同一オリジンポリシーはなにを制限していて、なにを制限していないか

同一オリジンポリシーは、以下のものを制限しているようです。

* XMLHttpRequestによる別オリジンへのリクエスト。
* frame, iframeで表示している別オリジンのドキュメントへのJavaScriptからのアクセス。
* Canvasによる別オリジンの画像の読み込み。

逆に、以下のようなJavaScript以外による別ドメインへのアクセスは制限されていないようです。

* a要素のクリックによる別オリジンのURLへの移動。
* location.hrefによる別オリジンのURLへの移動。
* form要素のサブミットによる別オリジンのURLへのPOSTリクエスト。
* img, script, style要素による別オリジンのデータの読み込み。


# もし同一オリジンポリシーがなかったら

別オリジンにXMLHttpRequestできたり、別オリジンの任意のページをframe, iframe経由で好きに読み込むことができたら、いったいどうなるのか、考えてみます。

まず悪意のあるJavaScriptが仕込まれた罠サイトがあるとします。JavaScriptの実行は、一応ブラウザの設定で無効にすることもできたりしますが、最近はもうほとんどそのようなことをする人はいないと思うので、あるサイトにアクセスするということは、そこにあるJavaScriptを実行されることと同義と考えていいと思います。

同一オリジンポリシーがなければ、XMLHttpRequestはHTTPリクエストを自由に送って、XMLに限らずいろんなものを取得できます。Cookieも普通に送信されるので、ブラウザでログインしていたら、ログインしている状態でそのサイトに自由にアクセスできてしまいます。

たとえばECサイトの送付先住所が掲載されているページにリクエストを送れば、住所を取得できてしまいます。

パスワードやクレジットカード情報が直接表示されるようなページは現在は基本的にありませんが、それ以外の、メールアドレスや住所氏名、電話番号といった情報は大抵普通に表示されています。これらの情報がすべて盗み出されてしまいます。

frame, iframeの場合もおそらく同様です。Canvasは少し勝手が違いますが、画像共有サイトにアップロードしてはいるが、非公開にしている画像などが盗まれることになると考えられます。

このような被害を防ぐために、同一オリジンポリシーが必要なのでしょう。


# 同一オリジンポリシーの制限がなくても安全な機能は、なぜ安全か

ついでに、同一オリジンポリシーの制限がない機能に、なぜ制限がないかについても考えてみます。

a要素、location.hrefについては簡単で、別オリジンのページに移動させられることは、単純にそれほど危険ではないからでしょう。前者に関しては基本的には能動的な操作さえ必要です。

img, script, style要素については少し混乱しますが、実は同様で、ブラウザがこれらの要素から別オリジンのドキュメントにアクセスさせられはしますが、そのアクセス結果を罠サイト側から知ることはできません。[^1]


# 例外

* form要素のサブミットによるPOSTリクエストは同一オリジンポリシーによる制限がありませんが、これは完全に安全ではなく、CSRF脆弱性と関連します。今回の本題ではないため省略します。
* script要素は完全に安全ではなく、秘匿情報がJavaScript内に出力されている場合に盗まれる可能性があります。これも省略します。

# 参考

[体系的に学ぶ 安全なWebアプリケーションの作り方](https://www.sbcr.jp/product/4797393163/) この本の勉強をしています。


[画像とキャンバスをオリジン間で利用できるようにする - HTML: HyperText Markup Language | MDN](https://developer.mozilla.org/ja/docs/Web/HTML/CORS_enabled_image) Canvasとオリジンの話。


# この記事のライセンス

![クリエイティブ・コモンズ・ライセンス](https://i.creativecommons.org/l/by/4.0/88x31.png)
この文書は[CC BY(クリエイティブ・コモンズ表示4.0国際ライセンス)](http://creativecommons.org/licenses/by/4.0/)で公開します。


[^1]: ただしscript要素に関しては例外があります。別オリジンのJavaScriptを読み込んだ場合、そのJavaScriptで定義された変数を罠サイト側で使用できるため、JavaScript内に秘匿情報があれば盗み出されることがあります。
Jenkins経由でGit Checkoutがタイムアウトになって出来なかった時

# はじめに
JenkinsでGit Checkoutをしたところ下記のErrorが出ました。
結果的にはファイル容量が大きすぎてタイムアウトしてビルドが通らなかったのですが、その時の解決方法です。

```
ERROR: Timeout after 10 minutes
FATAL: Could not checkout git hash
Hudson.plugins.git.GitException: Command “/usr/local/bin/git checkout -f git hash” returned status code 143:
stdout:
Stderr: Filtering content: 22%(2/9), 70.42 MiB | 9.20 MiB/s
　　at org.jenkinsci.plugins.gitclient.CliGitAPllmpl.launchCommandln(CliGitAPllmpl.java:2450)
　　at org.jenkinsci.plugins.gitclient.CliGitAPllmpl.access$1100(CliGitAPllmpl.java:84)
　　at org.jenkinsci.plugins.gitclient.CliGitAPllmpl$9.exeute(CliGitAPllmpl.java:2767)
Hudson.plugins.git.GitException: Could not checkout git hash
　　at org.jenkinsci.plugins.gitclient.CliGitAPllmpl$9.exeute(CliGitAPllmpl.java:2791)
…
Performing Post build task…
Match found for :: True
```

## 解決策
`Advanced clone behaviors`の設定を加えます。
`Fetch tags`をTrue。
クローンとフェッチのタイムアウト(分)を30に設定
`Shallow clone` -> `Shallow clone depth`を`0`に設定

![sample.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1022988/f82a403b-5099-d323-3b05-9a6e150e4ff5.png)

shallow cloneを使うことよりcheckoutの時間を短縮させますが、git logをしても過去のコミットを見ることはできません。
最新のリポジトリの状態でビルドしたいけど過去のコミットの情報は不要という場合に使用した方が良いです。
EclipseでのJUnitのエラー対処 備忘録

# エラー

```
[ERROR] Failed to execute goal project resource: Could not resolve dependencies for project xxxxx:jar:1.0.0: The following artifact could not be resolved xxxxx:jar:1.0.0 in  https://repo.maven.apache.org/maven2 was cached in the local repository, resolution will not be reattempted utill the update interval of central has elapsed or updates are forced
```

# 解決策

[実行]-[実行構成]

[{該当JUnitテスト}]-[テスト]-[テスト・ランナー]のバージョンを適切なバージョンに変更する
Anaconda仮想環境でDjangoの開発サーバーをバッチ起動

#はじめに
毎回、Anacondaのコマンドプロンプトを開いて→ディレクトリ移動して→runserverして→ローカルサーバーにアクセスして→というのが面倒くさかったことと、疑似的なデスクトップアプリ(?)にしたかったため作成しました。
※この記事を書いた本人はプログラミング初心者なので、間違い等は優しく指摘していただけると嬉しいです。

#自己紹介
Rujuu(@Rujuu_study)
↑これといったことは書かないと思いますが、フォローしていただけると大喜びしますm(_ _)m 

#環境
・Windows10
・conda4.9.0
・Python3.8.3
・django3.1.5



#コード
```runserver.bat
rem カレントディレクトリを実行しているファイルのフォルダに移動
cd /d %~dp0
rem anaconda環境の呼び出し(%USERNAME%はユーザー名を取得するためのもの)
call C:\Users\%USERNAME%\Anaconda3\Scripts\activate.bat
rem 仮想環境呼び出し(自身の仮想環境名にしてください)
call activate 仮想環境名

rem Chromeでローカルサーバーにアクセス(""内は自身が作成したurl.pyに沿ったものに)
start chrome.exe "http://127.0.0.1:8000/"
rem サーバー起動
python manage.py runserver
```
###注意事項
・作成するbatファイルはmanage.pyと同じ階層に置いてください。
・remはコメントです。
・コードをカスタマイズする際に「python manage.py runserver」の後に処理を書くと、追加した処理が実行されないかもです。
・デスクトップアプリ風(？)にする際は、バッチファイルのショートカットをデスクトップなどに作ってください。
・app画面が表示されなければ、再読み込みすることで表示されます。

#参考文献
[犬でもわかるバッチファイルの作り方～カレントディレクトリを意識しよう！](https://a-zs.net/inuwaka-batch-01/)
[batファイルから任意のanaconda仮想環境で.pyを起動](https://kiseno-log.com/2020/04/15/bat%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%8B%E3%82%89%E4%BB%BB%E6%84%8F%E3%81%AEanaconda%E4%BB%AE%E6%83%B3%E7%92%B0%E5%A2%83%E3%81%A7-py%E3%82%92%E8%B5%B7%E5%8B%95/)
[指定したURLを開くバッチファイルの作り方を教えてください。(Googlechromeで開く)](https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q12130438062)

#最後に
世の中の誰かの参考になれば嬉しいです。
改善案等待ってます。
【jquery,js】連動するオブジェクトを実装する [val,change,radioボタン] [js11_20210304]   

####  <font color='orange'>処理の概要</font>
チェックボックスを変更すると、連動して別のチェックボックスにも同じ変更が施される。

##### 処理のフロー：
今回は特に記述なし。

####  <font color='orange'>画面イメージ</font>


#####画像１
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647299/d1764302-48fc-8ed6-1609-c0429fffe21a.png" width="500px">

#####画像２
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647299/dc72cc70-8d65-9cb0-c662-4da9a4786403.png" width="500px">

####  <font color='orange'>ソースコード</font>
```html:index.html
<body>
       <div>
           【連動するチェックボックス】<br>
           同意する<input type="checkbox" id="interLockingCheck1"><br>
           会員になる<input type="checkbox" id="interLockingCheck2"><br>
       </div>
       <br><br>
       <div>
            【連動するラジオボタン】<br>
            子供<input type="radio" name="interLockingRadio1" value="1"><br>
            大人<input type="radio" name="interLockingRadio1" value="2"><br>
            <br>
            バス運賃（三ノ宮から神戸市北区）：150円<input type="radio" name="interLockingRadio2" value="1"><br>
            バス運賃（三ノ宮から神戸市北区）：300円<input type="radio" name="interLockingRadio2" value="2"><br>
        </div>
        <div id="sumValueOutput"></div>
</body>
```


```javascript:main.js
$(function(){
    var sumValue = 0;

    $("#interLockingCheck1").click(function(){
        var lobjCheck = $("#interLockingCheck1").prop("checked");
        $("#interLockingCheck2").prop("checked",lobjCheck);
    });

    $("input[name=interLockingRadio1]").click(function(){
        var lobjRadio = $("input[name=interLockingRadio1]:checked").val();
        $("input[name=interLockingRadio2]").val([lobjRadio]);
    });

    $("input[name=interLockingRadio1]").change(function(){
        sumValue = 150 * $("input[name=interLockingRadio2]:checked").val();
        var lobjMessage = "バス運賃の合計は " + sumValue + " 円です。";
        $("#sumValueOutput").html(lobjMessage);
    });

});
```

####  <font color='orange'>ポイント</font>
html：
なし
js：
(1)propは引数が1つの場合は、取得。引数が2つの場合は指定の属性を変更出来る
(2)チェックボックスから取得した値はすべて文字列なので、valに入力する場合は変換が必要。
(3)ラジオボタンで選択しているセレクタを選択する場合は「:checked」で選択できる。
(4)ラジオボタンのグルーピングは同じnameを付けること。

####  <font color='orange'>参考資料</font>
JavaScript(仕事の現場でサッと使える！デザイン教科書)　p60
HTML~フォーム④~

ではでは、今まで使った技術でフォームで作っていきましょう！！

```index.html
<link rel="stylesheet" href="css/style.css">
  <div class="form">
    <h1>お問い合わせフォーム</h1>
  <label>名前：<input type="text"></label><br>
  <label>電話番号：<input type="number"></label><br>
  <label>メールアドレス：<input type="email"></label><br>
  <fieldset>
    <legend>どこで当社を知りましたか？？(複数選択可)</legend>
    <label><input type="checkbox">知り合い</label>
    <label><input type="checkbox">新聞・テレビ</label>
    <label><input type="checkbox">インターネット</label>
  </fieldset>
  <label for="comment">お問い合わせ内容</label>
  <textarea id="comment" name="comment"></textarea>
  <button>送信</button>

</div>

```

簡易的なお問い合わせフォームなので雑ですが🥲
今まで作れなかった人が作れたので勘弁してあげてください笑
labelのあとのbrは行を変えたかったので作りました。
textareaはidとforを紐付けました👍

```style.css
.form {
  background-color: aqua;
  width: 40%;
  margin: 30px 40px ;
  padding: 30px;
  display: flex;
  flex-direction:column;
}

h1 {
  border: 2px solid black;
  width: 50%;
}

fieldset {
  width: 52%;
  margin-bottom:10px ;
}

textarea {
  display: block;
  height: 200px;
  margin: 20px;
  width: 80%%;
}


button {
  width: 10%;
  margin: 0px 0px 20px 20px;
}
```
cssは完全に感なのであれですが、、、、
噂のフレックスボックスですね(^_^;)フレックスボックスはこちらを
https://qiita.com/akari_0618/items/85a6f6d7eaf6681e11df

一応、ブラウザではこうなります！！
![スクリーンショット 2021-03-04 18.34.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1033397/f3c8a1b6-846d-cc76-775d-89b975b851ef.png)