@bendyline/gilde 0.1.86 → 0.1.88
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/data/craftbook-templates/index.json +1 -1
- package/data/craftbook-templates/raw-index.json +1 -1
- package/data/craftbook-templates/ta/tailor-resume/versions/1.0.5/craftbook.json +226 -0
- package/data/craftbook-templates/ta/tailor-resume/versions/1.0.5/test.json +79 -0
- package/data/knowledge-catalogs/ca/caselaw-alaska-part-0001/manifest.json +24 -0
- package/data/knowledge-catalogs/ca/caselaw-alaska-part-0001/versions/2026.10.1/manifest.json +658 -0
- package/data/knowledge-catalogs/ca/caselaw-nevada-part-0001/manifest.json +24 -0
- package/data/knowledge-catalogs/ca/caselaw-nevada-part-0001/versions/2026.10.1/manifest.json +666 -0
- package/data/knowledge-catalogs/ca/caselaw-wyoming-part-0001/manifest.json +24 -0
- package/data/knowledge-catalogs/ca/caselaw-wyoming-part-0001/versions/2026.10.3/manifest.json +626 -0
- package/data/knowledge-catalogs/index.json +1 -1
- package/data/knowledge-catalogs/raw-index.json +1 -1
- package/data/project-types/ch/checkers/versions/1.2.1/about.md +9 -0
- package/data/project-types/ch/checkers/versions/1.2.1/game.json +77 -0
- package/data/project-types/ch/checkers/versions/1.2.1/manifest.json +168 -0
- package/data/project-types/ch/checkers/versions/1.2.1/mission.md +9 -0
- package/data/project-types/ch/checkers/versions/1.2.1/pages/board/index.html +1158 -0
- package/data/project-types/ch/chess/versions/1.0.4/about.md +9 -0
- package/data/project-types/ch/chess/versions/1.0.4/game.json +127 -0
- package/data/project-types/ch/chess/versions/1.0.4/manifest.json +182 -0
- package/data/project-types/ch/chess/versions/1.0.4/mission.md +8 -0
- package/data/project-types/ch/chess/versions/1.0.4/pages/board/index.html +851 -0
- package/data/project-types/de/design-scheme/versions/1.0.2/about.md +6 -0
- package/data/project-types/de/design-scheme/versions/1.0.2/manifest.json +70 -0
- package/data/project-types/de/design-scheme/versions/1.0.2/mission.md +3 -0
- package/data/project-types/de/design-scheme/versions/1.0.2/pages/gallery/index.html +212 -0
- package/data/project-types/de/design-scheme/versions/1.0.2/schemes/index.json +9 -0
- package/data/project-types/de/design-scheme/versions/1.0.2/schemes/warm-dusk.json +4 -0
- package/data/project-types/ev/event-planner/versions/1.0.2/about.md +7 -0
- package/data/project-types/ev/event-planner/versions/1.0.2/budget.json +5 -0
- package/data/project-types/ev/event-planner/versions/1.0.2/guests.json +10 -0
- package/data/project-types/ev/event-planner/versions/1.0.2/manifest.json +171 -0
- package/data/project-types/ev/event-planner/versions/1.0.2/mission.md +6 -0
- package/data/project-types/ev/event-planner/versions/1.0.2/pages/dashboard/index.html +283 -0
- package/data/project-types/fi/fitness-coach/versions/1.0.2/about.md +7 -0
- package/data/project-types/fi/fitness-coach/versions/1.0.2/manifest.json +126 -0
- package/data/project-types/fi/fitness-coach/versions/1.0.2/mission.md +7 -0
- package/data/project-types/fi/fitness-coach/versions/1.0.2/pages/dashboard/index.html +273 -0
- package/data/project-types/fi/fitness-coach/versions/1.0.2/training.json +6 -0
- package/data/project-types/fl/flashcards/versions/1.1.1/about.md +8 -0
- package/data/project-types/fl/flashcards/versions/1.1.1/deck.json +7 -0
- package/data/project-types/fl/flashcards/versions/1.1.1/manifest.json +168 -0
- package/data/project-types/fl/flashcards/versions/1.1.1/mission.md +6 -0
- package/data/project-types/fl/flashcards/versions/1.1.1/pages/review/index.html +477 -0
- package/data/project-types/fr/freelance-office/versions/1.0.2/about.md +6 -0
- package/data/project-types/fr/freelance-office/versions/1.0.2/invoices.json +9 -0
- package/data/project-types/fr/freelance-office/versions/1.0.2/manifest.json +143 -0
- package/data/project-types/fr/freelance-office/versions/1.0.2/mission.md +6 -0
- package/data/project-types/fr/freelance-office/versions/1.0.2/pages/dashboard/index.html +258 -0
- package/data/project-types/fu/fundraiser-hq/versions/1.0.2/about.md +7 -0
- package/data/project-types/fu/fundraiser-hq/versions/1.0.2/donations.json +7 -0
- package/data/project-types/fu/fundraiser-hq/versions/1.0.2/manifest.json +127 -0
- package/data/project-types/fu/fundraiser-hq/versions/1.0.2/mission.md +6 -0
- package/data/project-types/fu/fundraiser-hq/versions/1.0.2/pages/dashboard/index.html +261 -0
- package/data/project-types/go/go/versions/1.0.2/about.md +9 -0
- package/data/project-types/go/go/versions/1.0.2/game.json +103 -0
- package/data/project-types/go/go/versions/1.0.2/manifest.json +168 -0
- package/data/project-types/go/go/versions/1.0.2/mission.md +8 -0
- package/data/project-types/go/go/versions/1.0.2/pages/board/index.html +855 -0
- package/data/project-types/ho/household-budget/versions/1.0.3/about.md +6 -0
- package/data/project-types/ho/household-budget/versions/1.0.3/ledger.json +5 -0
- package/data/project-types/ho/household-budget/versions/1.0.3/manifest.json +164 -0
- package/data/project-types/ho/household-budget/versions/1.0.3/mission.md +5 -0
- package/data/project-types/ho/household-budget/versions/1.0.3/pages/dashboard/index.html +340 -0
- package/data/project-types/ho/household-manual/versions/1.0.2/about.md +7 -0
- package/data/project-types/ho/household-manual/versions/1.0.2/manifest.json +153 -0
- package/data/project-types/ho/household-manual/versions/1.0.2/mission.md +8 -0
- package/data/project-types/ho/household-manual/versions/1.0.2/pages/dashboard/index.html +258 -0
- package/data/project-types/ho/household-manual/versions/1.0.2/systems.json +8 -0
- package/data/project-types/index.json +1 -1
- package/data/project-types/jo/job-hunt/versions/1.0.2/about.md +10 -0
- package/data/project-types/jo/job-hunt/versions/1.0.2/activity.json +4 -0
- package/data/project-types/jo/job-hunt/versions/1.0.2/manifest.json +213 -0
- package/data/project-types/jo/job-hunt/versions/1.0.2/mission.md +9 -0
- package/data/project-types/jo/job-hunt/versions/1.0.2/pages/dashboard/index.html +430 -0
- package/data/project-types/jo/job-hunt/versions/1.0.2/pipeline.json +6 -0
- package/data/project-types/la/language-trainer/versions/1.0.2/about.md +6 -0
- package/data/project-types/la/language-trainer/versions/1.0.2/manifest.json +80 -0
- package/data/project-types/la/language-trainer/versions/1.0.2/mission.md +4 -0
- package/data/project-types/la/language-trainer/versions/1.0.2/pages/dashboard/index.html +268 -0
- package/data/project-types/la/language-trainer/versions/1.0.2/progress.json +7 -0
- package/data/project-types/li/life-binder/versions/1.0.3/about.md +7 -0
- package/data/project-types/li/life-binder/versions/1.0.3/documents.json +145 -0
- package/data/project-types/li/life-binder/versions/1.0.3/manifest.json +138 -0
- package/data/project-types/li/life-binder/versions/1.0.3/mission.md +6 -0
- package/data/project-types/li/life-binder/versions/1.0.3/pages/dashboard/index.html +248 -0
- package/data/project-types/me/meal-planner/versions/1.0.2/about.md +6 -0
- package/data/project-types/me/meal-planner/versions/1.0.2/manifest.json +160 -0
- package/data/project-types/me/meal-planner/versions/1.0.2/menu.json +5 -0
- package/data/project-types/me/meal-planner/versions/1.0.2/mission.md +5 -0
- package/data/project-types/me/meal-planner/versions/1.0.2/pages/dashboard/index.html +248 -0
- package/data/project-types/me/meal-planner/versions/1.0.2/pantry.json +9 -0
- package/data/project-types/no/novel-writing-room/versions/1.0.2/about.md +7 -0
- package/data/project-types/no/novel-writing-room/versions/1.0.2/chapters.json +10 -0
- package/data/project-types/no/novel-writing-room/versions/1.0.2/manifest.json +158 -0
- package/data/project-types/no/novel-writing-room/versions/1.0.2/mission.md +7 -0
- package/data/project-types/no/novel-writing-room/versions/1.0.2/pages/dashboard/index.html +264 -0
- package/data/project-types/no/novel-writing-room/versions/1.0.2/sessions.json +6 -0
- package/data/project-types/raw-index.json +1 -1
- package/data/project-types/tr/trip-planner/versions/1.0.2/about.md +7 -0
- package/data/project-types/tr/trip-planner/versions/1.0.2/journal.json +4 -0
- package/data/project-types/tr/trip-planner/versions/1.0.2/manifest.json +194 -0
- package/data/project-types/tr/trip-planner/versions/1.0.2/mission.md +4 -0
- package/data/project-types/tr/trip-planner/versions/1.0.2/packing.json +8 -0
- package/data/project-types/tr/trip-planner/versions/1.0.2/pages/dashboard/index.html +308 -0
- package/data/project-types/tr/trip-planner/versions/1.0.2/trip.json +7 -0
- package/package.json +1 -1
- package/schemas/project-type-version.schema.json +13 -0
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
|
+
<meta name="gezel-demo" content="standalone" />
|
|
7
|
+
<title>Novel Writing Room</title>
|
|
8
|
+
<style>
|
|
9
|
+
:root {
|
|
10
|
+
color-scheme: light dark;
|
|
11
|
+
--bg: #faf7f2; --card: #fff; --ink: #2b2620; --muted: #7a7166;
|
|
12
|
+
--accent: #b5651d; --track: #ece5da; --good: #4a7c59;
|
|
13
|
+
}
|
|
14
|
+
:root[data-theme='dark'] {
|
|
15
|
+
--bg: #1c1a17; --card: #262320; --ink: #efe9e0; --muted: #a59a8c;
|
|
16
|
+
--accent: #e0894a; --track: #3a352f; --good: #7fae8d;
|
|
17
|
+
}
|
|
18
|
+
@media (prefers-color-scheme: dark) {
|
|
19
|
+
:root:not([data-theme='light']) {
|
|
20
|
+
--bg: #1c1a17; --card: #262320; --ink: #efe9e0; --muted: #a59a8c;
|
|
21
|
+
--accent: #e0894a; --track: #3a352f; --good: #7fae8d;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
* { box-sizing: border-box; }
|
|
25
|
+
body { margin: 0; font: 15px/1.5 system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif; background: var(--bg); color: var(--ink); padding: 1.5rem 1.25rem; }
|
|
26
|
+
main { max-width: 680px; margin: 0 auto; }
|
|
27
|
+
h1 { font-family: Georgia, 'PT Serif', 'Times New Roman', serif; font-size: 1.35rem; font-weight: 600; margin: 0 0 0.15rem; }
|
|
28
|
+
.sub { color: var(--muted); font-size: 0.9rem; margin: 0 0 0.9rem; }
|
|
29
|
+
.pace { background: var(--card); border: 1px solid var(--track); border-radius: 10px; padding: 1rem; margin-bottom: 0.75rem; }
|
|
30
|
+
.pace .total { font-size: 1.9rem; font-weight: 700; font-variant-numeric: tabular-nums; }
|
|
31
|
+
.pace .goal { color: var(--muted); font-size: 0.9rem; }
|
|
32
|
+
.bar { background: var(--track); border-radius: 4px; height: 12px; overflow: hidden; margin-top: 0.6rem; }
|
|
33
|
+
.bar > span { display: block; height: 100%; background: var(--good); border-radius: 4px; transition: width 0.4s ease; }
|
|
34
|
+
.board { display: grid; grid-template-columns: repeat(4, 1fr); gap: 0.6rem; }
|
|
35
|
+
.col { background: var(--card); border: 1px solid var(--track); border-radius: 10px; padding: 0.7rem 0.8rem; min-height: 5.5rem; }
|
|
36
|
+
.col h2 { font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--muted); margin: 0 0 0.45rem; }
|
|
37
|
+
.col h2 .count { color: var(--ink); }
|
|
38
|
+
.card { border: 1px solid var(--track); border-radius: 6px; padding: 0.35rem 0.5rem; margin: 0.3rem 0; font-size: 0.85rem; }
|
|
39
|
+
.card .id { color: var(--muted); font-size: 0.72rem; font-variant-numeric: tabular-nums; }
|
|
40
|
+
.empty { color: var(--muted); font-style: italic; font-size: 0.85rem; }
|
|
41
|
+
@media (max-width: 640px) { .board { grid-template-columns: 1fr 1fr; } }
|
|
42
|
+
.demo-banner {
|
|
43
|
+
display: flex;
|
|
44
|
+
align-items: center;
|
|
45
|
+
justify-content: space-between;
|
|
46
|
+
gap: 0.75rem;
|
|
47
|
+
margin: 0 0 0.85rem;
|
|
48
|
+
padding: 0.5rem 0.65rem;
|
|
49
|
+
border: 1px solid var(--accent);
|
|
50
|
+
border-radius: 6px;
|
|
51
|
+
background: color-mix(in srgb, var(--card) 88%, var(--accent));
|
|
52
|
+
color: var(--ink);
|
|
53
|
+
font-size: 0.8rem;
|
|
54
|
+
}
|
|
55
|
+
.demo-banner[hidden] { display: none; }
|
|
56
|
+
.demo-banner strong { font-weight: 700; }
|
|
57
|
+
.demo-reset {
|
|
58
|
+
flex: none;
|
|
59
|
+
padding: 0.25rem 0.5rem;
|
|
60
|
+
border: 1px solid var(--accent);
|
|
61
|
+
border-radius: 6px;
|
|
62
|
+
background: var(--card);
|
|
63
|
+
color: var(--ink);
|
|
64
|
+
cursor: pointer;
|
|
65
|
+
font: inherit;
|
|
66
|
+
}
|
|
67
|
+
.demo-reset:hover { border-color: var(--ink); }
|
|
68
|
+
</style>
|
|
69
|
+
</head>
|
|
70
|
+
<body>
|
|
71
|
+
<main>
|
|
72
|
+
<div class="demo-banner" data-gezel-demo-banner hidden>
|
|
73
|
+
<span><strong>Demo mode</strong> — sample data stays in this page.</span>
|
|
74
|
+
<button type="button" class="demo-reset" onclick="location.reload()">Reset demo</button>
|
|
75
|
+
</div>
|
|
76
|
+
<h1 id="title">Novel Writing Room</h1>
|
|
77
|
+
<p class="sub" id="sub">Loading the manuscript…</p>
|
|
78
|
+
<div class="pace">
|
|
79
|
+
<div class="total" id="total">—</div>
|
|
80
|
+
<div class="goal" id="goal">words logged</div>
|
|
81
|
+
<div class="bar"><span id="bar" style="width: 0%"></span></div>
|
|
82
|
+
</div>
|
|
83
|
+
<div class="board" id="board"></div>
|
|
84
|
+
</main>
|
|
85
|
+
<script>
|
|
86
|
+
/* gezel-page-demo-stub v1 */
|
|
87
|
+
/*
|
|
88
|
+
* The canonical demo stub for Gezel type pages. MIT License.
|
|
89
|
+
*
|
|
90
|
+
* Paste this file's bytes verbatim into a <script> block ahead of the
|
|
91
|
+
* page's own code, then call makeDemoGezel({ page, tools, data }) with the
|
|
92
|
+
* page's demo handlers. Served by Gezel, the real window.gezel is already
|
|
93
|
+
* injected and the stub steps aside; opened as a raw file (the live demos
|
|
94
|
+
* on gezelgilde.com), it installs a window.gezel whose tools and data are
|
|
95
|
+
* the page-supplied handler maps — one code path in every mode. `tools`
|
|
96
|
+
* and `data` map a tool name / declared read path to a function; data
|
|
97
|
+
* handlers back read() and list(), and url() returns the handler's value
|
|
98
|
+
* or passes a data: URI through. See docs/page-authoring.md.
|
|
99
|
+
*/
|
|
100
|
+
(function () {
|
|
101
|
+
'use strict';
|
|
102
|
+
window.makeDemoGezel = function (opts) {
|
|
103
|
+
if (window.gezel) return window.gezel;
|
|
104
|
+
var page = (opts && opts.page) || {};
|
|
105
|
+
var tools = (opts && opts.tools) || {};
|
|
106
|
+
var data = (opts && opts.data) || {};
|
|
107
|
+
var themeListeners = [];
|
|
108
|
+
var media = window.matchMedia ? window.matchMedia('(prefers-color-scheme: dark)') : null;
|
|
109
|
+
var ui = {
|
|
110
|
+
theme: { mode: media && media.matches ? 'dark' : 'light' },
|
|
111
|
+
onTheme: function (cb) {
|
|
112
|
+
themeListeners.push(cb);
|
|
113
|
+
return function () {
|
|
114
|
+
var at = themeListeners.indexOf(cb);
|
|
115
|
+
if (at >= 0) themeListeners.splice(at, 1);
|
|
116
|
+
};
|
|
117
|
+
},
|
|
118
|
+
};
|
|
119
|
+
if (media && media.addEventListener) {
|
|
120
|
+
media.addEventListener('change', function (ev) {
|
|
121
|
+
ui.theme = { mode: ev.matches ? 'dark' : 'light' };
|
|
122
|
+
themeListeners.slice().forEach(function (cb) { cb(ui.theme); });
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
function fail(code, message) {
|
|
126
|
+
var err = new Error(message);
|
|
127
|
+
err.code = code;
|
|
128
|
+
return Promise.reject(err);
|
|
129
|
+
}
|
|
130
|
+
function run(map, key, arg) {
|
|
131
|
+
if (!Object.prototype.hasOwnProperty.call(map, key)) return null;
|
|
132
|
+
return Promise.resolve().then(function () { return map[key](arg); });
|
|
133
|
+
}
|
|
134
|
+
window.gezel = {
|
|
135
|
+
page: {
|
|
136
|
+
api: 1,
|
|
137
|
+
projectId: 'demo',
|
|
138
|
+
source: 'type',
|
|
139
|
+
entry: page.entry || 'index.html',
|
|
140
|
+
typeName: page.typeName || 'demo',
|
|
141
|
+
params: page.params || {},
|
|
142
|
+
mode: 'demo',
|
|
143
|
+
},
|
|
144
|
+
tools: {
|
|
145
|
+
list: function () { return Promise.resolve(Object.keys(tools)); },
|
|
146
|
+
invoke: function (name, input) {
|
|
147
|
+
var call = run(tools, name, input || {});
|
|
148
|
+
if (!call) return fail('not-allowed', "The demo does not handle the tool '" + name + "'.");
|
|
149
|
+
return call.then(function (output) { return { output: output }; });
|
|
150
|
+
},
|
|
151
|
+
},
|
|
152
|
+
data: {
|
|
153
|
+
read: function (path, o) {
|
|
154
|
+
return run(data, path, o || {}) || fail('not-allowed', "The demo has no data for '" + path + "'.");
|
|
155
|
+
},
|
|
156
|
+
list: function (path, o) {
|
|
157
|
+
return run(data, path, o || {}) || Promise.resolve([]);
|
|
158
|
+
},
|
|
159
|
+
watch: function () { return function () {}; },
|
|
160
|
+
url: function (path) {
|
|
161
|
+
if (Object.prototype.hasOwnProperty.call(data, path)) return String(data[path]({}));
|
|
162
|
+
return typeof path === 'string' && path.indexOf('data:') === 0 ? path : '';
|
|
163
|
+
},
|
|
164
|
+
},
|
|
165
|
+
ui: ui,
|
|
166
|
+
refresh: function () {},
|
|
167
|
+
};
|
|
168
|
+
return window.gezel;
|
|
169
|
+
};
|
|
170
|
+
})();
|
|
171
|
+
</script>
|
|
172
|
+
<script>
|
|
173
|
+
(function () {
|
|
174
|
+
'use strict';
|
|
175
|
+
var STAGES = ['outline', 'drafting', 'revised', 'done'];
|
|
176
|
+
|
|
177
|
+
// ── demo manuscript (used only when the page opens as a raw file) ──
|
|
178
|
+
var demoSessions = {
|
|
179
|
+
title: 'The Glass Cartographer',
|
|
180
|
+
weeklyWordGoal: 5000,
|
|
181
|
+
events: [
|
|
182
|
+
{ at: new Date(Date.now() - 6 * 86400000).toISOString(), data: { words: 850 } },
|
|
183
|
+
{ at: new Date(Date.now() - 3 * 86400000).toISOString(), data: { words: 1200 } },
|
|
184
|
+
{ at: new Date().toISOString(), data: { words: 640 } },
|
|
185
|
+
],
|
|
186
|
+
};
|
|
187
|
+
var demoChapters = { records: [
|
|
188
|
+
{ id: 'ch-01', status: 'done', fields: { title: 'The map that changed overnight' } },
|
|
189
|
+
{ id: 'ch-02', status: 'revised', fields: { title: 'A city folded into glass' } },
|
|
190
|
+
{ id: 'ch-03', status: 'drafting', fields: { title: 'The ferryman’s bargain' } },
|
|
191
|
+
{ id: 'ch-04', status: 'outline', fields: { title: 'North of the last road' } },
|
|
192
|
+
{ id: 'ch-05', status: 'outline', fields: { title: 'The unfinished coast' } },
|
|
193
|
+
] };
|
|
194
|
+
|
|
195
|
+
makeDemoGezel({
|
|
196
|
+
page: { entry: 'dashboard/index.html', typeName: 'Novel Writing Room', params: { title: 'Untitled', weeklyWordGoal: 5000 } },
|
|
197
|
+
data: {
|
|
198
|
+
'sessions.json': function () { return demoSessions; },
|
|
199
|
+
'chapters.json': function () { return demoChapters; },
|
|
200
|
+
},
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
// ── one code path from here: window.gezel exists in every mode ──
|
|
204
|
+
var demoMode = gezel.page.mode === 'demo';
|
|
205
|
+
|
|
206
|
+
function applyTheme(mode) {
|
|
207
|
+
document.documentElement.setAttribute('data-theme', mode === 'dark' ? 'dark' : 'light');
|
|
208
|
+
}
|
|
209
|
+
applyTheme(gezel.ui.theme.mode);
|
|
210
|
+
gezel.ui.onTheme(function (theme) { applyTheme(theme.mode); });
|
|
211
|
+
|
|
212
|
+
if (demoMode) document.querySelector('[data-gezel-demo-banner]').hidden = false;
|
|
213
|
+
|
|
214
|
+
function esc(s) { return String(s).replace(/[&<>"]/g, function (c) { return { '&': '&', '<': '<', '>': '>', '"': '"' }[c]; }); }
|
|
215
|
+
function fmtNum(n) { return String(n).replace(/\B(?=(\d{3})+(?!\d))/g, ','); }
|
|
216
|
+
function weekStartMs(nowIso) {
|
|
217
|
+
var d = new Date(nowIso.slice(0, 10) + 'T00:00:00Z');
|
|
218
|
+
return d.getTime() - ((d.getUTCDay() + 6) % 7) * 86400000;
|
|
219
|
+
}
|
|
220
|
+
function wordsOf(e) {
|
|
221
|
+
var w = e && e.data ? Number(e.data.words) : NaN;
|
|
222
|
+
return isFinite(w) && w > 0 ? Math.round(w) : 0;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
function render(sessions, chapters) {
|
|
226
|
+
var events = Array.isArray(sessions.events) ? sessions.events : [];
|
|
227
|
+
var records = Array.isArray(chapters.records) ? chapters.records : [];
|
|
228
|
+
var goal = Number(sessions.weeklyWordGoal);
|
|
229
|
+
if (!isFinite(goal) || goal <= 0) goal = 0;
|
|
230
|
+
var total = 0;
|
|
231
|
+
events.forEach(function (e) { total += wordsOf(e); });
|
|
232
|
+
var start = weekStartMs(new Date().toISOString());
|
|
233
|
+
var week = 0;
|
|
234
|
+
events.forEach(function (e) { if (Date.parse(e.at) >= start) week += wordsOf(e); });
|
|
235
|
+
|
|
236
|
+
if (sessions.title) document.getElementById('title').textContent = sessions.title;
|
|
237
|
+
document.getElementById('sub').textContent = records.length + ' chapter(s) on the board, ' + events.length + ' session(s) logged';
|
|
238
|
+
document.getElementById('total').textContent = fmtNum(total);
|
|
239
|
+
document.getElementById('goal').textContent = 'words logged — ' + fmtNum(week) + (goal > 0 ? ' of ' + fmtNum(goal) : '') + ' this week';
|
|
240
|
+
document.getElementById('bar').style.width = (goal > 0 ? Math.min(100, Math.round((week / goal) * 100)) : week > 0 ? 100 : 0) + '%';
|
|
241
|
+
|
|
242
|
+
document.getElementById('board').innerHTML = STAGES.map(function (stage) {
|
|
243
|
+
var here = records.filter(function (r) { return r.status === stage; });
|
|
244
|
+
var cards = here.map(function (r) {
|
|
245
|
+
return '<div class="card"><span class="id">' + esc(r.id) + '</span> ' + esc(String((r.fields && r.fields.title) || '')) + '</div>';
|
|
246
|
+
}).join('');
|
|
247
|
+
return '<div class="col"><h2>' + stage + ' <span class="count">' + here.length + '</span></h2>' +
|
|
248
|
+
(cards || '<div class="empty">' + (stage === 'outline' ? 'Ask your Schrijfmaat to put chapters on the board.' : 'None yet.') + '</div>') + '</div>';
|
|
249
|
+
}).join('');
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
function loadRoom() {
|
|
253
|
+
return Promise.all([gezel.data.read('sessions.json'), gezel.data.read('chapters.json')])
|
|
254
|
+
.then(function (both) { render(both[0] || {}, both[1] || {}); })
|
|
255
|
+
.catch(function () {});
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
loadRoom();
|
|
259
|
+
gezel.data.watch('sessions.json', function () { loadRoom(); });
|
|
260
|
+
gezel.data.watch('chapters.json', function () { loadRoom(); });
|
|
261
|
+
})();
|
|
262
|
+
</script>
|
|
263
|
+
</body>
|
|
264
|
+
</html>
|