jekyll-theme-nangka 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE.txt +21 -0
- data/README.md +52 -0
- data/_includes/footer.html +17 -0
- data/_includes/head.html +12 -0
- data/_includes/header.html +35 -0
- data/_includes/partial/analytics.html +10 -0
- data/_includes/partial/breadcrumb.html +37 -0
- data/_includes/partial/disqus.html +23 -0
- data/_includes/partial/manifest.html +52 -0
- data/_includes/partial/mini-bio.html +16 -0
- data/_includes/partial/post-item.html +40 -0
- data/_includes/partial/scrimage.html +26 -0
- data/_includes/svg/icon-facebook.svg +1 -0
- data/_includes/svg/icon-github.html +1 -0
- data/_includes/svg/icon-github.svg +1 -0
- data/_includes/svg/icon-twitter.html +1 -0
- data/_includes/svg/icon-twitter.svg +1 -0
- data/_layouts/blog.html +21 -0
- data/_layouts/compress.html +9 -0
- data/_layouts/default.html +17 -0
- data/_layouts/home.html +11 -0
- data/_layouts/page.html +11 -0
- data/_layouts/post.html +50 -0
- data/_sass/_base.scss +298 -0
- data/_sass/_layout.scss +270 -0
- data/_sass/_normalize.scss +525 -0
- data/_sass/_syntax-highlighting.scss +204 -0
- data/_sass/print.scss +102 -0
- data/assets/404.html +24 -0
- data/assets/blog.json +5 -0
- data/assets/browserconfig.xml +15 -0
- data/assets/crossdomain.xml +19 -0
- data/assets/css/main.scss +56 -0
- data/assets/humans.txt +21 -0
- data/assets/icons/114.png +0 -0
- data/assets/icons/120.png +0 -0
- data/assets/icons/144.png +0 -0
- data/assets/icons/150.png +0 -0
- data/assets/icons/152.png +0 -0
- data/assets/icons/16.png +0 -0
- data/assets/icons/180.png +0 -0
- data/assets/icons/192.png +0 -0
- data/assets/icons/256.png +0 -0
- data/assets/icons/310.png +0 -0
- data/assets/icons/32.png +0 -0
- data/assets/icons/36.png +0 -0
- data/assets/icons/48.png +0 -0
- data/assets/icons/512.png +0 -0
- data/assets/icons/57.png +0 -0
- data/assets/icons/60.png +0 -0
- data/assets/icons/70.png +0 -0
- data/assets/icons/72.png +0 -0
- data/assets/icons/76.png +0 -0
- data/assets/icons/96.png +0 -0
- data/assets/icons/favicon.ico +0 -0
- data/assets/icons/icon.svg +31 -0
- data/assets/images/avatar.jpg +0 -0
- data/assets/js/app.js +35 -0
- data/assets/js/sw.js +174 -0
- data/assets/manifest.json +70 -0
- data/assets/opensearch.xml +13 -0
- data/assets/robots.txt +7 -0
- data/assets/search.html +16 -0
- metadata +261 -0
data/_sass/print.scss
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
@media print {
|
2
|
+
@page {
|
3
|
+
margin: 1.2cm;
|
4
|
+
}
|
5
|
+
|
6
|
+
body {
|
7
|
+
font: 12pt Georgia, "Times New Roman", Times, serif;
|
8
|
+
line-height: 1.3;
|
9
|
+
background: #fff !important;
|
10
|
+
-webkit-print-color-adjust: exact !important;
|
11
|
+
color-adjust: exact !important;
|
12
|
+
}
|
13
|
+
|
14
|
+
p {
|
15
|
+
orphans: 2;
|
16
|
+
widows: 2;
|
17
|
+
}
|
18
|
+
|
19
|
+
pre,code{
|
20
|
+
font-size: inherit;
|
21
|
+
}
|
22
|
+
|
23
|
+
|
24
|
+
.wrapper > :not(.content-wrapper), .content-wrapper > :not(article), footer, .time {
|
25
|
+
display: none;
|
26
|
+
}
|
27
|
+
|
28
|
+
h1 {
|
29
|
+
column-span: all;
|
30
|
+
break-before: column;
|
31
|
+
break-inside: avoid-column;
|
32
|
+
break-after: avoid-column;
|
33
|
+
font-size: 24pt;
|
34
|
+
background: #5c5c5c;
|
35
|
+
color: #fff !important;
|
36
|
+
-moz-color: #fff !important;
|
37
|
+
padding: 0 5pt;
|
38
|
+
border: none;
|
39
|
+
line-height: 1.4;
|
40
|
+
display: inline;
|
41
|
+
}
|
42
|
+
|
43
|
+
h2 {
|
44
|
+
font-size: 14pt;
|
45
|
+
margin-top: 25px;
|
46
|
+
break-after: avoid;
|
47
|
+
}
|
48
|
+
|
49
|
+
blockquote, ul {
|
50
|
+
margin: 0;
|
51
|
+
}
|
52
|
+
|
53
|
+
ul {
|
54
|
+
list-style: none;
|
55
|
+
}
|
56
|
+
|
57
|
+
li {
|
58
|
+
content: "» ";
|
59
|
+
word-wrap: break-word;
|
60
|
+
}
|
61
|
+
|
62
|
+
a {
|
63
|
+
color: #000;
|
64
|
+
word-wrap: break-word;
|
65
|
+
}
|
66
|
+
|
67
|
+
p a[href^="http://"]:after, a[href^="https://"]:after {
|
68
|
+
content: " (" attr(href) ")";
|
69
|
+
font-weight: normal;
|
70
|
+
font-size: 10pt;
|
71
|
+
font-style: italic;
|
72
|
+
border: none;
|
73
|
+
}
|
74
|
+
|
75
|
+
abbr:after {
|
76
|
+
content: " (" attr(title) ")";
|
77
|
+
font-weight: 100;
|
78
|
+
font-style: italic;
|
79
|
+
border: none;
|
80
|
+
}
|
81
|
+
|
82
|
+
p a[href^="#"]:after {
|
83
|
+
display: none;
|
84
|
+
}
|
85
|
+
|
86
|
+
.wrapper {
|
87
|
+
max-width: 100% !important;
|
88
|
+
float: none;
|
89
|
+
margin: 0;
|
90
|
+
padding: 0;
|
91
|
+
}
|
92
|
+
.post-meta {
|
93
|
+
margin: 0 0 .5cm 0;
|
94
|
+
:before {
|
95
|
+
content: $domain " - ";
|
96
|
+
}
|
97
|
+
}
|
98
|
+
img{
|
99
|
+
display: block;
|
100
|
+
margin: 0 auto;
|
101
|
+
}
|
102
|
+
}
|
data/assets/404.html
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
---
|
2
|
+
layout: default
|
3
|
+
permalink : /404.html
|
4
|
+
---
|
5
|
+
|
6
|
+
<style type="text/css" media="screen">
|
7
|
+
.container {
|
8
|
+
text-align: center;
|
9
|
+
}
|
10
|
+
.container h1 {
|
11
|
+
margin: 30px 0;
|
12
|
+
font-size: 4em;
|
13
|
+
line-height: 1;
|
14
|
+
border: 0;
|
15
|
+
letter-spacing: -1px;
|
16
|
+
}
|
17
|
+
</style>
|
18
|
+
|
19
|
+
<div class="container">
|
20
|
+
<h1>404</h1>
|
21
|
+
|
22
|
+
<p><strong>Page not found :(</strong></p>
|
23
|
+
<p>The requested page could not be found.</p>
|
24
|
+
</div>
|
data/assets/blog.json
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
layout: null
|
3
|
+
permalink: /browserconfig.xml
|
4
|
+
---
|
5
|
+
<?xml version="1.0" encoding="utf-8"?>
|
6
|
+
<browserconfig>
|
7
|
+
<msapplication>
|
8
|
+
<tile>
|
9
|
+
<square70x70logo src="{{ '/assets/icons/70.png' | absolute_url }}"/>
|
10
|
+
<square150x150logo src="{{ '/assets/icons/150.png' | absolute_url }}"/>
|
11
|
+
<square310x310logo src="{{ '/assets/icons/310.png' | absolute_url }}"/>
|
12
|
+
<TileColor>#ffffff</TileColor>
|
13
|
+
</tile>
|
14
|
+
</msapplication>
|
15
|
+
</browserconfig>
|
@@ -0,0 +1,19 @@
|
|
1
|
+
---
|
2
|
+
layout: null
|
3
|
+
permalink: /crossdomain.xml
|
4
|
+
---
|
5
|
+
<?xml version="1.0"?>
|
6
|
+
<!DOCTYPE cross-domain-policy SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd">
|
7
|
+
<cross-domain-policy>
|
8
|
+
<!-- Read this: https://www.adobe.com/devnet/articles/crossdomain_policy_file_spec.html -->
|
9
|
+
|
10
|
+
<!-- Most restrictive policy: -->
|
11
|
+
<site-control permitted-cross-domain-policies="none"/>
|
12
|
+
|
13
|
+
<!-- Least restrictive policy: -->
|
14
|
+
<!--
|
15
|
+
<site-control permitted-cross-domain-policies="all"/>
|
16
|
+
<allow-access-from domain="*" to-ports="*" secure="false"/>
|
17
|
+
<allow-http-request-headers-from domain="*" headers="*" secure="false"/>
|
18
|
+
-->
|
19
|
+
</cross-domain-policy>
|
@@ -0,0 +1,56 @@
|
|
1
|
+
---
|
2
|
+
# Only the main Sass file needs front matter (the dashes are enough)
|
3
|
+
---
|
4
|
+
@charset "utf-8";
|
5
|
+
|
6
|
+
|
7
|
+
|
8
|
+
// Our variables
|
9
|
+
$base-font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
10
|
+
$base-font-size: 16px;
|
11
|
+
$base-font-weight: 400;
|
12
|
+
$small-font-size: $base-font-size * 0.875;
|
13
|
+
$base-line-height: 1.5;
|
14
|
+
|
15
|
+
$spacing-unit: 30px;
|
16
|
+
$domain : "{{site.url}}";
|
17
|
+
|
18
|
+
$text-color: #111;
|
19
|
+
$background-color: #fdfdfd;
|
20
|
+
$brand-color: #2a7ae2;
|
21
|
+
|
22
|
+
$grey-color: #828282;
|
23
|
+
$grey-color-light: lighten($grey-color, 40%);
|
24
|
+
$grey-color-dark: darken($grey-color, 25%);
|
25
|
+
|
26
|
+
// Width of the content area
|
27
|
+
$content-width: 40rem;
|
28
|
+
|
29
|
+
$on-palm: 600px;
|
30
|
+
$on-laptop: 800px;
|
31
|
+
|
32
|
+
|
33
|
+
|
34
|
+
// Use media queries like this:
|
35
|
+
// @include media-query($on-palm) {
|
36
|
+
// .wrapper {
|
37
|
+
// padding-right: $spacing-unit / 2;
|
38
|
+
// padding-left: $spacing-unit / 2;
|
39
|
+
// }
|
40
|
+
// }
|
41
|
+
@mixin media-query($device) {
|
42
|
+
@media screen and (min-width: $device) {
|
43
|
+
@content;
|
44
|
+
}
|
45
|
+
}
|
46
|
+
|
47
|
+
|
48
|
+
|
49
|
+
// Import partials from `sass_dir` (defaults to `_sass`)
|
50
|
+
@import
|
51
|
+
"normalize",
|
52
|
+
"base",
|
53
|
+
"layout",
|
54
|
+
"syntax-highlighting",
|
55
|
+
"print"
|
56
|
+
;
|
data/assets/humans.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
---
|
2
|
+
layout: null
|
3
|
+
permalink: /humans.txt
|
4
|
+
---
|
5
|
+
/* TEAM */
|
6
|
+
Standard Man: {{ site.author | default : site.title }}
|
7
|
+
Contact:{{ site.email | default: 'su [at] bekti.net' | replace: '@',' [at] ' }}
|
8
|
+
Twitter: @{{site.twitter_username}}
|
9
|
+
From: Yogyakarta, Indonesia
|
10
|
+
|
11
|
+
/* THANKS */
|
12
|
+
Readers: The Reader
|
13
|
+
From: All around, the globe
|
14
|
+
|
15
|
+
/* SITE */
|
16
|
+
Site Generator : Jekyll {{ jekyll.version }}
|
17
|
+
Last update: {{ site.time | date: "%Y/%m/%d" }}
|
18
|
+
Language: Indonesia
|
19
|
+
Doctype: HTML5
|
20
|
+
IDE: Atom, Visual Studio Code, Git Bash, Google Chrome DevTools
|
21
|
+
Hosting : Github Pages
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
data/assets/icons/16.png
ADDED
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
data/assets/icons/32.png
ADDED
Binary file
|
data/assets/icons/36.png
ADDED
Binary file
|
data/assets/icons/48.png
ADDED
Binary file
|
Binary file
|
data/assets/icons/57.png
ADDED
Binary file
|
data/assets/icons/60.png
ADDED
Binary file
|
data/assets/icons/70.png
ADDED
Binary file
|
data/assets/icons/72.png
ADDED
Binary file
|
data/assets/icons/76.png
ADDED
Binary file
|
data/assets/icons/96.png
ADDED
Binary file
|
Binary file
|
@@ -0,0 +1,31 @@
|
|
1
|
+
<?xml version="1.0" standalone="no"?>
|
2
|
+
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
3
|
+
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
4
|
+
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
5
|
+
width="512.000000pt" height="512.000000pt" viewBox="0 0 512.000000 512.000000"
|
6
|
+
preserveAspectRatio="xMidYMid meet">
|
7
|
+
<metadata>
|
8
|
+
Created by potrace 1.13, written by Peter Selinger 2001-2015
|
9
|
+
</metadata>
|
10
|
+
<g transform="translate(0.000000,512.000000) scale(0.100000,-0.100000)"
|
11
|
+
fill="#000000" stroke="none">
|
12
|
+
<path d="M2292 4745 c-138 -48 -333 -155 -577 -318 -240 -160 -470 -347 -480
|
13
|
+
-390 -12 -55 -46 -267 -69 -432 -47 -340 -85 -787 -106 -1230 -17 -378 -60
|
14
|
+
-1825 -54 -1836 2 -4 35 -14 72 -24 l69 -18 17 -53 c36 -115 86 -145 246 -152
|
15
|
+
l116 -5 92 52 c50 29 224 117 386 196 301 148 439 230 513 307 l42 43 16 180
|
16
|
+
c9 99 29 301 45 448 41 375 58 589 66 833 l7 211 47 -56 c163 -195 346 -293
|
17
|
+
595 -321 101 -12 232 -2 341 26 390 97 684 448 780 929 26 126 25 458 0 600
|
18
|
+
-50 280 -160 491 -324 621 -80 63 -219 130 -337 161 -94 25 -114 27 -325 27
|
19
|
+
-277 1 -384 -19 -583 -107 -31 -14 -61 -27 -65 -28 -4 0 -14 34 -22 77 l-15
|
20
|
+
79 -72 13 -72 14 19 39 c11 21 20 44 20 52 0 8 -34 28 -82 47 -114 46 -204 51
|
21
|
+
-306 15z m95 -447 c-6 -154 -28 -340 -60 -506 -10 -53 -11 -75 -3 -78 6 -2 37
|
22
|
+
-13 68 -23 l58 -20 50 40 c60 47 149 129 322 296 186 179 286 237 464 268 363
|
23
|
+
63 612 -64 703 -358 23 -76 25 -96 26 -292 0 -165 -4 -228 -18 -292 -70 -324
|
24
|
+
-231 -574 -435 -676 -82 -40 -86 -41 -207 -45 -322 -11 -506 116 -546 378 -15
|
25
|
+
96 -8 146 41 308 22 74 40 148 40 167 0 39 -26 75 -86 116 -52 36 -70 34 -151
|
26
|
+
-12 -215 -123 -350 -353 -414 -709 -21 -117 -23 -163 -29 -750 -7 -648 -12
|
27
|
+
-728 -55 -850 -26 -77 -37 -90 -120 -145 -179 -119 -739 -385 -762 -362 -7 7
|
28
|
+
49 1234 87 1907 32 565 76 1127 96 1222 9 46 156 168 339 283 128 80 556 294
|
29
|
+
589 295 5 0 6 -68 3 -162z"/>
|
30
|
+
</g>
|
31
|
+
</svg>
|
Binary file
|
data/assets/js/app.js
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
---
|
2
|
+
---
|
3
|
+
//Register service worker
|
4
|
+
if ('serviceWorker' in navigator) {
|
5
|
+
navigator.serviceWorker.register('/sw.js')
|
6
|
+
.then(function(reg) {
|
7
|
+
// Registration was successful
|
8
|
+
console.log(reg.scope);
|
9
|
+
|
10
|
+
// updatefound is fired if service-worker.js changes.
|
11
|
+
reg.onupdatefound = function() {
|
12
|
+
var installingWorker = reg.installing;
|
13
|
+
{%- if site.google_analytics -%}
|
14
|
+
installingWorker.onstatechange = function() {
|
15
|
+
ga('send', 'event','Progressive Web App', 'Service Worker State', installingWorker.state);
|
16
|
+
};
|
17
|
+
{%- endif -%}
|
18
|
+
};
|
19
|
+
})
|
20
|
+
.catch(err => console.error('%c 😨\n', 'font-size:60px; color:red', err));
|
21
|
+
|
22
|
+
//Check to see whether the service worker is controlling the page.
|
23
|
+
if (navigator.serviceWorker.controller) {
|
24
|
+
// If .controller is set, then this page is being actively controlled by the service worker.
|
25
|
+
console.info('%c 🤘', 'font-size:70px; color: #bada55' /*,reg*/ );
|
26
|
+
|
27
|
+
} else {
|
28
|
+
// If .controller isn't set, then prompt the user to reload the page so that the service worker can take
|
29
|
+
// control. Until that happens, the service worker's fetch handler won't be used.
|
30
|
+
console.info('%c ⚓\n%cPlease reload this page to allow the service worker to handle network operations.', 'font-size:60px; color:green', 'background-color:#333;color:#fff;');
|
31
|
+
}
|
32
|
+
} else {
|
33
|
+
// The current browser doesn't support service workers.
|
34
|
+
console.log('%c 🗿\n%cService workers are not supported.', 'font-size:50px;color:#bcbcbc;', 'background-color:#333;color:#fff;');
|
35
|
+
}
|
data/assets/js/sw.js
ADDED
@@ -0,0 +1,174 @@
|
|
1
|
+
---
|
2
|
+
layout: null
|
3
|
+
permalink: /sw.js
|
4
|
+
---
|
5
|
+
"use strict";
|
6
|
+
var CACHE_NAME = '{{ site.github.build_revision }}{{ site.time | date: '%Y%m%d%H%M%S' }}';
|
7
|
+
var urlsToCache = [
|
8
|
+
'/?utm_source=homescreen','/manifest.json',{% for post in site.posts limit:10 %}{% unless post.redirect_to %}'{{ post.url | prepend: site.baseurl }}',
|
9
|
+
{% endunless %}{% endfor %}{% for page in site.pages %}{% if page.layout %}'{{ page.url | prepend: site.baseurl }}',
|
10
|
+
{% endif %}{% endfor %}'/assets/css/main.css',
|
11
|
+
'/blog.json',
|
12
|
+
'/assets/images/avatar.jpg'
|
13
|
+
];
|
14
|
+
var idbDatabase;
|
15
|
+
var IDB_VERSION = {{ site.time | date: '%Y%m%d' }};
|
16
|
+
var STOP_RETRYING_AFTER = 86400000; // One day, in milliseconds.
|
17
|
+
var STORE_NAME = 'urls';
|
18
|
+
|
19
|
+
// This is basic boilerplate for interacting with IndexedDB. Adapted from
|
20
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API/Using_IndexedDB
|
21
|
+
function openDatabaseAndReplayRequests() {
|
22
|
+
var indexedDBOpenRequest = indexedDB.open('offline-analytics', IDB_VERSION);
|
23
|
+
|
24
|
+
// This top-level error handler will be invoked any time there's an IndexedDB-related error.
|
25
|
+
indexedDBOpenRequest.onerror = function(error) {
|
26
|
+
console.error('IndexedDB error:', error);
|
27
|
+
};
|
28
|
+
|
29
|
+
// This should only execute if there's a need to create a new database for the given IDB_VERSION.
|
30
|
+
indexedDBOpenRequest.onupgradeneeded = function() {
|
31
|
+
this.result.createObjectStore(STORE_NAME, {keyPath: 'url'});
|
32
|
+
};
|
33
|
+
|
34
|
+
// This will execute each time the database is opened.
|
35
|
+
indexedDBOpenRequest.onsuccess = function() {
|
36
|
+
idbDatabase = this.result;
|
37
|
+
replayAnalyticsRequests();
|
38
|
+
};
|
39
|
+
}
|
40
|
+
|
41
|
+
// Helper method to get the object store that we care about.
|
42
|
+
function getObjectStore(storeName, mode) {
|
43
|
+
return idbDatabase.transaction(storeName, mode).objectStore(storeName);
|
44
|
+
}
|
45
|
+
|
46
|
+
function replayAnalyticsRequests() {
|
47
|
+
var savedRequests = [];
|
48
|
+
|
49
|
+
getObjectStore(STORE_NAME).openCursor().onsuccess = function(event) {
|
50
|
+
// See https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API/Using_IndexedDB#Using_a_cursor
|
51
|
+
var cursor = event.target.result;
|
52
|
+
|
53
|
+
if (cursor) {
|
54
|
+
// Keep moving the cursor forward and collecting saved requests.
|
55
|
+
savedRequests.push(cursor.value);
|
56
|
+
cursor.continue();
|
57
|
+
} else {
|
58
|
+
// At this point, we have all the saved requests.
|
59
|
+
//console.log('About to replay %d saved Google Analytics requests...',
|
60
|
+
// savedRequests.length);
|
61
|
+
|
62
|
+
savedRequests.forEach(function(savedRequest) {
|
63
|
+
var queueTime = Date.now() - savedRequest.timestamp;
|
64
|
+
if (queueTime > STOP_RETRYING_AFTER) {
|
65
|
+
getObjectStore(STORE_NAME, 'readwrite').delete(savedRequest.url);
|
66
|
+
//console.log(' Request has been queued for %d milliseconds. ' +
|
67
|
+
//'No longer attempting to replay.', queueTime);
|
68
|
+
} else {
|
69
|
+
// The qt= URL parameter specifies the time delta in between right now, and when the
|
70
|
+
// /collect request was initially intended to be sent. See
|
71
|
+
// https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters#qt
|
72
|
+
var requestUrl = savedRequest.url + '&qt=' + queueTime;
|
73
|
+
|
74
|
+
//console.log(' Replaying', requestUrl);
|
75
|
+
|
76
|
+
fetch(requestUrl).then(function(response) {
|
77
|
+
if (response.status < 400) {
|
78
|
+
// If sending the /collect request was successful, then remove it from the IndexedDB.
|
79
|
+
getObjectStore(STORE_NAME, 'readwrite').delete(savedRequest.url);
|
80
|
+
//console.log(' Replaying succeeded.');
|
81
|
+
} else {
|
82
|
+
// This will be triggered if, e.g., Google Analytics returns a HTTP 50x response.
|
83
|
+
// The request will be replayed the next time the service worker starts up.
|
84
|
+
//console.error(' Replaying failed:', response);
|
85
|
+
}
|
86
|
+
}).catch(function(error) {
|
87
|
+
// This will be triggered if the network is still down. The request will be replayed again
|
88
|
+
// the next time the service worker starts up.
|
89
|
+
//console.error(' Replaying failed:', error);
|
90
|
+
});
|
91
|
+
}
|
92
|
+
});
|
93
|
+
}
|
94
|
+
};
|
95
|
+
}
|
96
|
+
|
97
|
+
// Open the IndexedDB and check for requests to replay each time the service worker starts up.
|
98
|
+
// Since the service worker is terminated fairly frequently, it should start up again for most
|
99
|
+
// page navigations. It also might start up if it's used in a background sync or a push
|
100
|
+
// notification context.
|
101
|
+
openDatabaseAndReplayRequests();
|
102
|
+
|
103
|
+
self.addEventListener('install', event => {
|
104
|
+
event.waitUntil(caches.open(CACHE_NAME)
|
105
|
+
.then(cache => cache.addAll(urlsToCache)).then(() => {
|
106
|
+
return self.skipWaiting();
|
107
|
+
})
|
108
|
+
);
|
109
|
+
});
|
110
|
+
|
111
|
+
self.addEventListener('fetch',event => {
|
112
|
+
event.respondWith(
|
113
|
+
caches.match(event.request)
|
114
|
+
.then(response => {
|
115
|
+
if (response) return response;
|
116
|
+
|
117
|
+
var fetchRequest = event.request.clone();
|
118
|
+
return fetch(fetchRequest).then(response => {
|
119
|
+
if (!response || response.status != 200 || response.type !== 'basic'){
|
120
|
+
if (response.status >= 500) {
|
121
|
+
// If this is a Google Analytics ping then we want to retry it if a HTTP 5xx response
|
122
|
+
// was returned, just like we'd retry it if the network was down.
|
123
|
+
checkForAnalyticsRequest(event.request.url);
|
124
|
+
}
|
125
|
+
return response;
|
126
|
+
}
|
127
|
+
|
128
|
+
var responseToCache = response.clone();
|
129
|
+
caches.open(CACHE_NAME).then(cache => {
|
130
|
+
cache.put(event.request, responseToCache);
|
131
|
+
});
|
132
|
+
return response;
|
133
|
+
}).catch(() => {
|
134
|
+
// The catch() will be triggered for network failures. Let's see if it was a request for
|
135
|
+
// a Google Analytics ping, and save it to be retried if it was.
|
136
|
+
checkForAnalyticsRequest(event.request.url);
|
137
|
+
return caches.match('/offline.html');
|
138
|
+
})
|
139
|
+
}));
|
140
|
+
});
|
141
|
+
|
142
|
+
self.addEventListener('activate',event => {
|
143
|
+
var chacheWhiteList=[CACHE_NAME];
|
144
|
+
event.waitUntil(
|
145
|
+
caches.keys().then(keyList => {
|
146
|
+
return Promise.all(keyList.map(key => {
|
147
|
+
if (chacheWhiteList.indexOf(key) === -1)
|
148
|
+
return caches.delete(key);
|
149
|
+
}));
|
150
|
+
}).then(() => {
|
151
|
+
return self.clients.claim();
|
152
|
+
})
|
153
|
+
);
|
154
|
+
});
|
155
|
+
|
156
|
+
function checkForAnalyticsRequest(requestUrl) {
|
157
|
+
// Construct a URL object (https://developer.mozilla.org/en-US/docs/Web/API/URL.URL)
|
158
|
+
// to make it easier to check the various components without dealing with string parsing.
|
159
|
+
var url = new URL(requestUrl);
|
160
|
+
|
161
|
+
if ((url.hostname === 'www.google-analytics.com' ||
|
162
|
+
url.hostname === 'ssl.google-analytics.com') &&
|
163
|
+
url.pathname === '/collect') {
|
164
|
+
//console.log(' Storing Google Analytics request in IndexedDB to be replayed later.');
|
165
|
+
saveAnalyticsRequest(requestUrl);
|
166
|
+
}
|
167
|
+
}
|
168
|
+
|
169
|
+
function saveAnalyticsRequest(requestUrl) {
|
170
|
+
getObjectStore(STORE_NAME, 'readwrite').add({
|
171
|
+
url: requestUrl,
|
172
|
+
timestamp: Date.now()
|
173
|
+
});
|
174
|
+
}
|
@@ -0,0 +1,70 @@
|
|
1
|
+
---
|
2
|
+
layout: null
|
3
|
+
permalink: /manifest.json
|
4
|
+
---
|
5
|
+
{
|
6
|
+
"lang": "id",
|
7
|
+
"dir": "ltr",
|
8
|
+
"name": "{{ site.title }}",
|
9
|
+
"short_name": "{{ site.shortname | default : site.title}}",
|
10
|
+
"description": "{{ site.description | strip_newlines }}",
|
11
|
+
"background_color": "#03a9f4",
|
12
|
+
"theme_color": "#3da3f7",
|
13
|
+
"gcm_sender_id": "482941778795",
|
14
|
+
"display": "standalone",
|
15
|
+
"orientation": "portrait",
|
16
|
+
"start_url": "/?utm_source=homescreen",
|
17
|
+
"scope": "/",
|
18
|
+
"icons": [
|
19
|
+
{
|
20
|
+
"src": "/assets/icons/36.png",
|
21
|
+
"sizes": "36x36",
|
22
|
+
"type": "image\/png",
|
23
|
+
"density": "0.75"
|
24
|
+
},
|
25
|
+
{
|
26
|
+
"src": "/assets/icons/48.png",
|
27
|
+
"sizes": "48x48",
|
28
|
+
"type": "image\/png",
|
29
|
+
"density": "1.0"
|
30
|
+
},
|
31
|
+
{
|
32
|
+
"src": "/assets/icons/72.png",
|
33
|
+
"sizes": "72x72",
|
34
|
+
"type": "image\/png",
|
35
|
+
"density": "1.5"
|
36
|
+
},
|
37
|
+
{
|
38
|
+
"src": "/assets/icons/96.png",
|
39
|
+
"sizes": "96x96",
|
40
|
+
"type": "image\/png",
|
41
|
+
"density": "2.0"
|
42
|
+
},
|
43
|
+
{
|
44
|
+
"src": "/assets/icons/144.png",
|
45
|
+
"sizes": "144x144",
|
46
|
+
"type": "image\/png",
|
47
|
+
"density": "3.0"
|
48
|
+
},
|
49
|
+
{
|
50
|
+
"src": "/assets/icons/192.png",
|
51
|
+
"sizes": "192x192",
|
52
|
+
"type": "image\/png",
|
53
|
+
"density": "4.0"
|
54
|
+
},
|
55
|
+
{
|
56
|
+
"src": "/assets/icons/256.png",
|
57
|
+
"sizes": "256x256",
|
58
|
+
"type": "image\/png"
|
59
|
+
},
|
60
|
+
{
|
61
|
+
"src": "/assets/icons/512.png",
|
62
|
+
"sizes": "512x512",
|
63
|
+
"type": "image\/png"
|
64
|
+
},
|
65
|
+
{
|
66
|
+
"src": "/assets/icons/icon.svg",
|
67
|
+
"sizes": "any"
|
68
|
+
}
|
69
|
+
]
|
70
|
+
}
|
@@ -0,0 +1,13 @@
|
|
1
|
+
---
|
2
|
+
layout: null
|
3
|
+
permalink: /opensearch.xml
|
4
|
+
---
|
5
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
6
|
+
<OpenSearchDescription xmlns:moz="http://www.mozilla.org/2006/browser/search/"
|
7
|
+
xmlns="http://a9.com/-/spec/opensearch/1.1/">
|
8
|
+
<ShortName>{{ site.shortname }}</ShortName>
|
9
|
+
<Description>Search {{ site.shortname }}</Description>
|
10
|
+
<InputEncoding>UTF-8</InputEncoding>
|
11
|
+
<Url method="get" type="text/html"
|
12
|
+
template="{{'/search' | absolute_url }}?q={searchTerms}"/>
|
13
|
+
</OpenSearchDescription>
|
data/assets/robots.txt
ADDED
data/assets/search.html
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
---
|
2
|
+
layout: default
|
3
|
+
permalink: /search
|
4
|
+
---
|
5
|
+
<script>
|
6
|
+
(function () {
|
7
|
+
var cx = '{{site.cse_id}}';
|
8
|
+
var gcse = document.createElement('script');
|
9
|
+
gcse.type = 'text/javascript';
|
10
|
+
gcse.async = true;
|
11
|
+
gcse.src = 'https://cse.google.com/cse.js?cx=' + cx;
|
12
|
+
var s = document.getElementsByTagName('script')[0];
|
13
|
+
s.parentNode.insertBefore(gcse, s);
|
14
|
+
})();
|
15
|
+
</script>
|
16
|
+
<gcse:searchresults-only></gcse:searchresults-only>
|