deepresearch-flow 0.4.1__py3-none-any.whl → 0.5.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- deepresearch_flow/paper/db.py +34 -0
- deepresearch_flow/paper/db_ops.py +21 -7
- deepresearch_flow/paper/prompt_templates/deep_read_phi_system.j2 +6 -0
- deepresearch_flow/paper/prompt_templates/deep_read_phi_user.j2 +391 -0
- deepresearch_flow/paper/prompt_templates/eight_questions_phi_system.j2 +6 -0
- deepresearch_flow/paper/prompt_templates/eight_questions_phi_user.j2 +133 -0
- deepresearch_flow/paper/prompt_templates/simple_phi_system.j2 +6 -0
- deepresearch_flow/paper/prompt_templates/simple_phi_user.j2 +31 -0
- deepresearch_flow/paper/schemas/deep_read_phi_schema.json +30 -0
- deepresearch_flow/paper/template_registry.py +39 -0
- deepresearch_flow/paper/templates/deep_read_phi.md.j2 +40 -0
- deepresearch_flow/paper/web/app.py +106 -1
- deepresearch_flow/paper/web/constants.py +1 -0
- deepresearch_flow/paper/web/handlers/__init__.py +2 -1
- deepresearch_flow/paper/web/handlers/api.py +55 -0
- deepresearch_flow/paper/web/handlers/pages.py +105 -25
- deepresearch_flow/paper/web/markdown.py +230 -4
- deepresearch_flow/paper/web/pdfjs/web/viewer.html +57 -5
- deepresearch_flow/paper/web/pdfjs/web/viewer.js +5 -1
- deepresearch_flow/paper/web/static/css/main.css +8 -1
- deepresearch_flow/paper/web/static/js/detail.js +527 -124
- deepresearch_flow/paper/web/static/js/outline.js +48 -34
- deepresearch_flow/paper/web/static_assets.py +289 -0
- deepresearch_flow/paper/web/templates/detail.html +52 -66
- deepresearch_flow/paper/web/templates.py +7 -4
- deepresearch_flow/paper/web/text.py +8 -4
- deepresearch_flow/recognize/organize.py +9 -12
- deepresearch_flow/translator/fixers.py +15 -0
- {deepresearch_flow-0.4.1.dist-info → deepresearch_flow-0.5.1.dist-info}/METADATA +62 -2
- {deepresearch_flow-0.4.1.dist-info → deepresearch_flow-0.5.1.dist-info}/RECORD +34 -25
- {deepresearch_flow-0.4.1.dist-info → deepresearch_flow-0.5.1.dist-info}/WHEEL +0 -0
- {deepresearch_flow-0.4.1.dist-info → deepresearch_flow-0.5.1.dist-info}/entry_points.txt +0 -0
- {deepresearch_flow-0.4.1.dist-info → deepresearch_flow-0.5.1.dist-info}/licenses/LICENSE +0 -0
- {deepresearch_flow-0.4.1.dist-info → deepresearch_flow-0.5.1.dist-info}/top_level.txt +0 -0
|
@@ -8,8 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
function init() {
|
|
10
10
|
initFullscreen();
|
|
11
|
-
|
|
12
|
-
initFootnotes();
|
|
11
|
+
initMarkdownContent();
|
|
13
12
|
initBackToTop();
|
|
14
13
|
|
|
15
14
|
// View-specific initializers
|
|
@@ -28,6 +27,12 @@
|
|
|
28
27
|
// Back-to-top button
|
|
29
28
|
// ========================================
|
|
30
29
|
|
|
30
|
+
function escapeHtml(text) {
|
|
31
|
+
var div = document.createElement('div');
|
|
32
|
+
div.textContent = String(text || '');
|
|
33
|
+
return div.innerHTML;
|
|
34
|
+
}
|
|
35
|
+
|
|
31
36
|
function initBackToTop() {
|
|
32
37
|
var button = document.getElementById('backToTop');
|
|
33
38
|
if (!button) return;
|
|
@@ -81,66 +86,431 @@
|
|
|
81
86
|
}
|
|
82
87
|
|
|
83
88
|
// ========================================
|
|
84
|
-
// Markdown rendering (
|
|
89
|
+
// Markdown rendering (Marked + DOMPurify) + enhancements
|
|
85
90
|
// ========================================
|
|
86
91
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
92
|
+
var DOMPURIFY_CONFIG = {
|
|
93
|
+
ADD_TAGS: ['sup', 'table', 'thead', 'tbody', 'tfoot', 'tr', 'th', 'td', 'caption', 'colgroup', 'col'],
|
|
94
|
+
ADD_ATTR: ['colspan', 'rowspan', 'align'],
|
|
95
|
+
ALLOWED_URI_REGEXP: /^(?:(?:https?|mailto|tel|data:image\/)|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
function initMarkdownContent() {
|
|
99
|
+
var content = document.getElementById('content');
|
|
100
|
+
if (!content) return;
|
|
101
|
+
|
|
102
|
+
var markdownUrl = content.dataset.markdownUrl;
|
|
103
|
+
var rawMarkdownUrl = content.dataset.rawMarkdownUrl;
|
|
104
|
+
var imagesBaseUrl = content.dataset.imagesBaseUrl || '';
|
|
105
|
+
if (!markdownUrl) {
|
|
106
|
+
var rawText = content.textContent || '';
|
|
107
|
+
if (content.children.length === 0 && rawText.trim()) {
|
|
108
|
+
var rendered = renderMarkdown(rawText, imagesBaseUrl);
|
|
109
|
+
content.innerHTML = rendered;
|
|
110
|
+
} else {
|
|
111
|
+
rewriteRenderedImages(imagesBaseUrl);
|
|
112
|
+
}
|
|
113
|
+
if (rawMarkdownUrl) {
|
|
114
|
+
var statusEl = document.getElementById('markdownStatus');
|
|
115
|
+
var rawEl = document.getElementById('rawMarkdown');
|
|
116
|
+
if (statusEl) statusEl.textContent = 'Loading raw markdown...';
|
|
117
|
+
fetch(rawMarkdownUrl).then(function(res) {
|
|
118
|
+
if (!res.ok) throw new Error('Failed to load raw markdown');
|
|
119
|
+
return res.text();
|
|
120
|
+
}).then(function(text) {
|
|
121
|
+
if (rawEl) rawEl.textContent = text;
|
|
122
|
+
if (statusEl) statusEl.remove();
|
|
123
|
+
}).catch(function() {
|
|
124
|
+
if (statusEl) statusEl.textContent = 'Failed to load raw markdown.';
|
|
107
125
|
});
|
|
108
126
|
}
|
|
127
|
+
runMarkdownEnhancements();
|
|
128
|
+
initFootnotes();
|
|
129
|
+
dispatchContentUpdated();
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
109
132
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
133
|
+
var status = document.getElementById('markdownStatus');
|
|
134
|
+
var rawContainer = document.getElementById('rawMarkdown');
|
|
135
|
+
if (status) status.textContent = 'Loading markdown...';
|
|
136
|
+
|
|
137
|
+
fetch(markdownUrl).then(function(res) {
|
|
138
|
+
if (!res.ok) throw new Error('Failed to load markdown');
|
|
139
|
+
return res.text();
|
|
140
|
+
}).then(function(text) {
|
|
141
|
+
if (rawContainer) rawContainer.textContent = text;
|
|
142
|
+
var html = renderMarkdown(text, imagesBaseUrl);
|
|
143
|
+
content.innerHTML = html;
|
|
144
|
+
if (status) status.remove();
|
|
145
|
+
rewriteRenderedImages(imagesBaseUrl);
|
|
146
|
+
runMarkdownEnhancements();
|
|
147
|
+
initFootnotes();
|
|
148
|
+
dispatchContentUpdated();
|
|
149
|
+
}).catch(function() {
|
|
150
|
+
if (status) status.textContent = 'Failed to load markdown.';
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
function renderMarkdown(markdown, imagesBaseUrl) {
|
|
155
|
+
var normalized = normalizeFootnoteDefinitions(markdown || '');
|
|
156
|
+
var footnoteData = extractFootnotes(normalized);
|
|
157
|
+
var mathData = extractMathPlaceholders(footnoteData.markdown);
|
|
158
|
+
|
|
159
|
+
if (!window.marked) {
|
|
160
|
+
return '<pre><code>' + escapeHtml(markdown) + '</code></pre>';
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
var renderer = new window.marked.Renderer();
|
|
164
|
+
renderer.image = function(href, title, text) {
|
|
165
|
+
var src = rewriteImageUrl(href, imagesBaseUrl);
|
|
166
|
+
if (!src) return '';
|
|
167
|
+
var html = '<img src="' + escapeHtml(src) + '" alt="' + escapeHtml(text || '') + '"';
|
|
168
|
+
if (title) {
|
|
169
|
+
html += ' title="' + escapeHtml(title) + '"';
|
|
170
|
+
}
|
|
171
|
+
return html + ' />';
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
if (window.marked && window.marked.setOptions) {
|
|
175
|
+
window.marked.setOptions({ gfm: true, breaks: false });
|
|
176
|
+
}
|
|
177
|
+
var parsed = window.marked.parse(mathData.text || '', { renderer: renderer });
|
|
178
|
+
parsed = replaceMathPlaceholders(parsed, mathData.placeholders);
|
|
179
|
+
parsed = injectFootnotes(parsed, footnoteData);
|
|
180
|
+
if (window.DOMPurify) {
|
|
181
|
+
return window.DOMPurify.sanitize(parsed, DOMPURIFY_CONFIG);
|
|
182
|
+
}
|
|
183
|
+
return parsed;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
function rewriteImageUrl(url, imagesBaseUrl) {
|
|
187
|
+
if (!url) return url;
|
|
188
|
+
if (!imagesBaseUrl) return url;
|
|
189
|
+
if (isAbsoluteUrl(url)) return url;
|
|
190
|
+
|
|
191
|
+
var cleaned = String(url);
|
|
192
|
+
while (cleaned.indexOf('../') === 0) {
|
|
193
|
+
cleaned = cleaned.slice(3);
|
|
194
|
+
}
|
|
195
|
+
cleaned = cleaned.replace(/^\.\//, '');
|
|
196
|
+
cleaned = cleaned.replace(/^\/+/, '');
|
|
197
|
+
if (cleaned.indexOf('images/') === 0) {
|
|
198
|
+
cleaned = cleaned.slice('images/'.length);
|
|
199
|
+
}
|
|
200
|
+
var base = String(imagesBaseUrl).replace(/\/+$/, '');
|
|
201
|
+
return base + '/' + cleaned;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
function rewriteRenderedImages(imagesBaseUrl) {
|
|
205
|
+
if (!imagesBaseUrl) return;
|
|
206
|
+
var content = document.getElementById('content');
|
|
207
|
+
if (!content) return;
|
|
208
|
+
content.querySelectorAll('img').forEach(function(img) {
|
|
209
|
+
var src = img.getAttribute('src');
|
|
210
|
+
var rewritten = rewriteImageUrl(src, imagesBaseUrl);
|
|
211
|
+
if (rewritten && rewritten !== src) {
|
|
212
|
+
img.setAttribute('src', rewritten);
|
|
213
|
+
}
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
function isAbsoluteUrl(url) {
|
|
218
|
+
return /^(?:[a-z][a-z0-9+.\-]*:|\/\/|#)/i.test(url) || url.charAt(0) === '/';
|
|
219
|
+
}
|
|
118
220
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
221
|
+
function normalizeFootnoteDefinitions(text) {
|
|
222
|
+
return String(text || '').replace(/^\[\^([^\]]+)\]\s+/gm, '[^$1]: ');
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
function extractFootnotes(text) {
|
|
226
|
+
var lines = String(text || '').split(/\r?\n/);
|
|
227
|
+
var out = [];
|
|
228
|
+
var notes = {};
|
|
229
|
+
var order = [];
|
|
230
|
+
var i = 0;
|
|
231
|
+
while (i < lines.length) {
|
|
232
|
+
var line = lines[i];
|
|
233
|
+
var match = line.match(/^\[\^([^\]]+)\]:\s*(.*)$/);
|
|
234
|
+
if (!match) {
|
|
235
|
+
out.push(line);
|
|
236
|
+
i += 1;
|
|
237
|
+
continue;
|
|
238
|
+
}
|
|
239
|
+
var rawId = match[1].trim();
|
|
240
|
+
var id = sanitizeFootnoteId(rawId);
|
|
241
|
+
var content = match[2] || '';
|
|
242
|
+
var parts = [content];
|
|
243
|
+
i += 1;
|
|
244
|
+
while (i < lines.length) {
|
|
245
|
+
var next = lines[i];
|
|
246
|
+
if (/^\[\^([^\]]+)\]:\s*/.test(next)) {
|
|
247
|
+
break;
|
|
248
|
+
}
|
|
249
|
+
if (/^\s{2,}|\t/.test(next)) {
|
|
250
|
+
parts.push(next.replace(/^\s{2,}|\t/, ''));
|
|
251
|
+
i += 1;
|
|
252
|
+
continue;
|
|
253
|
+
}
|
|
254
|
+
if (next.trim() === '') {
|
|
255
|
+
parts.push('');
|
|
256
|
+
i += 1;
|
|
257
|
+
continue;
|
|
258
|
+
}
|
|
259
|
+
break;
|
|
260
|
+
}
|
|
261
|
+
if (!notes[id]) {
|
|
262
|
+
order.push(id);
|
|
122
263
|
}
|
|
264
|
+
notes[id] = parts.join('\n').trim();
|
|
265
|
+
}
|
|
266
|
+
return { markdown: out.join('\n'), notes: notes, order: order };
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
function injectFootnotes(html, footnoteData) {
|
|
270
|
+
if (!footnoteData || !footnoteData.order || footnoteData.order.length === 0) {
|
|
271
|
+
return html;
|
|
272
|
+
}
|
|
273
|
+
var notes = footnoteData.notes || {};
|
|
274
|
+
var order = footnoteData.order;
|
|
275
|
+
var replaced = String(html || '').replace(/\[\^([^\]]+)\]/g, function(match, rawId) {
|
|
276
|
+
var id = sanitizeFootnoteId(rawId);
|
|
277
|
+
if (!notes[id]) return match;
|
|
278
|
+
return '<sup class="footnote-ref"><a href="#fn' + id + '" id="fnref' + id + '">[' +
|
|
279
|
+
escapeHtml(rawId) + ']</a></sup>';
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
var items = order.map(function(id) {
|
|
283
|
+
var noteText = notes[id] || '';
|
|
284
|
+
var body = window.marked ? window.marked.parse(noteText) : '<p>' + escapeHtml(noteText) + '</p>';
|
|
285
|
+
return '<li id="fn' + id + '">' + body +
|
|
286
|
+
' <a class="footnote-backref" href="#fnref' + id + '">↩</a></li>';
|
|
287
|
+
}).join('');
|
|
288
|
+
var footnotesHtml = '<div class="footnotes"><ol>' + items + '</ol></div>';
|
|
289
|
+
return replaced + footnotesHtml;
|
|
290
|
+
}
|
|
123
291
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
292
|
+
function sanitizeFootnoteId(value) {
|
|
293
|
+
return String(value || '').replace(/[^a-zA-Z0-9_-]/g, '-');
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
function extractMathPlaceholders(text) {
|
|
297
|
+
var placeholders = {};
|
|
298
|
+
var out = [];
|
|
299
|
+
var idx = 0;
|
|
300
|
+
var inFence = false;
|
|
301
|
+
var fenceChar = '';
|
|
302
|
+
var fenceLen = 0;
|
|
303
|
+
var inlineDelimLen = 0;
|
|
304
|
+
|
|
305
|
+
function nextPlaceholder(value) {
|
|
306
|
+
var key = '@@MATH_' + Object.keys(placeholders).length + '@@';
|
|
307
|
+
placeholders[key] = value;
|
|
308
|
+
return key;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
while (idx < text.length) {
|
|
312
|
+
var atLineStart = idx === 0 || text[idx - 1] === '\n';
|
|
313
|
+
if (inlineDelimLen === 0 && atLineStart) {
|
|
314
|
+
var lineEnd = text.indexOf('\n', idx);
|
|
315
|
+
if (lineEnd === -1) lineEnd = text.length;
|
|
316
|
+
var line = text.slice(idx, lineEnd);
|
|
317
|
+
var stripped = line.replace(/^[ ]+/, '');
|
|
318
|
+
var leadingSpaces = line.length - stripped.length;
|
|
319
|
+
if (leadingSpaces <= 3 && stripped) {
|
|
320
|
+
var first = stripped[0];
|
|
321
|
+
if (first === '`' || first === '~') {
|
|
322
|
+
var runLen = 0;
|
|
323
|
+
while (runLen < stripped.length && stripped[runLen] === first) {
|
|
324
|
+
runLen += 1;
|
|
325
|
+
}
|
|
326
|
+
if (runLen >= 3) {
|
|
327
|
+
if (!inFence) {
|
|
328
|
+
inFence = true;
|
|
329
|
+
fenceChar = first;
|
|
330
|
+
fenceLen = runLen;
|
|
331
|
+
} else if (first === fenceChar && runLen >= fenceLen) {
|
|
332
|
+
inFence = false;
|
|
333
|
+
fenceChar = '';
|
|
334
|
+
fenceLen = 0;
|
|
335
|
+
}
|
|
336
|
+
out.push(line);
|
|
337
|
+
idx = lineEnd;
|
|
338
|
+
continue;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
if (inFence) {
|
|
345
|
+
out.push(text[idx]);
|
|
346
|
+
idx += 1;
|
|
347
|
+
continue;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
if (inlineDelimLen > 0) {
|
|
351
|
+
var delim = '`'.repeat(inlineDelimLen);
|
|
352
|
+
if (text.slice(idx, idx + inlineDelimLen) === delim) {
|
|
353
|
+
out.push(delim);
|
|
354
|
+
idx += inlineDelimLen;
|
|
355
|
+
inlineDelimLen = 0;
|
|
356
|
+
continue;
|
|
357
|
+
}
|
|
358
|
+
out.push(text[idx]);
|
|
359
|
+
idx += 1;
|
|
360
|
+
continue;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
if (text[idx] === '`') {
|
|
364
|
+
var inlineRun = 0;
|
|
365
|
+
while (idx + inlineRun < text.length && text[idx + inlineRun] === '`') {
|
|
366
|
+
inlineRun += 1;
|
|
367
|
+
}
|
|
368
|
+
inlineDelimLen = inlineRun;
|
|
369
|
+
out.push('`'.repeat(inlineRun));
|
|
370
|
+
idx += inlineRun;
|
|
371
|
+
continue;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
if (text.slice(idx, idx + 2) === '$$' && (idx === 0 || text[idx - 1] !== '\\')) {
|
|
375
|
+
var searchFrom = idx + 2;
|
|
376
|
+
var end = text.indexOf('$$', searchFrom);
|
|
377
|
+
while (end !== -1 && text[end - 1] === '\\') {
|
|
378
|
+
searchFrom = end + 2;
|
|
379
|
+
end = text.indexOf('$$', searchFrom);
|
|
380
|
+
}
|
|
381
|
+
if (end !== -1) {
|
|
382
|
+
out.push(nextPlaceholder(text.slice(idx, end + 2)));
|
|
383
|
+
idx = end + 2;
|
|
384
|
+
continue;
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
if (text[idx] === '$' && text.slice(idx, idx + 2) !== '$$' && (idx === 0 || text[idx - 1] !== '\\')) {
|
|
389
|
+
var lineEndInline = text.indexOf('\n', idx + 1);
|
|
390
|
+
if (lineEndInline === -1) lineEndInline = text.length;
|
|
391
|
+
var searchInline = idx + 1;
|
|
392
|
+
var endInline = text.indexOf('$', searchInline);
|
|
393
|
+
while (endInline !== -1 && endInline < lineEndInline && text[endInline - 1] === '\\') {
|
|
394
|
+
searchInline = endInline + 1;
|
|
395
|
+
endInline = text.indexOf('$', searchInline);
|
|
396
|
+
}
|
|
397
|
+
if (endInline !== -1 && endInline < lineEndInline) {
|
|
398
|
+
out.push(nextPlaceholder(text.slice(idx, endInline + 1)));
|
|
399
|
+
idx = endInline + 1;
|
|
400
|
+
continue;
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
out.push(text[idx]);
|
|
405
|
+
idx += 1;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
return { text: out.join(''), placeholders: placeholders };
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
function replaceMathPlaceholders(html, placeholders) {
|
|
412
|
+
var out = String(html || '');
|
|
413
|
+
Object.keys(placeholders || {}).forEach(function(key) {
|
|
414
|
+
var value = escapeHtml(placeholders[key]);
|
|
415
|
+
out = out.split(key).join(value);
|
|
416
|
+
});
|
|
417
|
+
return out;
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
function runMarkdownEnhancements() {
|
|
421
|
+
var content = document.getElementById('content');
|
|
422
|
+
if (!content) return;
|
|
423
|
+
|
|
424
|
+
// Markmap: convert fenced markmap blocks to autoloader containers
|
|
425
|
+
var markmapBlocks = 0;
|
|
426
|
+
document.querySelectorAll('code.language-markmap').forEach(function(code) {
|
|
427
|
+
var pre = code.parentElement;
|
|
428
|
+
if (!pre) return;
|
|
429
|
+
var wrapper = document.createElement('div');
|
|
430
|
+
wrapper.className = 'markmap';
|
|
431
|
+
var template = document.createElement('script');
|
|
432
|
+
template.type = 'text/template';
|
|
433
|
+
template.textContent = code.textContent || '';
|
|
434
|
+
wrapper.appendChild(template);
|
|
435
|
+
pre.replaceWith(wrapper);
|
|
436
|
+
markmapBlocks += 1;
|
|
437
|
+
});
|
|
438
|
+
function resizeMarkmaps() {
|
|
439
|
+
document.querySelectorAll('.markmap svg').forEach(function(svg) {
|
|
440
|
+
try {
|
|
441
|
+
var bbox = svg.getBBox();
|
|
442
|
+
if (!bbox || !bbox.height) {
|
|
443
|
+
svg.style.height = '800px';
|
|
444
|
+
svg.style.width = '100%';
|
|
445
|
+
return;
|
|
446
|
+
}
|
|
447
|
+
var height = Math.ceil(bbox.height * 2);
|
|
448
|
+
svg.style.height = height + 'px';
|
|
449
|
+
if (bbox.width && bbox.width > svg.clientWidth) {
|
|
450
|
+
svg.style.width = Math.ceil(bbox.width * 2) + 'px';
|
|
451
|
+
if (svg.parentElement) {
|
|
452
|
+
svg.parentElement.style.overflowX = 'auto';
|
|
453
|
+
}
|
|
454
|
+
} else {
|
|
455
|
+
svg.style.width = '100%';
|
|
456
|
+
}
|
|
457
|
+
} catch (err) {
|
|
458
|
+
// Ignore sizing errors
|
|
459
|
+
}
|
|
460
|
+
});
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
if (markmapBlocks && window.markmap && window.markmap.autoLoader && window.markmap.autoLoader.renderAll) {
|
|
464
|
+
window.markmap.autoLoader.renderAll();
|
|
465
|
+
setTimeout(resizeMarkmaps, 120);
|
|
466
|
+
setTimeout(resizeMarkmaps, 600);
|
|
467
|
+
setTimeout(resizeMarkmaps, 1600);
|
|
468
|
+
if (!window.__markmapResizeBound) {
|
|
469
|
+
window.__markmapResizeBound = true;
|
|
470
|
+
window.addEventListener('resize', function() {
|
|
471
|
+
setTimeout(resizeMarkmaps, 120);
|
|
133
472
|
});
|
|
134
473
|
}
|
|
135
474
|
}
|
|
136
475
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
476
|
+
// Mermaid: convert fenced code blocks to mermaid divs
|
|
477
|
+
document.querySelectorAll('code.language-mermaid').forEach(function(code) {
|
|
478
|
+
var pre = code.parentElement;
|
|
479
|
+
var div = document.createElement('div');
|
|
480
|
+
div.className = 'mermaid';
|
|
481
|
+
div.textContent = code.textContent;
|
|
482
|
+
pre.replaceWith(div);
|
|
483
|
+
});
|
|
484
|
+
|
|
485
|
+
if (window.mermaid) {
|
|
486
|
+
mermaid.initialize({ startOnLoad: false });
|
|
487
|
+
mermaid.run();
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
if (window.renderMathInElement) {
|
|
491
|
+
renderMathInElement(content, {
|
|
492
|
+
delimiters: [
|
|
493
|
+
{left: '$$', right: '$$', display: true},
|
|
494
|
+
{left: '$', right: '$', display: false},
|
|
495
|
+
{left: '\\(', right: '\\)', display: false},
|
|
496
|
+
{left: '\\[', right: '\\]', display: true}
|
|
497
|
+
],
|
|
498
|
+
throwOnError: false
|
|
499
|
+
});
|
|
141
500
|
}
|
|
142
501
|
}
|
|
143
502
|
|
|
503
|
+
function dispatchContentUpdated() {
|
|
504
|
+
var event;
|
|
505
|
+
try {
|
|
506
|
+
event = new CustomEvent('content:updated');
|
|
507
|
+
} catch (err) {
|
|
508
|
+
event = document.createEvent('Event');
|
|
509
|
+
event.initEvent('content:updated', true, true);
|
|
510
|
+
}
|
|
511
|
+
document.dispatchEvent(event);
|
|
512
|
+
}
|
|
513
|
+
|
|
144
514
|
// ========================================
|
|
145
515
|
// Footnote tooltips
|
|
146
516
|
// ========================================
|
|
@@ -305,92 +675,125 @@
|
|
|
305
675
|
var pdfUrl = document.body.dataset.pdfUrl;
|
|
306
676
|
if (!pdfUrl) return;
|
|
307
677
|
|
|
308
|
-
var
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
pageRendering =
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
678
|
+
var started = false;
|
|
679
|
+
var loadRequested = false;
|
|
680
|
+
|
|
681
|
+
function startPdf() {
|
|
682
|
+
if (started) return true;
|
|
683
|
+
var pdfJsLib = window.pdfjsLib;
|
|
684
|
+
if (!pdfJsLib || !pdfJsLib.getDocument) return false;
|
|
685
|
+
|
|
686
|
+
started = true;
|
|
687
|
+
pdfJsLib.GlobalWorkerOptions.workerSrc =
|
|
688
|
+
window.PDFJS_WORKER_SRC || '/pdfjs/build/pdf.worker.js';
|
|
689
|
+
|
|
690
|
+
var pdfDoc = null;
|
|
691
|
+
var pageNum = 1;
|
|
692
|
+
var pageRendering = false;
|
|
693
|
+
var pageNumPending = null;
|
|
694
|
+
var zoomLevel = 1.0;
|
|
695
|
+
var canvas = document.getElementById('the-canvas');
|
|
696
|
+
var ctx = canvas.getContext('2d');
|
|
697
|
+
|
|
698
|
+
function renderPage(num) {
|
|
699
|
+
pageRendering = true;
|
|
700
|
+
pdfDoc.getPage(num).then(function(page) {
|
|
701
|
+
var baseViewport = page.getViewport({scale: 1});
|
|
702
|
+
var containerWidth = canvas.clientWidth || baseViewport.width;
|
|
703
|
+
var fitScale = containerWidth / baseViewport.width;
|
|
704
|
+
var scale = fitScale * zoomLevel;
|
|
705
|
+
|
|
706
|
+
var viewport = page.getViewport({scale: scale});
|
|
707
|
+
var outputScale = window.devicePixelRatio || 1;
|
|
708
|
+
|
|
709
|
+
canvas.width = Math.floor(viewport.width * outputScale);
|
|
710
|
+
canvas.height = Math.floor(viewport.height * outputScale);
|
|
711
|
+
canvas.style.width = Math.floor(viewport.width) + 'px';
|
|
712
|
+
canvas.style.height = Math.floor(viewport.height) + 'px';
|
|
713
|
+
|
|
714
|
+
var transform = outputScale !== 1 ? [outputScale, 0, 0, outputScale, 0, 0] : null;
|
|
715
|
+
var renderContext = { canvasContext: ctx, viewport: viewport, transform: transform };
|
|
716
|
+
var renderTask = page.render(renderContext);
|
|
717
|
+
renderTask.promise.then(function() {
|
|
718
|
+
pageRendering = false;
|
|
719
|
+
document.getElementById('page_num').textContent = String(pageNum);
|
|
720
|
+
if (pageNumPending !== null) {
|
|
721
|
+
var next = pageNumPending;
|
|
722
|
+
pageNumPending = null;
|
|
723
|
+
renderPage(next);
|
|
724
|
+
}
|
|
725
|
+
});
|
|
348
726
|
});
|
|
349
|
-
}
|
|
350
|
-
}
|
|
727
|
+
}
|
|
351
728
|
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
729
|
+
function queueRenderPage(num) {
|
|
730
|
+
if (pageRendering) {
|
|
731
|
+
pageNumPending = num;
|
|
732
|
+
} else {
|
|
733
|
+
renderPage(num);
|
|
734
|
+
}
|
|
357
735
|
}
|
|
358
|
-
}
|
|
359
736
|
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
737
|
+
function onPrevPage() {
|
|
738
|
+
if (pageNum <= 1) return;
|
|
739
|
+
pageNum--;
|
|
740
|
+
queueRenderPage(pageNum);
|
|
741
|
+
}
|
|
365
742
|
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
743
|
+
function onNextPage() {
|
|
744
|
+
if (pageNum >= pdfDoc.numPages) return;
|
|
745
|
+
pageNum++;
|
|
746
|
+
queueRenderPage(pageNum);
|
|
747
|
+
}
|
|
371
748
|
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
749
|
+
function adjustZoom(delta) {
|
|
750
|
+
zoomLevel = Math.max(0.5, Math.min(3.0, zoomLevel + delta));
|
|
751
|
+
queueRenderPage(pageNum);
|
|
752
|
+
}
|
|
376
753
|
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
754
|
+
document.getElementById('prev').addEventListener('click', onPrevPage);
|
|
755
|
+
document.getElementById('next').addEventListener('click', onNextPage);
|
|
756
|
+
document.getElementById('zoomOut').addEventListener('click', function() { adjustZoom(-0.1); });
|
|
757
|
+
document.getElementById('zoomIn').addEventListener('click', function() { adjustZoom(0.1); });
|
|
381
758
|
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
759
|
+
pdfJsLib.getDocument(pdfUrl).promise.then(function(pdfDoc_) {
|
|
760
|
+
pdfDoc = pdfDoc_;
|
|
761
|
+
document.getElementById('page_count').textContent = String(pdfDoc.numPages);
|
|
762
|
+
renderPage(pageNum);
|
|
763
|
+
});
|
|
387
764
|
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
765
|
+
var resizeTimer = null;
|
|
766
|
+
window.addEventListener('resize', function() {
|
|
767
|
+
if (!pdfDoc) return;
|
|
768
|
+
if (resizeTimer) clearTimeout(resizeTimer);
|
|
769
|
+
resizeTimer = setTimeout(function() { queueRenderPage(pageNum); }, 150);
|
|
770
|
+
});
|
|
771
|
+
|
|
772
|
+
return true;
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
if (startPdf()) return;
|
|
776
|
+
|
|
777
|
+
if (!loadRequested && window.PDFJS_SCRIPT_SRC) {
|
|
778
|
+
loadRequested = true;
|
|
779
|
+
var script = document.createElement('script');
|
|
780
|
+
script.src = window.PDFJS_SCRIPT_SRC;
|
|
781
|
+
script.defer = true;
|
|
782
|
+
script.onload = function() {
|
|
783
|
+
try {
|
|
784
|
+
window.dispatchEvent(new Event('pdfjs:loaded'));
|
|
785
|
+
} catch (err) {
|
|
786
|
+
var event = document.createEvent('Event');
|
|
787
|
+
event.initEvent('pdfjs:loaded', true, true);
|
|
788
|
+
window.dispatchEvent(event);
|
|
789
|
+
}
|
|
790
|
+
};
|
|
791
|
+
document.head.appendChild(script);
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
window.addEventListener('pdfjs:loaded', function() {
|
|
795
|
+
startPdf();
|
|
796
|
+
}, { once: true });
|
|
394
797
|
}
|
|
395
798
|
|
|
396
799
|
// ========================================
|