はてなキーワード: DELETEとは
ロックに条件持たせる
やりたいことはできてるように見えるが、うーんしんどい
# Entity Relation Diagram
# ```mermaid
# ---
# title: Rental Office example
# ---
# erDiagram
# OFFICE ||--|{ ROOM : x
# OFFICE {
# number office_id
# }
# ROOM {
# number office_id
# number room_id
# }
# ROOM ||--|{ SCHEDULE : x
# SCHEDULE {
# number room_id
# datetime start_at
# datetime end_at
# }
# OFFICE ||--|{ BUSINESS_HOUR : x
# BUSINESS_HOUR {
# number office_id
# enum week_of_day
# datetime start_at
# datetime end_at
# }
# ```
# Directed Acyclic Graph
#
# ```mermaid
# graph LR
# A[OFFICE] --> B[ROOM]
# B --> C[SCHEDULE]
# A[OFFICE] --> D[BUSINESS_HOUR]
# D --> C
# A --> C
# ```
# 基底クラス: EntityLock
class EntityLock
attr_accessor :entity_name, :entity_locked, :attribute_locks
def initialize(entity_name)
@entity_name = entity_name
@entity_locked = false # エンティティ全体のロック状態を保持
@attribute_locks = {} # IDに対するロックを管理するハッシュ
end
def lock_entity
@entity_locked = true
puts "Entity '#{@entity_name}' is now locked."
end
def unlock_entity
@entity_locked = false
puts "Entity '#{@entity_name}' is now unlocked."
end
def lock(attributes)
entity_id = attributes["#{@entity_name.downcase}_id"]
if entity_id && !@attribute_locks[entity_id]
@attribute_locks[entity_id] = true
puts "#{@entity_name} with ID '#{entity_id}' is now locked."
end
end
def unlock(attributes)
entity_id = attributes["#{@entity_name.downcase}_id"]
if entity_id && @attribute_locks[entity_id]
@attribute_locks.delete(entity_id)
puts "#{@entity_name} with ID '#{entity_id}' is now unlocked."
end
end
def locked?(attributes)
# まずエンティティ全体がロックされているかチェック
return true if @entity_locked
# 次に特定のIDがロックされているかチェック
entity_id = attributes["#{@entity_name.downcase}_id"]
if entity_id && @attribute_locks[entity_id]
return true
end
# ロックされていなければfalseを返す
false
end
end
# 子クラス: OfficeLock, RoomLock, ScheduleLock
class OfficeLock < EntityLock
def initialize
super("Office")
end
end
class RoomLock < EntityLock
def initialize
super("Room")
end
end
class ScheduleLock < EntityLock
def initialize
super("Schedule")
end
end
# 子クラス: BusinessHourLock
class BusinessHourLock < EntityLock
def initialize
super("BusinessHour")
@attribute_locks = [] # BusinessHour用のロックを配列で管理
end
def lock(attributes)
start_at = attributes["start_at"]
end_at = attributes["end_at"]
if start_at && end_at
@attribute_locks << [start_at, end_at]
puts "BusinessHour from '#{start_at}' to '#{end_at}' is now locked."
end
end
def unlock(attributes)
start_at = attributes["start_at"]
end_at = attributes["end_at"]
if @attribute_locks.include?([start_at, end_at])
@attribute_locks.delete([start_at, end_at])
puts "BusinessHour from '#{start_at}' to '#{end_at}' is now unlocked."
end
end
def locked?(attributes)
# まずエンティティ全体がロックされているかチェック
return true if @entity_locked
# 次に特定の時間範囲がロックされているかチェック
start_at = attributes["start_at"]
end_at = attributes["end_at"]
if start_at && end_at
@attribute_locks.each do |(locked_start, locked_end)|
if locked_start <= start_at && end_at <= locked_end
return true
end
end
end
# ロックされていなければfalseを返す
false
end
end
# TreeNodeクラス
class TreeNode
attr_accessor :name, :children, :parents, :lock
def initialize(name, lock)
@name = name
@children = []
@parents = [] # 複数の親ノードを保持する配列
@lock = lock # TreeNodeにロックを持たせる
end
def add_child(child_node)
child_node.parents << self # 子ノードにこのノードを親として追加
@children << child_node
end
def display(level = 0)
indent = " " * (level * 4)
puts "#{indent}#{@name}"
@children.each { |child| child.display(level + 1) }
end
def has_dependency
return false if @parents.empty?
@parents.each do |parent|
puts "#{@name} is dependent on #{parent.name}"
return true
end
@parents.any?(&:has_dependency)
end
def locked?(attributes = {})
# 自身がロックされているか確認
return true if @lock.locked?(attributes)
# 親ノードがロックされているか再帰的に確認
@parents.any? { |parent| parent.locked?(attributes) }
end
end
# 木構造の組み立て
# ロックオブジェクトの作成
office_lock = OfficeLock.new
room_lock = RoomLock.new
schedule_lock = ScheduleLock.new
business_hour_lock = BusinessHourLock.new
# ノードの作成
office_node = TreeNode.new("Office", office_lock)
room_node = TreeNode.new("Room", room_lock)
schedule_node = TreeNode.new("Schedule", schedule_lock)
business_hour_node = TreeNode.new("BusinessHour", business_hour_lock)
# ノード間の依存関係の設定
office_node.add_child(room_node) # Office -> Room
room_node.add_child(schedule_node) # Room -> Schedule
office_node.add_child(business_hour_node) # Office -> BusinessHour
business_hour_node.add_child(schedule_node) # BusinessHour -> Schedule
# 木構造の表示
office_node.display
# ロックの確認
puts "Case 1. Office全体がロックされた場合"
puts "Is office_node locked? #{office_node.locked?({})}" # false
puts "Is schedule_node locked? #{schedule_node.locked?({})}" # false
office_lock.lock_entity
puts "Is office_node locked? #{office_node.locked?({})}" # true
puts "Is schedule_node locked? #{schedule_node.locked?({})}" # true
office_lock.unlock_entity
puts "Case 2. Room id:1 がロックされた場合"
puts "Is schedule_node locked? #{schedule_node.locked?({ "room_id" => 1 })}" # false
puts "Is schedule_node locked? #{schedule_node.locked?({ "room_id" => 2 })}" # false
room_lock.lock({ "room_id" => 1 })
puts "Is schedule_node locked? #{schedule_node.locked?({ "room_id" => 1 })}" # true
puts "Is schedule_node locked? #{schedule_node.locked?({ "room_id" => 2 })}" # false
room_lock.unlock({ "room_id" => 1 })
puts "Case 3. BusinessHour start_at:0 end_at:5 がロックされた場合"
puts "Is schedule_node locked? #{schedule_node.locked?({ "room_id" => 1, "start_at" => 0, "end_at" => 5 })}" # false
puts "Is schedule_node locked? #{schedule_node.locked?({ "room_id" => 1, "start_at" => 5, "end_at" => 10 })}" # false
business_hour_lock.lock({ "start_at" => 0, "end_at" => 5 })
puts "Is schedule_node locked? #{schedule_node.locked?({ "room_id" => 1, "start_at" => 0, "end_at" => 5 })}" # true
puts "Is schedule_node locked? #{schedule_node.locked?({ "room_id" => 1, "start_at" => 5, "end_at" => 10 })}" # false
business_hour_lock.unlock({ "start_at" => 0, "end_at" => 5 })
試してみたけどいけないんよ。
そこで正しくValueが#REF!の名前を拾えてるのにDeleteするとなぜかいまアクティブなシートのエラー参照じゃないプリントエリアが消されてる
エクセルのマクロで膨大な量の名前の定義を一括で削除させたくて、こんな風に書いたんだけど
For Each n In ActiveWorkbook.Names
If InStr(1, n.Name, "Print_Area") = 0 Then
n.Delete
ElseIf n.Value Like "*[#]REF!*" Then
End If
なぜか参照エラーになってるプリントエリアを消すべきところでエラー起こしてないプリントエリアが消される。
「Print_Area」だけど参照エラーになってるものが一個だけあるからそれを消してほしいだけなんだけど、アクティブシートのプリントエリアが消されて参照エラーの方は生き残ってしまう。
なんで…?
【やりたいこと】
1.シート1を正しく参照しているもの
2.シート2を正しく参照しているもの
3.#REF!を参照しているもの
の3つがある。
この3つ目だけを消したい。
【なぜか起きること】
For Eachで上から順に1と2を素通りして、3つめのときにローカルウインドウでName.Valueが#REF!なのを確認しているのに、
3つ目をDelete すると1つ目が消える
そもそもあの脚ってキートップを見やすくするために付けられてた
つまりはタッチタイピングできない人のために見やすくする理由で作られていて
打ちやすさは手前は平面、奥が少し盛り上がる状態が一番負担が少ない
これは「人による」みたいなことはなくて、人間はそういう風に出来ている
特にカーソル移動をするときにFnを使って矢印キーを押す人が多いが
EmacsならC-nやC-pを使うし、Vimならjやkを使う
なので矢印キーなんて(ホームポジションから遠いし)使わないよね、という思想の元作られている
他にもBackSpaceはC-hなのでDeleteになっているしF1とかF2とかは使わないというのが前提
「うるさい俺は矢印キーを使いたいんだ」
という人はRealforce使えばいいのであってHHKBである必要は全く無い
まぁHHKBの大きな思想に持ち運べる馬の鞍思想があるので、持ち運ぶために使うけど矢印キーを使いたい、という人は一定数いると思うけど
QWERTY配列の理由はよく使うキーを中心に構成されているとか
タイプライターが壊れないようにわざとバラしてあるだとか言われているが
本当に押しやすいとかタイピングが早くなるような配列はちゃんと研究されているし
例えば日本語なら親指シフトが最も良いなんていうのも昔はあったんだが
結局のところ毎秒3キー押せるのが3.5キーになったところで意味は無いし
それよりも共通認識として広まっているQWERTY配列でいいじゃん、となって現在に至る
打ち間違えるためだけに存在してそうなNum Lockキーだが
数字を打ち込むときにテンキーがあるのとないのでは大違いで圧倒的にテンキーの方が速い
一方でノートPCではテンキーを置く場所をケチりがちなので無理矢理Num Lockキーを使ってキーボードの一部をテンキーにしている
斜めになっているのでテンキーとは打ち方が変わってしまうが、それでも使いこなせば数字を打ち込むのがめちゃくちゃ速くなる
ただ、ほとんどの場合は外付けのテンキーを使ってる気もするのでやっぱりいらないかもしれない
余談だがテンキーのあるキーボードのNum Lock機能は矢印キーとテンキーを切り替えるもので
昔のゲームなんかはテンキーを使って上下左右をコントロールしていたのだが
その場合はそもそもゲーム自体がテンキーによる入力で上下左右に動けていたので
そしてWASDキーによる移動が主流になって完全に廃れた
絶滅危惧種となりつつあるHome End PageDown PageUpだが
PageDownとPageUpはそれなりに使い方が知られているとして
HomeとEndが行頭・行末への移動だと知っている人は意外と少ない
文章を打っていて行頭に戻りたければHomeを押せばいいし、行末ならEndでよい
マウスでカーソル移動する必要はなくて便利なのだが恐らく大半の人はマウスで移動しているのと
Emacsキーバインドプログラマーとコンソールを触る人はC-aとC-eで代用できるので
ワイ:
真面目な顔の人間の男の人の顔の絵を描いてください。
GPT:
*イメージ省略*
ワイ:
GPT:
*イメージ省略*
ワイ:
その整数が 3 か 5 の倍数の場合、ふざけた顔の男の顔(一枚目の顔)を表示してください。
GPT:
了解しました。以下は、指定された条件に基づいて動作するPythonのGUIアプリのコードです。このアプリは、tkinterを使用しています。まず、必要なライブラリをインストールしてください:
pip install tkinterimport tkinter as tk from tkinter import Entry, Label, PhotoImage def display_image(): num = entry.get() if num.isdigit(): num = int(num) if num % 3 == 0 or num % 5 == 0: label.config(image=goofy_face) else: label.config(image=serious_face) entry.delete(0, tk.END) def on_close(): root.quit() root.destroy() root = tk.Tk() root.title("Face Display App") # ふざけた顔と真面目な顔の画像をロードします # 以下の部分は、DALL-Eで生成された画像のパスに置き換える必要があります goofy_face = PhotoImage(file="path_to_goofy_face_image.png") serious_face = PhotoImage(file="path_to_serious_face_image.png") entry = Entry(root) entry.bind('<Return>', lambda event=None: display_image()) entry.pack(pady=20) label = Label(root) label.pack(pady=20) root.protocol("WM_DELETE_WINDOW", on_close) root.mainloop()このコードには、2つのPhotoImageオブジェクトがあります。これは、ふざけた顔の画像と真面目な顔の画像をロードするためのものです。path_to_goofy_face_image.pngとpath_to_serious_face_image.pngは、DALL-Eで生成された画像の実際のパスに置き換える必要があります。
このアプリは、ユーザーが整数を入力してReturnキーを押すと、指定された条件に基づいて画像を表示します。エスケープキーまたはウィンドウを閉じることでアプリを終了できます。
ワイ:
GPT:
私の投稿に説明不足がございましたこと、まずはお詫び申し上げます。
さて、ご指摘を頂きました
について補足をさせていただきます。
私の元の投稿では「クリア」を「ゲームクリア」の省略形を意味するものとして記載いたしました。
また、「ゲームクリア」とは「ゲーム用語の一つ。 ゲームを最後まで攻略すること。」(ピクシブ百科事典より引用)であります。
おそらくご指摘の意図は「スマホ上の操作としてアプリを削除する操作を指して"クリア"とは言わない」ということかと思います。
仰る通りでございます。わたくしもその点について異論はございません。
以上で補足とさせていただきます。
なお蛇足ではございますが、英語圏ではゲームクリアを「beat」(打ちのめす)「finished」(終わる)「completed」(完結)などと表現するのだそうでございます。
増田は、デスクトップとして使われていたフォルダの残骸を消したつもりが、実は依然としてデスクトップとして使われているフォルダを消していて、
このトラブル、散々経験した情報システムアドミニストレータ パソコンの奴隷としては以下の運用にしてる。
あと、他にも指摘している人がいるけど、ブラウザからOneDriveにアクセスしてゴミ箱を見てほしい。同期が1回でもされていると、そちらに残っているはず。
OneDriveのゴミ箱はローカルゴミ箱と連動していないので、ローカルでSHIFT+Deleteやゴミ箱空をしてもOneDrive上ではゴミ箱に移されて残っているはず。同期する前にやってるとそれは厳しいけど、ダメ元で覗いてみてね。
では、設定について。
バックアップ設定でフォルダを設定すると、何故かバックアップを外す人がいてトラブルになるので、バックアップ設定は全部不可にしている。
その上で、デスクトップやドキュメントの特殊は、あらかじめOneDrive上に手動でフォルダを設定した上で、それぞれのプロパティから移動させる。
この時、端末ごとにデータを同期させず、しかしファイルを保護したい場合には、パソコンごとに別のフォルダを指定すれば良い。
調べてみたらひどいクソ仕様だったので、同じ轍ふまないように知見共有します。
なお、消えてしまったデータは息子の卒業式の動画データ。復元不能。
ストレージは壊れるものという前提は理解しているつもりなので、状況ごとにいくつかのバックアップ体制は取ってある。
安くなったとは言えすべてのストレージをSSD化するには至っていない。
そのため、OSやソフトウェアなんかはSSDにインストール、写真や動画などのサイズがでかいデータはRaid HDDでミラーリングして格納するようにしている。
それ以外にもそれほどサイズの大きくないデータはonedriveとかのクラウドストレージを利用。そのデータもRaid HDDでミラーリングして二重にバックアップ体制を敷いている。
趣味で写真をやっているのだが、今回の事故はその編集のフローの中で起こった。
編集と格納は別で考えているので、アクセス速度が高いほうがいい編集はSSD上で行い、格納はRaid HDDに行っている。
そのタイミングでgoogle photoに分散バックアップ、必要に応じて家族なんかと共有を行う。
つまり、撮影が終わったら最初にすることは、SSD上にあるデスクトップの一時フォルダに写真と動画データをコピーすることから始まる。
Raid HDDに格納するのは、編集ソフトでレタッチが終わってからだ。
まずは写真データから編集を行い、RAWデータから無事にjpegデータへと書き出してHDDへの格納が終わった。
そのタイミングで妻からの頼まれごとのためにメールをpdfプリントして名前をつけて保存しようとした。
めったに使わない機能なのだが、指定されたのはonedriveフォルダだったので、そのまま保存をクリック。
ところが、PCからonedriveフォルダにアクセスしても出力したpdfデータが見つからない。
おかしいなと思ってもう一度出力を試みて保存フォルダのパスを確認してみる。
すると、今現在HDD側に指定してあるonedriveのパスが、SSD上のデフォルトのパスに指定されているようだった。
ここで思い至ったのが、確かPCにonedriveを設定した際にうっかりデフォルト設定のまま起動してしまい、その後、HDD上にパスを切り替えたという状況だった。
「そうかぁ。保存先を変更すると元のファイルを移動させるんじゃなくてコピーを作ってしまうんだな」なんて感じに妙に納得しつつ、もう一度しっかりとパスを確認した上でpdfをコピーしてからSSD上のonedriveをshift deleteで削除した。
エクスプローラーを閉じてデスクトップに戻ってくると妙な違和感。
ない。
はぁ?と思ってPCをダブルクリックすると、すぐに警告ウィンドウが開いて「デスクトップへのパスが間違っています」といったエラー表示。
焦る。かなり焦る。
ウィンドウをすべて閉じても、デスクトップ上にはデフォルトのアイコンだけが並んでいるだけ。
頭真っ白。
多少大事なデータはあったかなと思いながらも致命的と言えるものは思いつかず(まだ見落としてるだけかもしれない)、しかし、すぐに一時フォルダごと動画データがないことに気づく。
写真はすでにjpg出力してあるので、RAWデータが消えてしまったのはなんとかなる。
子供の卒業式の動画はまだ変換をかけてもないし、当然アップロードもしていない。
終わった。
あまりにもショックだ。
読み飛ばしここまで。
結局何が原因だったかというと、最初にonedriveをセットアップする際に、デフォルトの保存先、なおかつデスクトップやマイドキュメントなんかもバックアップに含めるという設定で始めてしまったからだったらしい。
この、onedriveのバックアップにデスクトップを含めるという操作をすると次のようなことが起こる。
「本来はC:\Users\ユーザー名\Desktopにあるはずのデスクトップデータが、C:\Users\ユーザー名\onedrive\Desktopに変更される」
・onedriveのバックアップからデスクトップを含めないように設定変更
この2つの動作を行ったにも関わらず、何故かこのパソコンのデスクトップは、C:\Users\ユーザー名\onedrive\Desktoに残ったままになってしまったというわけだ。
そのため、C:\Users\ユーザー名\Desktopにデスクトップがあると思いこんでいた自分は、C:\Users\ユーザー名\onedriveにあるonedriveのフォルダを、疑うことなく削除することができた。
そしてその結果、デスクトップにおいてあったデータのすべてを失った。
いや、流石にこんなクソ設定想定できないでしょ。
大事なデータを守るっていう名目があれば、大事なデータの格納先をそんな簡単に変えていいと思ってる?
それ、誰に許可取ってやってるんだよっていうさ。
その辺の共通プロトコルを、バックアップソフトが、しかもOSの提供元がやっていいのかよっていう。
これはちょっと言わせてくれ。
マイクロソフトクソだわ。
まぁ、なんというか皆さんも気をつけてください。というか、こんなの気をつけようがないけどな。
どこに気持ちをぶつけたって息子の大事な思い出は帰ってこないのはわかってるけど、やるせなさくらい吐き出させて。
※追記
ブラウザonedriveのゴミ箱にデータが残っている可能性はゼロです。
その理由は以下の通り。
このパソコンは1ヶ月ほど前に新規にセットアップしたものでした。
そのセットアップの過程で、onedriveをインストールする際にデフォルトの保存先、なおかつデスクトップをバックアップという設定にしてしまいました。
ここでノールックで設定してしまった自分が一番悪いことは認めます。
onedriveのセットアップが終わったあと、同期に時間がかかっていておかしいな?と思ってファイルのアップロード履歴を確認したところ、あらかじめ古いパソコンからコピーしてあったデスクトップのデータをアップロードしようとしていたので、慌てて設定を見直して、デスクトップ同期のオフ、保存先をHDDに変更しました。(変更した順番は書いてある通り覚えていません。順番が逆だったら起こり得なかったかも)
この操作によって、onedriveの保存先はHDDに変更になり、デスクトップの同期も停止しました。
しかしそうした操作を行ったにも関わらず、デスクトップの保存先はC:\Users\ユーザー名\Desktopに戻ることはなく、C:\Users\ユーザー名\onedrive\Desktopのままになってしまっていました。
そのことに気づかずに1ヶ月以上作業を続けていたなかで、記載の通りSSD内に同期されていないonedriveフォルダを発見したので削除した結果、デスクトップのデータが消失しまったという話です。
そして卒業式の動画データをデスクトップにコピーしたのは、onedriveの同期を切ったずっとあとのことです。
もともとonedriveにバックアップするつもりもないし、バックアップされていないのでwebに残っているはずもないのです。
デスクトップのデータがそんなところに格納されていることがわかっていれば、もともと削除なんてしません。
同期されていないすでに使われていないonedriveのデータだけしか削除するつもりではなかったのに、何故かその中に現在進行系で使っているデスクトップのデータが格納されていて、一緒に削除されてしまったというお話です。
ちなみに、削除直後は本当に何が起こったのか意味がわかりませんでした。
その後にマイコンピューターを開いた際、別ウィンドウでエラーが出たことで初めて状況が理解できたということです。
そのエラーが「デスクトップC:\Users\ユーザー名\onedrive\Desktopにアクセスできません」といった内容のエラーです。
デスクトップ?お前なんでそんなとこに保存されてたの?からの、そういえば思い出してみればこんなことあったよなーで、原因に思い至ったというわけです。
SDカードの復元を試みましたが、サイズの大きい動画データですので、ヘッダーは読み込めたものの、データそのものはすでに別の写真データに書き換えられてしまっていたせいかちゃんと開けませんでした。
SDカードからデスクトップにデータを移すタイミングというのは、行事ごとに撮影が終わったらSDを空にして新しく撮影できる状況を作るためなので、基本的にはデスクトップにコピーしたあとは次の撮影前に必ずフォーマットすることを習慣づけています。
それは、毎回SDカードを空っぽにすることで、現像のときにデータの重複が起こらないようにするためです。(趣味で写真を取っているので撮影枚数が莫大。尚且つ現像ソフトで不要データを削除するので、SDを空にしないと、削除後にまたコピーしてしまったりと効率が悪いため)
撮影→データをデスクトップに一次保存→次回撮影時にSDカードのフォーマット→時間があるときにPC上のデータを選別、現像→バックアップ含めてデータを格納→SDカードから新しい撮影データをPCにコピー→次回撮影時にフォーマット→時間あるときにPC上のデータを選別、現像→・・・・
SDカード自体も紛失の危険性とか考えてそれほど信用しているメディアではないので、できるだけデータが保管されている時間を短くするようにしています。
個人的には、このワークフローが一番データの保存性も高く、無駄も少ない処理方法だと思っています。
だって、デスクトップを間違って消すなんてこと普通しないでしょ。
壊れたなら仕方ないって、それはそれで納得できるんだって。
流石にこんなことまで想定したワークフロー作れってのは無理な話ですよ。
すでにonedriveからデスクトップの同期も切ってて、しかも別フォルダでonedriveがちゃんと稼働してるのに、まさか自分のデスクトップがC:\Users\ユーザー名\onedrive\Desktopに保存されてるなんて思う?
以下のスクリプトを登録することで。以下のループを繰り返させることができる。
「https://anond.hatelabo.jp/ここにユーザー名/を開く」→「直近の投稿の編集画面に遷移」→「削除ボタンを押す」→「ダイアログに答える」→「https://anond.hatelabo.jp/ここにユーザー名/に戻る」
実質ダイアログに答えるところだけやればよい。
// ==UserScript== // @name New Userscript // @namespace http://tampermonkey.net/ // @version 0.1 // @description try to take over the world! // @author You // @match https://anond.hatelabo.jp/ここにユーザー名/ // @icon https://www.google.com/s2/favicons?sz=64&domain=hatelabo.jp // @grant none // ==/UserScript== function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } (async function() { 'use strict'; await sleep(100); window.location.href = document.querySelectorAll("div.section")[0].querySelector("a.edit").href; })();
// ==UserScript== // @name New Userscript // @namespace http://tampermonkey.net/ // @version 0.1 // @description try to take over the world! // @author You // @match https://anond.hatelabo.jp/ここにユーザー名/edit* // @icon https://www.google.com/s2/favicons?sz=64&domain=hatelabo.jp // @grant none // ==/UserScript== function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } (async function() { 'use strict'; await sleep(100); document.querySelector("input.delete-button").click(); })();