mirror of
https://github.com/jakejarvis/jarv.is.git
synced 2025-04-27 17:30:28 -04:00
bundle simple analytics script locally & minify everything with terser
This commit is contained in:
parent
cb32af40dc
commit
b0893ff52f
448
assets/js/simple-analytics.js
Normal file
448
assets/js/simple-analytics.js
Normal file
@ -0,0 +1,448 @@
|
|||||||
|
/* jshint browser: true, laxbreak:true, -W080 */
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Copyright (c) 2018-2020 Simple Analytics. Licensed under MIT.
|
||||||
|
* https://github.com/simpleanalytics/scripts/blob/master/LICENSE
|
||||||
|
*/
|
||||||
|
|
||||||
|
// https://github.com/simpleanalytics/scripts/blob/3918189e9137b55522a2dbeb3d7cb4bc2c26c52a/src/default.js
|
||||||
|
|
||||||
|
(function(window, baseUrl, apiUrlPrefix, version, saGlobal) {
|
||||||
|
if (!window) return;
|
||||||
|
|
||||||
|
// Generate the needed variables, this seems like a lot of repetition, but it
|
||||||
|
// makes our script availble for multple destination which prevents us to
|
||||||
|
// need multiple scripts. The minified version stays small.
|
||||||
|
var https = "https:";
|
||||||
|
var pageviewsText = "pageview";
|
||||||
|
var errorText = "error";
|
||||||
|
var protocol = https + "//";
|
||||||
|
var con = window.console;
|
||||||
|
var slash = "/";
|
||||||
|
var nav = window.navigator;
|
||||||
|
var loc = window.location;
|
||||||
|
var doc = window.document;
|
||||||
|
var notSending = "Not sending requests ";
|
||||||
|
var localhost = "localhost";
|
||||||
|
var encodeURIComponentFunc = encodeURIComponent;
|
||||||
|
var decodeURIComponentFunc = decodeURIComponent;
|
||||||
|
var stringify = JSON.stringify;
|
||||||
|
var thousand = 1000;
|
||||||
|
var addEventListenerFunc = window.addEventListener;
|
||||||
|
var fullApiUrl = protocol + baseUrl;
|
||||||
|
var undefinedVar = undefined;
|
||||||
|
|
||||||
|
var payload = {
|
||||||
|
version: 2
|
||||||
|
};
|
||||||
|
|
||||||
|
// A simple log function so the user knows why a request is not being send
|
||||||
|
var warn = function(message) {
|
||||||
|
if (con && con.warn) con.warn("Simple Analytics:", message);
|
||||||
|
};
|
||||||
|
|
||||||
|
var now = Date.now;
|
||||||
|
|
||||||
|
var uuid = function() {
|
||||||
|
var cryptoObject = window.crypto || window.msCrypto;
|
||||||
|
var emptyUUID = [1e7] + -1e3 + -4e3 + -8e3 + -1e11;
|
||||||
|
|
||||||
|
if (!cryptoObject)
|
||||||
|
return emptyUUID.replace(/[018]/g, function(c) {
|
||||||
|
var r = (Math.random() * 16) | 0,
|
||||||
|
v = c < 2 ? r : (r & 0x3) | 0x8;
|
||||||
|
return v.toString(16);
|
||||||
|
});
|
||||||
|
|
||||||
|
return emptyUUID.replace(/[018]/g, function(c) {
|
||||||
|
return (
|
||||||
|
c ^
|
||||||
|
(cryptoObject.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))
|
||||||
|
).toString(16);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
var assign = function() {
|
||||||
|
var to = {};
|
||||||
|
for (var index = 0; index < arguments.length; index++) {
|
||||||
|
var nextSource = arguments[index];
|
||||||
|
if (nextSource) {
|
||||||
|
for (var nextKey in nextSource) {
|
||||||
|
if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
|
||||||
|
to[nextKey] = nextSource[nextKey];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return to;
|
||||||
|
};
|
||||||
|
|
||||||
|
// This code could error on not having resolvedOptions in the Android Webview, that's why we use try...catch
|
||||||
|
var timezone;
|
||||||
|
try {
|
||||||
|
timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
||||||
|
} catch (e) {
|
||||||
|
/* Do nothing */
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send data via image of XHR request
|
||||||
|
function sendData(data) {
|
||||||
|
data = assign(payload, data);
|
||||||
|
new Image().src =
|
||||||
|
fullApiUrl +
|
||||||
|
"/s.gif?" +
|
||||||
|
Object.keys(data)
|
||||||
|
.filter(function(key) {
|
||||||
|
return data[key] != undefinedVar;
|
||||||
|
})
|
||||||
|
.map(function(key) {
|
||||||
|
return (
|
||||||
|
encodeURIComponentFunc(key) +
|
||||||
|
"=" +
|
||||||
|
encodeURIComponentFunc(data[key])
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.join("&");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send errors
|
||||||
|
function sendError(errorOrMessage) {
|
||||||
|
errorOrMessage = errorOrMessage.message || errorOrMessage;
|
||||||
|
warn(errorOrMessage);
|
||||||
|
sendData({
|
||||||
|
type: errorText,
|
||||||
|
error: errorOrMessage,
|
||||||
|
url: hostname + loc.pathname
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// We listen for the error events and only send errors that are
|
||||||
|
// from our script (checked by filename) to our server.
|
||||||
|
addEventListenerFunc(
|
||||||
|
errorText,
|
||||||
|
function(event) {
|
||||||
|
if (event.filename && event.filename.indexOf(baseUrl) > -1) {
|
||||||
|
sendError(event.message);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
|
/** if spa **/
|
||||||
|
var pushState = "pushState";
|
||||||
|
var dis = window.dispatchEvent;
|
||||||
|
/** endif **/
|
||||||
|
|
||||||
|
/** if duration **/
|
||||||
|
var duration = "duration";
|
||||||
|
var start = now();
|
||||||
|
/** endif **/
|
||||||
|
|
||||||
|
/** if scroll **/
|
||||||
|
var scrolled = 0;
|
||||||
|
/** endif **/
|
||||||
|
|
||||||
|
var mode;
|
||||||
|
var hostname = loc.hostname;
|
||||||
|
var functionName = "sa_event";
|
||||||
|
|
||||||
|
payload.hostname = hostname;
|
||||||
|
|
||||||
|
// Don't track when localhost
|
||||||
|
/** unless testing **/
|
||||||
|
//if (loc.hostname.indexOf(".") == -1)
|
||||||
|
// return warn(notSending + "from " + loc.localhost);
|
||||||
|
/** endunless **/
|
||||||
|
|
||||||
|
try {
|
||||||
|
var getParams = function(regex) {
|
||||||
|
// From the search we grab the utm_source and ref and save only that
|
||||||
|
var matches = loc.search.match(
|
||||||
|
new RegExp("[?&](" + regex + ")=([^?&]+)", "gi")
|
||||||
|
);
|
||||||
|
var match = matches
|
||||||
|
? matches.map(function(m) {
|
||||||
|
return m.split("=")[1];
|
||||||
|
})
|
||||||
|
: [];
|
||||||
|
if (match && match[0]) return match[0];
|
||||||
|
};
|
||||||
|
|
||||||
|
var page = {};
|
||||||
|
var lastPageId = uuid();
|
||||||
|
var lastSendPath;
|
||||||
|
|
||||||
|
// We don't want to end up with sensitive data so we clean the referrer URL
|
||||||
|
var utmRegexPrefix = "(utm_)?";
|
||||||
|
var source = {
|
||||||
|
source: getParams(utmRegexPrefix + "source|source|ref"),
|
||||||
|
medium: getParams(utmRegexPrefix + "medium"),
|
||||||
|
campaign: getParams(utmRegexPrefix + "campaign"),
|
||||||
|
referrer:
|
||||||
|
(doc.referrer || "")
|
||||||
|
.replace(/^https?:\/\/((m|l|w{2,3}([0-9]+)?)\.)?([^?#]+)(.*)$/, "$4")
|
||||||
|
.replace(/^([^/]+)\/$/, "$1") || undefinedVar
|
||||||
|
};
|
||||||
|
|
||||||
|
// We don't put msHidden in if duration block, because it's used outside of that functionality
|
||||||
|
var msHidden = 0;
|
||||||
|
|
||||||
|
/** if duration **/
|
||||||
|
var hiddenStart;
|
||||||
|
window.addEventListener(
|
||||||
|
"visibilitychange",
|
||||||
|
function() {
|
||||||
|
if (doc.hidden) hiddenStart = now();
|
||||||
|
else msHidden += now() - hiddenStart;
|
||||||
|
},
|
||||||
|
false
|
||||||
|
);
|
||||||
|
/** endif **/
|
||||||
|
|
||||||
|
var sendBeaconText = "sendBeacon";
|
||||||
|
|
||||||
|
var sendOnLeave = function(id, push) {
|
||||||
|
var append = { type: "append", original_id: push ? id : lastPageId };
|
||||||
|
|
||||||
|
/** if duration **/
|
||||||
|
append[duration] = Math.round((now() - start + msHidden) / thousand);
|
||||||
|
msHidden = 0;
|
||||||
|
start = now();
|
||||||
|
/** endif **/
|
||||||
|
|
||||||
|
/** if scroll **/
|
||||||
|
append.scrolled = Math.max(0, scrolled, position());
|
||||||
|
/** endif **/
|
||||||
|
|
||||||
|
if (push || !(sendBeaconText in nav)) {
|
||||||
|
sendData(append);
|
||||||
|
} else {
|
||||||
|
nav[sendBeaconText](
|
||||||
|
fullApiUrl + "/append",
|
||||||
|
stringify(assign(payload, append))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
addEventListenerFunc("unload", sendOnLeave, false);
|
||||||
|
|
||||||
|
/** if scroll **/
|
||||||
|
var scroll = "scroll";
|
||||||
|
var body = doc.body || {};
|
||||||
|
var documentElement = doc.documentElement || {};
|
||||||
|
var position = function() {
|
||||||
|
try {
|
||||||
|
var Height = "Height";
|
||||||
|
var scrollHeight = scroll + Height;
|
||||||
|
var offsetHeight = "offset" + Height;
|
||||||
|
var clientHeight = "client" + Height;
|
||||||
|
var documentClientHeight = documentElement[clientHeight] || 0;
|
||||||
|
var height = Math.max(
|
||||||
|
body[scrollHeight] || 0,
|
||||||
|
body[offsetHeight] || 0,
|
||||||
|
documentElement[clientHeight] || 0,
|
||||||
|
documentElement[scrollHeight] || 0,
|
||||||
|
documentElement[offsetHeight] || 0
|
||||||
|
);
|
||||||
|
return Math.min(
|
||||||
|
100,
|
||||||
|
Math.round(
|
||||||
|
(100 * ((documentElement.scrollTop || 0) + documentClientHeight)) /
|
||||||
|
height /
|
||||||
|
5
|
||||||
|
) * 5
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
addEventListenerFunc("load", function() {
|
||||||
|
scrolled = position();
|
||||||
|
addEventListenerFunc(
|
||||||
|
scroll,
|
||||||
|
function() {
|
||||||
|
if (scrolled < position()) scrolled = position();
|
||||||
|
},
|
||||||
|
false
|
||||||
|
);
|
||||||
|
});
|
||||||
|
/** endif **/
|
||||||
|
|
||||||
|
var sendPageView = function(isPushState, deleteSourceInfo) {
|
||||||
|
if (isPushState) sendOnLeave("" + lastPageId, true);
|
||||||
|
lastPageId = uuid();
|
||||||
|
page.id = lastPageId;
|
||||||
|
|
||||||
|
sendData(
|
||||||
|
assign(page, deleteSourceInfo ? null : source, {
|
||||||
|
https: loc.protocol == https,
|
||||||
|
timezone: timezone,
|
||||||
|
width: window.innerWidth,
|
||||||
|
type: pageviewsText
|
||||||
|
})
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
var pageview = function(isPushState) {
|
||||||
|
// Obfuscate personal data in URL by dropping the search and hash
|
||||||
|
var path = decodeURIComponentFunc(loc.pathname);
|
||||||
|
|
||||||
|
/** if hash **/
|
||||||
|
// Add hash to path when script is put in to hash mode
|
||||||
|
if (mode == "hash" && loc.hash) path += loc.hash.split("?")[0];
|
||||||
|
/** endif **/
|
||||||
|
|
||||||
|
// Don't send the last path again (this could happen when pushState is used to change the path hash or search)
|
||||||
|
if (lastSendPath == path) return;
|
||||||
|
|
||||||
|
lastSendPath = path;
|
||||||
|
|
||||||
|
var data = {
|
||||||
|
path: path
|
||||||
|
};
|
||||||
|
|
||||||
|
// If a user does refresh we need to delete the referrer because otherwise it count double
|
||||||
|
var perf = window.performance;
|
||||||
|
var navigation = "navigation";
|
||||||
|
|
||||||
|
// Check if back, forward or reload buttons are being used in modern browsers
|
||||||
|
var userNavigated =
|
||||||
|
perf &&
|
||||||
|
perf.getEntriesByType &&
|
||||||
|
perf.getEntriesByType(navigation)[0] &&
|
||||||
|
perf.getEntriesByType(navigation)[0].type
|
||||||
|
? ["reload", "back_forward"].indexOf(
|
||||||
|
perf.getEntriesByType(navigation)[0].type
|
||||||
|
) > -1
|
||||||
|
: // Check if back, forward or reload buttons are being use in older browsers
|
||||||
|
// 1: TYPE_RELOAD, 2: TYPE_BACK_FORWARD
|
||||||
|
perf &&
|
||||||
|
perf[navigation] &&
|
||||||
|
[1, 2].indexOf(perf[navigation].type) > -1;
|
||||||
|
|
||||||
|
/** if uniques **/
|
||||||
|
// We set unique variable based on pushstate or back navigation, if no match we check the referrer
|
||||||
|
data.unique =
|
||||||
|
isPushState || userNavigated
|
||||||
|
? false
|
||||||
|
: doc.referrer
|
||||||
|
? doc.referrer.split(slash)[2] != loc.hostname
|
||||||
|
: true;
|
||||||
|
/** endif **/
|
||||||
|
|
||||||
|
page = data;
|
||||||
|
|
||||||
|
sendPageView(isPushState, isPushState || userNavigated);
|
||||||
|
};
|
||||||
|
|
||||||
|
/** if spa **/
|
||||||
|
var his = window.history;
|
||||||
|
var hisPushState = his ? his.pushState : undefinedVar;
|
||||||
|
|
||||||
|
// Overwrite history pushState function to
|
||||||
|
// allow listening on the pushState event
|
||||||
|
if (hisPushState && Event && dis) {
|
||||||
|
var stateListener = function(type) {
|
||||||
|
var orig = his[type];
|
||||||
|
return function() {
|
||||||
|
var rv = orig.apply(this, arguments);
|
||||||
|
var event;
|
||||||
|
if (typeof Event == "function") {
|
||||||
|
event = new Event(type);
|
||||||
|
} else {
|
||||||
|
// Fix for IE
|
||||||
|
event = doc.createEvent("Event");
|
||||||
|
event.initEvent(type, true, true);
|
||||||
|
}
|
||||||
|
event.arguments = arguments;
|
||||||
|
dis(event);
|
||||||
|
return rv;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
his.pushState = stateListener(pushState);
|
||||||
|
|
||||||
|
addEventListenerFunc(
|
||||||
|
pushState,
|
||||||
|
function() {
|
||||||
|
pageview(1);
|
||||||
|
},
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
|
addEventListenerFunc(
|
||||||
|
"popstate",
|
||||||
|
function() {
|
||||||
|
pageview(1);
|
||||||
|
},
|
||||||
|
false
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/** endif **/
|
||||||
|
|
||||||
|
/** if hash **/
|
||||||
|
// When in hash mode, we record a pageview based on the onhashchange function
|
||||||
|
if (mode == "hash" && "onhashchange" in window) {
|
||||||
|
addEventListenerFunc(
|
||||||
|
"hashchange",
|
||||||
|
function() {
|
||||||
|
pageview(1);
|
||||||
|
},
|
||||||
|
false
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/** endif **/
|
||||||
|
|
||||||
|
pageview();
|
||||||
|
|
||||||
|
/** if events **/
|
||||||
|
var sessionId = uuid();
|
||||||
|
|
||||||
|
var sendEvent = function(event) {
|
||||||
|
var isFunction = event instanceof Function;
|
||||||
|
if (["string", "number"].indexOf(typeof event) < 0 && !isFunction)
|
||||||
|
return warn("event is not a string: " + event);
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (isFunction) {
|
||||||
|
event = event();
|
||||||
|
if (["string", "number"].indexOf(typeof event) < 0)
|
||||||
|
return warn("event function output is not a string: " + event);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
return warn("in your event function: " + error.message);
|
||||||
|
}
|
||||||
|
event = ("" + event).replace(/[^a-z0-9]+/gi, "_").replace(/(^_|_$)/g, "");
|
||||||
|
if (event)
|
||||||
|
sendData(
|
||||||
|
assign(source, {
|
||||||
|
type: "event",
|
||||||
|
event: event,
|
||||||
|
session_id: sessionId
|
||||||
|
})
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
var defaultEventFunc = function(event) {
|
||||||
|
sendEvent(event);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Set default function if user didn't define a function
|
||||||
|
if (!window[functionName]) window[functionName] = defaultEventFunc;
|
||||||
|
|
||||||
|
var eventFunc = window[functionName];
|
||||||
|
|
||||||
|
// Read queue of the user defined function
|
||||||
|
var queue = eventFunc && eventFunc.q ? eventFunc.q : [];
|
||||||
|
|
||||||
|
// Overwrite user defined function
|
||||||
|
window[functionName] = defaultEventFunc;
|
||||||
|
|
||||||
|
// Post events from the queue of the user defined function
|
||||||
|
for (var event in queue) sendEvent(queue[event]);
|
||||||
|
/** endif **/
|
||||||
|
} catch (e) {
|
||||||
|
sendError(e);
|
||||||
|
}
|
||||||
|
})(window, "{{ (urls.Parse .Site.BaseURL).Host }}");
|
4
assets/vendor/emoji/emoji.js
vendored
4
assets/vendor/emoji/emoji.js
vendored
@ -1,10 +1,8 @@
|
|||||||
/* jshint indent: 2, browser: true, bitwise: true, plusplus: true */
|
/* jshint indent: 2, browser: true, bitwise: true, plusplus: true */
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
*
|
* Copyright (c) 2018 Twitter, Inc. and other contributors. Licensed under MIT.
|
||||||
* Copyright Twitter Inc. and other contributors. Licensed under MIT.
|
|
||||||
* https://github.com/twitter/twemoji/blob/gh-pages/LICENSE
|
* https://github.com/twitter/twemoji/blob/gh-pages/LICENSE
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(function (
|
(function (
|
||||||
|
@ -12,9 +12,6 @@
|
|||||||
{{ partialCached "page/footer" . }}
|
{{ partialCached "page/footer" . }}
|
||||||
{{ partial "scripts/_bundle" . }}
|
{{ partial "scripts/_bundle" . }}
|
||||||
{{ partial "scripts/shortcodes" . }}
|
{{ partial "scripts/shortcodes" . }}
|
||||||
{{ if eq hugo.Environment "production" }}
|
|
||||||
{{ partialCached "scripts/simple_analytics" . }}
|
|
||||||
{{ end }}
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
|
@ -5,14 +5,6 @@
|
|||||||
X-Frame-Options: sameorigin
|
X-Frame-Options: sameorigin
|
||||||
X-XSS-Protection: 1; mode=block
|
X-XSS-Protection: 1; mode=block
|
||||||
|
|
||||||
# Long cache (one week) for vendored and fingerprinted assets:
|
|
||||||
/css/*
|
|
||||||
Cache-Control: public, max-age=604800, immutable
|
|
||||||
/js/*
|
|
||||||
Cache-Control: public, max-age=604800, immutable
|
|
||||||
/vendor/*
|
|
||||||
Cache-Control: public, max-age=604800, immutable
|
|
||||||
|
|
||||||
# Recommended MIME type for PWA manifests:
|
# Recommended MIME type for PWA manifests:
|
||||||
# https://github.com/w3c/manifest/issues/689
|
# https://github.com/w3c/manifest/issues/689
|
||||||
/site.webmanifest
|
/site.webmanifest
|
||||||
|
@ -1,11 +1,9 @@
|
|||||||
{{ $style := resources.Get "sass/main.scss" | resources.ExecuteAsTemplate "sass/main.scss" . | resources.ToCSS (dict "targetPath" "css/main.min.css") | resources.PostCSS (dict "config" "postcss.config.js") | resources.Fingerprint "sha256" }}
|
{{ $style := resources.Get "sass/main.scss" | resources.ExecuteAsTemplate "sass/main.scss" . | resources.ToCSS (dict "targetPath" "css/main.css") | resources.PostCSS (dict "config" "postcss.config.js") }}
|
||||||
<link rel="stylesheet" href="{{ $style.Permalink }}">
|
<link rel="stylesheet" href="{{ $style.Permalink }}">
|
||||||
|
|
||||||
{{/* Page-specific styles set via front matter, scoped via SCSS */}}
|
{{/* Page-specific styles set via front matter, scoped via SCSS */}}
|
||||||
{{ with .Params.css }}
|
{{ with .Params.css }}
|
||||||
{{- $target := path.Join $.File.Dir "css/inline.min.scss" }}
|
{{- $target := path.Join $.File.Dir "css/inline.scss" }}
|
||||||
|
{{- $css := . | resources.FromString $target | resources.ToCSS | resources.PostCSS (dict "config" "postcss.config.js") -}}
|
||||||
{{- $css := . | resources.FromString $target | resources.ToCSS | resources.PostCSS (dict "config" "postcss.config.js") | resources.Fingerprint "sha256" -}}
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="{{ $css.Permalink }}">
|
<link rel="stylesheet" href="{{ $css.Permalink }}">
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
@ -1,5 +1,13 @@
|
|||||||
{{ $darkmode := resources.Get "js/dark-mode.js" | resources.ExecuteAsTemplate "vendor/emoji/dark-mode.js" . }}
|
{{ $darkmode := resources.Get "js/dark-mode.js" | resources.ExecuteAsTemplate "js/dark-mode.js" . }}
|
||||||
{{ $twemoji := resources.Get "vendor/emoji/emoji.js" | resources.ExecuteAsTemplate "vendor/emoji/emoji.min.js" . }}
|
{{ $twemoji := resources.Get "vendor/emoji/emoji.js" | resources.ExecuteAsTemplate "vendor/emoji/emoji.min.js" . }}
|
||||||
|
{{ $analytics := resources.Get "js/simple-analytics.js" | resources.ExecuteAsTemplate "js/simple-analytics.js" . }}
|
||||||
|
|
||||||
{{ $js := slice $darkmode $twemoji | resources.Concat "/js/main.js" | resources.Minify | resources.Fingerprint "sha256" }}
|
{{ $bundle := "" }}
|
||||||
<script async defer {{ printf "src=%q integrity=%q" $js.Permalink $js.Data.Integrity | safeHTMLAttr }}></script>
|
{{ if eq hugo.Environment "development" }}
|
||||||
|
{{ $bundle = slice $darkmode $twemoji }}
|
||||||
|
{{ else }}
|
||||||
|
{{ $bundle = slice $darkmode $twemoji $analytics }}
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{ $js := $bundle | resources.Concat "/js/app.js" }}
|
||||||
|
<script async defer src="{{ $js.Permalink }}"></script>
|
||||||
|
@ -1,2 +0,0 @@
|
|||||||
<script async defer src="https://s.jarv.is/latest.js" data-skip-dnt="true"></script>
|
|
||||||
<noscript><img src="https://s.jarv.is/image.gif" alt=""></noscript>
|
|
@ -79,6 +79,13 @@
|
|||||||
status = 301
|
status = 301
|
||||||
force = true
|
force = true
|
||||||
|
|
||||||
|
# Proxy data to Simple Analytics endpoint
|
||||||
|
[[redirects]]
|
||||||
|
from = "/s.gif*"
|
||||||
|
to = "https://queue.simpleanalyticscdn.com/simple.gif:splat"
|
||||||
|
status = 200
|
||||||
|
force = true
|
||||||
|
|
||||||
# Support ancient RSS subscriptions and links from WordPress era:
|
# Support ancient RSS subscriptions and links from WordPress era:
|
||||||
[[redirects]]
|
[[redirects]]
|
||||||
from = "/feed"
|
from = "/feed"
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
"start": "hugo server --disableFastRender --buildDrafts --buildFuture --port 1337 --bind 0.0.0.0 --verbose",
|
"start": "hugo server --disableFastRender --buildDrafts --buildFuture --port 1337 --bind 0.0.0.0 --verbose",
|
||||||
"optimize": "run-s optimize:**",
|
"optimize": "run-s optimize:**",
|
||||||
"optimize:html": "html-minifier --html5 --collapse-whitespace --collapse-boolean-attributes --preserve-line-breaks --minify-css --file-ext html --input-dir public --output-dir public **/*.html",
|
"optimize:html": "html-minifier --html5 --collapse-whitespace --collapse-boolean-attributes --preserve-line-breaks --minify-css --file-ext html --input-dir public --output-dir public **/*.html",
|
||||||
|
"optimize:js": "terser --mangle --compress passes=3,negate_iife=false,keep_fargs=false,sequences=false,reduce_vars=false --mangle-props --output public/js/app.js -- public/js/app.js",
|
||||||
"optimize:img": "find ./public -type d ! -path './public/vendor*' | xargs -n1 -P8 -I{} imagemin {}/* --plugin=jpegoptim --plugin.jpegoptim.progressive --plugin.jpegoptim.stripAll --plugin=pngquant --plugin.pngquant.quality={0.1,0.3} --plugin.pngquant.speed=1 --plugin.pngquant.strip --plugin=gifsicle --plugin=svgo --out-dir={}",
|
"optimize:img": "find ./public -type d ! -path './public/vendor*' | xargs -n1 -P8 -I{} imagemin {}/* --plugin=jpegoptim --plugin.jpegoptim.progressive --plugin.jpegoptim.stripAll --plugin=pngquant --plugin.pngquant.quality={0.1,0.3} --plugin.pngquant.speed=1 --plugin.pngquant.strip --plugin=gifsicle --plugin=svgo --out-dir={}",
|
||||||
"lint": "run-s lint:**",
|
"lint": "run-s lint:**",
|
||||||
"lint:scss": "stylelint assets/sass/**/* --syntax scss",
|
"lint:scss": "stylelint assets/sass/**/* --syntax scss",
|
||||||
@ -52,7 +53,8 @@
|
|||||||
"rimraf": "^3.0.2",
|
"rimraf": "^3.0.2",
|
||||||
"stylelint": "~13.3.3",
|
"stylelint": "~13.3.3",
|
||||||
"stylelint-config-sass-guidelines": "~7.0.0",
|
"stylelint-config-sass-guidelines": "~7.0.0",
|
||||||
"stylelint-scss": "~3.17.1"
|
"stylelint-scss": "~3.17.1",
|
||||||
|
"terser": "^4.6.12"
|
||||||
},
|
},
|
||||||
"resolutions": {
|
"resolutions": {
|
||||||
"postcss-clean/postcss": "^7.x"
|
"postcss-clean/postcss": "^7.x"
|
||||||
|
26
yarn.lock
26
yarn.lock
@ -545,6 +545,11 @@ buffer-fill@^1.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c"
|
resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c"
|
||||||
integrity sha1-+PeLdniYiO858gXNY39o5wISKyw=
|
integrity sha1-+PeLdniYiO858gXNY39o5wISKyw=
|
||||||
|
|
||||||
|
buffer-from@^1.0.0:
|
||||||
|
version "1.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef"
|
||||||
|
integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==
|
||||||
|
|
||||||
buffer@^5.2.1:
|
buffer@^5.2.1:
|
||||||
version "5.6.0"
|
version "5.6.0"
|
||||||
resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.6.0.tgz#a31749dc7d81d84db08abf937b6b8c4033f62786"
|
resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.6.0.tgz#a31749dc7d81d84db08abf937b6b8c4033f62786"
|
||||||
@ -848,7 +853,7 @@ color-name@~1.1.4:
|
|||||||
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
|
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
|
||||||
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
|
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
|
||||||
|
|
||||||
commander@^2.19.0, commander@~2.20.3:
|
commander@^2.19.0, commander@^2.20.0, commander@~2.20.3:
|
||||||
version "2.20.3"
|
version "2.20.3"
|
||||||
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
|
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
|
||||||
integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
|
integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
|
||||||
@ -4196,12 +4201,20 @@ sort-keys@^2.0.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
is-plain-obj "^1.0.0"
|
is-plain-obj "^1.0.0"
|
||||||
|
|
||||||
|
source-map-support@~0.5.12:
|
||||||
|
version "0.5.19"
|
||||||
|
resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61"
|
||||||
|
integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==
|
||||||
|
dependencies:
|
||||||
|
buffer-from "^1.0.0"
|
||||||
|
source-map "^0.6.0"
|
||||||
|
|
||||||
source-map@^0.5.0:
|
source-map@^0.5.0:
|
||||||
version "0.5.7"
|
version "0.5.7"
|
||||||
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
|
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
|
||||||
integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=
|
integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=
|
||||||
|
|
||||||
source-map@^0.6.1, source-map@~0.6.0:
|
source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1:
|
||||||
version "0.6.1"
|
version "0.6.1"
|
||||||
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
|
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
|
||||||
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
|
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
|
||||||
@ -4665,6 +4678,15 @@ tempfile@^2.0.0:
|
|||||||
temp-dir "^1.0.0"
|
temp-dir "^1.0.0"
|
||||||
uuid "^3.0.1"
|
uuid "^3.0.1"
|
||||||
|
|
||||||
|
terser@^4.6.12:
|
||||||
|
version "4.6.12"
|
||||||
|
resolved "https://registry.yarnpkg.com/terser/-/terser-4.6.12.tgz#44b98aef8703fdb09a3491bf79b43faffc5b4fee"
|
||||||
|
integrity sha512-fnIwuaKjFPANG6MAixC/k1TDtnl1YlPLUlLVIxxGZUn1gfUx2+l3/zGNB72wya+lgsb50QBi2tUV75RiODwnww==
|
||||||
|
dependencies:
|
||||||
|
commander "^2.20.0"
|
||||||
|
source-map "~0.6.1"
|
||||||
|
source-map-support "~0.5.12"
|
||||||
|
|
||||||
through@^2.3.8:
|
through@^2.3.8:
|
||||||
version "2.3.8"
|
version "2.3.8"
|
||||||
resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
|
resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user