画像アップロードに対応
Browse files
gemini.js
CHANGED
@@ -6,6 +6,55 @@ let lastIndexUpdateTimestamp = 0;
|
|
6 |
|
7 |
let replaceProofReadHistory = [];
|
8 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
9 |
function replaceProofRead(textarea, proofReadText) {
|
10 |
let novelContent1TextLines = document.getElementById("novelContent1").value.split("\n");
|
11 |
let proofReadTextLines = proofReadText.split("\n");
|
@@ -42,9 +91,31 @@ async function getModelList() {
|
|
42 |
});
|
43 |
}
|
44 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
45 |
async function proofRead(textarea) {
|
46 |
let content = textarea.value;
|
47 |
-
const ENDPOINT = `https://generativelanguage.googleapis.com/v1beta/models/gemini-
|
48 |
let prompt = `以下の文章を校正してください。文法がおかしい、誤字脱字、冗長な表現などを校正するのみに留め、内容は一切変更しないでください。\n\n${content}`;
|
49 |
const payload = {
|
50 |
method: 'POST',
|
@@ -52,31 +123,10 @@ async function proofRead(textarea) {
|
|
52 |
body: JSON.stringify({
|
53 |
contents: [{ parts: [{ text: prompt }] }],
|
54 |
generationConfig: {
|
55 |
-
"temperature":
|
56 |
-
"max_output_tokens":
|
57 |
},
|
58 |
-
safetySettings:
|
59 |
-
{
|
60 |
-
"category": "HARM_CATEGORY_HATE_SPEECH",
|
61 |
-
"threshold": "BLOCK_NONE"
|
62 |
-
},
|
63 |
-
{
|
64 |
-
"category": "HARM_CATEGORY_DANGEROUS_CONTENT",
|
65 |
-
"threshold": "BLOCK_NONE"
|
66 |
-
},
|
67 |
-
{
|
68 |
-
"category": "HARM_CATEGORY_HARASSMENT",
|
69 |
-
"threshold": "BLOCK_NONE"
|
70 |
-
},
|
71 |
-
{
|
72 |
-
"category": "HARM_CATEGORY_SEXUALLY_EXPLICIT",
|
73 |
-
"threshold": "BLOCK_NONE"
|
74 |
-
},
|
75 |
-
{
|
76 |
-
"category": "HARM_CATEGORY_CIVIC_INTEGRITY",
|
77 |
-
"threshold": "BLOCK_NONE"
|
78 |
-
}
|
79 |
-
]
|
80 |
})
|
81 |
};
|
82 |
let proofReadText;
|
@@ -128,32 +178,18 @@ function unmalform(text) {
|
|
128 |
}
|
129 |
|
130 |
async function summerize(text) {
|
131 |
-
const ENDPOINT = `https://generativelanguage.googleapis.com/v1beta/models/gemini-
|
132 |
const prompt = `以下の文章を240文字程度に要約してください:\n\n${text}`;
|
133 |
const payload = {
|
134 |
method: 'POST',
|
135 |
headers: {},
|
136 |
body: JSON.stringify({
|
137 |
contents: [{ parts: [{ text: prompt }] }],
|
138 |
-
generationConfig: {
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
},
|
144 |
-
{
|
145 |
-
"category": "HARM_CATEGORY_DANGEROUS_CONTENT",
|
146 |
-
"threshold": "BLOCK_NONE"
|
147 |
-
},
|
148 |
-
{
|
149 |
-
"category": "HARM_CATEGORY_HARASSMENT",
|
150 |
-
"threshold": "BLOCK_NONE"
|
151 |
-
},
|
152 |
-
{
|
153 |
-
"category": "HARM_CATEGORY_SEXUALLY_EXPLICIT",
|
154 |
-
"threshold": "BLOCK_NONE"
|
155 |
-
}
|
156 |
-
]
|
157 |
})
|
158 |
};
|
159 |
try {
|
@@ -294,7 +330,7 @@ function loadFromUserStorage() {
|
|
294 |
}
|
295 |
|
296 |
// 特別な処理が必要な要素
|
297 |
-
if (key === '
|
298 |
const inputElem = document.getElementById(`${key}Input`);
|
299 |
if (inputElem) {
|
300 |
inputElem.value = geminiClientData[key];
|
@@ -368,52 +404,71 @@ function createPayload() {
|
|
368 |
const lines = text.split('\n').filter(x => x);
|
369 |
|
370 |
let systemPrompt = `${partialEncodeURI(document.getElementById('generatePrompt').value)}`;
|
371 |
-
let prompt = `続きを書いて。${partialEncodeURI(document.getElementById('nextPrompt').value)} ${
|
372 |
-
|
373 |
-
|
374 |
-
|
375 |
-
|
376 |
-
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
|
382 |
-
|
383 |
-
|
384 |
-
|
385 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
386 |
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
"temperature": 1.0,
|
394 |
-
"max_output_tokens": 4096
|
395 |
},
|
396 |
-
|
397 |
-
|
398 |
-
|
399 |
-
|
400 |
-
|
401 |
-
|
402 |
-
|
403 |
-
"
|
404 |
-
|
405 |
-
|
406 |
-
|
407 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
408 |
},
|
409 |
-
|
410 |
-
|
411 |
-
|
412 |
-
|
413 |
-
|
414 |
-
}),
|
415 |
-
mode: 'cors'
|
416 |
-
};
|
417 |
}
|
418 |
|
419 |
function debugPrompt() {
|
@@ -601,7 +656,7 @@ function createOpenAIPayload() {
|
|
601 |
"role": "assistant"
|
602 |
},
|
603 |
{
|
604 |
-
"content":
|
605 |
"role": "user"
|
606 |
},
|
607 |
{
|
@@ -742,7 +797,7 @@ async function tokenCount() {
|
|
742 |
}
|
743 |
|
744 |
async function createDraft() {
|
745 |
-
const ENDPOINT = `https://generativelanguage.googleapis.com/v1beta/models/gemini-
|
746 |
let payload = createPayload();
|
747 |
const response = await fetch(ENDPOINT, payload);
|
748 |
const data = await response.json();
|
@@ -768,9 +823,9 @@ async function Request() {
|
|
768 |
|
769 |
if (selectedEndpoint.startsWith('models/gemini')) {
|
770 |
ENDPOINT = `https://generativelanguage.googleapis.com/v1beta/${selectedEndpoint}:generateContent?key=` + document.getElementById('geminiApiKey').value;
|
771 |
-
payload = createPayload();
|
772 |
} else if (selectedEndpoint === 'restart') {
|
773 |
-
ENDPOINT = `https://generativelanguage.googleapis.com/v1beta/models/gemini-
|
774 |
document.getElementById('novelContent2').value = '(下書き中)';
|
775 |
try {
|
776 |
draft = await createDraft();
|
@@ -785,7 +840,7 @@ async function Request() {
|
|
785 |
}
|
786 |
//document.getElementById('novelContent2').value = `# 下書き\n${draft}\n\n# リライト\n`;
|
787 |
document.getElementById('novelContent2').value = "";
|
788 |
-
const prompt = `以下の文章を、要件を満たす形に直したものを返信してください。\n返信内容は直した後のテキストのみになるようにし他の内容が混ざらないようにしてください。\n\n# 要件\n- 元の文章や会話の言い回しは不自然な日本語になっている部分もかなり多いので、根本的に書き替えること。ただし、登場人物の一人称や他者への呼称は変更しないこと。\n- 物語の大筋やキャラクターの性格は保ったまま、文章は全く別物に書き換える必要がある。元のテキストそのものはなるべく流用しないで新規に書くよう心掛ける。\n- 随所にレトリックを駆使しつつも凝り過ぎて読み辛くなることのないシンプルな美文になることを意識する。\n-
|
789 |
payload = {
|
790 |
method: 'POST',
|
791 |
headers: {},
|
@@ -800,32 +855,15 @@ async function Request() {
|
|
800 |
"role": "user"
|
801 |
}
|
802 |
],
|
803 |
-
|
804 |
"temperature": 1.0,
|
805 |
-
"max_output_tokens":
|
806 |
},
|
807 |
-
safetySettings:
|
808 |
-
{
|
809 |
-
"category": "HARM_CATEGORY_HATE_SPEECH",
|
810 |
-
"threshold": "BLOCK_NONE"
|
811 |
-
},
|
812 |
-
{
|
813 |
-
"category": "HARM_CATEGORY_DANGEROUS_CONTENT",
|
814 |
-
"threshold": "BLOCK_NONE"
|
815 |
-
},
|
816 |
-
{
|
817 |
-
"category": "HARM_CATEGORY_HARASSMENT",
|
818 |
-
"threshold": "BLOCK_NONE"
|
819 |
-
},
|
820 |
-
{
|
821 |
-
"category": "HARM_CATEGORY_SEXUALLY_EXPLICIT",
|
822 |
-
"threshold": "BLOCK_NONE"
|
823 |
-
}
|
824 |
-
]
|
825 |
}),
|
826 |
mode: 'cors'
|
827 |
};
|
828 |
-
selectedEndpoint = 'models/gemini-
|
829 |
} else {
|
830 |
ENDPOINT = document.getElementById('openaiEndpoint').value;
|
831 |
payload = createOpenAIPayload();
|
@@ -1277,7 +1315,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
|
1277 |
});
|
1278 |
|
1279 |
// 設定画面の要素のイベントリスナー
|
1280 |
-
['memo', 'geminiApiKey', 'endpointSelect', 'openaiEndpoint', 'openaiHeaders', 'openaiJsonBody', '
|
1281 |
document.getElementById(id).addEventListener('input', () => {
|
1282 |
saveToUserStorage(true);
|
1283 |
});
|
@@ -1326,11 +1364,11 @@ document.addEventListener('DOMContentLoaded', function () {
|
|
1326 |
|
1327 |
// 初期表示時にも実行
|
1328 |
updateNavbarBrand();
|
1329 |
-
generateIndexMenu(true);
|
1330 |
updateAllAccordionHeaderCounts();
|
1331 |
|
1332 |
// diff2htmlライブラリの読み込み
|
1333 |
const script = document.createElement('script');
|
1334 |
script.src = 'https://cdnjs.cloudflare.com/ajax/libs/jsdiff/5.1.0/diff.min.js';
|
1335 |
document.head.appendChild(script);
|
1336 |
-
});
|
|
|
6 |
|
7 |
let replaceProofReadHistory = [];
|
8 |
|
9 |
+
// 画像アップロード関連の機能
|
10 |
+
let imageCounter = 0;
|
11 |
+
|
12 |
+
function addImageInput() {
|
13 |
+
const container = document.getElementById('imageInputsContainer');
|
14 |
+
const imageInputGroup = document.createElement('div');
|
15 |
+
imageInputGroup.className = 'input-group mb-2';
|
16 |
+
imageInputGroup.id = `imageGroup_${imageCounter}`;
|
17 |
+
|
18 |
+
const input = document.createElement('input');
|
19 |
+
input.type = 'file';
|
20 |
+
input.className = 'form-control';
|
21 |
+
input.accept = 'image/*';
|
22 |
+
input.id = `imageInput_${imageCounter}`;
|
23 |
+
|
24 |
+
const deleteButton = document.createElement('button');
|
25 |
+
deleteButton.className = 'btn btn-outline-danger';
|
26 |
+
deleteButton.innerHTML = '<i class="fas fa-trash"></i>';
|
27 |
+
deleteButton.onclick = function() {
|
28 |
+
removeImageInput(this.parentElement);
|
29 |
+
};
|
30 |
+
|
31 |
+
imageInputGroup.appendChild(input);
|
32 |
+
imageInputGroup.appendChild(deleteButton);
|
33 |
+
container.appendChild(imageInputGroup);
|
34 |
+
|
35 |
+
imageCounter++;
|
36 |
+
}
|
37 |
+
|
38 |
+
function removeImageInput(element) {
|
39 |
+
if (element) {
|
40 |
+
element.remove();
|
41 |
+
}
|
42 |
+
}
|
43 |
+
|
44 |
+
function getAttachedImages() {
|
45 |
+
const images = [];
|
46 |
+
const container = document.getElementById('imageInputsContainer');
|
47 |
+
const inputs = container.getElementsByTagName('input');
|
48 |
+
|
49 |
+
for (let input of inputs) {
|
50 |
+
if (input.files && input.files[0]) {
|
51 |
+
images.push(input.files[0]);
|
52 |
+
}
|
53 |
+
}
|
54 |
+
|
55 |
+
return images;
|
56 |
+
}
|
57 |
+
|
58 |
function replaceProofRead(textarea, proofReadText) {
|
59 |
let novelContent1TextLines = document.getElementById("novelContent1").value.split("\n");
|
60 |
let proofReadTextLines = proofReadText.split("\n");
|
|
|
91 |
});
|
92 |
}
|
93 |
|
94 |
+
function getSafetySettings(endpoint) {
|
95 |
+
const threshold = endpoint.startsWith('models/model-exp-') ? 'OFF' : 'BLOCK_NONE';
|
96 |
+
return [
|
97 |
+
{
|
98 |
+
"category": "HARM_CATEGORY_HATE_SPEECH",
|
99 |
+
"threshold": threshold
|
100 |
+
},
|
101 |
+
{
|
102 |
+
"category": "HARM_CATEGORY_DANGEROUS_CONTENT",
|
103 |
+
"threshold": threshold
|
104 |
+
},
|
105 |
+
{
|
106 |
+
"category": "HARM_CATEGORY_HARASSMENT",
|
107 |
+
"threshold": threshold
|
108 |
+
},
|
109 |
+
{
|
110 |
+
"category": "HARM_CATEGORY_SEXUALLY_EXPLICIT",
|
111 |
+
"threshold": threshold
|
112 |
+
}
|
113 |
+
];
|
114 |
+
}
|
115 |
+
|
116 |
async function proofRead(textarea) {
|
117 |
let content = textarea.value;
|
118 |
+
const ENDPOINT = `https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash-exp:generateContent?key=${document.getElementById('geminiApiKey').value}`;
|
119 |
let prompt = `以下の文章を校正してください。文法がおかしい、誤字脱字、冗長な表現などを校正するのみに留め、内容は一切変更しないでください。\n\n${content}`;
|
120 |
const payload = {
|
121 |
method: 'POST',
|
|
|
123 |
body: JSON.stringify({
|
124 |
contents: [{ parts: [{ text: prompt }] }],
|
125 |
generationConfig: {
|
126 |
+
"temperature": parseFloat(document.getElementById('temperature').value),
|
127 |
+
"max_output_tokens": 8192
|
128 |
},
|
129 |
+
safetySettings: getSafetySettings('models/gemini-2.0-flash-exp')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
130 |
})
|
131 |
};
|
132 |
let proofReadText;
|
|
|
178 |
}
|
179 |
|
180 |
async function summerize(text) {
|
181 |
+
const ENDPOINT = `https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash-exp:generateContent?key=${document.getElementById('geminiApiKey').value}`;
|
182 |
const prompt = `以下の文章を240文字程度に要約してください:\n\n${text}`;
|
183 |
const payload = {
|
184 |
method: 'POST',
|
185 |
headers: {},
|
186 |
body: JSON.stringify({
|
187 |
contents: [{ parts: [{ text: prompt }] }],
|
188 |
+
generationConfig: {
|
189 |
+
temperature: parseFloat(document.getElementById('temperature').value),
|
190 |
+
max_output_tokens: 512
|
191 |
+
},
|
192 |
+
safetySettings: getSafetySettings('models/gemini-2.0-flash-exp')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
193 |
})
|
194 |
};
|
195 |
try {
|
|
|
330 |
}
|
331 |
|
332 |
// 特別な処理が必要な要素
|
333 |
+
if (key === 'encodeLength' || key === 'contentWidth') {
|
334 |
const inputElem = document.getElementById(`${key}Input`);
|
335 |
if (inputElem) {
|
336 |
inputElem.value = geminiClientData[key];
|
|
|
404 |
const lines = text.split('\n').filter(x => x);
|
405 |
|
406 |
let systemPrompt = `${partialEncodeURI(document.getElementById('generatePrompt').value)}`;
|
407 |
+
let prompt = `続きを書いて。${partialEncodeURI(document.getElementById('nextPrompt').value)} ${systemPrompt}`;
|
408 |
+
|
409 |
+
// 画像の取得と変換
|
410 |
+
const attachedImages = getAttachedImages();
|
411 |
+
const imagePromises = attachedImages.map(file => {
|
412 |
+
return new Promise((resolve, reject) => {
|
413 |
+
const reader = new FileReader();
|
414 |
+
reader.onload = () => {
|
415 |
+
// Base64エンコードされた画像データを取得("data:image/jpeg;base64,"などのプレフィックスを除去)
|
416 |
+
const base64Data = reader.result.split(',')[1];
|
417 |
+
resolve({
|
418 |
+
inline_data: {
|
419 |
+
data: base64Data,
|
420 |
+
mime_type: file.type
|
421 |
+
}
|
422 |
+
});
|
423 |
+
};
|
424 |
+
reader.onerror = reject;
|
425 |
+
reader.readAsDataURL(file);
|
426 |
+
});
|
427 |
+
});
|
428 |
|
429 |
+
// 画像の処理が完了してからペイロードを作成
|
430 |
+
return Promise.all(imagePromises).then(imageParts => {
|
431 |
+
let messages = [
|
432 |
+
{
|
433 |
+
"role": "user",
|
434 |
+
"parts": [{ "text": "." }]
|
|
|
|
|
435 |
},
|
436 |
+
{
|
437 |
+
"role": "model",
|
438 |
+
"parts": [{ "text": partialEncodeURI(lines.join("\n")) }]
|
439 |
+
},
|
440 |
+
{
|
441 |
+
"role": "user",
|
442 |
+
"parts": [
|
443 |
+
{ "text": prompt },
|
444 |
+
...imageParts
|
445 |
+
]
|
446 |
+
}
|
447 |
+
];
|
448 |
+
|
449 |
+
let max_output_tokens = 4096;
|
450 |
+
let selectedEndpoint = document.getElementById('endpointSelect').value;
|
451 |
+
if (selectedEndpoint.match(/^models\/gemini-2\.0/)) {
|
452 |
+
max_output_tokens = 8192;
|
453 |
+
}
|
454 |
+
if (selectedEndpoint.match(/^models\/gemini-2\.0-flash-thinking/)) {
|
455 |
+
max_output_tokens = 65536;
|
456 |
+
}
|
457 |
+
|
458 |
+
return {
|
459 |
+
method: 'POST',
|
460 |
+
headers: {},
|
461 |
+
body: JSON.stringify({
|
462 |
+
contents: messages,
|
463 |
+
generationConfig: {
|
464 |
+
"temperature": parseFloat(document.getElementById('temperature').value),
|
465 |
+
"max_output_tokens": max_output_tokens
|
466 |
},
|
467 |
+
safetySettings: getSafetySettings(selectedEndpoint)
|
468 |
+
}),
|
469 |
+
mode: 'cors'
|
470 |
+
};
|
471 |
+
});
|
|
|
|
|
|
|
472 |
}
|
473 |
|
474 |
function debugPrompt() {
|
|
|
656 |
"role": "assistant"
|
657 |
},
|
658 |
{
|
659 |
+
"content": `続きを書いてください。${partialEncodeURI(document.getElementById('nextPrompt').value)}`,
|
660 |
"role": "user"
|
661 |
},
|
662 |
{
|
|
|
797 |
}
|
798 |
|
799 |
async function createDraft() {
|
800 |
+
const ENDPOINT = `https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash-exp:generateContent?key=` + document.getElementById('geminiApiKey').value;
|
801 |
let payload = createPayload();
|
802 |
const response = await fetch(ENDPOINT, payload);
|
803 |
const data = await response.json();
|
|
|
823 |
|
824 |
if (selectedEndpoint.startsWith('models/gemini')) {
|
825 |
ENDPOINT = `https://generativelanguage.googleapis.com/v1beta/${selectedEndpoint}:generateContent?key=` + document.getElementById('geminiApiKey').value;
|
826 |
+
payload = await createPayload(); // 非同期処理を待機
|
827 |
} else if (selectedEndpoint === 'restart') {
|
828 |
+
ENDPOINT = `https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash-exp:generateContent?key=` + document.getElementById('geminiApiKey').value;
|
829 |
document.getElementById('novelContent2').value = '(下書き中)';
|
830 |
try {
|
831 |
draft = await createDraft();
|
|
|
840 |
}
|
841 |
//document.getElementById('novelContent2').value = `# 下書き\n${draft}\n\n# リライト\n`;
|
842 |
document.getElementById('novelContent2').value = "";
|
843 |
+
const prompt = `以下の文章を、要件を満たす形に直したものを返信してください。\n返信内容は直した後のテキストのみになるようにし他の内容が混ざらないようにしてください。\n\n# 要件\n- 元の文章や会話の言い回しは不自然な日本語になっている部分もかなり多いので、根本的に書き替えること。ただし、登場人物の一人称や他者への呼称は変更しないこと。\n- 物語の大筋やキャラクターの性格は保ったまま、文章は全く別物に書き換える必要がある。元のテキストそのものはなるべく流用しないで新規に書くよう心掛ける。\n- 随所にレトリックを駆使しつつも凝り過ぎて読み辛くなることのないシンプルな美文になることを意識する。\n- 登場人物の会話を重視し、文脈を読み取り元のキャラクター設定に合った台詞回しを保ちつつ、より生き生きとした魅力的な物像に仕上がるようにする。\n- 細かい動作や心理描写のディテールを重視し、よりリアルな描写になるようにする。\n- 文章の終わりに「。」をつける、字下げをするなど、一般的な小説のフォーマットに従う書き方にする。\n\n# 文章\n${draft}`;
|
844 |
payload = {
|
845 |
method: 'POST',
|
846 |
headers: {},
|
|
|
855 |
"role": "user"
|
856 |
}
|
857 |
],
|
858 |
+
generationConfig: {
|
859 |
"temperature": 1.0,
|
860 |
+
"max_output_tokens": 8192
|
861 |
},
|
862 |
+
safetySettings: getSafetySettings('models/gemini-2.0-flash-exp')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
863 |
}),
|
864 |
mode: 'cors'
|
865 |
};
|
866 |
+
selectedEndpoint = 'models/gemini-2.0-flash-exp';
|
867 |
} else {
|
868 |
ENDPOINT = document.getElementById('openaiEndpoint').value;
|
869 |
payload = createOpenAIPayload();
|
|
|
1315 |
});
|
1316 |
|
1317 |
// 設定画面の要素のイベントリスナー
|
1318 |
+
['memo', 'geminiApiKey', 'endpointSelect', 'openaiEndpoint', 'openaiHeaders', 'openaiJsonBody', 'encodeLength', 'temperature'].forEach(id => {
|
1319 |
document.getElementById(id).addEventListener('input', () => {
|
1320 |
saveToUserStorage(true);
|
1321 |
});
|
|
|
1364 |
|
1365 |
// 初期表示時にも実行
|
1366 |
updateNavbarBrand();
|
1367 |
+
//generateIndexMenu(true);
|
1368 |
updateAllAccordionHeaderCounts();
|
1369 |
|
1370 |
// diff2htmlライブラリの読み込み
|
1371 |
const script = document.createElement('script');
|
1372 |
script.src = 'https://cdnjs.cloudflare.com/ajax/libs/jsdiff/5.1.0/diff.min.js';
|
1373 |
document.head.appendChild(script);
|
1374 |
+
});
|