Easy-to-manage touch screens
무료 오픈소스 터치스크린으로 USB 설정 가이드, 드래그‑드롭 편집기, 로컬 제어를 제공하며 Home Assistant용으로 제작되었습니다
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
Build and keep your family tree. Works in English and Urdu, on a phone or a
laptop, and is designed so that someone who is not comfortable with software can
still use it on their own.
A Next.js app, local-first with a Supabase database behind it. You sign in with
your phone number and a password, your families are kept in the browser as you
work and saved online a moment later, so they come back on any phone you sign in
on — and a cleared browser is no longer the end of them.README 전문 보기 ↗Build and keep your family tree. Works in English and Urdu, on a phone or a laptop, and is designed so that someone who is not comfortable with software can still use it on their own.
A Next.js app, local-first with a Supabase database behind it. You sign in with your phone number and a password, your families are kept in the browser as you work and saved online a moment later, so they come back on any phone you sign in on — and a cleared browser is no longer the end of them.
There is no sign-up. Somebody asks to be let in and gives their number, the owner creates the account and sends them a link and a password. Nothing is sent by SMS or email, so no messaging provider is needed and nothing costs anything per user. See Accounts.
npm install
npm run dev # http://localhost:3000
npm run build && npm start # production
Copy .env.local.example to .env.local and fill in the two
NEXT_PUBLIC_SUPABASE_* values to connect the database. Without them the app
still runs — it falls back to local-only, where a number is just a label again
and nothing is saved online. That is the same thing a dead network gets, on
purpose, so a bad connection never locks anybody out of their own tree.
There is no sign-up screen, no OTP and no SMS provider. An account exists because you made one:
npm run invite -- +923001234567 "Nani Amma" # create, print link + password
npm run invite -- +923001234567 --reset # send them a new password
It prints a link and a password to pass on however you like — WhatsApp, a text, or read down the phone. The link carries the number, so the person only has to type the password. Passwords are generated in three short groups with no lookalike characters, because they get dictated to people.
This works with no messaging provider because phone_confirm marks the number
confirmed on the grounds that you confirmed it, by talking to them. Supabase
never sends the person anything.
scripts/invite.mjs needs SUPABASE_SERVICE_ROLE_KEY in .env.local. That key
bypasses row level security; it has no NEXT_PUBLIC_ prefix, so Next.js never
puts it in the browser bundle. Keep it that way.
To take somebody's access away without deleting anything, set
family_accounts.is_active to false.
This part drove most of the design decisions, so they are worth spelling out:
| View | What it is for |
|---|---|
| Family | One person and their immediate family. The default, and the easiest. |
| Whole tree | The full chart — pan, zoom, collapse branches. |
| List | Every person, searchable. |
Choosing اردو sets lang and dir on the document, and the layout flips
right-to-left throughout — the back arrow, the tabs, the cards, the forms.
Urdu text is set in Noto Nastaliq Urdu with the extra leading Nastaliq needs.
Every person can carry two names, one in Latin script and one in Urdu. Whichever matches the current language is shown large, and the other is shown underneath, so a family with relatives who read only one of the two scripts still works.
The language switch sits in the header on every screen rather than inside Settings, and each option is written in its own script — someone who opens the app in a language they cannot read is still one tap from fixing it.
Two places, and that is deliberate.
The browser holds the copy you are working on, filed under your number, so the
app is instant, works with no signal, and can undo. A second or so after you stop
editing, each changed family is written to the family_trees table in Supabase.
The line under the family list says which of those has happened.
Signing in on a new phone pulls your families down. Row level security is what
keeps them yours: every policy is owner_id = auth.uid(), so the database itself
refuses to hand your trees to anyone else.
A sync never destroys a tree. When the two copies disagree, the one edited
more recently wins, and a family that only one side has is kept rather than
deleted — the same rule the backup import has always followed. The reasoning is
in lib/cloud.ts: for somebody whose only other copy is a file they have
probably never saved, a wrong deletion is unrecoverable and a duplicate is not.
Deleting a family on your device does delete it online; a family that merely went
missing is treated as one to restore.
Settings → Backup → Save a backup file still writes everything to one JSON file, and still works offline — it is the one copy that does not depend on anybody else's servers.
Off until you ask for it. Share on a family card gives a link that anyone can open, with no account, to read that family — they cannot change anything. Turn it off and the link stops working. Nothing else about you is on that page.
{
"version": 1,
"settings": { "locale": "en", "textScale": 1 },
"trees": [
{
"id": "t1a2b3c4",
"name": "The Khan Family",
"nameUr": "خان خاندان",
"rootId": "karim-khan",
"focusId": "karim-khan",
"people": [
{
"id": "karim-khan",
"name": "Karim Khan",
"nameUr": "کریم خان",
"gender": "m",
"birth": "1948",
"fatherId": null,
"motherId": null,
"spouseIds": ["ayesha-khan"],
"notes": "Free text."
}
]
}
]
}
Only id and name are required on a person. Dates are free text on purpose —
1952, c. 570 CE and 11 AH / 632 CE all work, and nothing tries to parse
them.
Imports are repaired rather than rejected: references to people who are not in the file are dropped, marriages are made to point both ways, duplicate ids are renamed, and any parent link that would make someone their own ancestor is removed.
"See an example" loads the lineage of Prophet Muhammad ﷺ — 85 people from ʿAdnan down to the beginnings of the sayyid and sharif houses. It sits alongside your own families and can be removed like any other.
The ascending chain from the Prophet ﷺ to ʿAdnan — 21 forefathers — is the portion the classical biographers agree on; Ibn Ishaq (through Ibn Hisham's Sira), Ibn Saʿd's Tabaqat and al-Tabari's Tarikh all transmit it identically. Ancestry above ʿAdnan, up to Ismaʿil ibn Ibrahim, is disputed and is deliberately left out — Ibn Ishaq himself stops there. Where the sources disagree with each other (Shahrbanu's identity, whether Maria al-Qibtiyya is counted among the wives), the note on that person says so.
Names carry an Urdu spelling alongside the Latin one, and titles are given in both languages. The longer historical notes are in English only.
Dates are approximate: pre-Hijra figures CE only, later ones AH/CE, and c.
marks anything the sources do not fix precisely.
Solid lines follow the paternal line. Each person appears exactly once, under their father where the father is in the chart and under their mother otherwise — which is what keeps a grandchild attached through their mother when the father married in from outside the family.
Dashed lines mark the other parent where both are in the chart. Spouses are not given cards of their own; they are listed on their partner's card and have full entries everywhere else. That is why the example draws 46 cards for 85 people.
app/
layout.tsx fonts, providers, document shell
page.tsx home - the list of families
settings/page.tsx language, text size, backup
tree/[id]/page.tsx one family, and the three views
globals.css theme tokens, type scale, RTL-safe base styles
components/
LocaleShell.tsx puts language and text size onto <html>
Header.tsx header bar and the language switch
FamilyView.tsx the default one-person-at-a-time view
ChartView.tsx the pan/zoom chart
ListView.tsx searchable list
PersonSheet.tsx one person: details and every action
PersonForm.tsx add and edit
ui.tsx buttons, fields, sheet, confirm, avatar
Toast.tsx one message at a time, with an undo action
lib/
types.ts Person, Tree, Settings
family.ts relationship rules, repair, attach
layout.ts chart shape and positioning
store.tsx state, device storage, undo, import/export
accounts.ts phone numbers: normalising, and which one is open
cloud.ts reading and writing trees in Supabase, and the merge rule
supabase.ts the one browser client
seed.ts the bundled example
scripts/
invite.mjs create an account and print its link and password
supabase/migrations/ the family_accounts and family_trees schema
lib/family.ts, lib/layout.ts, lib/accounts.ts and lib/cloud.ts are plain
functions with no React in them,
so the rules about how relatives hang together can be reasoned about — and
tested — on their own.
npm run invite -- <number> --reset.