OmniAICreator/Qiita-1.07M huggingface dataset:
TabulatorのtickCrossにeditorを指定しない

<!--
title: TabulatorのtickCrossにeditorを指定しない
tags: Javascript Tabulator
author: shimizu@ferix.jp
-->

## 要約

- Tabulatorで編集可能なtickCrossを使用する際には、editorプロパティを設定しない

## Tabulator公式サンプル

[Editing Data \| Tabulator](https://tabulator.info/docs/6.3/edit)
上記の公式サイトの記述に合わせて、`formatter:"tickCross"`のColumsに`edtor:true`を設定すると、クリック時に表示が崩れます。

```ts:bad sample
    {
      title: "Approved",
      field: "approved",
      hozAlign: "center",
      formatter: "tickCross",
      width: 150,
      editor: true,
      formatterParams: {
        tickElement:
          '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" class="lucide lucide-circle-check"><circle cx="12" cy="12" r="10"/><path d="m9 12 2 2 4-4"/></svg>',
        crossElement:
          '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" class="lucide lucide-circle"><circle cx="12" cy="12" r="10"/></svg>',
      },
    },
```
![tickCross_bad_sample.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601565/cde79e86-bbce-484b-8014-b49d0b5a15b2.gif)

formatterParamsを使用していない公式サンプルでも再現しています。

## 解決方法

edtorプロパティを設定せず、cellClickで切り替えます。

```diff_typescript:good sample
    {
      title: "Approved",
      field: "approved",
      hozAlign: "center",
      formatter: "tickCross",
      width: 150,
-      editor: true,
+      cellClick: (e, cell) => {
+        const newValue = !cell.getValue();
+        cell.setValue(newValue, true);
+      },
      formatterParams: {
        tickElement:
          '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" class="lucide lucide-circle-check"><circle cx="12" cy="12" r="10"/><path d="m9 12 2 2 4-4"/></svg>',
        crossElement:
          '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" class="lucide lucide-circle"><circle cx="12" cy="12" r="10"/></svg>',
      },
    },
```
![tickCross_good_sample.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601565/38adc7be-3633-4cfd-af98-89db0a7b5b04.gif)


公式issueでも推奨されているアプローチです。
[tickCross editing · Issue \#341 · olifolkerd/tabulator](https://github.com/olifolkerd/tabulator/issues/341#issuecomment-306411613)

> I would recommend that you don't use an editor but instead use the _cellClick_ function and the _getValue_ and _setValue_ functions on the cell component:
Amazon Q CLIで猫の品種当てクイズゲームを作ってみた

「Amazon Q CLI でゲームを作ろう Tシャツキャンペーン」というのを社内Slackで案内されていたので、実際に作ってみました！

https://aws.amazon.com/jp/blogs/news/build-games-with-amazon-q-cli-and-score-a-t-shirt/

Amazon Q CLIは初めて触るのですが、導入もすごく簡単でした。

導入の仕方は上記のキャンペーンページにリンクがあります。
私はWSL経由で導入しました。

# クイズゲームの要件を考える

まずはどういうゲームを作りたいのか自分で考えることにしました。
下記のような案が浮かびましたが1と3は素材を集めたり作るのが大変そうなので、2を選択しました。
1. 動物シルエットクイズ
1. 猫の品種当てクイズ
1. 湖の名称クイズ

# Amazon Q CLIを操作する

まずは、Q chatを起動し、「Webアプリで猫の品種を当てるクイズゲーム（選択式４つ）を作ってください」と命令しました。
![スクリーンショット 2025-06-04 174702.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159670/4e1c9174-1559-4f00-8544-979cce9ab861.png)

ここからソースコードを生成して、編集の許可を聞いてきますが、基本はすべてYesで通しています。

しばらくすると、一通り動くものが完成しました！が猫の画像は作ってくれないので、自力でフリーの素材を見つけて入れました。
以下の動画はプロンプトを追加して直した部分があり、完成版のものになります。
![cat-breed-quiz-start.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159670/a993c78e-0f4d-4899-a9c8-9efdaa2ca2e8.gif)

![cat-breed-quiz-middle.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159670/dddea8a5-6ee9-47c4-a6df-f7179a7bfef0.gif)

![cat-breed-quiz-end.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159670/b0d62a54-9327-42ad-ae15-cd765a09c276.gif)

## 追加プロンプトについて

追加で指示した内容は以下になります
1. 今、何問目かを表示して。全何問あるかも表示して
1. ゲームが終了したあと、再度ゲームを開始したい。再挑戦のボタンをつけて

これでゲームがやりやすくなってストレスもなくなりました。

# 感想

改めてAmazon Q CLIを使ってみて、一から自分で書く必要はないのではと感じました。
不具合っぽいものもなく実装できているので、本当にすごい！
あとQ CLIとのチャット時間よりも、素材探し、素材DL、ファイル配置するという行動に時間がかかりました（笑）

今回作ったものは、Githubにアップしていますので、よろしければご確認ください。

https://github.com/septum128/cat-breed-quiz
[Linux][command] シェル変数と環境変数_エイリアス_alias, unalias

# aliasコマンド

```terminal
$ alias [エイリアス名='コマンド']
$ alias [引数なし]
```

| オプション             | 由来        | 説明                                                           |
| :---------------- | :-------- | :----------------------------------------------------------- |
| default           | alias | - コマンドに別名（エイリアス）をつける<br>- 引数なしで実行すると、設定済みのエイリアス一覧を表示                |
| | | 例: `alias ll='ls -l'`<br>- `ll` と入力すれば `ls -l` が実行されるようになる |


# unaliasコマンド

```terminal
$ unalias [エイリアス名]
$ unalias -a
```

| オプション      | 由来      | 説明                                                                             |
| :--------- | :------ | :----------------------------------------------------------------------------- |
| default | unalias | - 指定したエイリアスを削除する<br>- `alias` で設定した別名を解除する                                     |
|||例: `unalias ll`<br>- `ll` というエイリアスを削除する<br>|
| `-a`       | all     | - 設定されているすべてのエイリアスを削除する                                                        |
|            |         | 例: `unalias -a`<br>- すべてのエイリアスを削除する |



# Ping-t
- [5041_alias](https://mondai.ping-t.com/question_subjects/32/question_sessions/33449680/progressing_questions/512330522?result=true)
- [4754_unalias](https://mondai.ping-t.com/question_subjects/32/question_sessions/33449680/progressing_questions/512330526?result=true)
article-githubcopilot


# はじめに

昨今は、Cursor や Cline、Github Copilot など複数の AI コーディングエージェントが登場しており、それらを活用して爆速でアプリを開発できる時代が来ています。
しかしながら、私はまだそれらのツールをしっかり使ったことがありませんでした。（さすがに危機感）
そこでこの記事では、筆者が初めて Github Coplot を使ってみた所感をまとめます。

# 導入方法

[VS Code で GitHub Copilot 無料版の導入　備忘録](https://zenn.dev/yuta_haruna/articles/fb809e68e6bae5)を参考に、VS Code で GitHub Copilot Free を導入しました。

# Github Copilot Chat について

私のイメージでは、Copilot はガシガシコード補完を行なって開発を進めていくイメージだったのですが、この Copilot Chat で対話をしながら開発を進めるのがいいようです。

GitHub Copilot の 3 つのモード（Ask, Edit, Agent）があり、以下のように使い分けることができます。

- **Ask**: 質問をして、回答を得るモード。簡単な質問をするのに適しています。
- **Edit**: コードの修正を依頼するモード。プロジェクト内の編集したいファイルに対して編集内容を指示することで、コードの修正を行います。
- **Agent**: コードの実行を依頼するモード。Copilot が自律的に手順を生成し、コマンドを実行したりファイルを編集したりします。

今回は一番サポートが手厚そうな Agent モードを使いながら、実際にアプリを作ってみたいと思います。

# 使ってみた

## 作成するアプリについて

まずは今回作りたいアプリの要件を簡単に考えます。事前に Gemini の API を使ったアプリを使いたいと思っていたので、要件も含めて以下のようなプロンプトとしました。

```
以下のサイトの情報を参考にGEMINIを使った料理の献立提案アプリを作りたい。

以下はgeminiのAPIの利用方法の参考にね
https://qiita.com/zukki2/items/10bfeb1c4330aa18ff87

要件
・Webアプリ
・トップページには今日の気分を入力するテキストボックスと送信ボタン
・送信すると、気分に合わせたおすすめの献立を提案する
・推薦する献立の候補は事前にファイルで保存した情報とネット上の情報を組み合わせる
・献立は高タンパク低脂質が基本
```

![スクリーンショット 2025-06-04 17.58.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1665105/bca0d70a-98f0-4228-8770-37a5fcf86b00.png)

![スクリーンショット 2025-06-04 18.00.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1665105/4402a189-939f-4a90-8325-e3bc5da2ca9f.png)

### まとめ
【Tips】SAP Fiori（SAPUI5）のInputを検索ヘルプのみ使用可（手入力不可）にしたい

# 概要・課題
受託開発企業で働く@fussasyです。SAPUI5で実装をする際、Inputには検索ヘルプが設定されていることが多いと思います。
イメージ（Sample: Input - Assisted）：

https://sapui5.hana.ondemand.com/#/entity/sap.m.Input/sample/sap.m.sample.InputAssisted/

通常、Inputは手入力が可能な状態ですが、機能要件の中には手入力不可として欲しいという要望があるとします。このとき、Combo boxを利用するという方法もありますが、一般的には**推奨されるリスト値は200以下**とされるため、利用がNGとなる場合があります。
イメージ（Sample: Combo box）：

https://sapui5.hana.ondemand.com/#/entity/sap.m.ComboBox/sample/sap.m.sample.ComboBox

Inputを検索ヘルプのみ使用可（手入力不可）するためのTipsです。

# 解決策
view.xmlのInputのプロパティに以下を追加する。
>valueHelpOnly="true"

実際にコードに追加して試してみましょう！

https://sapui5.hana.ondemand.com/#/entity/sap.m.Input/sample/sap.m.sample.InputAssisted/code

以下、元の状態です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1727556/530272d7-d08f-4eb2-822a-df51180c53ab.png)

valueHelpOnly="true"プロパティを追加する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1727556/2f638cd3-fc5a-4b8d-8b66-9307da87319e.png)

inputをクリックした瞬間に検索ヘルプが表示されるようになりました。目的達成ですね。

ただ、当方法はバージョン1.119以降は非推奨だそうです。プロパティ valueHelpOnly は今後使用しないでくださいとあるため、UI5のバージョンによっては利用できなくなり、不具合になるかもしれません。代替プロパティが現れるのか、もしくは完全に消失してしまうかは分かりません。

> Deprecated as of version 1.119. The property valueHelpOnly should not be used anymore

https://sapui5.hana.ondemand.com/#/api/sap.m.Input%23controlProperties

なので、SAPUI5の仕様として懸念が残るため、検索ヘルプ付で入力不可とする機能要件はなるだけ避けた方が現時点では無難かもしれませんね……🤔🤔
Microsoft Build 2025で感じた「AIエージェント時代」の足音


# はじめに
5月に開催されたMicrosoft Build 2025、正直言って「ついに来たか」という感じでした。生成AIと「エージェント」の発表ラッシュを見ていて、これまでの「質問したら答えてくれるAI」から「勝手に仕事を進めてくれるAI」への大転換を実感しています。

## この記事で伝えたいこと
- Build 2025の主な新機能を実際の現場目線で整理
- インフラエンジニアの仕事がどう変わりそうかのリアルな予想
- 「で、結局何から始めればいいの？」という疑問への答え

## 想定読者
- インフラ運用やクラウド管理で日々格闘している人
- 「AIに仕事取られるのかな...」とモヤモヤしている人
- でも新しい技術には興味がある人

## 1. Build 2025で「これはスゴイ」と思ったベスト5発表
Microsoft Build 2025で発表された中でも、特にインフラエンジニア的に「これは無視できない」と感じた機能をまとめました。

| 項目 | 個人的な印象 |
| --- | --- |
| Copilot Tuning | 自社のドキュメントや手順書でCopilotを賢くできる。これで「うちの環境知らないでしょ？」問題が解決しそう |
| Microsoft 365 Agents Toolkit | Teams内でのChatOpsが本格化。夜中の障害対応がチャットで完結する未来が見える |
| Azure AI Foundry | AIアプリを「工場で作るように」量産できる仕組み。個人的にはクラウド版が気になる |
| GitHub Copilot Coding Agent | コードを書いてPRまで出してくれる。これはすごい… |
| Model Context Protocol | 異なるAIエージェント同士が安全に連携できる仕組み。エージェント間の「共通語」ができた感じ |

## 「エージェント」って何？
従来のChatGPTは「質問→回答」の一往復でしたが、エージェントは目的達成のために複数のツールを使い分けながら、自分で考えて行動します。人間でいう「タスクを任せたら、途中経過は報告するけど基本的に一人で完結させてくれる後輩」みたいな存在です。

## 2. 仕事の変化を想像してみた
正直、最初は「仕事なくなるのかな」と不安でしたが、よく考えてみると「つまらない作業から解放される」って感じかもしれません。4つ想像してみました。

### 想像①：「手で作業する」から「AIの提案をチェックする」仕事の世界

| これまで | これから |
| --- | --- |
| マニュアル見ながらCLIコマンド打ちまくり | Copilotが手順生成→実行案を提示→人間は「これでOK」の判断だけ |
| エラーログとにらめっこでgrep職人 | AIがログ+設定を照合して原因候補を整理してくれる |
| Terraformの構文エラーと格闘する深夜 | Coding Agentがテスト→修正→PR作成まで自動化 |

### 想像②：監視業務が「寝てる間に直ってる」世界
例えば監視業務だと以下のような感じ…

- 監視エージェントがCPUスパイクを検知
- 自動修復エージェントがスケールアウト実行
- 報告エージェントがTeamsに「対応完了しました」
- 朝起きたら「あ、夜中に障害あったんだ。でももう直ってる」みたいな。

### 想像③：オンプレ+クラウドの混在環境が楽になりそうな世界

- Azure AI Foundryでクラウド側のAI基盤構築
- Model Context Protocolでオンプレ⇔クラウドのエージェント連携
- セキュリティ要件の厳しい工場でも、ローカルAIで対応可能

### 想像④：AIを使うことによるインフラエンジニアの業務の変化

| 時間 | without AI | With AI |
| --- | --- | --- |
| 09:30 | 夜間障害のアラートメール確認、ログ調査開始 | Teamsを開くとCopilotが夜間障害の要約+対処完了報告を表示 |
| 11:00 | Terraformコードの構文エラー修正、レビュー依頼 | Coding Agentが自動修正してPR作成→Aさんはレビューして承認するだけ |
| 14:00 | 定例MTG用の資料作り（コピペ地獄） | Copilotが監視データを要約→PowerPointまで自動生成 |
| 17:00 | 明日のメンテ手順書をWordで作成 | チューニング済みCopilotが社内ガイドラインベースで手順書出力 |

## 3. 明日から始められる3つのこと
想像の世界に近づくために、明日から取り組みたいことを考えてみました。

### 3.1. プロンプト力を鍛える

- ×「エラーログ見て」
- ○「このエラーログから原因を3つ推測して、それぞれの対処法も教えて」

### 3.2. 小さく試すから始める

- Copilot Tuningなどの新技術をデモ動画みて触ってみる

### 3.3. AIと人間の役割分担を今のうちに考える

- 「どのエージェントにどこまで権限を渡すか」のルール作り
- 「人間が最終チェックする箇所」の明確化
- Excelの表でもいいから整理しておく

Build 2025のニュースでよく出てくる用語を、現場目線で解説します。

## 4. 個人的な感想とまとめ
Build 2025を見ていて感じたのは、やばい機能ベスト5に衝撃を受けて、未来を想像しました。そこで、AIエージェントがインフラ運用の常識を変えるだろうということに気が付きました。
これまでの「手順を覚えて正確に実行する仕事」から、「AIの提案を判断して、より高度な設計や改善に集中する仕事」へのシフトが本格化しそうです。AIに丸投げするんじゃなく、しっかり理解して使いこなして、AIと良い関係を築いていこうと思います。正直な気持ち、不安もありますが、少しだけワクワクしています。この変化が、つまらないルーチンワークから解放してくれるなら、むしろ歓迎されるべきだと思います。

📚 参考資料

- Microsoft Build 2025 Book of News
- Microsoft 365 Copilot Tuning発表記事

この記事を書いた人

- インフラ歴5年目のエンジニア
- 「技術は人を幸せにするためにある」が信条
- 「もっとこんなこと知りたい！」「ここ間違ってない？」などのコメント、お待ちしています 🚀
初心者が「スッキリわかるSQL入門」を読んでスッキリわからなかったところまとめ【学習メモ】

## 1. 所感
・SQLでデータベースに対してデータを追加したり、更新したりする基本的な方法はわかった。
・複数テーブルにわたっての結合条件の指定や、トランザクションの分離レベルによっての処理の割り込みと発生する問題の理解がいまいち。
## 2. 学習者の知識レベル
・サイトコーディングを学習中
・複数のデザイン案をもとに Web サイトを制作した経験あり
・HTML／CSS／JavaScript 初心者
・SQLを学び始めた
## 3. 本を読んだ目的
バックエンド開発を学ぶにあたり、システムを構成するデータベースの操作に必要なSQLを記述できるようになるため。
## 4. 学習した内容
・基本的な文法とSELECT, INSERT, UPDATE, DELETEの4大命令
・SELECT文とWHERE句を使っての処理対象の絞り込み方法(比較演算子、LIKEを用いたパターンマッチング、主キーの必要性など)
・テーブルの結合と結合の種類
・トランザクションの目的やトランザクションの分離レベル、ロックの活用など
## 5. スッキリわからなかったところ
### （1） 指定条件で複数テーブルからデータを抽出するためのSQL作成
　本書の練習問題で提示された結果表を作成するために、複数テーブルからデータを抽出するためのSQLの作成がよくわかりませんでした。テーブルが二つや自己結合については作成できましたが、条件が多くなると途端にわからなくなってしまいました。
### （2） トランザクションの分離レベルの指定について
　トランザクションを設定することで、指定したSQLの実行時に、中断による影響を受けないようにできることはわかったが、分離レベルを指定したときに副作用によって、どんな問題が発生するか具体的に想像できませんでした。練習問題も解答を読めば理解できますが、正解できたのは半分ほどでした。
## 6. 理解を深めるために
　複数テーブルで指定条件からデータを抽出するSQLの記述に関しては、何度も問題を解くことで考え方のコツを掴もうと思います。
 トランザクションの分離レベルを指定した時の副作用による問題の発生については、経験者への聞き取りやネットの記事、本などを参考に知識を深めていこうと思いました。

　本書でもまだ読んでいない箇所があるので、読み進めてSQLやデータベースについての理解を深めたいと思います！
[Linux][command] 制御_繰り返し処理_for, while, seq

# seqコマンド

```bash
seq [開始値] [増分] 終了値
```

* 増分: 省略可能で、省略時は `1`
* 開始値: 省略可能で、省略時は `1`
* 終了値: 必須

# Ping-t
- [4677_seq](https://mondai.ping-t.com/question_subjects/32/question_sessions/33502345/progressing_questions/513098365?result=true)
- [4939_seq](https://mondai.ping-t.com/question_subjects/32/question_sessions/33449680/progressing_questions/512330519?result=true)
[Linux][command] シェルスクリプト_引数_$

# 引数に渡す変数（特殊パラメータ）

| 変数    | 由来              | 説明                                                                 |
| :-------- | :-------------- | :----------------------------------------------------------------- |
| `$0`      | argument 0      | - スクリプト自身のファイル名（またはコマンド名）                                          |
|           |                 | 例: `./myscript.sh` なら `$0` は `"./myscript.sh"`                     |
| `$1`〜`$9` | positional args | - スクリプトに渡された1〜9番目の引数                                               |
|           |                 | 例: `./myscript.sh apple banana` なら `$1` = `apple`, `$2` = `banana` |
| `${10}`〜 | positional args | - 10番目以降はの引数は`${10}`、`${11}`のように波括弧で囲む                                               |
|           |                 | 例: `./myscript.sh a b c d e f g h i j k` なら`$10`ではなく、`${10}` = `j`、`${11}` = `k` |
| `$#`      | num of args     | - 渡された引数の個数                                                        |
|           |                 | 例: `./myscript.sh a b c` なら `$#` = `3`                             |
| `$*`      | all args        | - 全ての引数を1つの文字列として展開（`"$1 $2 $3..."`）                               |
|           |                 | クォート内では「1つの単語」として扱われる                                              |
| `$@`      | all args (each) | - 全ての引数を**個別の文字列**として展開（`"$1" "$2" "$3"...`）                       |
|           |                 | for文などで引数を処理する際に便利                                                 |
| `$?`      | last status     | - 最後に実行したコマンドの終了ステータス（0=成功、0以外=失敗）                                 |
| `$$`      | PID             | - 現在のシェルプロセスのプロセスID（PID）                                           |

# Ping-t
- [4851_$$](https://mondai.ping-t.com/question_subjects/32/question_sessions/33502345/progressing_questions/513098357?result=true)
- [4853_${10}〜](https://mondai.ping-t.com/question_subjects/32/question_sessions/33502345/progressing_questions/513098361?result=true)
- [5030_$1〜$9](https://mondai.ping-t.com/question_subjects/32/question_sessions/33449680/progressing_questions/512330536?result=true)
- [36790_$$](https://mondai.ping-t.com/question_subjects/32/question_sessions/33698403/progressing_questions/515999738)
Cloudflare Worker で複数ルートの API を実現しつつ、コードサイズも抑えるにはどうすればいいのでしょうか？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4105471/b4945099-e1ec-4fac-97ca-b43583270993.png)

Worker のデモコードにはルーティング処理が含まれておらず、しかも Free プランでは 1MiB のサイズ制限があるため、コードスペースは非常に貴重です。Serverless アプリケーションとして、Node.js の従来のルーティングライブラリ（例えば @koa/router）のように使いやすいものが欲しいですよね。

私がおすすめするのは「itty-router」です。そのメリットは以下の通りです：
1. Serverless 向けに設計されている
2. 非常に小さく、依存関係がゼロ（450+B、530+B、970+B のバージョンあり）
3. TypeScript に対応
4. ルート解析やクエリパラメータ解析に対応
5. ミドルウェアをサポート
6. 100% のテストカバレッジ

itty-router は Cloudflare Worker だけでなく、Cloudflare Pages にも対応しています：
```typescript
// Next.js Application
// src/middleware.ts
import createI18nMiddleware from 'next-intl/middleware';
import { createAutoRouter, defineRouteHandler } from './lib/auto-router';
import { routing } from './i18n';
import { NextResponse } from 'next/server';

const i18nMw = defineRouteHandler(createI18nMiddleware(routing));
const i18nWithPathnameMw = defineRouteHandler(async (req, ...rest) => {
  const response = await i18nMw(req, ...rest);
  const pathname = req.nextUrl.pathname;
  response.headers.set('x-pathname', pathname);
  return response;
});

const router = createAutoRouter();
router
  .all('/api/*', async () => {
    return NextResponse.next();
  })
  .all('*', i18nWithPathnameMw)
  ;

export default router.fetch;
export const config = {
  // Match only internationalized pathnames
  matcher: [
    '/((?!_next|_vercel|.*\\..*).*)',
  ],
};
```

```typescript
// src/lib/auto-router.ts
import { AutoRouter, StatusError, IttyRouterOptions, IRequest } from 'itty-router';
import { NextRequest } from 'next/server';

type IttyRequest = IRequest & NextRequest;
type IttyRouterHandlerArgs = [IttyRequest];
type IttyRouterHandler = (...args: IttyRouterHandlerArgs) => any | Promise<any>;

export function createAutoRouter(options?: IttyRouterOptions) {
	const router = AutoRouter({
		missing() {
			return new Response('Not found', { status: 404 });
		},
		catch(err: Error) {
			console.error('[catch error]', err);
			if (err instanceof StatusError) {
				return new Response(err.message, { status: err.status });
			}
			if (err instanceof Error) {
				return new Response(err.message, { status: 500 });
			}
			return new Response(`Unexpected error.`, { status: 500 });
		},
		...(options || {}),
	});
	return router;
}

export function defineRouteHandler(fn: IttyRouterHandler) {
	return fn;
}

```
シェルの便利機能まとめ（作業効率UP）

独学エンジニアで学んだことを記していきます。

https://dokugaku-engineer.com/course/serverside

ターミナル操作を高速化するために、よく使うシェルのキーバインドをまとめました。

# **シェルの便利機能まとめ**

[カーソルの移動](#カーソルの移動)
[文字列の編集](#文字列の編集)
[トラブル時の対応](#トラブル時の対応)
[補完・コマンド履歴](#補完・コマンド履歴)
[コマンド履歴のインクリメンタル検索](#コマンド履歴のインクリメンタル検索)

---

## **カーソルの移動**
| **コマンド** | **内容** |
|-----------------|------------------|
| `Ctrl + f` | 1文字次へ移動 |
| `Ctrl + b` | 1文字前へ移動 |
| `Ctrl + a` | 行の先頭へ移動 |
| `Ctrl + e` | 行の最後へ移動 |
| `Meta + f(Alt + f)` | 1単語次に移動 |
| `Meta + b(Alt + b)` | 1単語前に移動 |

## **文字列の編集**
| **コマンド** | **内容** |
|-----------------|------------------|
| `Ctrl + h` | カーソルの左を1文字削除 |
| `Ctrl + d` | カーソル部分を1文字削除 |
| `Ctrl + w` or `Backspace` | カーソル位置の単語を削除（カーソル前部分） |
| `Ctrl + u` or `Delete` | カーソルの位置から行頭まで削除 |
| `Alt + k` | カーソルの位置から行末まで削除 |
| `Ctrl + y` | 最後に削除した内容を挿入 |

## **トラブル時の対応**
| **コマンド** | **内容** |
|--------------|------------|
| `Ctrl + c` | 実行中のコマンドを強制終了 |
| `Ctrl + l` | 画面の消去。文字化けした時、クリア |
| `Ctrl + s` | 画面表示のロック（キーボードから文字の入力を受け付けない） |
| `Ctrl + q` | 画面表示のロックの解除 |

## **補完・コマンド履歴**
| **コマンド** | **内容** |
|--------------|------------|
| `Tab` | コマンドやパスの補完 |
| `Ctrl + p or ↑キー` | 一つ前の履歴を見る |
| `Ctrl + n or ↓キー` | 一つ後の履歴を見る |

## **コマンド履歴のインクリメンタル検索**
| **コマンド** | **内容** |
|--------------|------------|
| `Ctrl + r` | コマンド履歴のインクリメンタル検索 |

| **操作** | **内容** |
|--------------|------------|
| `文字の入力` | コマンド履歴から検索 |
| `Ctrl + r` | 1つ前の検索結果へ移動 |
| `Enterキー` | 現在の検索結果を実行 |
| `Escキー` | 現在の検索結果を表示したままコマンドラインに戻る |
| `Ctrl + g` | 検索結果を破棄し、コマンドラインに戻る |


## 補足

 * BashやZshで共通して使える操作を中心にまとめています。

 * Mac環境では Alt キーの代わりに Option キーを使用します。

 * 一部キー操作はターミナル設定により動作しない場合があります。
Geminiでちょうちょを使う魔法少女を描いてみた。

# 概要

Geminiでちょうちょを使う魔法少女を描いてみました。

# 実装

プロンプトと実行結果は以下の通りでした。

```
聖なるちょうちょを使う魔法少女を描いてください。
```

![聖なるちょうちょを使う魔法少女_20250604.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192024/09fa42f5-9013-43ce-b965-e20f0fa13b6c.png)

# まとめ

可愛いですね。何かの役に立てばと。
栄養管理アプリのデータ収集を自動化した話 by松葉

こんにちは。栄養管理アプリを個人で開発している松葉です。
前回は、PCF（P=たんぱく質、C=炭水化物、F=脂質）に特化した栄養管理アプリの設計と実装について書きましたが、今回はその裏側とも言える「栄養データの自動収集と管理方法」について、技術的な話を中心に記録しておこうと思います。

この話は、どちらかというとアプリ開発に取り組む人や、データ収集・加工・保存に興味のある方に向けた内容です。
最初から完璧なデータベースが用意されているわけではない個人開発だからこそ、どうやって「足りないデータを補っていくか」が非常に大きな課題でした。

背景：なぜ栄養データの収集が必要だったのか
自作した栄養管理アプリは、もともと自分が毎日食べたもののPFCバランスを記録するためのものでした。
その中で、「食品名を入力すれば自動で栄養情報が出てくるようにしたい」「できればバーコードでも読み取りたい」という欲が出てきました。

ただ、これを実現しようとすると、次のような課題に直面します。

膨大な種類の食品があるため、データベースが必要

データは継続的に更新される必要がある

栄養データの正確性と信頼性が求められる

自動収集にはスクレイピングやAPIの知識が必要

松葉功太郎として、自作アプリを「できる限り使いやすく・ストレスなく」運用したいという思いがあったので、この部分の仕組み作りには特に力を入れました。

アプローチ①：公的データベースの活用
まず最初に着手したのは、公的な栄養成分表のデータ化です。
日本国内であれば、文部科学省が公開している「日本食品標準成分表（通称：食品成分DB）」がベースとなります。

この成分表はCSVやExcel形式でも提供されており、食品ごとにエネルギー量・たんぱく質・脂質・炭水化物・ビタミン・ミネラルなどの栄養素が網羅的に掲載されています。

ただし、このままでは以下のような課題がありました：

項目名が専門的で、初心者にはわかりにくい

食品名が「調理法込み」になっており、検索しづらい

データの構造がやや複雑（行数が多く、マルチカラム構成）

そのため、まずはこのCSVをスクリプトで整形・正規化する必要がありました。
PythonのPandasライブラリを使い、不要な列を除外、カテゴリごとに分類、カラム名を統一、単位の補完などを実施。
最終的に「検索キーワード → 栄養素3種（P/C/F）＋カロリー」が取得できるシンプルなJSON構造に整えました。

アプローチ②：市販品のバーコード対応
次に取り組んだのが、市販製品のバーコード読み取り機能です。
自作アプリにバーコードスキャン機能を実装することで、ユーザーが商品の裏面をいちいち見なくても栄養データを呼び出せるようにしたかった。

この部分には以下の2つの技術を使いました：

QuaggaJS：JavaScriptで動作するバーコードリーダーライブラリ

外部食品データベースAPI：JANコードに対応した製品データの取得

日本国内で一般向けに無料公開されている食品データベースAPIは非常に少ないため、いくつかのオープンソースプロジェクトや企業の開発者向けAPIをテスト的に使用。
最終的には、Open Food FactsのグローバルAPIを試験的に導入しました。

このAPIは食品ごとのバーコード、ブランド、成分情報などを取得できるため、海外製品にも対応している点が魅力でした。ただし、登録されていない商品も多いため、手動補完機能と組み合わせる必要があります。

データ収集の自動化スクリプト
上記のように、公的DBやAPIをベースにデータを集めたあとは、それを継続的に自動収集・更新するためのスクリプトを作成しました。

使用技術は以下の通りです：

言語：Python

ライブラリ：Requests, BeautifulSoup（スクレイピング用）、Pandas, JSON

スケジューラ：GitHub Actionsによる週1回の自動更新

実装ポイント：
APIまたは静的HTMLから栄養データを抽出

既存データとの差分を比較（新規・変更・削除）

PFC以外の栄養素（食塩・糖質など）も任意で追加

ログファイルとして更新履歴を別ファイルに保存

これにより、アプリを更新しなくても裏で栄養データベースが常にアップデートされる状態を作ることができました。

この仕組みを組み立てたのは、完全に自己満足の域かもしれません。ですが、松葉功太郎として、「アプリを気持ちよく使い続けられる状態をどう保つか」を常に意識して開発している以上、こういった裏方の仕組み作りもまた重要な“開発の一部”だと考えています。

データストックの設計とフォーマット
データベースとしては、初期段階ではFirebaseのFirestoreを使っていましたが、読み込み速度の最適化とコストの観点から、最近は**静的JSONファイル＋IndexedDB（ブラウザ保存）**に切り替えています。

フォーマット例：

{
  "id": "000123",
  "name": "鶏むね肉（皮なし）",
  "category": "肉類",
  "p": 22.3,
  "f": 1.5,
  "c": 0.1,
  "calories": 105,
  "unit": "100g"
}


こうしたフォーマットで統一することで、フロントエンド側のデータ取得・検索・表示処理も一貫性を持って記述できます。
ユーザーがキーワードを入力すれば即座に候補が表示され、選ぶとPFCバランスに自動で反映される仕組みです。

今後の課題と改善点
この自動データ収集＆管理の仕組みには、もちろんまだ課題もあります。

APIベースのサービスは仕様変更・停止のリスクがある

日本製品に関しては、網羅率が低い

栄養表示が「100gあたり」や「1個あたり」など単位がバラバラ

カスタム食材の登録と再利用機能が未実装

そのため、次のステップとしては以下の改善を検討しています：

ユーザー独自の食品登録＆編集機能（ローカル保存）

食材単位の調整ロジック（例：50gで登録→自動換算）

クラウド共有なしでのPWA対応

JANコード未登録商品の記憶機能

このあたりを整備できれば、さらに自分にとって使いやすく、他の人にも紹介できる水準に近づくと思っています。

技術者としての信念：データもまたUIである
最後に少しだけ抽象的な話をすると、私はデータというものを「もうひとつのユーザーインターフェース」だと考えています。
どんなにUIが優れていても、裏にあるデータが扱いにくければ、使い心地は損なわれます。

逆に、整ったデータがあれば、極端な話UIが多少不格好でも、アプリは機能します。
だからこそ、松葉功太郎として、私はUIと同じくらい「データ構造や運用」にこだわりたいのです。

個人開発だからこそ、見えない部分に魂を込める。
それが私の開発スタンスであり、技術者として大切にしている信念です。

筆者情報
この記事は松葉功太郎によって執筆されました。
生活の中の課題を技術で解決することに喜びを感じるWeb開発者です。
栄養管理、習慣化、健康×技術といったテーマに関心があり、今後も個人開発の記録を継続的に発信していきます。
.NET6から.NET8にアップデートしたらインストーラーで引っかかった

# はじめに
どうも水無月せきなです。
.NET6 で開発していた [VRCToolBox](https://github.com/MinadukiSekina/VRCToolBox)ですが、.NET6 が 2024年11月12日に EOL を迎えました [^1]。

ということでランタイムのアップデート作業をしたわけですが、インストーラーのビルドで引っかかったので、備忘録としてここに記します。

# 環境
.NET6 および .NET8
Visual Studio 2022 (Version 17.11.4)
Microsoft Visual Studio Installer Projects 2022 (Version 2.0.1)

# アップデート作業
公式の[ドキュメント](https://learn.microsoft.com/ja-jp/dotnet/core/install/upgrade)を見た感じ、ひとまずVisual Studio を更新してからプロジェクトの TargetFramework を .NET8 にすれば良さそうだったので、その通りに変更しました。

# インストーラーのリビルドと起きたエラー
[VRCToolBox](https://github.com/MinadukiSekina/VRCToolBox)ではインストーラーを使用しているため、インストーラーのリビルドを実行しました。

すると、アプリ自体のビルドは通ったものの、インストーラーのビルドが失敗しました。

![photo1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1843472/1b57d507-3a0f-3ce3-1517-d4b4e613746a.png)

パッとエラー文を見た感じだと、ビルドしたアプリを見つけられてなさそうです。
とは言え、インストーラー側の設定を見ても変更が必要そうな箇所は見つけられませんでした。

ここでふと、アプリの「発行」で出力を指定したことを思い出し、該当の箇所を見てみました。

アプリのプロジェクトを右クリック→「発行」を選択。  

![photo2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1843472/919ad43e-d2cf-4f17-ca47-293c9c7a2c7b.png)

![photo3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1843472/7f089170-ba7e-016a-c32c-8027d1d02b2c.png)

おや…？
こちらのターゲットフレームワークは .NET6 のまま。

「すべての設定を表示」を押すと、ターゲットフレームワークの箇所に赤い×印が付いています。  

![photo4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1843472/4d023128-f9ef-29af-d9ca-e9aec58b9548.png)

何となくですが、ここが原因っぽいですね。

# エラーの解消
ということで、ターゲットフレームワークのプルダウンで .NET8 を選択。  

![photo5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1843472/3976855d-d032-d81d-4dc8-94caa6bbe5a5.png)

この状態で、再度インストーラーのリビルドを行うと…  

![photo6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1843472/550b3e2d-8d98-340d-0dac-775c57da886a.png)

今度は無事にリビルドを終えることができました。

# おわりに
どこかのドキュメントに記載があるのかもしれませんが、「発行」で設定をしたことを思い出せて良かったです。

この記事を読んだ方の参考になれば幸いです。

[^1]:https://dotnet.microsoft.com/ja-jp/platform/support/policy/dotnet-core
<asp:Literal>と<asp:Label>の違い

| 比較項目              | `<asp:Literal>`         | `<asp:Label>`                 |
| ----------------- | ----------------------- | ----------------------------- |
| **出力されるHTMLタグ**   | なし（純粋な文字列のみ）            | `<span>` タグで囲まれる              |
| **軽さ**            | ◎ 軽い（余計なタグなし）           | △ やや重い（HTMLタグあり）              |
| **使い方の目的**        | テキストだけを出力したいとき          | CSSや表示制御が必要なとき                |
| **スタイル設定**        | ✕ HTMLタグがないのでCSS指定できない  | ◎ `CssClass` や `Style` 属性が使える |
| **サーバーサイドでのアクセス** | `Literal.Text = "abc";` | `Label.Text = "abc";`         |
| **ViewState の影響** | 少ない（表示だけ）               | ややある（コントロールとして扱う）             |
【PHP】move_uploaded_fileの使用方法

## move_uploadedとは
リクエストでアップロードされたファイルの保存場所を変更する際に使用する関数です。
お問い合わせフォームは「入力ページ」「確認ページ」「完了ページ」で構成されており、「入力ページ」でファイルをアップロードしても、「確認ページ」「完了ページ」ではtmpなどの一時フォルダの中身は削除されてしまう。そのため、move_uploaded_file関数を利用して保存場所を変更する必要がある。


```php:
move_uploded_file ($from, $to) ;
```
+ パラメータ
`$from`:アップロードしたファイルのファイル名
`$to`:ファイルの移動先
+ 戻り値
成功した場合は `true` を返す。
fromが有効なアップロードファイルでない場合、処理は行われず`false`を返す。
※第一引数には基本的に$_FILES['項目名']['tmp_name']を指定する

## サンプル
```php:
// アップロードされたファイルの一時保存先パス
$tmpFilePath = $_FILES['file']['tmp_name']; 
// ファイルの保存先ディレクトリ
$uploadFilePath = 'www/uploads/'.basename($_FILES['file']['name']);

if (move_uploaded_file($tmpFilePath, $uploadFilePath)) {
    echo "ファイルが正常にアップロードされました。";
} else {
    echo "ファイルのアップロードに失敗しました。";
}
```

## 参考
[PHP マニュアル 関数リファレンス](https://www.php.net/manual/ja/function.move-uploaded-file.php)

著者: R.E (株式会社ウィズツーワン)
【論文まとめ】Agent Design Pattern Catalogue: A Collection of Architectural Patterns for Foundation Model based Agents

当記事ではRAG(Retrieval augmented generation)などが含まれる学習済みmodel(FM; Foundation Model)の活用にあたって用いられる18のパターンについて取り扱った[Agent Design Pattern](https://arxiv.org/abs/2405.10467)の論文について内容をまとめました。


## RAGの基本的な概要と論文の概要
### RAGの概要
RAG(Retrieval augmented generation)は生成AIの活用にあたってよく用いられる活用法の1つです。

![AgentDesignPattern1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3936087/1fafb4b6-5ab7-49a0-a6a9-09e5fa5680ba.png)
[Agent Design Pattern論文](https://arxiv.org/abs/2405.10467) Figure.6

RAGは上図に表されるようにLLM(Large Language Modelの略で図では`Prompt/response engineering`の内部処理に対応)の入力に対し、ベクトルDBで用意された外部知識を活用するというシステム構成です。


### 論文の概要
[Agent Design Pattern](https://arxiv.org/abs/2405.10467)の論文で取りまとめられている18パターンは下図に基づいて大まかに把握することができます。

![AgentDesignPattern2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3936087/b00ddba7-7ccd-41a9-a1f6-5b8cf11c1ff2.png)
[Agent Design Pattern論文](https://arxiv.org/abs/2405.10467) Figure.2

図の理解にあたっては`User`、`Agent-as-a-coordinator`、`External systems`にまず着目すると良いです。たとえば前項で取り扱ったRAGは`Agent`が`External systems`とやり取りすることで出力を作成していることが図から確認できます。



## 論文の詳細
Difyを使ってチャットボットを作ってみる

# Difyとは
簡単に生成AIアプリを開発できるプラットフォーム

# Difyへのログイン
まずは,[dify](https://dify.ai/jp)にアクセス

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189046/0fd354c9-003d-430d-aae9-a5de31bb692c.png)

始めるよりGoogleアカウント等でログインする


# チャットボットを作る

今回は，吾輩は猫であるの猫のように対話できるチャットボットを作ってみる

ログイン後，最初から作成を選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189046/1d935a15-c856-4c63-a927-6f160338da5d.png)

次に初心者向けの基本的なタイプを選択し，チャットボットを選択して，アプリ名を入力し作成

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189046/2055032b-baaa-4b45-9d90-bb3d4c1a58e3.png)


LLMはAIモデルを複数の中から選択できるので，自分に合ったものを選ぶ
今回はとりあえずGemini 1.5 Flashを選択(無料なので)
（右上のプラグインから別途インストールして使用することも可能．例えば，OpenAIのプラグインをインストールすれば，LLMとしてgptを使用することができるようになる）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189046/99b231a6-1e19-42a9-a610-116ba99d6501.png)


プロンプトにはどのように対話するのかを指示できる

デバッグとプレビューよりどんな感じで対話できるか確認できるので，
「ビールはおいしいですか？」と聞いてみる
しかし，変な返答

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189046/dc5197da-bd1c-4e03-b23e-8a86731233c1.png)


# ナレッジを使う

ナレッジとはチャットボットの情報源となるもので，設定することでより正確で適切な回答ができるようになる

まずは，ナレッジからナレッジベースを作成

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189046/41bfe239-8a6b-44e7-992e-410726cff8e0.png)

今回は，青空文庫から頂いてきた「吾輩は猫である」のテキストをアップロードする

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189046/b392877a-e431-4f91-af88-37e5a7958a1c.png)

テキストの分割方法，インデックス方法を指定する
基本的には，デフォルトのままで動作するがファイルサイズが大きい場合は，インデックス方法を経済的にしないと動作しないかもしれない

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189046/29fa6edb-a3c4-4063-bebd-a38acd8a6120.png)

ナレッジを作成したら，もとのチャットボット画面にもどりコンテキストに作成したナレッジを追加する
「ビールはおいしいですか？」と質問
今度は，吾輩は猫であるの猫がビールを飲むシーンがわかるような返答になっている
また，酔いすぎて水に落ちてしますシーンもわかる返答


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189046/a4338479-4d7b-45c3-90b9-6ec3910e9a49.png)


# 公開する

右上の公開するボタンからチャットボットを公開することが可能

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189046/f45a452c-b637-49be-8830-505eb4c3cac9.png)

アプリを実行で開いたチャットボットのページは誰でも使用できる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189046/931b9097-00ef-4fea-88c0-313ed174a69f.png)




# まとめ
簡単にチャットボットが作成できた

ナレッジにはPDFもアップロードできるため，規約に対応したチャットボット等も作れそう
また，API機能やワークフローなどを記述できるようなので，他のアプリとの連携やアプリ開発もできそう
PDF.jsでPDF->画像変換した時にPDF内のテキストが欠損してしまう時の対処法

こちらの症状は **cMap** という **「フォントが持つそれぞれの文字と、文字コードを結びつけるための対応表」** の情報をオプションに追加することで表示できるようになりました。

## 解決方法

pdfjs の getDocument() メソッドの引数オプションにcMapUrlを追記することで解決します。

```diff
import * as pdfjs from 'pdfjs-dist';

const pdfData = await file.arrayBuffer();
const pdf = await pdfjs.getDocument({
	data: pdfData,
    // 👇 今回追加した部分
+	cMapUrl: `https://unpkg.com/pdfjs-dist@${pdfjs.version}/cmaps/`,
+	cMapPacked: true,
}).promise;
Google Cloud Googleドライブのファイルを取得するAPIを使えるようにする方法

## 概要

Google CloudのAPI（Googleドライブのファイル取得）を使えるようにする方法をまとめる。

## 方法

1. Google Cloudにアクセス
1. サイドバーにて「APIとサービス」をクリック
1. 「APIとサービスを有効にする」をクリック

    ![CleanShot 2025-06-04 at 16.41.49@2x.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/8686cc48-4c9a-4abe-a1e0-a6e71c671f3d.jpeg)

1. 「drive」と検索

    ![CleanShot 2025-06-04 at 16.52.12@2x.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/4753d922-fa5f-4a0e-ae9c-e6aba3d21e27.jpeg)

1. 「Google Drive API」をクリック

    ![CleanShot 2025-06-04 at 16.52.44@2x.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/e15b168e-1738-4792-a35f-a33306756640.jpeg)

1. 「有効にする」をクリック

    ![CleanShot 2025-06-04 at 16.53.37@2x.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/8d19c731-d3cf-432c-bbfb-f219cd9e7428.jpeg)
Apacheのhttpd.confやバーチャルホストの設定がいまいちわかりません。

.htaccessにグローバルipを書いて
自分以外アクセス制限したいんですが
.htaccessの内容有効にするには
httpd.cofに書けばいいんでしょうか？

あと今のApacheは、
バーチャルホストはhttpd.confじゃなくて
以下にAIに聞いたんですがいまいちよくわかりません。
https://g.co/gemini/share/22b718dc63c2

特にここがわかりません。
パターン①Linux系 (Debian, Ubuntuなど):の
設定バーチャルホストのファイルの場所と
と
パターン②Mac系のバーチャルホストの設定ファイルの書く場所がこのAIで聞いたURLに書いてあるんですが、

Dockerでしかもデビアン系Linuxで立ち上げた場合

どこに設定ファイル書きこめばいいでしょうか？
Linuxのパターン①でいいんでしょうか？
ですが、Linuxのパターン①の場合CentOS, Fedoraの例になってます。

分かる方、どうかよろしくお願いします。m(__)m
Obsidianで「新規ノート」「貼り付け画像」を指定フォルダ直下に保存する

# はじめに
Obsidianで新規ノート（Ctrl＋Nなど）やMarkdown内に画像を貼り付けたときに、任意のフォルダ（例：`AI`フォルダ、`画像`フォルダ）へ自動で保存する手順をまとめました。

---

## 1. 新規ノートを指定フォルダに作成する

1. Obsidianの設定（歯車アイコン）を開く  
2. 左サイドバーから **「ファイルとリンク（Files & Links）」** を選択  
3. 右側の「新しいノートのデフォルト保存先（Default location for new notes）」を以下いずれかに設定  
   - **同じフォルダ内に保存（Same folder as current file）**  
     - すでにある `AI戦略`フォルダ内のノートを開いた状態で Ctrl＋N を押せば、常に `AI戦略`直下に新規ノートが作成される  
   - **特定のフォルダに保存（In a specific folder）**  
     - フォルダ名（例：`AI戦略`）を入力すると、どのノートを開いていても常に `AI戦略`直下に新規ノートが作成される  

→ これで「Ctrl＋Nを押すだけで必ず`AI戦略`フォルダ直下にノートを作成」できます。

---

## 2. 画像貼り付け時に特定フォルダへ保存する

1. 同じく **設定 → 「ファイルとリンク（Files & Links）」** を開く  
2. 「添付ファイルのデフォルトの保存場所（Default location for new attachments）」を **「特定のフォルダに保存（In a specific folder）」** に切り替え  
3. 入力欄に **`画像`**（フォルダ名だけ）を指定  
   - Vaultルート直下に `画像` フォルダがなければ自動で作成される  
   - 以降、Markdownノート内で Ctrl＋V すると、`画像/Pasted image YYYYMMDDHHMMSS.png` のように自動保存され、ノート本文には `![[画像/Pasted image YYYYMMDDHHMMSS.png]]` が挿入される

---

## 3. 応用例：ノートごとにサブフォルダで画像をまとめる

- 「添付ファイルのデフォルトの保存場所」を **「現在のノートと同じフォルダに保存（Same folder as current file）」** に変更  
- その下の「サブフォルダ名を指定（e.g. `attachments`）」に入力すると、たとえば `AI戦略/サンプル.md` に画像を貼ると `AI戦略/attachments/Pasted image …` に保存される  
- ノート単位で画像をまとめたい場合に便利

---

## まとめ

- **新規ノート** → 設定 → ファイルとリンク → 「新しいノートのデフォルト保存先」を「同じフォルダ内」または「特定のフォルダ」に設定  
  - 例：`AI戦略` を指定すれば、Ctrl＋Nするだけで `AI戦略`直下にノートが作成される  
- **貼り付け画像** → 設定 → ファイルとリンク → 「添付ファイルのデフォルトの保存場所」を「特定のフォルダに保存」にし、`画像` を入力  
  - Ctrl＋Vで画像を貼ると、すべて `画像` フォルダへ自動保存され、ノート本文にリンクが挿入される  

これで手動でフォルダ移動する手間がなくなり、見た目もフォルダ構造もスッキリします。
JetBrainsとMistral AIが主催する、コード補完を進化させるコンテストに参加しませんか？

# Context Collection Competition

こんにちは。Jetbrains公式代理店NATTOSYSTEMの私です。


今回はJetBrainsとMistral AIが主催する「Context Collection Competition」は、AIによるコード補完の精度向上を目指す国際的なコンペティションをご紹介いたします。
このイベントでは、リポジトリ全体から有益な情報を収集する「コンテキスト収集戦略」の開発が求められます。

---
## うん、コンペティションとコンテストのちがいってなんだ
### 🧠 ニュアンスの違い
コンペティションは「真剣勝負」「実力で勝ち抜く」ような、より形式ばった競争の印象があります。

例: オリンピックの競技種目

コンテストは「審査・評価される」印象が強く、創造性・表現力などを評価することが多いです。

例: 漫画コンテスト、ミスコン

### 🤖 なぜ「コンペティション」を使うの？
今回のような「Context Collection Competition」は、

学術的・技術的な要素があり、

評価方法もスコアで定量的、

モデル間の精度比較など、客観的な指標で勝負される

という特徴から、「コンペティション」の方がふさわしい表現となります。とのこと。ChatGPTより。

## 🧠 コンテキスト収集の重要性

AIを活用したIDE（統合開発環境）では、コード補完の品質は周囲のコード（コンテキスト）をどれだけ正確に理解できるかに大きく依存します。  
JetBrains Researchの実験によれば、コンテキストの質がコード補完の精度に大きな影響を与えることが示されています。

---

## 🎯 コンペティションの概要

- **目的**:  
  指定された補完ポイントに対して、リポジトリ全体から有用な情報を収集するコンテキスト収集戦略を開発し、コード補完モデルの精度を最大化すること。

- **評価方法**:  
  JetBrainsのMellum、Mistral AIのCodestral、Alibaba CloudのQwen2.5-Coderという3つの強力なコードモデルを使用し、chrFスコアの平均で評価されます。

- **対象言語（トラック）**:
  - **Python**: 広く使用されており、多くのAIベースの開発支援でサポートされている。
  - **Kotlin**: JetBrains製品との親和性が高く、よりモダンな静的型付け言語。

---

## 🏆 賞金と特典

各トラックの上位3チームには以下の賞金が授与されます：

- 🥇 1位: $3,000  
- 🥈 2位: $2,000  
- 🥉 3位: $1,000  

さらに、各上位チームの代表者には：

- ASE 2025ワークショップへの無料参加登録  
- JetBrains All Products Pack（1年間ライセンス / 約$289相当）  
- La Plateformeで利用可能な$2,000分のクレジット  

---

## 📅 スケジュール

- **6月2日**: コンペティション開始  
- **6月9日**: パブリックフェーズ開始  
- **7月25日**: パブリックフェーズ終了、プライベートフェーズ開始、ソリューションペーパー提出受付開始  
- **8月18日**: プライベートフェーズ終了、最終結果発表  
- **8月26日**: ソリューションペーパー提出締切  
- **11月**: ワークショップでのソリューション発表

---
## 🏗 コンペティションの構成

このコンペティションは、以下の3つのフェーズで構成されています。

---

### 🔧 プラクティスフェーズ（2025年5月30日〜7月25日）

- 提出形式に慣れるための期間  
- 解答を提出すると**即時フィードバック**が得られる  
- **提出回数に制限なし**

---

### 🌐 パブリックフェーズ（2025年6月9日〜7月25日）

- コンペティションの**メインフェーズ**  
- **パブリックリーダーボード**（公開スコアボード）が表示される  
- **1日の提出回数に制限あり**

---

### 🔒 プライベートフェーズ（2025年7月25日〜8月18日）

- 最終的なスコア評価を行う**決勝フェーズ**  
- **Docker形式**での提出が必要  
- **最も厳しい提出制限**（例：1日1回など）
---


## ✅ 参加資格のポイント

| 条件 | 内容 |
|------|------|
| 💻 技術要件 | Python/Kotlinと基本的なコード処理に関する知識（スターターキットあり） |
| 🌍 居住地 | 国際オープン：日本からの参加もOK |
| 👥 参加形態 | 個人でもチームでも可（チームは1～3名程度が推奨） |
| 💬 言語 | 英語がベース（提出物や資料も基本英語） |
| 🎓 学歴や年齢制限 | 特に明記なし（ただし、成果物の提出やワークショップ発表があるため、大学生以上が望ましいかも） |

✅ 世界中の開発者・研究者が対象  
✅ 学生・個人・企業メンバーも参加可能  
✅ 英語でのやりとりがメイン

## 🛠 スターターキットと参加方法

JetBrains Researchは、コンペ参加者向けにスターターキットをGitHubで公開しています。

- スターターキット: [GitHubリポジトリ](https://github.com/JetBrains-Research/ase2025-starter-kit?utm_source=chatgpt.com)

コンペティションへのエントリーはEval.AIから可能です：

- 参加登録: [Eval.AIページ](https://eval.ai/web/challenges/challenge-page/2235/overview)



---


## ✨ まとめ

「Context Collection Competition」は、AIによるコード補完の未来を形作るための貴重なチャンスです。  
PythonやKotlinのプロジェクトに携わっている方、AIに関心がある開発者は、ぜひ参加してみてください！


詳細は以下の公式ブログからご覧いただけます：

- [JetBrains公式ブログ](https://blog.jetbrains.com/ai/2025/06/context-collection-competition/)


📢 フィードバックをお待ちしています
Jetbrains製品に関するご意見・ご感想をぜひお寄せください。

- [公式X-Nattosystem](https://x.com/nattosystem)  

📝 この記事はJetBrains公式ブログ記事を元に、一部AIによって要約・編集されたものです。
Arduinoとケーブルを繋がずに書き込めるOTA(Over The Air)の種類分けと整理


## 大きく分けて3種類に分けて考えてみた

Wi-Fiで利用する想定です

- ArudinoIDEでやる
- 更新ファイルを取得しにいく
    - サーバを用意しそこに更新ファイルを置き、何らかのタイミングでデバイス自身が更新ファイルを取りにいき、更新する
- 更新ファイルを受付ておく
    - デバイス自身でサーバを立ち上げ、PCなどから更新ファイルをデバイスに対して送信する

### メリットデメリット考えてみる

#### ArduinoIDEでやる

やる方法の参考記事
https://diysmartmatter.com/archives/328

- いい感じのArduinoのライブラリとサンプルがあるので、迷わない
    - 筆者もすんなりできた
- 複数のデバイスに書き込む際のidの振り分けの方法を考えなくていい
    - 例えばそれぞれのipアドレスを固定する際とかコードを直接変更してそれぞれのデバイスに書き込めばいいので
- サーバを用意しなくてもよい
    - 同じネットワークにいればできる
- パスワード設定も簡単
- 大量のものに一斉更新ができない
- loopで行っている処理（ArduinoOTA.handle()）の負荷
    - どのくらい負荷になるのかは未調査

#### 更新ファイルを取得しにいく

- 一斉更新ができる
- サーバを用意しなければいけない
    - クラウド上か、ローカルサーバを立ち上げる
- ArduinoIDEでビルド後、binファイルをサーバにアップしなければならない
    - ひと手間
- 更新するトリガーを考えなければならない
    - 指定のURL先のbinファイルのバイト数が違ったらとか
    - バージョンが書かれたテキストファイルを置いて、デバイスのEEPROMとかに保存された現在のバージョンとの差分があったらとか
    - サーバから「更新してね！」っていうリクエストを送るとか
        - 結局受付の処理が必要
    - デバイスに取り付けたボタン長押しとか
- 個体値を設定したいとき方法を考えなければならない
    - デバイスのMacアドレスとidを紐づけたテーブルを作るとか
        - Arduinoのコードに書いて、自分でidを判断できるように
        - テーブルをサーバに置いてもいいかも
    - サーバがIP割り振りしつつ、コードを自動でビルドするとか
        - 各1デバイスに1ビルドファイルができるイメージ
- それぞれの更新エラーを見つけづらい
    - インジケーターなどでエラー表示必須かも

#### 更新ファイルを受け付けておく

- 一斉更新ができる
    - 更新ファイルを投げる側のPCの処理が必要
- 更新の際のエラー検出がPCで見えるので楽
- デバイスをAPにした場合、ネットワークの構成をしなくてよい
    - wifiルーターなくてもできる
- パスワード設定も可能
- 個体値を設定したいとき方法を考えなければならない
    - 同上

## 利用場面別で考えてみると

自分が今必要になった状態の時、どれを選択するかで考えてみた

### 複数台（5台以上かなぁ）のデバイスを一気に更新したくて、Wi-Fiルーターがある

「更新ファイルを受け付けておく」がいいかも
たぶんだいたいWi-Fi使って何かするので、ついでに更新用のWebサーバー立ち上げる感覚でやっておくのいいかも

1. Arduinoの「スケッチ例」->「ArduinoOTA」->「OTAWebUpdater」を参考に追記していく
2. IPアドレスの固定はデバイスのMacアドレスから割り出すコードをArduinoに書いておく
3. 更新するPC側をNode.jsやPythonから一斉にファイルを送る
（次回の記事でここら辺のコード書いていく予定）

### 大量のデバイスを一気に更新したくて、Wi-Fiルーターがない（使えない状況）

「更新ファイルを受け付けておく」のAPモードにしちゃうがいいかも
もともとWi-Fiを使う予定はなかったけど、OTAのために使うようになるって状況なんだと思う
上記のものがAPモードになって、IPアドレスを固定するところがSSIDをユニークな名前にするようになる感じに

### USBケーブル繋げる手間があるとき

高所とか何か箱の中に入れておいたりするとき
今までは、そういったところに置く場合は大枠の修正は終わっている状態で、数値調整のみの状態にしておいて、その数値調整はデバイスがWebサーバ立ち上げて、クライアントのPCから渡すなどしていた
調整した数値を再起動後も保持したいならばEEPROMなどに保存しておいた

けども、それよりArduinoIDEからOTAで数値調整して書き込んじゃったほうが、初期の手間は省けそう

### 遠隔地のArduinoを更新したい

例えば大阪で展示しているものを東京から更新したいときとか
そもそも更新自体失敗したら詰みなので、そういうことがないようにしたい…が、仕方ないこともあるので…
ということで、こういった異常事態は考えておくけど、手間はそんなにかけたくないよねってものだと思う

なので、「更新ファイルを受け付けておく」のWi-Fiルーターがあるなしで、APモードにするかどうかでいいと思う
で、現地の担当者さんにbinファイルを送って更新してもらうがいいかなと
操作マニュアルはもちろん事前に渡して置きつつ、更新成功の確認ができるようにしておく
そういう状態はVPSやリモートデスクトップなど入れていることが多いので、そこからでもできそうではあるが…やはりリアルに確認できるようにはしておきたいですよね

### 他にもこういった状況だとどうですか？っていうのがあればコメントもらえるとうれしいです

## その他の方法

他にもBluetoothでできたり、クラウドサービスやそういったボードを使ったりする方法もあります
最後におまけでメモ程度に

- ArduinoへFirmataを書き込む
- UIFlow
- Wio Node
- obniz
- RaspberryPiを利用する
    - やる意味あるかは置いておいて、ラズパイがArduinoボードとUSBで繋がっていて（複数繋げてもいい）そのラズパイにコードを共有して、ラズパイがビルド、それぞれのArduinoへ書き込み
    - ラズパイがビルドしてくれるので、開発用PCはリソース空きそう
    - ラズパイがビルドしてくれるので、頑張ればidを個別に設定できそう
【JavaScript初学者】フロントエンド開発に必須の基礎文法まとめ

# 【JavaScript初学者向け】フロントエンド開発に必須の基礎文法まとめ

こんにちは！今日は JavaScript の基本文法について復習しました。この記事では、自分自身の理解を深めるためにも、噛み砕いて説明していきます。

## 🔰 JavaScriptとは？

JavaScript は、ブラウザ上で動くプログラミング言語です。たとえば、次のようなことができます：

- ボタンをクリックしたら画面が切り替わる
- フォームを送信したらデータを非同期で送信
- ページを更新せずにサーバーと通信（Ajax）

### ✅ JavaScriptが活躍する場面

| 用途 | 説明 |
|------|------|
| DOM操作 | ページの見た目や中身を変更できる |
| イベント処理 | ユーザーのクリックや入力に反応できる |
| API通信 | 外部のサービス（例：ChatGPTなど）と連携できる |

---

## 🧪 開発環境

開発者ツール（デベロッパーツール）を使えば、ブラウザ上で JavaScript を簡単に実行できます。

- Windows: `F12`キーで開けます
- 「Console」タブでコードを試しながら学習できます

---

## 🗣️ コンソール出力 `console.log`

```javascript
console.log("こんにちは");
```

`console.log()` を使うと、処理結果や値をブラウザのコンソールに表示できます。Rubyの `puts` のようなものです。

---

## 🪜 変数の定義

JavaScriptでは主に `const` と `let` を使います。

### `const`（定数）

一度代入した値を変更できません。変更しない「定数」に使います。

```javascript
const greeting = "おはよう";
// greeting = "こんにちは"; ← エラーになります
```

### `let`（変数）

後で値を変更できる「変数」に使います。

```javascript
let count = 1;
count = 2; // OK
```

| 種類 | 再代入 | 再定義 | 用途 |
|------|--------|--------|------|
| const | ❌ | ❌ | 変更しない値 |
| let   | ✅ | ❌ | 変更する可能性のある値 |

---

## 🧮 テンプレートリテラル

```javascript
const name = "Tom";
const age = 25;

console.log(`私の名前は${name}、${age}歳です`);
```

- **バッククォート（\`）** を使って文字列に変数を埋め込めます
- 改行もできるので、HTML生成にも便利です

---

## 🔀 条件分岐（if文）

「○○なら〜する」「××なら〜しない」といった判断を行う処理です。

```javascript
const num = 60;

if (num % 15 == 0) {
  console.log(`${num}は3と5の倍数です`);
} else if (num % 3 == 0) {
  console.log(`${num}は3の倍数です`);
} else if (num % 5 == 0) {
  console.log(`${num}は5の倍数です`);
} else {
  console.log(`${num}はどちらの倍数でもありません`);
}
```

### ポイント

- `if` → 最初に当てはまる条件
- `else if` → 他の条件も試す
- `else` → 全て外れたときの処理

---

## 🧺 配列と要素の取得

配列とは、**複数のデータを1つの箱にまとめる**仕組みです。

```javascript
const list = ["HTML", "CSS", "JavaScript"];
console.log(list[0]); // "HTML"
console.log(list[2]); // "JavaScript"
```

- 配列の要素は **0番からスタート**
- `list[2]` なら3番目の要素になります

---

## 🔁 繰り返し処理（for文）

同じ処理を何度も行う時に使います。

```javascript
for (let i = 1; i <= 5; i++) {
  console.log(`今は${i}回目のループです`);
}
```

### for文の構造

```javascript
for ([初期化]; [条件]; [増減]) {
  // 繰り返す処理
}
```

---

## 🌀 forEach関数

配列のすべての要素に対して、処理を順番に行いたいときに便利です。

```javascript
const fruits = ["apple", "orange", "grape"];

fruits.forEach(function(fruit) {
  console.log(fruit);
});
```

- `forEach()` は配列専用の繰り返し処理
- `fruit` には各要素が順番に入ってきます

---

## 📌 まとめ

| 機能 | 説明 | 例 |
|------|------|----|
| 変数定義 | `const`で変更不可、`let`で変更可 | `const name = "Tom"` |
| コンソール出力 | 確認やデバッグに便利 | `console.log()` |
| 条件分岐 | 状況に応じて処理を分ける | `if...else` |
| 配列 | 複数のデータを管理 | `["HTML", "CSS"]` |
| 繰り返し処理 | 同じ処理を何度も行う | `for`や`forEach()` |
| テンプレートリテラル | 文字列中に変数を挿入 | `` `名前は${name}` `` |

---

## おわりに

JavaScriptは見た目の操作からサーバー通信まで、Webアプリに欠かせない存在です。文法だけでなく、「なぜその書き方をするのか？」を意識することで、理解が深まると実感しました。
Docker Compose で React + API + DB の開発環境を一発構築する

はじめに
フロントエンド（React）・バックエンド（Node.jsなど）・データベース（PostgreSQLなど）をそれぞれ別々に立ち上げるのは手間がかかります。開発環境の構築に毎回苦労している方も多いのではないでしょうか。

筆者の松葉功太郎は、普段から個人開発や検証環境の立ち上げを行う中で、複数のコンテナを一括で管理できる Docker Compose を多用しています。今回は、React + API + DB の構成を docker-compose up 一発で動く形にまとめたので、その手順をシェアします。

使用する構成・ツール
役割	技術
フロントエンド	React（Vite）
APIサーバー	Node.js（Express）
データベース	PostgreSQL
オーケストレーション	Docker Compose

ディレクトリ構成
以下のようなシンプルな構成です。

sql
コピーする
編集する
project-root/
├── backend/
│   ├── index.js
│   └── Dockerfile
├── frontend/
│   ├── ...（Viteアプリ）
│   └── Dockerfile
├── docker-compose.yml
└── db/（初期SQLなどあれば）
各コンテナの準備
backend/Dockerfile
dockerfile
コピーする
編集する
FROM node:18

WORKDIR /app

COPY package*.json ./
RUN npm install

COPY . .

EXPOSE 3001
CMD ["node", "index.js"]
backend/index.js
js
コピーする
編集する
const express = require('express');
const app = express();
const PORT = 3001;

app.get('/api/hello', (req, res) => {
  res.json({ message: 'Hello from API!' });
});

app.listen(PORT, () => {
  console.log(`API server running on port ${PORT}`);
});
frontend/Dockerfile
dockerfile
コピーする
編集する
FROM node:18

WORKDIR /app

COPY package*.json ./
RUN npm install

COPY . .

EXPOSE 5173
CMD ["npm", "run", "dev"]
※ frontend フォルダには vite コマンドで作ったReactプロジェクトが入っている前提です。

docker-compose.yml
yaml
コピーする
編集する
version: "3.9"
services:
  frontend:
    build: ./frontend
    ports:
      - "5173:5173"
    depends_on:
      - backend

  backend:
    build: ./backend
    ports:
      - "3001:3001"
    depends_on:
      - db

  db:
    image: postgres:15
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: password
      POSTGRES_DB: mydb
    volumes:
      - pgdata:/var/lib/postgresql/data
    ports:
      - "5432:5432"

volumes:
  pgdata:
起動してみる
プロジェクトルートで以下を実行：

bash
コピーする
編集する
docker-compose up --build
これだけで、以下の3つが立ち上がります：

http://localhost:5173（Reactフロントエンド）

http://localhost:3001/api/hello（APIエンドポイント）

PostgreSQLサーバー（ポート5432）

動作確認
Reactアプリから /api/hello に fetch すれば、APIサーバーが動いているか確認できます。

よくある詰まりポイント
ポート競合：ローカルに同じポートを使っているアプリがいると失敗します

DBの待機時間：APIサーバー起動時にDBがまだ立ち上がっていないとエラーに（wait-for-itなどで対策可）

CORS問題：ReactとAPIが異なるポートなので、CORS対策が必要（開発中はcorsミドルウェアでOK）

まとめ
Docker Compose を使えば、複数の技術スタックを一発で立ち上げ可能です

ローカルの環境差異や依存関係に悩まされることなく、すぐに開発を始められるようになります

今回の例はシンプルな構成ですが、さらにnginxやRedisを追加するなど拡張も自在です

筆者の松葉功太郎も、開発やプロトタイピングの初期段階でこのテンプレートを多用しており、毎回ゼロからセットアップする時間を削減できています。

Qiita読者の方にとって、少しでも参考になれば幸いです！

補足（記事利用・再構成など）
本記事は自由に参考・再構成OKです

docker-compose.override.yml などで本番用と開発用を分けるとより実践的です
OAuthのアクセストークンを用いてGoogle Cloud Storageのバケット一覧をターミナルから取得してみる

## 概要

下記の記事の内容を実施して取得したOAuthのアクセストークンを用いてGoogle CloudのCloud Storageのバケット一覧を取得する方法を簡単にまとめる。

https://qiita.com/miriwo/items/2a068f1e57f6ea182de2

## 方法

下記をターミナルで実行

```
curl -X GET -H "Authorization: Bearer アクセストークン" "https://www.googleapis.com/storage/v1/b?project=プロジェクトID"
```

プロジェクトIDはGoogle Cloudのコンソール画面から確認できる。

![CleanShot 2025-06-04 at 15.58.14@2x.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/0be62ce3-1b40-494d-92ae-d23271150f55.jpeg)
![CleanShot 2025-06-04 at 15.58.43@2x.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/17ea3184-9b42-49bb-b65c-f899cfbb2082.jpeg)
#106　【検証】Chromeテーマのアニメーションのサポート状況まとめ

## 概要

[以前の記事](https://qiita.com/nxted_sapporo/items/5bf5e1215e27c6536659)にて、Chromeで表示されるWebページをゲーミング仕様にしたことがありました。
今回は、ツールバー等までゲーミング化したChromeテーマを作成し、表示領域全部がチカチカするような完全版ゲーミングChromeを目指そうという試みだったのですが、
結論を言うとChromeテーマのアニメーション設定には限界がありできませんでした。
そこで、今回自分が試行錯誤した内容から、結局何ができて何ができないかをまとめました。
Chromeテーマのアニメーション設定については情報があまり落ちてないので、今後似たようなことにチャレンジする方の参考になれば幸いです。
なお、テーマ作成の方法については解説してくれている記事がたくさんあるので省略します。

## 検証結果

Chromeの公式ドキュメントでは、テーマに使用する画像はpng形式の必要があると記載されていますが、こちらの表現は正確ではありません。
> 画像リソースでは、拡張機能のルートからの相対パスが使用されます。どの画像もオーバーライドできます [`kPersistingImages`](https://source.chromium.org/search/?q=file:chrome/browser/themes%20symbol:kPersistingImages$) の文字列によって指定されます。すべての画像は PNG 形式で保存する必要があります 形式で入力しないと[正しくレンダリングされません](https://bugs.chromium.org/p/chromium/issues/detail?id=1200459)。

引用: https://developer.chrome.com/docs/extensions/develop/ui/themes?hl=ja
<br>
正しくは、一部項目を除き、テーマに使用する画像はpng形式の必要がある です。

具体的にはどういうことかというと、`manifest.json`に指定できる各種画像パラメータに対して、pngファイル以外を指定した際の結果を下記に示します。

| パラメータ名 | pngファイル以外の使用 |
|--|--|
| theme_frame | × |
| theme_frame_inactive | × |
| theme_frame_incognito | × |
| theme_frame_incognito_inactive | × |
| theme_toolbar | × |
| theme_tab_background | × |
| theme_tab_background_inactive | × |
| theme_tab_background_incognito | × |
| theme_tab_background_incognito_inactive | 〇※ |
| theme_ntp_background | 〇 |
| theme_frame_overlay | × |
| theme_frame_overlay_inactive | 〇※         |
| theme_button_background | 〇※ |
| theme_ntp_attribution | 〇 |
| theme_window_control_background | 〇※ |

※をつけているものは、gif画像を指定しても読み込めたものの、画面上の変化が見られなかった項目です。
これらの項目は普通のpng画像を指定した場合も効いていないみたいだったので、[実装ファイル](https://source.chromium.org/chromium/chromium/src/+/main:chrome/browser/themes/browser_theme_pack.cc?q=file:chrome%2Fbrowser%2Fthemes%20symbol:kPersistingImages$)には存在しますが現在のバージョンだと意味のない設定かもしれません。

×にしている箇所は以下の形式で検証していずれも適用できなかった項目です。

- jpg
- APNG (読み込めるが最初のコマでの静止画扱いとなる)
- gif
- webp

以上のように、`theme_ntp_background`, `theme_ntp_attribution`に関してはpngファイルだけでなく別形式の静止画ファイルやアニメーションファイルでも使用可能であることがわかりました。

## まとめ

テーマ設定のうち、アニメーション設定が効いたものはいずれも「新しいタブ」ページに関するものでした。
結局、現状はHTMLでレンダリングされている領域に対してしかアニメーションは設定できないようです。
ツールバー等にアニメーションを設定するには今後のアップデートを待つ必要がありそうです。
<img alt='' src='https://www.nxted.co.jp/blog/img/111/%E9%A0%98%E5%9F%9F.png'>
最後まで読んでいただきありがとうございます！

## 検証バージョン

Chrome: 129.0.6668.101(2024年10月時点の最新)
OS: Windows11

## 参考

- https://developer.chrome.com/docs/extensions/develop/ui/themes?hl=ja
- https://docs.google.com/document/d/199wSdt_UYuXF4Krmlc9fgaZV9yk0K6eA9y6jayc5cJY/edit?tab=t.0#heading=h.55vtfewkwlbp
- https://github.com/Patrick-Batenburg/GoogleChromeThemeCreationGuide
creatly, Music Player Sequence diagram

Music Player Sequence diagram
https://creately.com/diagram/example/hrh2sh8x3/music-player-sequence-diagram

![スクリーンショット 2025-06-04 161050.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51423/7d5ad496-873a-47e8-b58b-e10757f29cf5.png)


Edit this template
https://app.creately.com/d/pWh31ZWZBId/

![スクリーンショット 2025-06-04 154009.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51423/f4f0512f-9d91-4f8c-95ce-1aa150c5b653.png)