bazi-chart 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +85 -0
- package/dist/index.cjs +646 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +243 -0
- package/dist/index.d.ts +243 -0
- package/dist/index.js +604 -0
- package/dist/index.js.map +1 -0
- package/package.json +64 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/adapters/baziObject.ts","../src/adapters/pillarMap.ts","../src/normalize.ts","../src/theme.ts","../src/i18n.ts","../src/components/BaziChart.tsx"],"sourcesContent":["/**\n * bazi-chart — React components and adapters for rendering Bazi charts.\n *\n * Feed it raw output from a supported Bazi engine (or a pre-normalized chart)\n * and it renders a complete bilingual chart.\n */\n\nexport * from './types.js';\nexport * from './normalize.js';\nexport * from './theme.js';\nexport * from './i18n.js';\nexport { fromBaziObject } from './adapters/baziObject.js';\nexport { fromPillarMap } from './adapters/pillarMap.js';\nexport { BaziChart } from './components/BaziChart.js';\nexport type { BaziChartProps } from './components/BaziChart.js';\n","import type {\n ElementScore,\n NormalizedChart,\n NormalizedHiddenStem,\n NormalizedInteraction,\n NormalizedLuckPillar,\n NormalizedPillar,\n PillarPosition,\n} from '../types.js';\nimport { BRANCH_BY_CHAR, interactionFromZh } from 'bazi-terms';\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\ntype Raw = Record<string, any>;\n\nconst POSITION_ZH: Record<string, PillarPosition> = {\n 年柱: 'year',\n 月柱: 'month',\n 日柱: 'day',\n 时柱: 'hour',\n};\n\n/** Split a two-character void string like '戌亥' into ['戌','亥']. */\nfunction splitVoid(v: unknown): string[] | undefined {\n if (typeof v !== 'string' || v.length === 0) return undefined;\n return Array.from(v);\n}\n\n/** Extract the branch characters mentioned in a description like '午子相冲'. */\nfunction branchesInText(desc: string): string[] {\n return Array.from(desc).filter((ch) => ch in BRANCH_BY_CHAR);\n}\n\nfunction adaptPillar(position: PillarPosition, raw: Raw): NormalizedPillar {\n // 副星 lists the ten gods of the hidden stems (藏干), in order.\n const hiddenRaw: Raw[] = Array.isArray(raw['藏干详情']) ? raw['藏干详情'] : [];\n const secondary: string[] = Array.isArray(raw['副星']) ? raw['副星'] : [];\n const hiddenStems: NormalizedHiddenStem[] = hiddenRaw.map((h, i) => ({\n char: String(h['干'] ?? ''),\n tenGod: secondary[i],\n isMain: i === 0,\n }));\n\n return {\n position,\n ganZhi: String(raw['干支'] ?? ''),\n stem: String(raw['天干'] ?? ''),\n branch: String(raw['地支'] ?? ''),\n mainTenGod: raw['主星'] != null ? String(raw['主星']) : undefined,\n secondaryTenGods: secondary.length ? secondary : undefined,\n hiddenStems,\n naYin: raw['纳音'] != null ? String(raw['纳音']) : undefined,\n growthStage: raw['星运'] != null ? String(raw['星运']) : undefined,\n voidBranches: splitVoid(raw['空亡']),\n shenSha: Array.isArray(raw['神煞']) ? (raw['神煞'] as string[]) : undefined,\n };\n}\n\nfunction adaptInteractions(raw: Raw): NormalizedInteraction[] {\n const out: NormalizedInteraction[] = [];\n const stems: unknown[] = Array.isArray(raw['天干']) ? raw['天干'] : [];\n const branches: unknown[] = Array.isArray(raw['地支']) ? raw['地支'] : [];\n\n for (const s of stems) {\n const desc = String(s);\n out.push({\n typeKey: desc.includes('合') ? 'stemCombination' : undefined,\n branches: branchesInText(desc),\n description: desc,\n });\n }\n for (const b of branches) {\n const desc = String(b);\n out.push({\n typeKey: interactionFromZh(desc)?.key,\n branches: branchesInText(desc),\n description: desc,\n });\n }\n return out;\n}\n\nfunction adaptFiveElements(raw: Raw): ElementScore[] | undefined {\n if (!raw || typeof raw !== 'object') return undefined;\n const scores: ElementScore[] = [];\n for (const el of ['金', '木', '水', '火', '土']) {\n const entry = raw[el];\n if (entry && typeof entry === 'object') {\n scores.push({\n element: el,\n score: typeof entry['分值'] === 'number' ? entry['分值'] : undefined,\n percent: entry['占比'] != null ? String(entry['占比']) : undefined,\n });\n }\n }\n return scores.length ? scores : undefined;\n}\n\nfunction adaptDaYun(list: unknown): NormalizedLuckPillar[] {\n if (!Array.isArray(list)) return [];\n return list.map((raw: Raw) => ({\n ganZhi: String(raw['干支'] ?? ''),\n stem: raw['天干'] != null ? String(raw['天干']) : undefined,\n branch: raw['地支'] != null ? String(raw['地支']) : undefined,\n stemTenGod: raw['主星'] != null ? String(raw['主星']) : undefined,\n startAge: typeof raw['起始年龄'] === 'number' ? raw['起始年龄'] : undefined,\n endAge: typeof raw['结束年龄'] === 'number' ? raw['结束年龄'] : undefined,\n startYear: typeof raw['起始年份'] === 'number' ? raw['起始年份'] : undefined,\n endYear: typeof raw['结束年份'] === 'number' ? raw['结束年份'] : undefined,\n naYin: raw['纳音'] != null ? String(raw['纳音']) : undefined,\n isCurrent: raw['当前'] === true,\n }));\n}\n\n/**\n * Normalize a Chinese-field chart object (top-level `八字`) into a NormalizedChart.\n * The input uses Chinese field names throughout.\n */\nexport function fromBaziObject(data: Raw): NormalizedChart {\n const input: Raw = data['输入'] ?? {};\n const solarTimeRaw: Raw = data['真太阳时'] ?? {};\n const bazi: Raw = data['八字'] ?? {};\n const detail: Raw = bazi['柱位详细'] ?? {};\n\n const pillars: NormalizedPillar[] = [];\n for (const [zh, position] of Object.entries(POSITION_ZH)) {\n const raw = detail[zh];\n if (raw && typeof raw === 'object') pillars.push(adaptPillar(position, raw as Raw));\n }\n\n const wuxing: Raw = bazi['五行分值'] ?? {};\n\n return {\n meta: {\n engine: 'baziObject',\n gender: input['性别'] != null ? String(input['性别']) : undefined,\n zodiac: bazi['生肖'] != null ? String(bazi['生肖']) : undefined,\n lunar: bazi['农历'] != null ? String(bazi['农历']) : undefined,\n solar: bazi['公历'] != null ? String(bazi['公历']) : undefined,\n },\n solarTime: {\n clock: solarTimeRaw['钟表时间'] != null ? String(solarTimeRaw['钟表时间']) : undefined,\n trueSolar: solarTimeRaw['真太阳时'] != null ? String(solarTimeRaw['真太阳时']) : undefined,\n correctionMinutes:\n typeof solarTimeRaw['修正分钟'] === 'number' ? solarTimeRaw['修正分钟'] : undefined,\n shiChen: solarTimeRaw['时辰'] != null ? String(solarTimeRaw['时辰']) : undefined,\n },\n dayMaster: {\n char: bazi['日主'] != null ? String(bazi['日主']) : undefined,\n element: wuxing['日主五行'] != null ? String(wuxing['日主五行']) : undefined,\n },\n pillars,\n fiveElements: adaptFiveElements(wuxing),\n dayMasterElement: wuxing['日主五行'] != null ? String(wuxing['日主五行']) : undefined,\n daYun: adaptDaYun(bazi['大运']),\n daYunOnset: bazi['起运'] != null ? String(bazi['起运']) : undefined,\n interactions: adaptInteractions(bazi['刑冲合会'] ?? {}),\n extras: {\n mingGong: bazi['命宫'] != null ? String(bazi['命宫']) : undefined,\n shenGong: bazi['身宫'] != null ? String(bazi['身宫']) : undefined,\n taiYuan: bazi['胎元'] != null ? String(bazi['胎元']) : undefined,\n taiXi: bazi['胎息'] != null ? String(bazi['胎息']) : undefined,\n },\n };\n}\n","import type {\n NormalizedChart,\n NormalizedHiddenStem,\n NormalizedInteraction,\n NormalizedLuckPillar,\n NormalizedPillar,\n PillarPosition,\n} from '../types.js';\nimport { interactionFromEnum } from 'bazi-terms';\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\ntype Raw = Record<string, any>;\n\nconst PILLAR_ORDER: { field: string; position: PillarPosition }[] = [\n { field: 'year', position: 'year' },\n { field: 'month', position: 'month' },\n { field: 'day', position: 'day' },\n { field: 'hour', position: 'hour' },\n];\n\nfunction str(v: unknown): string | undefined {\n return v == null ? undefined : String(v);\n}\n\nfunction num(v: unknown): number | undefined {\n return typeof v === 'number' ? v : undefined;\n}\n\nfunction adaptPillar(position: PillarPosition, raw: Raw): NormalizedPillar {\n const hiddenRaw: Raw[] = Array.isArray(raw['hiddenStems']) ? raw['hiddenStems'] : [];\n const hiddenStems: NormalizedHiddenStem[] = hiddenRaw.map((h, i) => ({\n char: String(h['stem'] ?? ''),\n tenGod: str(h['tenGod']),\n isMain: h['isMain'] === true || (h['isMain'] === undefined && i === 0),\n }));\n\n return {\n position,\n ganZhi: String(raw['ganZhi'] ?? ''),\n stem: String(raw['stem'] ?? ''),\n branch: String(raw['branch'] ?? ''),\n mainTenGod: str(raw['stemTenGod']),\n hiddenStems,\n naYin: str(raw['naYin']),\n growthStage: str(raw['growthStage']),\n voidBranches: Array.isArray(raw['voidBranches']) ? (raw['voidBranches'] as string[]) : undefined,\n xun: str(raw['xun']),\n };\n}\n\nfunction adaptInteractions(list: unknown): NormalizedInteraction[] {\n if (!Array.isArray(list)) return [];\n return list.map((raw: Raw) => ({\n typeKey: interactionFromEnum(String(raw['type'] ?? ''))?.key,\n branches: Array.isArray(raw['branches']) ? (raw['branches'] as string[]) : undefined,\n pillars: Array.isArray(raw['pillars']) ? (raw['pillars'] as string[]) : undefined,\n description: str(raw['description']),\n }));\n}\n\nfunction adaptDaYun(daYun: Raw): NormalizedLuckPillar[] {\n const cycles: Raw[] = Array.isArray(daYun?.['cycles']) ? daYun['cycles'] : [];\n return cycles.map((c) => ({\n ganZhi: String(c['ganZhi'] ?? ''),\n stem: str(c['stem']),\n branch: str(c['branch']),\n stemTenGod: str(c['stemTenGod']),\n branchTenGod: str(c['branchTenGod']),\n startAge: num(c['startAge']),\n endAge: num(c['endAge']),\n startYear: num(c['startYear']),\n endYear: num(c['endYear']),\n }));\n}\n\n/** Format a calendar sub-object into a readable date string. */\nfunction formatCalendarPart(part: Raw): string | undefined {\n if (!part || typeof part !== 'object') return undefined;\n const y = num(part['year']);\n const m = num(part['month']);\n const d = num(part['day']);\n if (y == null || m == null || d == null) return undefined;\n const hh = num(part['hour']);\n const mm = num(part['minute']);\n const time = hh != null && mm != null ? ` ${String(hh).padStart(2, '0')}:${String(mm).padStart(2, '0')}` : '';\n return `${y}-${String(m).padStart(2, '0')}-${String(d).padStart(2, '0')}${time}`;\n}\n\n/**\n * Normalize a pillar-map chart object (`pillars` keyed by year/month/day/hour) into a NormalizedChart.\n * Field names are English; ten gods, Na Yin and growth stages are Chinese values;\n * elements are English keys ('metal'). All are passed through raw — the renderer\n * resolves them via bazi-terms, which accepts both Chinese and English keys.\n */\nexport function fromPillarMap(data: Raw): NormalizedChart {\n const rawPillars: Raw = data['pillars'] ?? {};\n const pillars: NormalizedPillar[] = [];\n for (const { field, position } of PILLAR_ORDER) {\n const raw = rawPillars[field];\n // The hour pillar can be null for births where it is not computed.\n if (raw && typeof raw === 'object') pillars.push(adaptPillar(position, raw as Raw));\n }\n\n const dm: Raw = data['dayMaster'] ?? {};\n const daYun: Raw = data['daYun'] ?? {};\n const solar: Raw = data['solarTimeInfo'] ?? {};\n const calendar: Raw = data['calendar'] ?? {};\n\n const lonCorr = num(solar['longitudeCorrectionMinutes']);\n const eotCorr = num(solar['equationOfTimeMinutes']);\n const correctionMinutes =\n lonCorr != null || eotCorr != null ? Math.round(((lonCorr ?? 0) + (eotCorr ?? 0)) * 100) / 100 : undefined;\n\n return {\n meta: {\n engine: 'pillarMap',\n zodiac: str(calendar['zodiac']),\n lunar: formatCalendarPart(calendar['lunar']),\n solar: formatCalendarPart(calendar['civilSolar'] ?? calendar['calculationSolar']),\n },\n solarTime: {\n trueSolar: str(solar['trueSolarDateTime'] ?? solar['trueSolarTime']),\n correctionMinutes,\n },\n dayMaster: {\n char: str(dm['char']),\n element: str(dm['element']),\n polarity: str(dm['polarity']),\n },\n pillars,\n dayMasterElement: str(dm['element']),\n daYun: adaptDaYun(daYun),\n daYunDirection: daYun['isForward'] === true ? 'forward' : daYun['isForward'] === false ? 'backward' : undefined,\n interactions: adaptInteractions(data['interactions']),\n };\n}\n","import type { EngineName, NormalizedChart } from './types.js';\nimport { fromBaziObject } from './adapters/baziObject.js';\nimport { fromPillarMap } from './adapters/pillarMap.js';\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\ntype Raw = Record<string, any>;\n\n/**\n * Detect which engine produced `data` (or whether it is already normalized).\n * Detection is intentionally structural and order-safe:\n * 1. bazi-object format → top-level `八字` object\n * 2. pre-normalized → `meta.engine`, or `pillars` as an array with `position`\n * 3. pillar-map format → `pillars` as an object keyed by year/month/day/hour\n */\nexport function detectEngine(data: unknown): EngineName {\n if (!data || typeof data !== 'object') return 'unknown';\n const d = data as Raw;\n\n if (d['八字'] && typeof d['八字'] === 'object') return 'baziObject';\n\n if (d['meta'] && typeof d['meta'] === 'object' && 'engine' in d['meta']) return 'normalized';\n if (Array.isArray(d['pillars']) && d['pillars'][0] && typeof d['pillars'][0] === 'object' && 'position' in d['pillars'][0]) {\n return 'normalized';\n }\n\n if (d['pillars'] && typeof d['pillars'] === 'object' && !Array.isArray(d['pillars'])) {\n const year = d['pillars']['year'];\n if (year && typeof year === 'object' && ('ganZhi' in year || 'stem' in year)) return 'pillarMap';\n }\n\n return 'unknown';\n}\n\n/**\n * Normalize any supported input into a NormalizedChart.\n * Accepts a raw bazi-object chart, a raw pillar-map chart,\n * or an already-normalized chart (returned as-is).\n *\n * @throws when the input matches none of the supported shapes.\n */\nexport function normalize(data: unknown): NormalizedChart {\n const engine = detectEngine(data);\n switch (engine) {\n case 'baziObject':\n return fromBaziObject(data as Raw);\n case 'pillarMap':\n return fromPillarMap(data as Raw);\n case 'normalized':\n return data as NormalizedChart;\n default:\n throw new Error(\n '[bazi-chart] Unrecognized chart data. Expected a bazi-object chart, ' +\n 'a pillar-map chart, or a pre-normalized NormalizedChart.',\n );\n }\n}\n","import type { ElementKey } from 'bazi-terms';\n\n/** Light/dark colour palette for the chart surface. */\nexport interface ThemePalette {\n bg: string;\n card: string;\n cardAlt: string;\n border: string;\n text: string;\n muted: string;\n accent: string;\n}\n\nexport type ThemeName = 'light' | 'dark';\n\nexport const PALETTES: Record<ThemeName, ThemePalette> = {\n light: {\n bg: '#ffffff',\n card: '#fafafa',\n cardAlt: '#f1f1f3',\n border: '#e4e4e7',\n text: '#18181b',\n muted: '#71717a',\n accent: '#a16207',\n },\n dark: {\n bg: '#18181b',\n card: '#27272a',\n cardAlt: '#333338',\n border: '#3f3f46',\n text: '#fafafa',\n muted: '#a1a1aa',\n accent: '#fbbf24',\n },\n};\n\n/**\n * Traditional Five-Element colours, tuned for readable contrast on both\n * light and dark surfaces: wood=green, fire=red, earth=brown, metal=gold, water=blue.\n */\nexport const ELEMENT_COLORS: Record<ElementKey, Record<ThemeName, string>> = {\n wood: { light: '#15803d', dark: '#4ade80' },\n fire: { light: '#dc2626', dark: '#f87171' },\n earth: { light: '#a0522d', dark: '#d2a679' },\n metal: { light: '#b8860b', dark: '#e6c34a' },\n water: { light: '#2563eb', dark: '#60a5fa' },\n};\n\n/** Fallback colour when an element cannot be resolved. */\nexport const NEUTRAL_COLOR: Record<ThemeName, string> = {\n light: '#52525b',\n dark: '#d4d4d8',\n};\n\n/** Resolve the colour for an element key under a theme. */\nexport function elementColor(key: ElementKey | undefined, theme: ThemeName): string {\n if (!key) return NEUTRAL_COLOR[theme];\n return ELEMENT_COLORS[key]?.[theme] ?? NEUTRAL_COLOR[theme];\n}\n","import { t, translate, elementOf, branchByChar, stemByChar } from 'bazi-terms';\nimport type { ElementKey } from 'bazi-terms';\nimport type { ChartLang } from './types.js';\n\n/**\n * Combine a Chinese and English string according to the render language.\n * For 'both', the two are joined with a middle dot unless they are identical.\n */\nexport function combine(zh: string, en: string, lang: ChartLang): string {\n if (lang === 'zh') return zh;\n if (lang === 'en') return en;\n if (!en || en === zh) return zh;\n return `${zh} · ${en}`;\n}\n\n/** Translate a UI label by its term key (from bazi-terms). */\nexport function labelText(key: string, lang: ChartLang): string {\n return combine(t(key, 'zh'), t(key, 'en'), lang);\n}\n\n/**\n * Translate a raw engine value (Chinese label or English key) into the target\n * render language. Unknown values fall back to the original string.\n */\nexport function valueText(raw: string | undefined, lang: ChartLang): string {\n if (!raw) return '';\n const zh = translate(raw, 'zh') || raw;\n const en = translate(raw, 'en');\n return combine(zh, en, lang);\n}\n\n/** Resolve an element key from a raw Chinese character or English key. */\nexport function elementKeyOf(raw: string | undefined): ElementKey | undefined {\n if (!raw) return undefined;\n return elementOf(raw)?.key;\n}\n\n/** Resolve the element key of a Heavenly Stem character. */\nexport function stemElement(char: string | undefined): ElementKey | undefined {\n if (!char) return undefined;\n return stemByChar(char)?.element;\n}\n\n/** Resolve the element key of an Earthly Branch character. */\nexport function branchElement(char: string | undefined): ElementKey | undefined {\n if (!char) return undefined;\n return branchByChar(char)?.element;\n}\n\n/** Resolve the zodiac (English) of an Earthly Branch character. */\nexport function branchZodiac(char: string | undefined, lang: ChartLang): string {\n if (!char) return '';\n const b = branchByChar(char);\n if (!b) return '';\n return combine(b.zodiacZh, b.zodiacEn, lang);\n}\n","import type { CSSProperties, ReactNode } from 'react';\nimport type {\n ChartLang,\n ElementScore,\n NormalizedChart,\n NormalizedInteraction,\n NormalizedLuckPillar,\n NormalizedPillar,\n PillarPosition,\n} from '../types.js';\nimport { normalize } from '../normalize.js';\nimport { PALETTES, elementColor, type ThemeName, type ThemePalette } from '../theme.js';\nimport {\n branchZodiac,\n combine,\n elementKeyOf,\n labelText,\n stemElement,\n branchElement,\n valueText,\n} from '../i18n.js';\n\nconst POS_LABEL: Record<PillarPosition, string> = {\n year: 'yearPillar',\n month: 'monthPillar',\n day: 'dayPillar',\n hour: 'hourPillar',\n};\n\nexport interface BaziChartProps {\n /** Raw chart data from a supported Bazi engine. Auto-detected. */\n data?: unknown;\n /** A pre-normalized chart; takes precedence over `data` when both are given. */\n chart?: NormalizedChart;\n /** Render language. Default 'both'. */\n lang?: ChartLang;\n /** Colour theme. Default 'light'. */\n theme?: ThemeName;\n /** Show the Luck Pillar (大运) timeline. Default true. */\n showDaYun?: boolean;\n /** Show the interactions (刑冲合会) panel. Default true. */\n showInteractions?: boolean;\n /** Show the Five-Element score bars (only some engines emit these). Default true. */\n showFiveElements?: boolean;\n /** Show per-pillar Shen Sha stars (only some engines emit these). Default true. */\n showShenSha?: boolean;\n /** Optional overrides merged onto the root container style. */\n style?: CSSProperties;\n}\n\n/**\n * `<BaziChart />` renders a complete Bazi (Four Pillars) chart from any\n * supported input format, bilingually, with inline styles only (SSR-safe, zero CSS deps).\n *\n * @example\n * const chart = myBaziEngine.calculate({ ... });\n * <BaziChart data={chart} lang=\"en\" />\n */\nexport function BaziChart(props: BaziChartProps): ReactNode {\n const {\n lang = 'both',\n theme = 'light',\n showDaYun = true,\n showInteractions = true,\n showFiveElements = true,\n showShenSha = true,\n style,\n } = props;\n\n const chart = props.chart ?? (props.data !== undefined ? normalize(props.data) : undefined);\n const p: ThemePalette = PALETTES[theme];\n\n /* ---------- shared inline styles (static, SSR-safe) ---------- */\n const box: CSSProperties = {\n background: p.bg,\n color: p.text,\n fontFamily:\n '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"PingFang SC\", \"Microsoft YaHei\", sans-serif',\n fontSize: 14,\n lineHeight: 1.5,\n padding: 20,\n borderRadius: 12,\n border: `1px solid ${p.border}`,\n boxSizing: 'border-box',\n maxWidth: 860,\n };\n const card: CSSProperties = {\n background: p.card,\n border: `1px solid ${p.border}`,\n borderRadius: 10,\n padding: 12,\n boxSizing: 'border-box',\n };\n const sectionTitle: CSSProperties = {\n fontSize: 13,\n fontWeight: 600,\n letterSpacing: 0.4,\n color: p.accent,\n textTransform: 'uppercase',\n margin: '20px 0 10px',\n };\n const muted: CSSProperties = { color: p.muted, fontSize: 12 };\n const bigChar = (color: string): CSSProperties => ({\n color,\n fontSize: 34,\n fontWeight: 700,\n lineHeight: 1.1,\n });\n const chip: CSSProperties = {\n display: 'inline-block',\n background: p.cardAlt,\n border: `1px solid ${p.border}`,\n borderRadius: 999,\n padding: '2px 9px',\n fontSize: 12,\n margin: '2px 4px 2px 0',\n whiteSpace: 'nowrap',\n };\n\n if (!chart) {\n return (\n <div style={{ ...box, ...style }}>\n <span style={muted}>\n No chart data. Pass `data` (engine output) or `chart` (NormalizedChart).\n </span>\n </div>\n );\n }\n\n const dmElementKey = elementKeyOf(chart.dayMaster.element ?? chart.dayMasterElement);\n\n /* ---------- header ---------- */\n const header = (\n <div style={{ display: 'flex', flexWrap: 'wrap', alignItems: 'baseline', gap: 10 }}>\n <h3 style={{ margin: 0, fontSize: 18, fontWeight: 700 }}>{labelText('bazi', lang)}</h3>\n {chart.dayMaster.char ? (\n <span style={chip}>\n {labelText('dayMaster', lang)}:{' '}\n <strong style={{ color: elementColor(dmElementKey, theme) }}>{chart.dayMaster.char}</strong>\n {dmElementKey ? ` (${valueText(dmElementKey, lang)})` : ''}\n </span>\n ) : null}\n {chart.meta.zodiac ? (\n <span style={chip}>\n {labelText('shengXiao', lang)}: {valueText(chart.meta.zodiac, lang)}\n </span>\n ) : null}\n {chart.meta.gender ? (\n <span style={chip}>\n {labelText('gender', lang)}: {valueText(chart.meta.gender, lang)}\n </span>\n ) : null}\n </div>\n );\n\n /* ---------- meta bar ---------- */\n const metaItems: string[] = [];\n if (chart.meta.solar) metaItems.push(`${labelText('gongLi', lang)}: ${chart.meta.solar}`);\n if (chart.meta.lunar) metaItems.push(`${labelText('nongLi', lang)}: ${chart.meta.lunar}`);\n if (chart.solarTime?.trueSolar)\n metaItems.push(`${labelText('zhenTaiYangShi', lang)}: ${chart.solarTime.trueSolar}`);\n if (chart.solarTime?.shiChen)\n metaItems.push(`${labelText('shiChen', lang)}: ${valueText(chart.solarTime.shiChen.replace('时', ''), lang)}`);\n const metaBar = metaItems.length ? (\n <div style={{ ...muted, marginTop: 8 }}>\n {metaItems.map((m, i) => (\n <span key={i} style={{ marginRight: 14, display: 'inline-block' }}>\n {m}\n </span>\n ))}\n </div>\n ) : null;\n\n /* ---------- pillars ---------- */\n const renderPillar = (pillar: NormalizedPillar) => {\n const sColor = elementColor(stemElement(pillar.stem), theme);\n const bColor = elementColor(branchElement(pillar.branch), theme);\n const isDay = pillar.position === 'day';\n return (\n <div\n key={pillar.position}\n style={{\n ...card,\n flex: '1 1 150px',\n minWidth: 150,\n borderColor: isDay ? p.accent : p.border,\n borderWidth: isDay ? 2 : 1,\n }}\n >\n <div style={{ ...muted, textAlign: 'center', fontWeight: 600, marginBottom: 6 }}>\n {labelText(POS_LABEL[pillar.position], lang)}\n </div>\n <div style={{ textAlign: 'center', fontSize: 12, minHeight: 18, color: p.muted }}>\n {pillar.mainTenGod ? valueText(pillar.mainTenGod, lang) : ''}\n </div>\n <div style={{ textAlign: 'center', margin: '6px 0' }}>\n <div style={bigChar(sColor)}>{pillar.stem}</div>\n <div style={{ ...muted, fontSize: 11 }}>\n {stemElement(pillar.stem) ? valueText(stemElement(pillar.stem) as string, lang) : ''}\n </div>\n </div>\n <div style={{ textAlign: 'center', margin: '6px 0' }}>\n <div style={bigChar(bColor)}>{pillar.branch}</div>\n <div style={{ ...muted, fontSize: 11 }}>{branchZodiac(pillar.branch, lang)}</div>\n </div>\n {pillar.hiddenStems.length ? (\n <div style={{ borderTop: `1px solid ${p.border}`, marginTop: 8, paddingTop: 6 }}>\n <div style={{ ...muted, fontSize: 11, marginBottom: 4 }}>{labelText('hiddenStems', lang)}</div>\n <div style={{ textAlign: 'center' }}>\n {pillar.hiddenStems.map((h, i) => (\n <span key={i} style={{ display: 'inline-block', margin: '0 4px', fontSize: 12 }}>\n <strong style={{ color: elementColor(stemElement(h.char), theme) }}>{h.char}</strong>\n {h.tenGod ? <span style={{ ...muted, fontSize: 10, display: 'block' }}>{valueText(h.tenGod, lang)}</span> : null}\n </span>\n ))}\n </div>\n </div>\n ) : null}\n <div style={{ borderTop: `1px solid ${p.border}`, marginTop: 8, paddingTop: 6, fontSize: 11, color: p.muted }}>\n {pillar.naYin ? (\n <div>\n {labelText('naYin', lang)}: {valueText(pillar.naYin, lang)}\n </div>\n ) : null}\n {pillar.growthStage ? (\n <div>\n {labelText('xingYun', lang)}: {valueText(pillar.growthStage, lang)}\n </div>\n ) : null}\n {pillar.voidBranches?.length ? (\n <div>\n {labelText('kongWang', lang)}: {pillar.voidBranches.join('')}\n </div>\n ) : null}\n </div>\n {showShenSha && pillar.shenSha?.length ? (\n <div style={{ marginTop: 8 }}>\n {pillar.shenSha.map((s, i) => (\n <span key={i} style={{ ...chip, fontSize: 11 }}>\n {valueText(s, lang)}\n </span>\n ))}\n </div>\n ) : null}\n </div>\n );\n };\n\n const pillars = (\n <div style={{ display: 'flex', flexWrap: 'wrap', gap: 10, marginTop: 14 }}>\n {chart.pillars.map(renderPillar)}\n </div>\n );\n\n /* ---------- five elements ---------- */\n const renderFiveElements = (scores: ElementScore[]) => {\n const max = Math.max(...scores.map((s) => s.score ?? 0), 1);\n return (\n <div>\n <div style={sectionTitle}>{labelText('wuXingFenZhi', lang)}</div>\n <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>\n {scores.map((s, i) => {\n const key = elementKeyOf(s.element);\n const width = Math.round(((s.score ?? 0) / max) * 100);\n const isDm = s.element === chart.dayMasterElement;\n return (\n <div key={i} style={{ display: 'flex', alignItems: 'center', gap: 8 }}>\n <div style={{ width: 88, fontSize: 12, color: elementColor(key, theme), fontWeight: isDm ? 700 : 400 }}>\n {valueText(s.element, lang)}\n </div>\n <div style={{ flex: 1, background: p.cardAlt, borderRadius: 6, height: 14, overflow: 'hidden' }}>\n <div style={{ width: `${width}%`, height: '100%', background: elementColor(key, theme) }} />\n </div>\n <div style={{ width: 74, textAlign: 'right', ...muted }}>\n {s.score != null ? s.score : ''}\n {s.percent ? ` (${s.percent})` : ''}\n </div>\n </div>\n );\n })}\n </div>\n </div>\n );\n };\n\n /* ---------- interactions ---------- */\n const renderInteractions = (items: NormalizedInteraction[]) => (\n <div>\n <div style={sectionTitle}>{labelText('interactions', lang)}</div>\n <div>\n {items.map((it, i) => (\n <span key={i} style={chip} title={it.description ?? undefined}>\n <strong>{it.typeKey ? labelText(it.typeKey, lang) : it.description ?? ''}</strong>\n {it.typeKey && it.branches?.length ? ` ${it.branches.join('')}` : ''}\n </span>\n ))}\n </div>\n </div>\n );\n\n /* ---------- da yun ---------- */\n const renderDaYun = (cycles: NormalizedLuckPillar[]) => (\n <div>\n <div style={sectionTitle}>\n {labelText('daYun', lang)}\n {chart.daYunDirection ? ` · ${labelText(chart.daYunDirection, lang)}` : ''}\n {chart.daYunOnset ? <span style={{ ...muted, textTransform: 'none', marginLeft: 8 }}>{chart.daYunOnset}</span> : null}\n </div>\n <div style={{ display: 'flex', gap: 8, overflowX: 'auto', paddingBottom: 6 }}>\n {cycles.map((c, i) => (\n <div\n key={i}\n style={{\n ...card,\n minWidth: 92,\n flex: '0 0 auto',\n textAlign: 'center',\n borderColor: c.isCurrent ? p.accent : p.border,\n borderWidth: c.isCurrent ? 2 : 1,\n }}\n >\n <div style={{ fontSize: 20, fontWeight: 700 }}>\n <span style={{ color: elementColor(stemElement(c.ganZhi[0]), theme) }}>{c.ganZhi[0]}</span>\n <span style={{ color: elementColor(branchElement(c.ganZhi[1]), theme) }}>{c.ganZhi[1]}</span>\n </div>\n {c.stemTenGod ? <div style={{ ...muted, fontSize: 11 }}>{valueText(c.stemTenGod, lang)}</div> : null}\n <div style={{ ...muted, fontSize: 11, marginTop: 4 }}>\n {c.startAge != null && c.endAge != null ? `${c.startAge}–${c.endAge}` : ''}\n </div>\n <div style={{ ...muted, fontSize: 10 }}>\n {c.startYear != null && c.endYear != null ? `${c.startYear}–${c.endYear}` : ''}\n </div>\n {c.isCurrent ? <div style={{ fontSize: 10, color: p.accent, marginTop: 2 }}>{labelText('current', lang)}</div> : null}\n </div>\n ))}\n </div>\n </div>\n );\n\n /* ---------- extras (palaces) ---------- */\n const renderExtras = (chart: NormalizedChart) => {\n const ex = chart.extras;\n if (!ex) return null;\n const rows: [string, string | undefined][] = [\n ['mingGong', ex.mingGong],\n ['shenGong', ex.shenGong],\n ['taiYuan', ex.taiYuan],\n ['taiXi', ex.taiXi],\n ];\n const filled = rows.filter(([, v]) => v);\n if (!filled.length) return null;\n return (\n <div>\n <div style={sectionTitle}>{combine('宫位', 'Palaces', lang)}</div>\n <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8 }}>\n {filled.map(([k, v], i) => (\n <span key={i} style={chip}>\n <span style={muted}>{labelText(k, lang)}:</span> <strong>{v}</strong>\n </span>\n ))}\n </div>\n </div>\n );\n };\n\n return (\n <div style={{ ...box, ...style }}>\n {header}\n {metaBar}\n {pillars}\n {showFiveElements && chart.fiveElements?.length ? renderFiveElements(chart.fiveElements) : null}\n {showInteractions && chart.interactions.length ? renderInteractions(chart.interactions) : null}\n {showDaYun && chart.daYun.length ? renderDaYun(chart.daYun) : null}\n {renderExtras(chart)}\n </div>\n );\n}\n"],"mappings":"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","names":["import_bazi_terms","adaptPillar","adaptInteractions","adaptDaYun","import_bazi_terms","chart"]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
import { ElementKey } from 'bazi-terms';
|
|
2
|
+
import { CSSProperties, ReactNode } from 'react';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Normalized chart model — the single shape every adapter produces.
|
|
6
|
+
*
|
|
7
|
+
* Design principle: adapters only RESHAPE raw engine output and keep the
|
|
8
|
+
* original Chinese values. Everything derivable (element, polarity, colour,
|
|
9
|
+
* bilingual labels) is resolved at render time from `bazi-terms`, so the
|
|
10
|
+
* model stays lean and engine-agnostic.
|
|
11
|
+
*/
|
|
12
|
+
/** Rendering language: Chinese, English, or both side by side. */
|
|
13
|
+
type ChartLang = 'zh' | 'en' | 'both';
|
|
14
|
+
/** Which engine (or a pre-normalized object) the input came from. */
|
|
15
|
+
type EngineName = 'baziObject' | 'pillarMap' | 'normalized' | 'unknown';
|
|
16
|
+
/** Pillar position, ordered year → month → day → hour. */
|
|
17
|
+
type PillarPosition = 'year' | 'month' | 'day' | 'hour';
|
|
18
|
+
/** A stem hidden inside a branch, with its ten god relative to the Day Master. */
|
|
19
|
+
interface NormalizedHiddenStem {
|
|
20
|
+
/** Stem character, e.g. '己'. */
|
|
21
|
+
char: string;
|
|
22
|
+
/** Ten god in raw Chinese, e.g. '正印'. Resolved via bazi-terms at render. */
|
|
23
|
+
tenGod?: string;
|
|
24
|
+
/** Whether this is the branch's main (本气) hidden stem. */
|
|
25
|
+
isMain?: boolean;
|
|
26
|
+
}
|
|
27
|
+
/** One of the four pillars, normalized. */
|
|
28
|
+
interface NormalizedPillar {
|
|
29
|
+
position: PillarPosition;
|
|
30
|
+
/** Combined stem-branch, e.g. '乙丑'. */
|
|
31
|
+
ganZhi: string;
|
|
32
|
+
/** Heavenly Stem character, e.g. '乙'. */
|
|
33
|
+
stem: string;
|
|
34
|
+
/** Earthly Branch character, e.g. '丑'. */
|
|
35
|
+
branch: string;
|
|
36
|
+
/** Main ten god of the pillar (主星 / stemTenGod, depending on format), raw Chinese. */
|
|
37
|
+
mainTenGod?: string;
|
|
38
|
+
/** Secondary ten gods (副星, when present), raw Chinese. */
|
|
39
|
+
secondaryTenGods?: string[];
|
|
40
|
+
/** Hidden stems with their ten gods. */
|
|
41
|
+
hiddenStems: NormalizedHiddenStem[];
|
|
42
|
+
/** Na Yin melody, raw Chinese, e.g. '海中金'. */
|
|
43
|
+
naYin?: string;
|
|
44
|
+
/** Growth stage (星运 / growthStage), raw Chinese, e.g. '墓'. */
|
|
45
|
+
growthStage?: string;
|
|
46
|
+
/** Void branch characters (空亡 / voidBranches), e.g. ['戌','亥']. */
|
|
47
|
+
voidBranches?: string[];
|
|
48
|
+
/** Shen Sha star names, raw Chinese (only some formats emit these). */
|
|
49
|
+
shenSha?: string[];
|
|
50
|
+
/** Decade (旬) stem-branch, e.g. '甲子' (only some formats emit this). */
|
|
51
|
+
xun?: string;
|
|
52
|
+
}
|
|
53
|
+
/** One ten-year Luck Pillar (大运). */
|
|
54
|
+
interface NormalizedLuckPillar {
|
|
55
|
+
ganZhi: string;
|
|
56
|
+
stem?: string;
|
|
57
|
+
branch?: string;
|
|
58
|
+
stemTenGod?: string;
|
|
59
|
+
branchTenGod?: string;
|
|
60
|
+
startAge?: number;
|
|
61
|
+
endAge?: number;
|
|
62
|
+
startYear?: number;
|
|
63
|
+
endYear?: number;
|
|
64
|
+
naYin?: string;
|
|
65
|
+
isCurrent?: boolean;
|
|
66
|
+
}
|
|
67
|
+
/** One interaction (刑冲合会) between branches or stems. */
|
|
68
|
+
interface NormalizedInteraction {
|
|
69
|
+
/** Resolved interaction type key from bazi-terms, when recognized. */
|
|
70
|
+
typeKey?: string;
|
|
71
|
+
/** Branch or stem characters involved. */
|
|
72
|
+
branches?: string[];
|
|
73
|
+
/** Pillar positions involved (some formats provide these). */
|
|
74
|
+
pillars?: string[];
|
|
75
|
+
/** Raw description from the engine. */
|
|
76
|
+
description?: string;
|
|
77
|
+
}
|
|
78
|
+
/** Five-element strength score (五行分值). */
|
|
79
|
+
interface ElementScore {
|
|
80
|
+
/** Element in raw Chinese, e.g. '金'. */
|
|
81
|
+
element: string;
|
|
82
|
+
score?: number;
|
|
83
|
+
/** Percentage string as emitted by the engine, e.g. '16%'. */
|
|
84
|
+
percent?: string;
|
|
85
|
+
}
|
|
86
|
+
/** Chart-level metadata. */
|
|
87
|
+
interface ChartMeta {
|
|
88
|
+
engine: EngineName;
|
|
89
|
+
/** Gender in raw Chinese, e.g. '男' (only some formats). */
|
|
90
|
+
gender?: string;
|
|
91
|
+
/** Zodiac animal in raw Chinese, e.g. '马' / '牛'. */
|
|
92
|
+
zodiac?: string;
|
|
93
|
+
/** Lunar date string, raw. */
|
|
94
|
+
lunar?: string;
|
|
95
|
+
/** Solar date string, raw. */
|
|
96
|
+
solar?: string;
|
|
97
|
+
}
|
|
98
|
+
/** True solar time correction block. */
|
|
99
|
+
interface SolarTime {
|
|
100
|
+
clock?: string;
|
|
101
|
+
trueSolar?: string;
|
|
102
|
+
correctionMinutes?: number;
|
|
103
|
+
/** Double-hour name in raw Chinese, e.g. '巳时' (only some formats). */
|
|
104
|
+
shiChen?: string;
|
|
105
|
+
}
|
|
106
|
+
/** Day Master summary. Element/polarity are derived from `char` at render. */
|
|
107
|
+
interface DayMasterInfo {
|
|
108
|
+
char?: string;
|
|
109
|
+
/** Raw element value; may be Chinese ('金') or an English key ('metal'). */
|
|
110
|
+
element?: string;
|
|
111
|
+
/** 'yang' | 'yin' when the engine provides it. */
|
|
112
|
+
polarity?: string;
|
|
113
|
+
}
|
|
114
|
+
/** Auxiliary palaces (only some formats emit these). */
|
|
115
|
+
interface ChartExtras {
|
|
116
|
+
mingGong?: string;
|
|
117
|
+
shenGong?: string;
|
|
118
|
+
taiYuan?: string;
|
|
119
|
+
taiXi?: string;
|
|
120
|
+
}
|
|
121
|
+
/** The complete normalized chart consumed by `<BaziChart />`. */
|
|
122
|
+
interface NormalizedChart {
|
|
123
|
+
meta: ChartMeta;
|
|
124
|
+
solarTime?: SolarTime;
|
|
125
|
+
dayMaster: DayMasterInfo;
|
|
126
|
+
/** Always up to four pillars; the hour pillar may be absent for late-night births. */
|
|
127
|
+
pillars: NormalizedPillar[];
|
|
128
|
+
fiveElements?: ElementScore[];
|
|
129
|
+
dayMasterElement?: string;
|
|
130
|
+
daYun: NormalizedLuckPillar[];
|
|
131
|
+
daYunDirection?: 'forward' | 'backward';
|
|
132
|
+
daYunOnset?: string;
|
|
133
|
+
interactions: NormalizedInteraction[];
|
|
134
|
+
extras?: ChartExtras;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Detect which engine produced `data` (or whether it is already normalized).
|
|
139
|
+
* Detection is intentionally structural and order-safe:
|
|
140
|
+
* 1. bazi-object format → top-level `八字` object
|
|
141
|
+
* 2. pre-normalized → `meta.engine`, or `pillars` as an array with `position`
|
|
142
|
+
* 3. pillar-map format → `pillars` as an object keyed by year/month/day/hour
|
|
143
|
+
*/
|
|
144
|
+
declare function detectEngine(data: unknown): EngineName;
|
|
145
|
+
/**
|
|
146
|
+
* Normalize any supported input into a NormalizedChart.
|
|
147
|
+
* Accepts a raw bazi-object chart, a raw pillar-map chart,
|
|
148
|
+
* or an already-normalized chart (returned as-is).
|
|
149
|
+
*
|
|
150
|
+
* @throws when the input matches none of the supported shapes.
|
|
151
|
+
*/
|
|
152
|
+
declare function normalize(data: unknown): NormalizedChart;
|
|
153
|
+
|
|
154
|
+
/** Light/dark colour palette for the chart surface. */
|
|
155
|
+
interface ThemePalette {
|
|
156
|
+
bg: string;
|
|
157
|
+
card: string;
|
|
158
|
+
cardAlt: string;
|
|
159
|
+
border: string;
|
|
160
|
+
text: string;
|
|
161
|
+
muted: string;
|
|
162
|
+
accent: string;
|
|
163
|
+
}
|
|
164
|
+
type ThemeName = 'light' | 'dark';
|
|
165
|
+
declare const PALETTES: Record<ThemeName, ThemePalette>;
|
|
166
|
+
/**
|
|
167
|
+
* Traditional Five-Element colours, tuned for readable contrast on both
|
|
168
|
+
* light and dark surfaces: wood=green, fire=red, earth=brown, metal=gold, water=blue.
|
|
169
|
+
*/
|
|
170
|
+
declare const ELEMENT_COLORS: Record<ElementKey, Record<ThemeName, string>>;
|
|
171
|
+
/** Fallback colour when an element cannot be resolved. */
|
|
172
|
+
declare const NEUTRAL_COLOR: Record<ThemeName, string>;
|
|
173
|
+
/** Resolve the colour for an element key under a theme. */
|
|
174
|
+
declare function elementColor(key: ElementKey | undefined, theme: ThemeName): string;
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Combine a Chinese and English string according to the render language.
|
|
178
|
+
* For 'both', the two are joined with a middle dot unless they are identical.
|
|
179
|
+
*/
|
|
180
|
+
declare function combine(zh: string, en: string, lang: ChartLang): string;
|
|
181
|
+
/** Translate a UI label by its term key (from bazi-terms). */
|
|
182
|
+
declare function labelText(key: string, lang: ChartLang): string;
|
|
183
|
+
/**
|
|
184
|
+
* Translate a raw engine value (Chinese label or English key) into the target
|
|
185
|
+
* render language. Unknown values fall back to the original string.
|
|
186
|
+
*/
|
|
187
|
+
declare function valueText(raw: string | undefined, lang: ChartLang): string;
|
|
188
|
+
/** Resolve an element key from a raw Chinese character or English key. */
|
|
189
|
+
declare function elementKeyOf(raw: string | undefined): ElementKey | undefined;
|
|
190
|
+
/** Resolve the element key of a Heavenly Stem character. */
|
|
191
|
+
declare function stemElement(char: string | undefined): ElementKey | undefined;
|
|
192
|
+
/** Resolve the element key of an Earthly Branch character. */
|
|
193
|
+
declare function branchElement(char: string | undefined): ElementKey | undefined;
|
|
194
|
+
/** Resolve the zodiac (English) of an Earthly Branch character. */
|
|
195
|
+
declare function branchZodiac(char: string | undefined, lang: ChartLang): string;
|
|
196
|
+
|
|
197
|
+
type Raw$1 = Record<string, any>;
|
|
198
|
+
/**
|
|
199
|
+
* Normalize a Chinese-field chart object (top-level `八字`) into a NormalizedChart.
|
|
200
|
+
* The input uses Chinese field names throughout.
|
|
201
|
+
*/
|
|
202
|
+
declare function fromBaziObject(data: Raw$1): NormalizedChart;
|
|
203
|
+
|
|
204
|
+
type Raw = Record<string, any>;
|
|
205
|
+
/**
|
|
206
|
+
* Normalize a pillar-map chart object (`pillars` keyed by year/month/day/hour) into a NormalizedChart.
|
|
207
|
+
* Field names are English; ten gods, Na Yin and growth stages are Chinese values;
|
|
208
|
+
* elements are English keys ('metal'). All are passed through raw — the renderer
|
|
209
|
+
* resolves them via bazi-terms, which accepts both Chinese and English keys.
|
|
210
|
+
*/
|
|
211
|
+
declare function fromPillarMap(data: Raw): NormalizedChart;
|
|
212
|
+
|
|
213
|
+
interface BaziChartProps {
|
|
214
|
+
/** Raw chart data from a supported Bazi engine. Auto-detected. */
|
|
215
|
+
data?: unknown;
|
|
216
|
+
/** A pre-normalized chart; takes precedence over `data` when both are given. */
|
|
217
|
+
chart?: NormalizedChart;
|
|
218
|
+
/** Render language. Default 'both'. */
|
|
219
|
+
lang?: ChartLang;
|
|
220
|
+
/** Colour theme. Default 'light'. */
|
|
221
|
+
theme?: ThemeName;
|
|
222
|
+
/** Show the Luck Pillar (大运) timeline. Default true. */
|
|
223
|
+
showDaYun?: boolean;
|
|
224
|
+
/** Show the interactions (刑冲合会) panel. Default true. */
|
|
225
|
+
showInteractions?: boolean;
|
|
226
|
+
/** Show the Five-Element score bars (only some engines emit these). Default true. */
|
|
227
|
+
showFiveElements?: boolean;
|
|
228
|
+
/** Show per-pillar Shen Sha stars (only some engines emit these). Default true. */
|
|
229
|
+
showShenSha?: boolean;
|
|
230
|
+
/** Optional overrides merged onto the root container style. */
|
|
231
|
+
style?: CSSProperties;
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* `<BaziChart />` renders a complete Bazi (Four Pillars) chart from any
|
|
235
|
+
* supported input format, bilingually, with inline styles only (SSR-safe, zero CSS deps).
|
|
236
|
+
*
|
|
237
|
+
* @example
|
|
238
|
+
* const chart = myBaziEngine.calculate({ ... });
|
|
239
|
+
* <BaziChart data={chart} lang="en" />
|
|
240
|
+
*/
|
|
241
|
+
declare function BaziChart(props: BaziChartProps): ReactNode;
|
|
242
|
+
|
|
243
|
+
export { BaziChart, type BaziChartProps, type ChartExtras, type ChartLang, type ChartMeta, type DayMasterInfo, ELEMENT_COLORS, type ElementScore, type EngineName, NEUTRAL_COLOR, type NormalizedChart, type NormalizedHiddenStem, type NormalizedInteraction, type NormalizedLuckPillar, type NormalizedPillar, PALETTES, type PillarPosition, type SolarTime, type ThemeName, type ThemePalette, branchElement, branchZodiac, combine, detectEngine, elementColor, elementKeyOf, fromBaziObject, fromPillarMap, labelText, normalize, stemElement, valueText };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
import { ElementKey } from 'bazi-terms';
|
|
2
|
+
import { CSSProperties, ReactNode } from 'react';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Normalized chart model — the single shape every adapter produces.
|
|
6
|
+
*
|
|
7
|
+
* Design principle: adapters only RESHAPE raw engine output and keep the
|
|
8
|
+
* original Chinese values. Everything derivable (element, polarity, colour,
|
|
9
|
+
* bilingual labels) is resolved at render time from `bazi-terms`, so the
|
|
10
|
+
* model stays lean and engine-agnostic.
|
|
11
|
+
*/
|
|
12
|
+
/** Rendering language: Chinese, English, or both side by side. */
|
|
13
|
+
type ChartLang = 'zh' | 'en' | 'both';
|
|
14
|
+
/** Which engine (or a pre-normalized object) the input came from. */
|
|
15
|
+
type EngineName = 'baziObject' | 'pillarMap' | 'normalized' | 'unknown';
|
|
16
|
+
/** Pillar position, ordered year → month → day → hour. */
|
|
17
|
+
type PillarPosition = 'year' | 'month' | 'day' | 'hour';
|
|
18
|
+
/** A stem hidden inside a branch, with its ten god relative to the Day Master. */
|
|
19
|
+
interface NormalizedHiddenStem {
|
|
20
|
+
/** Stem character, e.g. '己'. */
|
|
21
|
+
char: string;
|
|
22
|
+
/** Ten god in raw Chinese, e.g. '正印'. Resolved via bazi-terms at render. */
|
|
23
|
+
tenGod?: string;
|
|
24
|
+
/** Whether this is the branch's main (本气) hidden stem. */
|
|
25
|
+
isMain?: boolean;
|
|
26
|
+
}
|
|
27
|
+
/** One of the four pillars, normalized. */
|
|
28
|
+
interface NormalizedPillar {
|
|
29
|
+
position: PillarPosition;
|
|
30
|
+
/** Combined stem-branch, e.g. '乙丑'. */
|
|
31
|
+
ganZhi: string;
|
|
32
|
+
/** Heavenly Stem character, e.g. '乙'. */
|
|
33
|
+
stem: string;
|
|
34
|
+
/** Earthly Branch character, e.g. '丑'. */
|
|
35
|
+
branch: string;
|
|
36
|
+
/** Main ten god of the pillar (主星 / stemTenGod, depending on format), raw Chinese. */
|
|
37
|
+
mainTenGod?: string;
|
|
38
|
+
/** Secondary ten gods (副星, when present), raw Chinese. */
|
|
39
|
+
secondaryTenGods?: string[];
|
|
40
|
+
/** Hidden stems with their ten gods. */
|
|
41
|
+
hiddenStems: NormalizedHiddenStem[];
|
|
42
|
+
/** Na Yin melody, raw Chinese, e.g. '海中金'. */
|
|
43
|
+
naYin?: string;
|
|
44
|
+
/** Growth stage (星运 / growthStage), raw Chinese, e.g. '墓'. */
|
|
45
|
+
growthStage?: string;
|
|
46
|
+
/** Void branch characters (空亡 / voidBranches), e.g. ['戌','亥']. */
|
|
47
|
+
voidBranches?: string[];
|
|
48
|
+
/** Shen Sha star names, raw Chinese (only some formats emit these). */
|
|
49
|
+
shenSha?: string[];
|
|
50
|
+
/** Decade (旬) stem-branch, e.g. '甲子' (only some formats emit this). */
|
|
51
|
+
xun?: string;
|
|
52
|
+
}
|
|
53
|
+
/** One ten-year Luck Pillar (大运). */
|
|
54
|
+
interface NormalizedLuckPillar {
|
|
55
|
+
ganZhi: string;
|
|
56
|
+
stem?: string;
|
|
57
|
+
branch?: string;
|
|
58
|
+
stemTenGod?: string;
|
|
59
|
+
branchTenGod?: string;
|
|
60
|
+
startAge?: number;
|
|
61
|
+
endAge?: number;
|
|
62
|
+
startYear?: number;
|
|
63
|
+
endYear?: number;
|
|
64
|
+
naYin?: string;
|
|
65
|
+
isCurrent?: boolean;
|
|
66
|
+
}
|
|
67
|
+
/** One interaction (刑冲合会) between branches or stems. */
|
|
68
|
+
interface NormalizedInteraction {
|
|
69
|
+
/** Resolved interaction type key from bazi-terms, when recognized. */
|
|
70
|
+
typeKey?: string;
|
|
71
|
+
/** Branch or stem characters involved. */
|
|
72
|
+
branches?: string[];
|
|
73
|
+
/** Pillar positions involved (some formats provide these). */
|
|
74
|
+
pillars?: string[];
|
|
75
|
+
/** Raw description from the engine. */
|
|
76
|
+
description?: string;
|
|
77
|
+
}
|
|
78
|
+
/** Five-element strength score (五行分值). */
|
|
79
|
+
interface ElementScore {
|
|
80
|
+
/** Element in raw Chinese, e.g. '金'. */
|
|
81
|
+
element: string;
|
|
82
|
+
score?: number;
|
|
83
|
+
/** Percentage string as emitted by the engine, e.g. '16%'. */
|
|
84
|
+
percent?: string;
|
|
85
|
+
}
|
|
86
|
+
/** Chart-level metadata. */
|
|
87
|
+
interface ChartMeta {
|
|
88
|
+
engine: EngineName;
|
|
89
|
+
/** Gender in raw Chinese, e.g. '男' (only some formats). */
|
|
90
|
+
gender?: string;
|
|
91
|
+
/** Zodiac animal in raw Chinese, e.g. '马' / '牛'. */
|
|
92
|
+
zodiac?: string;
|
|
93
|
+
/** Lunar date string, raw. */
|
|
94
|
+
lunar?: string;
|
|
95
|
+
/** Solar date string, raw. */
|
|
96
|
+
solar?: string;
|
|
97
|
+
}
|
|
98
|
+
/** True solar time correction block. */
|
|
99
|
+
interface SolarTime {
|
|
100
|
+
clock?: string;
|
|
101
|
+
trueSolar?: string;
|
|
102
|
+
correctionMinutes?: number;
|
|
103
|
+
/** Double-hour name in raw Chinese, e.g. '巳时' (only some formats). */
|
|
104
|
+
shiChen?: string;
|
|
105
|
+
}
|
|
106
|
+
/** Day Master summary. Element/polarity are derived from `char` at render. */
|
|
107
|
+
interface DayMasterInfo {
|
|
108
|
+
char?: string;
|
|
109
|
+
/** Raw element value; may be Chinese ('金') or an English key ('metal'). */
|
|
110
|
+
element?: string;
|
|
111
|
+
/** 'yang' | 'yin' when the engine provides it. */
|
|
112
|
+
polarity?: string;
|
|
113
|
+
}
|
|
114
|
+
/** Auxiliary palaces (only some formats emit these). */
|
|
115
|
+
interface ChartExtras {
|
|
116
|
+
mingGong?: string;
|
|
117
|
+
shenGong?: string;
|
|
118
|
+
taiYuan?: string;
|
|
119
|
+
taiXi?: string;
|
|
120
|
+
}
|
|
121
|
+
/** The complete normalized chart consumed by `<BaziChart />`. */
|
|
122
|
+
interface NormalizedChart {
|
|
123
|
+
meta: ChartMeta;
|
|
124
|
+
solarTime?: SolarTime;
|
|
125
|
+
dayMaster: DayMasterInfo;
|
|
126
|
+
/** Always up to four pillars; the hour pillar may be absent for late-night births. */
|
|
127
|
+
pillars: NormalizedPillar[];
|
|
128
|
+
fiveElements?: ElementScore[];
|
|
129
|
+
dayMasterElement?: string;
|
|
130
|
+
daYun: NormalizedLuckPillar[];
|
|
131
|
+
daYunDirection?: 'forward' | 'backward';
|
|
132
|
+
daYunOnset?: string;
|
|
133
|
+
interactions: NormalizedInteraction[];
|
|
134
|
+
extras?: ChartExtras;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Detect which engine produced `data` (or whether it is already normalized).
|
|
139
|
+
* Detection is intentionally structural and order-safe:
|
|
140
|
+
* 1. bazi-object format → top-level `八字` object
|
|
141
|
+
* 2. pre-normalized → `meta.engine`, or `pillars` as an array with `position`
|
|
142
|
+
* 3. pillar-map format → `pillars` as an object keyed by year/month/day/hour
|
|
143
|
+
*/
|
|
144
|
+
declare function detectEngine(data: unknown): EngineName;
|
|
145
|
+
/**
|
|
146
|
+
* Normalize any supported input into a NormalizedChart.
|
|
147
|
+
* Accepts a raw bazi-object chart, a raw pillar-map chart,
|
|
148
|
+
* or an already-normalized chart (returned as-is).
|
|
149
|
+
*
|
|
150
|
+
* @throws when the input matches none of the supported shapes.
|
|
151
|
+
*/
|
|
152
|
+
declare function normalize(data: unknown): NormalizedChart;
|
|
153
|
+
|
|
154
|
+
/** Light/dark colour palette for the chart surface. */
|
|
155
|
+
interface ThemePalette {
|
|
156
|
+
bg: string;
|
|
157
|
+
card: string;
|
|
158
|
+
cardAlt: string;
|
|
159
|
+
border: string;
|
|
160
|
+
text: string;
|
|
161
|
+
muted: string;
|
|
162
|
+
accent: string;
|
|
163
|
+
}
|
|
164
|
+
type ThemeName = 'light' | 'dark';
|
|
165
|
+
declare const PALETTES: Record<ThemeName, ThemePalette>;
|
|
166
|
+
/**
|
|
167
|
+
* Traditional Five-Element colours, tuned for readable contrast on both
|
|
168
|
+
* light and dark surfaces: wood=green, fire=red, earth=brown, metal=gold, water=blue.
|
|
169
|
+
*/
|
|
170
|
+
declare const ELEMENT_COLORS: Record<ElementKey, Record<ThemeName, string>>;
|
|
171
|
+
/** Fallback colour when an element cannot be resolved. */
|
|
172
|
+
declare const NEUTRAL_COLOR: Record<ThemeName, string>;
|
|
173
|
+
/** Resolve the colour for an element key under a theme. */
|
|
174
|
+
declare function elementColor(key: ElementKey | undefined, theme: ThemeName): string;
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Combine a Chinese and English string according to the render language.
|
|
178
|
+
* For 'both', the two are joined with a middle dot unless they are identical.
|
|
179
|
+
*/
|
|
180
|
+
declare function combine(zh: string, en: string, lang: ChartLang): string;
|
|
181
|
+
/** Translate a UI label by its term key (from bazi-terms). */
|
|
182
|
+
declare function labelText(key: string, lang: ChartLang): string;
|
|
183
|
+
/**
|
|
184
|
+
* Translate a raw engine value (Chinese label or English key) into the target
|
|
185
|
+
* render language. Unknown values fall back to the original string.
|
|
186
|
+
*/
|
|
187
|
+
declare function valueText(raw: string | undefined, lang: ChartLang): string;
|
|
188
|
+
/** Resolve an element key from a raw Chinese character or English key. */
|
|
189
|
+
declare function elementKeyOf(raw: string | undefined): ElementKey | undefined;
|
|
190
|
+
/** Resolve the element key of a Heavenly Stem character. */
|
|
191
|
+
declare function stemElement(char: string | undefined): ElementKey | undefined;
|
|
192
|
+
/** Resolve the element key of an Earthly Branch character. */
|
|
193
|
+
declare function branchElement(char: string | undefined): ElementKey | undefined;
|
|
194
|
+
/** Resolve the zodiac (English) of an Earthly Branch character. */
|
|
195
|
+
declare function branchZodiac(char: string | undefined, lang: ChartLang): string;
|
|
196
|
+
|
|
197
|
+
type Raw$1 = Record<string, any>;
|
|
198
|
+
/**
|
|
199
|
+
* Normalize a Chinese-field chart object (top-level `八字`) into a NormalizedChart.
|
|
200
|
+
* The input uses Chinese field names throughout.
|
|
201
|
+
*/
|
|
202
|
+
declare function fromBaziObject(data: Raw$1): NormalizedChart;
|
|
203
|
+
|
|
204
|
+
type Raw = Record<string, any>;
|
|
205
|
+
/**
|
|
206
|
+
* Normalize a pillar-map chart object (`pillars` keyed by year/month/day/hour) into a NormalizedChart.
|
|
207
|
+
* Field names are English; ten gods, Na Yin and growth stages are Chinese values;
|
|
208
|
+
* elements are English keys ('metal'). All are passed through raw — the renderer
|
|
209
|
+
* resolves them via bazi-terms, which accepts both Chinese and English keys.
|
|
210
|
+
*/
|
|
211
|
+
declare function fromPillarMap(data: Raw): NormalizedChart;
|
|
212
|
+
|
|
213
|
+
interface BaziChartProps {
|
|
214
|
+
/** Raw chart data from a supported Bazi engine. Auto-detected. */
|
|
215
|
+
data?: unknown;
|
|
216
|
+
/** A pre-normalized chart; takes precedence over `data` when both are given. */
|
|
217
|
+
chart?: NormalizedChart;
|
|
218
|
+
/** Render language. Default 'both'. */
|
|
219
|
+
lang?: ChartLang;
|
|
220
|
+
/** Colour theme. Default 'light'. */
|
|
221
|
+
theme?: ThemeName;
|
|
222
|
+
/** Show the Luck Pillar (大运) timeline. Default true. */
|
|
223
|
+
showDaYun?: boolean;
|
|
224
|
+
/** Show the interactions (刑冲合会) panel. Default true. */
|
|
225
|
+
showInteractions?: boolean;
|
|
226
|
+
/** Show the Five-Element score bars (only some engines emit these). Default true. */
|
|
227
|
+
showFiveElements?: boolean;
|
|
228
|
+
/** Show per-pillar Shen Sha stars (only some engines emit these). Default true. */
|
|
229
|
+
showShenSha?: boolean;
|
|
230
|
+
/** Optional overrides merged onto the root container style. */
|
|
231
|
+
style?: CSSProperties;
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* `<BaziChart />` renders a complete Bazi (Four Pillars) chart from any
|
|
235
|
+
* supported input format, bilingually, with inline styles only (SSR-safe, zero CSS deps).
|
|
236
|
+
*
|
|
237
|
+
* @example
|
|
238
|
+
* const chart = myBaziEngine.calculate({ ... });
|
|
239
|
+
* <BaziChart data={chart} lang="en" />
|
|
240
|
+
*/
|
|
241
|
+
declare function BaziChart(props: BaziChartProps): ReactNode;
|
|
242
|
+
|
|
243
|
+
export { BaziChart, type BaziChartProps, type ChartExtras, type ChartLang, type ChartMeta, type DayMasterInfo, ELEMENT_COLORS, type ElementScore, type EngineName, NEUTRAL_COLOR, type NormalizedChart, type NormalizedHiddenStem, type NormalizedInteraction, type NormalizedLuckPillar, type NormalizedPillar, PALETTES, type PillarPosition, type SolarTime, type ThemeName, type ThemePalette, branchElement, branchZodiac, combine, detectEngine, elementColor, elementKeyOf, fromBaziObject, fromPillarMap, labelText, normalize, stemElement, valueText };
|