haraberget commited on
Commit
4a40c83
·
verified ·
1 Parent(s): 8f577f9

Update injection.js

Browse files
Files changed (1) hide show
  1. injection.js +120 -116
injection.js CHANGED
@@ -1,9 +1,8 @@
1
 
 
2
  (() => {
3
- // Stop the previous monitor before replacing its window.
4
- if (window.hitRenderMonitorTimer) {
5
- clearInterval(window.hitRenderMonitorTimer);
6
- }
7
  document.getElementById("hit-render-monitor")?.remove();
8
 
9
  const POSITION_KEY = "hitRenderMonitorPosition";
@@ -15,7 +14,6 @@
15
  totalSteps: 0,
16
  checkpoints: new Set(),
17
  completedUrl: "",
18
- lastReport: null,
19
  minimized: false
20
  };
21
 
@@ -41,37 +39,24 @@
41
 
42
  panel.innerHTML = `
43
  <div id="hit-header" style="
44
- display:flex;
45
- justify-content:space-between;
46
- align-items:center;
47
- padding:12px 14px;
48
- background:#22252d;
49
- border-radius:10px 10px 0 0;
50
- cursor:grab;
51
- user-select:none;
52
- touch-action:none;
53
- ">
54
  <strong style="font-size:15px">
55
  H3 Monitor <span id="hit-title-progress" style="color:#20b875">· Waiting</span>
56
  </strong>
57
  <div style="display:flex;gap:6px">
58
- <button id="hit-minimize" title="Minimize" style="
59
- background:#444;color:white;border:0;
60
- padding:3px 10px;cursor:pointer;font-size:16px
61
- ">−</button>
62
- <button id="hit-close" title="Close" style="
63
- background:#744;color:white;border:0;
64
- padding:3px 9px;cursor:pointer;font-size:15px
65
- ">×</button>
66
  </div>
67
  </div>
68
 
69
- <div id="hit-content" style="
70
- padding:14px;
71
- max-height:calc(85vh - 45px);
72
- overflow-y:auto;
73
- ">
74
- <div style="margin-top:2px">RENDER PROGRESS</div>
75
  <div style="height:12px;background:#333;border-radius:8px;margin:6px 0;overflow:hidden">
76
  <div id="hit-bar" style="height:100%;width:0%;background:#20b875;transition:width .3s"></div>
77
  </div>
@@ -80,7 +65,31 @@
80
 
81
  <hr style="border-color:#444;margin:12px 0">
82
 
83
- <div><strong>PROMPT INSPECTOR</strong></div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
84
  <div id="hit-prompt" style="background:#242730;padding:8px;margin-top:6px;max-height:125px;overflow:auto;white-space:pre-wrap;overflow-wrap:anywhere;color:#ddd">Waiting for prompt...</div>
85
 
86
  <hr style="border-color:#444;margin:12px 0">
@@ -88,46 +97,56 @@
88
  <div style="display:flex;justify-content:space-between;align-items:center">
89
  <strong>CALLBACK SIMULATOR</strong>
90
  <label style="font-size:11px">
91
- <input id="hit-report" type="checkbox" checked>
92
- Report to 1hit.no
93
  </label>
94
  </div>
95
  <div style="color:#e6b85c;font-size:11px;margin:4px 0 8px">
96
  Simulation only — no network requests
97
  </div>
98
-
99
  <div id="hit-json" style="background:#090b0e;padding:9px;max-height:230px;overflow:auto;white-space:pre-wrap;overflow-wrap:anywhere;font-size:11px;color:#9fe5b2">Waiting for events...</div>
100
 
101
  <hr style="border-color:#444;margin:12px 0">
102
 
103
- <div><strong>OUTPUT URL</strong></div>
104
  <div id="hit-url" style="color:#8fcaff;overflow-wrap:anywhere;margin-top:5px">Waiting for video...</div>
105
-
106
  <div id="hit-status" style="color:#aaa;font-size:11px;margin-top:10px">Polling every 15 seconds</div>
107
  </div>
108
  `;
109
 
110
  document.body.appendChild(panel);
111
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
112
  const el = id => panel.querySelector("#" + id);
113
 
114
- // Restore the previous position, if available.
115
  try {
116
  const saved = JSON.parse(sessionStorage.getItem(POSITION_KEY) || "null");
117
-
118
  if (saved && Number.isFinite(saved.left) && Number.isFinite(saved.top)) {
119
  panel.style.left = saved.left + "px";
120
  panel.style.top = saved.top + "px";
121
  panel.style.right = "auto";
122
  panel.style.bottom = "auto";
123
  }
124
- } catch (e) {
125
- console.warn("Could not restore monitor position:", e);
126
- }
127
 
128
  function savePosition() {
129
  const rect = panel.getBoundingClientRect();
130
-
131
  try {
132
  sessionStorage.setItem(POSITION_KEY, JSON.stringify({
133
  left: Math.round(rect.left),
@@ -136,7 +155,7 @@
136
  } catch (e) {}
137
  }
138
 
139
- // Drag the monitor using its title bar.
140
  const header = el("hit-header");
141
  let dragging = false;
142
  let dragOffsetX = 0;
@@ -144,44 +163,33 @@
144
 
145
  header.addEventListener("pointerdown", event => {
146
  if (event.target.closest("button")) return;
147
-
148
  dragging = true;
149
-
150
  const rect = panel.getBoundingClientRect();
151
  dragOffsetX = event.clientX - rect.left;
152
  dragOffsetY = event.clientY - rect.top;
153
-
154
  panel.style.right = "auto";
155
  panel.style.bottom = "auto";
156
  header.style.cursor = "grabbing";
157
-
158
  header.setPointerCapture(event.pointerId);
159
  event.preventDefault();
160
  });
161
 
162
  header.addEventListener("pointermove", event => {
163
  if (!dragging) return;
164
-
165
- const width = panel.offsetWidth;
166
- const height = panel.offsetHeight;
167
-
168
- const left = Math.max(
169
- 0,
170
- Math.min(window.innerWidth - width, event.clientX - dragOffsetX)
171
- );
172
-
173
- const top = Math.max(
174
- 0,
175
- Math.min(window.innerHeight - height, event.clientY - dragOffsetY)
176
- );
177
-
178
  panel.style.left = left + "px";
179
  panel.style.top = top + "px";
180
  });
181
 
182
  function stopDragging() {
183
  if (!dragging) return;
184
-
185
  dragging = false;
186
  header.style.cursor = "grab";
187
  savePosition();
@@ -191,41 +199,63 @@
191
  header.addEventListener("pointercancel", stopDragging);
192
  header.addEventListener("lostpointercapture", stopDragging);
193
 
194
- // Minimize and restore without stopping the monitor.
195
  el("hit-minimize").onclick = () => {
196
  state.minimized = !state.minimized;
 
 
 
 
 
 
197
 
198
- el("hit-content").style.display =
199
- state.minimized ? "none" : "block";
200
-
201
- el("hit-minimize").textContent =
202
- state.minimized ? "+" : "−";
 
 
 
 
 
 
 
 
 
203
 
204
- el("hit-minimize").title =
205
- state.minimized ? "Restore" : "Minimize";
 
206
 
207
- panel.style.width = state.minimized ? "260px" : "440px";
 
 
208
 
209
- savePosition();
210
- };
 
 
 
 
 
 
 
 
 
 
211
 
212
  function addEvent(data) {
213
  if (!el("hit-report").checked) return;
214
-
215
- const json = JSON.stringify(data, null, 2);
216
  const log = el("hit-json");
217
-
218
  log.textContent =
219
- (log.textContent === "Waiting for events..." ? "" : log.textContent + "\n\n")
220
- + json;
221
-
222
  log.scrollTop = log.scrollHeight;
223
  }
224
 
225
  function getPrompt() {
226
- const fields = [
227
- ...document.querySelectorAll("textarea, [contenteditable='true']")
228
- ];
229
 
230
  const candidates = fields.map(node => ({
231
  text: (node.value || node.innerText || node.textContent || "").trim(),
@@ -241,7 +271,6 @@
241
  .sort((a, b) => b.text.length - a.text.length);
242
 
243
  if (labelled.length) return labelled[0].text;
244
-
245
  candidates.sort((a, b) => b.text.length - a.text.length);
246
  return candidates[0]?.text || "";
247
  }
@@ -254,20 +283,11 @@
254
  ];
255
 
256
  for (const node of candidates) {
257
- const url =
258
- node.currentSrc ||
259
- node.src ||
260
- node.href ||
261
- "";
262
-
263
- if (url && (
264
- /\.mp4(?:[?#]|$)/i.test(url) ||
265
- url.startsWith("blob:")
266
- )) {
267
  return url;
268
  }
269
  }
270
-
271
  return "";
272
  }
273
 
@@ -285,33 +305,24 @@
285
  }
286
 
287
  function poll() {
288
- const prompt = getPrompt();
289
 
 
290
  if (prompt && prompt !== state.prompt) {
291
  state.prompt = prompt;
292
  state.checkpoints.clear();
293
  state.completedUrl = "";
294
-
295
  el("hit-prompt").textContent = prompt;
296
-
297
- addEvent({
298
- ...baseEvent("prompt"),
299
- message: "New prompt detected"
300
- });
301
  }
302
 
303
- const messages = [
304
- ...document.querySelectorAll('div[type="message"]')
305
- ];
306
-
307
  const matching = messages
308
  .map(node => node.innerText || "")
309
  .filter(text => text.includes("H3 denoising:"));
310
 
311
  if (matching.length) {
312
- const latest = matching[matching.length - 1];
313
-
314
- const match = latest.match(
315
  /H3 denoising:\s*(\d+)%.*?\|\s*(\d+)\/(\d+)/
316
  );
317
 
@@ -332,30 +343,23 @@
332
  el("hit-bar").style.width = pct + "%";
333
  el("hit-progress").textContent = pct + "%";
334
  el("hit-step").textContent = `Step ${step} / ${total}`;
335
-
336
  el("hit-title-progress").textContent = "· " + pct + "%";
337
 
338
  for (const threshold of [25, 50, 75, 100]) {
339
  if (pct >= threshold && !state.checkpoints.has(threshold)) {
340
  state.checkpoints.add(threshold);
341
-
342
- addEvent({
343
- ...baseEvent("progress"),
344
- checkpoint: threshold
345
- });
346
  }
347
  }
348
  }
349
  }
350
 
351
  const videoUrl = getVideoUrl();
352
-
353
  if (videoUrl) {
354
  el("hit-url").textContent = videoUrl;
355
 
356
  if (state.progress >= 100 && videoUrl !== state.completedUrl) {
357
  state.completedUrl = videoUrl;
358
-
359
  addEvent({
360
  ...baseEvent("completed"),
361
  video: {
@@ -380,5 +384,5 @@
380
  poll();
381
  window.hitRenderMonitorTimer = setInterval(poll, 15000);
382
 
383
- console.log("H3 Render Monitor v3 started.");
384
  })();
 
1
 
2
+
3
  (() => {
4
+ // H3 Render Monitor v4 — Kaggle
5
+ if (window.hitRenderMonitorTimer) clearInterval(window.hitRenderMonitorTimer);
 
 
6
  document.getElementById("hit-render-monitor")?.remove();
7
 
8
  const POSITION_KEY = "hitRenderMonitorPosition";
 
14
  totalSteps: 0,
15
  checkpoints: new Set(),
16
  completedUrl: "",
 
17
  minimized: false
18
  };
19
 
 
39
 
40
  panel.innerHTML = `
41
  <div id="hit-header" style="
42
+ display:flex;justify-content:space-between;align-items:center;
43
+ padding:12px 14px;background:#22252d;
44
+ border-radius:10px 10px 0 0;cursor:grab;
45
+ user-select:none;touch-action:none">
 
 
 
 
 
 
46
  <strong style="font-size:15px">
47
  H3 Monitor <span id="hit-title-progress" style="color:#20b875">· Waiting</span>
48
  </strong>
49
  <div style="display:flex;gap:6px">
50
+ <button id="hit-minimize" title="Minimize"
51
+ style="background:#444;color:white;border:0;padding:3px 10px;cursor:pointer;font-size:16px">−</button>
52
+ <button id="hit-close" title="Close"
53
+ style="background:#744;color:white;border:0;padding:3px 9px;cursor:pointer;font-size:15px">×</button>
 
 
 
 
54
  </div>
55
  </div>
56
 
57
+ <div id="hit-content" style="padding:14px;max-height:calc(85vh - 45px);overflow-y:auto">
58
+
59
+ <strong>RENDER PROGRESS</strong>
 
 
 
60
  <div style="height:12px;background:#333;border-radius:8px;margin:6px 0;overflow:hidden">
61
  <div id="hit-bar" style="height:100%;width:0%;background:#20b875;transition:width .3s"></div>
62
  </div>
 
65
 
66
  <hr style="border-color:#444;margin:12px 0">
67
 
68
+ <strong>KAGGLE SESSION</strong>
69
+ <div style="display:grid;grid-template-columns:1fr 1fr;gap:7px;margin-top:8px">
70
+ <div class="hit-stat"><small>ACCELERATOR</small><strong id="hit-accelerator">--</strong></div>
71
+ <div class="hit-stat"><small>QUOTA</small><strong id="hit-quota">--</strong></div>
72
+ <div class="hit-stat"><small>PERSISTENCE</small><strong id="hit-persistence">--</strong></div>
73
+ <div class="hit-stat"><small>INTERNET</small><strong id="hit-internet">--</strong></div>
74
+ <div class="hit-stat" style="grid-column:span 2"><small>ENVIRONMENT</small><strong id="hit-environment">--</strong></div>
75
+ </div>
76
+
77
+ <hr style="border-color:#444;margin:12px 0">
78
+
79
+ <strong>RESOURCE USAGE</strong>
80
+ <div style="color:#aaa;font-size:11px;margin-top:6px">
81
+ Live hardware readings not yet connected.
82
+ </div>
83
+ <div style="display:grid;grid-template-columns:1fr 1fr;gap:7px;margin-top:8px">
84
+ <div class="hit-stat"><small>CPU</small><strong>--</strong></div>
85
+ <div class="hit-stat"><small>RAM</small><strong>--</strong></div>
86
+ <div class="hit-stat"><small>DISK</small><strong>--</strong></div>
87
+ <div class="hit-stat"><small>GPU / VRAM</small><strong>--</strong></div>
88
+ </div>
89
+
90
+ <hr style="border-color:#444;margin:12px 0">
91
+
92
+ <strong>PROMPT INSPECTOR</strong>
93
  <div id="hit-prompt" style="background:#242730;padding:8px;margin-top:6px;max-height:125px;overflow:auto;white-space:pre-wrap;overflow-wrap:anywhere;color:#ddd">Waiting for prompt...</div>
94
 
95
  <hr style="border-color:#444;margin:12px 0">
 
97
  <div style="display:flex;justify-content:space-between;align-items:center">
98
  <strong>CALLBACK SIMULATOR</strong>
99
  <label style="font-size:11px">
100
+ <input id="hit-report" type="checkbox" checked> Report to 1hit.no
 
101
  </label>
102
  </div>
103
  <div style="color:#e6b85c;font-size:11px;margin:4px 0 8px">
104
  Simulation only — no network requests
105
  </div>
 
106
  <div id="hit-json" style="background:#090b0e;padding:9px;max-height:230px;overflow:auto;white-space:pre-wrap;overflow-wrap:anywhere;font-size:11px;color:#9fe5b2">Waiting for events...</div>
107
 
108
  <hr style="border-color:#444;margin:12px 0">
109
 
110
+ <strong>OUTPUT URL</strong>
111
  <div id="hit-url" style="color:#8fcaff;overflow-wrap:anywhere;margin-top:5px">Waiting for video...</div>
 
112
  <div id="hit-status" style="color:#aaa;font-size:11px;margin-top:10px">Polling every 15 seconds</div>
113
  </div>
114
  `;
115
 
116
  document.body.appendChild(panel);
117
 
118
+ // Style the statistic cards.
119
+ panel.querySelectorAll(".hit-stat").forEach(card => {
120
+ Object.assign(card.style, {
121
+ background: "#242730",
122
+ padding: "8px",
123
+ borderRadius: "6px",
124
+ minWidth: "0",
125
+ overflowWrap: "anywhere"
126
+ });
127
+ const small = card.querySelector("small");
128
+ const strong = card.querySelector("strong");
129
+ if (small) Object.assign(small.style, {
130
+ display: "block", color: "#aaa", fontSize: "10px", marginBottom: "3px"
131
+ });
132
+ if (strong) Object.assign(strong.style, {fontSize: "12px"});
133
+ });
134
+
135
  const el = id => panel.querySelector("#" + id);
136
 
137
+ // Restore previous popup position.
138
  try {
139
  const saved = JSON.parse(sessionStorage.getItem(POSITION_KEY) || "null");
 
140
  if (saved && Number.isFinite(saved.left) && Number.isFinite(saved.top)) {
141
  panel.style.left = saved.left + "px";
142
  panel.style.top = saved.top + "px";
143
  panel.style.right = "auto";
144
  panel.style.bottom = "auto";
145
  }
146
+ } catch (e) {}
 
 
147
 
148
  function savePosition() {
149
  const rect = panel.getBoundingClientRect();
 
150
  try {
151
  sessionStorage.setItem(POSITION_KEY, JSON.stringify({
152
  left: Math.round(rect.left),
 
155
  } catch (e) {}
156
  }
157
 
158
+ // Drag popup.
159
  const header = el("hit-header");
160
  let dragging = false;
161
  let dragOffsetX = 0;
 
163
 
164
  header.addEventListener("pointerdown", event => {
165
  if (event.target.closest("button")) return;
 
166
  dragging = true;
 
167
  const rect = panel.getBoundingClientRect();
168
  dragOffsetX = event.clientX - rect.left;
169
  dragOffsetY = event.clientY - rect.top;
 
170
  panel.style.right = "auto";
171
  panel.style.bottom = "auto";
172
  header.style.cursor = "grabbing";
 
173
  header.setPointerCapture(event.pointerId);
174
  event.preventDefault();
175
  });
176
 
177
  header.addEventListener("pointermove", event => {
178
  if (!dragging) return;
179
+ const left = Math.max(0, Math.min(
180
+ window.innerWidth - panel.offsetWidth,
181
+ event.clientX - dragOffsetX
182
+ ));
183
+ const top = Math.max(0, Math.min(
184
+ window.innerHeight - panel.offsetHeight,
185
+ event.clientY - dragOffsetY
186
+ ));
 
 
 
 
 
 
187
  panel.style.left = left + "px";
188
  panel.style.top = top + "px";
189
  });
190
 
191
  function stopDragging() {
192
  if (!dragging) return;
 
193
  dragging = false;
194
  header.style.cursor = "grab";
195
  savePosition();
 
199
  header.addEventListener("pointercancel", stopDragging);
200
  header.addEventListener("lostpointercapture", stopDragging);
201
 
202
+ // Minimize and restore.
203
  el("hit-minimize").onclick = () => {
204
  state.minimized = !state.minimized;
205
+ el("hit-content").style.display = state.minimized ? "none" : "block";
206
+ el("hit-minimize").textContent = state.minimized ? "+" : "−";
207
+ el("hit-minimize").title = state.minimized ? "Restore" : "Minimize";
208
+ panel.style.width = state.minimized ? "260px" : "440px";
209
+ savePosition();
210
+ };
211
 
212
+ // Read Kaggle session options from the actual page DOM.
213
+ function updateKaggleOptions() {
214
+ const getValue = label => {
215
+ const field = [...document.querySelectorAll('[role="combobox"]')]
216
+ .find(node => {
217
+ const text = (
218
+ node.getAttribute("aria-label") ||
219
+ node.getAttribute("aria-labelledby") ||
220
+ ""
221
+ ).toLowerCase();
222
+ return text.includes(label.toLowerCase());
223
+ });
224
+ return field?.innerText?.trim() || "";
225
+ };
226
 
227
+ const accelerator = getValue("Accelerator");
228
+ const persistence = getValue("Persistence");
229
+ const environment = getValue("Environment");
230
 
231
+ const internetInput = document.querySelector(
232
+ '#internet-toggle-switch-label input[type="checkbox"]'
233
+ );
234
 
235
+ const quota = [...document.querySelectorAll("p")]
236
+ .find(node => node.innerText.includes("Quota:"))
237
+ ?.innerText.match(/Quota:\s*(.*?)(?:\s*-\s*Link|$)/)?.[1] || "";
238
+
239
+ el("hit-accelerator").textContent = accelerator || "Not detected";
240
+ el("hit-quota").textContent = quota || "Not detected";
241
+ el("hit-persistence").textContent = persistence || "Not detected";
242
+ el("hit-environment").textContent = environment || "Not detected";
243
+ el("hit-internet").textContent = internetInput
244
+ ? (internetInput.checked ? "On" : "Off")
245
+ : "Not detected";
246
+ }
247
 
248
  function addEvent(data) {
249
  if (!el("hit-report").checked) return;
 
 
250
  const log = el("hit-json");
 
251
  log.textContent =
252
+ (log.textContent === "Waiting for events..." ? "" : log.textContent + "\n\n") +
253
+ JSON.stringify(data, null, 2);
 
254
  log.scrollTop = log.scrollHeight;
255
  }
256
 
257
  function getPrompt() {
258
+ const fields = [...document.querySelectorAll("textarea, [contenteditable='true']")];
 
 
259
 
260
  const candidates = fields.map(node => ({
261
  text: (node.value || node.innerText || node.textContent || "").trim(),
 
271
  .sort((a, b) => b.text.length - a.text.length);
272
 
273
  if (labelled.length) return labelled[0].text;
 
274
  candidates.sort((a, b) => b.text.length - a.text.length);
275
  return candidates[0]?.text || "";
276
  }
 
283
  ];
284
 
285
  for (const node of candidates) {
286
+ const url = node.currentSrc || node.src || node.href || "";
287
+ if (url && (/\.mp4(?:[?#]|$)/i.test(url) || url.startsWith("blob:"))) {
 
 
 
 
 
 
 
 
288
  return url;
289
  }
290
  }
 
291
  return "";
292
  }
293
 
 
305
  }
306
 
307
  function poll() {
308
+ updateKaggleOptions();
309
 
310
+ const prompt = getPrompt();
311
  if (prompt && prompt !== state.prompt) {
312
  state.prompt = prompt;
313
  state.checkpoints.clear();
314
  state.completedUrl = "";
 
315
  el("hit-prompt").textContent = prompt;
316
+ addEvent({...baseEvent("prompt"), message: "New prompt detected"});
 
 
 
 
317
  }
318
 
319
+ const messages = [...document.querySelectorAll('div[type="message"]')];
 
 
 
320
  const matching = messages
321
  .map(node => node.innerText || "")
322
  .filter(text => text.includes("H3 denoising:"));
323
 
324
  if (matching.length) {
325
+ const match = matching[matching.length - 1].match(
 
 
326
  /H3 denoising:\s*(\d+)%.*?\|\s*(\d+)\/(\d+)/
327
  );
328
 
 
343
  el("hit-bar").style.width = pct + "%";
344
  el("hit-progress").textContent = pct + "%";
345
  el("hit-step").textContent = `Step ${step} / ${total}`;
 
346
  el("hit-title-progress").textContent = "· " + pct + "%";
347
 
348
  for (const threshold of [25, 50, 75, 100]) {
349
  if (pct >= threshold && !state.checkpoints.has(threshold)) {
350
  state.checkpoints.add(threshold);
351
+ addEvent({...baseEvent("progress"), checkpoint: threshold});
 
 
 
 
352
  }
353
  }
354
  }
355
  }
356
 
357
  const videoUrl = getVideoUrl();
 
358
  if (videoUrl) {
359
  el("hit-url").textContent = videoUrl;
360
 
361
  if (state.progress >= 100 && videoUrl !== state.completedUrl) {
362
  state.completedUrl = videoUrl;
 
363
  addEvent({
364
  ...baseEvent("completed"),
365
  video: {
 
384
  poll();
385
  window.hitRenderMonitorTimer = setInterval(poll, 15000);
386
 
387
+ console.log("H3 Render Monitor v4 started.");
388
  })();