OmniAICreator/Qiita-1.07M huggingface dataset:
ComfyUI・SDXL・AnimateDiffの高解像度・高フレームレートの動画作成

# 記事の概要

ComfyUIとSDXLモデル、AnimateDiffを使って高解像度(1000×1440)・高フレームレート(32)の動画を作成する手順を紹介します。
GeForce RTX 4090であれば、高解像度・高フレームレートのアニメーションを作成することができます。

https://x.com/jun_kongo/status/1804022813394944004

動画でも解説してます。

https://youtu.be/h47D0_9Vyic

環境
OS:Windows 11
GPU:GeForce RTX 4090
CPU:i9-13900KF
memory:64G
python:3.10.10
pytorch:2.0.1
CUDA:11.8
cuDNN:8.8

# 環境構築

ComfyUIのインストール手順については割愛します。
基本的にComfyUI Managerの「Update ALL」から、最新の状態にアップデートしてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619695/f0de0f94-a266-f25f-2d03-932c132510d1.png)

また、ComfyUI Managerから以下の「Custom Nodes」をインストールする。

・AnimateDiff
・AnimateDiff Evolved
・ComfyUI Frame Interpolation
・Deforum Nodes

「ComfyUI_windows_portable\ComfyUI\custom_nodes\ComfyUI-AnimateDiff-Evolved\models」フォルダに、以下のページからダウンロードしたMotion Module（mm_sdxl_v10_beta.ckpt）を配置する。

https://civitai.com/models/108836/animatediff-motion-modules

# ワークフロー

以下のワークフローで動画を生成する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619695/fff19eab-231f-45f4-baa1-b906242e323c.png)

ワークフロー用のjsonファイルは以下からダウンロードできます。

https://note.com/kongo_jun/n/n714ca99276e5

### Load Checkpoint

チェックポイントを指定するノードで、「sd_xl_base_1.0.safetensors」などのSDXLのモデルを指定する。
（今回はMeinaSDXLのdreamboothモデルを使用している。）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619695/e327055f-9392-2821-7bf7-26d3f6cbc820.png)


※dreamboothでの再学習手順

https://qiita.com/kongo-jun/items/b49424a88e8ef01351ed


### AnimateDiff Loader

model_name（motoin_module）:mm_sdxl_v10_beta.ckpt
beta_schedule:linear（AnimateDiff-SDXL）

![AnimateDiff_Loader.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619695/11c79134-5e6f-969c-3e61-7ee529617ebe.png)


### Ksampler

sampler_name:dpmpp_3m_sde_gpu
scheduler:karras

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619695/0bc2d6ef-cb2a-8ad7-1822-6560769ab1b5.png)


### Load VAE

vae_name:sdxl_vae.safetensors

https://huggingface.co/stabilityai/sdxl-vae/blob/main/sdxl_vae.safetensors

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619695/4f2d4f5e-dbf1-d5c3-ed59-48d896053573.png)


### (deforum) FILM Interpolation

以下の設定で、1フレームが4フレームに増加する。

inter_amount:2
skip_first:false
skip_last:false

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619695/db91fb37-9c34-13a8-7d3f-0d034476cd79.png)


以下の設定に変更すると、1フレームが3フレームに増加する。

inter_amount:3
skip_first:true
skip_last:true

![Deforum調整.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619695/faadd45a-1774-1a95-63b0-6bffd0ba7c2e.png)

### (deforum) Save Video

実際に動画を作成するためのノードではないが、このノードがないと想定通り出力ができないため、追加している。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619695/0cfb158d-7a93-260b-9bf9-f19b8dce2e55.png)

# 結果

今回の設定だと、だいたい20分から30分程度で１つの動画が出力可能。

### 24FPSの設定

https://x.com/jun_kongo/status/1804026467564896514

### 32FPSの設定

https://x.com/jun_kongo/status/1804022813394944004
MacBook 上の Livebook から Raspberry Pi 上の Livebook に接続してLチカする

## はじめに

以前、2台の MacBook 上の Livebook を接続しました

https://qiita.com/RyoWakabayashi/items/9def33deff5ec0f06412

本記事では MacBook 上の Livebook から Raspberry Pi 上の Livebook に接続します

## Raspberry Pi の環境構築

以下の記事の手順で Raspberry Pi 上に Nerves Livebook を立ち上げます 

https://qiita.com/RyoWakabayashi/items/8119260ceeea462d6b7b

ブラウザで `nerves.local` を開き、パスワード `nerves` で認証します

## MacBook の環境構築

以前の記事と同じ手順ですが、ノード名を IP アドレス付きで起動するようにします

### Livebook のコードをクローンする

最新版ではなく、安定稼動するリリース済のバージョンを使用します

```bash
git clone -b v0.12.1 https://github.com/livebook-dev/livebook.git
cd livebook
```

### 依存モジュールをインストールする

```bash
mix deps.get --only prod
```

### ノード名を IP アドレスとして起動する

```bash
LIVEBOOK_DISTRIBUTION=name \
  LIVEBOOK_NODE="livebook-server@<MacBookのIPアドレス>" \
  LIVEBOOK_IP=0.0.0.0 \
  MIX_ENV=prod mix phx.server
```

表示された URL をブラウザで開きます

## ノードの接続

### MacBook の接続情報を取得する

MacBook 側で新しいノートブックを開き、以下のコードを実行します

```elixir
{node(), Node.get_cookie()}
```

実行結果（例）

```elixir
{:"hb2dbpe2-livebook-server@192.168.40.97", :c_XpnMHCvYnb9NFe4XGWZi_fI_P5fpAgIn6lPuP7n_POU6QIJ2BQXp}
```

自分のノード名とクッキーが取得できました

### Raspberry Pi からの接続

Raspberry Pi 側で新しいノートブックを開き、以下のコードを実行します

:::note info
{node, coockie} に MacBook 側の接続情報を設定しています
:::

```elixir
{node, coockie} = {:"hb2dbpe2-livebook-server@192.168.40.97", :c_XpnMHCvYnb9NFe4XGWZi_fI_P5fpAgIn6lPuP7n_POU6QIJ2BQXp}

Node.set_cookie(node, coockie)

Node.connect(node)
```

うまく接続できれば結果として `true` が返ってきます

### MacBook から Raspberry Pi 上の処理を実行する

MacBook 側のノートブックで接続ノードを確認します

```elixir
Node.list(:connected)
```

実行結果として、以下のように MacBook のノードと Raspberry Pi のノードが取得できます

```elixir
[:"livebook-server@192.168.40.97", :"livebook@nerves-6b7e.local"]
```

Raspberry Pi のノード上で処理を実行します

```elixir
Node.spawn_link(:"livebook@nerves-6b7e.local", fn -> node() |> IO.puts() end)
```

実行結果として、確かに Raspberry Pi 側のノード名が表示されました

```elixir
livebook@nerves-6b7e.local
```

### MacBook から Raspberry Pi にLチカさせる

同じように、 MacBook 側のノートブックから Raspberry Pi 側の LED を制御できます

```elixir
Node.spawn_link(:"livebook@nerves-6b7e.local", fn ->
  :green # 色
  |> Delux.Effects.blink(3) # 周波数
  |> Delux.render()
end)
```

Nerves 側に渡した関数の中身は以下の記事と同じです

https://qiita.com/RyoWakabayashi/items/281afab89249dbf68cd5

## まとめ

MacBook 上の Livebook から Raspberry Pi 上の Livebook に接続し、Lチカさせることができました

実は、逆方向の Raspberry Pi から MacBook に処理を実行させる方はできていません

Nerves Livebook を IPアドレス付きノード名で起動できれば大丈夫だとは思うのですが
【React】useInViewとcss animateを使って、スクロールに連動して要素を出現させる方法

## 概要
本記事では、ReactのライブラリであるuseInViewとCSSのアニメーションライブラリであるanimate.cssを使用して、スクロールに連動して要素を出現させる方法を紹介します。

具体的には、画面をスクロールして特定の位置に到達した際、要素がアニメーションと共に表示される仕組みを実装します。

↓イメージ
![useInView CSSアニメーション.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817219/5871b817-de14-8756-7a90-f3a1a3f2881f.gif)


## 前提知識
* Reactの基本的な知識
* React Hooksの基本的な知識
* CSSの基本的な知識

## 背景
ウェブページを訪れるユーザーに対して、動きのあるインタラクティブな要素を提供することで、ユーザーエクスペリエンスを向上させることができます。

特に、スクロールに連動して要素がアニメーションと共に表示される効果は、視覚的な魅力を高め、ユーザーの注意を引くことができます。

本記事では、このような効果を簡単に実現する方法を説明します。

## 学んだ技術の説明
### 技術の概要
#### useInView
Reactでスクロールや要素の表示状態をトリガーにするためのフックです。
要素がビューポートに入ったかどうかを監視し、指定された条件に応じて処理を実行します。

#### animate.css
シンプルで使いやすいCSSアニメーションライブラリです。
多様なアニメーション効果を提供し、クラス名を追加するだけで簡単に使用できます。


### インストールと設定
まず、必要なライブラリをインストールします。

```bash
npm install animate.css react-intersection-observer
```

### 基本的な使い方
以下に、useInViewとanimate.cssを使用して要素がスクロールに連動してアニメーション表示される例を示します。

```jsx
"use client";

// animate.cssをインポート
import "animate.css";
// useInViewをインポート
import { useInView } from "react-intersection-observer";

const Home = () => {
  // useInViewを使ってrefとinViewを定義
  const { ref, inView } = useInView({
    //　ref要素（以下JSX内）が画面上に現れてから170px過ぎた時、inViewがtrueになる。
    rootMargin: "-170px",
    // 最初の一度だけ実行
    triggerOnce: true,
  });

  return (
    <>
      <div className=" my-[500px]">↓スクロールしてください。</div>
      <div className=" my-[500px]">↓スクロールしてください。</div>
      {/* ref要素 */}
      <div
        ref={ref}
        className={`bg-blue-500 w-56 h-28 ${
          // inViewがtrueになったら、CSSアニメーションを使用して要素を表示
          inView ? "animate__animated animate__rotateInUpLeft" : "opacity-0"
        }`}
      >
        対象の要素
      </div>
      <div className=" my-[1000px]" />
    </>
  );
};

export default Home;
```

## まとめ
useInViewとanimate.cssを組み合わせることで、スクロールに連動したアニメーションを簡単に実装することができます。

ユーザーエクスペリエンスを向上させるために、ぜひ試してみてください。

## 参考資料
https://ja.react.dev/reference/react

https://www.npmjs.com/package/react-intersection-observer

https://animate.style/
人生初AWS Summit行ってきたまとめ

# はじめに
2024年6月21日に幕張メッセで行われたAWS Summitに行ってきました！
AWS初心者情シスな私が、歴戦の猛者な上司のCTOに引き連れられておっかなびっくり参加したレポートになります。

# 結論から言うと...
#### マジで初心者ほど参加したほうがいい。
#### モチベ爆上がり&自分の興味あるジャンルの取り組みの話が聞けるのはプライスレス。
#### 名刺はたくさん持っていこう！（1敗）
#### 企業ブースの方もAWSブースのSAさんも優しいので気になったらガンガン聞いちゃいましょう！

# 実際どうだったの？
地元千葉勢だったので8時50分ごろに到着。
Xで色々な情報が飛び交う中、無事お弁当引換券とモーニングドリンク、そして基調講演の指定席をGET。（お弁当本当美味しかったです。）
「早く着きすぎたかな～」とか思っていたのですが田中さんのDJとテックカンファレンスの独特な雰囲気に完全に没入していました。

基調講演ではAdobeやJR、電通デジタルさんの実例も交えながら生成AIとどのように組み合わせてイノベーションが創出されているかにフォーカスして講演が進められていました。１ユーザー企業としては、電通デジタルさんの∞AIシリーズがめちゃくちゃ刺さってました。

# セッションよりブース巡り！
基調講演後、上司と合流してブース巡りをしていました。
オフラインイベント、どうせなら普段話せない人と話したい！
セッションは後で聞けばいっか！と完全に開き直って散策してました。

各企業の取り組みやAWSの機能について片っ端から面白くて新鮮でした。
AWS HEROの山口さんや普段からQiitaで記事を拝見させていただいているみのるんさん、JAWSの皆さんにお会いできたのが何より嬉しかったです！
普段オンラインで画面の向こう側にいる人と生で会ってお話するのって自分のモチベに直結するなと痛感しました。
Cloud QuestやConnectやLexなど、取り組みたいことが視界のどこかで常に特集されていてワクワクが止まりませんでした。

# AWS Summitを一日キメた結果(個人差があります)
・モチベーションが尋常じゃなく爆発する
・今までスタックしてた技術的問題点がすんなり理解できる
・実務する際に「Summitで教えてもらったアレじゃん」となる
・お土産でもらったクッションで腰が守られる
・とりあえずコード書いてAWSログインしてみようって気持ちになる。

AWSド素人かつ、ユーザー企業情シスな自分が参加しても最高にエンジョイ出来る素敵イベントでした！
いつかは出店側で出れるように、認定者ラウンジに入れるようにCloud Questポチポチ頑張りながら実務でもAWS取り組んでいきます！

![Image (2).jfif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3564568/c19295be-77b2-a7a8-7ecf-871c982d5e41.jpeg)
[備忘録]　読んだネットの記事 (FA業界) ver.7

# 備忘録

"クイックデータで測定機用のソフトウェアから直接操作できる回転テーブル"
https://monoist.itmedia.co.jp/mn/articles/2406/18/news104.html

[備忘録]
- 従来では独自のソフトウェアでプログラムを作成する必要があった
- MODUSプログラムに回転角度を指令することができる

"日立産業制御ソリューションズが工場完全自動化ソリューションの新ブランド発表"
https://monoist.itmedia.co.jp/mn/articles/2406/20/news105.html

[備忘録]
- OT（制御技術）と最新のデジタル技術を組み合わせて現場や工場管理などの情報をシームレスに繋げる
- 入荷から製造、検査、出荷までの一連の業務の自動化を支援
- 受注情報と在庫情報に応じた生産計画の最適化に対応

"024年の国内産業用3Dプリンタ出荷台数のうち1割以上が金属3Dプリンタに"
https://monoist.itmedia.co.jp/mn/articles/2406/20/news006.html

[備忘録]
- 樹脂を材料とする産業用3Dプリンタよりも成長率が大きくなると予測
- 日本で購入できる海外メーカーの金属3Dプリンタが近年増えている 
    - 材料交換が容易になったから
    - 周辺サービスの充実
    - 材料の種類の増加
    - ソフトウェア機能の拡充
macOSでファイルの拡張子を追加／変更しようとすると警告が出る

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90217/a5655aac-f0a1-9392-17d5-d203a7dfebfc.png)

```
名前の末尾に拡張子　".PNG" を追加してもよろしいですか？
変更してしまうと、書類が別のアプリケーションで開かれてしまうことがありません。
```

 Finder → 設定 → 拡張子を変更する前に警告を表示

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90217/4896059b-ada2-9c54-a438-61ee65479aec.png)
storybookを使ってhoverされた時のテスト作ってみた

# はじめに
初めまして！
エンジニアになって数年、今まで本を読むだけでしたが、もっとプライベートで楽しみながら成長したい！自分が学んだ足跡を残していきたい！と思い記事を書きました！
最終的には自在に開発できるようになりたいと思っています。:triumph:
いろいろな記事を参考にさせてもらっています。:bow_tone2:

**「いいね」か「ブックマーク」**
を頂けると僕のモチベーションアップになります！:thumbsup:
少しでも気に入っていただけたらよろしくお願いいたします！:thumbsup:

# 今回の目的
storybookでUIテストをしたかった中でhoverのようなイベントでスタイルが適用されているか？を確認したかったため

# バージョン
React:18
storybook: 8.1.10

# ボタンの作りについて
storybookのサンプルを使用しています！
CSSのhoverは使用していません。
onMouseOverとonMouseLeaveでHoverの挙動を監視しstateに結果を格納します。

```tsx
...
const [ isHover, setIsHover ] = useState(false)

<button
  type="button"
  className={['storybook-button', `storybook-button--${size}`, mode, isHover && 'storybook-button-hover'].join(' ')}
  data-testid='button'
  onMouseOver={()=>{setState(true)}}
  onMouseLeave={()=>{setState(false)}}
  {...props}
>
  {label}
  <style jsx>{`
    button {
      background-color: ${backgroundColor};
    }
  `}</style>
</button>
```

# テストはこちら
storiesファイルはこちらです。
userEvent.hoverでhover状態に変更し、toHaveClassで適用されているか確認しましょう。
```tsx
export const Primary: Story = {
  args: {
    primary: true,
    label: 'Button',
  },
  play: async ({ canvasElement }) => {
    const canvas = within(canvasElement);
    // hover時のテスト
    await userEvent.hover(canvas.getByTestId('button'));
    await expect(canvas.getByTestId('button')).toHaveClass('storybook-button-hover');
    // unhover時のテスト
    await userEvent.unhover(canvas.getByTestId('button'));
    await expect(canvas.getByTestId('button')).not.toHaveClass('storybook-button-hover');
  },
};
````

# 結果はこちら
![スクリーンショット 2024-06-22 17.20.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/943982/d655f68a-7ea8-0aad-c672-9394c5a4ab3b.png)

# 参考
expect

https://github.com/testing-library/jest-dom

userEvent

https://testing-library.com/docs/user-event/v13

# 最後に
閲覧いただきありがとうございました！
PostgreSQLでLAST_DAY関数を自作する

OracleにあるファンクションがPostgreSQLでは用意されていない場合があるので自作します。

# 自作したファンクション
```plsql
CREATE OR REPLACE FUNCTION LAST_DAY(DATE)
returns DATE as $$
BEGIN
return DATE(date_trunc('month',$1) + '1month' + '-1 Day');
END
$$ Language plpgsql;
```

1. date_trunc()で与えられた日付を月単位で切り捨てて月初を取得
2. 切り捨てて得た月初に1か月足す
3. 最後に1日分引き算する

例) 2024-06-22 → 2024-06-01 → 2024-07-01 → 2024-06-30
78wincom

78win com là nhà cái cá cược với khuyến mãi hấp dẫn hàng đầu trong thị trường game cá cược. 78win đang tổ chức nhiều ưu đãi như tặng 78k miễn phí cho người chơi mới. Truy cập ngay Link 78win đăng nhập để trải nghiệm dịch vụ cá cược #1 tại Việt Nam
Địa chỉ :273 Trần Quý, Phường 4, Quận 11, Thành phố Hồ Chí Minh
#78wincom, #78win,  #78win01, #78wincom, #78winsg, #78win78
My website: https://78wincom.me/
My social:
https://vimeo.com/78wincomm
https://www.tumblr.com/blog/78wincomm
https://gravatar.com/78wincomm
https://glose.com/u/78wincom
https://www.deviantart.com/78wincomm
Linux ディスク追加＋パーディション作成＋マウント

Linuxシステムに新しいディスクを追加し、パーティションを作成して、2つのマウントポイントにマウントする手順を以下に説明します。
### 準備
VM
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2531066/6a5bbccf-6213-81cf-4934-478cbf8ea2d5.png)

disk
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2531066/4d7dd7dc-1939-6a63-2bb8-4e06006ed669.png)

VMにdiskをアタッチする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2531066/2bba9073-41d7-bd72-1d9c-27a953f7c7a1.png)


### 手順


2. **ディスクのパーティション作成**
   `fdisk`コマンドを使用して、新しいディスクにパーティションを作成します。


1. **`fdisk`を起動**
   ```sh
   sudo fdisk /dev/sdc
   ```

2. **新しいパーティションを作成**
   - `n` コマンドで新しいパーティションを作成します。
   - `p` を選択してプライマリパーティションを作成します。
   - パーティション番号を指定します（デフォルトの1で良い場合はEnterを押します）。
   - 最初のセクターを指定します（デフォルトの2048で良い場合はEnterを押します）。
   - 最後のセクターをサイズ指定で入力します。例えば、`+128G` で128GiBを指定します。

3. **パーティションテーブルの変更を保存**
   - `w` コマンドで変更をディスクに書き込みます。

### コマンド例


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2531066/84257bac-a305-31c7-54c6-a3b147913970.png)


これで、ディスク `/dev/sdc` に512GiB，510GiBのサイズを持つ二つパーティションが作成されました。他のパーティションを作成したり、ファイルシステムを作成したりすることもできます。

3. **パーティションのフォーマット**
   作成したパーティションをフォーマットします。
   ```sh
   mkfs.xfs /dev/sdc1
   mkfs.xfs /dev/sdc2
   ```

4. **マウントポイントの作成**
   パーティションをマウントするためのディレクトリを作成します。
   ```sh
   mkdir  /mount01
   mkdir  /mount02
   ```

6. **自動マウントの設定**
   再起動後も自動でマウントするために、`/etc/fstab`ファイルを編集します。
   ```sh
   vi /etc/fstab
   ```

   `fstab`ファイルに以下の行を追加します：
   ```
   /dev/sdc1  /mount01  xfs  defaults  0  0
   /dev/sdc2  /mount02  xfs  defaults  0  0
   ```

7. **設定の確認**
   正しくマウントされているか確認します。
   ```sh
   sudo mount -a
   df -h
   ```

### 結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2531066/ac01f6d7-ca5c-1688-6845-3aa5020dfdbf.png)



この手順に従うことで、新しいディスクをシステムに追加し、パーティションを作成して、それぞれを異なるマウントポイントにマウントすることができます。
[Dify]CodeInterpreterでワークフローを組むときはプロンプトに気をつけよう



みなさんCodeInterpreterを使ってますか？
一度使ってみたのですが、なかなか最初うまくいかなかったのでそれに関してこの記事で残しておきます。
以下の記事をみて解決できたのでよかったら皆さんも読んでみてください。

https://note.com/jolly_dahlia842/n/n7013edccc753?sub_rt=share_h

## 全体像
今回作成したフローは以下です。
![スクリーンショット 2024-06-22 16.42.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376115/dd122b5f-a2fd-1c37-28e9-69c754476315.png)

かなり単純ですが、プロンプトに注意して下さい。

## 最初に使ったプロンプト

最初以下のようなプロンプトで実施していました。ざっくりいうとpythonコードだけ出して！ということです。
```
Please output the python code from the question.
Be sure to output only python code.
```

その結果は以下です。
![スクリーンショット 2024-06-22 16.45.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376115/7caf7009-34a8-b3d7-14e5-b3a48b1ae090.png)
pythonコードのみ出力しているのですが、コードプロック(````python ```)に囲まれていることが原因でエラーが出てしまっているのです
コードブロックがない状態で出力するようにしないといけないです。

## 最終的なプロンプト

以下のようにするとうまくいきました。コードブロックで囲むな！というだけです。

```　プロンプト
Please output the python code from the question.
Be sure to output only python code.
Do not enclose the output in code blocks.
```

結果はこう。
![スクリーンショット 2024-06-22 16.48.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376115/4adcbcf6-041b-c01b-b0ee-6e39a1351985.png)


## 最後に
ただ現状CodeInterpreterは使い物にならないなと思っています。
それはサンドボックス環境で使えるライブラリが少ないからです。
なんかおもしろい使い方あれば教えてください。

Xやってるので気になる方はフォローお願いします。

https://x.com/hudebakonosoto
__m256dをシリアライズする。(IntelのIntrinsic関数をRISC-Vにポートする)

__m256dをネットワーク転送するために、__m256dをシリアライズするコードを書いてみました。以下のコードはBing AIで生成したコードを参考に作りました。文章はAI生成ではありません。

```c
#include <immintrin.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>

// シリアライズ
void serialize(__m256d value, char* buffer) {
    _mm256_storeu_pd((double*)buffer, value);
}

// デシリアライズ
__m256d deserialize(const char* buffer) {
    return _mm256_loadu_pd((const double*)buffer);
}

int main() {
    // 例として__m256d型のデータを作成
    __m256d value = _mm256_set_pd(1.0, 2.0, 3.0, 4.0);
    char buffer[32];

    // シリアライズ
    serialize(value, buffer);

    // ここでネットワーク送信を行う（省略）

    // 受信後にデシリアライズ
    __m256d received_value = deserialize(buffer);

    // 結果を表示
    double* data = (double*)&received_value;
    printf("%f %f %f %f\n", data[0], data[1], data[2], data[3]);

    return 0;
}
```

以下のようにコンパイルして実行できます。

```
$gcc -mavx serialize.c
$./a.out
4.000000 3.000000 2.000000 1.000000
```

考えられる課題感としては、RISC-V側で`_mm256_storeu_pd`と`_mm256_loadu_pd`を使用することができないため、なにかの回避策を考える必要があります。
__m256d自体もRISC-V側でそのままでは使えないと考えられます。

そもそもこのテストフレームワーク自体が、`_mm256_add_pd `というIntelのIntrinsic関数のポートのテストであるため、ポートのテストのために、テストされてポートされた関数が必要ということになります。

まずは、`_mm256_storeu_pd`と`_mm256_loadu_pd`のポートが必要かもしれません。

以下のような関数で置換してやる方法もありますが、正確性の担保が課題になりそうです。これはBing AIで生成したものの一部ですが、型が微妙に違います。また、ターゲットとなるRISC-V CPUにおいて、`vse64_v_f64m2`と`vle64_v_f64m2`が使えるかということも問題になりそうです。RISC-VとIntelの型をまたがるキャストは準備されてないと考えられるため、そこも難しいです。
```c
void serialize(vfloat64m2_t value, double* buffer) {
    vse64_v_f64m2(buffer, value, 4);
}
```

```c
vfloat64m2_t deserialize(const double* buffer) {
    return vle64_v_f64m2(buffer, 4);
}
```

Intel系の型からRISC-V系の型に変えるには、ポインター参照キャストが必須のようです。
run npm devでlocalhostに接続できない【next.js / Mac】

# 状況
`npm run dev`で[localhost:3000](http://localhost:3000)に接続しようとしたら、
サーバーは立ち上がるのですが、以下の画面が出てアクセスできませんでした。
```zsh
# サーバーは立ち上がっているが...
$ npm run dev

> ga4-test@0.1.0 dev
> next dev

  ▲ Next.js 14.2.3
  - Local:        http://localhost:3000

 ✓ Starting...
 ✓ Ready in 3.6s
```
localhostにアクセスできない！！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1841759/1058c267-02fc-b752-71ab-023d91924b59.png)

# 開発環境
- MacOS 14.5 (Sonoma)
- Chromium(Chrome / Arc)
- nodejs 22.3.0
- npm 10.8.1
- next 14.2.4

# 解決方法
localhost:3000ではなく、[127.0.0.1:3000](http://127.0.0.1:3000)にアクセスすると、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1841759/0bc46380-3ba2-f57a-8126-f5c856c40afe.png)

無事に画面が表示されます...　なんでや！？

# 原因＆根本解決
原因は、Next(React)のホストが、`http`で開かれていたためでした。
Chromium系（Chrome / Arcなど）は`https`でないと受け付けないそうです。

そこで、`package.json`の`scripts`の`dev`部分を書き換えると、問題なく`https`で起動できるようになります。
~~デフォルトそれだろ！！~~
```json:package.json
{
  "name": "ga4-test",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "// ここに、 '--experimental-https'を付け足してください"
    "dev": "next dev --experimental-https",
    "build": "next build",
    "start": "next start",
    "lint": "next lint"
  },
}

```
この状態で`npm run dev`をすると...
```zsh
npm run dev

> ga4-test@0.1.0 dev
> next dev --experimental-https

 ⚠ Self-signed certificates are currently an experimental feature, use with caution.
   Attempting to generate self signed certificate. This may prompt for your password
   CA Root certificate created in /Users/kiichi/Library/Application Support/mkcert
   Certificates created in /Users/kiichi/workspace/sandbox/ga4-test/certificates
   Adding certificates to .gitignore
  ▲ Next.js 14.2.4
  - Local:        https://localhost:3000

 ✓ Starting...
 ✓ Ready in 2.4s
```
無事に`https`で立ち上がっているのが確認できます！

# 参考資料
railsの記事でしたが、以下を足がかりにしました。
「Next.js」で検索していると、一生見つけられなかったです...
少しでも僕と同じ魂が救われますように...🙏

https://ja.stackoverflow.com/questions/69888/127-0-0-13000%E3%81%A7%E3%81%AF%E3%83%9A%E3%83%BC%E3%82%B8%E3%81%8C%E8%A1%A8%E7%A4%BA%E3%81%95%E3%82%8C%E3%82%8B%E3%81%8C-localhost3000-%E3%81%A7%E8%A1%A8%E7%A4%BA%E3%81%95%E3%82%8C%E3%81%AA%E3%81%84

https://github.com/vercel/next.js/discussions/10935#discussioncomment-7859142

https://github.com/facebook/create-react-app/issues/467
Googleタグマネージャーがプレビューできない！😭

# 状況
Google Tag Managerでプレビュー接続をしようとしたら、
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1841759/1e18d806-6e26-ee7e-9abe-2fe858d93c16.png">

<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1841759/5c31ff61-a14b-47c0-48a7-9c790bef91b6.png">

**繋がらない！！！！！** 😭😭😭😭

# 解決方法
拡張機能のuBlockOriginが悪さをしていました。

https://chromewebstore.google.com/detail/ublock-origin/cjpalhdlnbpafiamejdnhcphjbkeiagm

[拡張機能の管理画面](chrome://extensions/)から、機能を一時的にOFFにしてしまいましょう！
その状態で、改めてリトライをすると、、、

<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1841759/77b199ea-873d-c4bf-f07b-6839b50faddd.png">

やったぜ！🎉🎉🎉🎉🎉

# 原因＆根本解決
HTMLに埋め込んでいるGTMのタグが広告ブロックの対象となっており、正常に読み取りができなくなっていました。
```HTML
<!-- Google Tag Manager -->
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-HOGEHOGE');</script>
<!-- End Google Tag Manager -->
```

このコードの、`www.googletagmanager.com`の部分がブロックされてしまっているので、拡張機能のホワイトリスト（AdBlockの対象外のエンドポイント）に追加してあげましょう！

[拡張機能の管理画面](chrome://extensions/) > 詳細 > 拡張機能のオプション > 信頼するサイト

に以下のような形でGTMのURLを追加して、`✅変更を適用`を押せばOKです！

<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1841759/ecf35d34-f34a-cde4-bb5e-9056471c6377.png">


# 終わりに
Next.jsのパッケージを使ってGTMを導入していたのもあって、原因特定に時間がかかりました💦
調べてもあまり出てこなかったので、皆さん簡単に突破しているのでしょうか...？

# 参考資料

https://stackoverflow.com/questions/64969248/preview-mode-on-google-tag-manager-does-not-work-for-me-timeout
Rust で HTML エスケープ

# はじめに

**HTML エスケープ**は、セキュリティ上の観点から重要な処理です。特に、ユーザーからの入力データを HTML として表示する場合には、不正なコードやスクリプトの埋め込みを防ぐために必要です。

この記事では、Rust を使用して文字列を HTML エスケープする方法について詳しく説明します。



# HTML エスケープとは何か？
HTML エスケープは、HTML として特殊な意味を持つ文字（**特殊文字**）を**エンティティ表現**に置き換えることです。

主な目的は、HTML 文書内で意図しないタグや属性が挿入されることを防ぎ、クロスサイトスクリプティング（XSS）攻撃などのセキュリティリスクを低減させることです。詳しくは以下を参照してください。

https://www.ipa.go.jp/security/vuln/websecurity/cross-site-scripting.html

例えば、以下の文字をエスケープする必要があります。

||エンティティ|エスケープする理由|
|:-|:-|:-|
|**`<`**|`&lt;`|HTML タグの開始記号として解釈されるため|
|**`>`**|`&gt;`|HTML タグの終了記号として解釈されるため|
|**`"`**|`&quot;`|HTML 属性値の引用符として解釈されるため|
|**`'`**|`&#39;`|HTML属性値のシングルクォートとして解釈されるため|
|**`&`**|`&amp;`|HTMLでの「&」をそのまま表示させたい場合|

:::note
**エンティティ表現**
エンティティ表現（Entity representation）は、特定の文字や記号を表現するための特殊な文字列のことです。主に HTML などマークアップ言語で使用されます。

具体的には、以下のようなものがあります。
- **文字実体参照**（Character Entity References）
特定の文字を表すために文字実体参照が使われます。例えば、`&lt;` は `<`を、`&amp;` は `&`を表します。
- **数値文字参照**（Numeric Character References）
文字の Unicode コードポイントを 10 進数または 16 進数で表現する方法です。例えば、`&#60;` や `&#x3C;` は、`<` を表します。
:::

# Rust での実装

`escape_html` は、与えられた文字列 text 中の特定の文字（&, <, >, ", '）を HTML エスケープされた文字列に置き換える関数です。
```rust
fn escape_html(text: &str) -> String {
    let mut escaped_text = String::new();

    for ch in text.chars() {
        match ch {
            '&' => escaped_text.push_str("&amp;"),
            '<' => escaped_text.push_str("&lt;"),
            '>' => escaped_text.push_str("&gt;"),
            '"' => escaped_text.push_str("&quot;"),
            '\'' => escaped_text.push_str("&#39;"),
            _ => escaped_text.push(ch),
        }
    }

    escaped_text
}


fn main() {
    // オリジナルの HTML コード
    let original_html = r#"<div>Hello & 'World'</div>"#;

    // HTML エスケープを行う
    let escaped_html = escape_html(original_html);

    // エスケープされた HTML を表示する
    // Escaped HTML: &lt;div&gt;Hello &amp; &#39;World&#39;&lt;/div&gt;
    println!("Escaped HTML: {}", escaped_html);
}
```
「報告したら仕事が減る」にしないと報告されなくなっていく

## はじめに

◆この記事は何？
自然に報告が増えるような考え方はプラクティスを紹介する記事

◆対象は？
リーダーや上司などの報告を求める立場の方々

◆この記事のねらい
「報告されなくなる」の予防

## 先に結論
- 「報告したら仕事が減る」にしないと報告されなくなっていく
- 報告するメンバーのメリットをつくる
- メンバーの仕事を減らすためには？を考える

## 「報告したくない」と思うとき

報告する立場のメンバー目線で考えます。

上司やリーダーに報告するのが嫌な理由の一つに、「報告したら仕事が増えてしまう」があります。

例えば、「改善点は〇〇です」と報告して、リーダーから「ではあなたがやっておいて」と言われると、報告する側は「仕事が増えた」と感じる場合があります。

[『ソフトウェアテストのセオリー』](https://amzn.asia/d/04PuuSSz)では次のように説明されています。

> 組織のあるメンバが開発途中でソフトウェアに関する事象を発見した際に、その原因分析や対応を、なし崩し的に発見者に担当させるような対策は決して行ってはいけません。

報告するメリットがない環境では、メンバーは次第に報告しなくなります。

報告されなくなると、リーダーは必要な情報を得られなくなります。

報告されなくなるのはチームとして避けるべき状況であり、リーダー自らが「報告しやすい文化」をつくっていく必要があります。

## 報告するメリットをつくる

「報告しやすい文化」を醸成するには、「**報告すると良いことがある**」と感じてもらえる場を構築していきます。

最初に考えるのは、「**どう仕事を減らせるか？**」です。

リーダーは、メンバーの障壁を取り除く役割でもあります。
そもそも「報告」は、ただ話を聞くだけでなく次のアクションのための活動です。リーダーは、メンバーの障壁がないかを考えて、必要であれば障壁を取り除いていきます。

例えば、メンバーから「〇〇の課題がある」と報告されたら、どうすれば課題を解消できるか？を考える必要があります。

仮に課題がない場合でも、障壁を探してメンバーの仕事を減らしていくと、次第に報告が増えていきます。

他には、報告の場を通して、メンバーが承認されたり、メンバーが成長したりするようにフィードバックしていくことで、報告するメリットを作っていくことが出来ます。

## おわりに

この記事では、メンバーがリーダーに報告しやすくなるような考え方を紹介しました。

他にも報告しやすくなる工夫があれば教えてください。

参考になれば幸いです。
N-進グレイコード

# これは何？

[英語版 Wikipedia](https://en.wikipedia.org/wiki/Gray_code) に N-進グレイコード (n-ary Gray code) の処理が書かれていたのでメモ.

# やりたいこと

通常の10進位取り記法だと 1999 の次は 2000 となり、4か所の数字が同時に書き換わる.
グレイコードは、絶対値が1しか違わない数値同士ならば1か所の数字しか書き換わらないような性質を持つ表現方法である.

# ソースコード

```C#:Sample.cs
int N = 4;
int L = 3;
int M = 20;// M < N^L
Console.WriteLine($"{N}進位取り記法 ; {N}進グレイコード ; グレイコードから位取り記法へ ... {L}桁");
for (int i = 0; i < M; ++i) {
  int[] nary = ToNAry(i, N);
  int[] gray = ToGray(i, N);
  int[] invt = InvertGray(gray, N);
  Console.WriteLine($"{string.Join(null, nary).PadLeft(L, '0')} ; {string.Join(null, gray).PadLeft(L, '0')} ; {string.Join(null, invt).PadLeft(L, '0')}");
}

// 安全のため、全体的に uint を使うか、先頭で値の検証を行うかをする方がよい
// 変数の命名について:
//   g: グレイコードのある桁の値 (Gray)
//   d: 位取り記法のある桁の値 (Digit)

// value を @base-進グレイコードへ変換する
static int[] ToGray(int value, int @base) {// value >= 0, @base > 1
  int[] nary = ToNAry(value, @base);
  int[] gray = new int[nary.Length];
  int shift = 0;
  for(int i = 0; i < gray.Length; ++i) { 
    int d = nary[i];
    int g = (d + shift) % @base;
    shift = shift + @base - g;
    gray[i] = g;
  }
  return gray.ToArray();
}

// value を @base-進位取り記法へ変換する
static int[] ToNAry(int value, int @base) {// value >= 0, @base > 1
  List<int> nary = new();
  while (value != 0) {
    nary.Add(value % @base);
    value = value / @base;
  }
  nary.Reverse();
  return nary.ToArray();
}

// gray を @base-進位取り記法へ変換する
static int[] InvertGray(int[] gray, int @base) {// @base > 1
  int[] nary = new int[gray.Length];
  int shift = 0;
  for(int i = 0; i < gray.Length; ++i) { 
    int g = gray[i];
    int d = Mod(g - shift, @base);// C# の % 演算子は左辺と同じ符号の値を返すため不適
    shift = shift + @base - g;
    nary[i] = d;
  }
  return nary.ToArray();
}

// 剰余演算(a % b)を行う(返り値は b と同符号)
static int Mod(int a, int b) {
  // -7 % 4 = -3
  // Mod(-7, 4) = 1
  int q = (int) Math.Floor((double) a / b);
  int r = a - q * b;
  return r;
}
```

```text:出力結果
4進位取り記法 ; 4進グレイコード ; グレイコードから位取り記法へ ... 3桁
000 ; 000 ; 000
001 ; 001 ; 001
002 ; 002 ; 002
003 ; 003 ; 003
010 ; 013 ; 010
011 ; 010 ; 011
012 ; 011 ; 012
013 ; 012 ; 013
020 ; 022 ; 020
021 ; 023 ; 021
022 ; 020 ; 022
023 ; 021 ; 023
030 ; 031 ; 030
031 ; 032 ; 031
032 ; 033 ; 032
033 ; 030 ; 033
100 ; 130 ; 100
101 ; 131 ; 101
102 ; 132 ; 102
103 ; 133 ; 103
```

中央の列がグレイコードだが、一度に一か所の数字しか書き換わっていないことが観察できる.
00x で一の位を 0-3 まで取り尽くした後、桁上がりして 01x となるが、十の位を書き換えることになるので一の位は 3 のままとなっている.
01x では一の位を 3, 0, 1, 2 の順に取り尽くし、また桁上がりする.
02x では一の位を 2, 3, 0, 1 の順に取り尽くし、また桁上がりする.
[Dify]webapp-conversationでUIをカスタマイズする

みなさんこんな便利なテンプレートがあるのはご存知ですか？

https://github.com/langgenius/webapp-conversation

これを使うことでDifyで公開しているアプリのUIをカスタマイズできます。
カスタマイズができると何がいいかというと
- 好みのUIを作成できる
- 認証をつけることができる
などなどです。

では使ってみましょう。
## テンプレートを用意

まず以下でテンプレートをクローンする
```
 git clone git@github.com:langgenius/webapp-conversation.git
```

次に.envを作成する。Difyで公開しているアプリのAPIのID、URL、APIKeyをここに入れる
 ```
 # APP ID
NEXT_PUBLIC_APP_ID=
# APP API key
NEXT_PUBLIC_APP_KEY=
# API url prefix
NEXT_PUBLIC_API_URL=

```


必要であれば`config/index.ts`も入力しておく。私はとりあえずlanguageを`en`にしておきます。

```
export const APP_INFO: AppInfo = {
  title: 'Chat APP',
  description: '',
  copyright: '',
  privacy_policy: '',
  default_language: 'en'
}

export const isShowPrompt = true
export const promptTemplate = ''
```

以下で依存インストールして

```
npm install
# or
yarn
# or
pnpm install
```

以下で起動しましょう。
```
npm run dev
# or
yarn dev
# or
pnpm dev
```

そうすると`http://localhost:3000/`で開けます。
![スクリーンショット 2024-06-22 16.23.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376115/c5a5ca20-137a-9f35-6ede-1cce6c76af7a.png)


## カスタマイズしてみる

たとえばこん感じで緑色にできたりします。
![スクリーンショット 2024-06-22 16.33.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376115/e1955cfa-2e16-ff70-b359-066d34ce447a.png)

他にも色々できますが、今回は特にやりません。みなさん一度カスタマイズしてみてください！

## （補足）dify-clientでAPI連携している

このテンプレートでDifyのAPIを実行するのに`dify-client`というライブラリをつかっています。
テンプレート使わずにdify-clientで全部やってしまった方が実は楽しいかもしれませんね


## 最後に

Xやってるので気になる方はフォローお願いします。
https://x.com/hudebakonosoto
【React】DOM参照と値の保持にuseRefを活用

# はじめに
useRefを使うことでDOM要素の参照、値の保持をする事ができます。
useStateでは値が更新されると再レンダリングがされますが、useRefは保持している値が更新されても再レンダリングのトリガーならない事が特徴です。
本記事では useRefを使用しDOM要素の参照とuseRefでの値の更新を行います。


# 環境
- React：18.3.1
- Vite：5.3.1


# ソース

次の例では `inputRef` で input要素の参照、`countRef` で数値を保持を行っています。
「フォーカスを当てる」ボタンがクリックされると input 要素で作成した入力欄にフォーカスが当たり、同時に `countRef` の値がインクリメントされます。

```tsx:App.tsx
import { useRef } from 'react';
import './App.css'

function App() {
   // DOMを参照するのに使用 
   const inputRef = useRef<HTMLInputElement>(null);
   // 値を保持するのに使用
   const countRef = useRef<number>(0);
 
   const handleClick = () => {
     // input 要素にフォーカスを当てる
     if(inputRef.current)
      inputRef.current.focus();
 
     // countRef の値をインクリメントする
     countRef.current++;
     console.log(`Clicked ${countRef.current} times`);
   };
 
   return (
     <>
      <h1>{countRef.current}</h1>
       <input type="text" ref={inputRef} />
       <button onClick={handleClick}>フォーカスを当てる</button>
     </>
   );
}

export default App;
```

<details><summary>App.css</summary>

```css:App.css
body {
  width: 100%;
  height: 100vh;
  padding: 0;
  margin: 0;
  display: flex;
  justify-content: center;
  align-items: center;
}
```

</details>



# 実行結果

次のコマンドで起動し実際にブラウザで確認してみます。

```
npm run dev
```

refを使用して、ボタンクリック時に入力欄（input）要素をフォーカス状態にできている。
また、コンソールログから`countRef` の値をインクリメントできている事も確認。
useStateだと値の更新をトリガーに再レンダリングされますが、useRefでは値が更新されても再レンダリングされていないことが確認できます。

![useRefsam.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1247619/b0651db0-53d4-a289-bc4c-fc5ad94dad9d.gif)




# 参考


https://ja.react.dev/reference/react/useRef

https://qiita.com/toproad/items/c7c78d1f04903d41203a
課題（022）ー２

お疲れ様です。

昨日の続きから課題の最後まで取り組み、提出をしてきました。
昨日躓いていた nth-of-type と first-letter の部分が解決したのでメモを残します:relaxed:

![スクリーンショット 2024-06-22 154144.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3810013/2ea580d2-fddb-4764-6023-4ec8fded7088.png)

質問コーナーにて同じ質問をされている方がいたので、その質問に対しての返答を見てきましたところ、**nth-of-type** ではなく **nth-child** でした！

**●nth-of-type()**
親要素の中にある、同じ要素の中（pなど）でn番目の要素にスタイルを適用する
()には、例えば2番目のpであった場合、 **p:nth-of-type** としたあとに2を入力
<br>
**●nth-child()**
親要素の中にある、特定の順番にある要素にスタイルを適用する
()には、例えばhtml内の親要素の3行目のpであった場合、 **p:nth-child** としたあとに3を入力
<br>
という違いがあるのを見落としていました:cold_sweat:
調べるのはいいと思うのですが、内容をちゃんと読んでから、先走らずちゃんと情報を選択しないといけませんでした…

![スクリーンショット 2024-06-22 154209.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3810013/47d3102e-74a9-138c-015b-c13c7629bfa8.png)
そしてコードを訂正し、無事見本通りに実装できました。

あとはメディアクエリで、ブレークポイントを指定し、縦並びにするようにすればokでしたので、
1時間以内でできました。

html、cssの課題はあと数個でしたので、残りも取り組んでいきます。
【資料】ドローン写真測量　参考資料


# ドローン自動航行アプリ概要
## 参考資料

https://note.com/r_itou/n/nce8dc84f8b84

https://note.com/r_itou/n/n3675af5db0df

https://www.chick-fun.jp/litchi/

https://school-drone.com/column/service/litchi/

https://note.com/iserec/n/n9df0a29442be

## Mission Planner
フライトプランを作成
https://note.com/r_itou/n/nce8dc84f8b84

### 動作環境
Windows

## Litchi for DJI Drones
DJI Air2sに対応

### 動作環境
Android:
iPhone:iOS 12.4以降

DJI Air2s 対応
DJI mini3 proは非対応(Beta版のLitchi pilotで対応)
Mavic3以降非対応

#### ライセンス
買い切り、有料

## Litchi Pilot
Litchi for DJI Droneの後継アプリ
DJI mini3pro, Mavic3E等に対応

## PIX Capture Pro
### 動作環境
Androidのみ

#### ライセンス
 https://support.pix4d.com/hc/en-us/articles/10507353973277
Pix4D Customer(Professional) というライセンスが必要
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3821353/a9a7c0e8-c6d6-b1cf-d2ba-dfb810ff41f8.png)
引数のファイルを結合する（バイナリで）

Python の練習

```python
#!/usr/bin/python3
import sys

if len(sys.argv) < 3:
    raise Exception("arguments too short")

# 最初の引数は自分自身なので削除
sys.argv.pop(0)

# 最後の引数は出力ファイル（残りは結合したいファイル）
writefile = sys.argv.pop(-1)

with open(writefile, "wb") as w:
    for arg in sys.argv:
        with open(arg, "rb") as r:
            w.write(r.read())
```
プロジェクトマネジメント関連情報まとめ

# はじめに
この記事では、プロジェクトマネジメントに関する情報をまとめています。
※今後も随時更新予定

# 橋本将功 「プロジェクトマネジメントの基本が全部わかる本 交渉・タスクマネジメント・計画立案から見積り・契約・要件定義・設計・テスト・保守改善まで」 翔泳社、2022

https://www.shoeisha.co.jp/book/detail/9784798177427

タイトルの通りプロジェクトマネジメントの基本を体系的に学ぶことができます。また、本の中でプロジェクトマネージャーの仕事は球拾いという趣旨の記載があり、そういうことを着実にやってくれるプロジェクトマネージャーがいるプロジェクトは進めやすく、よい結果が出せそうだと思いました。

# 橋本将功「プロジェクトマネジメントの本物の実力がつく本 組織力・コミュニケーション能力・リーダーシップ・キャリア構築力を全部鍛える」 翔泳社、2023

https://www.shoeisha.co.jp/book/detail/9784798180960

# 倉貫義人 「人が増えても速くならない」 技術評論社、2023

https://gihyo.jp/book/2023/978-4-297-13565-2

文量は多くないですが、ビジネス側と開発側の前提の違いに起因する課題やそれに対する対策を具体的かつ簡潔にまとめてくれています。

# Bent Flyvbjerg 著、Dan Gardner 著、櫻井祐子 訳「BIG THINGS　どデカいことを成し遂げたヤツらはなにをしたのか？」サンマーク出版、2024

https://www.sunmark.co.jp/detail.php?csid=4037-1

システム開発のプロジェクトに限らず、ビルの建設や映画の製作など多種多様なあらゆる規模のプロジェクトが失敗しがちな理由を説き明かしています。

_**Think Slow, Act Fast ...and Build!**_

# プロジェクトマネジメント協会（PMI）「プロジェクトマネジメント知識体系ガイド（PMBOKガイド）第7版＋プロジェクトマネジメント標準」一般社団法人 PMI日本支部、2021

https://www.pmi-japan.shop/shopdetail/000000000028/

# PMBOKとは？プロジェクト管理の基礎を学ぼう

https://www.linpress.co.jp/blog/c35

PMBOK の全体像がまとまっています。

# Management Debt

https://staysaasy.com/management/2023/01/12/management-debt.html?s=09

マネージメントの負債も技術的負債と同じく自然発生し、時間とともに増加するので、モニタリングやマネージメントが必要という内容が記載されています。

# 【初心者必見】プロジェクトマネジメントのコミュニケーション計画とは？ 会議体の種類とポイントを解説

https://oboegakit.blog/project_meeting_management/#google_vignette
全く世の中の役に立たないものを全力で作りたい

# はじめに
  - 何か、**全く世の中の役に立たないものを全力で**作りたい
  - 明確な目標がないと勉強する気やQiitaの記事を書く気が起きない…

…と思い、それならば以下のものを作ろうかと思い立ちました。

世の中の役に立たなくても、自分が満足できれば良い、がこの製作スタンスです。

# 作りたいもの
  - **自律走行**と**変形**が可能なルンバの**バーチャルウォール**（以下、VWと表記）
    - バーチャルウォールとは：https://store.irobot-jp.com/item/4491744.html

# 何でこんなもの作ろうと思った？
- ルンバ買ったけど**お掃除させるだけ**なのもなぁ
- ルンバを使ってなんか作りたいな（せっかく賢い900シリーズ買ったし）
- ルンバの掃除で通った**軌道の情報が頑張れば取得できる**らしいぞ 
  - https://github.com/koalazak/dorita980
    -（全然更新されてないけど…）
- そういえば付属してきたVWってルンバとどんな通信してるの？気になる…
- 頑張って**通信模擬できればVWは作れる**んじゃね？　
  - 作った人いた：https://github.com/MKme/Roomba
- 高速な足回りも搭載すれば軌道情報から**ルンバの行く先を先回りして通せんぼ**できるんじゃね？
- そんな感じのロボット作るか
- あと変形させたい（某UCの4枚羽根的な見た目に）　**変形はロマン**です

…こんな感じの思考プロセスで、製作を決定しました(笑)。

# 搭載機能
以下の機能を搭載したいと考えています。

- バーチャルウォール通信
  - ルンバのVWとしての機能を持つ
- 変形
  - ルンバ用VWの形から車高の低い二輪移動ロボットの形に変形
- 高速な足回り
  - マイクロマウスに以前使っていまは眠っているモータを有効活用
- 自己位置・姿勢推定
  - ジャイロセンサとエンコーダの値を使って自己位置・姿勢推定
- 速度・角速度制御
  - エンコーダとジャイロセンサの値を使って速度・角速度制御
- 障害物検知と回避
  - 赤外LEDと赤外フォトトランジスタによる検知と軌道生成による回避
- 障害物除去
  - 簡易ハンドによる障害物除去
- wifi通信
  - webアプリ経由での各種操作、ルンバとの連携
- 充電機能
  - LiPo電池の充電回路を搭載し本体から電池を外さずにオンマシンで充電

# メカハードざっくり仕様
メカハードのざっくり構想は以下の通りです。
- 本体サイズ
  - 公式のVWぐらいのサイズに収まればベスト
- 足回り
  - マウスの足回りを流用、MiniZのタイヤと自作シャフト、カグスベール
- 外装カバー
  - 新規設計、RCサーボとリンク機構で作成、カバー自体は樹脂3Dプリンタで製作
- VW通信塔
  - 新規設計、本体上部と前面に赤外LED、上部には逆円錐形状のミラーを付けて作成
- メインフレーム
  - 新規設計、おそらくアルミ製、金属3Dプリンタとか使ってみたい

# 電気ハードざっくり仕様
電気ハードのざっくり構想は以下の通りです。

- マイコン１
  - Wifi内蔵、マイコン間通信にSPI
  - デバッグ用にUARTも搭載がよい
  - ESP-WROOM-02あたり？
- マイコン２
  - 多ピン、多ペリフェラル、マイコン間通信にSPI
  - デバッグ用にUARTも搭載がよい
  - STM32あたり？
- DCモータ
  - マウスのモータを流用、Faulhaber 1717T006SR
  - PWM出力2ch＋GPIO出力2ch
- エンコーダ
  - マウスのモータ搭載エンコーダを流用、IE2-512
  - 専用I/Fのあるマイコンが良い
- モータードライバ
  - テキトーに選定、Allegro A3950あたり
- 角速度センサ
  - テキトーに選定、STMicro L3GD20Hなど良いかも？
  - I2C接続
- 障害物センサ
  - 赤外LED・フォトTrともTBD、シェル一体型
  - ADC最低4ch＋GPIO出力最低2ch
- ハンド用近接センサ
  - 赤外LED・受光素子が一体となったもの
  - GPIO出力だと嬉しい GPIO出力1ch
- VW通信塔
  - 赤外LED*2、フォトTrともTBD
  - GPIO入力1ch＋GPIO出力最低2ch
- 変形用RCサーボ
  - TBD、なるべく小型のもの
  - PWM出力5ch（左右の羽根の展開に2chずつ＋VW通信塔の昇降に1ch）
- ハンド用RCサーボ
  - TBD、なるべく小型のもの
  - PWM出力2ch（ハンドの前方展開に1ch＋ハンド開閉に1ch）
- バッテリー
  - LiPo、1セル3.7V*2~3セル、数百mAh、数十C放電ぐらいの
  - 電圧監視用ADC1ch、充電回路
- ブザー
  - 状態確認用、圧電ブザー
  - PWM出力1ch
- LED
  - 状態確認用、LED3~4個
  - GPIO出力3~4ch
- ボタン
  - モード設定用、プッシュボタン2個
  - GPIO入力2ch
- プリント基板
  - 新規設計、~1.6mm厚、2～4層ぐらいで
  - 製造は外注、部品のはんだ付けは自分で

# ソフト超ざっくり仕様
ソフトの超ざっくり構想は以下の通りです。超絶ざっくりです。

- 本体側
  - OS非搭載、使用言語はC、C++
  - 各種通信用のライブラリのみ利用（TCP/IP通信、赤外線通信など）
  - その他やその上位は自前実装（コマンド通信、ADC値取得、RCサーボ制御、ジャイロ値取得、DCモータ制御、VW通信、充電制御）
- サーバ・アプリ側
  - 使用言語はJavaScript、Python
  - dorita980（iRobotクラウドAPIを使用してWifi経由でルンバを直接制御）使用
  - その他は超絶未定
  - AWSも、使えたら使ってみる

# 使用するツール
以下のツールを使用する想定でいます。

- メカ・電気PCB設計
  - Fusion360
- ソフト設計・実装
  - Cursorエディタ＋Arduino IDE
- 各種設計データ、ソースコードの管理
  - Git、GitHub

# 設計・製作する人
- わたし

# さいごに
 以上のような、しょーもないものを今後全力で作っていこうと思います。

ちゃんとしたものが出来上がるのか、そもそも何年かかるのか全く分かりませんが、見守っていただければと思います。

これが完成したころには、iRobotさんがそのはるか上を行く製品を作って世に出してくれているかもしれませんね。

このQiitaで果たして需要があるのかも不明です。需要あるよ～というはいいねください。

最後まで読んで下さりありがとうございました。
Googlemap geocodingが動作しない

# はじめに
ポートフォリオ制作中です！
今回はデプロイ後のGoogleMapとGeocodingがうまく動作しなかったため

本番環境でも動作せず、開発環境でdb:seedし直すと開発環境でも動作しなくなってしまったため、解決方法をまとめておきます！

# エラー状況

本番環境でも、開発環境でも、rails db:seedすると下記のエラーが出るようになった

```
$ rails db:seed
Google API error: request denied (API keys with referer restrictions cannot be used with this API.).
```
また、Googlemapは表示されるが、緯度経度が正しくないため変な場所にピンが刺さっている（Google Mapが表示されない問題もありましたが、本番環境ウェブサイトのURLを許可してないだけだった）

# 原因
このエラーはコードの問題ではなく、APIの制限設定によるものです

https://developers.google.com/maps/faq?hl=ja#browser-keys-blocked-error

上記の公式ドキュメントに記載されているように、Geocoding APIのキーの制限方法をHTTPリファラーにしていると先ほどのエラーが起きるようです！そのため、キーの制限方法をIPアドレスに切り替えることで解決できそうです

# 解決方法

https://console.cloud.google.com/billing/01341A-192333-0D62D1

上記のリンクに飛び、左上のハンバーガーメニューから「APIとサービス」を選択します

次に「認証情報」をクリックし、APIキーの一覧が出てくるため、該当のAPIを選択します

ここで制限設定をウェブサイトにしていたのがエラー原因でした
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3782860/c41415fd-c07b-7203-753a-cbbbbcae276d.png">

IPアドレスを選択し、+ボタンのADDからIPアドレスを追加しましょう
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3782860/20c5a44a-caff-d889-5929-878d1dcc5310.png">


:::note warn
注意⚠️
ここに追加するIPアドレスは、本番環境、開発環境二つのIPアドレスを入れます
どちらか一方しか入れない場合はどちらか一方しか適用されません
:::

# さいごに
Geocoding APIやPlaces APIのようなウェブサービス APIに対しては、
「HTTP リファラー」でのアプリケーションの制限ができないとのことです！
Maps JavaScript APIは「HTTP リファラー」で問題ないため開発環境と本番環境のURLを指定しています！

# 参照記事
https://developers.google.com/maps/faq?hl=ja#browser-keys-blocked-error

https://redretriever.github.io/gcp-api-key-use-http-referer-trouble/
AWSアーキテクチャー図作成おすすめサイト



## AWSアーキテクチャー図作成おすすめ❕
https://miro.com/ja/templates/aws-architecture-diagram/

https://app.diagrams.net/

https://www.microsoft.com/ja-jp/microsoft-365/visio/flowchart-software



## AWSを利用したシステム構築の要件定義、基本設計、詳細設計 :beginner:
AWS（Amazon Web Services）を利用したシステム構築においては、要件定義、基本設計、詳細設計の各フェーズでさまざまな要素を考慮する必要があります。この記事では、コスト、信頼性、セキュリティ、運用自動化、パフォーマンスに重点を置きながら、それぞれのフェーズでの考慮事項について解説します。

### 【要件定義】
#### コスト
予算設定: 初期投資および運用コストの予算を設定し、各サービスのコストを把握します。
コスト最適化: 必要なリソースの選定を行い、予算内で最大のパフォーマンスを発揮するよう設計します。リザーブドインスタンスやスポットインスタンスの利用も検討します。
#### 信頼性
可用性: サービスの可用性要件を定義し、冗長構成やフェイルオーバー機能を組み込む計画を立てます。
バックアップ: データのバックアップ戦略を策定し、定期的なバックアップとリストアテストの計画を立てます。
#### セキュリティ
アクセス制御: 誰が何にアクセスできるかを定義し、必要な権限管理のポリシーを設定します。
データ保護: データの暗号化要件を定義し、保存データと転送データの両方を保護します。
#### 運用自動化
自動化ツールの選定: Infrastructure as Code（IaC）ツール（例：Terraform、CloudFormation）の利用を検討します。
運用フローの自動化: インスタンスの起動/停止、スケーリング、モニタリングの自動化を計画します。
#### パフォーマンス
パフォーマンス要件: 必要なレスポンスタイム、スループット、遅延を定義します。
リソース最適化: 適切なインスタンスタイプ、ストレージタイプ、ネットワーク設定を選定します。
### 【基本設計】
#### コスト
サービス選定: 使用するAWSサービス（例：EC2、RDS、S3、Lambda）を選定し、各サービスのコストを見積もります。
コスト管理ツール: AWS Cost ExplorerやAWS Budgetsを利用し、コスト管理とモニタリングを行います。
####  信頼性
アーキテクチャ設計: マルチAZ配置、リージョン間レプリケーションなどを利用した高可用性アーキテクチャを設計します。
障害対応計画: 障害発生時の対応手順を策定し、ディザスタリカバリ計画を立てます。
#### セキュリティ
ネットワーク設計: VPC、サブネット、セキュリティグループ、ネットワークACLを設計し、安全なネットワーク構成を確立します。
IAMポリシー: IAMポリシーを設計し、最小権限の原則に基づくアクセス制御を実装します。
#### 運用自動化
デプロイメントパイプライン: CI/CDパイプラインを設計し、コードの自動デプロイメントとテストを行います。
モニタリングとアラート: CloudWatchを利用してシステムの監視とアラート設定を行います。
#### パフォーマンス
キャッシュの導入: CloudFront、ElastiCacheなどを利用してパフォーマンスを向上させます。
スケーリング戦略: オートスケーリングを設定し、トラフィックに応じた動的なリソース管理を行います。
### 【詳細設計】
#### コスト
具体的なリソース設定: 各リソースの具体的な設定（例：EC2インスタンスのタイプ、RDSのストレージタイプ）を詳細に定義します。
コストアラート設定: 特定のコストを超えた場合にアラートを発する設定を行います。
#### 信頼性
詳細な冗長構成: 各コンポーネントの冗長構成を詳細に設計し、障害発生時のフェイルオーバー手順を定義します。
バックアップとリストア手順: バックアップの取得方法とリストア手順を詳細に記述します。
#### セキュリティ
詳細なアクセス制御設定: 各IAMユーザーやロールに対するポリシーを詳細に定義し、アクセス制御を強化します。
セキュリティログの設定: CloudTrailを利用して、すべてのAPIコールを記録し、監査ログを管理します。
#### 運用自動化
スクリプトとテンプレート: IaCテンプレートや運用スクリプトを作成し、リソースのプロビジョニングと管理を自動化します。
自動化ワークフロー: AWS Step FunctionsやAWS Lambdaを利用して、運用フローの自動化ワークフローを設計します。
#### パフォーマンス
詳細なチューニング設定: 各リソースのパフォーマンスチューニング設定を詳細に記述します。
パフォーマンステスト: 負荷テストやパフォーマンステストを実施し、システムのパフォーマンスを検証します。
まとめ
AWSを利用したシステム構築においては、要件定義、基本設計、詳細設計の各フェーズでコスト、信頼性、セキュリティ、運用自動化、パフォーマンスの観点から慎重に計画を立てることが重要です。各フェーズで適切な設計と実装を行うことで、効率的かつ安全なシステム運用が可能となります。このガイドを参考に、AWSでのシステム設計と構築を進めてください。

最後に
何か間違いがございましたらご指摘お願いいたします。閲覧いただきありがとうございました。
OpenWrt上のksmbdで発生したトラブルと解決方法(ガバガバ解説)

# 発生した問題
- ①ksmbdをインストールした後、システムログに
`daemon.err ksmbd: modprobe of ksmbd module failed, can\'t start ksmbd!`
と表示されてksmbdが動作しない
- ②絵文字などを含むファイル/フォルダ名を開くとシステムログに
`ksmbd: next response offset exceeds response buffer size`と表示される
その後タイムアウトするか、非常に長い時間がかかってから表示される
- (初心者向け/備忘録)ユーザーの追加の仕方

# 解決方法
## ①ksmbdが動作しない
1. `modprobe -v ksmbd`を実行する
1. このときksmbdが無いよ！みたいなエラーが出た場合はパッケージが正しくインストールされていることを確認する
1. きちんとインストールされていることが確認できたら`depmod`を実行する
1. もう一度`modprobe -v ksmbd`を実行するとちゃんと認識される
:::note info
あんまり良くわかりませんがカーネル関連のパッケージの情報の整合性が取れてない場合にこうなるみたいです。
:::

## ②タイムアウトしたり、長い時間がかかって表示される
1. ksmbdのコンフィグにある
    ```
    	smb2 max read = 64K
    	smb2 max write = 64K
    	smb2 max trans = 64K
    	cache read buffers = no
    	cache trans buffers = no
    ```
    を全てコメントアウトするか削除するか`smb2 max ~~`を1024Kなどに増やすと治る。
    luciはこの箇所で編集できる。なぜ治るかは分からん。多分バッファが足りてないだけだと思う。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3314743/525c9f4d-cce6-73c4-8c9c-94f0d639c507.png)

## ③ユーザーの追加
1. `ksmbd.adduser -a -p <パスワード> <ユーザー名>`で追加
1. `ksmbd.adduser -u -p <パスワード> <ユーザー名>`で更新
1. `ksmbd.adduser -d <ユーザー名>`で削除
強制ルートなら別途Linuxユーザーを作らなくても大丈夫っぽい。
ちゃんとユーザーごとに管理したい場合は併せてLinuxユーザーを作る必要あり。
イベントループについて

以下ブラウザでの話になります。

## イベントループ
時間のかかる処理があっても、ブラウザの描画などほかの処理を止めないためにある機能。

### イベントループがないと
もしイベントループがないと、時間のかかる処理をする際に、全く他のことができなくなる。
画面上のボタンが押せなくなる等の支障が出る。

``` js
console.log("start");
setTimeout(function () {console.log("slow")}, 500);
console.log("end");
```

上記のコードをブラウザで実行すると
1. start
1. end
1. (0.5秒の遅延後)slow

の順番で表示される。

イベントループがないと
1. start
1. (0.5秒の遅延後)slow
1. end

の順番で表示される。

### イベントループとは
時間のかかる処理で止まらないためにイベントループがある。
イベントループとは、JavaScriptエンジン内のスタックが空になった際、タスクキューにある先頭のコールバック関数をスタック内に入れる処理をする。

#### ブラウザの機能
JavaScriptに関係のあるブラウザの機能
- JavaScriptエンジン
- web apis
- タスクキュー

の3つがある。

JavaScriptエンジンは、JavaScriptを解析実行する場所で、エンジン内にはスタックがある。
web apisはsettimeoutなどの処理を行う場所。
タスクキューはweb apisのコールバック関数が入る場所。

#### イベントループの流れ
1. コードが読み込まれ、処理の時間がかからないものはスタックに積み上げられ、実行
1. settimeoutなどの処理はweb apisに投げられて、そこで5秒待機などの処理をする
1. web apisでの処理が終了したら、コールバック関数がタスクキューに入れられる
1. もし、スタックが空の場合は、タスクキュー内の先頭の関数がスタックに格納される
アワードに載るようなサイトの右下あたりにあるアレをsvg単体で作る

## この記事の概要

こんな感じで、ファーストビューの右下あたりでくるくるしてる要素、たまに見ますよね。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/5b579af7-4908-9ce2-ff07-43e70dfaab77.gif)

最近は見る機会も減ってきているので今更感があるし、CSS を使えば全然簡単にできますが、これをあえて svg だけで作ってみました。

自分の修行の一環を公開するような記事です。

## 作り方

### 下準備

まずは動かしたい svg を作ります。
文字部分はまとめて動かすのでグルーピングしておきます。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/9a9a4967-602f-7704-2738-36cbf95c656c.png)

現時点のコードはこのようになっています。

```diff_xml
  <svg width="144" height="144" viewBox="0 0 144 144" xmlns="http://www.w3.org/2000/svg">
    <!-- 矢印部分 -->
    <path d="..." />
    <!-- 文字部分 -->
    <g>
      <path d="..." />
      <path d="..." />
      <path d="..." />
      <!-- 詳細なパスの記述 -->
    </g>
  </svg>
```

### `animateTransform`の使用

svg でコード内の要素をアニメーションさせるときの 1 つのやり方として`animateTransform`[^animateTransform]の使用があります。

[^animateTransform]: https://developer.mozilla.org/en-US/docs/Web/SVG/Element/animateTransform

今回でいうと、次のような記述をします。

- アニメーションさせる対象は何か
    - `<g>`でくくったパス
    - 後で id を指定する
- アニメーションのタイプは何か
    - 回転
- 回転の基準点はどこか
    - 中心
    - 144 x 144 のサイズなので、実際の座標は`72, 72`
- 何秒かけてアニメーションをするか
    - 20 秒
- アニメーションのリピート回数は何回か
    - 無限

これをコードに適用します

```diff_xml
  <svg width="144" height="144" viewBox="0 0 144 144" xmlns="http://www.w3.org/2000/svg">
    <!-- 矢印部分 -->
    <path d="..." />
    <!-- 文字部分 -->
    <g
+     id="rotating-group"
    >
      <path d="..." />
      <path d="..." />
      <path d="..." />
      <!-- 詳細なパスの記述 -->
    </g>
+   <animateTransform
+     xlink:href="#rotating-group"
+     attributeName="transform"
+     attributeType="XML"
+     type="rotate"
+     from="0 72 72"
+     to="360 72 72"
+     dur="20s"
+     repeatCount="indefinite"
+   />
  </svg>
```

これで、CSS を 1 行も書かずにアニメーションさせられました。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/67f0a1e3-8a8e-ce68-f23f-987f67ff2b5c.gif)

それ以外の部分のコードをちょろちょろっと書けば、冒頭に載せたような見た目となります。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/5b579af7-4908-9ce2-ff07-43e70dfaab77.gif)
【JavaScript】画像などのファイルをCtrl+Vで貼り付けたり、ドラッグ&ドロップで貼り付けたりする方法

## 結論

* MIMEタイプは画像で絞っているため、カスタムしたい場合は変えてください。
* ファイルが複数渡されたときはMIMEタイプが一致した最初のファイルのみを対象にしているため、複数処理したい場合は書き換えてください。
* ドロップ先のDOMは各自書き換えてください。今は画面のどこでもドロップ可能になっています。

```js
(() => {
    let isLoading = false;

    window.addEventListener("paste", e => {
        e.preventDefault();

        if (isLoading) {
            return;
        }
        isLoading = true;
        
        let imageItem = null;
        for (const item of e.clipboardData.items) {
            // MINEタイプの確認
            if (item.type.startsWith("image/")) {
                imageItem = item;
                break;
            }
        }
        if (imageItem === null) {
            isLoading = false;
            return;
        }

        const imageFile = imageItem.getAsFile();
        const url = URL.createObjectURL(imageFile);
        const image = new Image();
        image.onload = () => {
            // 画像の読み込み完了
            // TODO：あなたがimageを使ってやりたい処理を書く
            URL.revokeObjectURL(url);
            isLoading = false;
        };
        image.onerror = () => {
            // 画像の読み込み失敗
            URL.revokeObjectURL(url);
            isLoading = false;
        };
        image.src = url;
    }, false);

    window.addEventListener("dragover", e => {
        e.preventDefault();
    }, false);

    window.addEventListener("drop", e => {
        e.preventDefault();

        if (isLoading) {
            return;
        }
        isLoading = true;

        let imageFile = null;
        for (const file of e.dataTransfer.files) {
            // MINEタイプの確認
            if (file.type.startsWith("image/")) {
                imageFile = file;
                break;
            }
        }
        if (imageFile === null) {
            isLoading = false;
            return;
        }

        const reader = new FileReader();
        reader.onload = e => {
            const image = new Image();
            image.onload = () => {
                // 画像の読み込み完了
                // TODO：あなたがimageを使ってやりたい処理を書く
                isLoading = false;
            };
            image.onerror = () => {
                // 画像の読み込み失敗
                image = null;
                isLoading = false;
            };
            image.src = e.target.result;
        }
        reader.onerror = () => {
            // 画像の読み込み失敗
            isLoading = false;
        };
        reader.readAsDataURL(imageFile);
    });
})();
```