Generated from the company’s public pages
Model-written summary of observed first-party text — not a statement by the company.
);
}
/* ----------------------------------------------------------------------------------------------------- key facts */
type FactRow = { key: string; label: ReactNode; value: ReactNode; source: string | null; url: string | null; retrievedAt: string | null };
const MONEY_LABEL: Record<'revenue' | 'net_income' | 'total_assets', string> = { revenue: 'Revenue', net_income: 'Net income', total_assets: 'Total assets' };
function money(m: MoneyFact | null): ReactNode {
if (!m || typeof m.value !== 'number') return null;
return (
{fmtMoney(m.value, m.currency)} · FY{m.year}
);
}
/** Deterministic public registry links for identifiers (no lookup, no inference). */
const EDGAR = (cik: string) => `https://www.sec.gov/cgi-bin/browse-edgar?action=getcompany&CIK=${encodeURIComponent(cik)}`;
const GLEIF = (lei: string) => `https://search.gleif.org/#/record/${encodeURIComponent(lei)}`;
/** Builds the sourced fact rows: structured profile fields first (typed formatting), then any extra `facts[]` entries. */
export function buildFactRows(c: CompanyDetail): FactRow[] {
const p = c.profile ?? null;
const rows: FactRow[] = [];
const covered = new Set();
const push = (key: string, label: ReactNode, value: ReactNode, fields: string[] = [key]) => {
if (value === null || value === undefined || value === '' || value === false) return;
const s = sourceFor(p, ...fields);
const f = (c.facts ?? []).find((x) => x.key === key || fields.includes(x.key));
rows.push({ key, label, value, source: s?.source ?? f?.source ?? null, url: s?.url ?? f?.url ?? null, retrievedAt: s?.retrieved_at ?? f?.retrieved_at ?? null });
covered.add(key);
fields.forEach((x) => covered.add(x));
};
if (p) {
if (p.founded_year) push('founded_year', 'Founded', {p.founded_year}, ['founded_year', 'founded', 'inception']);
const hqParts = [p.hq?.city, p.hq?.region, p.hq?.country ? countryName(p.hq.country) : null].filter(Boolean) as string[];
if (hqParts.length)
push(
'hq',
'Headquarters',
{hqParts.join(', ')} map
,
['hq', 'headquarters', 'hq_city', 'hq_country'],
);
if (typeof p.employees === 'number')
push(
'employees',
'Employees',
{fmtInt(p.employees)}
{p.employees_year ? · {p.employees_year} : null}
,
['employees', 'employees_year'],
);
for (const k of ['revenue', 'net_income', 'total_assets'] as const) push(k, MONEY_LABEL[k], money(p[k]));
if (p.legal_form) push('legal_form', 'Legal form', p.legal_form);
if (p.public_company && (p.ticker || c.ticker))
push(
'listing',
'Listing',
{p.ticker ?? c.ticker}
{(p.exchange ?? c.exchange) && · {p.exchange ?? c.exchange}}
,
['ticker', 'exchange', 'listing'],
);
if (p.isin) push('isin', 'ISIN', {p.isin});
if (p.lei)
push(
'lei',
'LEI',
{p.lei} ,
);
if (p.sec_cik)
push(
'sec_cik',
'SEC CIK',
{p.sec_cik} ,
['sec_cik', 'cik'],
);
if (p.industry_labels?.length) push('industry_labels', 'Industry (Wikidata)', p.industry_labels.join(', '), ['industry_labels', 'industries']);
if (p.phone) push('phone', 'Phone', {p.phone});
if (p.wikipedia_url || p.wikidata_url)
push(
'references',
'References',
{p.wikipedia_url && (
Wikipedia
)}
{p.wikidata_url && (
Wikidata
)}
,
['wikipedia_url', 'wikidata_url'],
);
}
// extra flattened facts not already rendered from the structured profile
for (const f of c.facts ?? []) {
if (covered.has(f.key) || !f.value) continue;
rows.push({ key: `fact:${f.key}`, label: f.label || f.key, value: f.value, source: f.source, url: f.url, retrievedAt: f.retrieved_at });
covered.add(f.key);
}
return rows;
}
/** Overview → first block. Hides null facts; each row carries a source chip whose tooltip is the retrieval time. */
export function KeyFactsPanel({ c, className }: { c: CompanyDetail; className?: string }) {
const rows = buildFactRows(c);
const enriched = c.profile?.enriched_at ?? null;
return (
Key facts
{enriched && enriched {fmtDate(enriched)}}
{rows.length === 0 ? (
Facts appear here once Wikidata, Wikipedia or registry lookups have been reconciled for this company.
) : (
{rows.map((r) => (
{r.label}
{r.value}
))}
)}
{rows.length > 0 && Facts are quoted from their source as retrieved; figures are not converted or adjusted, and a missing fact is simply not shown.}
);
}
/* ------------------------------------------------------------------------------------------- corporate structure */
function validity(r: Relationship): string | null {
if (r.valid_from && r.valid_to) return `${fmtDate(r.valid_from)} – ${fmtDate(r.valid_to)}`;
if (r.valid_from) return `since ${fmtDate(r.valid_from)}`;
if (r.valid_to) return `until ${fmtDate(r.valid_to)}`;
return null;
}
function RelationshipRow({ r, showKind = false }: { r: Relationship; showKind?: boolean }) {
const name = relationshipName(r);
const v = validity(r);
const ended = !!r.valid_to;
return (
);
}
/** Parent / owners / subsidiaries / holdings / acquisitions, grouped; collapsible when there are more than 8 rows. */
export function CorporateStructurePanel({ relationships, className, collapseAfter = 8 }: { relationships: Relationship[]; className?: string; collapseAfter?: number }) {
const rels = relationships ?? [];
const groups = groupRelationships(rels);
const total = rels.length;
const body = (
{groups.map(({ group, rows }) => (
{group.label} ({rows.length})
{rows.map((r, i) => (
))}
))}
Structure as recorded by the cited sources (Wikidata statements, registries, first-party pages). “Former” marks a relationship with a recorded end date; the platform does not infer ownership changes.
) : (
body
)}
);
}
/* ---------------------------------------------------------------------------------------------- products (Wikidata) */
/** Fallback for the Products tab when no catalogue surface has been reconciled: products/services as stated on Wikidata. */
export function WikidataProducts({ products, source, className }: { products: string[]; source?: { url: string | null; retrieved_at: string } | null; className?: string }) {
if (!products?.length) return null;
return (
Products & services listed on Wikidata ({products.length})
{products.map((p) => (
{p}
))}
These names come from Wikidata “product or material produced” statements — not from a monitored catalogue page, so they carry no first-seen / last-seen dates.
);
}
export type { CompanyFact };