SPB Git forge
28commits 1branches 0releases
7.7 MBsize
maindefault branch
10 days agolast push
Python 66.3% TypeScript 22.7% JavaScript 8.6% HTML 1.4% CSS 0.7%
4.2 KB · 155 lines typescript
Raw Blame History
1/**2 * Event-type visual language (spec §21 taxonomy). Each type maps to a CSS token `--ev-<key>` declared in globals.css3 * (both themes), a short label and a lucide icon name used by `EventTypeBadge`. Unknown types fall back to `other`.4 */5export type EventTypeKey =6  | 'product'7  | 'pricing'8  | 'hiring'9  | 'leadership'10  | 'location'11  | 'financing'12  | 'ma'13  | 'partnership'14  | 'strategy'15  | 'technology'16  | 'legal'17  | 'marketing'18  | 'developer'19  | 'security'20  | 'operations'21  | 'sustainability'22  | 'investor_relations'23  | 'communication'24  | 'other';2526export interface EventStyle {27  key: EventTypeKey;28  label: string;29  /** CSS color expression, usable in `style={{ color }}`. */30  color: string;31  soft: string;32}3334const TYPE_TO_KEY: Record<string, EventTypeKey> = {35  PRODUCT: 'product',36  PRICING: 'pricing',37  HIRING: 'hiring',38  LEADERSHIP: 'leadership',39  LOCATION: 'location',40  FINANCING: 'financing',41  'M&A': 'ma',42  MA: 'ma',43  M_A: 'ma',44  MERGER: 'ma',45  ACQUISITION: 'ma',46  PARTNERSHIP: 'partnership',47  STRATEGY: 'strategy',48  TECHNOLOGY: 'technology',49  LEGAL: 'legal',50  MARKETING: 'marketing',51  DEVELOPER: 'developer',52  SECURITY: 'security',53  OPERATIONS: 'operations',54  SUSTAINABILITY: 'sustainability',55  INVESTOR_RELATIONS: 'investor_relations',56  COMMUNICATION: 'communication',57  NEWS: 'communication',58  OTHER: 'other',59};6061const LABELS: Record<EventTypeKey, string> = {62  product: 'Product',63  pricing: 'Pricing',64  hiring: 'Hiring',65  leadership: 'Leadership',66  location: 'Location',67  financing: 'Financing',68  ma: 'M&A',69  partnership: 'Partnership',70  strategy: 'Strategy',71  technology: 'Technology',72  legal: 'Legal',73  marketing: 'Marketing',74  developer: 'Developer',75  security: 'Security',76  operations: 'Operations',77  sustainability: 'Sustainability',78  investor_relations: 'Investor relations',79  communication: 'Communication',80  other: 'Other',81};8283export function eventKey(type: string | null | undefined): EventTypeKey {84  if (!type) return 'other';85  return TYPE_TO_KEY[type.toUpperCase()] ?? 'other';86}8788export function eventStyle(type: string | null | undefined): EventStyle {89  const key = eventKey(type);90  return { key, label: LABELS[key], color: `var(--ev-${key})`, soft: `color-mix(in srgb, var(--ev-${key}) 12%, transparent)` };91}9293/** Ordered list for filters and legends (the spec taxonomy order). */94export const EVENT_TYPES: string[] = [95  'PRODUCT',96  'PRICING',97  'HIRING',98  'LEADERSHIP',99  'LOCATION',100  'FINANCING',101  'M&A',102  'PARTNERSHIP',103  'STRATEGY',104  'TECHNOLOGY',105  'LEGAL',106  'MARKETING',107  'DEVELOPER',108  'SECURITY',109  'OPERATIONS',110  'SUSTAINABILITY',111  'INVESTOR_RELATIONS',112  'COMMUNICATION',113  'OTHER',114];115116export function eventTypeLabel(type: string | null | undefined): string {117  return LABELS[eventKey(type)];118}119120/** Subtype → careful human label. Anything unknown is humanised, never invented. */121const SUBTYPE_LABELS: Record<string, string> = {122  PRODUCT_LAUNCH: 'Product launch',123  PRODUCT_REMOVAL: 'Product no longer listed',124  PRODUCT_RENAME: 'Product renamed',125  PRICE_INCREASE: 'Price increase',126  PRICE_DECREASE: 'Price decrease',127  NEW_PRICING_TIER: 'New pricing tier',128  PRICING_CHANGE: 'Pricing change',129  JOB_COUNT_INCREASE: 'Job count increase',130  JOB_COUNT_DECREASE: 'Job count decrease',131  NEW_JOB: 'New listing',132  JOB_REMOVED: 'Listing no longer visible',133  NEW_EXECUTIVE: 'New executive listed',134  EXECUTIVE_REMOVED: 'Executive no longer listed',135  LEADERSHIP_CHANGE: 'Leadership page changed',136  NEW_OFFICE: 'New office listed',137  OFFICE_REMOVED: 'Office no longer listed',138  NEW_LOCATION: 'New location listed',139  COUNTRY_EXPANSION: 'Country expansion',140  NEW_PARTNERSHIP: 'New partnership',141  ACQUISITION: 'Acquisition',142  DIVESTITURE: 'Divestiture',143  API_LAUNCH: 'API launch',144  DOCUMENTATION_CHANGE: 'Documentation change',145  DOC_CHANGE: 'Documentation change',146  TERMS_CHANGE: 'Terms change',147  BRAND_REPOSITIONING: 'Brand repositioning',148  NEWS_RELEASE: 'News release',149  SECURITY_NOTICE: 'Security notice',150};151export function subtypeLabel(sub: string | null | undefined): string {152  if (!sub) return '';153  return SUBTYPE_LABELS[sub.toUpperCase()] ?? sub.replace(/[_-]+/g, ' ').toLowerCase().replace(/^\w/, (c) => c.toUpperCase());154}155