PageSourceSearch

https://www.fujisan-climb.jp/wp-content/themes/mtfuji-climbing-off…/assets/js/jmaVolcanoAlert.js?ver=1.0

js fujisan-climb.jp collected 2026-10-02 03:18:40 UTC 3,693 bytes, 119 lines download raw bytes

1(async () => {
2  const URL = "https://www.data.jma.go.jp/vois/data/report/activity_info/314.html";
3
4  const levelEl   = document.getElementById("volcano-level");
5  const noteEl    = document.getElementById("volcano-note");
6  const updatedEl = document.getElementById("volcano-updated");
7  const boxEl     = document.getElementById("volcano-box");
8  if (!levelEl || !boxEl) return;
9
10  function detectLang() {
11    const urlLang = new URLSearchParams(window.location.search).get('gtlang');
12    const htmlLang = document.documentElement.getAttribute('lang') || '';
13    const raw = (urlLang || htmlLang || 'ja').toLowerCase();
14
15    if (raw.startsWith('ja')) return 'ja';
16    return 'en';
17  }
18
19  const LANG = detectLang();
20
21  const I18N = {
22    ja: {
23      levelLabel: '噴火警戒レベル',
24      noteLabel: '警戒事項',
25      failed: '取得失敗',
26      notAvailable: '取得できませんでした',
27      noNote: '',
28      updatedFormat: (d) => {
29        const y = d.getFullYear();
30        const mo = String(d.getMonth() + 1).padStart(2, "0");
31        const da = String(d.getDate()).padStart(2, "0");
32        const hh = String(d.getHours()).padStart(2, "0");
33        const mm = String(d.getMinutes()).padStart(2, "0");
34        return `${y}/${mo}/${da} ${hh}:${mm}`;
35      },
36      noteMap: {
37        '特になし。': '特になし。'
38      }
39    },
40    en: {
41      levelLabel: 'Volcanic Alert Level',
42      noteLabel: 'Advisory',
43      failed: 'Failed to load',
44      notAvailable: 'Unavailable',
45      noNote: '',
46      updatedFormat: (d) => {
47        const y = d.getFullYear();
48        const mo = String(d.getMonth() + 1).padStart(2, "0");
49        const da = String(d.getDate()).padStart(2, "0");
50        const hh = String(d.getHours()).padStart(2, "0");
51        const mm = String(d.getMinutes()).padStart(2, "0");
52        return `${y}-${mo}-${da} ${hh}:${mm}`;
53      },
54      noteMap: {
55        '特になし。': 'None.'
56      }
57    }
58  };
59
60  const t = I18N[LANG] || I18N.ja;
61
62  function translateNote(note) {
63    const value = String(note || '').trim();
64    if (!value) return '';
65    return t.noteMap[value] || value;
66  }
67
68  try {
69    const html = await fetch(URL, { cache: "no-store" }).then(r => r.text());
70
71    const m = html.match(/噴火警戒レベル[  ]*([0-90-9])/);
72
73    const toHalf = (s) =>
74      String(s).replace(/[0-9]/g, d =>
75        String.fromCharCode(d.charCodeAt(0) - 0xFEE0)
76      );
77
78    const lv = m ? Number(toHalf(m[1])) : null;
79
80    const text = html
81      .replace(/<script[\s\S]*?<\/script>/gi, "")
82      .replace(/<style[\s\S]*?<\/style>/gi, "")
83      .replace(/<[^>]+>/g, "\n")
84      .replace(/\n{2,}/g, "\n")
85      .trim();
86
87    let note = "";
88    const idx = text.indexOf("現在の警戒事項等");
89    if (idx !== -1) {
90      const chunk = text.slice(idx, idx + 200);
91      const lines = chunk.split("\n").map(s => s.trim()).filter(Boolean);
92      note = lines[1] && lines[1] !== "現在の警戒事項等" ? lines[1] : (lines[2] || "");
93    }
94
95    const translatedNote = translateNote(note);
96
97    if (!lv) {
98      levelEl.textContent = `${t.levelLabel}: ${t.notAvailable}`;
99      boxEl.dataset.level = "0";
100    } else {
101      levelEl.textContent = `${t.levelLabel}: ${lv}`;
102      boxEl.dataset.level = String(lv);
103    }
104
105    if (noteEl) {
106      noteEl.textContent = translatedNote ? `${t.noteLabel}: ${translatedNote}` : t.noNote;
107    }
108
109    if (updatedEl) {
110      updatedEl.textContent = t.updatedFormat(new Date());
111    }
112  } catch (e) {
113    console.error(e);
114    levelEl.textContent = t.failed;
115    boxEl.dataset.level = "0";
116    if (noteEl) noteEl.textContent = "";
117    if (updatedEl) updatedEl.textContent = t.failed;
118  }
119})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.