aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJieiku2023-09-27 12:48:48 -0700
committerJieiku2023-09-27 12:48:48 -0700
commit0968b8ffbae62db8fcbb2f724d61bf24642072e2 (patch)
tree3bf4b1ca36e73ee3c01efb43f93af7bc97450fd2
parentf5d32f6032ea172d0f1076b1fa04c96c9205285b (diff)
downloadabridge-0968b8ffbae62db8fcbb2f724d61bf24642072e2.tar.gz
abridge-0968b8ffbae62db8fcbb2f724d61bf24642072e2.tar.bz2
abridge-0968b8ffbae62db8fcbb2f724d61bf24642072e2.zip
Fixes for Offline Site Build
-rw-r--r--config.toml12
-rw-r--r--content/archive/_index.es.md6
-rw-r--r--package_abridge.js326
-rw-r--r--static/sw.js2
-rw-r--r--static/sw.min.js2
-rw-r--r--templates/macros/macros.html5
-rw-r--r--templates/page.html8
7 files changed, 187 insertions, 174 deletions
diff --git a/config.toml b/config.toml
index a7612d6..e145628 100644
--- a/config.toml
+++ b/config.toml
@@ -1,7 +1,7 @@
# do NOT include a trailing slash on the base URL
-base_url="https://abridge.netlify.app"
+base_url = "https://abridge.netlify.app"
# Usable site directly from disk, Including Search: "/home/jieiku/.dev/abridge/public"
-# Also set index_format = "elasticlunr_javascript", and in [extra] uglyurls = true, integrity = false
+# Also set index format = "elasticlunr_javascript", and in [extra] uglyurls = true, integrity = false
# If you use the npm/node script then all you have to do is set offline = true, and everything else is automatic.
title = "Abridge"
@@ -24,7 +24,8 @@ taxonomies = [
#hard_link_static = false # set to true to hard link instead of copying, useful for very large files.
[search] # Options specific to elasticlunr search.
-index_format = "elasticlunr_json" # elasticlunr_json, elasticlunr_javascript
+# index format can be: elasticlunr_json or elasticlunr_javascript
+index_format = "elasticlunr_json"
include_title = true # include title of page/section in index
include_description = true # include description of page/section in index
include_content = true # include rendered content of page/section in index
@@ -94,7 +95,7 @@ toc = true
recent = true # TOC / index
recent_items = 15
series = true
-series_items = 9 # Max number of items to display in series list
+series_items = 9 # Max number of items to display in series list, use 0 to disable
#Series_parts = "$NUMBER_OF_PARTS part Series"
meta_index = { position="bottom", size="s90", author=false, readtime=false, readstring="min", date=true, updated=false, categories_tags=true, divider="" }
@@ -200,7 +201,8 @@ researchgate = "your-profile-id"
###############################################################################
# do NOT include a trailing slash on the online URL
-online_url="https://abridge.netlify.app"
+online_url = "https://abridge.netlify.app"
+online_indexformat = "elasticlunr_json"# used to restore your preferred index format when offline = false
offline = false # implies uglyurls=true and integrity=false, when true NPM/node will automatically set the path for the base_url, it will build the site, then set the base_url back to what it was.
uglyurls = false # if set to true then links are generated with the full path. eg https://abridge.netlify.app/index.html
diff --git a/content/archive/_index.es.md b/content/archive/_index.es.md
new file mode 100644
index 0000000..85198a5
--- /dev/null
+++ b/content/archive/_index.es.md
@@ -0,0 +1,6 @@
++++
+template = "archive.html"
+
+[extra]
+sec = ""
++++
diff --git a/package_abridge.js b/package_abridge.js
index eb02098..4f12bb5 100644
--- a/package_abridge.js
+++ b/package_abridge.js
@@ -4,17 +4,12 @@ const TOML = require('fast-toml');
const UglifyJS = require('uglify-js');
const jsonminify = require("jsonminify");
const replace = require('replace-in-file');
-//const crypto = require('crypto'); (disabled for now, because unused)
-
-// check if abridge is used directly or as a theme.
-bpath = '';
-if (fs.existsSync('./themes')) {
- bpath = 'themes/abridge/';
-}
+const util = require("util");
+const { exec } = require("child_process");
+const execPromise = util.promisify(exec);
const tomlString = String(fs.readFileSync('config.toml'));
const data = TOML.parse(tomlString);
-
const js_prestyle = data.extra.js_prestyle;
const js_switcher = data.extra.js_switcher;
const js_email_encode = data.extra.js_email_encode;
@@ -25,7 +20,7 @@ const uglyurls = data.extra.uglyurls;
const js_bundle = data.extra.js_bundle;
const offline = data.extra.offline;
const online_url = data.extra.online_url;
-const sitePath = path.resolve('public');// used for offline builds
+const online_indexformat = data.extra.online_indexformat;
const pwa = data.extra.pwa;
const pwa_VER = data.extra.pwa_VER;
const pwa_NORM_TTL = data.extra.pwa_NORM_TTL;
@@ -36,23 +31,169 @@ const pwa_TTL_EXEMPT = data.extra.pwa_TTL_EXEMPT;
const pwa_cache_all = data.extra.pwa_cache_all;
const pwa_BASE_CACHE_FILES = data.extra.pwa_BASE_CACHE_FILES;
-if (offline === false) {
- replace.sync({files: 'config.toml', from: /base_url.*=.*/g, to: "base_url=\""+online_url+"\""});
-} else if (offline === true) {
- replace.sync({files: 'config.toml', from: /base_url.*=.*/g, to: "base_url=\""+sitePath+"\""});
+async function execWrapper(cmd) {
+ const { stdout, stderr } = await execPromise(cmd);
+ if (stdout) {
+ console.log(stdout);
+ }
+ if (stderr) {
+ console.log('Error: '+stderr);
+ }
}
-base_url = data.base_url;
-if (base_url.slice(-1) == "/") {
- base_url = base_url.slice(0, -1);
-}
+async function abridge() {
+ if (offline === false) {
+ replace.sync({files: 'config.toml', from: /base_url.*=.*/g, to: "base_url = \""+online_url+"\""});
+ replace.sync({files: 'config.toml', from: /index_format.*=.*/g, to: "index_format = \""+online_indexformat+"\""});
+ } else if (offline === true) {
+ replace.sync({files: 'config.toml', from: /base_url.*=.*/g, to: "base_url = \""+__dirname+"\/public\""});
+ replace.sync({files: 'config.toml', from: /index_format.*=.*/g, to: "index_format = \"elasticlunr_javascript\""});
+ }
+
+ console.log('Zola Build to generate files for minification:');
+ await execWrapper('zola build');
+
+ // check if abridge is used directly or as a theme.
+ bpath = '';
+ if (fs.existsSync('./themes')) {
+ bpath = 'themes/abridge/';
+ }
-// disabled for now, because unused
-// function checksum(input) {
-// var hash = crypto.createHash('sha384').update(input, 'utf8');
-// var hashBase64 = hash.digest('base64');
-// return 'sha384-' + hashBase64;
-// }
+ base_url = data.base_url;
+ if (base_url.slice(-1) == "/") {
+ base_url = base_url.slice(0, -1);
+ }
+
+ if (search_library === 'elasticlunr') {
+ if (fs.existsSync('content/static/stork_toml.md')) {
+ replace.sync({files: 'content/static/stork_toml.md', from: /draft.*=.*/g, to: "draft = true"});
+ }
+ if (fs.existsSync('content/static/tinysearch_json.md')) {
+ replace.sync({files: 'content/static/tinysearch_json.md', from: /draft.*=.*/g, to: "draft = true"});
+ }
+ } else if (search_library === 'tinysearch') {
+ if (!fs.existsSync('content/static/tinysearch_json.md')) {// 'content/static/tinysearch_json.md' file is missing, copy from abridge theme.
+ fs.copyFileSync(bpath+'content/static/tinysearch_json.md', 'content/static/tinysearch_json.md',fs.constants.COPYFILE_EXCL);
+ }
+ if (fs.existsSync('content/static/stork_toml.md')) {
+ replace.sync({files: 'content/static/stork_toml.md', from: /draft.*=.*/g, to: "draft = true"});
+ }
+ if (fs.existsSync('content/static/tinysearch_json.md')) {
+ replace.sync({files: 'content/static/tinysearch_json.md', from: /draft.*=.*/g, to: "draft = false"});
+ }
+ // zola build && mkdir -p tmp && tinysearch --optimize --path tmp public/data_tinysearch/index.html && rsync -avz tmp/*.wasm static/ && rm -rf tmp
+ } else if (search_library === 'stork') {
+
+ if (!fs.existsSync('content/static/stork_toml.md')) {// 'content/static/stork_toml.md' file is missing, copy from abridge theme.
+ fs.copyFileSync(bpath+'content/static/stork_toml.md', 'content/static/stork_toml.md',fs.constants.COPYFILE_EXCL);
+ }
+ if (fs.existsSync('content/static/stork_toml.md')) {
+ replace.sync({files: 'content/static/stork_toml.md', from: /draft.*=.*/g, to: "draft = false"});
+ }
+ if (fs.existsSync('content/static/tinysearch_json.md')) {
+ replace.sync({files: 'content/static/tinysearch_json.md', from: /draft.*=.*/g, to: "draft = true"});
+ }
+ // zola build && stork build --input public/data_stork/index.html --output static/stork.st
+ }
+
+ if (pwa) {// Update pwa settings, file list, and hashes.
+ // update from abridge theme.
+ fs.copyFileSync(bpath+'static/sw.js', 'static/sw.js');
+ fs.copyFileSync(bpath+'static/js/sw_load.js', 'static/js/sw_load.js');
+ // Update settings in PWA javascript file, using options parsed from config.toml. sw.min.js?v=3.10.0", "++"
+ if (fs.existsSync('static/js/sw_load.js')) {
+ sw_load_min = '.js?v=';
+ if (js_bundle) {
+ sw_load_min = '.min.js?v=';
+ }
+ replace.sync({files: 'static/js/sw_load.js', from: /sw.*v=.*/g, to: "sw"+sw_load_min+pwa_VER+"\","});
+ }
+ if (fs.existsSync('static/sw.js')) {
+ replace.sync({files: 'static/sw.js', from: /NORM_TTL.*=.*/g, to: "NORM_TTL = "+pwa_NORM_TTL+";"});
+ replace.sync({files: 'static/sw.js', from: /LONG_TTL.*=.*/g, to: "LONG_TTL = "+pwa_LONG_TTL+";"});
+ replace.sync({files: 'static/sw.js', from: /TTL_NORM.*=.*/g, to: "TTL_NORM = ["+pwa_TTL_NORM+"];"});
+ replace.sync({files: 'static/sw.js', from: /TTL_LONG.*=.*/g, to: "TTL_LONG = ["+pwa_TTL_LONG+"];"});
+ replace.sync({files: 'static/sw.js', from: /TTL_EXEMPT.*=.*/g, to: "TTL_EXEMPT = ["+pwa_TTL_EXEMPT+"];"});
+ }
+
+ if (pwa_cache_all) {
+ // Generate array from the list of files, for the entire site.
+
+ var dir = 'public';
+ try {
+ fs.mkdirSync(dir);
+ } catch(e) {
+ if (e.code != 'EEXIST') throw e;
+ }
+ const path = './public/';
+ cache = 'this.BASE_CACHE_FILES = [';
+ files = fs.readdirSync(path, { recursive: true, withFileTypes: false })
+ .forEach(
+ (file) => {
+ // check if is directory, if not then add the path/file
+ if (!fs.lstatSync(path+file).isDirectory()) {
+ // format output
+ item = "/"+file.replace(/index\.html$/i,'');// strip index.html from path
+ item = item.replace(/^\/sw(\.min)?\.js/i,'');// dont cache service worker
+
+ // if formatted output is not empty line then append it to cache var
+ if (item != '') {// skip empty lines
+ cache = cache+"'"+item+"',";
+ }
+ }
+ }
+ );
+ cache = cache.slice(0, -1)+'];'// remove the last comma and close the array
+ } else if (pwa_BASE_CACHE_FILES) {
+ cache = 'this.BASE_CACHE_FILES = ['+pwa_BASE_CACHE_FILES+'];';
+ }
+
+ // update the BASE_CACHE_FILES variable in the sw.js service worker file
+ results = replace.sync({
+ files: 'static/sw.js',
+ from: /this\.BASE_CACHE_FILES =.*/g,
+ to: cache,
+ countMatches: true,
+ });
+ }
+
+ if (bpath === '') {// abridge used directly
+ // These are truely static js files, so they should only need to be updated by abridge maintainer or contributors.
+ minify(['static/js/theme.js']);
+ minify(['static/js/theme_light.js']);
+ minify(['static/js/katex.min.js','static/js/mathtex-script-type.min.js','static/js/katex-auto-render.min.js','static/js/katexoptions.js'],'static/js/katexbundle.min.js');
+ minify(['static/js/elasticlunr.min.js','static/js/search.js'],'static/js/search_elasticlunr.min.js');
+ minify(['static/js/stork.js','static/js/stork_config.js'],'static/js/search_stork.min.js');
+ minify(['static/js/tinysearch.js'],'static/js/search_tinysearch.min.js');
+ minify(['static/js/prestyle.js','static/js/theme_button.js','static/js/email.js','static/js/codecopy.js','static/js/sw_load.js'],'static/js/abridge_nosearch.min.js');
+ minify(['static/js/prestyle.js','static/js/theme_button.js','static/js/email.js','static/js/codecopy.js'],'static/js/abridge_nosearch_nopwa.min.js');
+ minify(['static/js/sw_load.js']);
+ minify(['static/sw.js']);
+ } else if (pwa) {
+ minify(['static/js/sw_load.js']);
+ minify(['static/sw.js']);
+ }
+
+ // if manifest.json is present, then minify it.
+ if (fs.existsSync('static/manifest.json')) {
+ let out;
+ try {
+ out = JSON.minify(fs.readFileSync('static/manifest.json', {encoding:"utf-8"}));
+ } catch(err) {
+ console.log(err);
+ }
+ fs.writeFileSync('static/manifest.min.json', out);
+ }
+
+ abridge_bundle = bundle(bpath,js_prestyle,js_switcher,js_email_encode,js_copycode,search_library,index_format,uglyurls,false);
+ minify(abridge_bundle,'static/js/abridge_nopwa.min.js');
+
+ abridge_bundle = bundle(bpath,js_prestyle,js_switcher,js_email_encode,js_copycode,search_library,index_format,uglyurls,pwa);
+ minify(abridge_bundle,'static/js/abridge.min.js');
+
+ console.log('Zola Build to generate new integrity hashes for the previously minified files:');
+ await execWrapper('zola build');
+}
function bundle(bpath,js_prestyle,js_switcher,js_email_encode,js_copycode,search_library,index_format,uglyurls,pwa) {
minify_files = [];
@@ -124,141 +265,4 @@ function minify(fileA,outfile) {
fs.writeFileSync(outfile, result.code);
}
-if (search_library === 'elasticlunr') {
- if (fs.existsSync('content/static/stork_toml.md')) {
- replace.sync({files: 'content/static/stork_toml.md', from: /draft.*=.*/g, to: "draft = true"});
- }
- if (fs.existsSync('content/static/tinysearch_json.md')) {
- replace.sync({files: 'content/static/tinysearch_json.md', from: /draft.*=.*/g, to: "draft = true"});
- }
-} else if (search_library === 'tinysearch') {
- if (!fs.existsSync('content/static/tinysearch_json.md')) {// 'content/static/tinysearch_json.md' file is missing, copy from abridge theme.
- fs.copyFileSync(bpath+'content/static/tinysearch_json.md', 'content/static/tinysearch_json.md',fs.constants.COPYFILE_EXCL);
- }
- if (fs.existsSync('content/static/stork_toml.md')) {
- replace.sync({files: 'content/static/stork_toml.md', from: /draft.*=.*/g, to: "draft = true"});
- }
- if (fs.existsSync('content/static/tinysearch_json.md')) {
- replace.sync({files: 'content/static/tinysearch_json.md', from: /draft.*=.*/g, to: "draft = false"});
- }
- // zola build && mkdir -p tmp && tinysearch --optimize --path tmp public/data_tinysearch/index.html && rsync -avz tmp/*.wasm static/ && rm -rf tmp
-} else if (search_library === 'stork') {
-
- if (!fs.existsSync('content/static/stork_toml.md')) {// 'content/static/stork_toml.md' file is missing, copy from abridge theme.
- fs.copyFileSync(bpath+'content/static/stork_toml.md', 'content/static/stork_toml.md',fs.constants.COPYFILE_EXCL);
- }
- if (fs.existsSync('content/static/stork_toml.md')) {
- replace.sync({files: 'content/static/stork_toml.md', from: /draft.*=.*/g, to: "draft = false"});
- }
- if (fs.existsSync('content/static/tinysearch_json.md')) {
- replace.sync({files: 'content/static/tinysearch_json.md', from: /draft.*=.*/g, to: "draft = true"});
- }
- // zola build && stork build --input public/data_stork/index.html --output static/stork.st
-}
-
-if (pwa) {// Update pwa settings, file list, and hashes.
- // update from abridge theme.
- fs.copyFileSync(bpath+'static/sw.js', 'static/sw.js');
- fs.copyFileSync(bpath+'static/js/sw_load.js', 'static/js/sw_load.js');
- // Update settings in PWA javascript file, using options parsed from config.toml. sw.min.js?v=3.10.0", "++"
- if (fs.existsSync('static/js/sw_load.js')) {
- sw_load_min = '.js?v=';
- if (js_bundle) {
- sw_load_min = '.min.js?v=';
- }
- replace.sync({files: 'static/js/sw_load.js', from: /sw.*v=.*/g, to: "sw"+sw_load_min+pwa_VER+"\","});
- }
- if (fs.existsSync('static/sw.js')) {
- replace.sync({files: 'static/sw.js', from: /NORM_TTL.*=.*/g, to: "NORM_TTL = "+pwa_NORM_TTL+";"});
- replace.sync({files: 'static/sw.js', from: /LONG_TTL.*=.*/g, to: "LONG_TTL = "+pwa_LONG_TTL+";"});
- replace.sync({files: 'static/sw.js', from: /TTL_NORM.*=.*/g, to: "TTL_NORM = ["+pwa_TTL_NORM+"];"});
- replace.sync({files: 'static/sw.js', from: /TTL_LONG.*=.*/g, to: "TTL_LONG = ["+pwa_TTL_LONG+"];"});
- replace.sync({files: 'static/sw.js', from: /TTL_EXEMPT.*=.*/g, to: "TTL_EXEMPT = ["+pwa_TTL_EXEMPT+"];"});
- }
-
- /// Generate hashes for PWA BASE_CACHE_FILES (disabled, seems unsupported, errors on install)
- // buff = fs.readFileSync('public/abridge.css');
- // const h_abridge_css = crypto.createHash('sha256').update(buff).digest('hex').slice(0,20);
- // buff = fs.readFileSync('public/js/abridge.min.js');
- // const h_abridge_js = crypto.createHash('sha256').update(buff).digest('hex').slice(0,20);
- // buff = fs.readFileSync('public/js/abridge_nosearch.min.js');
- // const h_abridge_nosearch_js = crypto.createHash('sha256').update(buff).digest('hex').slice(0,20);
- // buff = fs.readFileSync('public/js/katexbundle.min.js');
- // const h_katexbundle_js = crypto.createHash('sha256').update(buff).digest('hex').slice(0,20);
-
- if (pwa_cache_all) {
- // Generate array from the list of files, for the entire site.
- const path = './public/';
- cache = 'this.BASE_CACHE_FILES = [';
- files = fs.readdirSync(path, { recursive: true, withFileTypes: false })
- .forEach(
- (file) => {
- // check if is directory, if not then add the path/file
- if (!fs.lstatSync(path+file).isDirectory()) {
- // format output
- item = "/"+file.replace(/index\.html$/i,'');// strip index.html from path
- item = item.replace(/^\/sw(\.min)?\.js/i,'');// dont cache service worker
-
- // look for files ending in .js, if its not preceded by .min then skip it.
-
- // if formatted output is not empty line then append it to cache var
- if (item != '') {// skip empty lines
- cache = cache+"'"+item+"',";
- }
- }
- }
- );
- cache = cache.slice(0, -1)+'];'// remove the last comma and close the array
- } else if (pwa_BASE_CACHE_FILES) {
- cache = 'this.BASE_CACHE_FILES = ['+pwa_BASE_CACHE_FILES+'];';
- }
-
- /// add cachebust hashes (disabled, seems unsupported, errors on install)
- // cache = cache.replace(/abridge\.css/i,'abridge.css?h='+h_abridge_css);
- // cache = cache.replace(/abridge\.min\.js/i,'abridge.min.js?h='+h_abridge_js);
- // cache = cache.replace(/abridge_nosearch\.min\.js/i,'abridge_nosearch.min.js?h='+h_abridge_nosearch_js);
- // cache = cache.replace(/katexbundle\.min\.js/i,'katexbundle.min.js?h='+h_katexbundle_js);
- // console.log(cache);
-
- // update the BASE_CACHE_FILES variable in the sw.js service worker file
- results = replace.sync({
- files: 'static/sw.js',
- from: /this\.BASE_CACHE_FILES =.*/g,
- to: cache,
- countMatches: true,
- });
-}
-
-if (bpath === '') {// abridge used directly
- // These are truely static js files, so they should only need to be updated by abridge maintainer or contributors.
- minify(['static/js/theme.js']);
- minify(['static/js/theme_light.js']);
- minify(['static/js/katex.min.js','static/js/mathtex-script-type.min.js','static/js/katex-auto-render.min.js','static/js/katexoptions.js'],'static/js/katexbundle.min.js');
- minify(['static/js/elasticlunr.min.js','static/js/search.js'],'static/js/search_elasticlunr.min.js');
- minify(['static/js/stork.js','static/js/stork_config.js'],'static/js/search_stork.min.js');
- minify(['static/js/tinysearch.js'],'static/js/search_tinysearch.min.js');
- minify(['static/js/prestyle.js','static/js/theme_button.js','static/js/email.js','static/js/codecopy.js','static/js/sw_load.js'],'static/js/abridge_nosearch.min.js');
- minify(['static/js/prestyle.js','static/js/theme_button.js','static/js/email.js','static/js/codecopy.js'],'static/js/abridge_nosearch_nopwa.min.js');
- minify(['static/js/sw_load.js']);
- minify(['static/sw.js']);
-} else if (pwa) {
- minify(['static/js/sw_load.js']);
- minify(['static/sw.js']);
-}
-
-// if manifest.json is present, then minify it.
-if (fs.existsSync('static/manifest.json')) {
- let out;
- try {
- out = JSON.minify(fs.readFileSync('static/manifest.json', {encoding:"utf-8"}));
- } catch(err) {
- console.log(err);
- }
- fs.writeFileSync('static/manifest.min.json', out);
-}
-
-abridge_bundle = bundle(bpath,js_prestyle,js_switcher,js_email_encode,js_copycode,search_library,index_format,uglyurls,false);
-minify(abridge_bundle,'static/js/abridge_nopwa.min.js');
-
-abridge_bundle = bundle(bpath,js_prestyle,js_switcher,js_email_encode,js_copycode,search_library,index_format,uglyurls,pwa);
-minify(abridge_bundle,'static/js/abridge.min.js');
+abridge();
diff --git a/static/sw.js b/static/sw.js
index 17b5177..05e9c2b 100644
--- a/static/sw.js
+++ b/static/sw.js
@@ -5,7 +5,7 @@ class Pwa {
const Version = new URL(location).searchParams.get("v");
this.CACHE_VERSION = Version;
//this.BASE_CACHE_FILES=['/js/theme.min.js','/js/theme_light.min.js','/abridge.css','/js/abridge.min.js','/','/404.html','/offline/','/manifest.json'];
- this.BASE_CACHE_FILES = ['/404.html','/abridge.css','/android-chrome-192x192.png','/android-chrome-512x512.png','/apple-touch-icon.png','/atom.xml','/banner.png','/browserconfig.xml','/elasticlunr.min.js','/favicon-16x16.png','/favicon-32x32.png','/favicon.ico','/favicon.svg','/','/katex.min.css','/m1024.png','/m128.png','/m192.png','/m384.png','/m48.png','/m512.png','/m72.png','/m96.png','/manifest.json','/manifest.min.json','/mstile-150x150.png','/nojs.css','/robots.txt','/safari-pinned-tab.svg','/search_index.en.json','/search_index.fr.json','/sitemap.xml','/about/','/archive/','/contact/','/fonts/KaTeX_AMS-Regular.woff2','/fonts/KaTeX_Caligraphic-Bold.woff2','/fonts/KaTeX_Caligraphic-Regular.woff2','/fonts/KaTeX_Fraktur-Bold.woff2','/fonts/KaTeX_Fraktur-Regular.woff2','/fonts/KaTeX_Main-Bold.woff2','/fonts/KaTeX_Main-BoldItalic.woff2','/fonts/KaTeX_Main-Italic.woff2','/fonts/KaTeX_Main-Regular.woff2','/fonts/KaTeX_Math-BoldItalic.woff2','/fonts/KaTeX_Math-Italic.woff2','/fonts/KaTeX_SansSerif-Bold.woff2','/fonts/KaTeX_SansSerif-Italic.woff2','/fonts/KaTeX_SansSerif-Regular.woff2','/fonts/KaTeX_Script-Regular.woff2','/fonts/KaTeX_Size1-Regular.woff2','/fonts/KaTeX_Size2-Regular.woff2','/fonts/KaTeX_Size3-Regular.woff2','/fonts/KaTeX_Size4-Regular.woff2','/fonts/KaTeX_Typewriter-Regular.woff2','/fonts/Roboto-Bold.woff2','/fonts/Roboto-Italic.woff2','/fonts/Roboto-Mono-Italic.woff2','/fonts/Roboto-Mono.woff2','/fonts/Roboto.woff2','/fr/atom.xml','/fr/','/js/abridge.min.js','/js/abridge_nopwa.min.js','/js/abridge_nosearch.min.js','/js/abridge_nosearch_nopwa.min.js','/js/codecopy.js','/js/elasticlunr.min.js','/js/email.js','/js/katex-auto-render.min.js','/js/katex.min.js','/js/katexbundle.min.js','/js/katexbundle.min.old.js','/js/katexoptions.js','/js/lunr.da.js','/js/lunr.da.min.js','/js/lunr.de.js','/js/lunr.de.min.js','/js/lunr.du.js','/js/lunr.du.min.js','/js/lunr.es.js','/js/lunr.es.min.js','/js/lunr.fi.js','/js/lunr.fi.min.js','/js/lunr.fr.js','/js/lunr.fr.min.js','/js/lunr.hu.js','/js/lunr.hu.min.js','/js/lunr.it.js','/js/lunr.it.min.js','/js/lunr.jp.js','/js/lunr.jp.min.js','/js/lunr.no.js','/js/lunr.no.min.js','/js/lunr.pt.js','/js/lunr.pt.min.js','/js/lunr.ro.js','/js/lunr.ro.min.js','/js/lunr.ru.js','/js/lunr.ru.min.js','/js/lunr.stemmer.support.js','/js/lunr.stemmer.support.min.js','/js/lunr.sv.js','/js/lunr.sv.min.js','/js/lunr.tr.js','/js/lunr.tr.min.js','/js/lunr.zh.js','/js/lunr.zh.min.js','/js/mathtex-script-type.min.js','/js/prestyle.js','/js/search.js','/js/search_elasticlunr.min.js','/js/search_elasticlunr_jindex.min.js','/js/search_stork.min.js','/js/search_tinysearch.min.js','/js/searchjava.js','/js/searchjavaugly.js','/js/stork.js','/js/stork_config.js','/js/sw_load.js','/js/sw_load.min.js','/js/theme.js','/js/theme.min.js','/js/theme_button.js','/js/theme_light.js','/js/theme_light.min.js','/js/tinysearch.js','/offline/','/overview-abridge/','/overview-abridge/lighthouse.png','/overview-code-blocks/','/overview-embed-streamable/','/overview-embed-vimeo/','/overview-embed-youtube/','/overview-images/corro.svg','/overview-images/ferris-gesture.png','/overview-images/ferris-gesture.svg','/overview-images/ferris-happy.svg','/overview-images/ferris.svg','/overview-images/','/overview-markdown-and-style/','/overview-math/','/overview-rich-content/ferris-gesture.svg','/overview-rich-content/ferris.svg','/overview-rich-content/','/overview-rich-content/over9000-400.avif','/overview-rich-content/over9000-640.avif','/overview-rich-content/over9000-640.webp','/overview-rich-content/over9000-960.avif','/overview-rich-content/over9000.mp3','/overview-rich-content/over9000.ogg','/overview-rich-content/over9000_av1.mp4','/overview-rich-content/over9000_vp9.webm','/overview-showdata/','/privacy/','/tags/','/fr/about/','/fr/archive/','/fr/contact/','/fr/offline/','/fr/overview-abridge/','/fr/overview-abridge/lighthouse.png','/fr/overview-code-blocks/','/fr/overview-embed-streamable/','/fr/overview-embed-vimeo/','/fr/overview-embed-youtube/','/fr/overview-images/corro.svg','/fr/overview-images/ferris-gesture.png','/fr/overview-images/ferris-gesture.svg','/fr/overview-images/ferris-happy.svg','/fr/overview-images/ferris.svg','/fr/overview-images/','/fr/overview-markdown-and-style/','/fr/overview-math/','/fr/overview-rich-content/ferris-gesture.svg','/fr/overview-rich-content/ferris.svg','/fr/overview-rich-content/','/fr/overview-rich-content/over9000-400.avif','/fr/overview-rich-content/over9000-640.avif','/fr/overview-rich-content/over9000-640.webp','/fr/overview-rich-content/over9000-960.avif','/fr/overview-rich-content/over9000.mp3','/fr/overview-rich-content/over9000.ogg','/fr/overview-rich-content/over9000_av1.mp4','/fr/overview-rich-content/over9000_vp9.webm','/fr/overview-showdata/','/fr/privacy/','/fr/tags/','/overview-images/img/ferris-gesture.svg','/overview-images/img/ferris.svg','/page/1/','/page/2/','/page/3/','/page/4/','/tags/audio/atom.xml','/tags/audio/','/tags/config/atom.xml','/tags/config/','/tags/data/atom.xml','/tags/data/','/tags/features/atom.xml','/tags/features/','/tags/images/atom.xml','/tags/images/','/tags/markdown/atom.xml','/tags/markdown/','/tags/mathematics/atom.xml','/tags/mathematics/','/tags/shortcodes/atom.xml','/tags/shortcodes/','/tags/video/atom.xml','/tags/video/','/fr/overview-images/img/ferris-gesture.svg','/fr/overview-images/img/ferris.svg','/fr/page/1/','/fr/page/2/','/fr/page/3/','/fr/page/4/','/fr/tags/audio/atom.xml','/fr/tags/audio/','/fr/tags/config/atom.xml','/fr/tags/config/','/fr/tags/data/atom.xml','/fr/tags/data/','/fr/tags/features/atom.xml','/fr/tags/features/','/fr/tags/images/atom.xml','/fr/tags/images/','/fr/tags/markdown/atom.xml','/fr/tags/markdown/','/fr/tags/mathematics/atom.xml','/fr/tags/mathematics/','/fr/tags/shortcodes/atom.xml','/fr/tags/shortcodes/','/fr/tags/video/atom.xml','/fr/tags/video/'];
+ this.BASE_CACHE_FILES = ['/404.html','/abridge.css','/android-chrome-192x192.png','/android-chrome-512x512.png','/apple-touch-icon.png','/atom.xml','/banner.png','/browserconfig.xml','/elasticlunr.min.js','/favicon-16x16.png','/favicon-32x32.png','/favicon.ico','/favicon.svg','/','/katex.min.css','/m1024.png','/m128.png','/m192.png','/m384.png','/m48.png','/m512.png','/m72.png','/m96.png','/manifest.json','/manifest.min.json','/mstile-150x150.png','/nojs.css','/robots.txt','/safari-pinned-tab.svg','/search_index.en.json','/search_index.es.json','/search_index.fr.json','/sitemap.xml','/about/','/archive/','/blog/','/contact/','/es/atom.xml','/es/','/fonts/KaTeX_AMS-Regular.woff2','/fonts/KaTeX_Caligraphic-Bold.woff2','/fonts/KaTeX_Caligraphic-Regular.woff2','/fonts/KaTeX_Fraktur-Bold.woff2','/fonts/KaTeX_Fraktur-Regular.woff2','/fonts/KaTeX_Main-Bold.woff2','/fonts/KaTeX_Main-BoldItalic.woff2','/fonts/KaTeX_Main-Italic.woff2','/fonts/KaTeX_Main-Regular.woff2','/fonts/KaTeX_Math-BoldItalic.woff2','/fonts/KaTeX_Math-Italic.woff2','/fonts/KaTeX_SansSerif-Bold.woff2','/fonts/KaTeX_SansSerif-Italic.woff2','/fonts/KaTeX_SansSerif-Regular.woff2','/fonts/KaTeX_Script-Regular.woff2','/fonts/KaTeX_Size1-Regular.woff2','/fonts/KaTeX_Size2-Regular.woff2','/fonts/KaTeX_Size3-Regular.woff2','/fonts/KaTeX_Size4-Regular.woff2','/fonts/KaTeX_Typewriter-Regular.woff2','/fonts/Roboto-Bold.woff2','/fonts/Roboto-Italic.woff2','/fonts/Roboto-Mono-Italic.woff2','/fonts/Roboto-Mono.woff2','/fonts/Roboto.woff2','/fr/atom.xml','/fr/','/images/ferris-gesture.svg','/images/ferris.svg','/js/abridge.min.js','/js/abridge_nopwa.min.js','/js/abridge_nosearch.min.js','/js/abridge_nosearch_nopwa.min.js','/js/codecopy.js','/js/elasticlunr.min.js','/js/email.js','/js/katex-auto-render.min.js','/js/katex.min.js','/js/katexbundle.min.js','/js/katexbundle.min.old.js','/js/katexoptions.js','/js/lunr.da.js','/js/lunr.da.min.js','/js/lunr.de.js','/js/lunr.de.min.js','/js/lunr.du.js','/js/lunr.du.min.js','/js/lunr.es.js','/js/lunr.es.min.js','/js/lunr.fi.js','/js/lunr.fi.min.js','/js/lunr.fr.js','/js/lunr.fr.min.js','/js/lunr.hu.js','/js/lunr.hu.min.js','/js/lunr.it.js','/js/lunr.it.min.js','/js/lunr.jp.js','/js/lunr.jp.min.js','/js/lunr.no.js','/js/lunr.no.min.js','/js/lunr.pt.js','/js/lunr.pt.min.js','/js/lunr.ro.js','/js/lunr.ro.min.js','/js/lunr.ru.js','/js/lunr.ru.min.js','/js/lunr.stemmer.support.js','/js/lunr.stemmer.support.min.js','/js/lunr.sv.js','/js/lunr.sv.min.js','/js/lunr.tr.js','/js/lunr.tr.min.js','/js/lunr.zh.js','/js/lunr.zh.min.js','/js/mathtex-script-type.min.js','/js/prestyle.js','/js/search.js','/js/search_elasticlunr.min.js','/js/search_elasticlunr_jindex.min.js','/js/search_stork.min.js','/js/search_tinysearch.min.js','/js/searchjava.js','/js/searchjavaugly.js','/js/stork.js','/js/stork_config.js','/js/sw_load.js','/js/sw_load.min.js','/js/theme.js','/js/theme.min.js','/js/theme_button.js','/js/theme_light.js','/js/theme_light.min.js','/js/tinysearch.js','/offline/','/overview-abridge/','/overview-abridge/lighthouse.png','/overview-code-blocks/','/overview-images/corro.svg','/overview-images/ferris-gesture.png','/overview-images/ferris-gesture.svg','/overview-images/ferris-happy.svg','/overview-images/ferris.svg','/overview-images/','/overview-markdown-and-style/','/overview-math/','/overview-rich-content/','/overview-rich-content/over9000-400.avif','/overview-rich-content/over9000-640.avif','/overview-rich-content/over9000-640.webp','/overview-rich-content/over9000-960.avif','/overview-rich-content/over9000.mp3','/overview-rich-content/over9000.ogg','/overview-rich-content/over9000_av1.mp4','/overview-rich-content/over9000_vp9.webm','/overview-showdata/','/privacy/','/tags/','/es/archive/','/es/blog/','/es/tags/','/fr/about/','/fr/archive/','/fr/blog/','/fr/contact/','/fr/offline/','/fr/overview-abridge/','/fr/overview-abridge/lighthouse.png','/fr/overview-code-blocks/','/fr/overview-images/corro.svg','/fr/overview-images/ferris-gesture.png','/fr/overview-images/ferris-gesture.svg','/fr/overview-images/ferris-happy.svg','/fr/overview-images/ferris.svg','/fr/overview-images/','/fr/overview-markdown-and-style/','/fr/overview-math/','/fr/overview-rich-content/','/fr/overview-rich-content/over9000-400.avif','/fr/overview-rich-content/over9000-640.avif','/fr/overview-rich-content/over9000-640.webp','/fr/overview-rich-content/over9000-960.avif','/fr/overview-rich-content/over9000.mp3','/fr/overview-rich-content/over9000.ogg','/fr/overview-rich-content/over9000_av1.mp4','/fr/overview-rich-content/over9000_vp9.webm','/fr/overview-showdata/','/fr/privacy/','/fr/tags/','/overview-images/img/ferris-gesture.svg','/overview-images/img/ferris.svg','/page/1/','/page/2/','/page/3/','/page/4/','/tags/audio/atom.xml','/tags/audio/','/tags/config/atom.xml','/tags/config/','/tags/data/atom.xml','/tags/data/','/tags/features/atom.xml','/tags/features/','/tags/images/atom.xml','/tags/images/','/tags/markdown/atom.xml','/tags/markdown/','/tags/mathematics/atom.xml','/tags/mathematics/','/tags/shortcodes/atom.xml','/tags/shortcodes/','/tags/video/atom.xml','/tags/video/','/video-streaming-sites/overview-embed-streamable/','/video-streaming-sites/overview-embed-vimeo/','/video-streaming-sites/overview-embed-youtube/','/blog/page/1/','/es/page/1/','/es/tags/features/atom.xml','/es/tags/features/','/es/tags/shortcodes/atom.xml','/es/tags/shortcodes/','/es/tags/video/atom.xml','/es/tags/video/','/es/video-streaming-sites/overview-embed-streamable/','/fr/overview-images/img/ferris-gesture.svg','/fr/overview-images/img/ferris.svg','/fr/page/1/','/fr/page/2/','/fr/page/3/','/fr/page/4/','/fr/tags/audio/atom.xml','/fr/tags/audio/','/fr/tags/config/atom.xml','/fr/tags/config/','/fr/tags/data/atom.xml','/fr/tags/data/','/fr/tags/features/atom.xml','/fr/tags/features/','/fr/tags/images/atom.xml','/fr/tags/images/','/fr/tags/markdown/atom.xml','/fr/tags/markdown/','/fr/tags/mathematics/atom.xml','/fr/tags/mathematics/','/fr/tags/shortcodes/atom.xml','/fr/tags/shortcodes/','/fr/tags/video/atom.xml','/fr/tags/video/','/fr/video-streaming-sites/overview-embed-streamable/','/fr/video-streaming-sites/overview-embed-vimeo/','/fr/video-streaming-sites/overview-embed-youtube/','/es/blog/page/1/','/fr/blog/page/1/'];
this.host = `${self.location.protocol}//${self.location.host}`;
console.info(`Host: ${this.host}`);
this.OFFLINE_PAGE = '/offline/';
diff --git a/static/sw.min.js b/static/sw.min.js
index e959dfa..20a9eca 100644
--- a/static/sw.min.js
+++ b/static/sw.min.js
@@ -1 +1 @@
-class Pwa{constructor(e){this.scope=e;var s=new URL(location).searchParams.get("v");this.CACHE_VERSION=s,this.BASE_CACHE_FILES=["/404.html","/abridge.css","/android-chrome-192x192.png","/android-chrome-512x512.png","/apple-touch-icon.png","/atom.xml","/banner.png","/browserconfig.xml","/elasticlunr.min.js","/favicon-16x16.png","/favicon-32x32.png","/favicon.ico","/favicon.svg","/","/katex.min.css","/m1024.png","/m128.png","/m192.png","/m384.png","/m48.png","/m512.png","/m72.png","/m96.png","/manifest.json","/manifest.min.json","/mstile-150x150.png","/nojs.css","/robots.txt","/safari-pinned-tab.svg","/search_index.en.json","/search_index.fr.json","/sitemap.xml","/about/","/archive/","/contact/","/fonts/KaTeX_AMS-Regular.woff2","/fonts/KaTeX_Caligraphic-Bold.woff2","/fonts/KaTeX_Caligraphic-Regular.woff2","/fonts/KaTeX_Fraktur-Bold.woff2","/fonts/KaTeX_Fraktur-Regular.woff2","/fonts/KaTeX_Main-Bold.woff2","/fonts/KaTeX_Main-BoldItalic.woff2","/fonts/KaTeX_Main-Italic.woff2","/fonts/KaTeX_Main-Regular.woff2","/fonts/KaTeX_Math-BoldItalic.woff2","/fonts/KaTeX_Math-Italic.woff2","/fonts/KaTeX_SansSerif-Bold.woff2","/fonts/KaTeX_SansSerif-Italic.woff2","/fonts/KaTeX_SansSerif-Regular.woff2","/fonts/KaTeX_Script-Regular.woff2","/fonts/KaTeX_Size1-Regular.woff2","/fonts/KaTeX_Size2-Regular.woff2","/fonts/KaTeX_Size3-Regular.woff2","/fonts/KaTeX_Size4-Regular.woff2","/fonts/KaTeX_Typewriter-Regular.woff2","/fonts/Roboto-Bold.woff2","/fonts/Roboto-Italic.woff2","/fonts/Roboto-Mono-Italic.woff2","/fonts/Roboto-Mono.woff2","/fonts/Roboto.woff2","/fr/atom.xml","/fr/","/js/abridge.min.js","/js/abridge_nopwa.min.js","/js/abridge_nosearch.min.js","/js/abridge_nosearch_nopwa.min.js","/js/codecopy.js","/js/elasticlunr.min.js","/js/email.js","/js/katex-auto-render.min.js","/js/katex.min.js","/js/katexbundle.min.js","/js/katexbundle.min.old.js","/js/katexoptions.js","/js/lunr.da.js","/js/lunr.da.min.js","/js/lunr.de.js","/js/lunr.de.min.js","/js/lunr.du.js","/js/lunr.du.min.js","/js/lunr.es.js","/js/lunr.es.min.js","/js/lunr.fi.js","/js/lunr.fi.min.js","/js/lunr.fr.js","/js/lunr.fr.min.js","/js/lunr.hu.js","/js/lunr.hu.min.js","/js/lunr.it.js","/js/lunr.it.min.js","/js/lunr.jp.js","/js/lunr.jp.min.js","/js/lunr.no.js","/js/lunr.no.min.js","/js/lunr.pt.js","/js/lunr.pt.min.js","/js/lunr.ro.js","/js/lunr.ro.min.js","/js/lunr.ru.js","/js/lunr.ru.min.js","/js/lunr.stemmer.support.js","/js/lunr.stemmer.support.min.js","/js/lunr.sv.js","/js/lunr.sv.min.js","/js/lunr.tr.js","/js/lunr.tr.min.js","/js/lunr.zh.js","/js/lunr.zh.min.js","/js/mathtex-script-type.min.js","/js/prestyle.js","/js/search.js","/js/search_elasticlunr.min.js","/js/search_elasticlunr_jindex.min.js","/js/search_stork.min.js","/js/search_tinysearch.min.js","/js/searchjava.js","/js/searchjavaugly.js","/js/stork.js","/js/stork_config.js","/js/sw_load.js","/js/sw_load.min.js","/js/theme.js","/js/theme.min.js","/js/theme_button.js","/js/theme_light.js","/js/theme_light.min.js","/js/tinysearch.js","/offline/","/overview-abridge/","/overview-abridge/lighthouse.png","/overview-code-blocks/","/overview-embed-streamable/","/overview-embed-vimeo/","/overview-embed-youtube/","/overview-images/corro.svg","/overview-images/ferris-gesture.png","/overview-images/ferris-gesture.svg","/overview-images/ferris-happy.svg","/overview-images/ferris.svg","/overview-images/","/overview-markdown-and-style/","/overview-math/","/overview-rich-content/ferris-gesture.svg","/overview-rich-content/ferris.svg","/overview-rich-content/","/overview-rich-content/over9000-400.avif","/overview-rich-content/over9000-640.avif","/overview-rich-content/over9000-640.webp","/overview-rich-content/over9000-960.avif","/overview-rich-content/over9000.mp3","/overview-rich-content/over9000.ogg","/overview-rich-content/over9000_av1.mp4","/overview-rich-content/over9000_vp9.webm","/overview-showdata/","/privacy/","/tags/","/fr/about/","/fr/archive/","/fr/contact/","/fr/offline/","/fr/overview-abridge/","/fr/overview-abridge/lighthouse.png","/fr/overview-code-blocks/","/fr/overview-embed-streamable/","/fr/overview-embed-vimeo/","/fr/overview-embed-youtube/","/fr/overview-images/corro.svg","/fr/overview-images/ferris-gesture.png","/fr/overview-images/ferris-gesture.svg","/fr/overview-images/ferris-happy.svg","/fr/overview-images/ferris.svg","/fr/overview-images/","/fr/overview-markdown-and-style/","/fr/overview-math/","/fr/overview-rich-content/ferris-gesture.svg","/fr/overview-rich-content/ferris.svg","/fr/overview-rich-content/","/fr/overview-rich-content/over9000-400.avif","/fr/overview-rich-content/over9000-640.avif","/fr/overview-rich-content/over9000-640.webp","/fr/overview-rich-content/over9000-960.avif","/fr/overview-rich-content/over9000.mp3","/fr/overview-rich-content/over9000.ogg","/fr/overview-rich-content/over9000_av1.mp4","/fr/overview-rich-content/over9000_vp9.webm","/fr/overview-showdata/","/fr/privacy/","/fr/tags/","/overview-images/img/ferris-gesture.svg","/overview-images/img/ferris.svg","/page/1/","/page/2/","/page/3/","/page/4/","/tags/audio/atom.xml","/tags/audio/","/tags/config/atom.xml","/tags/config/","/tags/data/atom.xml","/tags/data/","/tags/features/atom.xml","/tags/features/","/tags/images/atom.xml","/tags/images/","/tags/markdown/atom.xml","/tags/markdown/","/tags/mathematics/atom.xml","/tags/mathematics/","/tags/shortcodes/atom.xml","/tags/shortcodes/","/tags/video/atom.xml","/tags/video/","/fr/overview-images/img/ferris-gesture.svg","/fr/overview-images/img/ferris.svg","/fr/page/1/","/fr/page/2/","/fr/page/3/","/fr/page/4/","/fr/tags/audio/atom.xml","/fr/tags/audio/","/fr/tags/config/atom.xml","/fr/tags/config/","/fr/tags/data/atom.xml","/fr/tags/data/","/fr/tags/features/atom.xml","/fr/tags/features/","/fr/tags/images/atom.xml","/fr/tags/images/","/fr/tags/markdown/atom.xml","/fr/tags/markdown/","/fr/tags/mathematics/atom.xml","/fr/tags/mathematics/","/fr/tags/shortcodes/atom.xml","/fr/tags/shortcodes/","/fr/tags/video/atom.xml","/fr/tags/video/"],this.host=e.location.protocol+"//"+e.location.host,this.OFFLINE_PAGE="/offline/",this.NOT_FOUND_PAGE="/404.html",this.CACHE_NAME="content-v"+this.CACHE_VERSION,this.NORM_TTL=0,this.LONG_TTL=0,this.TTL_NORM=["sw.min.js","sw_load.min.js"],this.TTL_LONG=["jpg","jpeg","png","gif","webp","avif","ico","svg","xsl","txt"],this.TTL_EXEMPT=["js","css","otf","eot","ttf","woff","woff2","mp4","webm","mp3","ogg"]}canCache(e){return!e.startsWith("http://localhost")&&e.toString().startsWith(this.host)}getFileExtension(e){e=e.split(".").reverse()[0].split("?")[0];return e.endsWith("/")?"/":e}getFileName(e){e=e.substring(1+e.lastIndexOf("/")).split("?")[0];return e.endsWith("/")?"/":e}getTTL(e){var s;return"string"==typeof e?(s=this.getFileExtension(e),e=this.getFileName(e),~this.TTL_NORM.indexOf(e)?this.NORM_TTL:~this.TTL_LONG.indexOf(s)?this.LONG_TTL:~this.TTL_EXEMPT.indexOf(s)?null:this.NORM_TTL):null}async installServiceWorker(){try{return await caches.open(this.CACHE_NAME).then(e=>e.addAll(this.BASE_CACHE_FILES),e=>{}),this.scope.skipWaiting()}catch(e){}}cleanupLegacyCache(){const r=[this.CACHE_NAME];return new Promise((s,t)=>{caches.keys().then(e=>e.filter(e=>!~r.indexOf(e))).then(e=>{e.length?Promise.all(e.map(e=>caches.delete(e))).then(()=>s()).catch(e=>{t(e)}):s()}).catch(e=>{t(e)})})}async preCacheUrl(s){const t=await caches.open(this.CACHE_NAME);return await t.match(s)?null:fetch(s).then(e=>t.put(s,e.clone()))}register(){this.scope.addEventListener("install",e=>{e.waitUntil(Promise.all([this.installServiceWorker(),this.scope.skipWaiting()]))}),this.scope.addEventListener("activate",s=>{s.waitUntil(Promise.all([this.cleanupLegacyCache(),this.scope.clients.claim(),this.scope.skipWaiting()]).catch(e=>{s.skipWaiting()}))}),this.scope.addEventListener("fetch",o=>{o.respondWith(caches.open(this.CACHE_NAME).then(async s=>{if(!this.canCache(o.request.url))return fetch(o.request);const t=await s.match(o.request);if(t){var r;let e=null;for(r of t.headers.entries())if("date"===r[0]){e=new Date(r[1]);break}if(!e)return t;var i=parseInt(""+((new Date).getTime()-e.getTime())/1e3),a=this.getTTL(o.request.url);if(null===a||a&&i<a)return t}return fetch(o.request.clone()).then(e=>e.status<400?(this.canCache(o.request.url)&&s.put(o.request,e.clone()),e):s.match(this.NOT_FOUND_PAGE)).catch(e=>(o.request.url,t||s.match(this.OFFLINE_PAGE)))}))})}}const pwa=new Pwa(self);pwa.register(); \ No newline at end of file
+class Pwa{constructor(e){this.scope=e;var s=new URL(location).searchParams.get("v");this.CACHE_VERSION=s,this.BASE_CACHE_FILES=["/404.html","/abridge.css","/android-chrome-192x192.png","/android-chrome-512x512.png","/apple-touch-icon.png","/atom.xml","/banner.png","/browserconfig.xml","/elasticlunr.min.js","/favicon-16x16.png","/favicon-32x32.png","/favicon.ico","/favicon.svg","/","/katex.min.css","/m1024.png","/m128.png","/m192.png","/m384.png","/m48.png","/m512.png","/m72.png","/m96.png","/manifest.json","/manifest.min.json","/mstile-150x150.png","/nojs.css","/robots.txt","/safari-pinned-tab.svg","/search_index.en.json","/search_index.es.json","/search_index.fr.json","/sitemap.xml","/about/","/archive/","/blog/","/contact/","/es/atom.xml","/es/","/fonts/KaTeX_AMS-Regular.woff2","/fonts/KaTeX_Caligraphic-Bold.woff2","/fonts/KaTeX_Caligraphic-Regular.woff2","/fonts/KaTeX_Fraktur-Bold.woff2","/fonts/KaTeX_Fraktur-Regular.woff2","/fonts/KaTeX_Main-Bold.woff2","/fonts/KaTeX_Main-BoldItalic.woff2","/fonts/KaTeX_Main-Italic.woff2","/fonts/KaTeX_Main-Regular.woff2","/fonts/KaTeX_Math-BoldItalic.woff2","/fonts/KaTeX_Math-Italic.woff2","/fonts/KaTeX_SansSerif-Bold.woff2","/fonts/KaTeX_SansSerif-Italic.woff2","/fonts/KaTeX_SansSerif-Regular.woff2","/fonts/KaTeX_Script-Regular.woff2","/fonts/KaTeX_Size1-Regular.woff2","/fonts/KaTeX_Size2-Regular.woff2","/fonts/KaTeX_Size3-Regular.woff2","/fonts/KaTeX_Size4-Regular.woff2","/fonts/KaTeX_Typewriter-Regular.woff2","/fonts/Roboto-Bold.woff2","/fonts/Roboto-Italic.woff2","/fonts/Roboto-Mono-Italic.woff2","/fonts/Roboto-Mono.woff2","/fonts/Roboto.woff2","/fr/atom.xml","/fr/","/images/ferris-gesture.svg","/images/ferris.svg","/js/abridge.min.js","/js/abridge_nopwa.min.js","/js/abridge_nosearch.min.js","/js/abridge_nosearch_nopwa.min.js","/js/codecopy.js","/js/elasticlunr.min.js","/js/email.js","/js/katex-auto-render.min.js","/js/katex.min.js","/js/katexbundle.min.js","/js/katexbundle.min.old.js","/js/katexoptions.js","/js/lunr.da.js","/js/lunr.da.min.js","/js/lunr.de.js","/js/lunr.de.min.js","/js/lunr.du.js","/js/lunr.du.min.js","/js/lunr.es.js","/js/lunr.es.min.js","/js/lunr.fi.js","/js/lunr.fi.min.js","/js/lunr.fr.js","/js/lunr.fr.min.js","/js/lunr.hu.js","/js/lunr.hu.min.js","/js/lunr.it.js","/js/lunr.it.min.js","/js/lunr.jp.js","/js/lunr.jp.min.js","/js/lunr.no.js","/js/lunr.no.min.js","/js/lunr.pt.js","/js/lunr.pt.min.js","/js/lunr.ro.js","/js/lunr.ro.min.js","/js/lunr.ru.js","/js/lunr.ru.min.js","/js/lunr.stemmer.support.js","/js/lunr.stemmer.support.min.js","/js/lunr.sv.js","/js/lunr.sv.min.js","/js/lunr.tr.js","/js/lunr.tr.min.js","/js/lunr.zh.js","/js/lunr.zh.min.js","/js/mathtex-script-type.min.js","/js/prestyle.js","/js/search.js","/js/search_elasticlunr.min.js","/js/search_elasticlunr_jindex.min.js","/js/search_stork.min.js","/js/search_tinysearch.min.js","/js/searchjava.js","/js/searchjavaugly.js","/js/stork.js","/js/stork_config.js","/js/sw_load.js","/js/sw_load.min.js","/js/theme.js","/js/theme.min.js","/js/theme_button.js","/js/theme_light.js","/js/theme_light.min.js","/js/tinysearch.js","/offline/","/overview-abridge/","/overview-abridge/lighthouse.png","/overview-code-blocks/","/overview-images/corro.svg","/overview-images/ferris-gesture.png","/overview-images/ferris-gesture.svg","/overview-images/ferris-happy.svg","/overview-images/ferris.svg","/overview-images/","/overview-markdown-and-style/","/overview-math/","/overview-rich-content/","/overview-rich-content/over9000-400.avif","/overview-rich-content/over9000-640.avif","/overview-rich-content/over9000-640.webp","/overview-rich-content/over9000-960.avif","/overview-rich-content/over9000.mp3","/overview-rich-content/over9000.ogg","/overview-rich-content/over9000_av1.mp4","/overview-rich-content/over9000_vp9.webm","/overview-showdata/","/privacy/","/tags/","/es/archive/","/es/blog/","/es/tags/","/fr/about/","/fr/archive/","/fr/blog/","/fr/contact/","/fr/offline/","/fr/overview-abridge/","/fr/overview-abridge/lighthouse.png","/fr/overview-code-blocks/","/fr/overview-images/corro.svg","/fr/overview-images/ferris-gesture.png","/fr/overview-images/ferris-gesture.svg","/fr/overview-images/ferris-happy.svg","/fr/overview-images/ferris.svg","/fr/overview-images/","/fr/overview-markdown-and-style/","/fr/overview-math/","/fr/overview-rich-content/","/fr/overview-rich-content/over9000-400.avif","/fr/overview-rich-content/over9000-640.avif","/fr/overview-rich-content/over9000-640.webp","/fr/overview-rich-content/over9000-960.avif","/fr/overview-rich-content/over9000.mp3","/fr/overview-rich-content/over9000.ogg","/fr/overview-rich-content/over9000_av1.mp4","/fr/overview-rich-content/over9000_vp9.webm","/fr/overview-showdata/","/fr/privacy/","/fr/tags/","/overview-images/img/ferris-gesture.svg","/overview-images/img/ferris.svg","/page/1/","/page/2/","/page/3/","/page/4/","/tags/audio/atom.xml","/tags/audio/","/tags/config/atom.xml","/tags/config/","/tags/data/atom.xml","/tags/data/","/tags/features/atom.xml","/tags/features/","/tags/images/atom.xml","/tags/images/","/tags/markdown/atom.xml","/tags/markdown/","/tags/mathematics/atom.xml","/tags/mathematics/","/tags/shortcodes/atom.xml","/tags/shortcodes/","/tags/video/atom.xml","/tags/video/","/video-streaming-sites/overview-embed-streamable/","/video-streaming-sites/overview-embed-vimeo/","/video-streaming-sites/overview-embed-youtube/","/blog/page/1/","/es/page/1/","/es/tags/features/atom.xml","/es/tags/features/","/es/tags/shortcodes/atom.xml","/es/tags/shortcodes/","/es/tags/video/atom.xml","/es/tags/video/","/es/video-streaming-sites/overview-embed-streamable/","/fr/overview-images/img/ferris-gesture.svg","/fr/overview-images/img/ferris.svg","/fr/page/1/","/fr/page/2/","/fr/page/3/","/fr/page/4/","/fr/tags/audio/atom.xml","/fr/tags/audio/","/fr/tags/config/atom.xml","/fr/tags/config/","/fr/tags/data/atom.xml","/fr/tags/data/","/fr/tags/features/atom.xml","/fr/tags/features/","/fr/tags/images/atom.xml","/fr/tags/images/","/fr/tags/markdown/atom.xml","/fr/tags/markdown/","/fr/tags/mathematics/atom.xml","/fr/tags/mathematics/","/fr/tags/shortcodes/atom.xml","/fr/tags/shortcodes/","/fr/tags/video/atom.xml","/fr/tags/video/","/fr/video-streaming-sites/overview-embed-streamable/","/fr/video-streaming-sites/overview-embed-vimeo/","/fr/video-streaming-sites/overview-embed-youtube/","/es/blog/page/1/","/fr/blog/page/1/"],this.host=e.location.protocol+"//"+e.location.host,this.OFFLINE_PAGE="/offline/",this.NOT_FOUND_PAGE="/404.html",this.CACHE_NAME="content-v"+this.CACHE_VERSION,this.NORM_TTL=0,this.LONG_TTL=0,this.TTL_NORM=["sw.min.js","sw_load.min.js"],this.TTL_LONG=["jpg","jpeg","png","gif","webp","avif","ico","svg","xsl","txt"],this.TTL_EXEMPT=["js","css","otf","eot","ttf","woff","woff2","mp4","webm","mp3","ogg"]}canCache(e){return!e.startsWith("http://localhost")&&e.toString().startsWith(this.host)}getFileExtension(e){e=e.split(".").reverse()[0].split("?")[0];return e.endsWith("/")?"/":e}getFileName(e){e=e.substring(1+e.lastIndexOf("/")).split("?")[0];return e.endsWith("/")?"/":e}getTTL(e){var s;return"string"==typeof e?(s=this.getFileExtension(e),e=this.getFileName(e),~this.TTL_NORM.indexOf(e)?this.NORM_TTL:~this.TTL_LONG.indexOf(s)?this.LONG_TTL:~this.TTL_EXEMPT.indexOf(s)?null:this.NORM_TTL):null}async installServiceWorker(){try{return await caches.open(this.CACHE_NAME).then(e=>e.addAll(this.BASE_CACHE_FILES),e=>{}),this.scope.skipWaiting()}catch(e){}}cleanupLegacyCache(){const r=[this.CACHE_NAME];return new Promise((s,t)=>{caches.keys().then(e=>e.filter(e=>!~r.indexOf(e))).then(e=>{e.length?Promise.all(e.map(e=>caches.delete(e))).then(()=>s()).catch(e=>{t(e)}):s()}).catch(e=>{t(e)})})}async preCacheUrl(s){const t=await caches.open(this.CACHE_NAME);return await t.match(s)?null:fetch(s).then(e=>t.put(s,e.clone()))}register(){this.scope.addEventListener("install",e=>{e.waitUntil(Promise.all([this.installServiceWorker(),this.scope.skipWaiting()]))}),this.scope.addEventListener("activate",s=>{s.waitUntil(Promise.all([this.cleanupLegacyCache(),this.scope.clients.claim(),this.scope.skipWaiting()]).catch(e=>{s.skipWaiting()}))}),this.scope.addEventListener("fetch",o=>{o.respondWith(caches.open(this.CACHE_NAME).then(async s=>{if(!this.canCache(o.request.url))return fetch(o.request);const t=await s.match(o.request);if(t){var r;let e=null;for(r of t.headers.entries())if("date"===r[0]){e=new Date(r[1]);break}if(!e)return t;var i=parseInt(""+((new Date).getTime()-e.getTime())/1e3),a=this.getTTL(o.request.url);if(null===a||a&&i<a)return t}return fetch(o.request.clone()).then(e=>e.status<400?(this.canCache(o.request.url)&&s.put(o.request,e.clone()),e):s.match(this.NOT_FOUND_PAGE)).catch(e=>(o.request.url,t||s.match(this.OFFLINE_PAGE)))}))})}}const pwa=new Pwa(self);pwa.register(); \ No newline at end of file
diff --git a/templates/macros/macros.html b/templates/macros/macros.html
index d0ce1a0..21c943d 100644
--- a/templates/macros/macros.html
+++ b/templates/macros/macros.html
@@ -11,8 +11,9 @@
{%- endmacro page_listing %}
-{%- macro series_link(inner, page) %}
- {%- set uglyurls = config.extra.uglyurls | default(value=false) -%}
+{%- macro series_link(inner, page, config) %}
+{%- set uglyurls = config.extra.uglyurls | default(value=false) -%}
+{%- if config.extra.offline %}{% set uglyurls = true %}{% endif %}
{%- if inner.content == page.content %}
<li><a href="{{ inner.permalink | safe }}{%- if uglyurls %}index.html{%- endif %}"><b>{{ inner.title }}</b></a></li>
{% else %}
diff --git a/templates/page.html b/templates/page.html
index f5ca311..b362877 100644
--- a/templates/page.html
+++ b/templates/page.html
@@ -112,7 +112,7 @@
{%- set num_pages = tag.page_count %}
{# Shows the first page #}
- {{ macros::series_link(inner=sorted_array.0, page=page) }}
+ {{ macros::series_link(inner=sorted_array.0, page=page, config=config) }}
{# Hides the next couple of pages if the current section is more than 3 away from start #}
{%- if current_section_index > 3 %}
@@ -140,7 +140,7 @@
{# Shows the current page #}
{%- if current_section_index != 0 and current_section_index != (num_pages - 1) %}
- {{ macros::series_link(inner=sorted_array[current_section_index], page=page) }}
+ {{ macros::series_link(inner=sorted_array[current_section_index], page=page, config=config) }}
{%- endif %}
{# Min(num_pages - 1, current_section_index + 3) #}
@@ -166,12 +166,12 @@
{%- endif %}
{%- set last = num_pages - 1%}
- {{ macros::series_link(inner=sorted_array[last], page=page) }}
+ {{ macros::series_link(inner=sorted_array[last], page=page, config=config) }}
{# If there is not more than max pages render normally #}
{%- else %}
{%- for inner in tag.pages | sort(attribute="date") %}
- {{ macros::series_link(inner=inner, page=page) }}
+ {{ macros::series_link(inner=inner, page=page, config=config) }}
{%- endfor %}
{%- endif %}
</ol>