<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>familytree, branch HEAD</title>
<subtitle>A self-hosted family tree builder.
</subtitle>
<entry>
<id>b97eb09cb6e877a6b6c70af71779b5ac344c6a2c</id>
<published>2026-05-10T12:52:40Z</published>
<updated>2026-05-10T12:52:40Z</updated>
<title>Move emoji to favicon, remove from tab title</title>
<link rel="alternate" type="text/html" href="commit/b97eb09cb6e877a6b6c70af71779b5ac344c6a2c.html" />
<author>
<name>Julian Piribauer</name>
<email>julian.piribauer@gmail.com</email>
</author>
<content>commit b97eb09cb6e877a6b6c70af71779b5ac344c6a2c
parent 0feedea0dbc1bb5476df290b80b4c602322d3f68
Author: Julian Piribauer &lt;julian.piribauer@gmail.com&gt;
Date:   Sun, 10 May 2026 12:52:40 +0000

Move emoji to favicon, remove from tab title

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;

</content>
</entry>
<entry>
<id>0feedea0dbc1bb5476df290b80b4c602322d3f68</id>
<published>2026-05-09T19:15:48Z</published>
<updated>2026-05-09T19:15:48Z</updated>
<title>Replace surname placeholder with generic example</title>
<link rel="alternate" type="text/html" href="commit/0feedea0dbc1bb5476df290b80b4c602322d3f68.html" />
<author>
<name>Julian Piribauer</name>
<email>julian.piribauer@gmail.com</email>
</author>
<content>commit 0feedea0dbc1bb5476df290b80b4c602322d3f68
parent 195872da94b7dedf92db23c033c95203ffd327a3
Author: Julian Piribauer &lt;julian.piribauer@gmail.com&gt;
Date:   Sat,  9 May 2026 19:15:48 +0000

Replace surname placeholder with generic example

&#39;e.g. Piribauer family&#39; → &#39;e.g. Smith family&#39; / &#39;z.B. Familie Müller&#39;

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;

</content>
</entry>
<entry>
<id>195872da94b7dedf92db23c033c95203ffd327a3</id>
<published>2026-05-09T19:09:00Z</published>
<updated>2026-05-09T19:09:00Z</updated>
<title>Change date format to DD.MM.YYYY throughout</title>
<link rel="alternate" type="text/html" href="commit/195872da94b7dedf92db23c033c95203ffd327a3.html" />
<author>
<name>Julian Piribauer</name>
<email>julian.piribauer@gmail.com</email>
</author>
<content>commit 195872da94b7dedf92db23c033c95203ffd327a3
parent 2f4b142a5dc706091df105ba54e243c99c300247
Author: Julian Piribauer &lt;julian.piribauer@gmail.com&gt;
Date:   Sat,  9 May 2026 19:09:00 +0000

Change date format to DD.MM.YYYY throughout

- Input placeholders updated in index.html
- formatDateRange now reads year from the last 4 chars (was first 4)
- All 11 existing birth_dates in the DB migrated from YYYY-MM-DD
  (and one YYYY.MM.DD outlier) to DD.MM.YYYY

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;

</content>
</entry>
<entry>
<id>2f4b142a5dc706091df105ba54e243c99c300247</id>
<published>2026-05-09T19:02:46Z</published>
<updated>2026-05-09T19:02:46Z</updated>
<title>Fix generation misalignment when one side of a partnership has more ancestors</title>
<link rel="alternate" type="text/html" href="commit/2f4b142a5dc706091df105ba54e243c99c300247.html" />
<author>
<name>Julian Piribauer</name>
<email>julian.piribauer@gmail.com</email>
</author>
<content>commit 2f4b142a5dc706091df105ba54e243c99c300247
parent 2358b8078b8d5c9da860df5ec6d18f27345b5815
Author: Julian Piribauer &lt;julian.piribauer@gmail.com&gt;
Date:   Sat,  9 May 2026 19:02:46 +0000

Fix generation misalignment when one side of a partnership has more ancestors

Three changes to the generation-ranking fix loop:
- Partner alignment now also handles the case where both partners are
  children (had been skipped), pushing the lower one down to max
- New step: pull parents down so they sit exactly one row above their
  children (prevents Ferdinand/Christine sitting 3 rows above Julian
  when Martin was pushed to gen 2 by his partnership with Silke)
- Together these ensure adding Mutter/Vater von Omi above Ingeborg no
  longer cascades incorrectly through the Piribauer side

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;

</content>
</entry>
<entry>
<id>2358b8078b8d5c9da860df5ec6d18f27345b5815</id>
<published>2026-05-09T18:49:11Z</published>
<updated>2026-05-09T18:49:11Z</updated>
<title>Prevent cyclic parent links from breaking the tree layout</title>
<link rel="alternate" type="text/html" href="commit/2358b8078b8d5c9da860df5ec6d18f27345b5815.html" />
<author>
<name>Julian Piribauer</name>
<email>julian.piribauer@gmail.com</email>
</author>
<content>commit 2358b8078b8d5c9da860df5ec6d18f27345b5815
parent 9272e3917019c24464776878c720a8107cd687fc
Author: Julian Piribauer &lt;julian.piribauer@gmail.com&gt;
Date:   Sat,  9 May 2026 18:49:11 +0000

Prevent cyclic parent links from breaking the tree layout

- Frontend: buildAcyclicParentLinks() does incremental BFS cycle
  detection before layout, skipping any link that would make a child
  an ancestor of its own parent
- Backend: add_parent_link rejects cycles with HTTP 422 before insert
- Deleted bad DB link (id=15) that caused Ingeborg&#39;s generation to
  reach ~40 and y-positions to exceed 10 000 px

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;

</content>
</entry>
<entry>
<id>9272e3917019c24464776878c720a8107cd687fc</id>
<published>2026-05-09T18:36:18Z</published>
<updated>2026-05-09T18:36:18Z</updated>
<title>PDF: open as blob URL (no print dialog); fix connector proportions; 🌳 tab icon</title>
<link rel="alternate" type="text/html" href="commit/9272e3917019c24464776878c720a8107cd687fc.html" />
<author>
<name>Julian Piribauer</name>
<email>julian.piribauer@gmail.com</email>
</author>
<content>commit 9272e3917019c24464776878c720a8107cd687fc
parent e88bfa7864ba208f2939e6b2bc9ddea7bec43def
Author: Julian Piribauer &lt;julian.piribauer@gmail.com&gt;
Date:   Sat,  9 May 2026 18:36:18 +0000

PDF: open as blob URL (no print dialog); fix connector proportions; 🌳 tab icon

- Replace window.print() with Blob URL opened in new tab — no print dialog
- dropY now 35% of the way between box bottom and nearest child, scales with GY
- Drop line starts from midY+5 so it visually connects to the partnership dot
- Add 🌳 emoji to browser tab title

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;

</content>
</entry>
<entry>
<id>e88bfa7864ba208f2939e6b2bc9ddea7bec43def</id>
<published>2026-05-09T18:18:02Z</published>
<updated>2026-05-09T18:18:02Z</updated>
<title>PDF: landscape, no browser headers/footers, Stammbaum title, fix connector overlap</title>
<link rel="alternate" type="text/html" href="commit/e88bfa7864ba208f2939e6b2bc9ddea7bec43def.html" />
<author>
<name>Julian Piribauer</name>
<email>julian.piribauer@gmail.com</email>
</author>
<content>commit e88bfa7864ba208f2939e6b2bc9ddea7bec43def
parent 8817fa61e397b9d30b036151ae561e4bec2923b2
Author: Julian Piribauer &lt;julian.piribauer@gmail.com&gt;
Date:   Sat,  9 May 2026 18:18:02 +0000

PDF: landscape, no browser headers/footers, Stammbaum title, fix connector overlap

- Switch to landscape orientation with zero page margins (suppresses browser print headers/footers)
- Title hardcoded to &#39;Stammbaum&#39;
- Increase generation gap GY 188→280 and node height NH 115→130 for more breathing room
- Fix connector dropY: was midY+50 which landed inside the box (NH/2+50=107 &lt; NH=115);
  now anchored at box bottom + 30px so the horizontal sibling bar always clears the parent box

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;

</content>
</entry>
<entry>
<id>8817fa61e397b9d30b036151ae561e4bec2923b2</id>
<published>2026-05-09T18:07:57Z</published>
<updated>2026-05-09T18:07:57Z</updated>
<title>Remove debug-headers endpoint; sync nginx config with name header</title>
<link rel="alternate" type="text/html" href="commit/8817fa61e397b9d30b036151ae561e4bec2923b2.html" />
<author>
<name>Julian Piribauer</name>
<email>julian.piribauer@gmail.com</email>
</author>
<content>commit 8817fa61e397b9d30b036151ae561e4bec2923b2
parent 657b4c037cb309f947a8083d7572de1b743fca5a
Author: Julian Piribauer &lt;julian.piribauer@gmail.com&gt;
Date:   Sat,  9 May 2026 18:07:57 +0000

Remove debug-headers endpoint; sync nginx config with name header

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;

</content>
</entry>
<entry>
<id>657b4c037cb309f947a8083d7572de1b743fca5a</id>
<published>2026-05-09T17:58:57Z</published>
<updated>2026-05-09T17:58:57Z</updated>
<title>Add cycle safeguard to generation-ranking loop</title>
<link rel="alternate" type="text/html" href="commit/657b4c037cb309f947a8083d7572de1b743fca5a.html" />
<author>
<name>Julian Piribauer</name>
<email>julian.piribauer@gmail.com</email>
</author>
<content>commit 657b4c037cb309f947a8083d7572de1b743fca5a
parent 17cd600fd4e17eb1ab2cc0d01dbd288507d46357
Author: Julian Piribauer &lt;julian.piribauer@gmail.com&gt;
Date:   Sat,  9 May 2026 17:58:57 +0000

Add cycle safeguard to generation-ranking loop

Bounds the while(changed) iteration to people.length * 4 to prevent
an infinite loop if parent links contain a cycle (e.g. bad data entry
where a grandparent was accidentally marked as a child).

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;

</content>
</entry>
<entry>
<id>17cd600fd4e17eb1ab2cc0d01dbd288507d46357</id>
<published>2026-05-09T17:49:50Z</published>
<updated>2026-05-09T17:49:50Z</updated>
<title>Show Authentik display name instead of userid throughout</title>
<link rel="alternate" type="text/html" href="commit/17cd600fd4e17eb1ab2cc0d01dbd288507d46357.html" />
<author>
<name>Julian Piribauer</name>
<email>julian.piribauer@gmail.com</email>
</author>
<content>commit 17cd600fd4e17eb1ab2cc0d01dbd288507d46357
parent 8f244e00bf1eaf2ae4ea20490d95c1ce69a8428c
Author: Julian Piribauer &lt;julian.piribauer@gmail.com&gt;
Date:   Sat,  9 May 2026 17:49:50 +0000

Show Authentik display name instead of userid throughout

- Add UserProfile table to store username → display_name mapping
- Upsert display name on every /api/me call from X-Authentik-Name header
- Return display_name from /api/me and member listing endpoints
- Update nginx to forward X-Authentik-Name header from Authentik
- Frontend: topbar and member modal now show display name (falls back to userid if not set)

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;

</content>
</entry>
<entry>
<id>8f244e00bf1eaf2ae4ea20490d95c1ce69a8428c</id>
<published>2026-05-09T17:43:37Z</published>
<updated>2026-05-09T17:43:37Z</updated>
<title>Add username-based member invite, PDF export, and layout crossing fix</title>
<link rel="alternate" type="text/html" href="commit/8f244e00bf1eaf2ae4ea20490d95c1ce69a8428c.html" />
<author>
<name>Julian Piribauer</name>
<email>julian.piribauer@gmail.com</email>
</author>
<content>commit 8f244e00bf1eaf2ae4ea20490d95c1ce69a8428c
parent aabd5cd68a20bbd86d33254f4ddcb835b26ca3d9
Author: Julian Piribauer &lt;julian.piribauer@gmail.com&gt;
Date:   Sat,  9 May 2026 17:43:37 +0000

Add username-based member invite, PDF export, and layout crossing fix

- Replace email-based invite with direct username lookup (POST /api/trees/{id}/members)
- Add Download PDF button: renders full tree at print resolution with all person data
- Fix Sugiyama upward-sweep comparator: slot tiebreaker fires first for shared children to eliminate crossing edges
- Update README to reflect username-based sharing and PDF export

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;

</content>
</entry>
<entry>
<id>aabd5cd68a20bbd86d33254f4ddcb835b26ca3d9</id>
<published>2026-05-03T12:10:47Z</published>
<updated>2026-05-03T12:10:47Z</updated>
<title>Add no-cache to HTML response; add onerror banner to surface JS errors</title>
<link rel="alternate" type="text/html" href="commit/aabd5cd68a20bbd86d33254f4ddcb835b26ca3d9.html" />
<author>
<name>Julian Piribauer</name>
<email>julian.piribauer@gmail.com</email>
</author>
<content>commit aabd5cd68a20bbd86d33254f4ddcb835b26ca3d9
parent b27a5588d8aaf7123d4ffe4ee31331149c46066e
Author: Julian Piribauer &lt;julian.piribauer@gmail.com&gt;
Date:   Sun,  3 May 2026 12:10:47 +0000

Add no-cache to HTML response; add onerror banner to surface JS errors

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;

</content>
</entry>
<entry>
<id>b27a5588d8aaf7123d4ffe4ee31331149c46066e</id>
<published>2026-05-03T12:07:34Z</published>
<updated>2026-05-03T12:07:34Z</updated>
<title>Self-host d3.v7.min.js instead of loading from CDN</title>
<link rel="alternate" type="text/html" href="commit/b27a5588d8aaf7123d4ffe4ee31331149c46066e.html" />
<author>
<name>Julian Piribauer</name>
<email>julian.piribauer@gmail.com</email>
</author>
<content>commit b27a5588d8aaf7123d4ffe4ee31331149c46066e
parent faf6508eeaa13508d68741d30f36adb6ee98df6f
Author: Julian Piribauer &lt;julian.piribauer@gmail.com&gt;
Date:   Sun,  3 May 2026 12:07:34 +0000

Self-host d3.v7.min.js instead of loading from CDN

Loading from d3js.org is a synchronous blocking script tag — if the CDN
is unreachable the browser waits forever and app.js never executes,
making the whole app silent with no errors.

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;

</content>
</entry>
<entry>
<id>faf6508eeaa13508d68741d30f36adb6ee98df6f</id>
<published>2026-05-03T07:23:55Z</published>
<updated>2026-05-03T07:23:55Z</updated>
<title>Auto-select tree on load: restore from localStorage or pick sole tree</title>
<link rel="alternate" type="text/html" href="commit/faf6508eeaa13508d68741d30f36adb6ee98df6f.html" />
<author>
<name>Julian Piribauer</name>
<email>julian.piribauer@gmail.com</email>
</author>
<content>commit faf6508eeaa13508d68741d30f36adb6ee98df6f
parent 345ea6317369fff896e757d675d346073423cf03
Author: Julian Piribauer &lt;julian.piribauer@gmail.com&gt;
Date:   Sun,  3 May 2026 07:23:55 +0000

Auto-select tree on load: restore from localStorage or pick sole tree

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;

</content>
</entry>
<entry>
<id>345ea6317369fff896e757d675d346073423cf03</id>
<published>2026-05-03T07:19:46Z</published>
<updated>2026-05-03T07:19:46Z</updated>
<title>Persist active tree across page loads via localStorage</title>
<link rel="alternate" type="text/html" href="commit/345ea6317369fff896e757d675d346073423cf03.html" />
<author>
<name>Julian Piribauer</name>
<email>julian.piribauer@gmail.com</email>
</author>
<content>commit 345ea6317369fff896e757d675d346073423cf03
parent 1c0a3b1b853e90caec16ff3bea24ac9bf88d1017
Author: Julian Piribauer &lt;julian.piribauer@gmail.com&gt;
Date:   Sun,  3 May 2026 07:19:46 +0000

Persist active tree across page loads via localStorage

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;

</content>
</entry>
<entry>
<id>1c0a3b1b853e90caec16ff3bea24ac9bf88d1017</id>
<published>2026-05-03T06:49:12Z</published>
<updated>2026-05-03T06:49:12Z</updated>
<title>Replace layout with bottom-up subtree width algorithm</title>
<link rel="alternate" type="text/html" href="commit/1c0a3b1b853e90caec16ff3bea24ac9bf88d1017.html" />
<author>
<name>Julian Piribauer</name>
<email>julian.piribauer@gmail.com</email>
</author>
<content>commit 1c0a3b1b853e90caec16ff3bea24ac9bf88d1017
parent 092b60117d8c44c4bcc4ee4083dbb1ff821a6114
Author: Julian Piribauer &lt;julian.piribauer@gmail.com&gt;
Date:   Sun,  3 May 2026 06:49:12 +0000

Replace layout with bottom-up subtree width algorithm

Throw out the top-down anchor approach that kept misaligning parent rows.
Instead: compute the minimum horizontal span for each group and all its
descendants (subtree width) from leaves upward, then assign X positions
top-down so every parent is exactly centered above its children by
construction. Connection lines adapt automatically since they read pos[].

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;

</content>
</entry>
<entry>
<id>092b60117d8c44c4bcc4ee4083dbb1ff821a6114</id>
<published>2026-05-03T06:43:03Z</published>
<updated>2026-05-03T06:43:03Z</updated>
<title>Fix sibling cluster centering under shared parents</title>
<link rel="alternate" type="text/html" href="commit/092b60117d8c44c4bcc4ee4083dbb1ff821a6114.html" />
<author>
<name>Julian Piribauer</name>
<email>julian.piribauer@gmail.com</email>
</author>
<content>commit 092b60117d8c44c4bcc4ee4083dbb1ff821a6114
parent 342025d2f6e345894003c0ef2b2d47caa01e2e2f
Author: Julian Piribauer &lt;julian.piribauer@gmail.com&gt;
Date:   Sun,  3 May 2026 06:43:03 +0000

Fix sibling cluster centering under shared parents

Each generation&#39;s groups are now clustered by shared parent before placement.
The whole sibling cluster is centered under the parent midpoint as a unit,
so multiple children of the same couple spread symmetrically rather than
being pushed rightward one-by-one by the overlap sweep.

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;

</content>
</entry>
<entry>
<id>342025d2f6e345894003c0ef2b2d47caa01e2e2f</id>
<published>2026-05-03T06:31:39Z</published>
<updated>2026-05-03T06:31:39Z</updated>
<title>Fix generation layout and parent-anchored horizontal placement</title>
<link rel="alternate" type="text/html" href="commit/342025d2f6e345894003c0ef2b2d47caa01e2e2f.html" />
<author>
<name>Julian Piribauer</name>
<email>julian.piribauer@gmail.com</email>
</author>
<content>commit 342025d2f6e345894003c0ef2b2d47caa01e2e2f
parent b50a48ef0e3097892d3efe7844a5b661fc6e4692
Author: Julian Piribauer &lt;julian.piribauer@gmail.com&gt;
Date:   Sun,  3 May 2026 06:31:39 +0000

Fix generation layout and parent-anchored horizontal placement

- Normalize API response parent_links → parentLinks in loadGraph
- Fix BFS: partners without parents now inherit their partner&#39;s generation;
  children are re-pushed down when parent generations change (combined loop)
- Replace per-row independent centering with parent-anchored X placement:
  each sibling group centers under its parents, left-to-right sweep resolves
  overlaps; unanchored rows (gen 0) still center at origin

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;

</content>
</entry>
<entry>
<id>b50a48ef0e3097892d3efe7844a5b661fc6e4692</id>
<published>2026-05-02T18:25:39Z</published>
<updated>2026-05-02T18:25:39Z</updated>
<title>Initial commit</title>
<link rel="alternate" type="text/html" href="commit/b50a48ef0e3097892d3efe7844a5b661fc6e4692.html" />
<author>
<name>Julian Piribauer</name>
<email>julian.piribauer@gmail.com</email>
</author>
<content>commit b50a48ef0e3097892d3efe7844a5b661fc6e4692
Author: Julian Piribauer &lt;julian.piribauer@gmail.com&gt;
Date:   Sat,  2 May 2026 18:25:39 +0000

Initial commit

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;

</content>
</entry>
</feed>
