@octo-cyber/kinship-calc 0.5.2

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.
Files changed (98) hide show
  1. package/.turbo/turbo-build.log +22 -0
  2. package/dist/controllers/family-tree.controller.d.ts +27 -0
  3. package/dist/controllers/family-tree.controller.d.ts.map +1 -0
  4. package/dist/controllers/family-tree.controller.js +88 -0
  5. package/dist/controllers/family-tree.controller.js.map +1 -0
  6. package/dist/controllers/kinship-calc.controller.d.ts +15 -0
  7. package/dist/controllers/kinship-calc.controller.d.ts.map +1 -0
  8. package/dist/controllers/kinship-calc.controller.js +45 -0
  9. package/dist/controllers/kinship-calc.controller.js.map +1 -0
  10. package/dist/engine/index.d.ts +7 -0
  11. package/dist/engine/index.d.ts.map +1 -0
  12. package/dist/engine/index.js +15 -0
  13. package/dist/engine/index.js.map +1 -0
  14. package/dist/engine/kinship-data.d.ts +31 -0
  15. package/dist/engine/kinship-data.d.ts.map +1 -0
  16. package/dist/engine/kinship-data.js +150 -0
  17. package/dist/engine/kinship-data.js.map +1 -0
  18. package/dist/engine/kinship-engine.d.ts +44 -0
  19. package/dist/engine/kinship-engine.d.ts.map +1 -0
  20. package/dist/engine/kinship-engine.js +184 -0
  21. package/dist/engine/kinship-engine.js.map +1 -0
  22. package/dist/engine/relation-path.d.ts +37 -0
  23. package/dist/engine/relation-path.d.ts.map +1 -0
  24. package/dist/engine/relation-path.js +60 -0
  25. package/dist/engine/relation-path.js.map +1 -0
  26. package/dist/entities/family-tree-person.entity.d.ts +12 -0
  27. package/dist/entities/family-tree-person.entity.d.ts.map +1 -0
  28. package/dist/entities/family-tree-person.entity.js +61 -0
  29. package/dist/entities/family-tree-person.entity.js.map +1 -0
  30. package/dist/entities/family-tree-relation.entity.d.ts +15 -0
  31. package/dist/entities/family-tree-relation.entity.d.ts.map +1 -0
  32. package/dist/entities/family-tree-relation.entity.js +58 -0
  33. package/dist/entities/family-tree-relation.entity.js.map +1 -0
  34. package/dist/entities/family-tree.entity.d.ts +9 -0
  35. package/dist/entities/family-tree.entity.d.ts.map +1 -0
  36. package/dist/entities/family-tree.entity.js +50 -0
  37. package/dist/entities/family-tree.entity.js.map +1 -0
  38. package/dist/entities/index.d.ts +12 -0
  39. package/dist/entities/index.d.ts.map +1 -0
  40. package/dist/entities/index.js +22 -0
  41. package/dist/entities/index.js.map +1 -0
  42. package/dist/entities/kinship-title.entity.d.ts +18 -0
  43. package/dist/entities/kinship-title.entity.d.ts.map +1 -0
  44. package/dist/entities/kinship-title.entity.js +59 -0
  45. package/dist/entities/kinship-title.entity.js.map +1 -0
  46. package/dist/index.d.ts +12 -0
  47. package/dist/index.d.ts.map +1 -0
  48. package/dist/index.js +33 -0
  49. package/dist/index.js.map +1 -0
  50. package/dist/kinship-calc.module.d.ts +9 -0
  51. package/dist/kinship-calc.module.d.ts.map +1 -0
  52. package/dist/kinship-calc.module.js +45 -0
  53. package/dist/kinship-calc.module.js.map +1 -0
  54. package/dist/schemas/kinship.schema.d.ts +129 -0
  55. package/dist/schemas/kinship.schema.d.ts.map +1 -0
  56. package/dist/schemas/kinship.schema.js +50 -0
  57. package/dist/schemas/kinship.schema.js.map +1 -0
  58. package/dist/services/family-tree.service.d.ts +38 -0
  59. package/dist/services/family-tree.service.d.ts.map +1 -0
  60. package/dist/services/family-tree.service.js +179 -0
  61. package/dist/services/family-tree.service.js.map +1 -0
  62. package/dist/services/kinship-calc.service.d.ts +26 -0
  63. package/dist/services/kinship-calc.service.d.ts.map +1 -0
  64. package/dist/services/kinship-calc.service.js +66 -0
  65. package/dist/services/kinship-calc.service.js.map +1 -0
  66. package/package.json +60 -0
  67. package/src/controllers/family-tree.controller.ts +102 -0
  68. package/src/controllers/kinship-calc.controller.ts +50 -0
  69. package/src/engine/index.ts +6 -0
  70. package/src/engine/kinship-data.ts +188 -0
  71. package/src/engine/kinship-engine.ts +230 -0
  72. package/src/engine/relation-path.ts +63 -0
  73. package/src/entities/family-tree-person.entity.ts +37 -0
  74. package/src/entities/family-tree-relation.entity.ts +36 -0
  75. package/src/entities/family-tree.entity.ts +28 -0
  76. package/src/entities/index.ts +18 -0
  77. package/src/entities/kinship-title.entity.ts +38 -0
  78. package/src/index.ts +33 -0
  79. package/src/kinship-calc.module.ts +51 -0
  80. package/src/schemas/kinship.schema.ts +70 -0
  81. package/src/services/family-tree.service.ts +211 -0
  82. package/src/services/kinship-calc.service.ts +68 -0
  83. package/tsconfig.build.json +4 -0
  84. package/tsconfig.json +10 -0
  85. package/web/components/FamilyTreeCanvas.tsx +177 -0
  86. package/web/components/FamilyTreeDialogs.tsx +275 -0
  87. package/web/components/KinshipResultCard.tsx +98 -0
  88. package/web/components/RegionSelector.tsx +32 -0
  89. package/web/components/RelationChainBuilder.tsx +104 -0
  90. package/web/index.ts +29 -0
  91. package/web/manifest.ts +24 -0
  92. package/web/messages/en-US.json +108 -0
  93. package/web/messages/zh-CN.json +108 -0
  94. package/web/pages/FamilyTreePage.tsx +240 -0
  95. package/web/pages/KinshipCalcPage.tsx +140 -0
  96. package/web/services/kinship-service.ts +140 -0
  97. package/web/stores/kinship-store.ts +80 -0
  98. package/web/types/kinship.ts +85 -0
@@ -0,0 +1,184 @@
1
+ "use strict";
2
+ /**
3
+ * Kinship Engine — core calculation logic.
4
+ *
5
+ * Given a relation path (sequence of atoms) and ego's gender,
6
+ * returns the appropriate Chinese kinship title with regional variants.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.calculateKinship = calculateKinship;
10
+ exports.detectGenerationConflict = detectGenerationConflict;
11
+ const kinship_data_js_1 = require("./kinship-data.js");
12
+ const relation_path_js_1 = require("./relation-path.js");
13
+ /**
14
+ * Calculate the kinship title for a given relation path.
15
+ * @param path dot-separated atom path, e.g. "F.B-.W"
16
+ * @param options region and ego gender
17
+ */
18
+ function calculateKinship(path, options = {}) {
19
+ const { region = 'standard', egoGender = 'male' } = options;
20
+ const atoms = (0, relation_path_js_1.decodePath)(path);
21
+ const lastAtom = atoms[atoms.length - 1] ?? '';
22
+ const entry = kinship_data_js_1.KINSHIP_LOOKUP.get(path);
23
+ const generationDelta = (0, relation_path_js_1.pathGenerationDelta)(path);
24
+ const relativeGender = (0, relation_path_js_1.atomGender)(lastAtom);
25
+ if (entry) {
26
+ return buildResult(path, entry, region, egoGender, generationDelta, relativeGender, true);
27
+ }
28
+ // Try to find approximate match via substitution rules
29
+ const approximated = approximatePath(path, region, egoGender, generationDelta, relativeGender);
30
+ if (approximated)
31
+ return approximated;
32
+ // Fallback to generation-based generic description
33
+ return buildGenericResult(path, generationDelta, relativeGender, egoGender);
34
+ }
35
+ function buildResult(path, entry, region, egoGender, generationDelta, relativeGender, isExact) {
36
+ const title = resolveRegionalTitle(entry, region) ?? entry.standard;
37
+ const reverseRaw = entry.reverse ?? null;
38
+ const reverseTitle = resolveReverseTitle(reverseRaw, egoGender);
39
+ const variants = {
40
+ standard: entry.standard,
41
+ };
42
+ if (entry.northern)
43
+ variants.northern = entry.northern;
44
+ if (entry.southern)
45
+ variants.southern = entry.southern;
46
+ if (entry.cantonese)
47
+ variants.cantonese = entry.cantonese;
48
+ if (entry.minnan)
49
+ variants.minnan = entry.minnan;
50
+ if (entry.wu)
51
+ variants.wu = entry.wu;
52
+ return {
53
+ path,
54
+ title,
55
+ standardTitle: entry.standard,
56
+ reverseTitle,
57
+ generationDelta,
58
+ relativeGender,
59
+ isExact,
60
+ note: entry.note ?? null,
61
+ variants,
62
+ };
63
+ }
64
+ /** Resolve the best title for a region, falling back to standard */
65
+ function resolveRegionalTitle(entry, region) {
66
+ if (region === 'northern' && entry.northern)
67
+ return entry.northern;
68
+ if (region === 'southern' && entry.southern)
69
+ return entry.southern;
70
+ if (region === 'cantonese' && entry.cantonese)
71
+ return entry.cantonese;
72
+ if (region === 'minnan' && entry.minnan)
73
+ return entry.minnan;
74
+ if (region === 'wu' && entry.wu)
75
+ return entry.wu;
76
+ return null;
77
+ }
78
+ /** "孙子/孙女" → pick by ego gender */
79
+ function resolveReverseTitle(raw, egoGender) {
80
+ if (!raw)
81
+ return null;
82
+ if (raw.includes('/')) {
83
+ const [male, female] = raw.split('/');
84
+ return egoGender === 'female' ? female : male;
85
+ }
86
+ return raw;
87
+ }
88
+ /**
89
+ * Try to approximate a title for unknown paths using heuristic rules.
90
+ * Examples:
91
+ * - "B+.B+" → treat as another sibling (堂兄 / older male)
92
+ * - Very deep ancestor → "先祖" + generation count
93
+ */
94
+ function approximatePath(path, region, egoGender, generationDelta, relativeGender) {
95
+ // Try removing H/W spouses from end and see if the bare path exists
96
+ const atoms = (0, relation_path_js_1.decodePath)(path);
97
+ if (atoms.length >= 2) {
98
+ const lastTwo = atoms.slice(-2);
99
+ if (lastTwo[1] === 'W' || lastTwo[1] === 'H') {
100
+ // Parent + spouse: e.g. "F.B+.W" → try the spouse rule
101
+ const parentPath = atoms.slice(0, -1).join('.');
102
+ const parentEntry = kinship_data_js_1.KINSHIP_LOOKUP.get(parentPath);
103
+ if (parentEntry) {
104
+ const spouseGender = lastTwo[1] === 'W' ? 'female' : 'male';
105
+ const spouseTitle = deriveSpouseTitle(parentEntry.standard, spouseGender);
106
+ if (spouseTitle) {
107
+ return {
108
+ path,
109
+ title: spouseTitle,
110
+ standardTitle: spouseTitle,
111
+ reverseTitle: null,
112
+ generationDelta,
113
+ relativeGender: spouseGender,
114
+ isExact: false,
115
+ note: `${parentEntry.standard}的配偶`,
116
+ variants: { standard: spouseTitle },
117
+ };
118
+ }
119
+ }
120
+ }
121
+ }
122
+ return null;
123
+ }
124
+ /** Derive spouse title from a relative's title */
125
+ function deriveSpouseTitle(relativeTitle, spouseGender) {
126
+ const maleTitles = {
127
+ '姐姐': '姐夫', '妹妹': '妹夫', '女儿': '女婿',
128
+ '伯母': '伯父', '婶母': '叔父', '舅母': '舅父',
129
+ '姑母': '姑父', '姨母': '姨父',
130
+ };
131
+ const femaleTitles = {
132
+ '哥哥': '嫂子', '弟弟': '弟媳', '儿子': '儿媳妇',
133
+ '伯父': '伯母', '叔父': '婶母', '舅父': '舅母',
134
+ '姑父': '姑母',
135
+ };
136
+ return spouseGender === 'male'
137
+ ? (maleTitles[relativeTitle] ?? null)
138
+ : (femaleTitles[relativeTitle] ?? null);
139
+ }
140
+ /** Generic fallback for unrecognized deep paths */
141
+ function buildGenericResult(path, generationDelta, relativeGender, egoGender) {
142
+ let title;
143
+ if (generationDelta > 3) {
144
+ title = relativeGender === 'female' ? `先祖${generationDelta}代女` : `先祖${generationDelta}代`;
145
+ }
146
+ else if (generationDelta < -3) {
147
+ const gen = Math.abs(generationDelta);
148
+ title = relativeGender === 'female' ? `第${gen}代孙女` : `第${gen}代孙`;
149
+ }
150
+ else if (generationDelta === 0) {
151
+ title = relativeGender === 'female' ? '同辈女性亲属' : '同辈男性亲属';
152
+ }
153
+ else {
154
+ title = '未知亲属关系';
155
+ }
156
+ return {
157
+ path,
158
+ title,
159
+ standardTitle: title,
160
+ reverseTitle: null,
161
+ generationDelta,
162
+ relativeGender,
163
+ isExact: false,
164
+ note: '无法精确匹配,请检查关系链',
165
+ variants: { standard: title },
166
+ };
167
+ }
168
+ /**
169
+ * Detect generational conflict — returns true if the path creates an
170
+ * impossible or paradoxical family structure.
171
+ * Example: ego being uncle AND father to the same person would be a conflict.
172
+ */
173
+ function detectGenerationConflict(paths) {
174
+ if (paths.length < 2)
175
+ return null;
176
+ const deltas = paths.map(relation_path_js_1.pathGenerationDelta);
177
+ const [delta0, delta1] = [deltas[0], deltas[1]];
178
+ // If two paths describe the same person but differ by more than one generation
179
+ if (delta0 !== undefined && delta1 !== undefined && Math.abs(delta0 - delta1) > 1) {
180
+ return `辈分冲突:两条路径的辈分差为 ${Math.abs(delta0 - delta1)} 代,请检查关系链`;
181
+ }
182
+ return null;
183
+ }
184
+ //# sourceMappingURL=kinship-engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kinship-engine.js","sourceRoot":"","sources":["../../src/engine/kinship-engine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Relation Path Encoding
3
+ *
4
+ * Each basic relation is encoded as a short atom:
5
+ * F = father (父)
6
+ * M = mother (母)
7
+ * S = son (子)
8
+ * D = daughter (女儿)
9
+ * B+ = elder brother (兄)
10
+ * B- = younger brother (弟)
11
+ * Z+ = elder sister (姐)
12
+ * Z- = younger sister (妹)
13
+ * H = husband (夫)
14
+ * W = wife (妻)
15
+ *
16
+ * A path is a sequence of atoms separated by dots, e.g.:
17
+ * "F" = father
18
+ * "F.F" = paternal grandfather
19
+ * "M.F" = maternal grandfather
20
+ * "F.B+" = father's elder brother (伯父)
21
+ * "F.B-.W" = father's younger brother's wife (婶婶)
22
+ *
23
+ * Gender of ego is passed separately because it affects some reverse titles.
24
+ */
25
+ export type RelationAtom = 'F' | 'M' | 'S' | 'D' | 'B+' | 'B-' | 'Z+' | 'Z-' | 'H' | 'W' | 'FF' | 'FM' | 'MF' | 'MM';
26
+ export type EgoGender = 'male' | 'female';
27
+ /** Encode a chain of atom strings into a canonical path string */
28
+ export declare function encodePath(atoms: string[]): string;
29
+ /** Decode a path string into atom array */
30
+ export declare function decodePath(path: string): string[];
31
+ /** Return the gender implied by the final atom */
32
+ export declare function atomGender(atom: string): 'male' | 'female' | 'unknown';
33
+ /** Generation delta of a single atom (+1 = elder generation, -1 = younger) */
34
+ export declare function atomGenerationDelta(atom: string): number;
35
+ /** Total generation delta for a path */
36
+ export declare function pathGenerationDelta(path: string): number;
37
+ //# sourceMappingURL=relation-path.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relation-path.d.ts","sourceRoot":"","sources":["../../src/engine/relation-path.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,MAAM,MAAM,YAAY,GACpB,GAAG,GAAG,GAAG,GACT,GAAG,GAAG,GAAG,GACT,IAAI,GAAG,IAAI,GACX,IAAI,GAAG,IAAI,GACX,GAAG,GAAG,GAAG,GACT,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;AAE7B,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,QAAQ,CAAA;AAEzC,kEAAkE;AAClE,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAElD;AAED,2CAA2C;AAC3C,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAEjD;AAED,kDAAkD;AAClD,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,QAAQ,GAAG,SAAS,CAItE;AAED,8EAA8E;AAC9E,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAIxD;AAED,wCAAwC;AACxC,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAExD"}
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ /**
3
+ * Relation Path Encoding
4
+ *
5
+ * Each basic relation is encoded as a short atom:
6
+ * F = father (父)
7
+ * M = mother (母)
8
+ * S = son (子)
9
+ * D = daughter (女儿)
10
+ * B+ = elder brother (兄)
11
+ * B- = younger brother (弟)
12
+ * Z+ = elder sister (姐)
13
+ * Z- = younger sister (妹)
14
+ * H = husband (夫)
15
+ * W = wife (妻)
16
+ *
17
+ * A path is a sequence of atoms separated by dots, e.g.:
18
+ * "F" = father
19
+ * "F.F" = paternal grandfather
20
+ * "M.F" = maternal grandfather
21
+ * "F.B+" = father's elder brother (伯父)
22
+ * "F.B-.W" = father's younger brother's wife (婶婶)
23
+ *
24
+ * Gender of ego is passed separately because it affects some reverse titles.
25
+ */
26
+ Object.defineProperty(exports, "__esModule", { value: true });
27
+ exports.encodePath = encodePath;
28
+ exports.decodePath = decodePath;
29
+ exports.atomGender = atomGender;
30
+ exports.atomGenerationDelta = atomGenerationDelta;
31
+ exports.pathGenerationDelta = pathGenerationDelta;
32
+ /** Encode a chain of atom strings into a canonical path string */
33
+ function encodePath(atoms) {
34
+ return atoms.join('.');
35
+ }
36
+ /** Decode a path string into atom array */
37
+ function decodePath(path) {
38
+ return path.split('.');
39
+ }
40
+ /** Return the gender implied by the final atom */
41
+ function atomGender(atom) {
42
+ if (['F', 'S', 'B+', 'B-', 'H', 'FF', 'MF'].includes(atom))
43
+ return 'male';
44
+ if (['M', 'D', 'Z+', 'Z-', 'W', 'FM', 'MM'].includes(atom))
45
+ return 'female';
46
+ return 'unknown';
47
+ }
48
+ /** Generation delta of a single atom (+1 = elder generation, -1 = younger) */
49
+ function atomGenerationDelta(atom) {
50
+ if (['F', 'M', 'FF', 'FM', 'MF', 'MM'].includes(atom))
51
+ return 1;
52
+ if (['S', 'D'].includes(atom))
53
+ return -1;
54
+ return 0; // siblings, spouses
55
+ }
56
+ /** Total generation delta for a path */
57
+ function pathGenerationDelta(path) {
58
+ return decodePath(path).reduce((sum, atom) => sum + atomGenerationDelta(atom), 0);
59
+ }
60
+ //# sourceMappingURL=relation-path.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relation-path.js","sourceRoot":"","sources":["../../src/engine/relation-path.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;;AAaH,gCAEC;AAGD,gCAEC;AAGD,gCAIC;AAGD,kDAIC;AAGD,kDAEC;AA3BD,kEAAkE;AAClE,SAAgB,UAAU,CAAC,KAAe;IACxC,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AACxB,CAAC;AAED,2CAA2C;AAC3C,SAAgB,UAAU,CAAC,IAAY;IACrC,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;AACxB,CAAC;AAED,kDAAkD;AAClD,SAAgB,UAAU,CAAC,IAAY;IACrC,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC;QAAE,OAAO,MAAM,CAAA;IACzE,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC;QAAE,OAAO,QAAQ,CAAA;IAC3E,OAAO,SAAS,CAAA;AAClB,CAAC;AAED,8EAA8E;AAC9E,SAAgB,mBAAmB,CAAC,IAAY;IAC9C,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC;QAAE,OAAO,CAAC,CAAA;IAC/D,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC,CAAA;IACxC,OAAO,CAAC,CAAA,CAAC,oBAAoB;AAC/B,CAAC;AAED,wCAAwC;AACxC,SAAgB,mBAAmB,CAAC,IAAY;IAC9C,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,GAAG,GAAG,mBAAmB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAA;AACnF,CAAC"}
@@ -0,0 +1,12 @@
1
+ export type PersonGender = 'male' | 'female';
2
+ export declare class FamilyTreePerson {
3
+ id: number;
4
+ treeId: number;
5
+ name: string;
6
+ gender: PersonGender;
7
+ birthYear: number | null;
8
+ notes: string | null;
9
+ isRoot: boolean;
10
+ createdAt: Date;
11
+ }
12
+ //# sourceMappingURL=family-tree-person.entity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"family-tree-person.entity.d.ts","sourceRoot":"","sources":["../../src/entities/family-tree-person.entity.ts"],"names":[],"mappings":"AAQA,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,QAAQ,CAAA;AAE5C,qBAEa,gBAAgB;IAE3B,EAAE,EAAG,MAAM,CAAA;IAGX,MAAM,EAAG,MAAM,CAAA;IAGf,IAAI,EAAG,MAAM,CAAA;IAGb,MAAM,EAAG,YAAY,CAAA;IAGrB,SAAS,EAAG,MAAM,GAAG,IAAI,CAAA;IAGzB,KAAK,EAAG,MAAM,GAAG,IAAI,CAAA;IAGrB,MAAM,EAAG,OAAO,CAAA;IAGhB,SAAS,EAAG,IAAI,CAAA;CACjB"}
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.FamilyTreePerson = void 0;
13
+ const core_1 = require("@octo-cyber/core");
14
+ let FamilyTreePerson = class FamilyTreePerson {
15
+ id;
16
+ treeId;
17
+ name;
18
+ gender;
19
+ birthYear;
20
+ notes;
21
+ isRoot;
22
+ createdAt;
23
+ };
24
+ exports.FamilyTreePerson = FamilyTreePerson;
25
+ __decorate([
26
+ (0, core_1.PrimaryGeneratedColumn)(),
27
+ __metadata("design:type", Number)
28
+ ], FamilyTreePerson.prototype, "id", void 0);
29
+ __decorate([
30
+ (0, core_1.Column)({ type: 'integer', name: 'tree_id' }),
31
+ __metadata("design:type", Number)
32
+ ], FamilyTreePerson.prototype, "treeId", void 0);
33
+ __decorate([
34
+ (0, core_1.Column)({ type: 'varchar', length: 50 }),
35
+ __metadata("design:type", String)
36
+ ], FamilyTreePerson.prototype, "name", void 0);
37
+ __decorate([
38
+ (0, core_1.Column)({ type: 'varchar', length: 10 }),
39
+ __metadata("design:type", String)
40
+ ], FamilyTreePerson.prototype, "gender", void 0);
41
+ __decorate([
42
+ (0, core_1.Column)({ type: 'integer', nullable: true, name: 'birth_year' }),
43
+ __metadata("design:type", Object)
44
+ ], FamilyTreePerson.prototype, "birthYear", void 0);
45
+ __decorate([
46
+ (0, core_1.Column)({ type: 'text', nullable: true }),
47
+ __metadata("design:type", Object)
48
+ ], FamilyTreePerson.prototype, "notes", void 0);
49
+ __decorate([
50
+ (0, core_1.Column)({ type: 'boolean', default: false, name: 'is_root' }),
51
+ __metadata("design:type", Boolean)
52
+ ], FamilyTreePerson.prototype, "isRoot", void 0);
53
+ __decorate([
54
+ (0, core_1.CreateDateColumn)({ name: 'created_at' }),
55
+ __metadata("design:type", Date)
56
+ ], FamilyTreePerson.prototype, "createdAt", void 0);
57
+ exports.FamilyTreePerson = FamilyTreePerson = __decorate([
58
+ (0, core_1.Entity)('kinship_family_tree_person'),
59
+ (0, core_1.Index)(['treeId'])
60
+ ], FamilyTreePerson);
61
+ //# sourceMappingURL=family-tree-person.entity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"family-tree-person.entity.js","sourceRoot":"","sources":["../../src/entities/family-tree-person.entity.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAMyB;AAMlB,IAAM,gBAAgB,GAAtB,MAAM,gBAAgB;IAE3B,EAAE,CAAS;IAGX,MAAM,CAAS;IAGf,IAAI,CAAS;IAGb,MAAM,CAAe;IAGrB,SAAS,CAAgB;IAGzB,KAAK,CAAgB;IAGrB,MAAM,CAAU;IAGhB,SAAS,CAAO;CACjB,CAAA;AAxBY,4CAAgB;AAE3B;IADC,IAAA,6BAAsB,GAAE;;4CACd;AAGX;IADC,IAAA,aAAM,EAAC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;;gDAC9B;AAGf;IADC,IAAA,aAAM,EAAC,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;;8CAC3B;AAGb;IADC,IAAA,aAAM,EAAC,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;;gDACnB;AAGrB;IADC,IAAA,aAAM,EAAC,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;;mDACvC;AAGzB;IADC,IAAA,aAAM,EAAC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;;+CACpB;AAGrB;IADC,IAAA,aAAM,EAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;;gDAC7C;AAGhB;IADC,IAAA,uBAAgB,EAAC,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;8BAC7B,IAAI;mDAAA;2BAvBL,gBAAgB;IAF5B,IAAA,aAAM,EAAC,4BAA4B,CAAC;IACpC,IAAA,YAAK,EAAC,CAAC,QAAQ,CAAC,CAAC;GACL,gBAAgB,CAwB5B"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Directed edge: fromPersonId → toPersonId with relationType.
3
+ * relationType is a basic atom code such as 'father', 'mother', 'son', 'daughter',
4
+ * 'elder-brother', 'younger-brother', 'elder-sister', 'younger-sister',
5
+ * 'husband', 'wife'.
6
+ */
7
+ export declare class FamilyTreeRelation {
8
+ id: number;
9
+ treeId: number;
10
+ fromPersonId: number;
11
+ toPersonId: number;
12
+ relationType: string;
13
+ createdAt: Date;
14
+ }
15
+ //# sourceMappingURL=family-tree-relation.entity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"family-tree-relation.entity.d.ts","sourceRoot":"","sources":["../../src/entities/family-tree-relation.entity.ts"],"names":[],"mappings":"AAQA;;;;;GAKG;AACH,qBAGa,kBAAkB;IAE7B,EAAE,EAAG,MAAM,CAAA;IAGX,MAAM,EAAG,MAAM,CAAA;IAGf,YAAY,EAAG,MAAM,CAAA;IAGrB,UAAU,EAAG,MAAM,CAAA;IAGnB,YAAY,EAAG,MAAM,CAAA;IAGrB,SAAS,EAAG,IAAI,CAAA;CACjB"}
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.FamilyTreeRelation = void 0;
13
+ const core_1 = require("@octo-cyber/core");
14
+ /**
15
+ * Directed edge: fromPersonId → toPersonId with relationType.
16
+ * relationType is a basic atom code such as 'father', 'mother', 'son', 'daughter',
17
+ * 'elder-brother', 'younger-brother', 'elder-sister', 'younger-sister',
18
+ * 'husband', 'wife'.
19
+ */
20
+ let FamilyTreeRelation = class FamilyTreeRelation {
21
+ id;
22
+ treeId;
23
+ fromPersonId;
24
+ toPersonId;
25
+ relationType;
26
+ createdAt;
27
+ };
28
+ exports.FamilyTreeRelation = FamilyTreeRelation;
29
+ __decorate([
30
+ (0, core_1.PrimaryGeneratedColumn)(),
31
+ __metadata("design:type", Number)
32
+ ], FamilyTreeRelation.prototype, "id", void 0);
33
+ __decorate([
34
+ (0, core_1.Column)({ type: 'integer', name: 'tree_id' }),
35
+ __metadata("design:type", Number)
36
+ ], FamilyTreeRelation.prototype, "treeId", void 0);
37
+ __decorate([
38
+ (0, core_1.Column)({ type: 'integer', name: 'from_person_id' }),
39
+ __metadata("design:type", Number)
40
+ ], FamilyTreeRelation.prototype, "fromPersonId", void 0);
41
+ __decorate([
42
+ (0, core_1.Column)({ type: 'integer', name: 'to_person_id' }),
43
+ __metadata("design:type", Number)
44
+ ], FamilyTreeRelation.prototype, "toPersonId", void 0);
45
+ __decorate([
46
+ (0, core_1.Column)({ type: 'varchar', length: 30, name: 'relation_type' }),
47
+ __metadata("design:type", String)
48
+ ], FamilyTreeRelation.prototype, "relationType", void 0);
49
+ __decorate([
50
+ (0, core_1.CreateDateColumn)({ name: 'created_at' }),
51
+ __metadata("design:type", Date)
52
+ ], FamilyTreeRelation.prototype, "createdAt", void 0);
53
+ exports.FamilyTreeRelation = FamilyTreeRelation = __decorate([
54
+ (0, core_1.Entity)('kinship_family_tree_relation'),
55
+ (0, core_1.Index)(['treeId', 'fromPersonId']),
56
+ (0, core_1.Index)(['treeId', 'toPersonId'])
57
+ ], FamilyTreeRelation);
58
+ //# sourceMappingURL=family-tree-relation.entity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"family-tree-relation.entity.js","sourceRoot":"","sources":["../../src/entities/family-tree-relation.entity.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAMyB;AAEzB;;;;;GAKG;AAII,IAAM,kBAAkB,GAAxB,MAAM,kBAAkB;IAE7B,EAAE,CAAS;IAGX,MAAM,CAAS;IAGf,YAAY,CAAS;IAGrB,UAAU,CAAS;IAGnB,YAAY,CAAS;IAGrB,SAAS,CAAO;CACjB,CAAA;AAlBY,gDAAkB;AAE7B;IADC,IAAA,6BAAsB,GAAE;;8CACd;AAGX;IADC,IAAA,aAAM,EAAC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;;kDAC9B;AAGf;IADC,IAAA,aAAM,EAAC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,gBAAgB,EAAE,CAAC;;wDAC/B;AAGrB;IADC,IAAA,aAAM,EAAC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC;;sDAC/B;AAGnB;IADC,IAAA,aAAM,EAAC,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,eAAe,EAAE,CAAC;;wDAC1C;AAGrB;IADC,IAAA,uBAAgB,EAAC,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;8BAC7B,IAAI;qDAAA;6BAjBL,kBAAkB;IAH9B,IAAA,aAAM,EAAC,8BAA8B,CAAC;IACtC,IAAA,YAAK,EAAC,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;IACjC,IAAA,YAAK,EAAC,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;GACnB,kBAAkB,CAkB9B"}
@@ -0,0 +1,9 @@
1
+ export declare class FamilyTree {
2
+ id: number;
3
+ name: string;
4
+ description: string | null;
5
+ ownerId: number;
6
+ createdAt: Date;
7
+ updatedAt: Date;
8
+ }
9
+ //# sourceMappingURL=family-tree.entity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"family-tree.entity.d.ts","sourceRoot":"","sources":["../../src/entities/family-tree.entity.ts"],"names":[],"mappings":"AAQA,qBACa,UAAU;IAErB,EAAE,EAAG,MAAM,CAAA;IAGX,IAAI,EAAG,MAAM,CAAA;IAGb,WAAW,EAAG,MAAM,GAAG,IAAI,CAAA;IAG3B,OAAO,EAAG,MAAM,CAAA;IAGhB,SAAS,EAAG,IAAI,CAAA;IAGhB,SAAS,EAAG,IAAI,CAAA;CACjB"}
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.FamilyTree = void 0;
13
+ const core_1 = require("@octo-cyber/core");
14
+ let FamilyTree = class FamilyTree {
15
+ id;
16
+ name;
17
+ description;
18
+ ownerId;
19
+ createdAt;
20
+ updatedAt;
21
+ };
22
+ exports.FamilyTree = FamilyTree;
23
+ __decorate([
24
+ (0, core_1.PrimaryGeneratedColumn)(),
25
+ __metadata("design:type", Number)
26
+ ], FamilyTree.prototype, "id", void 0);
27
+ __decorate([
28
+ (0, core_1.Column)({ type: 'varchar', length: 100 }),
29
+ __metadata("design:type", String)
30
+ ], FamilyTree.prototype, "name", void 0);
31
+ __decorate([
32
+ (0, core_1.Column)({ type: 'text', nullable: true }),
33
+ __metadata("design:type", Object)
34
+ ], FamilyTree.prototype, "description", void 0);
35
+ __decorate([
36
+ (0, core_1.Column)({ type: 'integer', name: 'owner_id' }),
37
+ __metadata("design:type", Number)
38
+ ], FamilyTree.prototype, "ownerId", void 0);
39
+ __decorate([
40
+ (0, core_1.CreateDateColumn)({ name: 'created_at' }),
41
+ __metadata("design:type", Date)
42
+ ], FamilyTree.prototype, "createdAt", void 0);
43
+ __decorate([
44
+ (0, core_1.UpdateDateColumn)({ name: 'updated_at' }),
45
+ __metadata("design:type", Date)
46
+ ], FamilyTree.prototype, "updatedAt", void 0);
47
+ exports.FamilyTree = FamilyTree = __decorate([
48
+ (0, core_1.Entity)('kinship_family_tree')
49
+ ], FamilyTree);
50
+ //# sourceMappingURL=family-tree.entity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"family-tree.entity.js","sourceRoot":"","sources":["../../src/entities/family-tree.entity.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAMyB;AAGlB,IAAM,UAAU,GAAhB,MAAM,UAAU;IAErB,EAAE,CAAS;IAGX,IAAI,CAAS;IAGb,WAAW,CAAgB;IAG3B,OAAO,CAAS;IAGhB,SAAS,CAAO;IAGhB,SAAS,CAAO;CACjB,CAAA;AAlBY,gCAAU;AAErB;IADC,IAAA,6BAAsB,GAAE;;sCACd;AAGX;IADC,IAAA,aAAM,EAAC,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;;wCAC5B;AAGb;IADC,IAAA,aAAM,EAAC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;;+CACd;AAG3B;IADC,IAAA,aAAM,EAAC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;;2CAC9B;AAGhB;IADC,IAAA,uBAAgB,EAAC,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;8BAC7B,IAAI;6CAAA;AAGhB;IADC,IAAA,uBAAgB,EAAC,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;8BAC7B,IAAI;6CAAA;qBAjBL,UAAU;IADtB,IAAA,aAAM,EAAC,qBAAqB,CAAC;GACjB,UAAU,CAkBtB"}
@@ -0,0 +1,12 @@
1
+ import { FamilyTree } from './family-tree.entity.js';
2
+ import { FamilyTreePerson } from './family-tree-person.entity.js';
3
+ import { FamilyTreeRelation } from './family-tree-relation.entity.js';
4
+ import { KinshipTitle } from './kinship-title.entity.js';
5
+ export { FamilyTree } from './family-tree.entity.js';
6
+ export { FamilyTreePerson } from './family-tree-person.entity.js';
7
+ export { FamilyTreeRelation } from './family-tree-relation.entity.js';
8
+ export { KinshipTitle } from './kinship-title.entity.js';
9
+ export type { KinshipRegion } from './kinship-title.entity.js';
10
+ export type { PersonGender } from './family-tree-person.entity.js';
11
+ export declare const KINSHIP_CALC_ENTITIES: (typeof FamilyTree | typeof FamilyTreePerson | typeof FamilyTreeRelation | typeof KinshipTitle)[];
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/entities/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAA;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAA;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAA;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AAExD,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAA;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAA;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAA;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AACxD,YAAY,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAA;AAC9D,YAAY,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAA;AAElE,eAAO,MAAM,qBAAqB,mGAKjC,CAAA"}
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.KINSHIP_CALC_ENTITIES = exports.KinshipTitle = exports.FamilyTreeRelation = exports.FamilyTreePerson = exports.FamilyTree = void 0;
4
+ const family_tree_entity_js_1 = require("./family-tree.entity.js");
5
+ const family_tree_person_entity_js_1 = require("./family-tree-person.entity.js");
6
+ const family_tree_relation_entity_js_1 = require("./family-tree-relation.entity.js");
7
+ const kinship_title_entity_js_1 = require("./kinship-title.entity.js");
8
+ var family_tree_entity_js_2 = require("./family-tree.entity.js");
9
+ Object.defineProperty(exports, "FamilyTree", { enumerable: true, get: function () { return family_tree_entity_js_2.FamilyTree; } });
10
+ var family_tree_person_entity_js_2 = require("./family-tree-person.entity.js");
11
+ Object.defineProperty(exports, "FamilyTreePerson", { enumerable: true, get: function () { return family_tree_person_entity_js_2.FamilyTreePerson; } });
12
+ var family_tree_relation_entity_js_2 = require("./family-tree-relation.entity.js");
13
+ Object.defineProperty(exports, "FamilyTreeRelation", { enumerable: true, get: function () { return family_tree_relation_entity_js_2.FamilyTreeRelation; } });
14
+ var kinship_title_entity_js_2 = require("./kinship-title.entity.js");
15
+ Object.defineProperty(exports, "KinshipTitle", { enumerable: true, get: function () { return kinship_title_entity_js_2.KinshipTitle; } });
16
+ exports.KINSHIP_CALC_ENTITIES = [
17
+ family_tree_entity_js_1.FamilyTree,
18
+ family_tree_person_entity_js_1.FamilyTreePerson,
19
+ family_tree_relation_entity_js_1.FamilyTreeRelation,
20
+ kinship_title_entity_js_1.KinshipTitle,
21
+ ];
22
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/entities/index.ts"],"names":[],"mappings":";;;AAAA,mEAAoD;AACpD,iFAAiE;AACjE,qFAAqE;AACrE,uEAAwD;AAExD,iEAAoD;AAA3C,mHAAA,UAAU,OAAA;AACnB,+EAAiE;AAAxD,gIAAA,gBAAgB,OAAA;AACzB,mFAAqE;AAA5D,oIAAA,kBAAkB,OAAA;AAC3B,qEAAwD;AAA/C,uHAAA,YAAY,OAAA;AAIR,QAAA,qBAAqB,GAAG;IACnC,kCAAU;IACV,+CAAgB;IAChB,mDAAkB;IAClB,sCAAY;CACb,CAAA"}
@@ -0,0 +1,18 @@
1
+ export type KinshipRegion = 'standard' | 'northern' | 'southern' | 'cantonese' | 'minnan' | 'wu';
2
+ /**
3
+ * Stores a computed kinship title for a specific relation path + region.
4
+ * relationPath is the canonical encoded path, e.g. "F" (father), "FF" (paternal grandfather).
5
+ */
6
+ export declare class KinshipTitle {
7
+ id: number;
8
+ /** Encoded relation path, e.g. "F", "M", "FF", "MF", "FB+", "MS" */
9
+ relationPath: string;
10
+ region: KinshipRegion;
11
+ /** How ego calls the relative, e.g. 爷爷, 外公 */
12
+ title: string;
13
+ /** How the relative calls ego back, e.g. 孙子/孙女 */
14
+ reverseTitle: string | null;
15
+ /** Description / mnemonic for this term */
16
+ description: string | null;
17
+ }
18
+ //# sourceMappingURL=kinship-title.entity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kinship-title.entity.d.ts","sourceRoot":"","sources":["../../src/entities/kinship-title.entity.ts"],"names":[],"mappings":"AAOA,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,UAAU,GAAG,UAAU,GAAG,WAAW,GAAG,QAAQ,GAAG,IAAI,CAAA;AAEhG;;;GAGG;AACH,qBAEa,YAAY;IAEvB,EAAE,EAAG,MAAM,CAAA;IAEX,oEAAoE;IAEpE,YAAY,EAAG,MAAM,CAAA;IAGrB,MAAM,EAAG,aAAa,CAAA;IAEtB,8CAA8C;IAE9C,KAAK,EAAG,MAAM,CAAA;IAEd,kDAAkD;IAElD,YAAY,EAAG,MAAM,GAAG,IAAI,CAAA;IAE5B,2CAA2C;IAE3C,WAAW,EAAG,MAAM,GAAG,IAAI,CAAA;CAC5B"}