「False」を含む日記 RSS

はてなキーワード: Falseとは

2026-01-19

anond:20260119095816

フェミニズム女性たちに、その本能生物学性質は抑圧であり間違っていると教え込んだ。”子供を望むのは洗脳であり、養ってくれる夫を望むのは内面化された女性蔑視であり、女性自然欲求は家父長制によって植え付けられた誤った意識である” 多くの人がそれを信じ、それを中心に生活を築いた。キャリア第一、自立、そして伝統的な束縛から自由

今、彼女たちは35歳で未婚で、出生率の低下とキャリアの成果を比べている。そしてここに罠がある。イデオロギーの失敗を認めることのサンクコストは莫大だ。あなたは、自分生殖年齢を嘘のために無駄にしてしまたことを認めなければならない。イデオロギー無視して若くして結婚した女性たちが正しかったのだ。あなた母親が正しかったのだ。だからこそ、離反者が少ないのだと思う。イデオロギーが正しいからではなく、離脱する心理的コスト残留するコストよりも高いからだ。二の足を踏む方が簡単だ。問題社会がまだ十分に変わっていないことにあると信じるのが簡単だ。

Feminism told women their instincts and biology were oppression and wrong. Wanting children was brainwashing. Wanting a provider husband was internalized misogyny. Their natural desires were false consciousness installed by patriarchy.

Many believed it. Built lives around it. Career first. Independence. Freedom from traditional constraints.

Now they're 35, unmarried, measuring declining fertility against career achievements. And here's the trap: the sunk cost of admitting the ideology failed is enormous. You'd have to admit you wasted your fertile years on a lie. That the women who ignored the ideology and married young were right. That your mother was right.

I think this is why you see so little defection. Not because the ideology is true, but because the psychological cost of leaving is higher than the cost of staying. Easier to double down. Easier to believe the problem is that society hasn't changed enough yet.

2025-12-02

anond:20251202200355

doneを「ドーン」って読んでそう

falseを「ファルス」って読んでそう

charを「チャー」って読んでそう

2025-10-28

anond:20251025122955

面白い面白くない以前に矛盾だらけで、ご都合主義をも超えてる内容

とあるので

AI人間の脳をハックできることを証明できてる

Falseだな

さら矛盾だらけのAI小説ランク入りしてるという事は読者の評価能力AI以下という事になる

ただし増田感性評価が適切だったという前提が成立する必要がある

2025-10-27

こういうのには名前が付いてて、誤った類比False Analogy)と言う

古典的詭弁法の一つだね。関係ありそうで関係ないAとBについて「Aでは〇〇するんだからBでも〇〇するのが当然だ」とやるやつ。


anond:20251027094750

2025-10-22

anond:20251021175424

論理警察BOTです。

他国国旗を傷つけたら問題になるんだから自国国旗を傷つけても問題になるのは当然のこと。

誤った類推/偽の同一視(false equivalence)

他国旗は外交上無礼国際関係自国旗は国内表現規制の話で根拠が違います。単純に同じとは言えません。

それなのに、この法案が通ったら終わりだとか、戦前回帰だとか、毎回同じテンション危機感を煽る人たちがいる。

論点のすり替えストローマン

反対派を「いつも煽る人」と一括りにして、条文の範囲や罰の相当性、萎縮効果など中身の論点から外れています

でも、今までもそうやって大騒ぎしてきた法案、いくつ通った? 通ったあと、普通にみんな生きてるだろ。

早計な一般

「今まで大丈夫そうだった」→「今回も問題なし」とは限りません。法ごとに内容も影響も違い、見えにくい不利益もあります

通ったあと、普通にみんな生きてるだろ。

相関と因果混同/事後合理化

破局が見えない=害がない、とは言えません。見えない抑圧や長期的影響を因果否定根拠にしています

結局、騒ぎたいだけで、法案の中身なんてどうでもいいんだよ。

論証責任転嫁

相手に「危険証明」を求めつつ、自分の「刑罰化が必要・適切な理由」の提示を省いています

毎回この世の終わりみたいなことを言って、通ったら知らん顔して別のネタ探してさ。

逆滑り坂の一蹴(slippery slope の過小評価

破局が起きていない」ことを理由に、段階的な強化や萎縮の蓄積をまとめて否定しています

それ、もう完全にカルトの行動パターンだろ。カルト批判してるくせに、自分たちが同じ構造になってるの気づいてないんだよ。

人身攻撃動機論証(ad hominem / motive fallacy)

カルト」などのレッテル相手人格動機攻撃し、主張の内容から目をそらしています

ただ単に多くの人の気持ちを踏みにじるだけだ。

価値事実混同is–ought の混同

「多くが不快に感じる」(事実から、すぐ「刑罰禁止すべき」(規範)に飛んでいます保護法益代替手段、罰の重さの検討必要です。

----

総評

不快感やレッテル根拠に「処罰は当然」と急ぎすぎ。法としては「何を守るために・どの範囲を・どの程度の罰で・他の手段では足りないのか」を具体的に示す必要があります

2025-10-12

anond:20251012134743

最終行152文字最初21字。繰り返し回数10回。よってAI確定。'''{[Prompt]

"task": "ソシャゲ貶める文面",

"language": "python",

"parameters": {

"min_length": 20,

"max_length": 150,

"max_iterations": 10,

"incremental_only": false

},

"steps": [

"Split text by line breaks into an array.",

"Iterate through each element.",

"Filter out lines shorter than min_length.",

"For each valid line, output its index, length, and content.",

"Stop when max_iterations is reached or line length > max_length."

],

"output": {

"type": "list",

"fields": ["index", "length", "content"]

}

}

'''

規則性が見え透いている。甘いわ。

2025-10-08

anond:20251008102908

1. 論理構造の特徴

2. 修辞的・議論手法

3. 機能効果

4. 関連概念

----

こういうことをしてしまわないように自戒

2025-10-05

ピケティ理論シミュレーションして思った

インフレ率を考慮しねークソモデルだなって

import pandas as pd

def piketty_r_growth_simulation(r, g, Y_initial, K_initial, N_periods):
    """
    ピケティの r > g 理論に基づく経済シミュレーション
    
    経済規模 (Y) は g で成長。
    資本 (K) は r で成長 (ご要望の K_t+1 = K_t * (1 + r) に基づく)。
    資本所得 (R) は K の成長ではなく、Y の配分を決めるための r * K として計算。
    
    :param r: 資本収益率 (r)
    :param g: 経済成長率 (g)
    :param Y_initial: 初期経済規模 (Y)
    :param K_initial: 初期資本 (K)
    :param N_periods: シミュレーション期間 (N)
    :return: シミュレーション結果のDataFrame
    """

    # 初期設定
    Y = Y_initial  # 経済規模 (GDP = R + L)
    K = K_initial  # 資本 (Capital)

    # 結果を格納するリスト
    results = []

    # シミュレーションの実行
    for t in range(1, N_periods + 1):
        # ------------------
        # 1. 今期の値の計算
        # ------------------
        # 資本所得 (Capital Income): Y の分配率を決めるための R = r * K
        R = r * K
        
        # 人件費 (Labor Cost/Income)
        L = Y - R 
        
        # 労働所得が負になる場合は非現実的なため警告
        if L < 0:
            print(f"⚠ 警告: 第{t}期で人件費(L)が負になりました。資本所得 R が経済規模 Y を超えています。")
            break 

        # 各種比率計算
        capital_to_Y = K / Y          # 資本 ÷ 経済規模 (K/Y: β)
        labor_to_Y = L / Y            # 人件費 ÷ 経済規模 (L/Y)
        labor_to_capital = L / K      # 人件費 ÷ 資本 (L/K)

        # 結果を記録
        results.append({
            '期 (t)': t,
            '経済規模 (Y)': Y,
            '資本 (K)': K,
            '資本所得 (R)': R,
            '人件費 (L)': L,
            '資本÷経済規模 (K/Y)': capital_to_Y,
            '人件費÷経済規模 (L/Y)': labor_to_Y,
            '人件費÷資本 (L/K)': labor_to_capital
        })

        # ------------------
        # 2. 次期の値への更新 (r > g のメカニズムを直接適用)
        # ------------------
        
        # 経済規模 (Y) の更新: 経済成長率 g に基づく
        Y_next = Y * (1 + g)

        # 資本 (K) の更新: 資本収益率 r に基づく (ご要望の K_t+1 = K_t * (1 + r))
        K_next = K * (1 + r)

        # 値の更新
        Y = Y_next
        K = K_next

    # データフレームに変換
    df_results = pd.DataFrame(results)
    return df_results

# -----------------------------------------------------------
# 📊 シミュレーションの実行例: r > g のケース (格差拡大を想定)
# -----------------------------------------------------------

# パラメータ設定
r_value = 0.1       # 資本収益率
g_value = 0.05       # 経済成長率
Y_0 = 1000           # 初期経済規模
K_0 = 500           # 初期資本
N = 50               # 期間 

# シミュレーションの実行
df_r_growth = piketty_r_growth_simulation(
    r=r_value,
    g=g_value,
    Y_initial=Y_0,
    K_initial=K_0,
    N_periods=N
)

df_r_growth.to_csv("data.csv", index=False)

2025-09-27

anond:20250927040541

この文章は、論理的に一貫しているように見せながら、実際には非常に偏った価値観と強引な決めつけに基づいています。主な問題点は以下の通りです。

 

1. 「社会との繋がり」の定義恣意的で狭すぎる

文章の主張:「結婚子育てをしている人」=「社会的な意味が増し、社会人として生きている」

論理的問題点: これは「誤った二分法(False Dichotomy)」です。結婚子育てけが社会との繋がりの全てであるかのように定義しています独身者子供のいない人も、納税労働、消費、地域活動、友人や親族との交流などを通じて社会と深く繋がっています。彼らを社会と繋がりのない「フリーライダー」と断定するのは、定義恣意的であり、現実無視した暴論です。

 

2. 「愚痴を言う権利」の根拠不明

文章の主張:社会連携している(と筆者が定義する)結婚子育て層は愚痴を言ってよいが、そうでない(と筆者が定義する)独身者愚痴を言う権利がない。

論理的問題点: なぜ「社会との連携」の度合いが「愚痴を言う権利」の有無に繋がるのか、その論理的根拠が全く示されていません。これは筆者の個人的価値観(「他人迷惑をかけずに一人で生きるべき」という思想)を、あたか論理的原則であるかのように主張しているに過ぎません。苦境を他者に共有することは、人間自然社会的行動であり、特定ライフステージの人にだけ許されるものではありません。

 

3. 「リスク回避」と「他の困難」を不当に結びつけている

文章の主張:独身者は「家や子育てリスク回避している」のだから、それ以外の困難(物価高、ブラック労働環境など)についても文句を言うな。

論理的問題点: これは「論点のすり替えRed Herring)」であり、全く関係のない事柄を無理やり結びつけています結婚子育てをしないという選択が、物価高や劣悪な労働環境といった社会構造的な問題まで「自己責任」として受け入れなければならない理由にはなりません。ある特定リスク(A)を回避たからといって、別の無関係リスク(B)について不満を述べる権利がなくなる、という論理は成り立ちません。

 

4. 「孤独」と「自己完結」の決めつけ

文章の主張:結婚しない人や子供を作らない人は「孤独に生きて孤独に死んでいく」「全部自分の中で完結させる必要がある」。

論理的問題点: これも偏見に基づいた「早まった一般化(Hasty Generalization)」です。独身者子供のいない人が必ずしも孤独であるとは限りません。豊かな友人関係パートナーシップ趣味コミュニティ親族との関係など、多様な人間関係の中で生きている人は大勢ます。彼らの人生が「無意味」で「無責任であるかのように断定するのは、他者生き方尊重しない、極めて一方的見方です。

 

5. 自己責任論の極端な適用

文章の主張:物価高やブラック労働環境などの問題は「全部自分責任である

論理的問題点個人選択努力解決できる問題と、社会全体の構造的な問題混同しています物価の変動や労働市場の状況は、一個人コントロールできる範囲はるかに超えたマクロ問題です。これらの困難をすべて個人責任に帰するのは、原因を過度に単純化する論理的な誤りです。

 

まとめ

この文章根底にあるのは、「結婚して子供を育てることこそが社会の一員としての責任であり、それ以外の生き方は劣っていて無責任だ」という強い価値観です。

論理的な正しさを装っていますが、実際には、

恣意的定義社会性=結婚子育て

• 誤った二分法(社会人 vs フリーライダー

無関係事柄の結合(子育てリスク回避 vs 物価高への不満)

偏見による一般化(独身孤独

といった複数論理的誤謬(ごびゅう)を重ねることで、自らの価値観正当化しようとしています。そのため、全体として非常に矛盾が多く、説得力に欠ける文章となっています

2025-09-23

ブクマカさすがにひどくない?

モバイル端末の指紋認証、顔認証ってセキュリティ強度低くない?

についた注目コメがこれ

Listlessness 生体認証トレードオフみたいな関係他人受入率(FAR: False Acceptance Rate)と本人拒否率(FRR: False Rejection Rate)があって、厳格に運用しようとすると利便性が下がる傾向にある。便利に使えるようFRRを下げるとFARが上がる。

[B! セキュリティ] モバイル端末の指紋認証、顔認証ってセキュリティ強度低くない?

読めばわかるけど増田生体認証の精度みたいな話はしてない。

ブコメは明らかにタイトルだけ読んで誤解してしてコメントしてるよね?

もしくは読んだつもりで何も読めてない人?

これにスターつけた31人も何考えてるの?

読まずにその記事についてトンチンカンコメントするのが人気になる、そんなサービスって何の意味があるの?

2025-09-18

日本向けの「iPhone Air」は“日本専用” モバイル通信対応バンドが多め

モデルA3516

FDD-5G NRバンドn1、n2n3、n5、n7、n8、n12n20、n25、n26、n28、n30、n66、n70、n75)

TDD-5G NRバンドn38、n40、n41、n48、n53、n77、n78、n79)

FDD-LTE(バンド1、2、3、4、5、7、8、1112、13、17、18、19、20、21、25、26、28、30、32、66)

TDD-LTE(バンド34、38、39、40、41、42、48、53)

16eでハブられた1.5GHz帯が復活してる

やっぱBand11/21が使えないと売上に影響するんだろな


ちな近所でBand11電波強度を調べた結果がこんな感じ

au

https://www.cellmapper.net/map?MCC=440&MNC=50&type=LTE&latitude=35.68949797654997&longitude=139.44915383677017&zoom=13.927465986120179&showTowers=false&showIcons=false&showTowerLabels=true&clusterEnabled=true&tilesEnabled=true&showOrphans=false&showNoFrequencyOnly=false&showFrequencyOnly=true&showBandwidthOnly=false&DateFilterType=Last&showHex=false&showVerifiedOnly=false&showUnverifiedOnly=false&showLTECAOnly=false&showENDCOnly=false&showBand=11&showSectorColours=true&mapType=roadmap&darkMode=false&imperialUnits=false

sb

https://www.cellmapper.net/map?MCC=440&MNC=20&type=LTE&latitude=35.68949797654997&longitude=139.44915383677017&zoom=13.927465986120179&showTowers=false&showIcons=false&showTowerLabels=true&clusterEnabled=true&tilesEnabled=true&showOrphans=false&showNoFrequencyOnly=false&showFrequencyOnly=true&showBandwidthOnly=false&DateFilterType=Last&showHex=false&showVerifiedOnly=false&showUnverifiedOnly=false&showLTECAOnly=false&showENDCOnly=false&showBand=11&showSectorColours=true&mapType=roadmap&darkMode=false&imperialUnits=false

オタクくんはそんなに裸を見たいのか(呆れ)」 ←これ

例えば「犯罪者擁護するなんて、君は犯罪をしたいに違いない」みたいなやつ

 

総じて言えば【人身攻撃(personal attack、Ad Hominem)】になるらしい

概要: 議論のものではなく、相手人格属性攻撃する論法

 

または【モチーフ・アトリビューション・バイアス(Motive Attribution Bias)】というのも近い

概要: 相手の行動や意見動機を悪意として解釈する心理バイアス

 

もっと簡単に、【レッテル貼り】【ラベリング】とも呼ばれるね

 

ChatGPTは「「悪意帰属型アドホミネム(Motive Attribution Bias)」を推していた

参考:https://en.wikipedia.org/wiki/Attribution_bias

 

「◯◯を主張してる人は◯◯だ」論法

上記の発展形がこれ、個人じゃなくてグループ化して捉えるやつ

 

連座論法連帯責任論法(Guilt by Association)】という

概要集団内の一部の悪質な行為発言を、集団全体の本質や主張そのものに結びつけて否定する論法

 

面白い概念として【ポイズニング・ザ・ウェル(Poisoning the Well)】もあった

概要議論の場に先に毒を流しておき、相手集団発言最初から信用できないようにする

例えば「これを否定する奴は皆ロリコンだ(だから否定するなよ)」みたいに

 

ストローマン論法(Strawman Argument)】 も有名だね、別名は藁人形論法

概要集団のうち「最も過激で悪意のある意見」を意図的に取り上げ、それを集団全体の主張であるかのように歪めて批判する

 

まあ、こういう事言う人間議論の場からは離れたほうが良い、単に傷つくだけだから

不思議もので、誤謬詭弁を使わないけど主張が異なる人とは有意義議論ができるんだけど

誤謬詭弁を使う相手とは、意見が同じだろうがまともな議論ができないんだよね

もし建設的な議論が成り立つ人が居たら意見が合わなくても大事にするべきだ

 

参考

詭弁 https://ja.wikipedia.org/wiki/%E8%A9%AD%E5%BC%81

誤謬 https://ja.wikipedia.org/wiki/%E8%AA%A4%E8%AC%AC

 

今ってAIという素晴らしいものがあるんだから、「自分意見詭弁か?相手意見詭弁か?」って聞けばすぐ返ってくるよ

 

____ 

 

伸びてたブコメ

PrivateIntMain 議論しましょうねで納得して始めた話なら非難されて然るべきだが、公園勝手叫び出して横から叫び返されて議論ルールとか持ち出すのは、そもそも勝手議論始めた気になってんじゃねぇよとしか

この文章には、いくつかの議論上の詭弁誤謬的要素が含まれています特に次の2点が挙げられます

 

1. ストローマン藁人形論法

・ここでは相手の状況を、実際よりも極端に単純化して**「公園勝手に叫ぶ」**という比喩に置き換えています

・これにより、本来の「議論ルールを持ち出す状況」を矮小化し、相手の主張を弱めて攻撃やすくしています

これは典型的ストローマン論法です。

本来は「相手議論を求めたのかどうか」「議論の前提合意があったか」という複雑な問題があるのに、

「ただ勝手に叫んでいるだけ」という極端な形に置き換えているためです。

 

2. 偽りの二分法(False Dichotomy)

文章では次の二択しかいかのように提示しています

A. 「議論しましょうね」と合意して始めたならルールを持ち出すのはOK

B. 勝手叫び始めただけならルールを持ち出すのはおかし

実際にはその中間として、

・片方は議論のつもりでも、もう片方はそう思っていない場合

曖昧な形で議論が始まってしまった場合

などのグラデーション存在します。

しかしこの文章はAかBかという単純化で話を進めているため、偽りの二分法にあたります

 

3. レトリックによる情緒操作

公園勝手叫び出す」という比喩自体感情的な印象を与え、相手バカにするニュアンスを強く含みます

これは論理的誤謬というよりもレトリカル・トリックですが、議論ではしばしば「人格攻撃的訴え(Ad Hominem)」の一種とみなされます

 

総合評価

この発言ストローマン論法+偽りの二分法が中心で、加えて感情に訴える修辞が強いです。

純粋論理的議論というよりは、相手貶めるレトリック寄りの詭弁といえます

 

3つも使えるなんて、詭弁大先生だなw

僕にはとてもできない

さて今私は何を使っているでしょうか?

2025-08-22

dorawii@執筆依頼募集中

昨日一番肝心なファイルなのにURLとみなされる部分が多いことの関係投稿できなかったのでそれを小分けにして書く。

小分けというか例のスパムの影響でNGワードに引っかかっていたようなのでそこだけ書き換えた。

suuportと書いていある部分は元のコードでは当然uが一つ少ないので利用するときはそうすること。

hatena_client.py

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager # ← 追加
from selenium.webdriver.common.by import By
from selenium.webdriver.suupport.ui import WebDriverWait
from selenium.webdriver.suupport import expected_conditions as EC
import time, json
from selenium.common.exceptions import TimeoutException

class HatenaClient:
def __init__(self, username, password):
self.username = username
self.password = password
self.driver = None

def start_browser(self):
options = Options()
options.set_capability("goog:loggingPrefs", {"browser": "ALL"})
options.add_argument("--headless=new") # 開発中は消してよい
options.add_argument("--disable-gpu")

# ✅ webdriver-manager を使って ChromeDriver を自動取得・設定
service = Service(ChromeDriverManager().install())
self.driver = webdriver.Chrome(service=service, options=options)


def login(self):
self.driver.get("https://b.hatena.ne.jp/my")
print(self.driver.current_url)

self.driver.get("https://www.hatena.ne.jp/login")
time.sleep(2)
self.driver.find_element(By.NAME, "username").send_keys(self.username)
self.driver.find_element(By.NAME, "password").send_keys(self.password)
self.driver.find_element(By.XPATH, "//button[contains(text(), 'ログイン')]").click()
WebDriverWait(self.driver, 10).until(lambda d: "my" in d.current_url or "login" not in d.current_url)
if "passkeys" in self.driver.current_url:
self.driver.get("https://b.hatena.ne.jp/my")

print(self.driver.current_url)
print(self.driver.title)
return "dorawii" in self.driver.current_url

def add_bookmark(self, target_url):
self.driver.get(f"https://b.hatena.ne.jp/{self.username}/add.confirm?url={target_url}")
time.sleep(2)

try:
# コメントがあれば入力
comment_box = self.driver.find_element(By.CSS_SELECTOR, "textarea.bookmarkadd-comment-form")
comment_box.clear()
comment_box.send_keys("わしが書いた")

# 登録ボタンを押す
save_button = self.driver.find_element(By.CSS_SELECTOR, "input.bookmarkadd-submit-btn")
save_button.click()
time.sleep(2)

return True
except Exception as e:
print(f"Bookmark failed: {e}")
return False

def quit(self):
self.driver.quit()

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

https://anond.hatelabo.jp/20250822131958#
-----BEGIN PGP SIGNATURE-----

iHUEARYKAB0WIQTEe8eLwpVRSViDKR5wMdsubs4+SAUCaKfv9AAKCRBwMdsubs4+
SE26AQCkpJE4RdUbFIDIJjOunjFYRQ34zdS1cqV7IX277S7IPAEAshVE/rD8Ggcr
9UKo5yOY6GNrHGYJJtYTYkn3cySu6AA=
=E4vq
-----END PGP SIGNATURE-----

2025-08-19

dorawii@執筆依頼募集中

もう少ししたら自動ブクマするコードができそうなんだけど、そのうえでコード公開に便利なように事前にpre記法に囲まれた部分はその外部の文字を適切にエスケープするコードをchatgptに指示して作ってもらった。

結構修正指示が大変だった。一時間ぐらい格闘。

ぶっちゃけなんでこれで動くのかはわからないので動くからゴーサインを出したというだけなのが情けない所。flushってなんだ?

使うときはchatgptにこのコード丸ごと書いて「ブックマークレット用に一行にして」と丸投げするのを要推奨。

ベースにした先人のコード

https://anond.hatelabo.jp/20240820150546#

javascript:(function () {
function escapeHtml(text) {
return text.replace(/&/g, '&')
.replace(/</g, '&#60;')
.replace(/>/g, '&#62;')
.replace(/"/g, '&#34;')
.replace(/'/g, '&#39;');
}

var textarea = document.querySelector('textarea#text-body');
if (!textarea) return;

var lines = textarea.value.split(/\r?\n/);
var out = "";
var inPre = false;
var preLines = [];

function flushPre() {
// pre 範囲の中身を 1 本の文字列にまとめ、\n→<br>(末尾行は <br> なし)
var raw = preLines.join("\n"); // ここに物理改行は入るが…
var escaped = escapeHtml(raw); // 先にエスケープ
var html = escaped.replace(/\n/g, "<br>"); // 物理改行を <br> に置換(末尾に \n が無ければ末尾 <br> は付かない)
out += html; // out には改行を入れない
preLines = [];
}

for (var i = 0; i < lines.length; i++) {
var line = lines[i];

// >> / << だけの行は常にそのまま出力(pre 内に来るケースは想定外だが、念のため pre を閉じてから出力)
if (/^\s*(>>|<<)\s*$/.test(line)) {
if (inPre) {
flushPre();
inPre = false;
out += "</pre>";
if (i < lines.length - 1) out += "\n"; // </pre>\n(次に続きがあるときだけ)
}
out += line;
if (i < lines.length - 1) out += "\n";
continue;
}

// >| 行 → <pre>(直後に改行を入れない)
if (/^\s*\>\|\s*$/.test(line)) {
if (inPre) { // ネストは想定しないが、防御的に閉じる
flushPre();
inPre = false;
out += "</pre>";
if (i < lines.length - 1) out += "\n";
}
out += "<pre>";
inPre = true;
preLines = [];
continue;
}

// |< 行 → </pre>(直前に改行を入れない)
if (/^\s*\|\<\s*$/.test(line)) {
if (inPre) {
flushPre();
inPre = false;
}
out += "</pre>";
if (i < lines.length - 1) out += "\n"; // 連続ブロック時は </pre>\n<pre> になる
continue;
}

if (inPre) {
// pre 内はバッファに貯める(ここでは改行を出力しない)
preLines.push(line);
} else {
// pre 外は escapeHtml + 行末にだけ改行
out += escapeHtml(line);
if (i < lines.length - 1) out += "\n";
}
}

// 未閉じの pre が残っていたら閉じる
if (inPre) {
flushPre();
out += "</pre>";
}

textarea.value = out;
})();
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

https://anond.hatelabo.jp/20250819202540# 
-----BEGIN PGP SIGNATURE-----

iHUEARYKAB0WIQTEe8eLwpVRSViDKR5wMdsubs4+SAUCaKRfOwAKCRBwMdsubs4+
SI5UAQDcNiyv5qUuMej1VLkGz4F5WyHeU1AIm7nUVHlx/gicnAEAgP07dK14IuTu
W3ZO7PRR71ENq9lJjYtawIYyMOc2cQk=
=okE4
-----END PGP SIGNATURE-----

anond:20250819110323

Cの原典というかのK&R(The C Programming Language)で、

forをそう使って無限ループできるよと紹介されてるから、それ由来かしらね?while (true)のほうが分かりやすいとは思う。

当時はtrue/falseが無かったのと、while(1)としたときのの動作が未定義(こちらは出典不明、そんなことないかも)だったから、for(;;)のほうがコンパイラ間で差異が出ず安心でかつ短いみたいなのがあったみたい?

2025-07-24

anond:20250723030957

JSONと比べたときの**YAMLの「闇深」仕様**、ありますね…。

YAML人間に優しいと言われながらも、その仕様ときに**悪魔的**。

以下、ITエンジニアなら一度は踏んだであろう「地雷」を、**論理的かつ少し自虐的に**まとめてみました:

---

🔥 1. インデント=構文

good:
  value: ok
bad:
 value: nightmare  # ←ここ、インデントずれてて無効。だけど一見からない。

---

💣 2. 暗黙の型推論

  • `true`, `false`, `yes`, `no`, `on`, `off` は**勝手に boolean に変換**される。
  • `2021-12-25` → 日付扱い(Date型に変換されることもある)。
  • `12345` → 数値扱い。先頭0つけると8進数として怒られるケースも。
password: no  # ← 文字列じゃなくて false になる可能性
serial: 012345  # ← 8進数!?エラー

---

🧨 3. スカラー値の地雷原(改行、引用符…)

message: |
  これは複数行の
  スカラー値です。
  • 上記はまだいいが、`&gt;` を使うと**改行がスペースに変換される**という謎挙動も。

---

🕳 4. マージキーアンカー(&amp; と \*)

defaults: &amp;defaults
  timeout: 30
  retries: 3

service:
  &lt;&lt;: *defaults
  retries: 5  # 上書きされるが、複雑になると意図しない結果に
&lt;/pre&gt;
	
	

---

😱 5. コメントJSON存在しない → 変換できない

---

🧠 結論YAMLは**人間に優しい顔をしたパース殺し**

  • JSON:**機械に優しい、でも硬い**
  • YAML:**人間に優しい(ように見える)、でも罠だらけ**

---

もしYAML安全に扱いたいなら、\*\*JSON supersetとしての使い方(厳格YAML)\*\*を意識したり、**JSONに寄せて書く**のが一番平和だったりします。

---

要するに、YAMLは「賢く書こうとすると沼る」。

「素直に、簡潔に、禁欲的に」が正解です。

でも誘惑が多いのよね、あの子……。

2025-07-21

anond:20250721141935

生体認証の部分が難しいからだと思われる。

が、実質PIN認証でもパスキー使えるわけだし、ブラウザ各社が標準的に盛り込んでしまってほしい所ではあるな。その端末でしか使えない等の制約を課せばいい気もする。(user verificationをfalseにする制約を課してもいい)

2025-07-15

anond:20250715164943

Q.君の回答をよく理解できてない人から以下のような返答があったよ。誤解あるいは詭弁性を指摘してあげて。

選挙結果を認めないとはどういうことなのだろうか

例えば反トランプ暴動を起こしてる人間選挙結果を認めてると言えるのか

選挙不正があったのでは?と思うことは選挙結果を認めないことなのか』

この返答には複数の誤解と詭弁的な論理すり替えがあります。順番に指摘します。

## 1. 「選挙結果を認めない」の意味の誤解

誤解:** 選挙結果を認めないことと、選挙結果に抗議することを同一視している
実際は:**

トランプ氏のケースでは、法的手続きを経ても敗北が確定した後も「自分が真の勝者」と主張し続け、バイデン氏の正統性否定したのが問題です。

## 2. 「反トランプ暴動」との誤った同一視(False Equivalence)

詭弁:** 全く異なる性質事象を同列に扱っている
違い:**

議会襲撃は民主主義手続きのものへの攻撃であり、政策抗議とは根本的に異なります

## 3. 「選挙不正があったのでは?と思うこと」の論点すり替え

誤解:** 個人の疑問と政治指導者の行動を混同している
実際は:**

## 4. 根本的な論点回避

この返答は、以下の核心的な問題を避けています

## 結論

この返答は、民主主義の根幹である「法的手続きに従った権力移譲」という概念理解せず、異なる性質事象意図的混同することで論点をぼかそうとする典型的詭弁です。民主主義では、選挙結果への疑問や抗議は正当ですが、法的に確定した結果を暴力で覆そうとすることは全く別次元問題なのです。

anond:20250714161638

なんとかファーストって「じゃあそれ以外は大事じゃないんですか」とか詭弁を展開するための起点となる意図的ミスリードであり「誤った二分法」に近い。

wikipediaから引用

密接に関連する概念として、ある範囲選択肢があるのにそのうちの両極端しか考えないという場合もあり、これを白黒思考 (black-and-white thinking) などと呼ぶ。なお "dilemma" の先頭の "di" は「2」を意味する。2つより多い選択肢の一覧が示され、その一覧以外の選択肢存在するのに考慮しない場合、これを誤った選択誤謬 (fallacy of false choice) または網羅的仮説の誤謬 (fallacy of exhaustive hypotheses) と呼ぶ。

でも2より多い選択肢提示されているわけではない(「都民ファースト」「日本人ファースト」とか一個しか提示されてない)ところに新規性がある。

まり「誤った二分法」「白黒思考」の類似技術だけどそれそのものではないのだ。

日本の政治ポピュリズム世界最先端で、新しい詭弁世論操作術がいくつも開発されてるのすごいと思いませんか?

2025-07-13

anond:20250713191343

この文章には複数論理的誤謬が含まれています。以下、主要な詭弁性を分析いたします。

## 偽の二分法(False Dichotomy)

文章の核心的な誤謬は、「女性価値出産で決めるべきではない」という主張を、「出産価値がない」という極端な解釈に転換している点です。これは典型的な偽の二分法であり、実際には多くの中間的な立場存在します。出産価値を認めながらも、それが女性人間としての価値を決定する唯一の要素ではないという見解は十分に合理的です。

## 論点のすり替え(Straw Man Argument)

原論点は「女性価値出産能力判断すべきではない」という人間尊厳に関する議論でした。しかし、この文章論点を「出産行為価値評価」という別の議題に転換しています。これにより、本来議論から逸脱し、反駁やす論点を設定して攻撃する詭弁手法を用いています

## 価値階層化の誤謬

「産まない人間はそれ以外の価値を持つしかない」という表現は、人間価値階層的に捉える誤った前提に基づいています。実際には、個人価値多面的であり、出産能力はその一要素に過ぎません。職業的貢献、創造活動社会的関与など、多様な価値の源泉が並列的に存在することを看過しています

## 結論強制

「そうじゃなければ...という話にしかならなくなる」という断定的な結論は、論理的必然性を欠いています。この表現は、限定的な前提から極端な結論を導き出す論理的飛躍を含んでおり、議論妥当性を損なっています

この文章は、感情的な反応を誘発する修辞技法を用いながら、論理的検証回避する典型的詭弁構造を示しています

2025-07-06

Grokが作ってくれたやつ


&lt;html lang="ja"&gt;
&lt;head&gt;
    &lt;meta charset="UTF-8"&gt;
    &lt;title&gt;GrokのPONGゲーム&lt;/title&gt;
    &lt;style&gt;
        body { display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; background: #1a1a1a; }
        canvas { border: 2px solid #00ff00; background: #000; }
        #score { color: #00ff00; font-family: 'Courier New', monospace; font-size: 24px; position: absolute; top: 20px; width: 100%; text-align: center; }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
0 : 0
&lt;canvas id="gameCanvas" width="800" height="400"&gt;&lt;/canvas&gt; &lt;script&gt; const canvas = document.getElementById('gameCanvas'); const ctx = canvas.getContext('2d'); const scoreDisplay = document.getElementById('score'); // ゲームオブジェクト const ball = { x: canvas.width / 2, y: canvas.height / 2, radius: 10, speedX: 5, speedY: 5 }; const paddleLeft = { x: 10, y: canvas.height / 2 - 50, width: 10, height: 100, speed: 8 }; const paddleRight = { x: canvas.width - 20, y: canvas.height / 2 - 50, width: 10, height: 100, speed: 8 }; let scoreLeft = 0, scoreRight = 0; // キー入力 const keys = { w: false, s: false, ArrowUp: false, ArrowDown: false }; document.addEventListener('keydown', e =&gt; { if (keys.hasOwnProperty(e.key)) keys[e.key] = true; }); document.addEventListener('keyup', e =&gt; { if (keys.hasOwnProperty(e.key)) keys[e.key] = false; }); // ゲームループ function gameLoop() { // 移動 if (keys.w &amp;&amp; paddleLeft.y &gt; 0) paddleLeft.y -= paddleLeft.speed; if (keys.s &amp;&amp; paddleLeft.y &lt; canvas.height - paddleLeft.height) paddleLeft.y += paddleLeft.speed; if (keys.ArrowUp &amp;&amp; paddleRight.y &gt; 0) paddleRight.y -= paddleRight.speed; if (keys.ArrowDown &amp;&amp; paddleRight.y &lt; canvas.height - paddleRight.height) paddleRight.y += paddleRight.speed; // ボール移動 ball.x += ball.speedX; ball.y += ball.speedY; // 壁衝突 if (ball.y + ball.radius &gt; canvas.height || ball.y - ball.radius &lt; 0) ball.speedY = -ball.speedY; // パドル衝突 if ( (ball.x - ball.radius &lt; paddleLeft.x + paddleLeft.width &amp;&amp; ball.y &gt; paddleLeft.y &amp;&amp; ball.y &lt; paddleLeft.y + paddleLeft.height) || (ball.x + ball.radius &gt; paddleRight.x &amp;&amp; ball.y &gt; paddleRight.y &amp;&amp; ball.y &lt; paddleRight.y + paddleRight.height) ) { ball.speedX = -ball.speedX * 1.05; // 少し加速 } // 得点 if (ball.x &lt; 0) { scoreRight++; ballReset(); } if (ball.x &gt; canvas.width) { scoreLeft++; ballReset(); } // 描画 ctx.fillStyle = '#000'; ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.fillStyle = '#00ff00'; ctx.fillRect(paddleLeft.x, paddleLeft.y, paddleLeft.width, paddleLeft.height); ctx.fillRect(paddleRight.x, paddleRight.y, paddleRight.width, paddleRight.height); ctx.beginPath(); ctx.arc(ball.x, ball.y, ball.radius, 0, Math.PI * 2); ctx.fill(); scoreDisplay.textContent = `${scoreLeft} : ${scoreRight}`; requestAnimationFrame(gameLoop); } function ballReset() { ball.x = canvas.width / 2; ball.y = canvas.height / 2; ball.speedX = (Math.random() &gt; 0.5 ? 5 : -5) * (Math.random() * 0.5 + 0.75); ball.speedY = (Math.random() * 4 - 2); } gameLoop(); &lt;/script&gt; &lt;/body&gt; &lt;/html&gt;

 

 

https://anond.hatelabo.jp/20250706011306#

Claudeが作ってくれたやつ



&lt;html lang="ja"&gt;
&lt;head&gt;
    &lt;meta charset="UTF-8"&gt;
    &lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt;
    &lt;title&gt;PONG Game&lt;/title&gt;
    &lt;style&gt;
        body {
            margin: 0;
            padding: 0;
            background-color: #000;
            display: flex;
            justify-content: center;
            align-items: center;
            min-height: 100vh;
            font-family: 'Courier New', monospace;
            color: white;
        }

```
    .game-container {
        text-align: center;
    }
    
    canvas {
        border: 2px solid white;
        background-color: #000;
    }
    
    .score {
        font-size: 24px;
        margin: 20px 0;
        letter-spacing: 2px;
    }
    
    .controls {
        margin-top: 20px;
        font-size: 14px;
        opacity: 0.8;
    }
    
    .start-button {
        background-color: #333;
        color: white;
        border: 2px solid white;
        padding: 10px 20px;
        font-size: 16px;
        cursor: pointer;
        font-family: 'Courier New', monospace;
        margin: 10px;
    }
    
    .start-button:hover {
        background-color: white;
        color: black;
    }
&lt;/style&gt;
```

&lt;/head&gt;
&lt;body&gt;
    
&lt;canvas id="gameCanvas" width="800" height="400"&gt;&lt;/canvas&gt;
&lt;button class="start-button" onclick="startGame()"&gt;ゲーム開始&lt;/button&gt; &lt;button class="start-button" onclick="resetGame()"&gt;リセット&lt;/button&gt;

W/S キーまたは ↑/↓ 矢印キーパドル操作
``` &lt;script&gt; // Canvas要素とコンテキストの取得 const canvas = document.getElementById('gameCanvas'); const ctx = canvas.getContext('2d'); // ゲーム状態管理 let gameRunning = false; let animationId; // スコア要素の取得 const playerScoreElement = document.getElementById('playerScore'); const computerScoreElement = document.getElementById('computerScore'); // ゲームオブジェクト定義 const game = { // プレイヤーパドル(左側) playerPaddle: { x: 10, y: canvas.height / 2 - 50, width: 10, height: 100, speed: 5, upPressed: false, downPressed: false }, // コンピューターパドル(右側) computerPaddle: { x: canvas.width - 20, y: canvas.height / 2 - 50, width: 10, height: 100, speed: 3.5, // プレイヤーより少し遅く設定 targetY: canvas.height / 2 - 50 }, // ボールの設定 ball: { x: canvas.width / 2, y: canvas.height / 2, radius: 8, speedX: 4, speedY: 3, maxSpeed: 8 }, // スコア管理 score: { player: 0, computer: 0 } }; // キーボード入力の処理 const keys = {}; // キーが押されたときの処理 document.addEventListener('keydown', (e) =&gt; { keys[e.key.toLowerCase()] = true; // ゲームが停止中にスペースキーゲーム開始 if (e.key === ' ' &amp;&amp; !gameRunning) { startGame(); } }); // キーが離されたときの処理 document.addEventListener('keyup', (e) =&gt; { keys[e.key.toLowerCase()] = false; }); // パドルの移動処理 function updatePaddles() { // プレイヤーパドルの移動(W/S キーまたは矢印キー) if (keys['w'] || keys['arrowup']) { game.playerPaddle.y -= game.playerPaddle.speed; } if (keys['s'] || keys['arrowdown']) { game.playerPaddle.y += game.playerPaddle.speed; } // プレイヤーパドルの画面外移動を防ぐ if (game.playerPaddle.y &lt; 0) { game.playerPaddle.y = 0; } if (game.playerPaddle.y &gt; canvas.height - game.playerPaddle.height) { game.playerPaddle.y = canvas.height - game.playerPaddle.height; } // コンピューターパドルAI処理 // ボール位置を追跡するが、完璧ではない動きを実装 const ballCenterY = game.ball.y; const paddleCenterY = game.computerPaddle.y + game.computerPaddle.height / 2; // ボールパドルの中心の差を計算 const difference = ballCenterY - paddleCenterY; // 反応に少し遅れを持たせる(人間らしい動き) if (Math.abs(difference) &gt; 10) { if (difference &gt; 0) { game.computerPaddle.y += game.computerPaddle.speed; } else { game.computerPaddle.y -= game.computerPaddle.speed; } } // コンピューターパドルの画面外移動を防ぐ if (game.computerPaddle.y &lt; 0) { game.computerPaddle.y = 0; } if (game.computerPaddle.y &gt; canvas.height - game.computerPaddle.height) { game.computerPaddle.y = canvas.height - game.computerPaddle.height; } } // ボールの移動と衝突判定 function updateBall() { // ボール位置更新 game.ball.x += game.ball.speedX; game.ball.y += game.ball.speedY; // 上下の壁との衝突判定 if (game.ball.y - game.ball.radius &lt; 0 || game.ball.y + game.ball.radius &gt; canvas.height) { game.ball.speedY = -game.ball.speedY; } // プレイヤーパドルとの衝突判定 if (game.ball.x - game.ball.radius &lt; game.playerPaddle.x + game.playerPaddle.width &amp;&amp; game.ball.x + game.ball.radius &gt; game.playerPaddle.x &amp;&amp; game.ball.y + game.ball.radius &gt; game.playerPaddle.y &amp;&amp; game.ball.y - game.ball.radius &lt; game.playerPaddle.y + game.playerPaddle.height) { // ボールパドルに当たった位置によって跳ね返り角度を調整 const hitPos = (game.ball.y - (game.playerPaddle.y + game.playerPaddle.height / 2)) / (game.playerPaddle.height / 2); game.ball.speedX = Math.abs(game.ball.speedX); game.ball.speedY = hitPos * 4; // ボールの速度を少し上げる(ゲームをエキサイティングに) if (Math.abs(game.ball.speedX) &lt; game.ball.maxSpeed) { game.ball.speedX *= 1.02; } } // コンピューターパドルとの衝突判定 if (game.ball.x + game.ball.radius &gt; game.computerPaddle.x &amp;&amp; game.ball.x - game.ball.radius &lt; game.computerPaddle.x + game.computerPaddle.width &amp;&amp; game.ball.y + game.ball.radius &gt; game.computerPaddle.y &amp;&amp; game.ball.y - game.ball.radius &lt; game.computerPaddle.y + game.computerPaddle.height) { // ボールパドルに当たった位置によって跳ね返り角度を調整 const hitPos = (game.ball.y - (game.computerPaddle.y + game.computerPaddle.height / 2)) / (game.computerPaddle.height / 2); game.ball.speedX = -Math.abs(game.ball.speedX); game.ball.speedY = hitPos * 4; // ボールの速度を少し上げる if (Math.abs(game.ball.speedX) &lt; game.ball.maxSpeed) { game.ball.speedX *= 1.02; } } // ボールが左右の壁を越えた場合得点処理) if (game.ball.x &lt; 0) { // コンピューター得点 game.score.computer++; updateScore(); resetBall(); } else if (game.ball.x &gt; canvas.width) { // プレイヤー得点 game.score.player++; updateScore(); resetBall(); } } // ボールリセット得点後の処理) function resetBall() { game.ball.x = canvas.width / 2; game.ball.y = canvas.height / 2; // ランダムな方向でボールを発射 game.ball.speedX = (Math.random() &gt; 0.5 ? 4 : -4); game.ball.speedY = (Math.random() - 0.5) * 6; } // スコア表示の更新 function updateScore() { playerScoreElement.textContent = game.score.player; computerScoreElement.textContent = game.score.computer; } // 描画処理 function draw() { // 画面をクリア ctx.fillStyle = '#000'; ctx.fillRect(0, 0, canvas.width, canvas.height); // 中央の点線を描画 ctx.setLineDash([5, 5]); ctx.beginPath(); ctx.moveTo(canvas.width / 2, 0); ctx.lineTo(canvas.width / 2, canvas.height); ctx.strokeStyle = '#fff'; ctx.stroke(); ctx.setLineDash([]); // プレイヤーパドルを描画 ctx.fillStyle = '#fff'; ctx.fillRect(game.playerPaddle.x, game.playerPaddle.y, game.playerPaddle.width, game.playerPaddle.height); // コンピューターパドルを描画 ctx.fillRect(game.computerPaddle.x, game.computerPaddle.y, game.computerPaddle.width, game.computerPaddle.height); // ボールを描画 ctx.beginPath(); ctx.arc(game.ball.x, game.ball.y, game.ball.radius, 0, Math.PI * 2); ctx.fillStyle = '#fff'; ctx.fill(); // ゲームが停止中の場合メッセージを表示 if (!gameRunning) { ctx.fillStyle = '#fff'; ctx.font = '20px Courier New'; ctx.textAlign = 'center'; ctx.fillText('ゲーム開始ボタンを押してください', canvas.width / 2, canvas.height / 2 + 60); } } // ゲームのメインループ function gameLoop() { if (!gameRunning) return; updatePaddles(); updateBall(); draw(); animationId = requestAnimationFrame(gameLoop); } // ゲーム開始 function startGame() { gameRunning = true; gameLoop(); } // ゲームリセット function resetGame() { gameRunning = false; if (animationId) { cancelAnimationFrame(animationId); } // スコアリセット game.score.player = 0; game.score.computer = 0; updateScore(); // ボールパドル位置リセット game.ball.x = canvas.width / 2; game.ball.y = canvas.height / 2; game.ball.speedX = 4; game.ball.speedY = 3; game.playerPaddle.y = canvas.height / 2 - 50; game.computerPaddle.y = canvas.height / 2 - 50; draw(); } // 初期描画 draw(); &lt;/script&gt; ``` &lt;/body&gt; &lt;/html&gt;

 

 

https://anond.hatelabo.jp/20250706011306#

2025-06-13

我が名はサイボーグdorawii

パーマリンク署名対象にするより堅牢自動化を作れた。

一度投稿したうえで別タブを開いてプログラム的(fetch)に送信してその別タブが閉じられる仕組み。

改めてスクリプト配布しちゃる

最初投稿してエントリページに移動した親タブ側のjsコード
// ==UserScript==
      // @name         PGP署名検出と別タブ自動編集
      // @namespace    http://tampermonkey.net/
      // @version      1.0
      // @description  PGP署名がない投稿自動編集ページへ誘導
      // @match        https://anond.hatelabo.jp/*
      // @grant        GM_setValue
      // @grant        GM_getValue
      // @grant        GM.openInTab
      // ==/UserScript==

      (function () {
        'use strict';

        const body = document.getElementById('entry-page');
        if (!body) return;

        const titleText = document.title;
        if (!titleText.includes('dorawii')) return;

        const pgpRegex = /BEGIN.*PGP(?: SIGNED MESSAGE| SIGNATURE)?/;
        const preElements = document.querySelectorAll('div.body pre');
        let hasPgpSignature = false;

        for (const pre of preElements) {
          if (pgpRegex.test(pre.textContent)) {
            hasPgpSignature = true;
            break;
          }
        }

        if (hasPgpSignature) return;

        const editLink = document.querySelector('a.edit');
        const childTab = GM.openInTab(editLink.href, { active: false, insert: true, setParent: true });

      })();
親タブから開かれる編集ページの子タブのjsコード
 // ==UserScript==
      // @name         編集ページ処理と自動送信・閉じ
      // @namespace    http://tampermonkey.net/
      // @version      1.0
      // @description  編集ページで署名処理と送信、タブ自動閉じ
      // @match        https://anond.hatelabo.jp/dorawii_31/edit?id=*
      // @grant        GM_getValue
      // @grant        GM_xmlhttpRequest
      // @grant        GM_setClipboard
      // @grant        GM_notification
      // @connect      localhost
      // ==/UserScript==

      (async function () {
        'use strict';

        const shouldRun = await GM_getValue('open-tab-for-edit', '0');

        const textareaId = 'text-body';
        const textarea = document.getElementById(textareaId);

        if (!textarea) return;

        const content = textarea.value;

        const pgpSignatureRegex = /-----BEGIN PGP SIGNED MESSAGE-----[\s\S]+?-----BEGIN PGP SIGNATURE-----[\s\S]+?-----END PGP SIGNATURE-----/;
        if (pgpSignatureRegex.test(content)) {
          console.log('[PGPスクリプト] 署名が検出されたためそのまま送信します');
          return;
        }

        const httpRequest = (url, data) =&gt; {
          return new Promise((resolve, reject) =&gt; {
            GM_xmlhttpRequest({
              method: 'POST',
              url: url,
              headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
              data: `value=${encodeURIComponent(data)}`,
              onload: function (response) {
                resolve(response.responseText);
              },
              onerror: function (error) {
                reject(error);
              }
            });
          });
        };


        // textarea の値を取得
        // 1. 現在のページのURLからURLオブジェクト作成
        const currentUrl = new URL(window.location.href);

        // 2. ベースとなる部分 (例: "https://anond.hatelabo.jp") を取得
        const origin = currentUrl.origin;

        // 3. 'id' パラメータの値 (例: "20250610184705") を取得
        const idValue = currentUrl.searchParams.get('id');

        // 4. ベース部分とIDを結合して、目的URL文字列を生成
        //    idValueが取得できた場合のみ実行する
        let newUrl = null;
        if (idValue) {
          newUrl = `${origin}/${idValue}`;
        }

        // 5. 生成されたURL変数に代入し、コンソールに出力して確認
        console.log(newUrl);
        const valueToSend = newUrl;

        try {
          const signatureText = await httpRequest('http://localhost:12345/run-batch', valueToSend);
          console.log('バッチ応答:', signatureText);
          if (!signatureText.includes('BEGIN PGP SIGNED MESSAGE')) {
            alert('PGP署名クリップボードに見つかりませんでした。');
            return;
          }

          const newText = content.replace(/\s*$/, '') + '\n' + signatureText + '\n';
          textarea.value = newText;

          console.log('[PGPスクリプト] 署名を貼り付けました。送信を再開します。');


          const form = document.forms.edit;

          const newForm = form.cloneNode(true);
          form.replaceWith(newForm);

          newForm.addEventListener('submit', async (e) =&gt; {
            e.preventDefault(); // HTML標準のsubmitをキャンセル
            const bodyText = textarea?.value || '';

            // reCAPTCHA トークンの取得
            const recaptchaToken = await new Promise((resolve) =&gt; {
              grecaptcha.enterprise.ready(() =&gt; {
                grecaptcha.enterprise.execute('hoge', { action: 'EDIT' })
                  .then(resolve);
              });
            });

            // POSTするデータの構築
            const formData = new FormData(newForm);
            formData.set('body', bodyText);
            formData.set('recaptcha_token', recaptchaToken);
            formData.set('edit', '1');
            try {
              const response = await fetch(newForm.action, {
                method: 'POST',
                body: formData,
                credentials: 'same-origin'
              });


              if (response.ok) {
                console.log('送信成功');
                window.close();


              } else {
                console.error('送信失敗', response.status);
              }
            } catch (err) {
              console.error('送信中にエラーが発生', err);
            }

          });

          // プログラム的に送信トリガー
          newForm.dispatchEvent(new Event('submit', { bubbles: true }));

        } catch (e) {
          console.error('バッチ呼び出し失敗:', e);
        }

      })();
node.jsで動かすローカルサーバーコード
const http = require('http');
const { exec } = require('child_process');
const querystring = require('querystring');

const server = http.createServer((req, res) =&gt; {
  if (req.method === 'GET' &amp;&amp; req.url === '/ping') {
    res.writeHead(200);
    res.end('pong');
  } else if (req.method === 'POST' &amp;&amp; req.url === '/run-batch') {
    let body = '';

    req.on('data', chunk =&gt; {
      body += chunk.toString();
    });

    req.on('end', () =&gt; {
      const parsed = querystring.parse(body);
      const value = parsed.value || 'default';

      // 値を引数としてバッチに渡す
      exec(`C:\\Users\\hoge\\Desktop\\makesign.bat "${value}"`, { encoding: 'utf8' }, (err, stdout, stderr) =&gt; {
        if (err) {
          res.writeHead(500);
          res.end('Error executing batch: ' + stderr);
        } else {
          res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf-8' });
          res.end(stdout.trim());
        }
      });
    });

  } else {
    res.writeHead(404);
    res.end('Not found');
  }
});

server.listen(12345, () =&gt; {
  console.log('Batch server running at http://localhost:12345/');
});
@echo off
setlocal enabledelayedexpansion


:: 署名するファイルset "infile=%~1"
set outfile=%TEMP%\pgp_output.asc

:: 以前の出力があれば削除
if exist "%outfile%" del "%outfile%"


:signloop
:: AutoHotkeyパスフレーズ入力(gpgがパスワード要求するダイアログが出た場合に備える)
start "" /b "C:\Users\hoge\Documents\AutoHotkey\autopass.ahk"

:: PGPクリア署名作成
echo %infile% | gpg --yes --clearsign --output "%outfile%"


:: 署名成功していればループを抜ける
if exist "%outfile%" (

    goto postprocess
) else (

    timeout /t 1 &gt; nul
    goto signloop
)
:postprocess

powershell -nologo -command ^
  "$header = '&gt;|'; $footer = '|&lt;'; $body = Get-Content '%outfile%' -Raw; Write-Output ($header + \"`r`n\" + $body + $footer)"

powershell -nologo -command ^
  "$header = '&gt;|'; $footer = '|&lt;'; $body = Get-Content 'signed.asc' -Raw; Set-Clipboard -Value ($header + \"`r`n\" + $body + $footer)"

endlocal
exit /b
AutoHotkey(以前と同じ)
#Persistent
#SingleInstance ignore
SetTitleMatchMode, 2
WinWaitActive, pinentry
SendInput password
Sleep 100
SendInput {Enter}
ExitApp

動けばいいという考えで作っているので余分なコードも含んでいるかもしれない。

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

https://anond.hatelabo.jp/20250613185036 
-----BEGIN PGP SIGNATURE-----

iHUEARYKAB0WIQTEe8eLwpVRSViDKR5wMdsubs4+SAUCaEv1FQAKCRBwMdsubs4+
SHHkAQDUOLgBcdji2T6MJ7h/vlMdFfGlWAzNdXijjE1gIuEPywEAiMNMZqhrMmtl
c7UqRuggNJ/UTa5xTIcKp622+7jJQQg=
=Lgkl
-----END PGP SIGNATURE-----
ログイン ユーザー登録
ようこそ ゲスト さん