Compare commits
188 Commits
76648f1166
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ba6ac7052a | ||
|
|
5f0a420ea5 | ||
|
|
2d454188cc | ||
|
|
c437e195e9 | ||
|
|
ac8596f8b3 | ||
|
|
23ad1e6f0b | ||
| 86007209e8 | |||
| f05fb7540a | |||
|
|
bdade0a4e8 | ||
|
|
57a0950bf2 | ||
| 00c390bb2c | |||
| 5c4eb0daaa | |||
|
|
7087f3e526 | ||
| f37718e61c | |||
| 220a433617 | |||
|
|
5f9e58407e | ||
|
|
2c956793c7 | ||
|
|
29beedd2f0 | ||
|
|
2a49e2e60c | ||
|
|
903af90459 | ||
|
|
373275cd7a | ||
|
|
e7584f2698 | ||
|
|
53ddc9fdbb | ||
|
|
b527ea8b72 | ||
|
|
259a16b752 | ||
|
|
0b369d29df | ||
|
|
1e7cff47ad | ||
|
|
7265e29035 | ||
|
|
23039c8b76 | ||
|
|
1a6b5b0840 | ||
|
|
0faa2e14bc | ||
|
|
72c5a28e1f | ||
|
|
d4a66c6530 | ||
|
|
dcbdf1026d | ||
|
|
6cb2f50414 | ||
|
|
75de123f2b | ||
|
|
3758fa83a1 | ||
|
|
c384b33ecf | ||
|
|
a832c99acd | ||
|
|
00603f8efd | ||
|
|
8864bad706 | ||
|
|
169834d96e | ||
|
|
5f51237a52 | ||
|
|
4940bb7c59 | ||
|
|
88e308834a | ||
|
|
02f6ce4b6d | ||
|
|
b342e07fa9 | ||
|
|
2ad082b613 | ||
|
|
d3232e9ce4 | ||
|
|
7c289859ad | ||
|
|
2d643f4ecd | ||
|
|
e7e0e64caa | ||
|
|
ba512632d9 | ||
|
|
e7e3932944 | ||
|
|
b3069323c7 | ||
|
|
25a145dfa2 | ||
|
|
dab398e75d | ||
|
|
98bb579c77 | ||
|
|
b33f38d271 | ||
|
|
de6175b60a | ||
|
|
9c8153d681 | ||
|
|
6601f2f290 | ||
|
|
e98e08bc74 | ||
|
|
e25f9bf6b1 | ||
|
|
2d01288db8 | ||
|
|
66e689e5c1 | ||
|
|
610d5b0790 | ||
|
|
fbdbc56179 | ||
|
|
bc427a7bce | ||
|
|
73e19e10a6 | ||
|
|
0222d99cfa | ||
|
|
697fd6ffd3 | ||
|
|
9dc96b7781 | ||
|
|
1623e03dbc | ||
|
|
0c9075e75f | ||
|
|
73d97d7bbb | ||
|
|
50c4cdb057 | ||
|
|
9d917da48d | ||
|
|
3a59ac98bc | ||
|
|
f82c851c17 | ||
|
|
0cb582ff95 | ||
|
|
1c8f1493a5 | ||
|
|
a20debf2ca | ||
|
|
6274eefb83 | ||
|
|
67c1ab6cf9 | ||
|
|
bde568aba0 | ||
|
|
62e7827600 | ||
|
|
30cf3ad669 | ||
|
|
7664b40eb2 | ||
|
|
1b6ccead88 | ||
|
|
b6eb98e181 | ||
|
|
bd14ba3eae | ||
|
|
180f0e0f6d | ||
|
|
c7f7f71f10 | ||
|
|
ab4c5a8acd | ||
|
|
44ad5fb09b | ||
|
|
e00bc57923 | ||
|
|
e5aa9e91c7 | ||
|
|
495db56f4e | ||
|
|
c305700910 | ||
|
|
156ee2f439 | ||
|
|
99c83ec9d1 | ||
|
|
c14e5a0572 | ||
|
|
bad17266b4 | ||
|
|
b4804c5114 | ||
|
|
642f9ac957 | ||
|
|
4d2e96a7b8 | ||
|
|
ac9ca4ce99 | ||
|
|
d4f6cb0a95 | ||
|
|
a78d30c9c1 | ||
|
|
94f51ee2b5 | ||
|
|
38e8cf9305 | ||
|
|
50dc04f1d5 | ||
|
|
fb4966b212 | ||
|
|
985d4aa61f | ||
|
|
8ba5fe5af5 | ||
|
|
3c5701c767 | ||
|
|
15607cb7f6 | ||
|
|
c865d4943f | ||
|
|
921a1d9e30 | ||
|
|
b856e6ad68 | ||
|
|
cabe5cb61a | ||
|
|
631df5c7fb | ||
|
|
9ff5da4f16 | ||
|
|
9ac20faeea | ||
|
|
61ee4388d8 | ||
|
|
0904f4f95e | ||
|
|
5146b1dc3e | ||
|
|
33019b3890 | ||
|
|
800a898e97 | ||
|
|
4f7ce69c03 | ||
|
|
297160bc41 | ||
|
|
a7d65c5785 | ||
|
|
12a15b1d26 | ||
|
|
a439697617 | ||
|
|
2f05e44737 | ||
|
|
3d785c1d49 | ||
|
|
2d279824ec | ||
|
|
245ab17c29 | ||
|
|
e6337caf0d | ||
|
|
b3cc608eb3 | ||
|
|
d6fe08410d | ||
|
|
6dbd968bd7 | ||
|
|
093e223107 | ||
|
|
b2403d8147 | ||
|
|
9a91b38003 | ||
|
|
667545c601 | ||
|
|
69161411aa | ||
|
|
083c59bfa7 | ||
|
|
3596101494 | ||
|
|
a7cee2a6a5 | ||
|
|
f1a874919e | ||
| c7656f6220 | |||
|
|
be0c9b003a | ||
|
|
52b196ed56 | ||
|
|
6312f23fc0 | ||
|
|
351fa62a27 | ||
|
|
c406c9dd79 | ||
|
|
543ab4e31b | ||
|
|
1316d978bf | ||
|
|
9320dd3835 | ||
|
|
6acfe121ce | ||
|
|
dd77951dbb | ||
|
|
10fcdc2b1d | ||
|
|
3454ebc1aa | ||
|
|
5267a39d51 | ||
|
|
e24fd97fc8 | ||
|
|
663ae0acb5 | ||
|
|
76f61556cb | ||
|
|
7c8512a046 | ||
|
|
fd414f0933 | ||
| cfcf44d04b | |||
|
|
9ab3da8658 | ||
|
|
5db18aadde | ||
|
|
8e3a750cd1 | ||
|
|
9de5f4517e | ||
|
|
2d1c26f9df | ||
|
|
bd578f56d3 | ||
|
|
fa58de7ff5 | ||
|
|
f94393010a | ||
|
|
56d522d3a6 | ||
|
|
e26688bb23 | ||
|
|
93fff0c77a | ||
|
|
6fb25316b6 | ||
|
|
2afb391e20 | ||
|
|
6c4e08a39d | ||
| 1342dfb64e | |||
|
|
0bc85d90ac |
@@ -3,6 +3,7 @@ on:
|
||||
push:
|
||||
paths:
|
||||
- 'public/code-stats.json'
|
||||
- 'public/heatmap.json'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
@@ -11,32 +12,51 @@ jobs:
|
||||
steps:
|
||||
- name: Manual Internal Checkout
|
||||
run: |
|
||||
git clone http://gitea-http:3000/${{ github.repository }}.git .
|
||||
git clone --filter=blob:none http://gitea-http:3000/${{ github.repository }}.git .
|
||||
git checkout ${{ github.ref_name }}
|
||||
|
||||
|
||||
- name: Update README
|
||||
- name: Sync with upstream
|
||||
run: |
|
||||
git fetch origin
|
||||
git rebase origin/${{ github.ref_name }}
|
||||
|
||||
- name: Process Statistics and Update README
|
||||
run: |
|
||||
if ! command -v jq &> /dev/null; then
|
||||
if command -v apk &> /dev/null; then apk add --no-cache jq;
|
||||
elif command -v apt-get &> /dev/null; then apt-get update && apt-get install -y jq; fi
|
||||
fi
|
||||
|
||||
if ! command -v python3 &> /dev/null; then
|
||||
if command -v apk &> /dev/null; then apk add --no-cache python3;
|
||||
elif command -v apt-get &> /dev/null; then apt-get update && apt-get install -y python3; fi
|
||||
fi
|
||||
|
||||
# Use our own heatmap.json instead of Gitea API
|
||||
HEATMAP_FILE="public/heatmap.json"
|
||||
TOTAL_COMMITS=$(jq '[.days[] | .count] | add' "$HEATMAP_FILE")
|
||||
|
||||
echo "Global Commit Velocity: $TOTAL_COMMITS"
|
||||
echo "COMMIT_VELOCITY=$TOTAL_COMMITS" >> $GITHUB_ENV
|
||||
|
||||
LOC=$(grep '"total_code"' public/code-stats.json | sed 's/[^0-9]*//g')
|
||||
FORMATTED_LOC=$(printf "%'d" $LOC)
|
||||
echo "FORMATTED_LOC=$FORMATTED_LOC" >> $GITHUB_ENV
|
||||
|
||||
echo "Injecting $FORMATTED_LOC into README.template..."
|
||||
python3 scripts/generate_heatmap_svg.py public/heatmap.json public/heatmap.svg
|
||||
|
||||
sed "s/REPLACE_ME_LOC/$FORMATTED_LOC/g" README.template > README.md
|
||||
|
||||
if [ ! -s README.md ]; then
|
||||
echo "Error: README.md is empty!"
|
||||
exit 1
|
||||
fi
|
||||
sed "s/REPLACE_ME_LOC/$FORMATTED_LOC/g" README.template | \
|
||||
sed "s/REPLACE_ME_COMMITS/$TOTAL_COMMITS/g" > README.md
|
||||
|
||||
- name: Commit and Push
|
||||
run: |
|
||||
git config user.name "Ares-Bot"
|
||||
git config user.email "ares@beane.me"
|
||||
git add README.md
|
||||
git add README.md public/heatmap.svg
|
||||
|
||||
if git diff --staged --quiet; then
|
||||
echo "No changes"
|
||||
echo "No changes to commit"
|
||||
else
|
||||
git commit -m "chore: sync code velocity to $FORMATTED_LOC LOC [skip ci]"
|
||||
git push http://${{ secrets.GITHUB_TOKEN }}@gitea-http:3000/${{ github.repository }}.git ${{ github.ref_name }}
|
||||
git commit -m "chore: sync profile metrics [skip ci]"
|
||||
git push http://patrick:${{ secrets.PAT_TOKEN }}@gitea-http:3000/${{ github.repository }}.git ${{ github.ref_name }}
|
||||
fi
|
||||
|
||||
13
README.md
13
README.md
@@ -7,7 +7,7 @@ My lab functions as a live production environment where threat intelligence, aut
|
||||
|
||||
---
|
||||
|
||||
## 🛰️ The Fleet (10 Nodes)
|
||||
## 🛰 The Fleet (10 Nodes)
|
||||
|
||||
> This environment blends production, research, and continuous experimentation.
|
||||
> Availability and controls are intentionally tuned per node role.
|
||||
@@ -43,12 +43,12 @@ My lab functions as a live production environment where threat intelligence, aut
|
||||
- **Retention:**
|
||||
- 24 hours for lower confidence scenarios
|
||||
- 14 days for high-confidence IOCs
|
||||
- 30 days for offender watchlist
|
||||
- 7 days for offender watchlist
|
||||
- **Notification:** High-severity events dynamically pushed to Discord.
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ The Arsenal
|
||||
## 🛠 The Arsenal
|
||||
|
||||
**Languages:** Python (Flask, Gunicorn), Bash, JavaScript (React, Node.js)
|
||||
**Infrastructure:** Kubernetes (K8s), Docker, Caddy, NGINX
|
||||
@@ -72,10 +72,15 @@ Actively used across this environment or in adjacent projects:
|
||||
|
||||
## ⚡ Efficiency Metrics
|
||||
|
||||
- **Codebase Growth:** `0` lines of custom code across all our repositories
|
||||
- **Codebase Growth:** `53135` lines of custom code across all our repositories
|
||||
- **Commit Velocity:** `1006` commits since Jan 1
|
||||
- **Ares:** Ryzen 9 9950X sustaining ~0.06 load avg while running Gitea and a Kubernetes control plane
|
||||
- **Resilience:** Automated failover between AWS and peer nodes
|
||||
|
||||
## 📈 Activity
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
### 🧩 Deployment Patterns
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# 🛡 Patrick Beane
|
||||
# 🛡️ Patrick Beane
|
||||
|
||||
**SRE | Security Engineer | Self-Hosted Infra & Detection**
|
||||
|
||||
@@ -36,14 +36,14 @@ My lab functions as a live production environment where threat intelligence, aut
|
||||
|
||||
---
|
||||
|
||||
## 🛡 Detection & Response Lifecycle
|
||||
## 🛡️ Detection & Response Lifecycle
|
||||
|
||||
- **Triage:** Telemetry ingested from 7 active nodes into the Argus engine.
|
||||
- **Escalation:** Post-exploitation indicators (e.g. webshells) trigger immediate `PERM_BAN`.
|
||||
- **Retention:**
|
||||
- 24 hours for lower confidence scenarios
|
||||
- 14 days for high-confidence IOCs
|
||||
- 30 days for offender watchlist
|
||||
- 7 days for offender watchlist
|
||||
- **Notification:** High-severity events dynamically pushed to Discord.
|
||||
|
||||
---
|
||||
@@ -73,9 +73,14 @@ Actively used across this environment or in adjacent projects:
|
||||
## ⚡ Efficiency Metrics
|
||||
|
||||
- **Codebase Growth:** `REPLACE_ME_LOC` lines of custom code across all our repositories
|
||||
- **Commit Velocity:** `REPLACE_ME_COMMITS` commits since Jan 1
|
||||
- **Ares:** Ryzen 9 9950X sustaining ~0.06 load avg while running Gitea and a Kubernetes control plane
|
||||
- **Resilience:** Automated failover between AWS and peer nodes
|
||||
|
||||
## 📈 Activity
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
### 🧩 Deployment Patterns
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"generated_at": "2026-01-20T19:42:04.836106Z",
|
||||
"total_code": 13759,
|
||||
"total_comments": 1132,
|
||||
"total_blanks": 1859
|
||||
"generated_at": "2026-04-06T05:50:01Z",
|
||||
"total_code": 53135,
|
||||
"total_comments": 4686,
|
||||
"total_blanks": 8984
|
||||
}
|
||||
1469
public/heatmap.json
Normal file
1469
public/heatmap.json
Normal file
File diff suppressed because it is too large
Load Diff
392
public/heatmap.svg
Normal file
392
public/heatmap.svg
Normal file
@@ -0,0 +1,392 @@
|
||||
<svg width="676" height="114" viewBox="0 0 676 114" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Commit activity heatmap">
|
||||
<style>
|
||||
text { font: 10px -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif; fill: #57606a; }
|
||||
</style>
|
||||
<text x="30" y="10">Apr</text>
|
||||
<text x="66" y="10">May</text>
|
||||
<text x="126" y="10">Jun</text>
|
||||
<text x="174" y="10">Jul</text>
|
||||
<text x="222" y="10">Aug</text>
|
||||
<text x="282" y="10">Sep</text>
|
||||
<text x="330" y="10">Oct</text>
|
||||
<text x="378" y="10">Nov</text>
|
||||
<text x="438" y="10">Dec</text>
|
||||
<text x="486" y="10">Jan</text>
|
||||
<text x="546" y="10">Feb</text>
|
||||
<text x="594" y="10">Mar</text>
|
||||
<text x="642" y="10">Apr</text>
|
||||
<text x="0" y="40">Mon</text>
|
||||
<text x="0" y="64">Wed</text>
|
||||
<text x="0" y="88">Fri</text>
|
||||
<rect x="30" y="20" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-04-06: 0 commits</title></rect>
|
||||
<rect x="30" y="32" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-04-07: 0 commits</title></rect>
|
||||
<rect x="30" y="44" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-04-08: 0 commits</title></rect>
|
||||
<rect x="30" y="56" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-04-09: 0 commits</title></rect>
|
||||
<rect x="30" y="68" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-04-10: 0 commits</title></rect>
|
||||
<rect x="30" y="80" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-04-11: 0 commits</title></rect>
|
||||
<rect x="30" y="92" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-04-12: 0 commits</title></rect>
|
||||
<rect x="42" y="20" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-04-13: 0 commits</title></rect>
|
||||
<rect x="42" y="32" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-04-14: 0 commits</title></rect>
|
||||
<rect x="42" y="44" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-04-15: 0 commits</title></rect>
|
||||
<rect x="42" y="56" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-04-16: 0 commits</title></rect>
|
||||
<rect x="42" y="68" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-04-17: 0 commits</title></rect>
|
||||
<rect x="42" y="80" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-04-18: 0 commits</title></rect>
|
||||
<rect x="42" y="92" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-04-19: 0 commits</title></rect>
|
||||
<rect x="54" y="20" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-04-20: 0 commits</title></rect>
|
||||
<rect x="54" y="32" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-04-21: 0 commits</title></rect>
|
||||
<rect x="54" y="44" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-04-22: 0 commits</title></rect>
|
||||
<rect x="54" y="56" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-04-23: 0 commits</title></rect>
|
||||
<rect x="54" y="68" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-04-24: 0 commits</title></rect>
|
||||
<rect x="54" y="80" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-04-25: 0 commits</title></rect>
|
||||
<rect x="54" y="92" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-04-26: 0 commits</title></rect>
|
||||
<rect x="66" y="20" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-04-27: 0 commits</title></rect>
|
||||
<rect x="66" y="32" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-04-28: 0 commits</title></rect>
|
||||
<rect x="66" y="44" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-04-29: 0 commits</title></rect>
|
||||
<rect x="66" y="56" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-04-30: 0 commits</title></rect>
|
||||
<rect x="66" y="68" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-05-01: 0 commits</title></rect>
|
||||
<rect x="66" y="80" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-05-02: 0 commits</title></rect>
|
||||
<rect x="66" y="92" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-05-03: 0 commits</title></rect>
|
||||
<rect x="78" y="20" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-05-04: 0 commits</title></rect>
|
||||
<rect x="78" y="32" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-05-05: 0 commits</title></rect>
|
||||
<rect x="78" y="44" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-05-06: 0 commits</title></rect>
|
||||
<rect x="78" y="56" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-05-07: 0 commits</title></rect>
|
||||
<rect x="78" y="68" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-05-08: 0 commits</title></rect>
|
||||
<rect x="78" y="80" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-05-09: 0 commits</title></rect>
|
||||
<rect x="78" y="92" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-05-10: 0 commits</title></rect>
|
||||
<rect x="90" y="20" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-05-11: 0 commits</title></rect>
|
||||
<rect x="90" y="32" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-05-12: 0 commits</title></rect>
|
||||
<rect x="90" y="44" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-05-13: 0 commits</title></rect>
|
||||
<rect x="90" y="56" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-05-14: 0 commits</title></rect>
|
||||
<rect x="90" y="68" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-05-15: 0 commits</title></rect>
|
||||
<rect x="90" y="80" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-05-16: 0 commits</title></rect>
|
||||
<rect x="90" y="92" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-05-17: 0 commits</title></rect>
|
||||
<rect x="102" y="20" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-05-18: 0 commits</title></rect>
|
||||
<rect x="102" y="32" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-05-19: 0 commits</title></rect>
|
||||
<rect x="102" y="44" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-05-20: 0 commits</title></rect>
|
||||
<rect x="102" y="56" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-05-21: 0 commits</title></rect>
|
||||
<rect x="102" y="68" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-05-22: 0 commits</title></rect>
|
||||
<rect x="102" y="80" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-05-23: 0 commits</title></rect>
|
||||
<rect x="102" y="92" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-05-24: 0 commits</title></rect>
|
||||
<rect x="114" y="20" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-05-25: 0 commits</title></rect>
|
||||
<rect x="114" y="32" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-05-26: 0 commits</title></rect>
|
||||
<rect x="114" y="44" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-05-27: 0 commits</title></rect>
|
||||
<rect x="114" y="56" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-05-28: 0 commits</title></rect>
|
||||
<rect x="114" y="68" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-05-29: 0 commits</title></rect>
|
||||
<rect x="114" y="80" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-05-30: 0 commits</title></rect>
|
||||
<rect x="114" y="92" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-05-31: 0 commits</title></rect>
|
||||
<rect x="126" y="20" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-06-01: 0 commits</title></rect>
|
||||
<rect x="126" y="32" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-06-02: 0 commits</title></rect>
|
||||
<rect x="126" y="44" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-06-03: 0 commits</title></rect>
|
||||
<rect x="126" y="56" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-06-04: 0 commits</title></rect>
|
||||
<rect x="126" y="68" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-06-05: 0 commits</title></rect>
|
||||
<rect x="126" y="80" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-06-06: 0 commits</title></rect>
|
||||
<rect x="126" y="92" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-06-07: 0 commits</title></rect>
|
||||
<rect x="138" y="20" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-06-08: 0 commits</title></rect>
|
||||
<rect x="138" y="32" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-06-09: 0 commits</title></rect>
|
||||
<rect x="138" y="44" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-06-10: 0 commits</title></rect>
|
||||
<rect x="138" y="56" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-06-11: 0 commits</title></rect>
|
||||
<rect x="138" y="68" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-06-12: 0 commits</title></rect>
|
||||
<rect x="138" y="80" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-06-13: 0 commits</title></rect>
|
||||
<rect x="138" y="92" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-06-14: 0 commits</title></rect>
|
||||
<rect x="150" y="20" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-06-15: 0 commits</title></rect>
|
||||
<rect x="150" y="32" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-06-16: 0 commits</title></rect>
|
||||
<rect x="150" y="44" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-06-17: 0 commits</title></rect>
|
||||
<rect x="150" y="56" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-06-18: 0 commits</title></rect>
|
||||
<rect x="150" y="68" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-06-19: 0 commits</title></rect>
|
||||
<rect x="150" y="80" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-06-20: 0 commits</title></rect>
|
||||
<rect x="150" y="92" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-06-21: 0 commits</title></rect>
|
||||
<rect x="162" y="20" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-06-22: 0 commits</title></rect>
|
||||
<rect x="162" y="32" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-06-23: 0 commits</title></rect>
|
||||
<rect x="162" y="44" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-06-24: 0 commits</title></rect>
|
||||
<rect x="162" y="56" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-06-25: 0 commits</title></rect>
|
||||
<rect x="162" y="68" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-06-26: 0 commits</title></rect>
|
||||
<rect x="162" y="80" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-06-27: 0 commits</title></rect>
|
||||
<rect x="162" y="92" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-06-28: 0 commits</title></rect>
|
||||
<rect x="174" y="20" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-06-29: 0 commits</title></rect>
|
||||
<rect x="174" y="32" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-06-30: 0 commits</title></rect>
|
||||
<rect x="174" y="44" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-07-01: 0 commits</title></rect>
|
||||
<rect x="174" y="56" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-07-02: 0 commits</title></rect>
|
||||
<rect x="174" y="68" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-07-03: 0 commits</title></rect>
|
||||
<rect x="174" y="80" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-07-04: 0 commits</title></rect>
|
||||
<rect x="174" y="92" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-07-05: 0 commits</title></rect>
|
||||
<rect x="186" y="20" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-07-06: 0 commits</title></rect>
|
||||
<rect x="186" y="32" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-07-07: 0 commits</title></rect>
|
||||
<rect x="186" y="44" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-07-08: 0 commits</title></rect>
|
||||
<rect x="186" y="56" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-07-09: 0 commits</title></rect>
|
||||
<rect x="186" y="68" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-07-10: 0 commits</title></rect>
|
||||
<rect x="186" y="80" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-07-11: 0 commits</title></rect>
|
||||
<rect x="186" y="92" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-07-12: 0 commits</title></rect>
|
||||
<rect x="198" y="20" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-07-13: 0 commits</title></rect>
|
||||
<rect x="198" y="32" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-07-14: 0 commits</title></rect>
|
||||
<rect x="198" y="44" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-07-15: 0 commits</title></rect>
|
||||
<rect x="198" y="56" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-07-16: 0 commits</title></rect>
|
||||
<rect x="198" y="68" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-07-17: 0 commits</title></rect>
|
||||
<rect x="198" y="80" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-07-18: 0 commits</title></rect>
|
||||
<rect x="198" y="92" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-07-19: 0 commits</title></rect>
|
||||
<rect x="210" y="20" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-07-20: 0 commits</title></rect>
|
||||
<rect x="210" y="32" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-07-21: 0 commits</title></rect>
|
||||
<rect x="210" y="44" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-07-22: 0 commits</title></rect>
|
||||
<rect x="210" y="56" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-07-23: 0 commits</title></rect>
|
||||
<rect x="210" y="68" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-07-24: 0 commits</title></rect>
|
||||
<rect x="210" y="80" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-07-25: 0 commits</title></rect>
|
||||
<rect x="210" y="92" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-07-26: 0 commits</title></rect>
|
||||
<rect x="222" y="20" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-07-27: 0 commits</title></rect>
|
||||
<rect x="222" y="32" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-07-28: 0 commits</title></rect>
|
||||
<rect x="222" y="44" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-07-29: 0 commits</title></rect>
|
||||
<rect x="222" y="56" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-07-30: 0 commits</title></rect>
|
||||
<rect x="222" y="68" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-07-31: 0 commits</title></rect>
|
||||
<rect x="222" y="80" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-08-01: 0 commits</title></rect>
|
||||
<rect x="222" y="92" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-08-02: 0 commits</title></rect>
|
||||
<rect x="234" y="20" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-08-03: 0 commits</title></rect>
|
||||
<rect x="234" y="32" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-08-04: 0 commits</title></rect>
|
||||
<rect x="234" y="44" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-08-05: 0 commits</title></rect>
|
||||
<rect x="234" y="56" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-08-06: 0 commits</title></rect>
|
||||
<rect x="234" y="68" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-08-07: 0 commits</title></rect>
|
||||
<rect x="234" y="80" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-08-08: 0 commits</title></rect>
|
||||
<rect x="234" y="92" width="10" height="10" rx="2" ry="2" fill="#9be9a8"><title>2025-08-09: 5 commits</title></rect>
|
||||
<rect x="246" y="20" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-08-10: 0 commits</title></rect>
|
||||
<rect x="246" y="32" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-08-11: 0 commits</title></rect>
|
||||
<rect x="246" y="44" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-08-12: 0 commits</title></rect>
|
||||
<rect x="246" y="56" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-08-13: 0 commits</title></rect>
|
||||
<rect x="246" y="68" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-08-14: 0 commits</title></rect>
|
||||
<rect x="246" y="80" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-08-15: 0 commits</title></rect>
|
||||
<rect x="246" y="92" width="10" height="10" rx="2" ry="2" fill="#9be9a8"><title>2025-08-16: 4 commits</title></rect>
|
||||
<rect x="258" y="20" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-08-17: 0 commits</title></rect>
|
||||
<rect x="258" y="32" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-08-18: 0 commits</title></rect>
|
||||
<rect x="258" y="44" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-08-19: 0 commits</title></rect>
|
||||
<rect x="258" y="56" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-08-20: 0 commits</title></rect>
|
||||
<rect x="258" y="68" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-08-21: 0 commits</title></rect>
|
||||
<rect x="258" y="80" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-08-22: 0 commits</title></rect>
|
||||
<rect x="258" y="92" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-08-23: 0 commits</title></rect>
|
||||
<rect x="270" y="20" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-08-24: 0 commits</title></rect>
|
||||
<rect x="270" y="32" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-08-25: 0 commits</title></rect>
|
||||
<rect x="270" y="44" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-08-26: 0 commits</title></rect>
|
||||
<rect x="270" y="56" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-08-27: 0 commits</title></rect>
|
||||
<rect x="270" y="68" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-08-28: 0 commits</title></rect>
|
||||
<rect x="270" y="80" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-08-29: 0 commits</title></rect>
|
||||
<rect x="270" y="92" width="10" height="10" rx="2" ry="2" fill="#9be9a8"><title>2025-08-30: 1 commit</title></rect>
|
||||
<rect x="282" y="20" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-08-31: 0 commits</title></rect>
|
||||
<rect x="282" y="32" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-09-01: 0 commits</title></rect>
|
||||
<rect x="282" y="44" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-09-02: 0 commits</title></rect>
|
||||
<rect x="282" y="56" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-09-03: 0 commits</title></rect>
|
||||
<rect x="282" y="68" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-09-04: 0 commits</title></rect>
|
||||
<rect x="282" y="80" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-09-05: 0 commits</title></rect>
|
||||
<rect x="282" y="92" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-09-06: 0 commits</title></rect>
|
||||
<rect x="294" y="20" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-09-07: 0 commits</title></rect>
|
||||
<rect x="294" y="32" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-09-08: 0 commits</title></rect>
|
||||
<rect x="294" y="44" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-09-09: 0 commits</title></rect>
|
||||
<rect x="294" y="56" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-09-10: 0 commits</title></rect>
|
||||
<rect x="294" y="68" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-09-11: 0 commits</title></rect>
|
||||
<rect x="294" y="80" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-09-12: 0 commits</title></rect>
|
||||
<rect x="294" y="92" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-09-13: 0 commits</title></rect>
|
||||
<rect x="306" y="20" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-09-14: 0 commits</title></rect>
|
||||
<rect x="306" y="32" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-09-15: 0 commits</title></rect>
|
||||
<rect x="306" y="44" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-09-16: 0 commits</title></rect>
|
||||
<rect x="306" y="56" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-09-17: 0 commits</title></rect>
|
||||
<rect x="306" y="68" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-09-18: 0 commits</title></rect>
|
||||
<rect x="306" y="80" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-09-19: 0 commits</title></rect>
|
||||
<rect x="306" y="92" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-09-20: 0 commits</title></rect>
|
||||
<rect x="318" y="20" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-09-21: 0 commits</title></rect>
|
||||
<rect x="318" y="32" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-09-22: 0 commits</title></rect>
|
||||
<rect x="318" y="44" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-09-23: 0 commits</title></rect>
|
||||
<rect x="318" y="56" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-09-24: 0 commits</title></rect>
|
||||
<rect x="318" y="68" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-09-25: 0 commits</title></rect>
|
||||
<rect x="318" y="80" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-09-26: 0 commits</title></rect>
|
||||
<rect x="318" y="92" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-09-27: 0 commits</title></rect>
|
||||
<rect x="330" y="20" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-09-28: 0 commits</title></rect>
|
||||
<rect x="330" y="32" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-09-29: 0 commits</title></rect>
|
||||
<rect x="330" y="44" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-09-30: 0 commits</title></rect>
|
||||
<rect x="330" y="56" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-10-01: 0 commits</title></rect>
|
||||
<rect x="330" y="68" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-10-02: 0 commits</title></rect>
|
||||
<rect x="330" y="80" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-10-03: 0 commits</title></rect>
|
||||
<rect x="330" y="92" width="10" height="10" rx="2" ry="2" fill="#9be9a8"><title>2025-10-04: 6 commits</title></rect>
|
||||
<rect x="342" y="20" width="10" height="10" rx="2" ry="2" fill="#9be9a8"><title>2025-10-05: 5 commits</title></rect>
|
||||
<rect x="342" y="32" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-10-06: 0 commits</title></rect>
|
||||
<rect x="342" y="44" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-10-07: 0 commits</title></rect>
|
||||
<rect x="342" y="56" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-10-08: 0 commits</title></rect>
|
||||
<rect x="342" y="68" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-10-09: 0 commits</title></rect>
|
||||
<rect x="342" y="80" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-10-10: 0 commits</title></rect>
|
||||
<rect x="342" y="92" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-10-11: 0 commits</title></rect>
|
||||
<rect x="354" y="20" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-10-12: 0 commits</title></rect>
|
||||
<rect x="354" y="32" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-10-13: 0 commits</title></rect>
|
||||
<rect x="354" y="44" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-10-14: 0 commits</title></rect>
|
||||
<rect x="354" y="56" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-10-15: 0 commits</title></rect>
|
||||
<rect x="354" y="68" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-10-16: 0 commits</title></rect>
|
||||
<rect x="354" y="80" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-10-17: 0 commits</title></rect>
|
||||
<rect x="354" y="92" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-10-18: 0 commits</title></rect>
|
||||
<rect x="366" y="20" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-10-19: 0 commits</title></rect>
|
||||
<rect x="366" y="32" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-10-20: 0 commits</title></rect>
|
||||
<rect x="366" y="44" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-10-21: 0 commits</title></rect>
|
||||
<rect x="366" y="56" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-10-22: 0 commits</title></rect>
|
||||
<rect x="366" y="68" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-10-23: 0 commits</title></rect>
|
||||
<rect x="366" y="80" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-10-24: 0 commits</title></rect>
|
||||
<rect x="366" y="92" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-10-25: 0 commits</title></rect>
|
||||
<rect x="378" y="20" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-10-26: 0 commits</title></rect>
|
||||
<rect x="378" y="32" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-10-27: 0 commits</title></rect>
|
||||
<rect x="378" y="44" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-10-28: 0 commits</title></rect>
|
||||
<rect x="378" y="56" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-10-29: 0 commits</title></rect>
|
||||
<rect x="378" y="68" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-10-30: 0 commits</title></rect>
|
||||
<rect x="378" y="80" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-10-31: 0 commits</title></rect>
|
||||
<rect x="378" y="92" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-11-01: 0 commits</title></rect>
|
||||
<rect x="390" y="20" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-11-02: 0 commits</title></rect>
|
||||
<rect x="390" y="32" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-11-03: 0 commits</title></rect>
|
||||
<rect x="390" y="44" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-11-04: 0 commits</title></rect>
|
||||
<rect x="390" y="56" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-11-05: 0 commits</title></rect>
|
||||
<rect x="390" y="68" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-11-06: 0 commits</title></rect>
|
||||
<rect x="390" y="80" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-11-07: 0 commits</title></rect>
|
||||
<rect x="390" y="92" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-11-08: 0 commits</title></rect>
|
||||
<rect x="402" y="20" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-11-09: 0 commits</title></rect>
|
||||
<rect x="402" y="32" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-11-10: 0 commits</title></rect>
|
||||
<rect x="402" y="44" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-11-11: 0 commits</title></rect>
|
||||
<rect x="402" y="56" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-11-12: 0 commits</title></rect>
|
||||
<rect x="402" y="68" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-11-13: 0 commits</title></rect>
|
||||
<rect x="402" y="80" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-11-14: 0 commits</title></rect>
|
||||
<rect x="402" y="92" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-11-15: 0 commits</title></rect>
|
||||
<rect x="414" y="20" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-11-16: 0 commits</title></rect>
|
||||
<rect x="414" y="32" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-11-17: 0 commits</title></rect>
|
||||
<rect x="414" y="44" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-11-18: 0 commits</title></rect>
|
||||
<rect x="414" y="56" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-11-19: 0 commits</title></rect>
|
||||
<rect x="414" y="68" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-11-20: 0 commits</title></rect>
|
||||
<rect x="414" y="80" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-11-21: 0 commits</title></rect>
|
||||
<rect x="414" y="92" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-11-22: 0 commits</title></rect>
|
||||
<rect x="426" y="20" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-11-23: 0 commits</title></rect>
|
||||
<rect x="426" y="32" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-11-24: 0 commits</title></rect>
|
||||
<rect x="426" y="44" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-11-25: 0 commits</title></rect>
|
||||
<rect x="426" y="56" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-11-26: 0 commits</title></rect>
|
||||
<rect x="426" y="68" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-11-27: 0 commits</title></rect>
|
||||
<rect x="426" y="80" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-11-28: 0 commits</title></rect>
|
||||
<rect x="426" y="92" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-11-29: 0 commits</title></rect>
|
||||
<rect x="438" y="20" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-11-30: 0 commits</title></rect>
|
||||
<rect x="438" y="32" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-12-01: 0 commits</title></rect>
|
||||
<rect x="438" y="44" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-12-02: 0 commits</title></rect>
|
||||
<rect x="438" y="56" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-12-03: 0 commits</title></rect>
|
||||
<rect x="438" y="68" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-12-04: 0 commits</title></rect>
|
||||
<rect x="438" y="80" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-12-05: 0 commits</title></rect>
|
||||
<rect x="438" y="92" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-12-06: 0 commits</title></rect>
|
||||
<rect x="450" y="20" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-12-07: 0 commits</title></rect>
|
||||
<rect x="450" y="32" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-12-08: 0 commits</title></rect>
|
||||
<rect x="450" y="44" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-12-09: 0 commits</title></rect>
|
||||
<rect x="450" y="56" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-12-10: 0 commits</title></rect>
|
||||
<rect x="450" y="68" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-12-11: 0 commits</title></rect>
|
||||
<rect x="450" y="80" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-12-12: 0 commits</title></rect>
|
||||
<rect x="450" y="92" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-12-13: 0 commits</title></rect>
|
||||
<rect x="462" y="20" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-12-14: 0 commits</title></rect>
|
||||
<rect x="462" y="32" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-12-15: 0 commits</title></rect>
|
||||
<rect x="462" y="44" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-12-16: 0 commits</title></rect>
|
||||
<rect x="462" y="56" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-12-17: 0 commits</title></rect>
|
||||
<rect x="462" y="68" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-12-18: 0 commits</title></rect>
|
||||
<rect x="462" y="80" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-12-19: 0 commits</title></rect>
|
||||
<rect x="462" y="92" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-12-20: 0 commits</title></rect>
|
||||
<rect x="474" y="20" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-12-21: 0 commits</title></rect>
|
||||
<rect x="474" y="32" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-12-22: 0 commits</title></rect>
|
||||
<rect x="474" y="44" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-12-23: 0 commits</title></rect>
|
||||
<rect x="474" y="56" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-12-24: 0 commits</title></rect>
|
||||
<rect x="474" y="68" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-12-25: 0 commits</title></rect>
|
||||
<rect x="474" y="80" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-12-26: 0 commits</title></rect>
|
||||
<rect x="474" y="92" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-12-27: 0 commits</title></rect>
|
||||
<rect x="486" y="20" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-12-28: 0 commits</title></rect>
|
||||
<rect x="486" y="32" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-12-29: 0 commits</title></rect>
|
||||
<rect x="486" y="44" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-12-30: 0 commits</title></rect>
|
||||
<rect x="486" y="56" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2025-12-31: 0 commits</title></rect>
|
||||
<rect x="486" y="68" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2026-01-01: 0 commits</title></rect>
|
||||
<rect x="486" y="80" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2026-01-02: 0 commits</title></rect>
|
||||
<rect x="486" y="92" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2026-01-03: 0 commits</title></rect>
|
||||
<rect x="498" y="20" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2026-01-04: 0 commits</title></rect>
|
||||
<rect x="498" y="32" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2026-01-05: 0 commits</title></rect>
|
||||
<rect x="498" y="44" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2026-01-06: 0 commits</title></rect>
|
||||
<rect x="498" y="56" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2026-01-07: 0 commits</title></rect>
|
||||
<rect x="498" y="68" width="10" height="10" rx="2" ry="2" fill="#9be9a8"><title>2026-01-08: 10 commits</title></rect>
|
||||
<rect x="498" y="80" width="10" height="10" rx="2" ry="2" fill="#9be9a8"><title>2026-01-09: 4 commits</title></rect>
|
||||
<rect x="498" y="92" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2026-01-10: 0 commits</title></rect>
|
||||
<rect x="510" y="20" width="10" height="10" rx="2" ry="2" fill="#9be9a8"><title>2026-01-11: 1 commit</title></rect>
|
||||
<rect x="510" y="32" width="10" height="10" rx="2" ry="2" fill="#9be9a8"><title>2026-01-12: 9 commits</title></rect>
|
||||
<rect x="510" y="44" width="10" height="10" rx="2" ry="2" fill="#9be9a8"><title>2026-01-13: 11 commits</title></rect>
|
||||
<rect x="510" y="56" width="10" height="10" rx="2" ry="2" fill="#40c463"><title>2026-01-14: 23 commits</title></rect>
|
||||
<rect x="510" y="68" width="10" height="10" rx="2" ry="2" fill="#9be9a8"><title>2026-01-15: 10 commits</title></rect>
|
||||
<rect x="510" y="80" width="10" height="10" rx="2" ry="2" fill="#9be9a8"><title>2026-01-16: 10 commits</title></rect>
|
||||
<rect x="510" y="92" width="10" height="10" rx="2" ry="2" fill="#9be9a8"><title>2026-01-17: 3 commits</title></rect>
|
||||
<rect x="522" y="20" width="10" height="10" rx="2" ry="2" fill="#40c463"><title>2026-01-18: 23 commits</title></rect>
|
||||
<rect x="522" y="32" width="10" height="10" rx="2" ry="2" fill="#9be9a8"><title>2026-01-19: 9 commits</title></rect>
|
||||
<rect x="522" y="44" width="10" height="10" rx="2" ry="2" fill="#40c463"><title>2026-01-20: 28 commits</title></rect>
|
||||
<rect x="522" y="56" width="10" height="10" rx="2" ry="2" fill="#9be9a8"><title>2026-01-21: 6 commits</title></rect>
|
||||
<rect x="522" y="68" width="10" height="10" rx="2" ry="2" fill="#40c463"><title>2026-01-22: 15 commits</title></rect>
|
||||
<rect x="522" y="80" width="10" height="10" rx="2" ry="2" fill="#40c463"><title>2026-01-23: 17 commits</title></rect>
|
||||
<rect x="522" y="92" width="10" height="10" rx="2" ry="2" fill="#9be9a8"><title>2026-01-24: 5 commits</title></rect>
|
||||
<rect x="534" y="20" width="10" height="10" rx="2" ry="2" fill="#40c463"><title>2026-01-25: 20 commits</title></rect>
|
||||
<rect x="534" y="32" width="10" height="10" rx="2" ry="2" fill="#216e39"><title>2026-01-26: 56 commits</title></rect>
|
||||
<rect x="534" y="44" width="10" height="10" rx="2" ry="2" fill="#40c463"><title>2026-01-27: 22 commits</title></rect>
|
||||
<rect x="534" y="56" width="10" height="10" rx="2" ry="2" fill="#40c463"><title>2026-01-28: 16 commits</title></rect>
|
||||
<rect x="534" y="68" width="10" height="10" rx="2" ry="2" fill="#40c463"><title>2026-01-29: 28 commits</title></rect>
|
||||
<rect x="534" y="80" width="10" height="10" rx="2" ry="2" fill="#40c463"><title>2026-01-30: 16 commits</title></rect>
|
||||
<rect x="534" y="92" width="10" height="10" rx="2" ry="2" fill="#30a14e"><title>2026-01-31: 31 commits</title></rect>
|
||||
<rect x="546" y="20" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2026-02-01: 0 commits</title></rect>
|
||||
<rect x="546" y="32" width="10" height="10" rx="2" ry="2" fill="#9be9a8"><title>2026-02-02: 2 commits</title></rect>
|
||||
<rect x="546" y="44" width="10" height="10" rx="2" ry="2" fill="#9be9a8"><title>2026-02-03: 1 commit</title></rect>
|
||||
<rect x="546" y="56" width="10" height="10" rx="2" ry="2" fill="#30a14e"><title>2026-02-04: 40 commits</title></rect>
|
||||
<rect x="546" y="68" width="10" height="10" rx="2" ry="2" fill="#9be9a8"><title>2026-02-05: 10 commits</title></rect>
|
||||
<rect x="546" y="80" width="10" height="10" rx="2" ry="2" fill="#9be9a8"><title>2026-02-06: 8 commits</title></rect>
|
||||
<rect x="546" y="92" width="10" height="10" rx="2" ry="2" fill="#9be9a8"><title>2026-02-07: 1 commit</title></rect>
|
||||
<rect x="558" y="20" width="10" height="10" rx="2" ry="2" fill="#9be9a8"><title>2026-02-08: 6 commits</title></rect>
|
||||
<rect x="558" y="32" width="10" height="10" rx="2" ry="2" fill="#9be9a8"><title>2026-02-09: 2 commits</title></rect>
|
||||
<rect x="558" y="44" width="10" height="10" rx="2" ry="2" fill="#40c463"><title>2026-02-10: 27 commits</title></rect>
|
||||
<rect x="558" y="56" width="10" height="10" rx="2" ry="2" fill="#9be9a8"><title>2026-02-11: 6 commits</title></rect>
|
||||
<rect x="558" y="68" width="10" height="10" rx="2" ry="2" fill="#9be9a8"><title>2026-02-12: 10 commits</title></rect>
|
||||
<rect x="558" y="80" width="10" height="10" rx="2" ry="2" fill="#9be9a8"><title>2026-02-13: 2 commits</title></rect>
|
||||
<rect x="558" y="92" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2026-02-14: 0 commits</title></rect>
|
||||
<rect x="570" y="20" width="10" height="10" rx="2" ry="2" fill="#9be9a8"><title>2026-02-15: 1 commit</title></rect>
|
||||
<rect x="570" y="32" width="10" height="10" rx="2" ry="2" fill="#9be9a8"><title>2026-02-16: 1 commit</title></rect>
|
||||
<rect x="570" y="44" width="10" height="10" rx="2" ry="2" fill="#9be9a8"><title>2026-02-17: 3 commits</title></rect>
|
||||
<rect x="570" y="56" width="10" height="10" rx="2" ry="2" fill="#9be9a8"><title>2026-02-18: 1 commit</title></rect>
|
||||
<rect x="570" y="68" width="10" height="10" rx="2" ry="2" fill="#9be9a8"><title>2026-02-19: 4 commits</title></rect>
|
||||
<rect x="570" y="80" width="10" height="10" rx="2" ry="2" fill="#9be9a8"><title>2026-02-20: 4 commits</title></rect>
|
||||
<rect x="570" y="92" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2026-02-21: 0 commits</title></rect>
|
||||
<rect x="582" y="20" width="10" height="10" rx="2" ry="2" fill="#9be9a8"><title>2026-02-22: 1 commit</title></rect>
|
||||
<rect x="582" y="32" width="10" height="10" rx="2" ry="2" fill="#9be9a8"><title>2026-02-23: 2 commits</title></rect>
|
||||
<rect x="582" y="44" width="10" height="10" rx="2" ry="2" fill="#9be9a8"><title>2026-02-24: 4 commits</title></rect>
|
||||
<rect x="582" y="56" width="10" height="10" rx="2" ry="2" fill="#9be9a8"><title>2026-02-25: 5 commits</title></rect>
|
||||
<rect x="582" y="68" width="10" height="10" rx="2" ry="2" fill="#9be9a8"><title>2026-02-26: 2 commits</title></rect>
|
||||
<rect x="582" y="80" width="10" height="10" rx="2" ry="2" fill="#9be9a8"><title>2026-02-27: 9 commits</title></rect>
|
||||
<rect x="582" y="92" width="10" height="10" rx="2" ry="2" fill="#40c463"><title>2026-02-28: 19 commits</title></rect>
|
||||
<rect x="594" y="20" width="10" height="10" rx="2" ry="2" fill="#9be9a8"><title>2026-03-01: 9 commits</title></rect>
|
||||
<rect x="594" y="32" width="10" height="10" rx="2" ry="2" fill="#9be9a8"><title>2026-03-02: 10 commits</title></rect>
|
||||
<rect x="594" y="44" width="10" height="10" rx="2" ry="2" fill="#9be9a8"><title>2026-03-03: 2 commits</title></rect>
|
||||
<rect x="594" y="56" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2026-03-04: 0 commits</title></rect>
|
||||
<rect x="594" y="68" width="10" height="10" rx="2" ry="2" fill="#9be9a8"><title>2026-03-05: 14 commits</title></rect>
|
||||
<rect x="594" y="80" width="10" height="10" rx="2" ry="2" fill="#30a14e"><title>2026-03-06: 29 commits</title></rect>
|
||||
<rect x="594" y="92" width="10" height="10" rx="2" ry="2" fill="#9be9a8"><title>2026-03-07: 10 commits</title></rect>
|
||||
<rect x="606" y="20" width="10" height="10" rx="2" ry="2" fill="#40c463"><title>2026-03-08: 19 commits</title></rect>
|
||||
<rect x="606" y="32" width="10" height="10" rx="2" ry="2" fill="#9be9a8"><title>2026-03-09: 2 commits</title></rect>
|
||||
<rect x="606" y="44" width="10" height="10" rx="2" ry="2" fill="#40c463"><title>2026-03-10: 20 commits</title></rect>
|
||||
<rect x="606" y="56" width="10" height="10" rx="2" ry="2" fill="#40c463"><title>2026-03-11: 27 commits</title></rect>
|
||||
<rect x="606" y="68" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2026-03-12: 0 commits</title></rect>
|
||||
<rect x="606" y="80" width="10" height="10" rx="2" ry="2" fill="#30a14e"><title>2026-03-13: 37 commits</title></rect>
|
||||
<rect x="606" y="92" width="10" height="10" rx="2" ry="2" fill="#216e39"><title>2026-03-14: 49 commits</title></rect>
|
||||
<rect x="618" y="20" width="10" height="10" rx="2" ry="2" fill="#9be9a8"><title>2026-03-15: 9 commits</title></rect>
|
||||
<rect x="618" y="32" width="10" height="10" rx="2" ry="2" fill="#40c463"><title>2026-03-16: 17 commits</title></rect>
|
||||
<rect x="618" y="44" width="10" height="10" rx="2" ry="2" fill="#40c463"><title>2026-03-17: 21 commits</title></rect>
|
||||
<rect x="618" y="56" width="10" height="10" rx="2" ry="2" fill="#9be9a8"><title>2026-03-18: 14 commits</title></rect>
|
||||
<rect x="618" y="68" width="10" height="10" rx="2" ry="2" fill="#9be9a8"><title>2026-03-19: 10 commits</title></rect>
|
||||
<rect x="618" y="80" width="10" height="10" rx="2" ry="2" fill="#40c463"><title>2026-03-20: 16 commits</title></rect>
|
||||
<rect x="618" y="92" width="10" height="10" rx="2" ry="2" fill="#9be9a8"><title>2026-03-21: 7 commits</title></rect>
|
||||
<rect x="630" y="20" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2026-03-22: 0 commits</title></rect>
|
||||
<rect x="630" y="32" width="10" height="10" rx="2" ry="2" fill="#9be9a8"><title>2026-03-23: 1 commit</title></rect>
|
||||
<rect x="630" y="44" width="10" height="10" rx="2" ry="2" fill="#40c463"><title>2026-03-24: 19 commits</title></rect>
|
||||
<rect x="630" y="56" width="10" height="10" rx="2" ry="2" fill="#9be9a8"><title>2026-03-25: 9 commits</title></rect>
|
||||
<rect x="630" y="68" width="10" height="10" rx="2" ry="2" fill="#9be9a8"><title>2026-03-26: 7 commits</title></rect>
|
||||
<rect x="630" y="80" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2026-03-27: 0 commits</title></rect>
|
||||
<rect x="630" y="92" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2026-03-28: 0 commits</title></rect>
|
||||
<rect x="642" y="20" width="10" height="10" rx="2" ry="2" fill="#9be9a8"><title>2026-03-29: 2 commits</title></rect>
|
||||
<rect x="642" y="32" width="10" height="10" rx="2" ry="2" fill="#9be9a8"><title>2026-03-30: 9 commits</title></rect>
|
||||
<rect x="642" y="44" width="10" height="10" rx="2" ry="2" fill="#9be9a8"><title>2026-03-31: 6 commits</title></rect>
|
||||
<rect x="642" y="56" width="10" height="10" rx="2" ry="2" fill="#9be9a8"><title>2026-04-01: 1 commit</title></rect>
|
||||
<rect x="642" y="68" width="10" height="10" rx="2" ry="2" fill="#9be9a8"><title>2026-04-02: 10 commits</title></rect>
|
||||
<rect x="642" y="80" width="10" height="10" rx="2" ry="2" fill="#9be9a8"><title>2026-04-03: 9 commits</title></rect>
|
||||
<rect x="642" y="92" width="10" height="10" rx="2" ry="2" fill="#40c463"><title>2026-04-04: 24 commits</title></rect>
|
||||
<rect x="654" y="20" width="10" height="10" rx="2" ry="2" fill="#40c463"><title>2026-04-05: 22 commits</title></rect>
|
||||
<rect x="654" y="32" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2026-04-06: 0 commits</title></rect>
|
||||
<rect x="654" y="44" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2026-04-07: 0 commits</title></rect>
|
||||
<rect x="654" y="56" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2026-04-08: 0 commits</title></rect>
|
||||
<rect x="654" y="68" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2026-04-09: 0 commits</title></rect>
|
||||
<rect x="654" y="80" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2026-04-10: 0 commits</title></rect>
|
||||
<rect x="654" y="92" width="10" height="10" rx="2" ry="2" fill="#ebedf0"><title>2026-04-11: 0 commits</title></rect>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 43 KiB |
BIN
scripts/__pycache__/generate_heatmap_svg.cpython-314.pyc
Normal file
BIN
scripts/__pycache__/generate_heatmap_svg.cpython-314.pyc
Normal file
Binary file not shown.
160
scripts/generate_heatmap_svg.py
Normal file
160
scripts/generate_heatmap_svg.py
Normal file
@@ -0,0 +1,160 @@
|
||||
#!/usr/bin/env python3
|
||||
import json
|
||||
import math
|
||||
import sys
|
||||
from datetime import datetime, timedelta
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
COLORS = [
|
||||
"#ebedf0",
|
||||
"#9be9a8",
|
||||
"#40c463",
|
||||
"#30a14e",
|
||||
"#216e39",
|
||||
]
|
||||
|
||||
CELL = 12
|
||||
GAP = 2
|
||||
RECT = CELL - GAP
|
||||
LEFT_PAD = 30
|
||||
TOP_PAD = 20
|
||||
RIGHT_PAD = 10
|
||||
BOTTOM_PAD = 10
|
||||
FONT_FAMILY = "-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif"
|
||||
LABEL_COLOR = "#57606a"
|
||||
|
||||
|
||||
def load_heatmap(path):
|
||||
with path.open() as handle:
|
||||
return json.load(handle)
|
||||
|
||||
|
||||
def date_range(start, end):
|
||||
current = start
|
||||
while current <= end:
|
||||
yield current
|
||||
current += timedelta(days=1)
|
||||
|
||||
|
||||
def previous_sunday(day):
|
||||
return day - timedelta(days=(day.weekday() + 1) % 7)
|
||||
|
||||
|
||||
def next_saturday(day):
|
||||
return day + timedelta(days=(5 - day.weekday()) % 7)
|
||||
|
||||
|
||||
def intensity(count, max_count):
|
||||
if count <= 0 or max_count <= 0:
|
||||
return 0
|
||||
return max(1, min(4, math.ceil((count / max_count) * 4)))
|
||||
|
||||
|
||||
def weekday_row(day):
|
||||
return (day.weekday() + 1) % 7
|
||||
|
||||
|
||||
def month_labels(grid_start, visible_start, grid_end):
|
||||
labels = []
|
||||
total_weeks = ((grid_end - grid_start).days // 7) + 1
|
||||
|
||||
for week in range(total_weeks):
|
||||
week_start = grid_start + timedelta(days=week * 7)
|
||||
week_label = None
|
||||
|
||||
for offset in range(7):
|
||||
day = week_start + timedelta(days=offset)
|
||||
if day < visible_start:
|
||||
continue
|
||||
|
||||
if week == 0 and week_label is None:
|
||||
week_label = day.strftime("%b")
|
||||
|
||||
if day.day == 1:
|
||||
week_label = day.strftime("%b")
|
||||
break
|
||||
|
||||
if week_label is not None:
|
||||
if not labels or labels[-1][1] != week_label:
|
||||
labels.append((week, week_label))
|
||||
|
||||
return labels
|
||||
|
||||
|
||||
def build_rect(day, start, counts, max_count):
|
||||
date_str = day.isoformat()
|
||||
count = counts.get(date_str, 0)
|
||||
level = intensity(count, max_count)
|
||||
x = LEFT_PAD + (((day - start).days // 7) * CELL)
|
||||
y = TOP_PAD + (weekday_row(day) * CELL)
|
||||
|
||||
commit_label = "commit" if count == 1 else "commits"
|
||||
|
||||
return (
|
||||
f'<rect x="{x}" y="{y}" width="{RECT}" height="{RECT}" rx="2" ry="2" '
|
||||
f'fill="{COLORS[level]}">'
|
||||
f"<title>{date_str}: {count} {commit_label}</title>"
|
||||
"</rect>"
|
||||
)
|
||||
|
||||
|
||||
def generate_svg(data):
|
||||
counts = {entry["date"]: entry["count"] for entry in data["days"]}
|
||||
max_count = data["max_daily_commits"]
|
||||
|
||||
start = datetime.strptime(data["from_date"], "%Y-%m-%d").date()
|
||||
end = datetime.strptime(data["to_date"], "%Y-%m-%d").date()
|
||||
aligned_start = previous_sunday(start)
|
||||
aligned_end = next_saturday(end)
|
||||
weeks = ((aligned_end - aligned_start).days // 7) + 1
|
||||
|
||||
width = LEFT_PAD + (weeks * CELL) + RIGHT_PAD
|
||||
height = TOP_PAD + (7 * CELL) + BOTTOM_PAD
|
||||
|
||||
svg = [
|
||||
f'<svg width="{width}" height="{height}" viewBox="0 0 {width} {height}" '
|
||||
'xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Commit activity heatmap">',
|
||||
'<style>',
|
||||
f'text {{ font: 10px {FONT_FAMILY}; fill: {LABEL_COLOR}; }}',
|
||||
'</style>',
|
||||
]
|
||||
|
||||
for week, label in month_labels(aligned_start, start, aligned_end):
|
||||
x = LEFT_PAD + (week * CELL)
|
||||
svg.append(f'<text x="{x}" y="10">{label}</text>')
|
||||
|
||||
for label, row in (("Mon", 1), ("Wed", 3), ("Fri", 5)):
|
||||
y = TOP_PAD + (row * CELL) + 8
|
||||
svg.append(f'<text x="0" y="{y}">{label}</text>')
|
||||
|
||||
for day in date_range(aligned_start, aligned_end):
|
||||
svg.append(build_rect(day, aligned_start, counts, max_count))
|
||||
|
||||
svg.append("</svg>")
|
||||
return "\n".join(svg) + "\n"
|
||||
|
||||
|
||||
def main():
|
||||
if len(sys.argv) not in {2, 3}:
|
||||
print(
|
||||
"Usage: generate_heatmap_svg.py <heatmap.json> [output.svg]",
|
||||
file=sys.stderr,
|
||||
)
|
||||
return 1
|
||||
|
||||
input_path = Path(sys.argv[1])
|
||||
output = generate_svg(load_heatmap(input_path))
|
||||
|
||||
if len(sys.argv) == 3:
|
||||
output_path = Path(sys.argv[2])
|
||||
output_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
output_path.write_text(output)
|
||||
else:
|
||||
sys.stdout.write(output)
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
Reference in New Issue
Block a user