diff --git a/bibdle_logo.svg b/bibdle_logo.svg new file mode 100644 index 0000000..9a0dca1 --- /dev/null +++ b/bibdle_logo.svg @@ -0,0 +1,385 @@ + + diff --git a/src/app.html b/src/app.html index a282adb..ced680e 100644 --- a/src/app.html +++ b/src/app.html @@ -4,6 +4,7 @@ + %sveltekit.head%
diff --git a/src/lib/assets/bibdle-logo-square.png b/src/lib/assets/bibdle-logo-square.png new file mode 100644 index 0000000..3a4a6d0 Binary files /dev/null and b/src/lib/assets/bibdle-logo-square.png differ diff --git a/src/routes/global/+page.server.ts b/src/routes/global/+page.server.ts index 1100a7d..1416c57 100644 --- a/src/routes/global/+page.server.ts +++ b/src/routes/global/+page.server.ts @@ -285,11 +285,8 @@ export const load: PageServerLoad = async () => { if (!cohort || cohort.size < 3) continue; // skip tiny cohorts let retained = 0; for (const userId of cohort) { - for (let j = 1; j <= windowDays; j++) { - if (dateUsersMap.get(addDays(dateD, j))?.has(userId)) { - retained++; - break; - } + if (dateUsersMap.get(addDays(dateD, windowDays))?.has(userId)) { + retained++; } } series.push({ @@ -304,6 +301,32 @@ export const load: PageServerLoad = async () => { const retention7dSeries = retentionSeries(7, 30); const retention30dSeries = retentionSeries(30, 30); + // ── Weekly Active Users history (12 weeks) ──────────────────────────────── + + const wauWeeks: { weekStart: string; weekEnd: string; wau: number; changePct: number | null }[] = []; + + for (let w = 0; w < 12; w++) { + const weekEnd = estDateStr(w * 7); + const weekStart = estDateStr(w * 7 + 6); + const users = new Set+ EST reference date: {todayEst} +
+EST reference date: {todayEst}
-| Date | +New Players | +Return Rate | +7d Avg | ++ |
|---|---|---|---|---|
| {row.date} | +{row.cohort} | +{row.rate != null + ? `${row.rate}%` + : "—"} | +{row.rollingAvg != null + ? `${row.rollingAvg}%` + : "—"} | +
+
+ {#if row.rollingAvg != null}
+
+ {/if}
+
+ |
+
+ Not enough data yet. +
+ {/if} +| Date | -New Players | -Return Rate | -7d Avg | -- |
|---|---|---|---|---|
| {row.date} | -{row.cohort} | -{row.rate != null ? `${row.rate}%` : '—'} | -{row.rollingAvg != null ? `${row.rollingAvg}%` : '—'} | -
-
- {#if row.rollingAvg != null}
-
- {/if}
-
- |
-
Not enough data yet.
- {/if} -+ Unique players per 7-day window. Most recent week first. Avg + WAU: {avgWau} +
+| Week | +Active Users | +Wk/Wk Change | ++ |
|---|---|---|---|
| {row.weekStart} – {row.weekEnd} | +{row.wau} | ++ {row.changePct != null + ? signed(row.changePct, "%") + : "—"} + | +
+
+
+
+ |
+
| Date | -Completions | -- |
|---|---|---|
| {row.date} | -{row.count} | -
-
-
-
- |
-
| Date | +Completions | ++ |
|---|---|---|
| {row.date} | +{row.count} | +
+
+
+
+ |
+
No active streaks yet.
- {:else} -| Days | -Players | -- |
|---|---|---|
| {row.days} | -{row.count} | -
-
-
-
- |
-
+ No active streaks yet. +
+ {:else} +| Days | +Players | ++ |
|---|---|---|
| {row.days} | +{row.count} | +
+
+
+
+ |
+
% of each day's players who returned within the window. Cohorts with fewer than 3 players are excluded.
++ % of each day's players who played again exactly 7 or 30 days later (regardless of activity in between). Cohorts with fewer than 3 players are excluded. +
-Not enough data yet.
- {:else} -| Cohort Date | -n | -Ret. % | -- |
|---|---|---|---|
| {row.date} | -{row.cohortSize} | -{row.rate}% | -
-
-
-
- |
-
+ Not enough data yet. +
+ {:else} +| Cohort Date | +n | +Ret. % | ++ |
|---|---|---|---|
| {row.date} | +{row.cohortSize} | +{row.rate}% | +
+
+
+
+ |
+
Not enough data yet.
- {:else} -| Cohort Date | -n | -Ret. % | -- |
|---|---|---|---|
| {row.date} | -{row.cohortSize} | -{row.rate}% | -
-
-
-
- |
-
+ Not enough data yet. +
+ {:else} +| Cohort Date | +n | +Ret. % | ++ |
|---|---|---|---|
| {row.date} | +{row.cohortSize} | +{row.rate}% | +
+
+
+
+ |
+