jekyll-theme-zer0 1.19.1 → 1.21.0
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +404 -0
- data/README.md +27 -19
- data/_data/authors.yml +154 -5
- data/_data/backlog.yml +12 -5
- data/_data/content_statistics.yml +273 -297
- data/_data/features.yml +4 -25
- data/_data/navigation/README.md +24 -0
- data/_data/navigation/about.yml +2 -0
- data/_data/navigation/main.yml +2 -7
- data/_data/roadmap.yml +86 -12
- data/_data/roadmap_plan.yml +37 -0
- data/_data/routing.yml +73 -0
- data/_includes/components/author-avatar-url.html +28 -0
- data/_includes/components/author-bio.html +86 -0
- data/_includes/components/author-card.html +184 -121
- data/_includes/components/author-eeat.html +10 -4
- data/_includes/components/info-section.html +1 -1
- data/_includes/components/mermaid.html +0 -3
- data/_includes/components/post-card.html +19 -9
- data/_includes/content/giscus.html +3 -2
- data/_includes/core/footer-fabs.html +28 -0
- data/_includes/core/footer.html +7 -17
- data/_includes/core/head.html +2 -2
- data/_includes/navigation/breadcrumbs.html +20 -2
- data/_includes/navigation/local-graph.html +18 -2
- data/_includes/obsidian/full-graph.html +4 -6
- data/_layouts/article.html +44 -74
- data/_layouts/author.html +274 -0
- data/_layouts/authors.html +55 -0
- data/_layouts/news.html +3 -3
- data/_layouts/note.html +21 -6
- data/_layouts/notebook.html +21 -6
- data/_layouts/root.html +31 -17
- data/_layouts/section.html +3 -3
- data/_plugins/author_pages_generator.rb +121 -0
- data/_sass/components/_author.scss +219 -0
- data/_sass/components/_content-tables.scss +16 -1
- data/_sass/components/_notes-index.scss +102 -0
- data/_sass/components/_search-modal.scss +40 -0
- data/_sass/components/_ui-enhancements.scss +570 -0
- data/_sass/core/_docs-code-examples.scss +463 -0
- data/_sass/core/_docs-layout.scss +0 -453
- data/_sass/core/_navbar.scss +253 -0
- data/_sass/core/_sidebar-extras.scss +79 -0
- data/_sass/core/_toc.scss +87 -0
- data/_sass/core/_variables.scss +7 -142
- data/_sass/custom.scss +24 -1122
- data/_sass/layouts/_global-chrome.scss +59 -0
- data/assets/css/main.scss +19 -2
- data/assets/js/author-profile.js +190 -0
- data/assets/js/modules/navigation/navbar.js +104 -0
- data/assets/js/obsidian-graph.js +2 -2
- data/assets/js/obsidian-local-graph.js +11 -5
- data/assets/vendor/cytoscape/cytoscape.min.js +32 -0
- data/scripts/README.md +39 -0
- data/scripts/bin/validate +11 -1
- data/scripts/dev/css-diff.sh +49 -0
- data/scripts/dev/shot.js +37 -0
- data/scripts/features/generate-preview-images +110 -6
- data/scripts/features/pixelate-preview-images +126 -0
- data/scripts/features/pixelate_images.py +662 -0
- data/scripts/github-setup.sh +0 -0
- data/scripts/lib/preview_generator.py +47 -3
- data/scripts/pixelate-preview-images.sh +12 -0
- data/scripts/sync-backlog.rb +149 -26
- data/scripts/sync-plan.rb +164 -0
- data/scripts/sync-plan.sh +21 -0
- data/scripts/test/integration/auto-version +10 -8
- data/scripts/test/lib/run_tests.sh +2 -0
- data/scripts/test/lib/test_content_review.sh +205 -0
- data/scripts/test/lib/test_pixelate_images.sh +108 -0
- metadata +29 -20
- data/_data/hub.yml +0 -68
- data/_data/hub_index.yml +0 -203
- data/_data/navigation/hub.yml +0 -110
- data/assets/vendor/font-awesome/css/all.min.css +0 -9
- data/assets/vendor/font-awesome/webfonts/fa-brands-400.ttf +0 -0
- data/assets/vendor/font-awesome/webfonts/fa-brands-400.woff2 +0 -0
- data/assets/vendor/font-awesome/webfonts/fa-regular-400.ttf +0 -0
- data/assets/vendor/font-awesome/webfonts/fa-regular-400.woff2 +0 -0
- data/assets/vendor/font-awesome/webfonts/fa-solid-900.ttf +0 -0
- data/assets/vendor/font-awesome/webfonts/fa-solid-900.woff2 +0 -0
- data/assets/vendor/font-awesome/webfonts/fa-v4compatibility.ttf +0 -0
- data/assets/vendor/font-awesome/webfonts/fa-v4compatibility.woff2 +0 -0
- data/assets/vendor/jquery/jquery-3.7.1.min.js +0 -2
- data/scripts/lib/hub.rb +0 -208
- data/scripts/provision-org-sites.rb +0 -252
- data/scripts/provision-org-sites.sh +0 -23
- data/scripts/sync-hub-metadata.rb +0 -184
- data/scripts/sync-hub-metadata.sh +0 -22
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# Unit tests for the scripts/content-review.rb scoring engine (issue #166).
|
|
4
|
+
#
|
|
5
|
+
# content-review.rb is the deterministic (no-API) tier of the AI content
|
|
6
|
+
# reviewer. It had zero direct unit coverage — it only ran as a side effect of
|
|
7
|
+
# the ai-content-review workflow on PRs touching pages/**. A scoring regression
|
|
8
|
+
# (code-fence false-positive) shipped in v1.18 and was fixed in v1.18.1 (PR
|
|
9
|
+
# #155), which is exactly the class of bug a unit test catches.
|
|
10
|
+
#
|
|
11
|
+
# These tests drive the real production config + schema
|
|
12
|
+
# (.github/config/content_review.yml, frontmatter_schema.yml) against synthetic
|
|
13
|
+
# Markdown fixtures, so they exercise the actual thresholds rather than a copy
|
|
14
|
+
# that can drift. Fixtures live under a temp `pages/_docs/**` tree so the
|
|
15
|
+
# production scope/path-pattern globs match without polluting the content dirs.
|
|
16
|
+
#
|
|
17
|
+
# Run under LC_ALL=C LANG=C for locale-independence parity with the T-015 guard.
|
|
18
|
+
|
|
19
|
+
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)"
|
|
20
|
+
CR_SCRIPT="$REPO_ROOT/scripts/content-review.rb"
|
|
21
|
+
CR_CONFIG="$REPO_ROOT/.github/config/content_review.yml"
|
|
22
|
+
CR_SCHEMA="$REPO_ROOT/.github/config/frontmatter_schema.yml"
|
|
23
|
+
|
|
24
|
+
echo "Testing content-review.rb scoring engine..."
|
|
25
|
+
|
|
26
|
+
# --- Fixture workspace -------------------------------------------------------
|
|
27
|
+
CR_WORK="$(mktemp -d)"
|
|
28
|
+
mkdir -p "$CR_WORK/pages/_docs/test"
|
|
29
|
+
|
|
30
|
+
# A well-formed docs page: complete front matter, in-range title/description,
|
|
31
|
+
# a keyword list, an H2, a language-tagged code fence, and an image with alt
|
|
32
|
+
# text. Should score high (no errors; at most cosmetic info items).
|
|
33
|
+
cat > "$CR_WORK/pages/_docs/test/good.md" <<'EOF'
|
|
34
|
+
---
|
|
35
|
+
title: Getting Started with the Zer0 Mistakes Theme
|
|
36
|
+
description: A friendly, complete walkthrough that takes you from an empty repository all the way to a deployed Zer0 Mistakes site in roughly ten short minutes.
|
|
37
|
+
lastmod: 2026-06-23T00:00:00.000Z
|
|
38
|
+
layout: default
|
|
39
|
+
categories:
|
|
40
|
+
- docs
|
|
41
|
+
tags:
|
|
42
|
+
- jekyll
|
|
43
|
+
- setup
|
|
44
|
+
keywords:
|
|
45
|
+
- jekyll
|
|
46
|
+
- theme
|
|
47
|
+
- setup
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Overview
|
|
51
|
+
|
|
52
|
+
This guide walks you through installing the theme, configuring your site, and
|
|
53
|
+
publishing it to GitHub Pages. Each step is short and copy-pasteable so you can
|
|
54
|
+
get a working site quickly without guessing at the details. We cover the local
|
|
55
|
+
development loop first, then the production deployment, and finally a few
|
|
56
|
+
verification checks so you know everything is wired up correctly before you
|
|
57
|
+
share the link with anyone else who might be reviewing your brand new site.
|
|
58
|
+
|
|
59
|
+
## Install
|
|
60
|
+
|
|
61
|
+
Run the bundled installer and start the development server with these commands:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
bundle install
|
|
65
|
+
bundle exec jekyll serve
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+

|
|
69
|
+
EOF
|
|
70
|
+
|
|
71
|
+
# Same page with the required `description` removed: one frontmatter error
|
|
72
|
+
# (required field) plus one SEO warning (no meta description). Must score
|
|
73
|
+
# strictly lower than the well-formed page.
|
|
74
|
+
cat > "$CR_WORK/pages/_docs/test/missing-desc.md" <<'EOF'
|
|
75
|
+
---
|
|
76
|
+
title: Getting Started with the Zer0 Mistakes Theme
|
|
77
|
+
lastmod: 2026-06-23T00:00:00.000Z
|
|
78
|
+
layout: default
|
|
79
|
+
categories:
|
|
80
|
+
- docs
|
|
81
|
+
tags:
|
|
82
|
+
- jekyll
|
|
83
|
+
- setup
|
|
84
|
+
keywords:
|
|
85
|
+
- jekyll
|
|
86
|
+
- theme
|
|
87
|
+
- setup
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## Overview
|
|
91
|
+
|
|
92
|
+
This guide walks you through installing the theme, configuring your site, and
|
|
93
|
+
publishing it to GitHub Pages. Each step is short and copy-pasteable so you can
|
|
94
|
+
get a working site quickly without guessing at the details. We cover the local
|
|
95
|
+
development loop first, then the production deployment, and finally a few
|
|
96
|
+
verification checks so you know everything is wired up correctly before you
|
|
97
|
+
share the link with anyone else.
|
|
98
|
+
EOF
|
|
99
|
+
|
|
100
|
+
# A page whose only code fence is properly language-tagged. The closing bare
|
|
101
|
+
# ``` must NOT be flagged as a fence without a language (the v1.18.1 regression).
|
|
102
|
+
cat > "$CR_WORK/pages/_docs/test/codefence.md" <<'EOF'
|
|
103
|
+
---
|
|
104
|
+
title: Configuring the Zer0 Mistakes Theme Options
|
|
105
|
+
description: A focused reference covering the handful of configuration options you will set most often when tailoring the Zer0 Mistakes theme to your own project.
|
|
106
|
+
lastmod: 2026-06-23T00:00:00.000Z
|
|
107
|
+
layout: default
|
|
108
|
+
categories:
|
|
109
|
+
- docs
|
|
110
|
+
tags:
|
|
111
|
+
- jekyll
|
|
112
|
+
- config
|
|
113
|
+
keywords:
|
|
114
|
+
- jekyll
|
|
115
|
+
- config
|
|
116
|
+
- options
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## Configuration
|
|
120
|
+
|
|
121
|
+
Set the options you need in your config file, then restart the server so the
|
|
122
|
+
changes take effect. The example below shows the most common starting point for
|
|
123
|
+
a new site and is safe to copy verbatim into your own configuration before you
|
|
124
|
+
begin customizing anything else about the project.
|
|
125
|
+
|
|
126
|
+
```yaml
|
|
127
|
+
title: My Site
|
|
128
|
+
description: A site built with the theme
|
|
129
|
+
```
|
|
130
|
+
EOF
|
|
131
|
+
|
|
132
|
+
# A clearly failing page: missing description, layout, categories, and tags
|
|
133
|
+
# (four required-field errors) — well below the fail threshold.
|
|
134
|
+
cat > "$CR_WORK/pages/_docs/test/failing.md" <<'EOF'
|
|
135
|
+
---
|
|
136
|
+
title: Bad
|
|
137
|
+
lastmod: 2026-06-23T00:00:00.000Z
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
Too short.
|
|
141
|
+
EOF
|
|
142
|
+
|
|
143
|
+
# --- Helpers -----------------------------------------------------------------
|
|
144
|
+
# Run the reviewer against one fixture (path relative to CR_WORK), writing JSON.
|
|
145
|
+
# Echoes nothing; returns the script's exit code.
|
|
146
|
+
cr_run() { # $1 = relative md path, $2 = json out path, $3..= extra args
|
|
147
|
+
local rel="$1" out="$2"; shift 2
|
|
148
|
+
( cd "$CR_WORK" && LC_ALL=C LANG=C ruby "$CR_SCRIPT" \
|
|
149
|
+
--files "$rel" --config "$CR_CONFIG" --schema "$CR_SCHEMA" \
|
|
150
|
+
--json "$out" --quiet "$@" >/dev/null 2>&1 )
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
cr_score() { # $1 = json path -> prints first file's score
|
|
154
|
+
ruby -E UTF-8 -rjson -e 'puts JSON.parse(File.read(ARGV[0]))["files"][0]["score"]' "$1"
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
cr_collection() { # $1 = json path -> prints detected collection
|
|
158
|
+
ruby -E UTF-8 -rjson -e 'puts JSON.parse(File.read(ARGV[0]))["files"][0]["collection"]' "$1"
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
cr_has_message() { # $1 = json path, $2 = substring -> exit 0 if any issue contains it
|
|
162
|
+
ruby -E UTF-8 -rjson -e 'd=JSON.parse(File.read(ARGV[0]))["files"][0]; exit(d["issues"].any?{|i| i["message"].include?(ARGV[1])} ? 0 : 1)' "$1" "$2"
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
# --- Run + assert ------------------------------------------------------------
|
|
166
|
+
cr_run "pages/_docs/test/good.md" "$CR_WORK/good.json"
|
|
167
|
+
cr_run "pages/_docs/test/missing-desc.md" "$CR_WORK/missing.json"
|
|
168
|
+
cr_run "pages/_docs/test/codefence.md" "$CR_WORK/codefence.json"
|
|
169
|
+
|
|
170
|
+
GOOD_SCORE="$(cr_score "$CR_WORK/good.json")"
|
|
171
|
+
MISSING_SCORE="$(cr_score "$CR_WORK/missing.json")"
|
|
172
|
+
|
|
173
|
+
assert_equals "docs" "$(cr_collection "$CR_WORK/good.json")" \
|
|
174
|
+
"fixture under pages/_docs/** is detected as the 'docs' collection"
|
|
175
|
+
|
|
176
|
+
assert_true "[ '${GOOD_SCORE:-0}' -ge 80 ]" \
|
|
177
|
+
"a well-formed docs page scores >= 80 (got ${GOOD_SCORE})"
|
|
178
|
+
|
|
179
|
+
assert_true "[ '${MISSING_SCORE:-100}' -lt '${GOOD_SCORE:-0}' ]" \
|
|
180
|
+
"removing the required description lowers the score (${MISSING_SCORE} < ${GOOD_SCORE})"
|
|
181
|
+
|
|
182
|
+
assert_true "cr_has_message '$CR_WORK/missing.json' 'description'" \
|
|
183
|
+
"the missing-description page reports a description issue"
|
|
184
|
+
|
|
185
|
+
assert_false "cr_has_message '$CR_WORK/codefence.json' 'Code fence without a language'" \
|
|
186
|
+
"a closing bare \`\`\` after a tagged fence is not flagged (v1.18.1 regression guard)"
|
|
187
|
+
|
|
188
|
+
# --strict exit behaviour: a failing page exits 0 in warn mode, non-zero strict.
|
|
189
|
+
cr_run "pages/_docs/test/failing.md" "$CR_WORK/failing.json"
|
|
190
|
+
FAILING_SCORE="$(cr_score "$CR_WORK/failing.json")"
|
|
191
|
+
assert_true "[ '${FAILING_SCORE:-100}' -lt 70 ]" \
|
|
192
|
+
"the failing fixture scores below the 70 fail threshold (got ${FAILING_SCORE})"
|
|
193
|
+
|
|
194
|
+
cr_run "pages/_docs/test/failing.md" "$CR_WORK/failing-warn.json"
|
|
195
|
+
assert_equals "0" "$?" \
|
|
196
|
+
"without --strict, a failing page still exits 0 (advisory mode)"
|
|
197
|
+
|
|
198
|
+
cr_run "pages/_docs/test/failing.md" "$CR_WORK/failing-strict.json" --strict
|
|
199
|
+
assert_equals "1" "$?" \
|
|
200
|
+
"with --strict, a failing page exits non-zero (1)"
|
|
201
|
+
|
|
202
|
+
# --- Cleanup -----------------------------------------------------------------
|
|
203
|
+
rm -rf "$CR_WORK"
|
|
204
|
+
|
|
205
|
+
echo -e "\n${GREEN}content-review.rb scoring tests complete${NC}"
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# Unit tests for scripts/features/pixelate_images.py (preview-image pixelator).
|
|
4
|
+
#
|
|
5
|
+
# These drive the dependency-free Python engine as a subprocess and assert on
|
|
6
|
+
# its behaviour: the internal self-test, a real PNG round-trip that shrinks the
|
|
7
|
+
# file, dry-run leaving files untouched, and graceful handling of non-PNG input.
|
|
8
|
+
#
|
|
9
|
+
# Sourced by scripts/test/lib/run_tests.sh (uses its exported assert helpers),
|
|
10
|
+
# but also runnable directly for local iteration.
|
|
11
|
+
|
|
12
|
+
TEST_SELF_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
13
|
+
REPO_ROOT="$(cd "$TEST_SELF_DIR/../../.." && pwd)"
|
|
14
|
+
ENGINE="$REPO_ROOT/scripts/features/pixelate_images.py"
|
|
15
|
+
|
|
16
|
+
# Fallback helpers so the file also runs standalone (when not sourced by the
|
|
17
|
+
# library runner that exports these).
|
|
18
|
+
if ! declare -F assert_true >/dev/null 2>&1; then
|
|
19
|
+
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; BLUE='\033[0;34m'; NC='\033[0m'
|
|
20
|
+
TESTS_RUN=0; TESTS_PASSED=0; TESTS_FAILED=0; declare -a FAILED_TESTS=()
|
|
21
|
+
assert_true() { ((TESTS_RUN++)); if eval "$1"; then ((TESTS_PASSED++)); echo -e "${GREEN}✓${NC} $2"; else ((TESTS_FAILED++)); echo -e "${RED}✗${NC} $2"; FAILED_TESTS+=("$2"); fi; }
|
|
22
|
+
assert_equals() { ((TESTS_RUN++)); if [[ "$1" == "$2" ]]; then ((TESTS_PASSED++)); echo -e "${GREEN}✓${NC} $3"; else ((TESTS_FAILED++)); echo -e "${RED}✗${NC} $3 (expected '$1' got '$2')"; FAILED_TESTS+=("$3"); fi; }
|
|
23
|
+
print_suite_header() { echo -e "\n${BLUE}=== $1 ===${NC}"; }
|
|
24
|
+
STANDALONE=true
|
|
25
|
+
fi
|
|
26
|
+
|
|
27
|
+
set +e
|
|
28
|
+
|
|
29
|
+
print_suite_header "pixelate_images.py"
|
|
30
|
+
|
|
31
|
+
if ! command -v python3 >/dev/null 2>&1; then
|
|
32
|
+
echo -e "${YELLOW}⚠ python3 not available — skipping pixelate_images tests${NC}"
|
|
33
|
+
else
|
|
34
|
+
# ---- Test: internal self-test ----------------------------------------
|
|
35
|
+
if python3 "$ENGINE" --selftest >/dev/null 2>&1; then
|
|
36
|
+
assert_true "true" "engine --selftest passes"
|
|
37
|
+
else
|
|
38
|
+
assert_true "false" "engine --selftest passes"
|
|
39
|
+
fi
|
|
40
|
+
|
|
41
|
+
# ---- Set up a temp workspace with a synthetic gradient PNG -----------
|
|
42
|
+
PX_TMP="$(mktemp -d)"
|
|
43
|
+
trap '[[ -n "${PX_TMP:-}" ]] && rm -rf "$PX_TMP"' EXIT
|
|
44
|
+
|
|
45
|
+
# Build the input PNG independently of the engine's encoder so the
|
|
46
|
+
# round-trip genuinely exercises decode + re-encode.
|
|
47
|
+
python3 - "$PX_TMP/in.png" <<'PY'
|
|
48
|
+
import sys, struct, zlib
|
|
49
|
+
path = sys.argv[1]
|
|
50
|
+
w = h = 256
|
|
51
|
+
body = bytearray()
|
|
52
|
+
for y in range(h):
|
|
53
|
+
body.append(0) # filter: none
|
|
54
|
+
for x in range(w):
|
|
55
|
+
body += bytes(((x + y) % 256, (x * 2) % 256, (y * 2) % 256))
|
|
56
|
+
def chunk(t, d):
|
|
57
|
+
return struct.pack(">I", len(d)) + t + d + struct.pack(">I", zlib.crc32(t + d) & 0xffffffff)
|
|
58
|
+
png = (b"\x89PNG\r\n\x1a\n"
|
|
59
|
+
+ chunk(b"IHDR", struct.pack(">IIBBBBB", w, h, 8, 2, 0, 0, 0))
|
|
60
|
+
+ chunk(b"IDAT", zlib.compress(bytes(body), 9))
|
|
61
|
+
+ chunk(b"IEND", b""))
|
|
62
|
+
open(path, "wb").write(png)
|
|
63
|
+
PY
|
|
64
|
+
assert_true "[[ -s '$PX_TMP/in.png' ]]" "synthetic input PNG created"
|
|
65
|
+
ORIG_SIZE=$(wc -c < "$PX_TMP/in.png" | tr -d ' ')
|
|
66
|
+
|
|
67
|
+
# ---- Test: dry-run does not modify the input -------------------------
|
|
68
|
+
BEFORE=$(wc -c < "$PX_TMP/in.png" | tr -d ' ')
|
|
69
|
+
python3 "$ENGINE" --dry-run "$PX_TMP/in.png" >/dev/null 2>&1
|
|
70
|
+
AFTER=$(wc -c < "$PX_TMP/in.png" | tr -d ' ')
|
|
71
|
+
assert_equals "$BEFORE" "$AFTER" "dry-run leaves the file unchanged"
|
|
72
|
+
|
|
73
|
+
# ---- Test: real run writes a smaller, valid indexed PNG --------------
|
|
74
|
+
python3 "$ENGINE" --colors 64 --block 4 --output-dir "$PX_TMP/out" "$PX_TMP/in.png" >/dev/null 2>&1
|
|
75
|
+
OUT="$PX_TMP/out/in.png"
|
|
76
|
+
assert_true "[[ -s '$OUT' ]]" "optimized output written"
|
|
77
|
+
NEW_SIZE=$(wc -c < "$OUT" 2>/dev/null | tr -d ' ')
|
|
78
|
+
assert_true "[[ '${NEW_SIZE:-0}' -lt '$ORIG_SIZE' ]]" "output is smaller than original ($ORIG_SIZE -> ${NEW_SIZE:-0} bytes)"
|
|
79
|
+
|
|
80
|
+
# Output must be a valid PNG-8 (colour type 3) that decodes back.
|
|
81
|
+
if python3 - "$ENGINE" "$OUT" <<'PY'
|
|
82
|
+
import sys, importlib.util
|
|
83
|
+
spec = importlib.util.spec_from_file_location("pixelate_images", sys.argv[1])
|
|
84
|
+
P = importlib.util.module_from_spec(spec); spec.loader.exec_module(P)
|
|
85
|
+
img = P.decode_png(open(sys.argv[2], "rb").read())
|
|
86
|
+
assert img.width == 64 and img.height == 64, (img.width, img.height)
|
|
87
|
+
PY
|
|
88
|
+
then
|
|
89
|
+
assert_true "true" "output decodes back to expected 64x64 dimensions"
|
|
90
|
+
else
|
|
91
|
+
assert_true "false" "output decodes back to expected 64x64 dimensions"
|
|
92
|
+
fi
|
|
93
|
+
|
|
94
|
+
# ---- Test: non-PNG input is skipped gracefully (no crash) ------------
|
|
95
|
+
printf 'not a png at all' > "$PX_TMP/fake.png"
|
|
96
|
+
python3 "$ENGINE" --dry-run "$PX_TMP/fake.png" >/dev/null 2>&1
|
|
97
|
+
assert_equals "0" "$?" "non-PNG input is handled gracefully (exit 0)"
|
|
98
|
+
|
|
99
|
+
rm -rf "$PX_TMP"; PX_TMP=""
|
|
100
|
+
fi
|
|
101
|
+
|
|
102
|
+
# When run standalone, print a summary and exit with the right code.
|
|
103
|
+
if [[ "${STANDALONE:-false}" == "true" ]]; then
|
|
104
|
+
echo ""
|
|
105
|
+
echo -e "Total: $TESTS_RUN ${GREEN}Passed: $TESTS_PASSED${NC} ${RED}Failed: $TESTS_FAILED${NC}"
|
|
106
|
+
[[ $TESTS_FAILED -eq 0 ]]
|
|
107
|
+
exit $?
|
|
108
|
+
fi
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: jekyll-theme-zer0
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.21.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Amr Abdel
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-06-
|
|
11
|
+
date: 2026-06-26 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: jekyll
|
|
@@ -86,15 +86,12 @@ files:
|
|
|
86
86
|
- _data/generate_statistics.sh
|
|
87
87
|
- _data/github-actions-example.yml
|
|
88
88
|
- _data/glossary.yml
|
|
89
|
-
- _data/hub.yml
|
|
90
|
-
- _data/hub_index.yml
|
|
91
89
|
- _data/landing.yml
|
|
92
90
|
- _data/navigation/README.md
|
|
93
91
|
- _data/navigation/about.yml
|
|
94
92
|
- _data/navigation/admin.yml
|
|
95
93
|
- _data/navigation/docs.yml
|
|
96
94
|
- _data/navigation/home.yml
|
|
97
|
-
- _data/navigation/hub.yml
|
|
98
95
|
- _data/navigation/main.yml
|
|
99
96
|
- _data/navigation/posts.yml
|
|
100
97
|
- _data/navigation/quickstart.yml
|
|
@@ -102,6 +99,8 @@ files:
|
|
|
102
99
|
- _data/prerequisites.yml
|
|
103
100
|
- _data/prompts.yml
|
|
104
101
|
- _data/roadmap.yml
|
|
102
|
+
- _data/roadmap_plan.yml
|
|
103
|
+
- _data/routing.yml
|
|
105
104
|
- _data/statistics_config.yml
|
|
106
105
|
- _data/theme-manifest.yml
|
|
107
106
|
- _data/theme_backgrounds.yml
|
|
@@ -117,6 +116,8 @@ files:
|
|
|
117
116
|
- _includes/components/admin-tabs.html
|
|
118
117
|
- _includes/components/ai-chat.html
|
|
119
118
|
- _includes/components/analytics-dashboard.html
|
|
119
|
+
- _includes/components/author-avatar-url.html
|
|
120
|
+
- _includes/components/author-bio.html
|
|
120
121
|
- _includes/components/author-card.html
|
|
121
122
|
- _includes/components/author-eeat.html
|
|
122
123
|
- _includes/components/background-customizer.html
|
|
@@ -170,6 +171,7 @@ files:
|
|
|
170
171
|
- _includes/content/toc.html
|
|
171
172
|
- _includes/content/transclude.html
|
|
172
173
|
- _includes/core/branding.html
|
|
174
|
+
- _includes/core/footer-fabs.html
|
|
173
175
|
- _includes/core/footer.html
|
|
174
176
|
- _includes/core/head.html
|
|
175
177
|
- _includes/core/header.html
|
|
@@ -205,6 +207,8 @@ files:
|
|
|
205
207
|
- _layouts/README.md
|
|
206
208
|
- _layouts/admin.html
|
|
207
209
|
- _layouts/article.html
|
|
210
|
+
- _layouts/author.html
|
|
211
|
+
- _layouts/authors.html
|
|
208
212
|
- _layouts/collection.html
|
|
209
213
|
- _layouts/default.html
|
|
210
214
|
- _layouts/home.html
|
|
@@ -222,32 +226,41 @@ files:
|
|
|
222
226
|
- _layouts/tag.html
|
|
223
227
|
- _layouts/welcome.html
|
|
224
228
|
- _plugins/admin_page_urls.rb
|
|
229
|
+
- _plugins/author_pages_generator.rb
|
|
225
230
|
- _plugins/content_statistics_generator.rb
|
|
226
231
|
- _plugins/obsidian_links.rb
|
|
227
232
|
- _plugins/preview_image_generator.rb
|
|
228
233
|
- _plugins/sanitize_config_filter.rb
|
|
229
234
|
- _plugins/search_and_sitemap_generator.rb
|
|
230
235
|
- _plugins/theme_version.rb
|
|
236
|
+
- _sass/components/_author.scss
|
|
231
237
|
- _sass/components/_back-to-top.scss
|
|
232
238
|
- _sass/components/_callout.scss
|
|
233
239
|
- _sass/components/_content-tables.scss
|
|
234
240
|
- _sass/components/_cookie-banner.scss
|
|
235
241
|
- _sass/components/_footer.scss
|
|
242
|
+
- _sass/components/_notes-index.scss
|
|
236
243
|
- _sass/components/_notes.scss
|
|
237
244
|
- _sass/components/_post-navigation.scss
|
|
245
|
+
- _sass/components/_search-modal.scss
|
|
238
246
|
- _sass/components/_skeleton.scss
|
|
239
247
|
- _sass/components/_theme-preview.scss
|
|
248
|
+
- _sass/components/_ui-enhancements.scss
|
|
249
|
+
- _sass/core/_docs-code-examples.scss
|
|
240
250
|
- _sass/core/_docs-layout.scss
|
|
241
251
|
- _sass/core/_nav-tree.scss
|
|
242
252
|
- _sass/core/_navbar.scss
|
|
243
253
|
- _sass/core/_obsidian.scss
|
|
244
254
|
- _sass/core/_offcanvas-panels.scss
|
|
245
255
|
- _sass/core/_sidebar-categories.scss
|
|
256
|
+
- _sass/core/_sidebar-extras.scss
|
|
246
257
|
- _sass/core/_syntax.scss
|
|
247
258
|
- _sass/core/_theme.scss
|
|
259
|
+
- _sass/core/_toc.scss
|
|
248
260
|
- _sass/core/_variables.scss
|
|
249
261
|
- _sass/core/code-copy.scss
|
|
250
262
|
- _sass/custom.scss
|
|
263
|
+
- _sass/layouts/_global-chrome.scss
|
|
251
264
|
- _sass/layouts/_landing.scss
|
|
252
265
|
- _sass/layouts/_navbar-extras.scss
|
|
253
266
|
- _sass/layouts/_section.scss
|
|
@@ -278,6 +291,7 @@ files:
|
|
|
278
291
|
- assets/data/notebooks/weather_data.csv
|
|
279
292
|
- assets/data/wiki-index.json
|
|
280
293
|
- assets/js/ai-chat.js
|
|
294
|
+
- assets/js/author-profile.js
|
|
281
295
|
- assets/js/auto-hide-nav.js
|
|
282
296
|
- assets/js/back-to-top.js
|
|
283
297
|
- assets/js/background-customizer.js
|
|
@@ -327,18 +341,9 @@ files:
|
|
|
327
341
|
- assets/vendor/bootstrap-icons/font/fonts/bootstrap-icons.woff2
|
|
328
342
|
- assets/vendor/bootstrap/css/bootstrap.min.css
|
|
329
343
|
- assets/vendor/bootstrap/js/bootstrap.bundle.min.js
|
|
330
|
-
- assets/vendor/
|
|
331
|
-
- assets/vendor/font-awesome/webfonts/fa-brands-400.ttf
|
|
332
|
-
- assets/vendor/font-awesome/webfonts/fa-brands-400.woff2
|
|
333
|
-
- assets/vendor/font-awesome/webfonts/fa-regular-400.ttf
|
|
334
|
-
- assets/vendor/font-awesome/webfonts/fa-regular-400.woff2
|
|
335
|
-
- assets/vendor/font-awesome/webfonts/fa-solid-900.ttf
|
|
336
|
-
- assets/vendor/font-awesome/webfonts/fa-solid-900.woff2
|
|
337
|
-
- assets/vendor/font-awesome/webfonts/fa-v4compatibility.ttf
|
|
338
|
-
- assets/vendor/font-awesome/webfonts/fa-v4compatibility.woff2
|
|
344
|
+
- assets/vendor/cytoscape/cytoscape.min.js
|
|
339
345
|
- assets/vendor/github-calendar/github-calendar-responsive.css
|
|
340
346
|
- assets/vendor/github-calendar/github-calendar.min.js
|
|
341
|
-
- assets/vendor/jquery/jquery-3.7.1.min.js
|
|
342
347
|
- assets/vendor/mathjax/es5/adaptors/liteDOM.js
|
|
343
348
|
- assets/vendor/mathjax/es5/core.js
|
|
344
349
|
- assets/vendor/mathjax/es5/output/chtml/fonts/woff-v2/MathJax_AMS-Regular.woff
|
|
@@ -380,6 +385,8 @@ files:
|
|
|
380
385
|
- scripts/build
|
|
381
386
|
- scripts/content-review.rb
|
|
382
387
|
- scripts/convert-notebooks.sh
|
|
388
|
+
- scripts/dev/css-diff.sh
|
|
389
|
+
- scripts/dev/shot.js
|
|
383
390
|
- scripts/docker-publish
|
|
384
391
|
- scripts/docs/check-freshness.sh
|
|
385
392
|
- scripts/docs/check-links.sh
|
|
@@ -388,6 +395,8 @@ files:
|
|
|
388
395
|
- scripts/example-usage.sh
|
|
389
396
|
- scripts/features/generate-preview-images
|
|
390
397
|
- scripts/features/install-preview-generator
|
|
398
|
+
- scripts/features/pixelate-preview-images
|
|
399
|
+
- scripts/features/pixelate_images.py
|
|
391
400
|
- scripts/features/validate_preview_urls.py
|
|
392
401
|
- scripts/fix-markdown-format.sh
|
|
393
402
|
- scripts/fork-cleanup.sh
|
|
@@ -446,7 +455,6 @@ files:
|
|
|
446
455
|
- scripts/lib/frontmatter.sh
|
|
447
456
|
- scripts/lib/gem.sh
|
|
448
457
|
- scripts/lib/git.sh
|
|
449
|
-
- scripts/lib/hub.rb
|
|
450
458
|
- scripts/lib/install/README.md
|
|
451
459
|
- scripts/lib/install/agents.sh
|
|
452
460
|
- scripts/lib/install/ai/diagnose.sh
|
|
@@ -476,18 +484,17 @@ files:
|
|
|
476
484
|
- scripts/lint-pages
|
|
477
485
|
- scripts/migrate-nav-modes.sh
|
|
478
486
|
- scripts/migrate.sh
|
|
487
|
+
- scripts/pixelate-preview-images.sh
|
|
479
488
|
- scripts/platform/setup-linux.sh
|
|
480
489
|
- scripts/platform/setup-macos.sh
|
|
481
490
|
- scripts/platform/setup-wsl.sh
|
|
482
491
|
- scripts/post-template-setup.sh
|
|
483
|
-
- scripts/provision-org-sites.rb
|
|
484
|
-
- scripts/provision-org-sites.sh
|
|
485
492
|
- scripts/release
|
|
486
493
|
- scripts/setup.sh
|
|
487
494
|
- scripts/sync-backlog.rb
|
|
488
495
|
- scripts/sync-backlog.sh
|
|
489
|
-
- scripts/sync-
|
|
490
|
-
- scripts/sync-
|
|
496
|
+
- scripts/sync-plan.rb
|
|
497
|
+
- scripts/sync-plan.sh
|
|
491
498
|
- scripts/test-auto-version.sh
|
|
492
499
|
- scripts/test-mermaid.sh
|
|
493
500
|
- scripts/test-notebook-conversion.sh
|
|
@@ -497,10 +504,12 @@ files:
|
|
|
497
504
|
- scripts/test/lib/run_tests.sh
|
|
498
505
|
- scripts/test/lib/test_analyze_commits.sh
|
|
499
506
|
- scripts/test/lib/test_changelog.sh
|
|
507
|
+
- scripts/test/lib/test_content_review.sh
|
|
500
508
|
- scripts/test/lib/test_gem.sh
|
|
501
509
|
- scripts/test/lib/test_git.sh
|
|
502
510
|
- scripts/test/lib/test_locale_independence.sh
|
|
503
511
|
- scripts/test/lib/test_migrate.sh
|
|
512
|
+
- scripts/test/lib/test_pixelate_images.sh
|
|
504
513
|
- scripts/test/lib/test_validation.sh
|
|
505
514
|
- scripts/test/lib/test_version.sh
|
|
506
515
|
- scripts/test/theme/validate
|
data/_data/hub.yml
DELETED
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
# =============================================================================
|
|
2
|
-
# Content Hub registry — _data/hub.yml
|
|
3
|
-
# =============================================================================
|
|
4
|
-
#
|
|
5
|
-
# Source of truth for the org content hub. Content NEVER leaves the source
|
|
6
|
-
# repos: each org repo publishes its own GitHub Pages project site at
|
|
7
|
-
# https://<org>.github.io/<repo>/ using this theme via `remote_theme`, and
|
|
8
|
-
# this site is the dashboard that presents and monitors them.
|
|
9
|
-
#
|
|
10
|
-
# Consumers of this registry:
|
|
11
|
-
# scripts/provision-org-sites.sh rolls the Pages scaffold out to org repos
|
|
12
|
-
# (templates/org-site/*) and enables Pages
|
|
13
|
-
# scripts/sync-hub-metadata.sh refreshes the generated dashboard data:
|
|
14
|
-
# _data/hub_index.yml (repo stats)
|
|
15
|
-
# _data/navigation/hub.yml (sidebar tree)
|
|
16
|
-
#
|
|
17
|
-
# Validated by `./scripts/sync-hub-metadata.sh --check` (CI gate).
|
|
18
|
-
# =============================================================================
|
|
19
|
-
|
|
20
|
-
# GitHub organization (or user) whose repositories make up the hub.
|
|
21
|
-
org: year-of-ai
|
|
22
|
-
|
|
23
|
-
# When true, every non-archived repo in the org is included unless listed in
|
|
24
|
-
# `exclude_repos`. When false, only repos listed under `repos:` are included.
|
|
25
|
-
auto_discover: true
|
|
26
|
-
|
|
27
|
-
# Repos that are never treated as content sites.
|
|
28
|
-
exclude_repos:
|
|
29
|
-
- zer0-mistakes # this site/theme itself
|
|
30
|
-
- .github # org meta repo, if one appears
|
|
31
|
-
|
|
32
|
-
# Settings applied when provisioning org repos as Pages sites.
|
|
33
|
-
pages:
|
|
34
|
-
# Value for `remote_theme:` in the generated _config.yml of each org repo.
|
|
35
|
-
# The org root site (year-of-ai/year-of-ai.github.io) is a fork of the
|
|
36
|
-
# zer0-mistakes theme and doubles as the remote_theme source for the years.
|
|
37
|
-
theme_repo: year-of-ai/year-of-ai.github.io
|
|
38
|
-
# Git ref to scaffold against / publish from. Empty = repo default branch.
|
|
39
|
-
branch: ""
|
|
40
|
-
|
|
41
|
-
# Rules applied to every repo unless overridden per-repo below.
|
|
42
|
-
defaults:
|
|
43
|
-
# Paths that are repo/agent plumbing rather than content. Used both for the
|
|
44
|
-
# generated Pages `exclude:` list and for the dashboard page counts.
|
|
45
|
-
exclude:
|
|
46
|
-
- "README.md" # rendered as the site homepage, not counted as content
|
|
47
|
-
- "CLAUDE.md"
|
|
48
|
-
- "AGENTS.md"
|
|
49
|
-
- "LIFECYCLE.md"
|
|
50
|
-
- "ROADMAP.md"
|
|
51
|
-
- "lifecycle.yml"
|
|
52
|
-
- "seed.md"
|
|
53
|
-
- "seed-package/**"
|
|
54
|
-
- "telemetry/**"
|
|
55
|
-
- ".github/**"
|
|
56
|
-
- ".claude/**"
|
|
57
|
-
|
|
58
|
-
# Optional per-repo overrides, merged onto discovered repos by `name`.
|
|
59
|
-
# Supported keys: name (required), title, description, branch.
|
|
60
|
-
repos:
|
|
61
|
-
- name: "2005"
|
|
62
|
-
title: "2005 — Year Knowledge Base"
|
|
63
|
-
- name: "2006"
|
|
64
|
-
title: "2006 — Year Knowledge Base"
|
|
65
|
-
- name: "2007"
|
|
66
|
-
title: "2007 — Year Knowledge Base"
|
|
67
|
-
- name: "2008"
|
|
68
|
-
title: "2008 — Year Knowledge Base"
|