@attrx/role-morphic 0.1.0 → 0.2.1

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/roles/area/constants.ts","../src/roles/area/convert.ts","../src/roles/area/cast.ts","../src/roles/length/constants.ts","../src/roles/length/convert.ts","../src/roles/length/cast.ts","../src/roles/mass/constants.ts","../src/roles/mass/convert.ts","../src/roles/mass/cast.ts","../src/roles/temperature/constants.ts","../src/roles/temperature/convert.ts","../src/roles/temperature/cast.ts","../src/roles/volume/constants.ts","../src/roles/volume/convert.ts","../src/roles/volume/cast.ts","../src/roles/speed/constants.ts","../src/roles/speed/convert.ts","../src/roles/speed/cast.ts","../src/roles/energy/constants.ts","../src/roles/energy/convert.ts","../src/roles/energy/cast.ts","../src/roles/power/constants.ts","../src/roles/power/convert.ts","../src/roles/power/cast.ts","../src/roles/pressure/constants.ts","../src/roles/pressure/convert.ts","../src/roles/pressure/cast.ts","../src/roles/frequency/constants.ts","../src/roles/frequency/convert.ts","../src/roles/frequency/cast.ts","../src/roles/angle/constants.ts","../src/roles/angle/convert.ts","../src/roles/angle/cast.ts","../src/roles/time/constants.ts","../src/roles/time/convert.ts","../src/roles/time/cast.ts","../src/roles/digital/constants.ts","../src/roles/digital/convert.ts","../src/roles/digital/cast.ts","../src/roles/color/types.ts","../src/roles/color/convert.ts","../src/roles/color/cast.ts","../src/roles/date/cast.ts","../src/roles/currency/cast.ts"],"names":["parseNumber","detectUnit","numStr","value","p","q"],"mappings":"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","file":"cast.js","sourcesContent":["/**\n * Area Role - Constants\n *\n * Fatores de conversão, símbolos e aliases para unidades de área.\n *\n * Fontes:\n * - NIST SP 811 (2008)\n * - International Yard and Pound Agreement (1959)\n * - SI Brochure, 9th Edition (2019)\n */\n\nimport type { SimpleUnitConfig, UnitAliases } from \"../../contracts\";\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport type AreaUnit =\n // SI\n | \"square_kilometer\"\n | \"hectare\"\n | \"are\"\n | \"square_meter\"\n | \"square_decimeter\"\n | \"square_centimeter\"\n | \"square_millimeter\"\n // Imperial/US\n | \"square_mile\"\n | \"acre\"\n | \"square_yard\"\n | \"square_foot\"\n | \"square_inch\";\n\n// =============================================================================\n// UNITS CONFIG\n// =============================================================================\n\n/**\n * Configuração de cada unidade de área.\n *\n * TODOS os fatores são EXATOS:\n * - SI: derivados de potências de 10\n * - Imperial: derivados de (comprimento)² onde comprimento é exato desde 1959\n *\n * Relações imperiais:\n * - 1 in² = (0.0254 m)² = 0.00064516 m²\n * - 1 ft² = (0.3048 m)² = 0.09290304 m²\n * - 1 yd² = (0.9144 m)² = 0.83612736 m²\n * - 1 mi² = (1609.344 m)² = 2589988.110336 m²\n * - 1 acre = 43560 ft² = 4046.8564224 m²\n */\nexport const AREA_UNITS: Record<AreaUnit, SimpleUnitConfig> = {\n // SI Units (todos exatos)\n square_kilometer: {\n factor: 1_000_000,\n symbol: \"km²\",\n singular: \"square kilometer\",\n plural: \"square kilometers\",\n },\n hectare: {\n factor: 10_000,\n symbol: \"ha\",\n singular: \"hectare\",\n plural: \"hectares\",\n },\n are: {\n factor: 100,\n symbol: \"a\",\n singular: \"are\",\n plural: \"ares\",\n },\n square_meter: {\n factor: 1,\n symbol: \"m²\",\n singular: \"square meter\",\n plural: \"square meters\",\n },\n square_decimeter: {\n factor: 0.01,\n symbol: \"dm²\",\n singular: \"square decimeter\",\n plural: \"square decimeters\",\n },\n square_centimeter: {\n factor: 0.0001,\n symbol: \"cm²\",\n singular: \"square centimeter\",\n plural: \"square centimeters\",\n },\n square_millimeter: {\n factor: 0.000001,\n symbol: \"mm²\",\n singular: \"square millimeter\",\n plural: \"square millimeters\",\n },\n\n // Imperial/US (todos exatos, derivados de comprimento² desde 1959)\n square_mile: {\n factor: 2_589_988.110336,\n symbol: \"mi²\",\n singular: \"square mile\",\n plural: \"square miles\",\n },\n acre: {\n factor: 4_046.8564224,\n symbol: \"ac\",\n singular: \"acre\",\n plural: \"acres\",\n },\n square_yard: {\n factor: 0.83612736,\n symbol: \"yd²\",\n singular: \"square yard\",\n plural: \"square yards\",\n },\n square_foot: {\n factor: 0.09290304,\n symbol: \"ft²\",\n singular: \"square foot\",\n plural: \"square feet\",\n },\n square_inch: {\n factor: 0.00064516,\n symbol: \"in²\",\n singular: \"square inch\",\n plural: \"square inches\",\n },\n};\n\n// =============================================================================\n// ALIASES\n// =============================================================================\n\n/**\n * Aliases para reconhecimento de unidades no cast\n */\nexport const AREA_ALIASES: UnitAliases = {\n // square_kilometer\n \"km²\": \"square_kilometer\",\n km2: \"square_kilometer\",\n // hectare\n ha: \"hectare\",\n // are\n a: \"are\",\n // square_meter\n \"m²\": \"square_meter\",\n m2: \"square_meter\",\n // square_decimeter\n \"dm²\": \"square_decimeter\",\n dm2: \"square_decimeter\",\n // square_centimeter\n \"cm²\": \"square_centimeter\",\n cm2: \"square_centimeter\",\n // square_millimeter\n \"mm²\": \"square_millimeter\",\n mm2: \"square_millimeter\",\n // square_mile\n \"mi²\": \"square_mile\",\n mi2: \"square_mile\",\n // acre\n ac: \"acre\",\n // square_yard\n \"yd²\": \"square_yard\",\n yd2: \"square_yard\",\n // square_foot\n \"ft²\": \"square_foot\",\n ft2: \"square_foot\",\n // square_inch\n \"in²\": \"square_inch\",\n in2: \"square_inch\",\n};\n\n// =============================================================================\n// HELPERS\n// =============================================================================\n\n/** Lista de todas as unidades */\nexport const AREA_UNIT_LIST = Object.keys(AREA_UNITS) as AreaUnit[];\n\n/** Fatores de conversão (para compatibilidade) */\nexport const AREA_FACTORS: Record<AreaUnit, number> = Object.fromEntries(\n Object.entries(AREA_UNITS).map(([unit, config]) => [\n unit,\n config.factor ?? 1,\n ]),\n) as Record<AreaUnit, number>;\n","/**\n * Area Role - Convert Pillar\n *\n * Conversão entre unidades de área usando arquitetura hub-and-spoke.\n * Base: square_meter (m²)\n *\n * @example\n * import { convertArea, toBaseArea, fromBaseArea } from '@attrx/role-morphic/area/convert';\n *\n * convertArea('hectare', 'acre', 1); // 2.47105...\n * toBaseArea('hectare', 1); // 10000\n * fromBaseArea('acre', 10000); // 2.47105...\n */\n\nimport { AREA_UNITS, type AreaUnit } from \"./constants\";\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport type Result<T> =\n | { ok: true; value: T }\n | { ok: false; error: string };\n\n// =============================================================================\n// CONSTANTS\n// =============================================================================\n\n/** Variante base para conversões */\nexport const AREA_BASE: AreaUnit = \"square_meter\";\n\n// =============================================================================\n// CONVERT\n// =============================================================================\n\n/**\n * Converte valor para a unidade base (square_meter)\n *\n * @param variant - Unidade de origem\n * @param value - Valor a converter\n * @returns Valor em square_meter\n *\n * @example\n * toBaseArea('hectare', 1); // 10000\n * toBaseArea('acre', 1); // 4046.8564224\n */\nexport function toBaseArea(variant: AreaUnit, value: number): number {\n const unit = AREA_UNITS[variant];\n\n if (!unit) {\n throw new Error(`Unknown area variant: ${variant}`);\n }\n\n return value * (unit.factor ?? 1);\n}\n\n/**\n * Converte valor da unidade base (square_meter) para outra unidade\n *\n * @param variant - Unidade de destino\n * @param baseValue - Valor em square_meter\n * @returns Valor na unidade de destino\n *\n * @example\n * fromBaseArea('hectare', 10000); // 1\n * fromBaseArea('acre', 4046.86); // ~1\n */\nexport function fromBaseArea(variant: AreaUnit, baseValue: number): number {\n const unit = AREA_UNITS[variant];\n\n if (!unit) {\n throw new Error(`Unknown area variant: ${variant}`);\n }\n\n return baseValue / (unit.factor ?? 1);\n}\n\n/**\n * Converte entre duas unidades de área\n *\n * @param from - Unidade de origem\n * @param to - Unidade de destino\n * @param value - Valor a converter\n * @returns Valor convertido\n *\n * @example\n * convertArea('hectare', 'acre', 1); // 2.47105...\n * convertArea('square_meter', 'hectare', 10000); // 1\n */\nexport function convertArea(\n from: AreaUnit,\n to: AreaUnit,\n value: number\n): number {\n // Otimização: mesma unidade\n if (from === to) {\n return value;\n }\n\n // Hub-and-spoke: from → base → to\n const baseValue = toBaseArea(from, value);\n return fromBaseArea(to, baseValue);\n}\n\n/**\n * Versão safe de convertArea que retorna Result\n *\n * @example\n * tryConvertArea('hectare', 'acre', 1);\n * // { ok: true, value: 2.47105... }\n *\n * tryConvertArea('invalid', 'acre', 1);\n * // { ok: false, error: 'Unknown area variant: invalid' }\n */\nexport function tryConvertArea(\n from: AreaUnit,\n to: AreaUnit,\n value: number\n): Result<number> {\n try {\n const result = convertArea(from, to, value);\n return { ok: true, value: result };\n } catch (err) {\n return { ok: false, error: String(err) };\n }\n}\n\n/**\n * Verifica se uma variante existe\n */\nexport function hasAreaVariant(variant: string): variant is AreaUnit {\n return variant in AREA_UNITS;\n}\n\n/**\n * Lista todas as variantes disponíveis\n */\nexport function getAreaVariants(): AreaUnit[] {\n return Object.keys(AREA_UNITS) as AreaUnit[];\n}\n","/**\n * Area Role - Cast Pillar\n *\n * Normaliza input sujo para número tipado.\n * Detecta unidades em strings e converte se necessário.\n *\n * @example\n * import { castArea, castAreaStrict, detectAreaUnit } from '@attrx/role-morphic/area/cast';\n *\n * castArea('100 ha', 'hectare'); // 100\n * castArea('100 ha', 'acre'); // 247.105... (converte)\n * castAreaStrict('100 ha'); // 100 (não converte)\n * detectAreaUnit('100 hectares'); // 'hectare'\n */\n\nimport { AREA_UNITS, AREA_ALIASES, type AreaUnit } from \"./constants\";\nimport { convertArea } from \"./convert\";\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport type Result<T> =\n | { ok: true; value: T }\n | { ok: false; error: string };\n\n// =============================================================================\n// CAST\n// =============================================================================\n\n/**\n * Faz cast de input para número, detectando e convertendo unidade se presente\n *\n * @param input - Valor de entrada (number, string, etc)\n * @param targetVariant - Unidade alvo para conversão\n * @returns Número ou null se não puder converter\n *\n * @example\n * castArea(100, 'hectare'); // 100\n * castArea('100', 'hectare'); // 100\n * castArea('100 ha', 'hectare'); // 100\n * castArea('100 ha', 'acre'); // 247.105... (converte)\n * castArea('100 acres', 'hectare'); // 40.4686... (converte)\n * castArea('invalid', 'hectare'); // null\n */\nexport function castArea(\n input: unknown,\n targetVariant: AreaUnit = \"square_meter\"\n): number | null {\n // Já é número\n if (typeof input === \"number\") {\n return Number.isFinite(input) ? input : null;\n }\n\n // String\n if (typeof input === \"string\") {\n return parseAreaString(input, targetVariant);\n }\n\n return null;\n}\n\n/**\n * Faz cast sem conversão de unidade (só parseia o valor literal)\n *\n * @param input - Valor de entrada\n * @returns Número ou null\n *\n * @example\n * castAreaStrict('100 ha'); // 100 (ignora unidade, não converte)\n * castAreaStrict('100'); // 100\n * castAreaStrict(100); // 100\n */\nexport function castAreaStrict(input: unknown): number | null {\n // Já é número\n if (typeof input === \"number\") {\n return Number.isFinite(input) ? input : null;\n }\n\n // String\n if (typeof input === \"string\") {\n const numValue = parseNumber(input);\n return numValue;\n }\n\n return null;\n}\n\n/**\n * Versão safe de castArea que retorna Result\n */\nexport function tryCastArea(\n input: unknown,\n targetVariant: AreaUnit = \"square_meter\"\n): Result<number> {\n const result = castArea(input, targetVariant);\n if (result === null) {\n return {\n ok: false,\n error: `Cannot cast \"${String(input)}\" to area:${targetVariant}`,\n };\n }\n return { ok: true, value: result };\n}\n\n// =============================================================================\n// DETECTION\n// =============================================================================\n\n/**\n * Detecta unidade de área a partir de uma string\n *\n * @param input - String com possível unidade\n * @returns Unidade detectada ou null\n *\n * @example\n * detectAreaUnit('100 ha'); // 'hectare'\n * detectAreaUnit('100 hectares'); // 'hectare'\n * detectAreaUnit('100 m²'); // 'square_meter'\n * detectAreaUnit('100'); // null\n */\nexport function detectAreaUnit(input: string): AreaUnit | null {\n const trimmed = input.trim().toLowerCase();\n const match = trimmed.match(/^[+-]?[\\d.,\\s]+\\s*(.*)$/);\n\n if (!match || !match[1]) {\n return null;\n }\n\n const unitStr = match[1].trim();\n return detectUnit(unitStr);\n}\n\n// =============================================================================\n// INTERNAL HELPERS\n// =============================================================================\n\n/**\n * Parseia string para número, detectando unidade e convertendo se necessário\n */\nfunction parseAreaString(input: string, targetVariant: AreaUnit): number | null {\n const trimmed = input.trim().toLowerCase();\n\n // Extrai número e possível unidade\n const match = trimmed.match(/^([+-]?[\\d.,\\s]+)\\s*(.*)$/);\n if (!match) {\n return null;\n }\n\n const [, numStr, unitStr] = match;\n\n // Normaliza número\n const numValue = parseNumber(numStr);\n if (numValue === null) {\n return null;\n }\n\n // Se tem unidade no input, converte se necessário\n const cleanUnitStr = unitStr.trim();\n if (cleanUnitStr) {\n const detectedUnit = detectUnit(cleanUnitStr);\n if (detectedUnit && detectedUnit !== targetVariant) {\n // Converte da unidade detectada para a target\n return convertArea(detectedUnit, targetVariant, numValue);\n }\n }\n\n return numValue;\n}\n\n/**\n * Parseia string numérica considerando formatos brasileiro e americano\n */\nfunction parseNumber(numStr: string): number | null {\n // Remove espaços\n numStr = numStr.replace(/\\s/g, \"\");\n\n const lastComma = numStr.lastIndexOf(\",\");\n const lastDot = numStr.lastIndexOf(\".\");\n const hasComma = lastComma !== -1;\n const hasDot = lastDot !== -1;\n\n if (hasComma && hasDot) {\n if (lastComma > lastDot) {\n // Brasileiro: 1.000,50\n numStr = numStr.replace(/\\./g, \"\").replace(\",\", \".\");\n } else {\n // Americano: 1,000.50\n numStr = numStr.replace(/,/g, \"\");\n }\n } else if (hasComma && !hasDot) {\n // Só vírgulas: detecta se é milhar ou decimal\n const afterComma = numStr.split(\",\").slice(1);\n const isThousandSep = afterComma.every((part) => part.length === 3);\n if (isThousandSep) {\n numStr = numStr.replace(/,/g, \"\");\n } else {\n numStr = numStr.replace(\",\", \".\");\n }\n } else if (!hasComma && hasDot) {\n // Só pontos: múltiplos pontos = milhar brasileiro\n const afterDot = numStr.split(\".\").slice(1);\n if (afterDot.length > 1) {\n numStr = numStr.replace(/\\./g, \"\");\n }\n }\n\n const value = parseFloat(numStr);\n return isNaN(value) ? null : value;\n}\n\n/**\n * Detecta unidade a partir de string (símbolo ou alias)\n */\nfunction detectUnit(unitStr: string): AreaUnit | null {\n const normalized = unitStr.toLowerCase().trim();\n\n // Checa aliases primeiro\n if (normalized in AREA_ALIASES) {\n return AREA_ALIASES[normalized] as AreaUnit;\n }\n\n // Checa símbolos e nomes\n for (const [variant, config] of Object.entries(AREA_UNITS)) {\n if (\n config.symbol.toLowerCase() === normalized ||\n config.singular?.toLowerCase() === normalized ||\n config.plural?.toLowerCase() === normalized ||\n variant.toLowerCase() === normalized\n ) {\n return variant as AreaUnit;\n }\n }\n\n return null;\n}\n","/**\n * Length Role - Constants\n *\n * Fatores de conversão, símbolos e aliases para unidades de comprimento.\n *\n * Fontes:\n * - NIST SP 811 (2008)\n * - International Yard and Pound Agreement (1959)\n * - SI Brochure, 9th Edition (2019)\n */\n\nimport type { SimpleUnitConfig, UnitAliases } from \"../../contracts\";\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport type LengthUnit =\n // SI\n | \"kilometer\"\n | \"hectometer\"\n | \"decameter\"\n | \"meter\"\n | \"decimeter\"\n | \"centimeter\"\n | \"millimeter\"\n | \"micrometer\"\n | \"nanometer\"\n // Imperial/US\n | \"inch\"\n | \"foot\"\n | \"yard\"\n | \"mile\"\n // Nautical\n | \"nautical_mile\"\n // Other\n | \"fathom\"\n | \"furlong\"\n | \"league\";\n\n// =============================================================================\n// UNITS CONFIG\n// =============================================================================\n\n/**\n * Configuração de cada unidade de comprimento.\n *\n * TODOS os fatores são EXATOS:\n * - SI: derivados de potências de 10\n * - Imperial: exatos desde International Yard and Pound Agreement (1959)\n * - 1 yard = 0.9144 m (exato por definição)\n * - 1 foot = 0.3048 m (= yard/3)\n * - 1 inch = 0.0254 m (= foot/12)\n * - 1 mile = 1609.344 m (= 5280 feet)\n */\nexport const LENGTH_UNITS: Record<LengthUnit, SimpleUnitConfig> = {\n // SI Units (todos exatos)\n kilometer: {\n factor: 1000,\n symbol: \"km\",\n singular: \"kilometer\",\n plural: \"kilometers\",\n },\n hectometer: {\n factor: 100,\n symbol: \"hm\",\n singular: \"hectometer\",\n plural: \"hectometers\",\n },\n decameter: {\n factor: 10,\n symbol: \"dam\",\n singular: \"decameter\",\n plural: \"decameters\",\n },\n meter: {\n factor: 1,\n symbol: \"m\",\n singular: \"meter\",\n plural: \"meters\",\n },\n decimeter: {\n factor: 0.1,\n symbol: \"dm\",\n singular: \"decimeter\",\n plural: \"decimeters\",\n },\n centimeter: {\n factor: 0.01,\n symbol: \"cm\",\n singular: \"centimeter\",\n plural: \"centimeters\",\n },\n millimeter: {\n factor: 0.001,\n symbol: \"mm\",\n singular: \"millimeter\",\n plural: \"millimeters\",\n },\n micrometer: {\n factor: 0.000001,\n symbol: \"μm\",\n singular: \"micrometer\",\n plural: \"micrometers\",\n },\n nanometer: {\n factor: 0.000000001,\n symbol: \"nm\",\n singular: \"nanometer\",\n plural: \"nanometers\",\n },\n\n // Imperial/US (exatos desde 1959)\n inch: {\n factor: 0.0254,\n symbol: \"in\",\n singular: \"inch\",\n plural: \"inches\",\n },\n foot: {\n factor: 0.3048,\n symbol: \"ft\",\n singular: \"foot\",\n plural: \"feet\",\n },\n yard: {\n factor: 0.9144,\n symbol: \"yd\",\n singular: \"yard\",\n plural: \"yards\",\n },\n mile: {\n factor: 1609.344,\n symbol: \"mi\",\n singular: \"mile\",\n plural: \"miles\",\n },\n\n // Nautical (exato por definição internacional)\n nautical_mile: {\n factor: 1852,\n symbol: \"nmi\",\n singular: \"nautical mile\",\n plural: \"nautical miles\",\n },\n\n // Other (derivados, portanto exatos)\n fathom: {\n factor: 1.8288, // 6 feet\n symbol: \"ftm\",\n singular: \"fathom\",\n plural: \"fathoms\",\n },\n furlong: {\n factor: 201.168, // 660 feet = 1/8 mile\n symbol: \"fur\",\n singular: \"furlong\",\n plural: \"furlongs\",\n },\n league: {\n factor: 4828.032, // 3 miles\n symbol: \"lea\",\n singular: \"league\",\n plural: \"leagues\",\n },\n};\n\n// =============================================================================\n// ALIASES\n// =============================================================================\n\n/**\n * Aliases para reconhecimento de unidades no cast\n */\nexport const LENGTH_ALIASES: UnitAliases = {\n // kilometer\n km: \"kilometer\",\n // hectometer\n hm: \"hectometer\",\n // decameter\n dam: \"decameter\",\n // meter\n m: \"meter\",\n // decimeter\n dm: \"decimeter\",\n // centimeter\n cm: \"centimeter\",\n // millimeter\n mm: \"millimeter\",\n // micrometer\n \"μm\": \"micrometer\",\n um: \"micrometer\",\n // nanometer\n nm: \"nanometer\",\n // inch\n in: \"inch\",\n '\"': \"inch\",\n // foot\n ft: \"foot\",\n \"'\": \"foot\",\n // yard\n yd: \"yard\",\n // mile\n mi: \"mile\",\n // nautical_mile\n nmi: \"nautical_mile\",\n // fathom\n ftm: \"fathom\",\n // furlong\n fur: \"furlong\",\n // league\n lea: \"league\",\n};\n\n// =============================================================================\n// HELPERS\n// =============================================================================\n\n/** Lista de todas as unidades */\nexport const LENGTH_UNIT_LIST = Object.keys(LENGTH_UNITS) as LengthUnit[];\n\n/** Fatores de conversão (para compatibilidade) */\nexport const LENGTH_FACTORS: Record<LengthUnit, number> = Object.fromEntries(\n Object.entries(LENGTH_UNITS).map(([unit, config]) => [\n unit,\n config.factor ?? 1,\n ]),\n) as Record<LengthUnit, number>;\n","/**\n * Length Role - Convert Pillar\n *\n * Conversão entre unidades de comprimento usando arquitetura hub-and-spoke.\n * Base: meter (m)\n *\n * @example\n * import { convertLength, toBaseLength, fromBaseLength } from '@attrx/role-morphic/length/convert';\n *\n * convertLength('kilometer', 'mile', 1); // 0.621371...\n * toBaseLength('kilometer', 1); // 1000\n * fromBaseLength('mile', 1000); // 0.621371...\n */\n\nimport { LENGTH_UNITS, type LengthUnit } from \"./constants\";\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport type Result<T> =\n | { ok: true; value: T }\n | { ok: false; error: string };\n\n// =============================================================================\n// CONSTANTS\n// =============================================================================\n\n/** Variante base para conversões */\nexport const LENGTH_BASE: LengthUnit = \"meter\";\n\n// =============================================================================\n// CONVERT\n// =============================================================================\n\n/**\n * Converte valor para a unidade base (meter)\n *\n * @param variant - Unidade de origem\n * @param value - Valor a converter\n * @returns Valor em meters\n *\n * @example\n * toBaseLength('kilometer', 1); // 1000\n * toBaseLength('mile', 1); // 1609.344\n */\nexport function toBaseLength(variant: LengthUnit, value: number): number {\n const unit = LENGTH_UNITS[variant];\n\n if (!unit) {\n throw new Error(`Unknown length variant: ${variant}`);\n }\n\n return value * (unit.factor ?? 1);\n}\n\n/**\n * Converte valor da unidade base (meter) para outra unidade\n *\n * @param variant - Unidade de destino\n * @param baseValue - Valor em meters\n * @returns Valor na unidade de destino\n *\n * @example\n * fromBaseLength('kilometer', 1000); // 1\n * fromBaseLength('mile', 1609.344); // 1\n */\nexport function fromBaseLength(variant: LengthUnit, baseValue: number): number {\n const unit = LENGTH_UNITS[variant];\n\n if (!unit) {\n throw new Error(`Unknown length variant: ${variant}`);\n }\n\n return baseValue / (unit.factor ?? 1);\n}\n\n/**\n * Converte entre duas unidades de comprimento\n *\n * @param from - Unidade de origem\n * @param to - Unidade de destino\n * @param value - Valor a converter\n * @returns Valor convertido\n *\n * @example\n * convertLength('kilometer', 'mile', 1); // 0.621371...\n * convertLength('foot', 'meter', 1); // 0.3048\n */\nexport function convertLength(\n from: LengthUnit,\n to: LengthUnit,\n value: number\n): number {\n // Otimização: mesma unidade\n if (from === to) {\n return value;\n }\n\n // Hub-and-spoke: from → base → to\n const baseValue = toBaseLength(from, value);\n return fromBaseLength(to, baseValue);\n}\n\n/**\n * Versão safe de convertLength que retorna Result\n *\n * @example\n * tryConvertLength('kilometer', 'mile', 1);\n * // { ok: true, value: 0.621371... }\n *\n * tryConvertLength('invalid', 'mile', 1);\n * // { ok: false, error: 'Unknown length variant: invalid' }\n */\nexport function tryConvertLength(\n from: LengthUnit,\n to: LengthUnit,\n value: number\n): Result<number> {\n try {\n const result = convertLength(from, to, value);\n return { ok: true, value: result };\n } catch (err) {\n return { ok: false, error: String(err) };\n }\n}\n\n/**\n * Verifica se uma variante existe\n */\nexport function hasLengthVariant(variant: string): variant is LengthUnit {\n return variant in LENGTH_UNITS;\n}\n\n/**\n * Lista todas as variantes disponíveis\n */\nexport function getLengthVariants(): LengthUnit[] {\n return Object.keys(LENGTH_UNITS) as LengthUnit[];\n}\n","/**\n * Length Role - Cast Pillar\n *\n * Normaliza input sujo para número tipado.\n * Detecta unidades em strings e converte se necessário.\n *\n * @example\n * import { castLength, castLengthStrict, detectLengthUnit } from '@attrx/role-morphic/length/cast';\n *\n * castLength('100 km', 'kilometer'); // 100\n * castLength('100 km', 'mile'); // 62.1371... (converte)\n * castLengthStrict('100 km'); // 100 (não converte)\n * detectLengthUnit('100 meters'); // 'meter'\n */\n\nimport { LENGTH_UNITS, LENGTH_ALIASES, type LengthUnit } from \"./constants\";\nimport { convertLength } from \"./convert\";\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport type Result<T> =\n | { ok: true; value: T }\n | { ok: false; error: string };\n\n// =============================================================================\n// CAST\n// =============================================================================\n\n/**\n * Faz cast de input para número, detectando e convertendo unidade se presente\n *\n * @param input - Valor de entrada (number, string, etc)\n * @param targetVariant - Unidade alvo para conversão\n * @returns Número ou null se não puder converter\n *\n * @example\n * castLength(100, 'meter'); // 100\n * castLength('100', 'meter'); // 100\n * castLength('100 km', 'kilometer'); // 100\n * castLength('100 km', 'mile'); // 62.1371... (converte)\n * castLength('1 mile', 'kilometer'); // 1.609344 (converte)\n * castLength('invalid', 'meter'); // null\n */\nexport function castLength(\n input: unknown,\n targetVariant: LengthUnit = \"meter\"\n): number | null {\n // Já é número\n if (typeof input === \"number\") {\n return Number.isFinite(input) ? input : null;\n }\n\n // String\n if (typeof input === \"string\") {\n return parseLengthString(input, targetVariant);\n }\n\n return null;\n}\n\n/**\n * Faz cast sem conversão de unidade (só parseia o valor literal)\n *\n * @param input - Valor de entrada\n * @returns Número ou null\n *\n * @example\n * castLengthStrict('100 km'); // 100 (ignora unidade, não converte)\n * castLengthStrict('100'); // 100\n * castLengthStrict(100); // 100\n */\nexport function castLengthStrict(input: unknown): number | null {\n // Já é número\n if (typeof input === \"number\") {\n return Number.isFinite(input) ? input : null;\n }\n\n // String\n if (typeof input === \"string\") {\n const numValue = parseNumber(input);\n return numValue;\n }\n\n return null;\n}\n\n/**\n * Versão safe de castLength que retorna Result\n */\nexport function tryCastLength(\n input: unknown,\n targetVariant: LengthUnit = \"meter\"\n): Result<number> {\n const result = castLength(input, targetVariant);\n if (result === null) {\n return {\n ok: false,\n error: `Cannot cast \"${String(input)}\" to length:${targetVariant}`,\n };\n }\n return { ok: true, value: result };\n}\n\n// =============================================================================\n// DETECTION\n// =============================================================================\n\n/**\n * Detecta unidade de comprimento a partir de uma string\n *\n * @param input - String com possível unidade\n * @returns Unidade detectada ou null\n *\n * @example\n * detectLengthUnit('100 km'); // 'kilometer'\n * detectLengthUnit('100 meters'); // 'meter'\n * detectLengthUnit('100 ft'); // 'foot'\n * detectLengthUnit('100'); // null\n */\nexport function detectLengthUnit(input: string): LengthUnit | null {\n const trimmed = input.trim().toLowerCase();\n const match = trimmed.match(/^[+-]?[\\d.,\\s]+\\s*(.*)$/);\n\n if (!match || !match[1]) {\n return null;\n }\n\n const unitStr = match[1].trim();\n return detectUnit(unitStr);\n}\n\n// =============================================================================\n// INTERNAL HELPERS\n// =============================================================================\n\n/**\n * Parseia string para número, detectando unidade e convertendo se necessário\n */\nfunction parseLengthString(input: string, targetVariant: LengthUnit): number | null {\n const trimmed = input.trim().toLowerCase();\n\n // Extrai número e possível unidade\n const match = trimmed.match(/^([+-]?[\\d.,\\s]+)\\s*(.*)$/);\n if (!match) {\n return null;\n }\n\n const [, numStr, unitStr] = match;\n\n // Normaliza número\n const numValue = parseNumber(numStr);\n if (numValue === null) {\n return null;\n }\n\n // Se tem unidade no input, converte se necessário\n const cleanUnitStr = unitStr.trim();\n if (cleanUnitStr) {\n const detectedUnit = detectUnit(cleanUnitStr);\n if (detectedUnit && detectedUnit !== targetVariant) {\n // Converte da unidade detectada para a target\n return convertLength(detectedUnit, targetVariant, numValue);\n }\n }\n\n return numValue;\n}\n\n/**\n * Parseia string numérica considerando formatos brasileiro e americano\n */\nfunction parseNumber(numStr: string): number | null {\n // Remove espaços\n numStr = numStr.replace(/\\s/g, \"\");\n\n const lastComma = numStr.lastIndexOf(\",\");\n const lastDot = numStr.lastIndexOf(\".\");\n const hasComma = lastComma !== -1;\n const hasDot = lastDot !== -1;\n\n if (hasComma && hasDot) {\n if (lastComma > lastDot) {\n // Brasileiro: 1.000,50\n numStr = numStr.replace(/\\./g, \"\").replace(\",\", \".\");\n } else {\n // Americano: 1,000.50\n numStr = numStr.replace(/,/g, \"\");\n }\n } else if (hasComma && !hasDot) {\n // Só vírgulas: detecta se é milhar ou decimal\n const afterComma = numStr.split(\",\").slice(1);\n const isThousandSep = afterComma.every((part) => part.length === 3);\n if (isThousandSep) {\n numStr = numStr.replace(/,/g, \"\");\n } else {\n numStr = numStr.replace(\",\", \".\");\n }\n } else if (!hasComma && hasDot) {\n // Só pontos: múltiplos pontos = milhar brasileiro\n const afterDot = numStr.split(\".\").slice(1);\n if (afterDot.length > 1) {\n numStr = numStr.replace(/\\./g, \"\");\n }\n }\n\n const value = parseFloat(numStr);\n return isNaN(value) ? null : value;\n}\n\n/**\n * Detecta unidade a partir de string (símbolo ou alias)\n */\nfunction detectUnit(unitStr: string): LengthUnit | null {\n const normalized = unitStr.toLowerCase().trim();\n\n // Checa aliases primeiro\n if (normalized in LENGTH_ALIASES) {\n return LENGTH_ALIASES[normalized] as LengthUnit;\n }\n\n // Checa símbolos e nomes\n for (const [variant, config] of Object.entries(LENGTH_UNITS)) {\n if (\n config.symbol.toLowerCase() === normalized ||\n config.singular?.toLowerCase() === normalized ||\n config.plural?.toLowerCase() === normalized ||\n variant.toLowerCase() === normalized\n ) {\n return variant as LengthUnit;\n }\n }\n\n return null;\n}\n","/**\n * Mass Role - Constants\n *\n * Fatores de conversão, símbolos e aliases para unidades de massa.\n *\n * Fontes:\n * - NIST SP 811 (2008)\n * - International Yard and Pound Agreement (1959)\n * - SI Brochure, 9th Edition (2019)\n *\n * Nota: Massa ≠ Peso\n * - Massa: quantidade de matéria (invariante)\n * - Peso: força gravitacional (varia com localização)\n */\n\nimport type { SimpleUnitConfig, UnitAliases } from \"../../contracts\";\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport type MassUnit =\n // SI / Metric\n | \"metric_ton\"\n | \"kilogram\"\n | \"hectogram\"\n | \"decagram\"\n | \"gram\"\n | \"decigram\"\n | \"centigram\"\n | \"milligram\"\n | \"microgram\"\n // Avoirdupois (US/UK)\n | \"long_ton\"\n | \"short_ton\"\n | \"stone\"\n | \"pound\"\n | \"ounce\"\n | \"dram\"\n | \"grain\"\n // Troy (metais preciosos)\n | \"troy_pound\"\n | \"troy_ounce\"\n | \"pennyweight\";\n\n// =============================================================================\n// UNITS CONFIG\n// =============================================================================\n\n/**\n * Configuração de cada unidade de massa.\n *\n * Base: kilogram (kg) - Unidade SI de massa\n *\n * TODOS os fatores são EXATOS:\n * - SI: derivados de potências de 10\n * - Avoirdupois: exatos desde International Yard and Pound Agreement (1959)\n * - 1 pound = 0.45359237 kg (exato por definição)\n * - Outras derivadas de pound\n * - Troy: derivados de grain e pound avoirdupois\n */\nexport const MASS_UNITS: Record<MassUnit, SimpleUnitConfig> = {\n // ===========================================================================\n // SI / Metric\n // ===========================================================================\n metric_ton: {\n factor: 1000,\n symbol: \"t\",\n singular: \"metric ton\",\n plural: \"metric tons\",\n },\n kilogram: {\n factor: 1,\n symbol: \"kg\",\n singular: \"kilogram\",\n plural: \"kilograms\",\n },\n hectogram: {\n factor: 0.1,\n symbol: \"hg\",\n singular: \"hectogram\",\n plural: \"hectograms\",\n },\n decagram: {\n factor: 0.01,\n symbol: \"dag\",\n singular: \"decagram\",\n plural: \"decagrams\",\n },\n gram: {\n factor: 0.001,\n symbol: \"g\",\n singular: \"gram\",\n plural: \"grams\",\n },\n decigram: {\n factor: 0.0001,\n symbol: \"dg\",\n singular: \"decigram\",\n plural: \"decigrams\",\n },\n centigram: {\n factor: 0.00001,\n symbol: \"cg\",\n singular: \"centigram\",\n plural: \"centigrams\",\n },\n milligram: {\n factor: 0.000001,\n symbol: \"mg\",\n singular: \"milligram\",\n plural: \"milligrams\",\n },\n microgram: {\n factor: 0.000000001,\n symbol: \"μg\",\n singular: \"microgram\",\n plural: \"micrograms\",\n },\n\n // ===========================================================================\n // Avoirdupois (US/UK) - Sistema padrão para peso comum\n // ===========================================================================\n long_ton: {\n factor: 1016.0469088, // 2240 lb (exato)\n symbol: \"long tn\",\n singular: \"long ton\",\n plural: \"long tons\",\n },\n short_ton: {\n factor: 907.18474, // 2000 lb (exato)\n symbol: \"sh tn\",\n singular: \"short ton\",\n plural: \"short tons\",\n },\n stone: {\n factor: 6.35029318, // 14 lb (exato)\n symbol: \"st\",\n singular: \"stone\",\n plural: \"stone\", // stone não muda no plural em inglês\n },\n pound: {\n factor: 0.45359237, // Exato desde 1959\n symbol: \"lb\",\n singular: \"pound\",\n plural: \"pounds\",\n },\n ounce: {\n factor: 0.028349523125, // 1/16 lb (exato)\n symbol: \"oz\",\n singular: \"ounce\",\n plural: \"ounces\",\n },\n dram: {\n factor: 0.0017718451953125, // 1/16 oz (exato)\n symbol: \"dr\",\n singular: \"dram\",\n plural: \"drams\",\n },\n grain: {\n factor: 0.00006479891, // 1/7000 lb (exato)\n symbol: \"gr\",\n singular: \"grain\",\n plural: \"grains\",\n },\n\n // ===========================================================================\n // Troy (metais preciosos)\n // ===========================================================================\n troy_pound: {\n factor: 0.3732417216, // 12 troy oz (exato)\n symbol: \"lb t\",\n singular: \"troy pound\",\n plural: \"troy pounds\",\n },\n troy_ounce: {\n factor: 0.0311034768, // 480 grains (exato)\n symbol: \"oz t\",\n singular: \"troy ounce\",\n plural: \"troy ounces\",\n },\n pennyweight: {\n factor: 0.00155517384, // 1/20 troy oz (exato)\n symbol: \"dwt\",\n singular: \"pennyweight\",\n plural: \"pennyweights\",\n },\n};\n\n// =============================================================================\n// ALIASES\n// =============================================================================\n\n/**\n * Aliases para reconhecimento de unidades no cast\n */\nexport const MASS_ALIASES: UnitAliases = {\n // metric_ton\n t: \"metric_ton\",\n // kilogram\n kg: \"kilogram\",\n // hectogram\n hg: \"hectogram\",\n // decagram\n dag: \"decagram\",\n // gram\n g: \"gram\",\n // decigram\n dg: \"decigram\",\n // centigram\n cg: \"centigram\",\n // milligram\n mg: \"milligram\",\n // microgram\n \"μg\": \"microgram\",\n ug: \"microgram\",\n mcg: \"microgram\",\n // long_ton\n \"long tn\": \"long_ton\",\n // short_ton\n \"sh tn\": \"short_ton\",\n // stone\n st: \"stone\",\n // pound\n lb: \"pound\",\n lbs: \"pound\",\n \"#\": \"pound\",\n // ounce\n oz: \"ounce\",\n // dram\n dr: \"dram\",\n // grain\n gr: \"grain\",\n // troy_pound\n \"lb t\": \"troy_pound\",\n // troy_ounce\n \"oz t\": \"troy_ounce\",\n ozt: \"troy_ounce\",\n // pennyweight\n dwt: \"pennyweight\",\n};\n\n// =============================================================================\n// HELPERS\n// =============================================================================\n\n/** Lista de todas as unidades */\nexport const MASS_UNIT_LIST = Object.keys(MASS_UNITS) as MassUnit[];\n\n/** Fatores de conversão (para compatibilidade) */\nexport const MASS_FACTORS: Record<MassUnit, number> = Object.fromEntries(\n Object.entries(MASS_UNITS).map(([unit, config]) => [\n unit,\n config.factor ?? 1,\n ]),\n) as Record<MassUnit, number>;\n","/**\n * Mass Role - Convert Pillar\n *\n * Conversão entre unidades de massa usando arquitetura hub-and-spoke.\n * Base: kilogram (kg)\n *\n * @example\n * import { convertMass, toBaseMass, fromBaseMass } from '@attrx/role-morphic/mass/convert';\n *\n * convertMass('kilogram', 'pound', 1); // 2.20462...\n * toBaseMass('pound', 1); // 0.45359237\n * fromBaseMass('pound', 0.45359237); // 1\n */\n\nimport { MASS_UNITS, type MassUnit } from \"./constants\";\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport type Result<T> =\n | { ok: true; value: T }\n | { ok: false; error: string };\n\n// =============================================================================\n// CONSTANTS\n// =============================================================================\n\n/** Variante base para conversões */\nexport const MASS_BASE: MassUnit = \"kilogram\";\n\n// =============================================================================\n// CONVERT\n// =============================================================================\n\n/**\n * Converte valor para a unidade base (kilogram)\n *\n * @param variant - Unidade de origem\n * @param value - Valor a converter\n * @returns Valor em kilogram\n *\n * @example\n * toBaseMass('pound', 1); // 0.45359237\n * toBaseMass('gram', 1000); // 1\n */\nexport function toBaseMass(variant: MassUnit, value: number): number {\n const unit = MASS_UNITS[variant];\n\n if (!unit) {\n throw new Error(`Unknown mass variant: ${variant}`);\n }\n\n return value * (unit.factor ?? 1);\n}\n\n/**\n * Converte valor da unidade base (kilogram) para outra unidade\n *\n * @param variant - Unidade de destino\n * @param baseValue - Valor em kilogram\n * @returns Valor na unidade de destino\n *\n * @example\n * fromBaseMass('pound', 1); // 2.20462...\n * fromBaseMass('gram', 1); // 1000\n */\nexport function fromBaseMass(variant: MassUnit, baseValue: number): number {\n const unit = MASS_UNITS[variant];\n\n if (!unit) {\n throw new Error(`Unknown mass variant: ${variant}`);\n }\n\n return baseValue / (unit.factor ?? 1);\n}\n\n/**\n * Converte entre duas unidades de massa\n *\n * @param from - Unidade de origem\n * @param to - Unidade de destino\n * @param value - Valor a converter\n * @returns Valor convertido\n *\n * @example\n * convertMass('kilogram', 'pound', 1); // 2.20462...\n * convertMass('pound', 'kilogram', 2.2); // ~1\n * convertMass('gram', 'milligram', 1); // 1000\n */\nexport function convertMass(\n from: MassUnit,\n to: MassUnit,\n value: number\n): number {\n // Otimização: mesma unidade\n if (from === to) {\n return value;\n }\n\n // Hub-and-spoke: from → base → to\n const baseValue = toBaseMass(from, value);\n return fromBaseMass(to, baseValue);\n}\n\n/**\n * Versão safe de convertMass que retorna Result\n *\n * @example\n * tryConvertMass('kilogram', 'pound', 1);\n * // { ok: true, value: 2.20462... }\n *\n * tryConvertMass('invalid', 'pound', 1);\n * // { ok: false, error: 'Unknown mass variant: invalid' }\n */\nexport function tryConvertMass(\n from: MassUnit,\n to: MassUnit,\n value: number\n): Result<number> {\n try {\n const result = convertMass(from, to, value);\n return { ok: true, value: result };\n } catch (err) {\n return { ok: false, error: String(err) };\n }\n}\n\n/**\n * Verifica se uma variante existe\n */\nexport function hasMassVariant(variant: string): variant is MassUnit {\n return variant in MASS_UNITS;\n}\n\n/**\n * Lista todas as variantes disponíveis\n */\nexport function getMassVariants(): MassUnit[] {\n return Object.keys(MASS_UNITS) as MassUnit[];\n}\n","/**\n * Mass Role - Cast Pillar\n *\n * Normaliza input sujo para número tipado.\n * Detecta unidades em strings e converte se necessário.\n *\n * @example\n * import { castMass, castMassStrict, detectMassUnit } from '@attrx/role-morphic/mass/cast';\n *\n * castMass('100 kg', 'kilogram'); // 100\n * castMass('100 lb', 'kilogram'); // 45.359237 (converte)\n * castMassStrict('100 kg'); // 100 (não converte)\n * detectMassUnit('100 pounds'); // 'pound'\n */\n\nimport { MASS_UNITS, MASS_ALIASES, type MassUnit } from \"./constants\";\nimport { convertMass } from \"./convert\";\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport type Result<T> =\n | { ok: true; value: T }\n | { ok: false; error: string };\n\n// =============================================================================\n// CAST\n// =============================================================================\n\n/**\n * Faz cast de input para número, detectando e convertendo unidade se presente\n *\n * @param input - Valor de entrada (number, string, etc)\n * @param targetVariant - Unidade alvo para conversão\n * @returns Número ou null se não puder converter\n *\n * @example\n * castMass(100, 'kilogram'); // 100\n * castMass('100', 'kilogram'); // 100\n * castMass('100 kg', 'kilogram'); // 100\n * castMass('100 lb', 'kilogram'); // 45.359237 (converte)\n * castMass('100 pounds', 'gram'); // 45359.237 (converte)\n * castMass('invalid', 'kilogram'); // null\n */\nexport function castMass(\n input: unknown,\n targetVariant: MassUnit = \"kilogram\"\n): number | null {\n // Já é número\n if (typeof input === \"number\") {\n return Number.isFinite(input) ? input : null;\n }\n\n // String\n if (typeof input === \"string\") {\n return parseMassString(input, targetVariant);\n }\n\n return null;\n}\n\n/**\n * Faz cast sem conversão de unidade (só parseia o valor literal)\n *\n * @param input - Valor de entrada\n * @returns Número ou null\n *\n * @example\n * castMassStrict('100 kg'); // 100 (ignora unidade, não converte)\n * castMassStrict('100'); // 100\n * castMassStrict(100); // 100\n */\nexport function castMassStrict(input: unknown): number | null {\n // Já é número\n if (typeof input === \"number\") {\n return Number.isFinite(input) ? input : null;\n }\n\n // String\n if (typeof input === \"string\") {\n const numValue = parseNumber(input);\n return numValue;\n }\n\n return null;\n}\n\n/**\n * Versão safe de castMass que retorna Result\n */\nexport function tryCastMass(\n input: unknown,\n targetVariant: MassUnit = \"kilogram\"\n): Result<number> {\n const result = castMass(input, targetVariant);\n if (result === null) {\n return {\n ok: false,\n error: `Cannot cast \"${String(input)}\" to mass:${targetVariant}`,\n };\n }\n return { ok: true, value: result };\n}\n\n// =============================================================================\n// DETECTION\n// =============================================================================\n\n/**\n * Detecta unidade de massa a partir de uma string\n *\n * @param input - String com possível unidade\n * @returns Unidade detectada ou null\n *\n * @example\n * detectMassUnit('100 kg'); // 'kilogram'\n * detectMassUnit('100 pounds'); // 'pound'\n * detectMassUnit('100 oz'); // 'ounce'\n * detectMassUnit('100'); // null\n */\nexport function detectMassUnit(input: string): MassUnit | null {\n const trimmed = input.trim().toLowerCase();\n const match = trimmed.match(/^[+-]?[\\d.,\\s]+\\s*(.*)$/);\n\n if (!match || !match[1]) {\n return null;\n }\n\n const unitStr = match[1].trim();\n return detectUnit(unitStr);\n}\n\n// =============================================================================\n// INTERNAL HELPERS\n// =============================================================================\n\n/**\n * Parseia string para número, detectando unidade e convertendo se necessário\n */\nfunction parseMassString(input: string, targetVariant: MassUnit): number | null {\n const trimmed = input.trim().toLowerCase();\n\n // Extrai número e possível unidade\n const match = trimmed.match(/^([+-]?[\\d.,\\s]+)\\s*(.*)$/);\n if (!match) {\n return null;\n }\n\n const [, numStr, unitStr] = match;\n\n // Normaliza número\n const numValue = parseNumber(numStr);\n if (numValue === null) {\n return null;\n }\n\n // Se tem unidade no input, converte se necessário\n const cleanUnitStr = unitStr.trim();\n if (cleanUnitStr) {\n const detectedUnit = detectUnit(cleanUnitStr);\n if (detectedUnit && detectedUnit !== targetVariant) {\n // Converte da unidade detectada para a target\n return convertMass(detectedUnit, targetVariant, numValue);\n }\n }\n\n return numValue;\n}\n\n/**\n * Parseia string numérica considerando formatos brasileiro e americano\n */\nfunction parseNumber(numStr: string): number | null {\n // Remove espaços\n numStr = numStr.replace(/\\s/g, \"\");\n\n const lastComma = numStr.lastIndexOf(\",\");\n const lastDot = numStr.lastIndexOf(\".\");\n const hasComma = lastComma !== -1;\n const hasDot = lastDot !== -1;\n\n if (hasComma && hasDot) {\n if (lastComma > lastDot) {\n // Brasileiro: 1.000,50\n numStr = numStr.replace(/\\./g, \"\").replace(\",\", \".\");\n } else {\n // Americano: 1,000.50\n numStr = numStr.replace(/,/g, \"\");\n }\n } else if (hasComma && !hasDot) {\n // Só vírgulas: detecta se é milhar ou decimal\n const afterComma = numStr.split(\",\").slice(1);\n const isThousandSep = afterComma.every((part) => part.length === 3);\n if (isThousandSep) {\n numStr = numStr.replace(/,/g, \"\");\n } else {\n numStr = numStr.replace(\",\", \".\");\n }\n } else if (!hasComma && hasDot) {\n // Só pontos: múltiplos pontos = milhar brasileiro\n const afterDot = numStr.split(\".\").slice(1);\n if (afterDot.length > 1) {\n numStr = numStr.replace(/\\./g, \"\");\n }\n }\n\n const value = parseFloat(numStr);\n return isNaN(value) ? null : value;\n}\n\n/**\n * Detecta unidade a partir de string (símbolo ou alias)\n */\nfunction detectUnit(unitStr: string): MassUnit | null {\n const normalized = unitStr.toLowerCase().trim();\n\n // Checa aliases primeiro\n if (normalized in MASS_ALIASES) {\n return MASS_ALIASES[normalized] as MassUnit;\n }\n\n // Checa símbolos e nomes\n for (const [variant, config] of Object.entries(MASS_UNITS)) {\n if (\n config.symbol.toLowerCase() === normalized ||\n config.singular?.toLowerCase() === normalized ||\n config.plural?.toLowerCase() === normalized ||\n variant.toLowerCase() === normalized\n ) {\n return variant as MassUnit;\n }\n }\n\n return null;\n}\n","/**\n * Temperature Role - Constants\n *\n * Fórmulas de conversão, símbolos e aliases para unidades de temperatura.\n *\n * IMPORTANTE: Temperatura usa FÓRMULAS, não fatores multiplicativos.\n * Isso porque as escalas têm offsets diferentes (0°C ≠ 0°F ≠ 0K).\n *\n * Fontes:\n * - NIST SP 811 (2008)\n * - SI Brochure, 9th Edition (2019)\n */\n\nimport type { SimpleUnitConfig, UnitAliases } from \"../../contracts\";\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport type TemperatureUnit = \"celsius\" | \"fahrenheit\" | \"kelvin\" | \"rankine\";\n\n// =============================================================================\n// UNITS CONFIG\n// =============================================================================\n\n/**\n * Configuração de cada unidade de temperatura.\n *\n * Base: celsius (°C)\n *\n * Fórmulas de conversão:\n * - Celsius ↔ Fahrenheit: °F = °C × 9/5 + 32\n * - Celsius ↔ Kelvin: K = °C + 273.15\n * - Celsius ↔ Rankine: °R = (°C + 273.15) × 9/5\n *\n * Pontos de referência:\n * | Descrição | Celsius | Fahrenheit | Kelvin | Rankine |\n * |------------------|---------|------------|---------|---------|\n * | Zero absoluto | -273.15 | -459.67 | 0 | 0 |\n * | Congelamento H₂O | 0 | 32 | 273.15 | 491.67 |\n * | Corpo humano | 37 | 98.6 | 310.15 | 558.27 |\n * | Ebulição H₂O | 100 | 212 | 373.15 | 671.67 |\n */\nexport const TEMPERATURE_UNITS: Record<TemperatureUnit, SimpleUnitConfig> = {\n celsius: {\n symbol: \"°C\",\n singular: \"degree Celsius\",\n plural: \"degrees Celsius\",\n toBase: (c: number) => c,\n fromBase: (c: number) => c,\n noSpace: true, // 25°C não 25 °C\n },\n fahrenheit: {\n symbol: \"°F\",\n singular: \"degree Fahrenheit\",\n plural: \"degrees Fahrenheit\",\n toBase: (f: number) => (f - 32) * (5 / 9),\n fromBase: (c: number) => c * (9 / 5) + 32,\n noSpace: true, // 77°F não 77 °F\n },\n kelvin: {\n symbol: \"K\",\n singular: \"kelvin\",\n plural: \"kelvins\",\n toBase: (k: number) => k - 273.15,\n fromBase: (c: number) => c + 273.15,\n // Kelvin usa espaço: \"273 K\" (convenção SI)\n },\n rankine: {\n symbol: \"°R\",\n singular: \"degree Rankine\",\n plural: \"degrees Rankine\",\n toBase: (r: number) => (r - 491.67) * (5 / 9),\n fromBase: (c: number) => (c + 273.15) * (9 / 5),\n noSpace: true, // 500°R não 500 °R\n },\n};\n\n// =============================================================================\n// ALIASES\n// =============================================================================\n\n/**\n * Aliases para reconhecimento de unidades no cast\n */\nexport const TEMPERATURE_ALIASES: UnitAliases = {\n // celsius\n c: \"celsius\",\n \"°c\": \"celsius\",\n // fahrenheit\n f: \"fahrenheit\",\n \"°f\": \"fahrenheit\",\n // kelvin\n k: \"kelvin\",\n // rankine\n r: \"rankine\",\n \"°r\": \"rankine\",\n};\n\n// =============================================================================\n// HELPERS\n// =============================================================================\n\n/** Lista de todas as unidades */\nexport const TEMPERATURE_UNIT_LIST = Object.keys(\n TEMPERATURE_UNITS,\n) as TemperatureUnit[];\n\n/**\n * Constantes importantes\n */\nexport const TEMPERATURE_CONSTANTS = {\n /** Zero absoluto em Celsius */\n ABSOLUTE_ZERO_CELSIUS: -273.15,\n /** Zero absoluto em Fahrenheit */\n ABSOLUTE_ZERO_FAHRENHEIT: -459.67,\n /** Offset Celsius → Kelvin */\n CELSIUS_TO_KELVIN_OFFSET: 273.15,\n /** Offset Fahrenheit → Rankine (são a mesma escala, só diferente offset) */\n FAHRENHEIT_TO_RANKINE_OFFSET: 459.67,\n /** Ponto de congelamento da água em Fahrenheit */\n WATER_FREEZING_FAHRENHEIT: 32,\n /** Ponto de ebulição da água em Fahrenheit */\n WATER_BOILING_FAHRENHEIT: 212,\n} as const;\n","/**\n * Temperature Role - Convert Pillar\n *\n * Conversão entre unidades de temperatura usando arquitetura hub-and-spoke.\n * Base: celsius (°C)\n *\n * IMPORTANTE: Diferente de outras roles, temperatura usa FÓRMULAS\n * ao invés de fatores multiplicativos (escalas têm offsets diferentes).\n *\n * Fórmulas de conversão:\n * - Celsius ↔ Fahrenheit: °F = °C × 9/5 + 32\n * - Celsius ↔ Kelvin: K = °C + 273.15\n * - Celsius ↔ Rankine: °R = (°C + 273.15) × 9/5\n *\n * @example\n * import { convertTemperature, toBaseTemperature, fromBaseTemperature } from '@attrx/role-morphic/temperature/convert';\n *\n * convertTemperature('celsius', 'fahrenheit', 0); // 32\n * convertTemperature('celsius', 'kelvin', 0); // 273.15\n * toBaseTemperature('fahrenheit', 32); // 0\n * fromBaseTemperature('kelvin', 0); // 273.15\n */\n\nimport { TEMPERATURE_UNITS, type TemperatureUnit } from \"./constants\";\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport type Result<T> =\n | { ok: true; value: T }\n | { ok: false; error: string };\n\n// =============================================================================\n// CONSTANTS\n// =============================================================================\n\n/** Variante base para conversões */\nexport const TEMPERATURE_BASE: TemperatureUnit = \"celsius\";\n\n// =============================================================================\n// CONVERT\n// =============================================================================\n\n/**\n * Converte valor para a unidade base (celsius)\n *\n * @param variant - Unidade de origem\n * @param value - Valor a converter\n * @returns Valor em celsius\n *\n * @example\n * toBaseTemperature('fahrenheit', 32); // 0\n * toBaseTemperature('kelvin', 273.15); // 0\n * toBaseTemperature('rankine', 491.67); // 0\n */\nexport function toBaseTemperature(variant: TemperatureUnit, value: number): number {\n const unit = TEMPERATURE_UNITS[variant];\n\n if (!unit) {\n throw new Error(`Unknown temperature variant: ${variant}`);\n }\n\n // Temperatura usa fórmulas (toBase/fromBase), não factor\n if (unit.toBase) {\n return unit.toBase(value);\n }\n\n // Fallback (não deveria acontecer para temperature)\n return value * (unit.factor ?? 1);\n}\n\n/**\n * Converte valor da unidade base (celsius) para outra unidade\n *\n * @param variant - Unidade de destino\n * @param baseValue - Valor em celsius\n * @returns Valor na unidade de destino\n *\n * @example\n * fromBaseTemperature('fahrenheit', 0); // 32\n * fromBaseTemperature('kelvin', 0); // 273.15\n * fromBaseTemperature('rankine', 0); // 491.67\n */\nexport function fromBaseTemperature(variant: TemperatureUnit, baseValue: number): number {\n const unit = TEMPERATURE_UNITS[variant];\n\n if (!unit) {\n throw new Error(`Unknown temperature variant: ${variant}`);\n }\n\n // Temperatura usa fórmulas (toBase/fromBase), não factor\n if (unit.fromBase) {\n return unit.fromBase(baseValue);\n }\n\n // Fallback (não deveria acontecer para temperature)\n return baseValue / (unit.factor ?? 1);\n}\n\n/**\n * Converte entre duas unidades de temperatura\n *\n * @param from - Unidade de origem\n * @param to - Unidade de destino\n * @param value - Valor a converter\n * @returns Valor convertido\n *\n * @example\n * convertTemperature('celsius', 'fahrenheit', 0); // 32\n * convertTemperature('celsius', 'fahrenheit', 100); // 212\n * convertTemperature('fahrenheit', 'celsius', 32); // 0\n * convertTemperature('celsius', 'kelvin', 0); // 273.15\n * convertTemperature('kelvin', 'rankine', 0); // 0\n */\nexport function convertTemperature(\n from: TemperatureUnit,\n to: TemperatureUnit,\n value: number\n): number {\n // Otimização: mesma unidade\n if (from === to) {\n return value;\n }\n\n // Hub-and-spoke: from → base (celsius) → to\n const baseValue = toBaseTemperature(from, value);\n return fromBaseTemperature(to, baseValue);\n}\n\n/**\n * Versão safe de convertTemperature que retorna Result\n *\n * @example\n * tryConvertTemperature('celsius', 'fahrenheit', 0);\n * // { ok: true, value: 32 }\n *\n * tryConvertTemperature('invalid', 'fahrenheit', 0);\n * // { ok: false, error: 'Unknown temperature variant: invalid' }\n */\nexport function tryConvertTemperature(\n from: TemperatureUnit,\n to: TemperatureUnit,\n value: number\n): Result<number> {\n try {\n const result = convertTemperature(from, to, value);\n return { ok: true, value: result };\n } catch (err) {\n return { ok: false, error: String(err) };\n }\n}\n\n/**\n * Verifica se uma variante existe\n */\nexport function hasTemperatureVariant(variant: string): variant is TemperatureUnit {\n return variant in TEMPERATURE_UNITS;\n}\n\n/**\n * Lista todas as variantes disponíveis\n */\nexport function getTemperatureVariants(): TemperatureUnit[] {\n return Object.keys(TEMPERATURE_UNITS) as TemperatureUnit[];\n}\n","/**\n * Temperature Role - Cast Pillar\n *\n * Normaliza input sujo para número tipado.\n * Detecta unidades em strings e converte se necessário.\n *\n * @example\n * import { castTemperature, castTemperatureStrict, detectTemperatureUnit } from '@attrx/role-morphic/temperature/cast';\n *\n * castTemperature('100 °C', 'celsius'); // 100\n * castTemperature('32 °F', 'celsius'); // 0 (converte)\n * castTemperatureStrict('100 °C'); // 100 (não converte)\n * detectTemperatureUnit('100 degrees F'); // 'fahrenheit'\n */\n\nimport { TEMPERATURE_UNITS, TEMPERATURE_ALIASES, type TemperatureUnit } from \"./constants\";\nimport { convertTemperature } from \"./convert\";\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport type Result<T> =\n | { ok: true; value: T }\n | { ok: false; error: string };\n\n// =============================================================================\n// CAST\n// =============================================================================\n\n/**\n * Faz cast de input para número, detectando e convertendo unidade se presente\n *\n * @param input - Valor de entrada (number, string, etc)\n * @param targetVariant - Unidade alvo para conversão\n * @returns Número ou null se não puder converter\n *\n * @example\n * castTemperature(100, 'celsius'); // 100\n * castTemperature('100', 'celsius'); // 100\n * castTemperature('100 °C', 'celsius'); // 100\n * castTemperature('32 °F', 'celsius'); // 0 (converte F → C)\n * castTemperature('273.15 K', 'celsius'); // 0 (converte K → C)\n * castTemperature('invalid', 'celsius'); // null\n */\nexport function castTemperature(\n input: unknown,\n targetVariant: TemperatureUnit = \"celsius\"\n): number | null {\n // Já é número\n if (typeof input === \"number\") {\n return Number.isFinite(input) ? input : null;\n }\n\n // String\n if (typeof input === \"string\") {\n return parseTemperatureString(input, targetVariant);\n }\n\n return null;\n}\n\n/**\n * Faz cast sem conversão de unidade (só parseia o valor literal)\n *\n * @param input - Valor de entrada\n * @returns Número ou null\n *\n * @example\n * castTemperatureStrict('100 °C'); // 100 (ignora unidade, não converte)\n * castTemperatureStrict('100'); // 100\n * castTemperatureStrict(100); // 100\n */\nexport function castTemperatureStrict(input: unknown): number | null {\n // Já é número\n if (typeof input === \"number\") {\n return Number.isFinite(input) ? input : null;\n }\n\n // String\n if (typeof input === \"string\") {\n const numValue = parseNumber(input);\n return numValue;\n }\n\n return null;\n}\n\n/**\n * Versão safe de castTemperature que retorna Result\n */\nexport function tryCastTemperature(\n input: unknown,\n targetVariant: TemperatureUnit = \"celsius\"\n): Result<number> {\n const result = castTemperature(input, targetVariant);\n if (result === null) {\n return {\n ok: false,\n error: `Cannot cast \"${String(input)}\" to temperature:${targetVariant}`,\n };\n }\n return { ok: true, value: result };\n}\n\n// =============================================================================\n// DETECTION\n// =============================================================================\n\n/**\n * Detecta unidade de temperatura a partir de uma string\n *\n * @param input - String com possível unidade\n * @returns Unidade detectada ou null\n *\n * @example\n * detectTemperatureUnit('100 °C'); // 'celsius'\n * detectTemperatureUnit('100 degrees F'); // 'fahrenheit'\n * detectTemperatureUnit('273 K'); // 'kelvin'\n * detectTemperatureUnit('100'); // null\n */\nexport function detectTemperatureUnit(input: string): TemperatureUnit | null {\n const trimmed = input.trim().toLowerCase();\n const match = trimmed.match(/^[+-]?[\\d.,\\s]+\\s*(.*)$/);\n\n if (!match || !match[1]) {\n return null;\n }\n\n const unitStr = match[1].trim();\n return detectUnit(unitStr);\n}\n\n// =============================================================================\n// INTERNAL HELPERS\n// =============================================================================\n\n/**\n * Parseia string para número, detectando unidade e convertendo se necessário\n */\nfunction parseTemperatureString(input: string, targetVariant: TemperatureUnit): number | null {\n const trimmed = input.trim().toLowerCase();\n\n // Extrai número e possível unidade\n const match = trimmed.match(/^([+-]?[\\d.,\\s]+)\\s*(.*)$/);\n if (!match) {\n return null;\n }\n\n const [, numStr, unitStr] = match;\n\n // Normaliza número\n const numValue = parseNumber(numStr);\n if (numValue === null) {\n return null;\n }\n\n // Se tem unidade no input, converte se necessário\n const cleanUnitStr = unitStr.trim();\n if (cleanUnitStr) {\n const detectedUnit = detectUnit(cleanUnitStr);\n if (detectedUnit && detectedUnit !== targetVariant) {\n // Converte da unidade detectada para a target\n return convertTemperature(detectedUnit, targetVariant, numValue);\n }\n }\n\n return numValue;\n}\n\n/**\n * Parseia string numérica considerando formatos brasileiro e americano\n */\nfunction parseNumber(numStr: string): number | null {\n // Remove espaços\n numStr = numStr.replace(/\\s/g, \"\");\n\n const lastComma = numStr.lastIndexOf(\",\");\n const lastDot = numStr.lastIndexOf(\".\");\n const hasComma = lastComma !== -1;\n const hasDot = lastDot !== -1;\n\n if (hasComma && hasDot) {\n if (lastComma > lastDot) {\n // Brasileiro: 1.000,50\n numStr = numStr.replace(/\\./g, \"\").replace(\",\", \".\");\n } else {\n // Americano: 1,000.50\n numStr = numStr.replace(/,/g, \"\");\n }\n } else if (hasComma && !hasDot) {\n // Só vírgulas: detecta se é milhar ou decimal\n const afterComma = numStr.split(\",\").slice(1);\n const isThousandSep = afterComma.every((part) => part.length === 3);\n if (isThousandSep) {\n numStr = numStr.replace(/,/g, \"\");\n } else {\n numStr = numStr.replace(\",\", \".\");\n }\n } else if (!hasComma && hasDot) {\n // Só pontos: múltiplos pontos = milhar brasileiro\n const afterDot = numStr.split(\".\").slice(1);\n if (afterDot.length > 1) {\n numStr = numStr.replace(/\\./g, \"\");\n }\n }\n\n const value = parseFloat(numStr);\n return isNaN(value) ? null : value;\n}\n\n/**\n * Detecta unidade a partir de string (símbolo ou alias)\n */\nfunction detectUnit(unitStr: string): TemperatureUnit | null {\n const normalized = unitStr.toLowerCase().trim();\n\n // Checa aliases primeiro\n if (normalized in TEMPERATURE_ALIASES) {\n return TEMPERATURE_ALIASES[normalized] as TemperatureUnit;\n }\n\n // Checa símbolos e nomes\n for (const [variant, config] of Object.entries(TEMPERATURE_UNITS)) {\n if (\n config.symbol.toLowerCase() === normalized ||\n config.singular?.toLowerCase() === normalized ||\n config.plural?.toLowerCase() === normalized ||\n variant.toLowerCase() === normalized\n ) {\n return variant as TemperatureUnit;\n }\n }\n\n return null;\n}\n","/**\n * Volume Role - Constants\n *\n * Fatores de conversão, símbolos e aliases para unidades de volume.\n *\n * Fontes:\n * - NIST SP 811 (2008)\n * - NIST Handbook 44 (2024)\n * - SI Brochure, 9th Edition (2019)\n *\n * Notas:\n * - Base: liter (L) - unidade aceita para uso com o SI\n * - 1 L = 1 dm³ = 0.001 m³\n * - Galão US vs UK: ~20% diferença (UK é maior)\n */\n\nimport type { SimpleUnitConfig, UnitAliases } from \"../../contracts\";\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport type VolumeUnit =\n // SI / Métrico\n | \"cubic_meter\"\n | \"cubic_decimeter\"\n | \"cubic_centimeter\"\n | \"cubic_millimeter\"\n | \"hectoliter\"\n | \"decaliter\"\n | \"liter\"\n | \"deciliter\"\n | \"centiliter\"\n | \"milliliter\"\n | \"microliter\"\n // US Customary\n | \"gallon_us\"\n | \"quart_us\"\n | \"pint_us\"\n | \"cup_us\"\n | \"fluid_ounce_us\"\n | \"tablespoon_us\"\n | \"teaspoon_us\"\n // Imperial (UK)\n | \"gallon_uk\"\n | \"quart_uk\"\n | \"pint_uk\"\n | \"fluid_ounce_uk\"\n // Other\n | \"barrel_oil\"\n | \"cubic_inch\"\n | \"cubic_foot\"\n | \"cubic_yard\";\n\n// =============================================================================\n// UNITS CONFIG\n// =============================================================================\n\n/**\n * Configuração de cada unidade de volume.\n *\n * Base: liter (L)\n *\n * Fatores exatos:\n * - SI: derivados de potências de 10\n * - US: baseados em 1 gallon US = 231 in³ (exato)\n * - UK: 1 gallon UK = 4.54609 L (exato, definição 1985)\n */\nexport const VOLUME_UNITS: Record<VolumeUnit, SimpleUnitConfig> = {\n // SI / Métrico\n cubic_meter: {\n factor: 1000,\n symbol: \"m³\",\n singular: \"cubic meter\",\n plural: \"cubic meters\",\n },\n cubic_decimeter: {\n factor: 1,\n symbol: \"dm³\",\n singular: \"cubic decimeter\",\n plural: \"cubic decimeters\",\n },\n cubic_centimeter: {\n factor: 0.001,\n symbol: \"cm³\",\n singular: \"cubic centimeter\",\n plural: \"cubic centimeters\",\n },\n cubic_millimeter: {\n factor: 0.000001,\n symbol: \"mm³\",\n singular: \"cubic millimeter\",\n plural: \"cubic millimeters\",\n },\n hectoliter: {\n factor: 100,\n symbol: \"hL\",\n singular: \"hectoliter\",\n plural: \"hectoliters\",\n },\n decaliter: {\n factor: 10,\n symbol: \"daL\",\n singular: \"decaliter\",\n plural: \"decaliters\",\n },\n liter: {\n factor: 1,\n symbol: \"L\",\n singular: \"liter\",\n plural: \"liters\",\n },\n deciliter: {\n factor: 0.1,\n symbol: \"dL\",\n singular: \"deciliter\",\n plural: \"deciliters\",\n },\n centiliter: {\n factor: 0.01,\n symbol: \"cL\",\n singular: \"centiliter\",\n plural: \"centiliters\",\n },\n milliliter: {\n factor: 0.001,\n symbol: \"mL\",\n singular: \"milliliter\",\n plural: \"milliliters\",\n },\n microliter: {\n factor: 0.000001,\n symbol: \"μL\",\n singular: \"microliter\",\n plural: \"microliters\",\n },\n\n // US Customary (baseado em 1 gallon = 231 in³ = 3.785411784 L)\n gallon_us: {\n factor: 3.785411784,\n symbol: \"gal\",\n singular: \"gallon\",\n plural: \"gallons\",\n },\n quart_us: {\n factor: 0.946352946, // gallon/4\n symbol: \"qt\",\n singular: \"quart\",\n plural: \"quarts\",\n },\n pint_us: {\n factor: 0.473176473, // gallon/8\n symbol: \"pt\",\n singular: \"pint\",\n plural: \"pints\",\n },\n cup_us: {\n factor: 0.2365882365, // gallon/16\n symbol: \"cup\",\n singular: \"cup\",\n plural: \"cups\",\n },\n fluid_ounce_us: {\n factor: 0.0295735295625, // gallon/128\n symbol: \"fl oz\",\n singular: \"fluid ounce\",\n plural: \"fluid ounces\",\n },\n tablespoon_us: {\n factor: 0.01478676478125, // fl oz/2\n symbol: \"tbsp\",\n singular: \"tablespoon\",\n plural: \"tablespoons\",\n },\n teaspoon_us: {\n factor: 0.00492892159375, // tbsp/3\n symbol: \"tsp\",\n singular: \"teaspoon\",\n plural: \"teaspoons\",\n },\n\n // Imperial UK (1 gallon UK = 4.54609 L exato)\n gallon_uk: {\n factor: 4.54609,\n symbol: \"gal (UK)\",\n singular: \"gallon (UK)\",\n plural: \"gallons (UK)\",\n },\n quart_uk: {\n factor: 1.1365225, // gallon/4\n symbol: \"qt (UK)\",\n singular: \"quart (UK)\",\n plural: \"quarts (UK)\",\n },\n pint_uk: {\n factor: 0.56826125, // gallon/8\n symbol: \"pt (UK)\",\n singular: \"pint (UK)\",\n plural: \"pints (UK)\",\n },\n fluid_ounce_uk: {\n factor: 0.0284130625, // gallon/160\n symbol: \"fl oz (UK)\",\n singular: \"fluid ounce (UK)\",\n plural: \"fluid ounces (UK)\",\n },\n\n // Other\n barrel_oil: {\n factor: 158.987294928, // 42 US gallons (petroleum)\n symbol: \"bbl\",\n singular: \"barrel\",\n plural: \"barrels\",\n },\n cubic_inch: {\n factor: 0.016387064, // (0.0254)³ × 1000\n symbol: \"in³\",\n singular: \"cubic inch\",\n plural: \"cubic inches\",\n },\n cubic_foot: {\n factor: 28.316846592, // (0.3048)³ × 1000\n symbol: \"ft³\",\n singular: \"cubic foot\",\n plural: \"cubic feet\",\n },\n cubic_yard: {\n factor: 764.554857984, // (0.9144)³ × 1000\n symbol: \"yd³\",\n singular: \"cubic yard\",\n plural: \"cubic yards\",\n },\n};\n\n// =============================================================================\n// ALIASES\n// =============================================================================\n\n/**\n * Aliases para reconhecimento de unidades no cast\n */\nexport const VOLUME_ALIASES: UnitAliases = {\n // cubic_meter\n \"m³\": \"cubic_meter\",\n m3: \"cubic_meter\",\n // cubic_decimeter\n \"dm³\": \"cubic_decimeter\",\n dm3: \"cubic_decimeter\",\n // cubic_centimeter\n \"cm³\": \"cubic_centimeter\",\n cm3: \"cubic_centimeter\",\n cc: \"cubic_centimeter\",\n // cubic_millimeter\n \"mm³\": \"cubic_millimeter\",\n mm3: \"cubic_millimeter\",\n // hectoliter\n hL: \"hectoliter\",\n hl: \"hectoliter\",\n // decaliter\n daL: \"decaliter\",\n dal: \"decaliter\",\n // liter\n L: \"liter\",\n l: \"liter\",\n // deciliter\n dL: \"deciliter\",\n dl: \"deciliter\",\n // centiliter\n cL: \"centiliter\",\n cl: \"centiliter\",\n // milliliter\n mL: \"milliliter\",\n ml: \"milliliter\",\n // microliter\n \"μL\": \"microliter\",\n uL: \"microliter\",\n ul: \"microliter\",\n // gallon_us\n gal: \"gallon_us\",\n // quart_us\n qt: \"quart_us\",\n // pint_us\n pt: \"pint_us\",\n // cup_us\n cup: \"cup_us\",\n // fluid_ounce_us\n \"fl oz\": \"fluid_ounce_us\",\n floz: \"fluid_ounce_us\",\n // tablespoon_us\n tbsp: \"tablespoon_us\",\n // teaspoon_us\n tsp: \"teaspoon_us\",\n // gallon_uk\n \"gal uk\": \"gallon_uk\",\n // quart_uk\n \"qt uk\": \"quart_uk\",\n // pint_uk\n \"pt uk\": \"pint_uk\",\n // fluid_ounce_uk\n \"fl oz uk\": \"fluid_ounce_uk\",\n // barrel_oil\n bbl: \"barrel_oil\",\n // cubic_inch\n \"in³\": \"cubic_inch\",\n in3: \"cubic_inch\",\n // cubic_foot\n \"ft³\": \"cubic_foot\",\n ft3: \"cubic_foot\",\n // cubic_yard\n \"yd³\": \"cubic_yard\",\n yd3: \"cubic_yard\",\n};\n\n// =============================================================================\n// HELPERS\n// =============================================================================\n\n/** Lista de todas as unidades */\nexport const VOLUME_UNIT_LIST = Object.keys(VOLUME_UNITS) as VolumeUnit[];\n\n/** Fatores de conversão (para compatibilidade) */\nexport const VOLUME_FACTORS: Record<VolumeUnit, number> = Object.fromEntries(\n Object.entries(VOLUME_UNITS).map(([unit, config]) => [\n unit,\n config.factor ?? 1,\n ]),\n) as Record<VolumeUnit, number>;\n","/**\n * Volume Role - Convert Pillar\n *\n * Conversão entre unidades de volume usando arquitetura hub-and-spoke.\n * Base: liter (L)\n *\n * @example\n * import { convertVolume, toBaseVolume, fromBaseVolume } from '@attrx/role-morphic/volume/convert';\n *\n * convertVolume('gallon_us', 'liter', 1); // 3.785411784\n * toBaseVolume('milliliter', 500); // 0.5\n * fromBaseVolume('gallon_us', 3.785411784); // 1\n */\n\nimport { VOLUME_UNITS, type VolumeUnit } from \"./constants\";\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport type Result<T> =\n | { ok: true; value: T }\n | { ok: false; error: string };\n\n// =============================================================================\n// CONSTANTS\n// =============================================================================\n\n/** Variante base para conversões */\nexport const VOLUME_BASE: VolumeUnit = \"liter\";\n\n// =============================================================================\n// CONVERT\n// =============================================================================\n\n/**\n * Converte valor para a unidade base (liter)\n *\n * @param variant - Unidade de origem\n * @param value - Valor a converter\n * @returns Valor em liter\n *\n * @example\n * toBaseVolume('milliliter', 500); // 0.5\n * toBaseVolume('gallon_us', 1); // 3.785411784\n */\nexport function toBaseVolume(variant: VolumeUnit, value: number): number {\n const unit = VOLUME_UNITS[variant];\n\n if (!unit) {\n throw new Error(`Unknown volume variant: ${variant}`);\n }\n\n return value * (unit.factor ?? 1);\n}\n\n/**\n * Converte valor da unidade base (liter) para outra unidade\n *\n * @param variant - Unidade de destino\n * @param baseValue - Valor em liter\n * @returns Valor na unidade de destino\n *\n * @example\n * fromBaseVolume('milliliter', 0.5); // 500\n * fromBaseVolume('gallon_us', 3.785411784); // 1\n */\nexport function fromBaseVolume(variant: VolumeUnit, baseValue: number): number {\n const unit = VOLUME_UNITS[variant];\n\n if (!unit) {\n throw new Error(`Unknown volume variant: ${variant}`);\n }\n\n return baseValue / (unit.factor ?? 1);\n}\n\n/**\n * Converte entre duas unidades de volume\n *\n * @param from - Unidade de origem\n * @param to - Unidade de destino\n * @param value - Valor a converter\n * @returns Valor convertido\n *\n * @example\n * convertVolume('gallon_us', 'liter', 1); // 3.785411784\n * convertVolume('milliliter', 'liter', 500); // 0.5\n * convertVolume('cup_us', 'tablespoon_us', 1); // 16\n */\nexport function convertVolume(\n from: VolumeUnit,\n to: VolumeUnit,\n value: number\n): number {\n // Otimização: mesma unidade\n if (from === to) {\n return value;\n }\n\n // Hub-and-spoke: from → base → to\n const baseValue = toBaseVolume(from, value);\n return fromBaseVolume(to, baseValue);\n}\n\n/**\n * Versão safe de convertVolume que retorna Result\n *\n * @example\n * tryConvertVolume('gallon_us', 'liter', 1);\n * // { ok: true, value: 3.785411784 }\n *\n * tryConvertVolume('invalid', 'liter', 1);\n * // { ok: false, error: 'Unknown volume variant: invalid' }\n */\nexport function tryConvertVolume(\n from: VolumeUnit,\n to: VolumeUnit,\n value: number\n): Result<number> {\n try {\n const result = convertVolume(from, to, value);\n return { ok: true, value: result };\n } catch (err) {\n return { ok: false, error: String(err) };\n }\n}\n\n/**\n * Verifica se uma variante existe\n */\nexport function hasVolumeVariant(variant: string): variant is VolumeUnit {\n return variant in VOLUME_UNITS;\n}\n\n/**\n * Lista todas as variantes disponíveis\n */\nexport function getVolumeVariants(): VolumeUnit[] {\n return Object.keys(VOLUME_UNITS) as VolumeUnit[];\n}\n","/**\n * Volume Role - Cast Pillar\n *\n * Normaliza input sujo para número tipado.\n * Detecta unidades em strings e converte se necessário.\n *\n * @example\n * import { castVolume, castVolumeStrict, detectVolumeUnit } from '@attrx/role-morphic/volume/cast';\n *\n * castVolume('500 ml', 'liter'); // 0.5 (converte)\n * castVolume('1 gal', 'liter'); // 3.785411784 (converte)\n * castVolumeStrict('500 ml'); // 500 (não converte)\n * detectVolumeUnit('2 gallons'); // 'gallon_us'\n */\n\nimport { VOLUME_UNITS, VOLUME_ALIASES, type VolumeUnit } from \"./constants\";\nimport { convertVolume } from \"./convert\";\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport type Result<T> =\n | { ok: true; value: T }\n | { ok: false; error: string };\n\n// =============================================================================\n// CAST\n// =============================================================================\n\n/**\n * Faz cast de input para número, detectando e convertendo unidade se presente\n *\n * @param input - Valor de entrada (number, string, etc)\n * @param targetVariant - Unidade alvo para conversão\n * @returns Número ou null se não puder converter\n *\n * @example\n * castVolume(100, 'liter'); // 100\n * castVolume('100', 'liter'); // 100\n * castVolume('500 ml', 'liter'); // 0.5 (converte)\n * castVolume('1 gal', 'liter'); // 3.785411784 (converte)\n * castVolume('invalid', 'liter'); // null\n */\nexport function castVolume(\n input: unknown,\n targetVariant: VolumeUnit = \"liter\"\n): number | null {\n // Já é número\n if (typeof input === \"number\") {\n return Number.isFinite(input) ? input : null;\n }\n\n // String\n if (typeof input === \"string\") {\n return parseVolumeString(input, targetVariant);\n }\n\n return null;\n}\n\n/**\n * Faz cast sem conversão de unidade (só parseia o valor literal)\n *\n * @param input - Valor de entrada\n * @returns Número ou null\n *\n * @example\n * castVolumeStrict('500 ml'); // 500 (ignora unidade, não converte)\n * castVolumeStrict('100'); // 100\n * castVolumeStrict(100); // 100\n */\nexport function castVolumeStrict(input: unknown): number | null {\n // Já é número\n if (typeof input === \"number\") {\n return Number.isFinite(input) ? input : null;\n }\n\n // String\n if (typeof input === \"string\") {\n const numValue = parseNumber(input);\n return numValue;\n }\n\n return null;\n}\n\n/**\n * Versão safe de castVolume que retorna Result\n */\nexport function tryCastVolume(\n input: unknown,\n targetVariant: VolumeUnit = \"liter\"\n): Result<number> {\n const result = castVolume(input, targetVariant);\n if (result === null) {\n return {\n ok: false,\n error: `Cannot cast \"${String(input)}\" to volume:${targetVariant}`,\n };\n }\n return { ok: true, value: result };\n}\n\n// =============================================================================\n// DETECTION\n// =============================================================================\n\n/**\n * Detecta unidade de volume a partir de uma string\n *\n * @param input - String com possível unidade\n * @returns Unidade detectada ou null\n *\n * @example\n * detectVolumeUnit('500 ml'); // 'milliliter'\n * detectVolumeUnit('2 gallons'); // 'gallon_us'\n * detectVolumeUnit('1 L'); // 'liter'\n * detectVolumeUnit('100'); // null\n */\nexport function detectVolumeUnit(input: string): VolumeUnit | null {\n const trimmed = input.trim().toLowerCase();\n const match = trimmed.match(/^[+-]?[\\d.,\\s]+\\s*(.*)$/);\n\n if (!match || !match[1]) {\n return null;\n }\n\n const unitStr = match[1].trim();\n return detectUnit(unitStr);\n}\n\n// =============================================================================\n// INTERNAL HELPERS\n// =============================================================================\n\n/**\n * Parseia string para número, detectando unidade e convertendo se necessário\n */\nfunction parseVolumeString(input: string, targetVariant: VolumeUnit): number | null {\n const trimmed = input.trim().toLowerCase();\n\n // Extrai número e possível unidade\n const match = trimmed.match(/^([+-]?[\\d.,\\s]+)\\s*(.*)$/);\n if (!match) {\n return null;\n }\n\n const [, numStr, unitStr] = match;\n\n // Normaliza número\n const numValue = parseNumber(numStr);\n if (numValue === null) {\n return null;\n }\n\n // Se tem unidade no input, converte se necessário\n const cleanUnitStr = unitStr.trim();\n if (cleanUnitStr) {\n const detectedUnit = detectUnit(cleanUnitStr);\n if (detectedUnit && detectedUnit !== targetVariant) {\n // Converte da unidade detectada para a target\n return convertVolume(detectedUnit, targetVariant, numValue);\n }\n }\n\n return numValue;\n}\n\n/**\n * Parseia string numérica considerando formatos brasileiro e americano\n */\nfunction parseNumber(numStr: string): number | null {\n // Remove espaços\n numStr = numStr.replace(/\\s/g, \"\");\n\n const lastComma = numStr.lastIndexOf(\",\");\n const lastDot = numStr.lastIndexOf(\".\");\n const hasComma = lastComma !== -1;\n const hasDot = lastDot !== -1;\n\n if (hasComma && hasDot) {\n if (lastComma > lastDot) {\n // Brasileiro: 1.000,50\n numStr = numStr.replace(/\\./g, \"\").replace(\",\", \".\");\n } else {\n // Americano: 1,000.50\n numStr = numStr.replace(/,/g, \"\");\n }\n } else if (hasComma && !hasDot) {\n // Só vírgulas: detecta se é milhar ou decimal\n const afterComma = numStr.split(\",\").slice(1);\n const isThousandSep = afterComma.every((part) => part.length === 3);\n if (isThousandSep) {\n numStr = numStr.replace(/,/g, \"\");\n } else {\n numStr = numStr.replace(\",\", \".\");\n }\n } else if (!hasComma && hasDot) {\n // Só pontos: múltiplos pontos = milhar brasileiro\n const afterDot = numStr.split(\".\").slice(1);\n if (afterDot.length > 1) {\n numStr = numStr.replace(/\\./g, \"\");\n }\n }\n\n const value = parseFloat(numStr);\n return isNaN(value) ? null : value;\n}\n\n/**\n * Detecta unidade a partir de string (símbolo ou alias)\n */\nfunction detectUnit(unitStr: string): VolumeUnit | null {\n const normalized = unitStr.toLowerCase().trim();\n\n // Checa aliases primeiro\n if (normalized in VOLUME_ALIASES) {\n return VOLUME_ALIASES[normalized] as VolumeUnit;\n }\n\n // Checa símbolos e nomes\n for (const [variant, config] of Object.entries(VOLUME_UNITS)) {\n if (\n config.symbol.toLowerCase() === normalized ||\n config.singular?.toLowerCase() === normalized ||\n config.plural?.toLowerCase() === normalized ||\n variant.toLowerCase() === normalized\n ) {\n return variant as VolumeUnit;\n }\n }\n\n return null;\n}\n","/**\n * Speed Role - Constants\n *\n * Fatores de conversão, símbolos e aliases para unidades de velocidade.\n *\n * Fontes:\n * - NIST SP 811 (2008)\n * - SI Brochure, 9th Edition (2019)\n * - International Yard and Pound Agreement (1959)\n */\n\nimport type { SimpleUnitConfig, UnitAliases } from \"../../contracts\";\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport type SpeedUnit =\n // SI\n | \"meter_per_second\"\n | \"kilometer_per_hour\"\n // Imperial/US\n | \"mile_per_hour\"\n | \"foot_per_second\"\n // Nautical\n | \"knot\"\n // Scientific\n | \"mach\"\n | \"speed_of_light\";\n\n// =============================================================================\n// UNITS CONFIG\n// =============================================================================\n\n/**\n * Configuração de cada unidade de velocidade.\n *\n * Fatores exatos:\n * - km/h = 1000/3600 m/s = 0.277777... m/s\n * - mph = 1609.344/3600 m/s = 0.44704 m/s (exato, derivado de mile)\n * - ft/s = 0.3048 m/s (exato, derivado de foot)\n * - knot = 1852/3600 m/s = 0.514444... m/s (exato, derivado de nautical mile)\n *\n * Fatores aproximados:\n * - Mach: varia com temperatura/altitude, usando 340.29 m/s (nível do mar, 15°C)\n * - Velocidade da luz: exato por definição SI (299792458 m/s)\n */\nexport const SPEED_UNITS: Record<SpeedUnit, SimpleUnitConfig> = {\n // SI Units\n meter_per_second: {\n factor: 1,\n symbol: \"m/s\",\n singular: \"meter per second\",\n plural: \"meters per second\",\n },\n kilometer_per_hour: {\n factor: 1000 / 3600, // 0.277777...\n symbol: \"km/h\",\n singular: \"kilometer per hour\",\n plural: \"kilometers per hour\",\n },\n\n // Imperial/US (exatos desde 1959)\n mile_per_hour: {\n factor: 0.44704, // 1609.344 / 3600 (exato)\n symbol: \"mph\",\n singular: \"mile per hour\",\n plural: \"miles per hour\",\n },\n foot_per_second: {\n factor: 0.3048, // exato\n symbol: \"ft/s\",\n singular: \"foot per second\",\n plural: \"feet per second\",\n },\n\n // Nautical (exato)\n knot: {\n factor: 1852 / 3600, // 0.514444...\n symbol: \"kn\",\n singular: \"knot\",\n plural: \"knots\",\n },\n\n // Scientific\n mach: {\n factor: 340.29, // velocidade do som ao nível do mar, 15°C (aproximado)\n symbol: \"Ma\",\n singular: \"mach\",\n plural: \"mach\",\n },\n speed_of_light: {\n factor: 299792458, // exato por definição SI\n symbol: \"c\",\n singular: \"speed of light\",\n plural: \"speed of light\",\n },\n};\n\n// =============================================================================\n// ALIASES\n// =============================================================================\n\n/**\n * Aliases para reconhecimento de unidades no cast\n */\nexport const SPEED_ALIASES: UnitAliases = {\n // meter_per_second\n \"m/s\": \"meter_per_second\",\n mps: \"meter_per_second\",\n // kilometer_per_hour\n \"km/h\": \"kilometer_per_hour\",\n kmh: \"kilometer_per_hour\",\n kph: \"kilometer_per_hour\",\n // mile_per_hour\n mph: \"mile_per_hour\",\n \"mi/h\": \"mile_per_hour\",\n // foot_per_second\n \"ft/s\": \"foot_per_second\",\n fps: \"foot_per_second\",\n // knot\n kn: \"knot\",\n kt: \"knot\",\n kts: \"knot\",\n // mach\n ma: \"mach\",\n // speed_of_light\n c: \"speed_of_light\",\n};\n\n// =============================================================================\n// HELPERS\n// =============================================================================\n\n/** Lista de todas as unidades */\nexport const SPEED_UNIT_LIST = Object.keys(SPEED_UNITS) as SpeedUnit[];\n\n/** Fatores de conversão (para compatibilidade) */\nexport const SPEED_FACTORS: Record<SpeedUnit, number> = Object.fromEntries(\n Object.entries(SPEED_UNITS).map(([unit, config]) => [\n unit,\n config.factor ?? 1,\n ]),\n) as Record<SpeedUnit, number>;\n","/**\n * Speed Role - Convert Pillar\n *\n * Conversão entre unidades de velocidade usando arquitetura hub-and-spoke.\n * Base: meter_per_second (m/s)\n *\n * @example\n * import { convertSpeed, toBaseSpeed, fromBaseSpeed } from '@attrx/role-morphic/speed/convert';\n *\n * convertSpeed('kilometer_per_hour', 'mile_per_hour', 100); // 62.1371...\n * toBaseSpeed('kilometer_per_hour', 100); // 27.7778...\n * fromBaseSpeed('mile_per_hour', 27.7778); // ~62.14\n */\n\nimport { SPEED_UNITS, type SpeedUnit } from \"./constants\";\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport type Result<T> =\n | { ok: true; value: T }\n | { ok: false; error: string };\n\n// =============================================================================\n// CONSTANTS\n// =============================================================================\n\n/** Variante base para conversões */\nexport const SPEED_BASE: SpeedUnit = \"meter_per_second\";\n\n// =============================================================================\n// CONVERT\n// =============================================================================\n\n/**\n * Converte valor para a unidade base (meter_per_second)\n *\n * @param variant - Unidade de origem\n * @param value - Valor a converter\n * @returns Valor em meter_per_second\n *\n * @example\n * toBaseSpeed('kilometer_per_hour', 100); // 27.7778...\n * toBaseSpeed('mile_per_hour', 60); // 26.8224\n */\nexport function toBaseSpeed(variant: SpeedUnit, value: number): number {\n const unit = SPEED_UNITS[variant];\n\n if (!unit) {\n throw new Error(`Unknown speed variant: ${variant}`);\n }\n\n return value * (unit.factor ?? 1);\n}\n\n/**\n * Converte valor da unidade base (meter_per_second) para outra unidade\n *\n * @param variant - Unidade de destino\n * @param baseValue - Valor em meter_per_second\n * @returns Valor na unidade de destino\n *\n * @example\n * fromBaseSpeed('kilometer_per_hour', 27.7778); // ~100\n * fromBaseSpeed('mile_per_hour', 26.8224); // ~60\n */\nexport function fromBaseSpeed(variant: SpeedUnit, baseValue: number): number {\n const unit = SPEED_UNITS[variant];\n\n if (!unit) {\n throw new Error(`Unknown speed variant: ${variant}`);\n }\n\n return baseValue / (unit.factor ?? 1);\n}\n\n/**\n * Converte entre duas unidades de velocidade\n *\n * @param from - Unidade de origem\n * @param to - Unidade de destino\n * @param value - Valor a converter\n * @returns Valor convertido\n *\n * @example\n * convertSpeed('kilometer_per_hour', 'mile_per_hour', 100); // 62.1371...\n * convertSpeed('knot', 'kilometer_per_hour', 1); // 1.852\n * convertSpeed('mach', 'kilometer_per_hour', 1); // 1225.044\n */\nexport function convertSpeed(\n from: SpeedUnit,\n to: SpeedUnit,\n value: number\n): number {\n // Otimização: mesma unidade\n if (from === to) {\n return value;\n }\n\n // Hub-and-spoke: from → base → to\n const baseValue = toBaseSpeed(from, value);\n return fromBaseSpeed(to, baseValue);\n}\n\n/**\n * Versão safe de convertSpeed que retorna Result\n *\n * @example\n * tryConvertSpeed('kilometer_per_hour', 'mile_per_hour', 100);\n * // { ok: true, value: 62.1371... }\n *\n * tryConvertSpeed('invalid', 'mile_per_hour', 100);\n * // { ok: false, error: 'Unknown speed variant: invalid' }\n */\nexport function tryConvertSpeed(\n from: SpeedUnit,\n to: SpeedUnit,\n value: number\n): Result<number> {\n try {\n const result = convertSpeed(from, to, value);\n return { ok: true, value: result };\n } catch (err) {\n return { ok: false, error: String(err) };\n }\n}\n\n/**\n * Verifica se uma variante existe\n */\nexport function hasSpeedVariant(variant: string): variant is SpeedUnit {\n return variant in SPEED_UNITS;\n}\n\n/**\n * Lista todas as variantes disponíveis\n */\nexport function getSpeedVariants(): SpeedUnit[] {\n return Object.keys(SPEED_UNITS) as SpeedUnit[];\n}\n","/**\n * Speed Role - Cast Pillar\n *\n * Normaliza input sujo para número tipado.\n * Detecta unidades em strings e converte se necessário.\n *\n * @example\n * import { castSpeed, castSpeedStrict, detectSpeedUnit } from '@attrx/role-morphic/speed/cast';\n *\n * castSpeed('100 km/h', 'meter_per_second'); // 27.7778... (converte)\n * castSpeed('60 mph', 'kilometer_per_hour'); // 96.5606... (converte)\n * castSpeedStrict('100 km/h'); // 100 (não converte)\n * detectSpeedUnit('60 miles per hour'); // 'mile_per_hour'\n */\n\nimport { SPEED_UNITS, SPEED_ALIASES, type SpeedUnit } from \"./constants\";\nimport { convertSpeed } from \"./convert\";\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport type Result<T> =\n | { ok: true; value: T }\n | { ok: false; error: string };\n\n// =============================================================================\n// CAST\n// =============================================================================\n\n/**\n * Faz cast de input para número, detectando e convertendo unidade se presente\n *\n * @param input - Valor de entrada (number, string, etc)\n * @param targetVariant - Unidade alvo para conversão\n * @returns Número ou null se não puder converter\n *\n * @example\n * castSpeed(100, 'meter_per_second'); // 100\n * castSpeed('100', 'meter_per_second'); // 100\n * castSpeed('100 km/h', 'meter_per_second'); // 27.7778... (converte)\n * castSpeed('60 mph', 'kilometer_per_hour'); // 96.5606... (converte)\n * castSpeed('invalid', 'meter_per_second'); // null\n */\nexport function castSpeed(\n input: unknown,\n targetVariant: SpeedUnit = \"meter_per_second\"\n): number | null {\n // Já é número\n if (typeof input === \"number\") {\n return Number.isFinite(input) ? input : null;\n }\n\n // String\n if (typeof input === \"string\") {\n return parseSpeedString(input, targetVariant);\n }\n\n return null;\n}\n\n/**\n * Faz cast sem conversão de unidade (só parseia o valor literal)\n *\n * @param input - Valor de entrada\n * @returns Número ou null\n *\n * @example\n * castSpeedStrict('100 km/h'); // 100 (ignora unidade, não converte)\n * castSpeedStrict('100'); // 100\n * castSpeedStrict(100); // 100\n */\nexport function castSpeedStrict(input: unknown): number | null {\n // Já é número\n if (typeof input === \"number\") {\n return Number.isFinite(input) ? input : null;\n }\n\n // String\n if (typeof input === \"string\") {\n const numValue = parseNumber(input);\n return numValue;\n }\n\n return null;\n}\n\n/**\n * Versão safe de castSpeed que retorna Result\n */\nexport function tryCastSpeed(\n input: unknown,\n targetVariant: SpeedUnit = \"meter_per_second\"\n): Result<number> {\n const result = castSpeed(input, targetVariant);\n if (result === null) {\n return {\n ok: false,\n error: `Cannot cast \"${String(input)}\" to speed:${targetVariant}`,\n };\n }\n return { ok: true, value: result };\n}\n\n// =============================================================================\n// DETECTION\n// =============================================================================\n\n/**\n * Detecta unidade de velocidade a partir de uma string\n *\n * @param input - String com possível unidade\n * @returns Unidade detectada ou null\n *\n * @example\n * detectSpeedUnit('100 km/h'); // 'kilometer_per_hour'\n * detectSpeedUnit('60 mph'); // 'mile_per_hour'\n * detectSpeedUnit('10 knots'); // 'knot'\n * detectSpeedUnit('100'); // null\n */\nexport function detectSpeedUnit(input: string): SpeedUnit | null {\n const trimmed = input.trim().toLowerCase();\n const match = trimmed.match(/^[+-]?[\\d.,\\s]+\\s*(.*)$/);\n\n if (!match || !match[1]) {\n return null;\n }\n\n const unitStr = match[1].trim();\n return detectUnit(unitStr);\n}\n\n// =============================================================================\n// INTERNAL HELPERS\n// =============================================================================\n\n/**\n * Parseia string para número, detectando unidade e convertendo se necessário\n */\nfunction parseSpeedString(input: string, targetVariant: SpeedUnit): number | null {\n const trimmed = input.trim().toLowerCase();\n\n // Extrai número e possível unidade\n const match = trimmed.match(/^([+-]?[\\d.,\\s]+)\\s*(.*)$/);\n if (!match) {\n return null;\n }\n\n const [, numStr, unitStr] = match;\n\n // Normaliza número\n const numValue = parseNumber(numStr);\n if (numValue === null) {\n return null;\n }\n\n // Se tem unidade no input, converte se necessário\n const cleanUnitStr = unitStr.trim();\n if (cleanUnitStr) {\n const detectedUnit = detectUnit(cleanUnitStr);\n if (detectedUnit && detectedUnit !== targetVariant) {\n // Converte da unidade detectada para a target\n return convertSpeed(detectedUnit, targetVariant, numValue);\n }\n }\n\n return numValue;\n}\n\n/**\n * Parseia string numérica considerando formatos brasileiro e americano\n */\nfunction parseNumber(numStr: string): number | null {\n // Remove espaços\n numStr = numStr.replace(/\\s/g, \"\");\n\n const lastComma = numStr.lastIndexOf(\",\");\n const lastDot = numStr.lastIndexOf(\".\");\n const hasComma = lastComma !== -1;\n const hasDot = lastDot !== -1;\n\n if (hasComma && hasDot) {\n if (lastComma > lastDot) {\n // Brasileiro: 1.000,50\n numStr = numStr.replace(/\\./g, \"\").replace(\",\", \".\");\n } else {\n // Americano: 1,000.50\n numStr = numStr.replace(/,/g, \"\");\n }\n } else if (hasComma && !hasDot) {\n // Só vírgulas: detecta se é milhar ou decimal\n const afterComma = numStr.split(\",\").slice(1);\n const isThousandSep = afterComma.every((part) => part.length === 3);\n if (isThousandSep) {\n numStr = numStr.replace(/,/g, \"\");\n } else {\n numStr = numStr.replace(\",\", \".\");\n }\n } else if (!hasComma && hasDot) {\n // Só pontos: múltiplos pontos = milhar brasileiro\n const afterDot = numStr.split(\".\").slice(1);\n if (afterDot.length > 1) {\n numStr = numStr.replace(/\\./g, \"\");\n }\n }\n\n const value = parseFloat(numStr);\n return isNaN(value) ? null : value;\n}\n\n/**\n * Detecta unidade a partir de string (símbolo ou alias)\n */\nfunction detectUnit(unitStr: string): SpeedUnit | null {\n const normalized = unitStr.toLowerCase().trim();\n\n // Checa aliases primeiro\n if (normalized in SPEED_ALIASES) {\n return SPEED_ALIASES[normalized] as SpeedUnit;\n }\n\n // Checa símbolos e nomes\n for (const [variant, config] of Object.entries(SPEED_UNITS)) {\n if (\n config.symbol.toLowerCase() === normalized ||\n config.singular?.toLowerCase() === normalized ||\n config.plural?.toLowerCase() === normalized ||\n variant.toLowerCase() === normalized\n ) {\n return variant as SpeedUnit;\n }\n }\n\n return null;\n}\n","/**\n * Energy Role - Constants\n *\n * Fatores de conversão, símbolos e aliases para unidades de energia.\n *\n * Fontes:\n * - NIST SP 811 (2008)\n * - SI Brochure, 9th Edition (2019)\n * - CODATA 2018 (electronvolt)\n */\n\nimport type { SimpleUnitConfig, UnitAliases } from \"../../contracts\";\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport type EnergyUnit =\n // SI\n | \"gigajoule\"\n | \"megajoule\"\n | \"kilojoule\"\n | \"joule\"\n | \"millijoule\"\n // Calories\n | \"calorie\"\n | \"kilocalorie\"\n // Watt-hour\n | \"watt_hour\"\n | \"kilowatt_hour\"\n | \"megawatt_hour\"\n | \"gigawatt_hour\"\n // BTU\n | \"btu\"\n | \"therm\"\n // Scientific\n | \"electronvolt\"\n | \"kiloelectronvolt\"\n | \"megaelectronvolt\"\n | \"erg\"\n // Mechanical\n | \"foot_pound\";\n\n// =============================================================================\n// UNITS CONFIG\n// =============================================================================\n\n/**\n * Configuração de cada unidade de energia.\n *\n * Base: joule (J) - unidade SI de energia\n * 1 joule = 1 newton × 1 metro = 1 kg⋅m²/s²\n *\n * Fatores exatos:\n * - SI: prefixos são potências de 10\n * - Calorie (IT): 4.1868 J (International Table, recomendado)\n * - Watt-hour: 3600 J (1 W × 1 h)\n * - BTU (IT): 1055.05585262 J (International Table)\n * - Electronvolt: 1.602176634e-19 J (SI 2019, exato)\n * - Erg: 1e-7 J (CGS)\n */\nexport const ENERGY_UNITS: Record<EnergyUnit, SimpleUnitConfig> = {\n // SI Units (todos exatos)\n gigajoule: {\n factor: 1_000_000_000,\n symbol: \"GJ\",\n singular: \"gigajoule\",\n plural: \"gigajoules\",\n },\n megajoule: {\n factor: 1_000_000,\n symbol: \"MJ\",\n singular: \"megajoule\",\n plural: \"megajoules\",\n },\n kilojoule: {\n factor: 1_000,\n symbol: \"kJ\",\n singular: \"kilojoule\",\n plural: \"kilojoules\",\n },\n joule: {\n factor: 1,\n symbol: \"J\",\n singular: \"joule\",\n plural: \"joules\",\n },\n millijoule: {\n factor: 0.001,\n symbol: \"mJ\",\n singular: \"millijoule\",\n plural: \"millijoules\",\n },\n\n // Calories (International Table - IT)\n // 1 cal (IT) = 4.1868 J (exato por definição)\n calorie: {\n factor: 4.1868,\n symbol: \"cal\",\n singular: \"calorie\",\n plural: \"calories\",\n },\n // 1 kcal = 1000 cal = 4186.8 J (= 1 \"food Calorie\")\n kilocalorie: {\n factor: 4186.8,\n symbol: \"kcal\",\n singular: \"kilocalorie\",\n plural: \"kilocalories\",\n },\n\n // Watt-hour (exatos)\n // 1 Wh = 1 W × 3600 s = 3600 J\n watt_hour: {\n factor: 3600,\n symbol: \"Wh\",\n singular: \"watt-hour\",\n plural: \"watt-hours\",\n },\n kilowatt_hour: {\n factor: 3_600_000,\n symbol: \"kWh\",\n singular: \"kilowatt-hour\",\n plural: \"kilowatt-hours\",\n },\n megawatt_hour: {\n factor: 3_600_000_000,\n symbol: \"MWh\",\n singular: \"megawatt-hour\",\n plural: \"megawatt-hours\",\n },\n gigawatt_hour: {\n factor: 3_600_000_000_000,\n symbol: \"GWh\",\n singular: \"gigawatt-hour\",\n plural: \"gigawatt-hours\",\n },\n\n // BTU (International Table)\n // 1 BTU (IT) = 1055.05585262 J (definição)\n btu: {\n factor: 1055.05585262,\n symbol: \"BTU\",\n singular: \"BTU\",\n plural: \"BTUs\",\n },\n // 1 therm = 100,000 BTU (IT)\n therm: {\n factor: 105505585.262,\n symbol: \"thm\",\n singular: \"therm\",\n plural: \"therms\",\n },\n\n // Scientific\n // 1 eV = 1.602176634e-19 J (SI 2019, exato por definição)\n electronvolt: {\n factor: 1.602176634e-19,\n symbol: \"eV\",\n singular: \"electronvolt\",\n plural: \"electronvolts\",\n },\n kiloelectronvolt: {\n factor: 1.602176634e-16,\n symbol: \"keV\",\n singular: \"kiloelectronvolt\",\n plural: \"kiloelectronvolts\",\n },\n megaelectronvolt: {\n factor: 1.602176634e-13,\n symbol: \"MeV\",\n singular: \"megaelectronvolt\",\n plural: \"megaelectronvolts\",\n },\n // 1 erg = 1e-7 J (CGS, exato)\n erg: {\n factor: 1e-7,\n symbol: \"erg\",\n singular: \"erg\",\n plural: \"ergs\",\n },\n\n // Mechanical\n // 1 ft⋅lbf = 1.3558179483314004 J (derivado de foot e pound-force)\n foot_pound: {\n factor: 1.3558179483314004,\n symbol: \"ft⋅lbf\",\n singular: \"foot-pound\",\n plural: \"foot-pounds\",\n },\n};\n\n// =============================================================================\n// ALIASES\n// =============================================================================\n\n/**\n * Aliases para reconhecimento de unidades no cast\n */\nexport const ENERGY_ALIASES: UnitAliases = {\n // gigajoule\n gj: \"gigajoule\",\n // megajoule\n mj: \"megajoule\",\n // kilojoule\n kj: \"kilojoule\",\n // joule\n j: \"joule\",\n // calorie\n cal: \"calorie\",\n // kilocalorie\n kcal: \"kilocalorie\",\n Cal: \"kilocalorie\",\n // watt_hour\n wh: \"watt_hour\",\n // kilowatt_hour\n kwh: \"kilowatt_hour\",\n // megawatt_hour\n mwh: \"megawatt_hour\",\n // gigawatt_hour\n gwh: \"gigawatt_hour\",\n // btu\n btu: \"btu\",\n // therm\n thm: \"therm\",\n // electronvolt\n ev: \"electronvolt\",\n // kiloelectronvolt\n kev: \"kiloelectronvolt\",\n // megaelectronvolt\n mev: \"megaelectronvolt\",\n // erg\n erg: \"erg\",\n // foot_pound\n \"ft-lb\": \"foot_pound\",\n \"ft-lbf\": \"foot_pound\",\n};\n\n// =============================================================================\n// HELPERS\n// =============================================================================\n\n/** Lista de todas as unidades */\nexport const ENERGY_UNIT_LIST = Object.keys(ENERGY_UNITS) as EnergyUnit[];\n\n/** Fatores de conversão (para compatibilidade) */\nexport const ENERGY_FACTORS: Record<EnergyUnit, number> = Object.fromEntries(\n Object.entries(ENERGY_UNITS).map(([unit, config]) => [\n unit,\n config.factor ?? 1,\n ]),\n) as Record<EnergyUnit, number>;\n","/**\n * Energy Role - Convert Pillar\n *\n * Conversão entre unidades de energia usando arquitetura hub-and-spoke.\n * Base: joule (J)\n *\n * @example\n * import { convertEnergy, toBaseEnergy, fromBaseEnergy } from '@attrx/role-morphic/energy/convert';\n *\n * convertEnergy('kilocalorie', 'kilojoule', 1); // 4.1868\n * toBaseEnergy('kilowatt_hour', 1); // 3600000\n * fromBaseEnergy('btu', 1055.06); // ~1\n */\n\nimport { ENERGY_UNITS, type EnergyUnit } from \"./constants\";\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport type Result<T> =\n | { ok: true; value: T }\n | { ok: false; error: string };\n\n// =============================================================================\n// CONSTANTS\n// =============================================================================\n\n/** Variante base para conversões */\nexport const ENERGY_BASE: EnergyUnit = \"joule\";\n\n// =============================================================================\n// CONVERT\n// =============================================================================\n\n/**\n * Converte valor para a unidade base (joule)\n *\n * @param variant - Unidade de origem\n * @param value - Valor a converter\n * @returns Valor em joule\n *\n * @example\n * toBaseEnergy('kilowatt_hour', 1); // 3600000\n * toBaseEnergy('kilocalorie', 1); // 4186.8\n */\nexport function toBaseEnergy(variant: EnergyUnit, value: number): number {\n const unit = ENERGY_UNITS[variant];\n\n if (!unit) {\n throw new Error(`Unknown energy variant: ${variant}`);\n }\n\n return value * (unit.factor ?? 1);\n}\n\n/**\n * Converte valor da unidade base (joule) para outra unidade\n *\n * @param variant - Unidade de destino\n * @param baseValue - Valor em joule\n * @returns Valor na unidade de destino\n *\n * @example\n * fromBaseEnergy('kilowatt_hour', 3600000); // 1\n * fromBaseEnergy('kilocalorie', 4186.8); // 1\n */\nexport function fromBaseEnergy(variant: EnergyUnit, baseValue: number): number {\n const unit = ENERGY_UNITS[variant];\n\n if (!unit) {\n throw new Error(`Unknown energy variant: ${variant}`);\n }\n\n return baseValue / (unit.factor ?? 1);\n}\n\n/**\n * Converte entre duas unidades de energia\n *\n * @param from - Unidade de origem\n * @param to - Unidade de destino\n * @param value - Valor a converter\n * @returns Valor convertido\n *\n * @example\n * convertEnergy('kilocalorie', 'kilojoule', 1); // 4.1868\n * convertEnergy('kilowatt_hour', 'megajoule', 1); // 3.6\n * convertEnergy('btu', 'joule', 1); // 1055.056...\n */\nexport function convertEnergy(\n from: EnergyUnit,\n to: EnergyUnit,\n value: number\n): number {\n // Otimização: mesma unidade\n if (from === to) {\n return value;\n }\n\n // Hub-and-spoke: from → base → to\n const baseValue = toBaseEnergy(from, value);\n return fromBaseEnergy(to, baseValue);\n}\n\n/**\n * Versão safe de convertEnergy que retorna Result\n *\n * @example\n * tryConvertEnergy('kilocalorie', 'kilojoule', 1);\n * // { ok: true, value: 4.1868 }\n *\n * tryConvertEnergy('invalid', 'joule', 1);\n * // { ok: false, error: 'Unknown energy variant: invalid' }\n */\nexport function tryConvertEnergy(\n from: EnergyUnit,\n to: EnergyUnit,\n value: number\n): Result<number> {\n try {\n const result = convertEnergy(from, to, value);\n return { ok: true, value: result };\n } catch (err) {\n return { ok: false, error: String(err) };\n }\n}\n\n/**\n * Verifica se uma variante existe\n */\nexport function hasEnergyVariant(variant: string): variant is EnergyUnit {\n return variant in ENERGY_UNITS;\n}\n\n/**\n * Lista todas as variantes disponíveis\n */\nexport function getEnergyVariants(): EnergyUnit[] {\n return Object.keys(ENERGY_UNITS) as EnergyUnit[];\n}\n","/**\n * Energy Role - Cast Pillar\n *\n * Normaliza input sujo para número tipado.\n * Detecta unidades em strings e converte se necessário.\n *\n * @example\n * import { castEnergy, castEnergyStrict, detectEnergyUnit } from '@attrx/role-morphic/energy/cast';\n *\n * castEnergy('100 kWh', 'kilowatt_hour'); // 100\n * castEnergy('100 BTU', 'joule'); // 105505.59 (converte)\n * castEnergyStrict('100 kWh'); // 100 (não converte)\n * detectEnergyUnit('100 kilocalories'); // 'kilocalorie'\n */\n\nimport { ENERGY_UNITS, ENERGY_ALIASES, type EnergyUnit } from \"./constants\";\nimport { convertEnergy } from \"./convert\";\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport type Result<T> =\n | { ok: true; value: T }\n | { ok: false; error: string };\n\n// =============================================================================\n// CAST\n// =============================================================================\n\n/**\n * Faz cast de input para número, detectando e convertendo unidade se presente\n *\n * @param input - Valor de entrada (number, string, etc)\n * @param targetVariant - Unidade alvo para conversão\n * @returns Número ou null se não puder converter\n *\n * @example\n * castEnergy(100, 'joule'); // 100\n * castEnergy('100', 'joule'); // 100\n * castEnergy('100 kWh', 'kilowatt_hour'); // 100\n * castEnergy('100 BTU', 'joule'); // 105505.59 (converte)\n * castEnergy('1 kcal', 'kilojoule'); // 4.1868 (converte)\n * castEnergy('invalid', 'joule'); // null\n */\nexport function castEnergy(\n input: unknown,\n targetVariant: EnergyUnit = \"joule\"\n): number | null {\n // Já é número\n if (typeof input === \"number\") {\n return Number.isFinite(input) ? input : null;\n }\n\n // String\n if (typeof input === \"string\") {\n return parseEnergyString(input, targetVariant);\n }\n\n return null;\n}\n\n/**\n * Faz cast sem conversão de unidade (só parseia o valor literal)\n *\n * @param input - Valor de entrada\n * @returns Número ou null\n *\n * @example\n * castEnergyStrict('100 kWh'); // 100 (ignora unidade, não converte)\n * castEnergyStrict('100'); // 100\n * castEnergyStrict(100); // 100\n */\nexport function castEnergyStrict(input: unknown): number | null {\n // Já é número\n if (typeof input === \"number\") {\n return Number.isFinite(input) ? input : null;\n }\n\n // String\n if (typeof input === \"string\") {\n const numValue = parseNumber(input);\n return numValue;\n }\n\n return null;\n}\n\n/**\n * Versão safe de castEnergy que retorna Result\n */\nexport function tryCastEnergy(\n input: unknown,\n targetVariant: EnergyUnit = \"joule\"\n): Result<number> {\n const result = castEnergy(input, targetVariant);\n if (result === null) {\n return {\n ok: false,\n error: `Cannot cast \"${String(input)}\" to energy:${targetVariant}`,\n };\n }\n return { ok: true, value: result };\n}\n\n// =============================================================================\n// DETECTION\n// =============================================================================\n\n/**\n * Detecta unidade de energia a partir de uma string\n *\n * @param input - String com possível unidade\n * @returns Unidade detectada ou null\n *\n * @example\n * detectEnergyUnit('100 kWh'); // 'kilowatt_hour'\n * detectEnergyUnit('100 kilocalories'); // 'kilocalorie'\n * detectEnergyUnit('100 BTU'); // 'btu'\n * detectEnergyUnit('100'); // null\n */\nexport function detectEnergyUnit(input: string): EnergyUnit | null {\n const trimmed = input.trim().toLowerCase();\n const match = trimmed.match(/^[+-]?[\\d.,\\s]+\\s*(.*)$/);\n\n if (!match || !match[1]) {\n return null;\n }\n\n const unitStr = match[1].trim();\n return detectUnit(unitStr);\n}\n\n// =============================================================================\n// INTERNAL HELPERS\n// =============================================================================\n\n/**\n * Parseia string para número, detectando unidade e convertendo se necessário\n */\nfunction parseEnergyString(input: string, targetVariant: EnergyUnit): number | null {\n const trimmed = input.trim().toLowerCase();\n\n // Extrai número e possível unidade\n const match = trimmed.match(/^([+-]?[\\d.,\\s]+)\\s*(.*)$/);\n if (!match) {\n return null;\n }\n\n const [, numStr, unitStr] = match;\n\n // Normaliza número\n const numValue = parseNumber(numStr);\n if (numValue === null) {\n return null;\n }\n\n // Se tem unidade no input, converte se necessário\n const cleanUnitStr = unitStr.trim();\n if (cleanUnitStr) {\n const detectedUnit = detectUnit(cleanUnitStr);\n if (detectedUnit && detectedUnit !== targetVariant) {\n // Converte da unidade detectada para a target\n return convertEnergy(detectedUnit, targetVariant, numValue);\n }\n }\n\n return numValue;\n}\n\n/**\n * Parseia string numérica considerando formatos brasileiro e americano\n */\nfunction parseNumber(numStr: string): number | null {\n // Remove espaços\n numStr = numStr.replace(/\\s/g, \"\");\n\n const lastComma = numStr.lastIndexOf(\",\");\n const lastDot = numStr.lastIndexOf(\".\");\n const hasComma = lastComma !== -1;\n const hasDot = lastDot !== -1;\n\n if (hasComma && hasDot) {\n if (lastComma > lastDot) {\n // Brasileiro: 1.000,50\n numStr = numStr.replace(/\\./g, \"\").replace(\",\", \".\");\n } else {\n // Americano: 1,000.50\n numStr = numStr.replace(/,/g, \"\");\n }\n } else if (hasComma && !hasDot) {\n // Só vírgulas: detecta se é milhar ou decimal\n const afterComma = numStr.split(\",\").slice(1);\n const isThousandSep = afterComma.every((part) => part.length === 3);\n if (isThousandSep) {\n numStr = numStr.replace(/,/g, \"\");\n } else {\n numStr = numStr.replace(\",\", \".\");\n }\n } else if (!hasComma && hasDot) {\n // Só pontos: múltiplos pontos = milhar brasileiro\n const afterDot = numStr.split(\".\").slice(1);\n if (afterDot.length > 1) {\n numStr = numStr.replace(/\\./g, \"\");\n }\n }\n\n const value = parseFloat(numStr);\n return isNaN(value) ? null : value;\n}\n\n/**\n * Detecta unidade a partir de string (símbolo ou alias)\n */\nfunction detectUnit(unitStr: string): EnergyUnit | null {\n const normalized = unitStr.toLowerCase().trim();\n\n // Checa aliases primeiro\n if (normalized in ENERGY_ALIASES) {\n return ENERGY_ALIASES[normalized] as EnergyUnit;\n }\n\n // Checa símbolos e nomes\n for (const [variant, config] of Object.entries(ENERGY_UNITS)) {\n if (\n config.symbol.toLowerCase() === normalized ||\n config.singular?.toLowerCase() === normalized ||\n config.plural?.toLowerCase() === normalized ||\n variant.toLowerCase() === normalized\n ) {\n return variant as EnergyUnit;\n }\n }\n\n return null;\n}\n","/**\n * Power Role - Constants\n *\n * Fatores de conversão, símbolos e aliases para unidades de potência.\n *\n * Fontes:\n * - NIST SP 811 (2008)\n * - SI Brochure, 9th Edition (2019)\n */\n\nimport type { SimpleUnitConfig, UnitAliases } from \"../../contracts\";\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport type PowerUnit =\n // SI\n | \"gigawatt\"\n | \"megawatt\"\n | \"kilowatt\"\n | \"watt\"\n | \"milliwatt\"\n | \"microwatt\"\n // Horsepower\n | \"horsepower_mechanical\"\n | \"horsepower_metric\"\n | \"horsepower_electric\"\n | \"horsepower_boiler\"\n // BTU-based\n | \"btu_per_hour\"\n | \"btu_per_second\"\n // Other\n | \"ton_of_refrigeration\"\n | \"foot_pound_per_second\"\n | \"calorie_per_second\"\n | \"kilocalorie_per_hour\";\n\n// =============================================================================\n// UNITS CONFIG\n// =============================================================================\n\n/**\n * Configuração de cada unidade de potência.\n *\n * Base: watt (W) - unidade SI de potência\n * 1 watt = 1 joule por segundo = 1 kg⋅m²/s³\n *\n * Cavalos-vapor (existem várias definições):\n * - Mechanical (imperial): 550 ft⋅lbf/s = 745.69987158227 W\n * - Metric (PS, CV, pk): 75 kgf⋅m/s = 735.49875 W (exato)\n * - Electrical: 746 W (exato por definição)\n * - Boiler: 9809.5 W (33,475 BTU/h)\n */\nexport const POWER_UNITS: Record<PowerUnit, SimpleUnitConfig> = {\n // SI Units (todos exatos)\n gigawatt: {\n factor: 1_000_000_000,\n symbol: \"GW\",\n singular: \"gigawatt\",\n plural: \"gigawatts\",\n },\n megawatt: {\n factor: 1_000_000,\n symbol: \"MW\",\n singular: \"megawatt\",\n plural: \"megawatts\",\n },\n kilowatt: {\n factor: 1_000,\n symbol: \"kW\",\n singular: \"kilowatt\",\n plural: \"kilowatts\",\n },\n watt: {\n factor: 1,\n symbol: \"W\",\n singular: \"watt\",\n plural: \"watts\",\n },\n milliwatt: {\n factor: 0.001,\n symbol: \"mW\",\n singular: \"milliwatt\",\n plural: \"milliwatts\",\n },\n microwatt: {\n factor: 0.000001,\n symbol: \"μW\",\n singular: \"microwatt\",\n plural: \"microwatts\",\n },\n\n // Horsepower variants\n // Mechanical (imperial): 550 ft⋅lbf/s\n // = 550 × 0.3048 m × 4.4482216152605 N / s = 745.69987158227 W\n horsepower_mechanical: {\n factor: 745.69987158227,\n symbol: \"hp\",\n singular: \"horsepower\",\n plural: \"horsepower\",\n },\n // Metric (PS, CV, pk): 75 kgf⋅m/s = 75 × 9.80665 W = 735.49875 W (exato)\n horsepower_metric: {\n factor: 735.49875,\n symbol: \"PS\",\n singular: \"metric horsepower\",\n plural: \"metric horsepower\",\n },\n // Electrical: 746 W (exato por definição)\n horsepower_electric: {\n factor: 746,\n symbol: \"hp(E)\",\n singular: \"electric horsepower\",\n plural: \"electric horsepower\",\n },\n // Boiler: 33,475 BTU/h = 9809.5 W\n horsepower_boiler: {\n factor: 9809.5,\n symbol: \"hp(S)\",\n singular: \"boiler horsepower\",\n plural: \"boiler horsepower\",\n },\n\n // BTU-based\n // 1 BTU/h = 1055.05585262 J / 3600 s = 0.29307107017222 W\n btu_per_hour: {\n factor: 0.29307107017222,\n symbol: \"BTU/h\",\n singular: \"BTU per hour\",\n plural: \"BTUs per hour\",\n },\n // 1 BTU/s = 1055.05585262 W\n btu_per_second: {\n factor: 1055.05585262,\n symbol: \"BTU/s\",\n singular: \"BTU per second\",\n plural: \"BTUs per second\",\n },\n\n // Other\n // 1 ton of refrigeration = 12000 BTU/h = 3516.8528420667 W\n ton_of_refrigeration: {\n factor: 3516.8528420667,\n symbol: \"TR\",\n singular: \"ton of refrigeration\",\n plural: \"tons of refrigeration\",\n },\n // 1 ft⋅lbf/s = 1.3558179483314004 W\n foot_pound_per_second: {\n factor: 1.3558179483314004,\n symbol: \"ft⋅lbf/s\",\n singular: \"foot-pound per second\",\n plural: \"foot-pounds per second\",\n },\n // 1 cal/s = 4.1868 W\n calorie_per_second: {\n factor: 4.1868,\n symbol: \"cal/s\",\n singular: \"calorie per second\",\n plural: \"calories per second\",\n },\n // 1 kcal/h = 4186.8 / 3600 = 1.163 W\n kilocalorie_per_hour: {\n factor: 1.163,\n symbol: \"kcal/h\",\n singular: \"kilocalorie per hour\",\n plural: \"kilocalories per hour\",\n },\n};\n\n// =============================================================================\n// ALIASES\n// =============================================================================\n\n/**\n * Aliases para reconhecimento de unidades no cast\n */\nexport const POWER_ALIASES: UnitAliases = {\n // gigawatt\n gw: \"gigawatt\",\n // megawatt\n mw: \"megawatt\",\n // kilowatt\n kw: \"kilowatt\",\n // watt\n w: \"watt\",\n // microwatt\n \"μw\": \"microwatt\",\n uw: \"microwatt\",\n // horsepower_mechanical\n hp: \"horsepower_mechanical\",\n // horsepower_metric\n ps: \"horsepower_metric\",\n cv: \"horsepower_metric\",\n // horsepower_electric\n \"hp(e)\": \"horsepower_electric\",\n // horsepower_boiler\n \"hp(s)\": \"horsepower_boiler\",\n bhp: \"horsepower_boiler\",\n // btu_per_hour\n \"btu/h\": \"btu_per_hour\",\n \"btu/hr\": \"btu_per_hour\",\n // btu_per_second\n \"btu/s\": \"btu_per_second\",\n // ton_of_refrigeration\n tr: \"ton_of_refrigeration\",\n rt: \"ton_of_refrigeration\",\n // foot_pound_per_second\n \"ft-lb/s\": \"foot_pound_per_second\",\n \"ft-lbf/s\": \"foot_pound_per_second\",\n // calorie_per_second\n \"cal/s\": \"calorie_per_second\",\n // kilocalorie_per_hour\n \"kcal/h\": \"kilocalorie_per_hour\",\n \"kcal/hr\": \"kilocalorie_per_hour\",\n};\n\n// =============================================================================\n// HELPERS\n// =============================================================================\n\n/** Lista de todas as unidades */\nexport const POWER_UNIT_LIST = Object.keys(POWER_UNITS) as PowerUnit[];\n\n/** Fatores de conversão (para compatibilidade) */\nexport const POWER_FACTORS: Record<PowerUnit, number> = Object.fromEntries(\n Object.entries(POWER_UNITS).map(([unit, config]) => [\n unit,\n config.factor ?? 1,\n ]),\n) as Record<PowerUnit, number>;\n","/**\n * Power Role - Convert Pillar\n *\n * Conversão entre unidades de potência usando hub-and-spoke (via watt).\n *\n * @example\n * import { convertPower, toBasePower, fromBasePower } from '@attrx/role-morphic/power/convert';\n *\n * convertPower('horsepower_mechanical', 'kilowatt', 1); // 0.7457\n * toBasePower('kilowatt', 2.5); // 2500 (watts)\n * fromBasePower('kilowatt', 2500); // 2.5\n */\n\nimport { POWER_UNITS, type PowerUnit } from \"./constants\";\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport type Result<T> = { ok: true; value: T } | { ok: false; error: string };\n\n// =============================================================================\n// CONSTANTS\n// =============================================================================\n\n/** Unidade base para conversões (hub) */\nexport const POWER_BASE: PowerUnit = \"watt\";\n\n// =============================================================================\n// CORE CONVERSION\n// =============================================================================\n\n/**\n * Converte valor para a unidade base (watt)\n *\n * @param variant - Unidade de origem\n * @param value - Valor a converter\n * @returns Valor em watts\n *\n * @example\n * toBasePower('kilowatt', 2.5); // 2500\n * toBasePower('horsepower_mechanical', 1); // 745.7\n */\nexport function toBasePower(variant: PowerUnit, value: number): number {\n const config = POWER_UNITS[variant];\n if (!config) {\n throw new Error(`Unknown power unit: ${variant}`);\n }\n return value * (config.factor ?? 1);\n}\n\n/**\n * Converte valor da unidade base (watt) para outra unidade\n *\n * @param variant - Unidade de destino\n * @param baseValue - Valor em watts\n * @returns Valor na unidade de destino\n *\n * @example\n * fromBasePower('kilowatt', 2500); // 2.5\n * fromBasePower('watt', 100); // 100\n */\nexport function fromBasePower(variant: PowerUnit, baseValue: number): number {\n const config = POWER_UNITS[variant];\n if (!config) {\n throw new Error(`Unknown power unit: ${variant}`);\n }\n return baseValue / (config.factor ?? 1);\n}\n\n/**\n * Converte entre duas unidades de potência\n *\n * @param from - Unidade de origem\n * @param to - Unidade de destino\n * @param value - Valor a converter\n * @returns Valor convertido\n *\n * @example\n * convertPower('horsepower_mechanical', 'kilowatt', 1); // 0.7457\n * convertPower('kilowatt', 'watt', 2.5); // 2500\n */\nexport function convertPower(\n from: PowerUnit,\n to: PowerUnit,\n value: number,\n): number {\n if (from === to) {\n return value;\n }\n const baseValue = toBasePower(from, value);\n return fromBasePower(to, baseValue);\n}\n\n/**\n * Versão safe de convertPower que retorna Result\n *\n * @example\n * tryConvertPower('kilowatt', 'watt', 1); // { ok: true, value: 1000 }\n * tryConvertPower('invalid', 'watt', 1); // { ok: false, error: '...' }\n */\nexport function tryConvertPower(\n from: PowerUnit,\n to: PowerUnit,\n value: number,\n): Result<number> {\n try {\n return { ok: true, value: convertPower(from, to, value) };\n } catch (e) {\n return { ok: false, error: (e as Error).message };\n }\n}\n\n// =============================================================================\n// HELPERS\n// =============================================================================\n\n/**\n * Verifica se uma variante existe\n *\n * @example\n * hasPowerVariant('kilowatt'); // true\n * hasPowerVariant('invalid'); // false\n */\nexport function hasPowerVariant(variant: string): variant is PowerUnit {\n return variant in POWER_UNITS;\n}\n\n/**\n * Retorna lista de todas as variantes disponíveis\n *\n * @example\n * getPowerVariants(); // ['gigawatt', 'megawatt', 'kilowatt', ...]\n */\nexport function getPowerVariants(): PowerUnit[] {\n return Object.keys(POWER_UNITS) as PowerUnit[];\n}\n","/**\n * Power Role - Cast Pillar\n *\n * Normaliza input sujo para número, com detecção automática de unidade.\n *\n * @example\n * import { castPower, castPowerStrict, detectPowerUnit } from '@attrx/role-morphic/power/cast';\n *\n * castPower('100 kW'); // 100000 (converted to watts)\n * castPower('100 kW', 'kilowatt'); // 100 (kept as kilowatts)\n * castPowerStrict('100'); // 100 (no conversion)\n * detectPowerUnit('100 hp'); // 'horsepower_mechanical'\n */\n\nimport { POWER_UNITS, POWER_ALIASES, type PowerUnit } from \"./constants\";\nimport { convertPower, POWER_BASE } from \"./convert\";\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport type Result<T> = { ok: true; value: T } | { ok: false; error: string };\n\n// =============================================================================\n// CAST\n// =============================================================================\n\n/**\n * Faz cast de input para número, com conversão opcional para unidade alvo\n *\n * @param input - Valor de entrada (number, string, etc)\n * @param targetVariant - Unidade alvo (default: watt)\n * @returns Número ou null se não puder converter\n *\n * @example\n * castPower('100 kW'); // 100000 (watts)\n * castPower('100 kW', 'kilowatt'); // 100\n * castPower('100'); // 100\n * castPower(100); // 100\n * castPower('invalid'); // null\n */\nexport function castPower(\n input: unknown,\n targetVariant: PowerUnit = POWER_BASE,\n): number | null {\n // Already a number\n if (typeof input === \"number\") {\n return Number.isFinite(input) ? input : null;\n }\n\n // String parsing\n if (typeof input === \"string\") {\n const parsed = parsePowerString(input);\n if (parsed === null) {\n return null;\n }\n\n // If unit was detected and differs from target, convert\n if (parsed.unit && parsed.unit !== targetVariant) {\n return convertPower(parsed.unit, targetVariant, parsed.value);\n }\n\n return parsed.value;\n }\n\n return null;\n}\n\n/**\n * Faz cast sem conversão (apenas parseia o número)\n *\n * @param input - Valor de entrada\n * @returns Número ou null\n *\n * @example\n * castPowerStrict('100 kW'); // 100 (ignora a unidade)\n * castPowerStrict('100'); // 100\n */\nexport function castPowerStrict(input: unknown): number | null {\n if (typeof input === \"number\") {\n return Number.isFinite(input) ? input : null;\n }\n\n if (typeof input === \"string\") {\n const parsed = parsePowerString(input);\n return parsed?.value ?? null;\n }\n\n return null;\n}\n\n/**\n * Versão safe de castPower que retorna Result\n */\nexport function tryCastPower(\n input: unknown,\n targetVariant: PowerUnit = POWER_BASE,\n): Result<number> {\n const result = castPower(input, targetVariant);\n if (result === null) {\n return { ok: false, error: `Cannot cast \"${String(input)}\" to power` };\n }\n return { ok: true, value: result };\n}\n\n// =============================================================================\n// DETECT UNIT\n// =============================================================================\n\n/**\n * Detecta a unidade de potência de uma string\n *\n * @param input - String com valor e unidade\n * @returns Unidade detectada ou null\n *\n * @example\n * detectPowerUnit('100 kW'); // 'kilowatt'\n * detectPowerUnit('100 hp'); // 'horsepower_mechanical'\n * detectPowerUnit('100'); // null\n */\nexport function detectPowerUnit(input: string): PowerUnit | null {\n const trimmed = input.trim().toLowerCase();\n\n // Extract unit part (after the number)\n const match = trimmed.match(/^[+-]?[\\d.,\\s]+\\s*(.*)$/);\n if (!match || !match[1]) {\n return null;\n }\n\n const unitStr = match[1].trim();\n if (!unitStr) {\n return null;\n }\n\n // Check direct unit names\n if (unitStr in POWER_UNITS) {\n return unitStr as PowerUnit;\n }\n\n // Check aliases\n if (unitStr in POWER_ALIASES) {\n return POWER_ALIASES[unitStr] as PowerUnit;\n }\n\n // Check symbols (case-sensitive for some)\n for (const [unit, config] of Object.entries(POWER_UNITS)) {\n if (config.symbol.toLowerCase() === unitStr) {\n return unit as PowerUnit;\n }\n }\n\n return null;\n}\n\n// =============================================================================\n// INTERNAL HELPERS\n// =============================================================================\n\ninterface ParsedPower {\n value: number;\n unit: PowerUnit | null;\n}\n\n/**\n * Parseia string de potência extraindo valor e unidade\n */\nfunction parsePowerString(input: string): ParsedPower | null {\n const trimmed = input.trim();\n if (!trimmed) {\n return null;\n }\n\n // Try to extract number and unit\n const match = trimmed.match(/^([+-]?[\\d.,\\s]+)\\s*(.*)$/);\n if (!match) {\n return null;\n }\n\n const numStr = match[1].replace(/\\s/g, \"\").replace(\",\", \".\");\n const value = parseFloat(numStr);\n\n if (isNaN(value) || !Number.isFinite(value)) {\n return null;\n }\n\n const unitStr = match[2]?.trim().toLowerCase() || \"\";\n let unit: PowerUnit | null = null;\n\n if (unitStr) {\n // Check aliases first\n if (unitStr in POWER_ALIASES) {\n unit = POWER_ALIASES[unitStr] as PowerUnit;\n }\n // Check direct unit names\n else if (unitStr in POWER_UNITS) {\n unit = unitStr as PowerUnit;\n }\n // Check symbols\n else {\n for (const [u, config] of Object.entries(POWER_UNITS)) {\n if (config.symbol.toLowerCase() === unitStr) {\n unit = u as PowerUnit;\n break;\n }\n }\n }\n }\n\n return { value, unit };\n}\n","/**\n * Pressure Role - Constants\n *\n * Fatores de conversão, símbolos e aliases para unidades de pressão.\n *\n * Fontes:\n * - SI Brochure, 9th Edition (2019)\n * - NIST SP 811\n * - 10th CGPM (1954) - definição da atmosfera padrão\n */\n\nimport type { SimpleUnitConfig, UnitAliases } from \"../../contracts\";\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport type PressureUnit =\n // SI\n | \"megapascal\"\n | \"kilopascal\"\n | \"hectopascal\"\n | \"pascal\"\n // Bar\n | \"bar\"\n | \"millibar\"\n // Atmosphere\n | \"atmosphere\"\n // Mercury\n | \"torr\"\n | \"mmhg\"\n | \"inhg\"\n // Imperial\n | \"psi\"\n | \"ksi\"\n // Water column\n | \"cmh2o\"\n | \"inh2o\";\n\n// =============================================================================\n// UNITS CONFIG\n// =============================================================================\n\n/**\n * Configuração de cada unidade de pressão.\n *\n * Base: pascal (Pa) = 1 N/m² = 1 kg/(m·s²)\n *\n * Relações importantes:\n * - 1 atm = 101325 Pa (exato, CGPM 1954)\n * - 1 bar = 100000 Pa (exato por definição)\n * - 1 Torr = 101325/760 Pa (exato)\n * - 1 psi = 6894.757293168 Pa (derivado de lb/in²)\n */\nexport const PRESSURE_UNITS: Record<PressureUnit, SimpleUnitConfig> = {\n // SI Units (todos exatos)\n megapascal: {\n factor: 1e6,\n symbol: \"MPa\",\n singular: \"megapascal\",\n plural: \"megapascals\",\n },\n kilopascal: {\n factor: 1000,\n symbol: \"kPa\",\n singular: \"kilopascal\",\n plural: \"kilopascals\",\n },\n hectopascal: {\n factor: 100,\n symbol: \"hPa\",\n singular: \"hectopascal\",\n plural: \"hectopascals\",\n },\n pascal: {\n factor: 1,\n symbol: \"Pa\",\n singular: \"pascal\",\n plural: \"pascals\",\n },\n\n // Bar (exatos por definição)\n bar: {\n factor: 100000,\n symbol: \"bar\",\n singular: \"bar\",\n plural: \"bar\",\n },\n millibar: {\n factor: 100, // = 1 hPa\n symbol: \"mbar\",\n singular: \"millibar\",\n plural: \"millibar\",\n },\n\n // Atmosphere (exato, CGPM 1954)\n atmosphere: {\n factor: 101325,\n symbol: \"atm\",\n singular: \"atmosphere\",\n plural: \"atmospheres\",\n },\n\n // Mercury column\n torr: {\n factor: 101325 / 760, // ≈ 133.322368421\n symbol: \"Torr\",\n singular: \"torr\",\n plural: \"torr\",\n },\n mmhg: {\n factor: 133.322387415, // Convenção NIST\n symbol: \"mmHg\",\n singular: \"millimeter of mercury\",\n plural: \"millimeters of mercury\",\n },\n inhg: {\n factor: 3386.389, // Polegadas de mercúrio\n symbol: \"inHg\",\n singular: \"inch of mercury\",\n plural: \"inches of mercury\",\n },\n\n // Imperial (derivados de lb/in²)\n psi: {\n factor: 6894.757293168, // 1 lbf/in²\n symbol: \"psi\",\n singular: \"pound per square inch\",\n plural: \"pounds per square inch\",\n },\n ksi: {\n factor: 6894757.293168, // 1000 psi\n symbol: \"ksi\",\n singular: \"kilopound per square inch\",\n plural: \"kilopounds per square inch\",\n },\n\n // Water column\n cmh2o: {\n factor: 98.0665, // cm de água a 4°C\n symbol: \"cmH₂O\",\n singular: \"centimeter of water\",\n plural: \"centimeters of water\",\n },\n inh2o: {\n factor: 249.08891, // polegadas de água\n symbol: \"inH₂O\",\n singular: \"inch of water\",\n plural: \"inches of water\",\n },\n};\n\n// =============================================================================\n// ALIASES\n// =============================================================================\n\n/**\n * Aliases para reconhecimento de unidades no cast\n */\nexport const PRESSURE_ALIASES: UnitAliases = {\n // megapascal\n mpa: \"megapascal\",\n // kilopascal\n kpa: \"kilopascal\",\n // hectopascal\n hpa: \"hectopascal\",\n // pascal\n pa: \"pascal\",\n // bar\n bar: \"bar\",\n // millibar\n mbar: \"millibar\",\n mb: \"millibar\",\n // atmosphere\n atm: \"atmosphere\",\n // torr\n torr: \"torr\",\n // mmhg\n mmhg: \"mmhg\",\n // inhg\n inhg: \"inhg\",\n // psi\n psi: \"psi\",\n // ksi\n ksi: \"ksi\",\n // cmh2o\n cmh2o: \"cmh2o\",\n // inh2o\n inh2o: \"inh2o\",\n};\n\n// =============================================================================\n// HELPERS\n// =============================================================================\n\n/** Lista de todas as unidades */\nexport const PRESSURE_UNIT_LIST = Object.keys(PRESSURE_UNITS) as PressureUnit[];\n\n/** Fatores de conversão (para compatibilidade) */\nexport const PRESSURE_FACTORS: Record<PressureUnit, number> =\n Object.fromEntries(\n Object.entries(PRESSURE_UNITS).map(([unit, config]) => [\n unit,\n config.factor ?? 1,\n ]),\n ) as Record<PressureUnit, number>;\n","/**\n * Pressure Role - Convert Pillar\n *\n * Conversão entre unidades de pressão usando hub-and-spoke (via pascal).\n *\n * @example\n * import { convertPressure, toBasePressure, fromBasePressure } from '@attrx/role-morphic/pressure/convert';\n *\n * convertPressure('bar', 'pascal', 1); // 100000\n * toBasePressure('bar', 2.5); // 250000 (pascals)\n * fromBasePressure('bar', 250000); // 2.5\n */\n\nimport { PRESSURE_UNITS, type PressureUnit } from \"./constants\";\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport type Result<T> = { ok: true; value: T } | { ok: false; error: string };\n\n// =============================================================================\n// CONSTANTS\n// =============================================================================\n\n/** Unidade base para conversões (hub) */\nexport const PRESSURE_BASE: PressureUnit = \"pascal\";\n\n// =============================================================================\n// CORE CONVERSION\n// =============================================================================\n\n/**\n * Converte valor para a unidade base (pascal)\n *\n * @param variant - Unidade de origem\n * @param value - Valor a converter\n * @returns Valor em pascals\n *\n * @example\n * toBasePressure('bar', 2.5); // 250000\n * toBasePressure('atmosphere', 1); // 101325\n */\nexport function toBasePressure(variant: PressureUnit, value: number): number {\n const config = PRESSURE_UNITS[variant];\n if (!config) {\n throw new Error(`Unknown pressure unit: ${variant}`);\n }\n return value * (config.factor ?? 1);\n}\n\n/**\n * Converte valor da unidade base (pascal) para outra unidade\n *\n * @param variant - Unidade de destino\n * @param baseValue - Valor em pascals\n * @returns Valor na unidade de destino\n *\n * @example\n * fromBasePressure('bar', 250000); // 2.5\n * fromBasePressure('atmosphere', 101325); // 1\n */\nexport function fromBasePressure(variant: PressureUnit, baseValue: number): number {\n const config = PRESSURE_UNITS[variant];\n if (!config) {\n throw new Error(`Unknown pressure unit: ${variant}`);\n }\n return baseValue / (config.factor ?? 1);\n}\n\n/**\n * Converte entre duas unidades de pressão\n *\n * @param from - Unidade de origem\n * @param to - Unidade de destino\n * @param value - Valor a converter\n * @returns Valor convertido\n *\n * @example\n * convertPressure('bar', 'pascal', 1); // 100000\n * convertPressure('atmosphere', 'psi', 1); // 14.696\n */\nexport function convertPressure(\n from: PressureUnit,\n to: PressureUnit,\n value: number,\n): number {\n if (from === to) {\n return value;\n }\n const baseValue = toBasePressure(from, value);\n return fromBasePressure(to, baseValue);\n}\n\n/**\n * Versão safe de convertPressure que retorna Result\n *\n * @example\n * tryConvertPressure('bar', 'pascal', 1); // { ok: true, value: 100000 }\n * tryConvertPressure('invalid', 'pascal', 1); // { ok: false, error: '...' }\n */\nexport function tryConvertPressure(\n from: PressureUnit,\n to: PressureUnit,\n value: number,\n): Result<number> {\n try {\n return { ok: true, value: convertPressure(from, to, value) };\n } catch (e) {\n return { ok: false, error: (e as Error).message };\n }\n}\n\n// =============================================================================\n// HELPERS\n// =============================================================================\n\n/**\n * Verifica se uma variante existe\n *\n * @example\n * hasPressureVariant('bar'); // true\n * hasPressureVariant('invalid'); // false\n */\nexport function hasPressureVariant(variant: string): variant is PressureUnit {\n return variant in PRESSURE_UNITS;\n}\n\n/**\n * Retorna lista de todas as variantes disponíveis\n *\n * @example\n * getPressureVariants(); // ['megapascal', 'kilopascal', 'hectopascal', ...]\n */\nexport function getPressureVariants(): PressureUnit[] {\n return Object.keys(PRESSURE_UNITS) as PressureUnit[];\n}\n","/**\n * Pressure Role - Cast Pillar\n *\n * Normaliza input sujo para número, com detecção automática de unidade.\n *\n * @example\n * import { castPressure, castPressureStrict, detectPressureUnit } from '@attrx/role-morphic/pressure/cast';\n *\n * castPressure('1 bar'); // 100000 (converted to pascals)\n * castPressure('1 bar', 'bar'); // 1 (kept as bar)\n * castPressureStrict('100'); // 100 (no conversion)\n * detectPressureUnit('14.7 psi'); // 'psi'\n */\n\nimport { PRESSURE_UNITS, PRESSURE_ALIASES, type PressureUnit } from \"./constants\";\nimport { convertPressure, PRESSURE_BASE } from \"./convert\";\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport type Result<T> = { ok: true; value: T } | { ok: false; error: string };\n\n// =============================================================================\n// CAST\n// =============================================================================\n\n/**\n * Faz cast de input para número, com conversão opcional para unidade alvo\n *\n * @param input - Valor de entrada (number, string, etc)\n * @param targetVariant - Unidade alvo (default: pascal)\n * @returns Número ou null se não puder converter\n *\n * @example\n * castPressure('1 bar'); // 100000 (pascals)\n * castPressure('1 bar', 'bar'); // 1\n * castPressure('100'); // 100\n * castPressure(100); // 100\n * castPressure('invalid'); // null\n */\nexport function castPressure(\n input: unknown,\n targetVariant: PressureUnit = PRESSURE_BASE,\n): number | null {\n // Already a number\n if (typeof input === \"number\") {\n return Number.isFinite(input) ? input : null;\n }\n\n // String parsing\n if (typeof input === \"string\") {\n const parsed = parsePressureString(input);\n if (parsed === null) {\n return null;\n }\n\n // If unit was detected and differs from target, convert\n if (parsed.unit && parsed.unit !== targetVariant) {\n return convertPressure(parsed.unit, targetVariant, parsed.value);\n }\n\n return parsed.value;\n }\n\n return null;\n}\n\n/**\n * Faz cast sem conversão (apenas parseia o número)\n *\n * @param input - Valor de entrada\n * @returns Número ou null\n *\n * @example\n * castPressureStrict('100 bar'); // 100 (ignora a unidade)\n * castPressureStrict('100'); // 100\n */\nexport function castPressureStrict(input: unknown): number | null {\n if (typeof input === \"number\") {\n return Number.isFinite(input) ? input : null;\n }\n\n if (typeof input === \"string\") {\n const parsed = parsePressureString(input);\n return parsed?.value ?? null;\n }\n\n return null;\n}\n\n/**\n * Versão safe de castPressure que retorna Result\n */\nexport function tryCastPressure(\n input: unknown,\n targetVariant: PressureUnit = PRESSURE_BASE,\n): Result<number> {\n const result = castPressure(input, targetVariant);\n if (result === null) {\n return { ok: false, error: `Cannot cast \"${String(input)}\" to pressure` };\n }\n return { ok: true, value: result };\n}\n\n// =============================================================================\n// DETECT UNIT\n// =============================================================================\n\n/**\n * Detecta a unidade de pressão de uma string\n *\n * @param input - String com valor e unidade\n * @returns Unidade detectada ou null\n *\n * @example\n * detectPressureUnit('100 bar'); // 'bar'\n * detectPressureUnit('14.7 psi'); // 'psi'\n * detectPressureUnit('100'); // null\n */\nexport function detectPressureUnit(input: string): PressureUnit | null {\n const trimmed = input.trim().toLowerCase();\n\n // Extract unit part (after the number)\n const match = trimmed.match(/^[+-]?[\\d.,\\s]+\\s*(.*)$/);\n if (!match || !match[1]) {\n return null;\n }\n\n const unitStr = match[1].trim();\n if (!unitStr) {\n return null;\n }\n\n // Check direct unit names\n if (unitStr in PRESSURE_UNITS) {\n return unitStr as PressureUnit;\n }\n\n // Check aliases\n if (unitStr in PRESSURE_ALIASES) {\n return PRESSURE_ALIASES[unitStr] as PressureUnit;\n }\n\n // Check symbols (case-sensitive for some)\n for (const [unit, config] of Object.entries(PRESSURE_UNITS)) {\n if (config.symbol.toLowerCase() === unitStr) {\n return unit as PressureUnit;\n }\n }\n\n return null;\n}\n\n// =============================================================================\n// INTERNAL HELPERS\n// =============================================================================\n\ninterface ParsedPressure {\n value: number;\n unit: PressureUnit | null;\n}\n\n/**\n * Parseia string de pressão extraindo valor e unidade\n */\nfunction parsePressureString(input: string): ParsedPressure | null {\n const trimmed = input.trim();\n if (!trimmed) {\n return null;\n }\n\n // Try to extract number and unit\n const match = trimmed.match(/^([+-]?[\\d.,\\s]+)\\s*(.*)$/);\n if (!match) {\n return null;\n }\n\n const numStr = match[1].replace(/\\s/g, \"\").replace(\",\", \".\");\n const value = parseFloat(numStr);\n\n if (isNaN(value) || !Number.isFinite(value)) {\n return null;\n }\n\n const unitStr = match[2]?.trim().toLowerCase() || \"\";\n let unit: PressureUnit | null = null;\n\n if (unitStr) {\n // Check aliases first\n if (unitStr in PRESSURE_ALIASES) {\n unit = PRESSURE_ALIASES[unitStr] as PressureUnit;\n }\n // Check direct unit names\n else if (unitStr in PRESSURE_UNITS) {\n unit = unitStr as PressureUnit;\n }\n // Check symbols\n else {\n for (const [u, config] of Object.entries(PRESSURE_UNITS)) {\n if (config.symbol.toLowerCase() === unitStr) {\n unit = u as PressureUnit;\n break;\n }\n }\n }\n }\n\n return { value, unit };\n}\n","/**\n * Frequency Role - Constants\n *\n * Fatores de conversão, símbolos e aliases para unidades de frequência.\n *\n * Fontes:\n * - SI Brochure, 9th Edition (2019)\n * - NIST SP 811\n */\n\nimport type { SimpleUnitConfig, UnitAliases } from \"../../contracts\";\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport type FrequencyUnit =\n // SI\n | \"terahertz\"\n | \"gigahertz\"\n | \"megahertz\"\n | \"kilohertz\"\n | \"hertz\"\n | \"millihertz\"\n | \"microhertz\"\n // Other\n | \"rpm\"\n | \"bpm\"\n | \"radians_per_second\"\n | \"cycles_per_minute\";\n\n// =============================================================================\n// UNITS CONFIG\n// =============================================================================\n\n/**\n * Configuração de cada unidade de frequência.\n *\n * Base: hertz (Hz) = 1 ciclo por segundo\n *\n * Relações:\n * - 1 RPM = 1/60 Hz (rotações por minuto)\n * - 1 rad/s = 1/(2π) Hz\n */\nexport const FREQUENCY_UNITS: Record<FrequencyUnit, SimpleUnitConfig> = {\n // SI Units (todos exatos)\n terahertz: {\n factor: 1e12,\n symbol: \"THz\",\n singular: \"terahertz\",\n plural: \"terahertz\",\n },\n gigahertz: {\n factor: 1e9,\n symbol: \"GHz\",\n singular: \"gigahertz\",\n plural: \"gigahertz\",\n },\n megahertz: {\n factor: 1e6,\n symbol: \"MHz\",\n singular: \"megahertz\",\n plural: \"megahertz\",\n },\n kilohertz: {\n factor: 1000,\n symbol: \"kHz\",\n singular: \"kilohertz\",\n plural: \"kilohertz\",\n },\n hertz: {\n factor: 1,\n symbol: \"Hz\",\n singular: \"hertz\",\n plural: \"hertz\",\n },\n millihertz: {\n factor: 0.001,\n symbol: \"mHz\",\n singular: \"millihertz\",\n plural: \"millihertz\",\n },\n microhertz: {\n factor: 0.000001,\n symbol: \"μHz\",\n singular: \"microhertz\",\n plural: \"microhertz\",\n },\n\n // Other units\n rpm: {\n factor: 1 / 60, // 1 RPM = 1/60 Hz\n symbol: \"rpm\",\n singular: \"revolution per minute\",\n plural: \"revolutions per minute\",\n },\n bpm: {\n factor: 1 / 60, // 1 BPM = 1/60 Hz\n symbol: \"bpm\",\n singular: \"beat per minute\",\n plural: \"beats per minute\",\n },\n radians_per_second: {\n factor: 1 / (2 * Math.PI), // 1 rad/s = 1/(2π) Hz ≈ 0.159154943\n symbol: \"rad/s\",\n singular: \"radian per second\",\n plural: \"radians per second\",\n },\n cycles_per_minute: {\n factor: 1 / 60, // same as RPM\n symbol: \"cpm\",\n singular: \"cycle per minute\",\n plural: \"cycles per minute\",\n },\n};\n\n// =============================================================================\n// ALIASES\n// =============================================================================\n\n/**\n * Aliases para reconhecimento de unidades no cast\n */\nexport const FREQUENCY_ALIASES: UnitAliases = {\n // terahertz\n thz: \"terahertz\",\n // gigahertz\n ghz: \"gigahertz\",\n // megahertz\n mhz: \"megahertz\",\n // kilohertz\n khz: \"kilohertz\",\n // hertz\n hz: \"hertz\",\n cps: \"hertz\",\n // microhertz\n \"μhz\": \"microhertz\",\n uhz: \"microhertz\",\n // rpm\n rpm: \"rpm\",\n // bpm\n bpm: \"bpm\",\n // radians_per_second\n \"rad/s\": \"radians_per_second\",\n // cycles_per_minute\n cpm: \"cycles_per_minute\",\n};\n\n// =============================================================================\n// HELPERS\n// =============================================================================\n\n/** Lista de todas as unidades */\nexport const FREQUENCY_UNIT_LIST = Object.keys(\n FREQUENCY_UNITS,\n) as FrequencyUnit[];\n\n/** Fatores de conversão (para compatibilidade) */\nexport const FREQUENCY_FACTORS: Record<FrequencyUnit, number> =\n Object.fromEntries(\n Object.entries(FREQUENCY_UNITS).map(([unit, config]) => [\n unit,\n config.factor ?? 1,\n ]),\n ) as Record<FrequencyUnit, number>;\n","/**\n * Frequency Role - Convert Pillar\n *\n * Conversão entre unidades de frequência usando hub-and-spoke (via hertz).\n *\n * @example\n * import { convertFrequency, toBaseFrequency, fromBaseFrequency } from '@attrx/role-morphic/frequency/convert';\n *\n * convertFrequency('megahertz', 'hertz', 1); // 1000000\n * toBaseFrequency('megahertz', 2.4); // 2400000 (hertz)\n * fromBaseFrequency('megahertz', 2400000); // 2.4\n */\n\nimport { FREQUENCY_UNITS, type FrequencyUnit } from \"./constants\";\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport type Result<T> = { ok: true; value: T } | { ok: false; error: string };\n\n// =============================================================================\n// CONSTANTS\n// =============================================================================\n\n/** Unidade base para conversões (hub) */\nexport const FREQUENCY_BASE: FrequencyUnit = \"hertz\";\n\n// =============================================================================\n// CORE CONVERSION\n// =============================================================================\n\n/**\n * Converte valor para a unidade base (hertz)\n *\n * @param variant - Unidade de origem\n * @param value - Valor a converter\n * @returns Valor em hertz\n *\n * @example\n * toBaseFrequency('megahertz', 2.4); // 2400000\n * toBaseFrequency('rpm', 60); // 1\n */\nexport function toBaseFrequency(variant: FrequencyUnit, value: number): number {\n const config = FREQUENCY_UNITS[variant];\n if (!config) {\n throw new Error(`Unknown frequency unit: ${variant}`);\n }\n return value * (config.factor ?? 1);\n}\n\n/**\n * Converte valor da unidade base (hertz) para outra unidade\n *\n * @param variant - Unidade de destino\n * @param baseValue - Valor em hertz\n * @returns Valor na unidade de destino\n *\n * @example\n * fromBaseFrequency('megahertz', 2400000); // 2.4\n * fromBaseFrequency('rpm', 1); // 60\n */\nexport function fromBaseFrequency(variant: FrequencyUnit, baseValue: number): number {\n const config = FREQUENCY_UNITS[variant];\n if (!config) {\n throw new Error(`Unknown frequency unit: ${variant}`);\n }\n return baseValue / (config.factor ?? 1);\n}\n\n/**\n * Converte entre duas unidades de frequência\n *\n * @param from - Unidade de origem\n * @param to - Unidade de destino\n * @param value - Valor a converter\n * @returns Valor convertido\n *\n * @example\n * convertFrequency('megahertz', 'hertz', 1); // 1000000\n * convertFrequency('rpm', 'hertz', 60); // 1\n */\nexport function convertFrequency(\n from: FrequencyUnit,\n to: FrequencyUnit,\n value: number,\n): number {\n if (from === to) {\n return value;\n }\n const baseValue = toBaseFrequency(from, value);\n return fromBaseFrequency(to, baseValue);\n}\n\n/**\n * Versão safe de convertFrequency que retorna Result\n *\n * @example\n * tryConvertFrequency('megahertz', 'hertz', 1); // { ok: true, value: 1000000 }\n * tryConvertFrequency('invalid', 'hertz', 1); // { ok: false, error: '...' }\n */\nexport function tryConvertFrequency(\n from: FrequencyUnit,\n to: FrequencyUnit,\n value: number,\n): Result<number> {\n try {\n return { ok: true, value: convertFrequency(from, to, value) };\n } catch (e) {\n return { ok: false, error: (e as Error).message };\n }\n}\n\n// =============================================================================\n// HELPERS\n// =============================================================================\n\n/**\n * Verifica se uma variante existe\n *\n * @example\n * hasFrequencyVariant('hertz'); // true\n * hasFrequencyVariant('invalid'); // false\n */\nexport function hasFrequencyVariant(variant: string): variant is FrequencyUnit {\n return variant in FREQUENCY_UNITS;\n}\n\n/**\n * Retorna lista de todas as variantes disponíveis\n *\n * @example\n * getFrequencyVariants(); // ['terahertz', 'gigahertz', 'megahertz', ...]\n */\nexport function getFrequencyVariants(): FrequencyUnit[] {\n return Object.keys(FREQUENCY_UNITS) as FrequencyUnit[];\n}\n","/**\n * Frequency Role - Cast Pillar\n *\n * Normaliza input sujo para número, com detecção automática de unidade.\n *\n * @example\n * import { castFrequency, castFrequencyStrict, detectFrequencyUnit } from '@attrx/role-morphic/frequency/cast';\n *\n * castFrequency('2.4 GHz'); // 2400000000 (converted to hertz)\n * castFrequency('2.4 GHz', 'gigahertz'); // 2.4 (kept as gigahertz)\n * castFrequencyStrict('100'); // 100 (no conversion)\n * detectFrequencyUnit('3600 rpm'); // 'rpm'\n */\n\nimport { FREQUENCY_UNITS, FREQUENCY_ALIASES, type FrequencyUnit } from \"./constants\";\nimport { convertFrequency, FREQUENCY_BASE } from \"./convert\";\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport type Result<T> = { ok: true; value: T } | { ok: false; error: string };\n\n// =============================================================================\n// CAST\n// =============================================================================\n\n/**\n * Faz cast de input para número, com conversão opcional para unidade alvo\n *\n * @param input - Valor de entrada (number, string, etc)\n * @param targetVariant - Unidade alvo (default: hertz)\n * @returns Número ou null se não puder converter\n *\n * @example\n * castFrequency('2.4 GHz'); // 2400000000 (hertz)\n * castFrequency('2.4 GHz', 'gigahertz'); // 2.4\n * castFrequency('100'); // 100\n * castFrequency(100); // 100\n * castFrequency('invalid'); // null\n */\nexport function castFrequency(\n input: unknown,\n targetVariant: FrequencyUnit = FREQUENCY_BASE,\n): number | null {\n // Already a number\n if (typeof input === \"number\") {\n return Number.isFinite(input) ? input : null;\n }\n\n // String parsing\n if (typeof input === \"string\") {\n const parsed = parseFrequencyString(input);\n if (parsed === null) {\n return null;\n }\n\n // If unit was detected and differs from target, convert\n if (parsed.unit && parsed.unit !== targetVariant) {\n return convertFrequency(parsed.unit, targetVariant, parsed.value);\n }\n\n return parsed.value;\n }\n\n return null;\n}\n\n/**\n * Faz cast sem conversão (apenas parseia o número)\n *\n * @param input - Valor de entrada\n * @returns Número ou null\n *\n * @example\n * castFrequencyStrict('100 MHz'); // 100 (ignora a unidade)\n * castFrequencyStrict('100'); // 100\n */\nexport function castFrequencyStrict(input: unknown): number | null {\n if (typeof input === \"number\") {\n return Number.isFinite(input) ? input : null;\n }\n\n if (typeof input === \"string\") {\n const parsed = parseFrequencyString(input);\n return parsed?.value ?? null;\n }\n\n return null;\n}\n\n/**\n * Versão safe de castFrequency que retorna Result\n */\nexport function tryCastFrequency(\n input: unknown,\n targetVariant: FrequencyUnit = FREQUENCY_BASE,\n): Result<number> {\n const result = castFrequency(input, targetVariant);\n if (result === null) {\n return { ok: false, error: `Cannot cast \"${String(input)}\" to frequency` };\n }\n return { ok: true, value: result };\n}\n\n// =============================================================================\n// DETECT UNIT\n// =============================================================================\n\n/**\n * Detecta a unidade de frequência de uma string\n *\n * @param input - String com valor e unidade\n * @returns Unidade detectada ou null\n *\n * @example\n * detectFrequencyUnit('100 MHz'); // 'megahertz'\n * detectFrequencyUnit('3600 rpm'); // 'rpm'\n * detectFrequencyUnit('100'); // null\n */\nexport function detectFrequencyUnit(input: string): FrequencyUnit | null {\n const trimmed = input.trim().toLowerCase();\n\n // Extract unit part (after the number)\n const match = trimmed.match(/^[+-]?[\\d.,\\s]+\\s*(.*)$/);\n if (!match || !match[1]) {\n return null;\n }\n\n const unitStr = match[1].trim();\n if (!unitStr) {\n return null;\n }\n\n // Check direct unit names\n if (unitStr in FREQUENCY_UNITS) {\n return unitStr as FrequencyUnit;\n }\n\n // Check aliases\n if (unitStr in FREQUENCY_ALIASES) {\n return FREQUENCY_ALIASES[unitStr] as FrequencyUnit;\n }\n\n // Check symbols (case-sensitive for some)\n for (const [unit, config] of Object.entries(FREQUENCY_UNITS)) {\n if (config.symbol.toLowerCase() === unitStr) {\n return unit as FrequencyUnit;\n }\n }\n\n return null;\n}\n\n// =============================================================================\n// INTERNAL HELPERS\n// =============================================================================\n\ninterface ParsedFrequency {\n value: number;\n unit: FrequencyUnit | null;\n}\n\n/**\n * Parseia string de frequência extraindo valor e unidade\n */\nfunction parseFrequencyString(input: string): ParsedFrequency | null {\n const trimmed = input.trim();\n if (!trimmed) {\n return null;\n }\n\n // Try to extract number and unit\n const match = trimmed.match(/^([+-]?[\\d.,\\s]+)\\s*(.*)$/);\n if (!match) {\n return null;\n }\n\n const numStr = match[1].replace(/\\s/g, \"\").replace(\",\", \".\");\n const value = parseFloat(numStr);\n\n if (isNaN(value) || !Number.isFinite(value)) {\n return null;\n }\n\n const unitStr = match[2]?.trim().toLowerCase() || \"\";\n let unit: FrequencyUnit | null = null;\n\n if (unitStr) {\n // Check aliases first\n if (unitStr in FREQUENCY_ALIASES) {\n unit = FREQUENCY_ALIASES[unitStr] as FrequencyUnit;\n }\n // Check direct unit names\n else if (unitStr in FREQUENCY_UNITS) {\n unit = unitStr as FrequencyUnit;\n }\n // Check symbols\n else {\n for (const [u, config] of Object.entries(FREQUENCY_UNITS)) {\n if (config.symbol.toLowerCase() === unitStr) {\n unit = u as FrequencyUnit;\n break;\n }\n }\n }\n }\n\n return { value, unit };\n}\n","/**\n * Angle Role - Constants\n *\n * Fatores de conversão, símbolos e aliases para unidades de ângulo.\n *\n * Base: degree (grau) - mais comum em aplicações práticas.\n * Nota: Embora radiano seja a unidade SI, grau é mais intuitivo para a maioria dos casos.\n *\n * Fontes:\n * - SI Brochure, 9th Edition (2019)\n * - NIST SP 811 (2008)\n */\n\nimport type { SimpleUnitConfig, UnitAliases } from \"../../contracts\";\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport type AngleUnit =\n | \"turn\"\n | \"degree\"\n | \"arcminute\"\n | \"arcsecond\"\n | \"milliarcsecond\"\n | \"radian\"\n | \"milliradian\"\n | \"gradian\";\n\n// =============================================================================\n// CONSTANTS\n// =============================================================================\n\n/**\n * Fator exato: 180/π graus por radiano\n * Valor: 57.29577951308232...\n */\nconst DEGREES_PER_RADIAN = 180 / Math.PI;\n\n/**\n * Fator exato: 180/(1000π) graus por milirradiano\n */\nconst DEGREES_PER_MILLIRADIAN = 180 / (1000 * Math.PI);\n\n// =============================================================================\n// UNITS CONFIG\n// =============================================================================\n\n/**\n * Configuração de cada unidade de ângulo.\n *\n * Fatores EXATOS:\n * - turn: 360 (definição)\n * - degree: 1 (base)\n * - arcminute: 1/60 (definição)\n * - arcsecond: 1/3600 (definição)\n * - milliarcsecond: 1/3600000 (definição)\n * - gradian: 360/400 = 0.9 (definição)\n * - radian: 180/π (exato por definição matemática)\n * - milliradian: 180/(1000π) (derivado)\n */\nexport const ANGLE_UNITS: Record<AngleUnit, SimpleUnitConfig> = {\n // Volta completa\n turn: {\n factor: 360,\n symbol: \"tr\",\n singular: \"turn\",\n plural: \"turns\",\n },\n\n // Base\n degree: {\n factor: 1,\n symbol: \"°\",\n singular: \"degree\",\n plural: \"degrees\",\n noSpace: true, // 45° não 45 °\n },\n\n // Subdivisões do grau\n arcminute: {\n factor: 1 / 60, // 0.016666...\n symbol: \"′\",\n singular: \"arcminute\",\n plural: \"arcminutes\",\n noSpace: true, // 30′ não 30 ′\n },\n arcsecond: {\n factor: 1 / 3600, // 0.000277...\n symbol: \"″\",\n singular: \"arcsecond\",\n plural: \"arcseconds\",\n noSpace: true, // 45″ não 45 ″\n },\n milliarcsecond: {\n factor: 1 / 3600000, // 2.777...e-7\n symbol: \"mas\",\n singular: \"milliarcsecond\",\n plural: \"milliarcseconds\",\n },\n\n // Radianos (unidade SI)\n radian: {\n factor: DEGREES_PER_RADIAN, // 180/π ≈ 57.2958\n symbol: \"rad\",\n singular: \"radian\",\n plural: \"radians\",\n },\n milliradian: {\n factor: DEGREES_PER_MILLIRADIAN, // 180/(1000π) ≈ 0.0573\n symbol: \"mrad\",\n singular: \"milliradian\",\n plural: \"milliradians\",\n },\n\n // Gradiano (gon)\n gradian: {\n factor: 0.9, // 360/400\n symbol: \"gon\",\n singular: \"gradian\",\n plural: \"gradians\",\n },\n};\n\n// =============================================================================\n// ALIASES\n// =============================================================================\n\n/**\n * Aliases para reconhecimento de unidades no cast\n */\nexport const ANGLE_ALIASES: UnitAliases = {\n // turn\n tr: \"turn\",\n rev: \"turn\",\n // degree\n \"°\": \"degree\",\n deg: \"degree\",\n // arcminute\n \"′\": \"arcminute\",\n \"'\": \"arcminute\",\n arcmin: \"arcminute\",\n // arcsecond\n \"″\": \"arcsecond\",\n '\"': \"arcsecond\",\n arcsec: \"arcsecond\",\n // milliarcsecond\n mas: \"milliarcsecond\",\n // radian\n rad: \"radian\",\n // milliradian\n mrad: \"milliradian\",\n // gradian\n gon: \"gradian\",\n grad: \"gradian\",\n};\n\n// =============================================================================\n// HELPERS\n// =============================================================================\n\n/** Lista de todas as unidades */\nexport const ANGLE_UNIT_LIST = Object.keys(ANGLE_UNITS) as AngleUnit[];\n\n/** Fatores de conversão (para compatibilidade) */\nexport const ANGLE_FACTORS: Record<AngleUnit, number> = Object.fromEntries(\n Object.entries(ANGLE_UNITS).map(([unit, config]) => [\n unit,\n config.factor ?? 1,\n ]),\n) as Record<AngleUnit, number>;\n","/**\n * Angle Role - Convert Pillar\n *\n * Conversão entre unidades de ângulo usando hub-and-spoke (via degree).\n *\n * @example\n * import { convertAngle, toBaseAngle, fromBaseAngle } from '@attrx/role-morphic/angle/convert';\n *\n * convertAngle('degree', 'radian', 180); // π ≈ 3.14159\n * toBaseAngle('turn', 1); // 360 (degrees)\n * fromBaseAngle('radian', 180); // π ≈ 3.14159\n */\n\nimport { ANGLE_UNITS, type AngleUnit } from \"./constants\";\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport type Result<T> = { ok: true; value: T } | { ok: false; error: string };\n\n// =============================================================================\n// CONSTANTS\n// =============================================================================\n\n/** Unidade base para conversões (hub) */\nexport const ANGLE_BASE: AngleUnit = \"degree\";\n\n// =============================================================================\n// CORE CONVERSION\n// =============================================================================\n\n/**\n * Converte valor para a unidade base (degree)\n *\n * @param variant - Unidade de origem\n * @param value - Valor a converter\n * @returns Valor em degrees\n *\n * @example\n * toBaseAngle('turn', 1); // 360\n * toBaseAngle('radian', Math.PI); // 180\n */\nexport function toBaseAngle(variant: AngleUnit, value: number): number {\n const config = ANGLE_UNITS[variant];\n if (!config) {\n throw new Error(`Unknown angle unit: ${variant}`);\n }\n return value * (config.factor ?? 1);\n}\n\n/**\n * Converte valor da unidade base (degree) para outra unidade\n *\n * @param variant - Unidade de destino\n * @param baseValue - Valor em degrees\n * @returns Valor na unidade de destino\n *\n * @example\n * fromBaseAngle('radian', 180); // π ≈ 3.14159\n * fromBaseAngle('turn', 360); // 1\n */\nexport function fromBaseAngle(variant: AngleUnit, baseValue: number): number {\n const config = ANGLE_UNITS[variant];\n if (!config) {\n throw new Error(`Unknown angle unit: ${variant}`);\n }\n return baseValue / (config.factor ?? 1);\n}\n\n/**\n * Converte entre duas unidades de ângulo\n *\n * @param from - Unidade de origem\n * @param to - Unidade de destino\n * @param value - Valor a converter\n * @returns Valor convertido\n *\n * @example\n * convertAngle('degree', 'radian', 180); // π ≈ 3.14159\n * convertAngle('turn', 'degree', 1); // 360\n */\nexport function convertAngle(\n from: AngleUnit,\n to: AngleUnit,\n value: number,\n): number {\n if (from === to) {\n return value;\n }\n const baseValue = toBaseAngle(from, value);\n return fromBaseAngle(to, baseValue);\n}\n\n/**\n * Versão safe de convertAngle que retorna Result\n *\n * @example\n * tryConvertAngle('degree', 'radian', 180); // { ok: true, value: π }\n * tryConvertAngle('invalid', 'radian', 180); // { ok: false, error: '...' }\n */\nexport function tryConvertAngle(\n from: AngleUnit,\n to: AngleUnit,\n value: number,\n): Result<number> {\n try {\n return { ok: true, value: convertAngle(from, to, value) };\n } catch (e) {\n return { ok: false, error: (e as Error).message };\n }\n}\n\n// =============================================================================\n// HELPERS\n// =============================================================================\n\n/**\n * Verifica se uma variante existe\n *\n * @example\n * hasAngleVariant('degree'); // true\n * hasAngleVariant('invalid'); // false\n */\nexport function hasAngleVariant(variant: string): variant is AngleUnit {\n return variant in ANGLE_UNITS;\n}\n\n/**\n * Retorna lista de todas as variantes disponíveis\n *\n * @example\n * getAngleVariants(); // ['turn', 'degree', 'arcminute', ...]\n */\nexport function getAngleVariants(): AngleUnit[] {\n return Object.keys(ANGLE_UNITS) as AngleUnit[];\n}\n\n// =============================================================================\n// CONVENIENCE FUNCTIONS\n// =============================================================================\n\n/**\n * Converte graus para radianos\n *\n * @example\n * degreesToRadians(180) // π ≈ 3.14159\n * degreesToRadians(90) // π/2 ≈ 1.5708\n */\nexport function degreesToRadians(degrees: number): number {\n return convertAngle(\"degree\", \"radian\", degrees);\n}\n\n/**\n * Converte radianos para graus\n *\n * @example\n * radiansToDegrees(Math.PI) // 180\n * radiansToDegrees(Math.PI / 2) // 90\n */\nexport function radiansToDegrees(radians: number): number {\n return convertAngle(\"radian\", \"degree\", radians);\n}\n\n/**\n * Normaliza ângulo para o intervalo [0, 360)\n *\n * @example\n * normalizeAngle(450) // 90\n * normalizeAngle(-90) // 270\n * normalizeAngle(360) // 0\n */\nexport function normalizeAngle(degrees: number): number {\n const normalized = degrees % 360;\n // Evita -0 (JavaScript tem +0 e -0)\n if (normalized === 0) return 0;\n return normalized < 0 ? normalized + 360 : normalized;\n}\n","/**\n * Angle Role - Cast Pillar\n *\n * Normaliza input sujo para número, com detecção automática de unidade.\n *\n * @example\n * import { castAngle, castAngleStrict, detectAngleUnit } from '@attrx/role-morphic/angle/cast';\n *\n * castAngle('90°'); // 90 (degrees)\n * castAngle('3.14159 rad', 'degree'); // ~180 (converted to degrees)\n * castAngleStrict('90'); // 90 (no conversion)\n * detectAngleUnit('45°'); // 'degree'\n */\n\nimport { ANGLE_UNITS, ANGLE_ALIASES, type AngleUnit } from \"./constants\";\nimport { convertAngle, ANGLE_BASE } from \"./convert\";\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport type Result<T> = { ok: true; value: T } | { ok: false; error: string };\n\n// =============================================================================\n// CAST\n// =============================================================================\n\n/**\n * Faz cast de input para número, com conversão opcional para unidade alvo\n *\n * @param input - Valor de entrada (number, string, etc)\n * @param targetVariant - Unidade alvo (default: degree)\n * @returns Número ou null se não puder converter\n *\n * @example\n * castAngle('90°'); // 90\n * castAngle('3.14159 rad', 'degree'); // ~180\n * castAngle('100'); // 100\n * castAngle(45); // 45\n * castAngle('invalid'); // null\n */\nexport function castAngle(\n input: unknown,\n targetVariant: AngleUnit = ANGLE_BASE,\n): number | null {\n // Already a number\n if (typeof input === \"number\") {\n return Number.isFinite(input) ? input : null;\n }\n\n // String parsing\n if (typeof input === \"string\") {\n const parsed = parseAngleString(input);\n if (parsed === null) {\n return null;\n }\n\n // If unit was detected and differs from target, convert\n if (parsed.unit && parsed.unit !== targetVariant) {\n return convertAngle(parsed.unit, targetVariant, parsed.value);\n }\n\n return parsed.value;\n }\n\n return null;\n}\n\n/**\n * Faz cast sem conversão (apenas parseia o número)\n *\n * @param input - Valor de entrada\n * @returns Número ou null\n *\n * @example\n * castAngleStrict('90°'); // 90 (ignora a unidade)\n * castAngleStrict('100'); // 100\n */\nexport function castAngleStrict(input: unknown): number | null {\n if (typeof input === \"number\") {\n return Number.isFinite(input) ? input : null;\n }\n\n if (typeof input === \"string\") {\n const parsed = parseAngleString(input);\n return parsed?.value ?? null;\n }\n\n return null;\n}\n\n/**\n * Versão safe de castAngle que retorna Result\n */\nexport function tryCastAngle(\n input: unknown,\n targetVariant: AngleUnit = ANGLE_BASE,\n): Result<number> {\n const result = castAngle(input, targetVariant);\n if (result === null) {\n return { ok: false, error: `Cannot cast \"${String(input)}\" to angle` };\n }\n return { ok: true, value: result };\n}\n\n// =============================================================================\n// DETECT UNIT\n// =============================================================================\n\n/**\n * Detecta a unidade de ângulo de uma string\n *\n * @param input - String com valor e unidade\n * @returns Unidade detectada ou null\n *\n * @example\n * detectAngleUnit('90°'); // 'degree'\n * detectAngleUnit('3.14 rad'); // 'radian'\n * detectAngleUnit('100'); // null\n */\nexport function detectAngleUnit(input: string): AngleUnit | null {\n const trimmed = input.trim();\n\n // Special case: degree symbol can be directly attached to number\n if (trimmed.endsWith(\"°\")) {\n return \"degree\";\n }\n\n const lowerTrimmed = trimmed.toLowerCase();\n\n // Extract unit part (after the number)\n const match = lowerTrimmed.match(/^[+-]?[\\d.,\\s]+\\s*(.*)$/);\n if (!match || !match[1]) {\n return null;\n }\n\n const unitStr = match[1].trim();\n if (!unitStr) {\n return null;\n }\n\n // Check direct unit names\n if (unitStr in ANGLE_UNITS) {\n return unitStr as AngleUnit;\n }\n\n // Check aliases\n if (unitStr in ANGLE_ALIASES) {\n return ANGLE_ALIASES[unitStr] as AngleUnit;\n }\n\n // Check symbols (case-sensitive for some)\n for (const [unit, config] of Object.entries(ANGLE_UNITS)) {\n if (config.symbol.toLowerCase() === unitStr || config.symbol === unitStr) {\n return unit as AngleUnit;\n }\n }\n\n return null;\n}\n\n// =============================================================================\n// INTERNAL HELPERS\n// =============================================================================\n\ninterface ParsedAngle {\n value: number;\n unit: AngleUnit | null;\n}\n\n/**\n * Parseia string de ângulo extraindo valor e unidade\n */\nfunction parseAngleString(input: string): ParsedAngle | null {\n const trimmed = input.trim();\n if (!trimmed) {\n return null;\n }\n\n // Special case: degree symbol directly attached (45°)\n const degreeMatch = trimmed.match(/^([+-]?[\\d.,]+)°$/);\n if (degreeMatch) {\n const numStr = degreeMatch[1].replace(\",\", \".\");\n const value = parseFloat(numStr);\n if (isNaN(value) || !Number.isFinite(value)) {\n return null;\n }\n return { value, unit: \"degree\" };\n }\n\n // Try to extract number and unit\n const match = trimmed.match(/^([+-]?[\\d.,\\s]+)\\s*(.*)$/);\n if (!match) {\n return null;\n }\n\n const numStr = match[1].replace(/\\s/g, \"\").replace(\",\", \".\");\n const value = parseFloat(numStr);\n\n if (isNaN(value) || !Number.isFinite(value)) {\n return null;\n }\n\n const unitStr = match[2]?.trim().toLowerCase() || \"\";\n let unit: AngleUnit | null = null;\n\n if (unitStr) {\n // Check aliases first\n if (unitStr in ANGLE_ALIASES) {\n unit = ANGLE_ALIASES[unitStr] as AngleUnit;\n }\n // Check direct unit names\n else if (unitStr in ANGLE_UNITS) {\n unit = unitStr as AngleUnit;\n }\n // Check symbols\n else {\n for (const [u, config] of Object.entries(ANGLE_UNITS)) {\n if (config.symbol.toLowerCase() === unitStr || config.symbol === unitStr) {\n unit = u as AngleUnit;\n break;\n }\n }\n }\n }\n\n return { value, unit };\n}\n","/**\n * Time Role - Constants\n *\n * Fatores de conversão, símbolos e aliases para unidades de tempo/duração.\n *\n * Fontes:\n * - SI Brochure, 9th Edition (2019)\n * - Gregorian calendar (365.2425 dias/ano)\n */\n\nimport type { SimpleUnitConfig, UnitAliases } from \"../../contracts\";\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport type TimeUnit =\n // SI prefixes\n | \"nanosecond\"\n | \"microsecond\"\n | \"millisecond\"\n | \"second\"\n // Common\n | \"minute\"\n | \"hour\"\n | \"day\"\n | \"week\"\n // Calendar (approximate)\n | \"month\"\n | \"year\"\n | \"decade\"\n | \"century\"\n | \"millennium\";\n\n// =============================================================================\n// UNITS CONFIG\n// =============================================================================\n\n/**\n * Configuração de cada unidade de tempo.\n *\n * Fatores exatos:\n * - SI: prefixos são exatos por definição\n * - day, hour, minute: exatos (86400s, 3600s, 60s)\n * - week: exato (7 dias = 604800s)\n *\n * Fatores aproximados (baseados no calendário Gregoriano):\n * - year: 365.2425 dias (média do ciclo de 400 anos)\n * - month: year/12\n */\nexport const TIME_UNITS: Record<TimeUnit, SimpleUnitConfig> = {\n // SI prefixes (exatos)\n nanosecond: {\n factor: 1e-9,\n symbol: \"ns\",\n singular: \"nanosecond\",\n plural: \"nanoseconds\",\n },\n microsecond: {\n factor: 1e-6,\n symbol: \"μs\",\n singular: \"microsecond\",\n plural: \"microseconds\",\n },\n millisecond: {\n factor: 0.001,\n symbol: \"ms\",\n singular: \"millisecond\",\n plural: \"milliseconds\",\n },\n second: {\n factor: 1,\n symbol: \"s\",\n singular: \"second\",\n plural: \"seconds\",\n },\n\n // Common (exatos)\n minute: {\n factor: 60,\n symbol: \"min\",\n singular: \"minute\",\n plural: \"minutes\",\n },\n hour: {\n factor: 3600,\n symbol: \"h\",\n singular: \"hour\",\n plural: \"hours\",\n },\n day: {\n factor: 86400,\n symbol: \"d\",\n singular: \"day\",\n plural: \"days\",\n },\n week: {\n factor: 604800,\n symbol: \"wk\",\n singular: \"week\",\n plural: \"weeks\",\n },\n\n // Calendar (aproximados - baseados no ano Gregoriano)\n month: {\n factor: 2629746, // 31556952 / 12\n symbol: \"mo\",\n singular: \"month\",\n plural: \"months\",\n },\n year: {\n factor: 31556952, // 365.2425 * 86400\n symbol: \"yr\",\n singular: \"year\",\n plural: \"years\",\n },\n decade: {\n factor: 315569520, // 10 * year\n symbol: \"dec\",\n singular: \"decade\",\n plural: \"decades\",\n },\n century: {\n factor: 3155695200, // 100 * year\n symbol: \"c\",\n singular: \"century\",\n plural: \"centuries\",\n },\n millennium: {\n factor: 31556952000, // 1000 * year\n symbol: \"ky\",\n singular: \"millennium\",\n plural: \"millennia\",\n },\n};\n\n// =============================================================================\n// ALIASES\n// =============================================================================\n\n/**\n * Aliases para reconhecimento de unidades no cast\n */\nexport const TIME_ALIASES: UnitAliases = {\n // nanosecond\n ns: \"nanosecond\",\n // microsecond\n \"μs\": \"microsecond\",\n us: \"microsecond\",\n // millisecond\n ms: \"millisecond\",\n // second\n s: \"second\",\n sec: \"second\",\n // minute\n min: \"minute\",\n // hour\n h: \"hour\",\n hr: \"hour\",\n hrs: \"hour\",\n // day\n d: \"day\",\n // week\n wk: \"week\",\n // month\n mo: \"month\",\n // year\n yr: \"year\",\n y: \"year\",\n // decade\n dec: \"decade\",\n // century\n c: \"century\",\n // millennium\n ky: \"millennium\",\n};\n\n// =============================================================================\n// HELPERS\n// =============================================================================\n\n/** Lista de todas as unidades */\nexport const TIME_UNIT_LIST = Object.keys(TIME_UNITS) as TimeUnit[];\n\n/** Fatores de conversão (para compatibilidade) */\nexport const TIME_FACTORS: Record<TimeUnit, number> = Object.fromEntries(\n Object.entries(TIME_UNITS).map(([unit, config]) => [\n unit,\n config.factor ?? 1,\n ]),\n) as Record<TimeUnit, number>;\n","/**\n * Time Role - Convert Pillar\n *\n * Conversão entre unidades de tempo usando hub-and-spoke (via second).\n *\n * @example\n * import { convertTime, toBaseTime, fromBaseTime } from '@attrx/role-morphic/time/convert';\n *\n * convertTime('hour', 'minute', 1); // 60\n * toBaseTime('minute', 5); // 300 (seconds)\n * fromBaseTime('hour', 3600); // 1\n */\n\nimport { TIME_UNITS, type TimeUnit } from \"./constants\";\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport type Result<T> = { ok: true; value: T } | { ok: false; error: string };\n\n// =============================================================================\n// CONSTANTS\n// =============================================================================\n\n/** Unidade base para conversões (hub) */\nexport const TIME_BASE: TimeUnit = \"second\";\n\n// =============================================================================\n// CORE CONVERSION\n// =============================================================================\n\n/**\n * Converte valor para a unidade base (second)\n *\n * @param variant - Unidade de origem\n * @param value - Valor a converter\n * @returns Valor em seconds\n *\n * @example\n * toBaseTime('minute', 5); // 300\n * toBaseTime('hour', 1); // 3600\n */\nexport function toBaseTime(variant: TimeUnit, value: number): number {\n const config = TIME_UNITS[variant];\n if (!config) {\n throw new Error(`Unknown time unit: ${variant}`);\n }\n return value * (config.factor ?? 1);\n}\n\n/**\n * Converte valor da unidade base (second) para outra unidade\n *\n * @param variant - Unidade de destino\n * @param baseValue - Valor em seconds\n * @returns Valor na unidade de destino\n *\n * @example\n * fromBaseTime('minute', 300); // 5\n * fromBaseTime('hour', 3600); // 1\n */\nexport function fromBaseTime(variant: TimeUnit, baseValue: number): number {\n const config = TIME_UNITS[variant];\n if (!config) {\n throw new Error(`Unknown time unit: ${variant}`);\n }\n return baseValue / (config.factor ?? 1);\n}\n\n/**\n * Converte entre duas unidades de tempo\n *\n * @param from - Unidade de origem\n * @param to - Unidade de destino\n * @param value - Valor a converter\n * @returns Valor convertido\n *\n * @example\n * convertTime('hour', 'minute', 1); // 60\n * convertTime('day', 'hour', 1); // 24\n */\nexport function convertTime(\n from: TimeUnit,\n to: TimeUnit,\n value: number,\n): number {\n if (from === to) {\n return value;\n }\n const baseValue = toBaseTime(from, value);\n return fromBaseTime(to, baseValue);\n}\n\n/**\n * Versão safe de convertTime que retorna Result\n *\n * @example\n * tryConvertTime('hour', 'minute', 1); // { ok: true, value: 60 }\n * tryConvertTime('invalid', 'minute', 1); // { ok: false, error: '...' }\n */\nexport function tryConvertTime(\n from: TimeUnit,\n to: TimeUnit,\n value: number,\n): Result<number> {\n try {\n return { ok: true, value: convertTime(from, to, value) };\n } catch (e) {\n return { ok: false, error: (e as Error).message };\n }\n}\n\n// =============================================================================\n// HELPERS\n// =============================================================================\n\n/**\n * Verifica se uma variante existe\n *\n * @example\n * hasTimeVariant('second'); // true\n * hasTimeVariant('invalid'); // false\n */\nexport function hasTimeVariant(variant: string): variant is TimeUnit {\n return variant in TIME_UNITS;\n}\n\n/**\n * Retorna lista de todas as variantes disponíveis\n *\n * @example\n * getTimeVariants(); // ['nanosecond', 'microsecond', 'millisecond', ...]\n */\nexport function getTimeVariants(): TimeUnit[] {\n return Object.keys(TIME_UNITS) as TimeUnit[];\n}\n","/**\n * Time Role - Cast Pillar\n *\n * Normaliza input sujo para número, com detecção automática de unidade.\n *\n * @example\n * import { castTime, castTimeStrict, detectTimeUnit } from '@attrx/role-morphic/time/cast';\n *\n * castTime('5 min'); // 300 (converted to seconds)\n * castTime('5 min', 'minute'); // 5 (kept as minutes)\n * castTimeStrict('100'); // 100 (no conversion)\n * detectTimeUnit('2 hours'); // 'hour'\n */\n\nimport { TIME_UNITS, TIME_ALIASES, type TimeUnit } from \"./constants\";\nimport { convertTime, TIME_BASE } from \"./convert\";\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport type Result<T> = { ok: true; value: T } | { ok: false; error: string };\n\n// =============================================================================\n// CAST\n// =============================================================================\n\n/**\n * Faz cast de input para número, com conversão opcional para unidade alvo\n *\n * @param input - Valor de entrada (number, string, etc)\n * @param targetVariant - Unidade alvo (default: second)\n * @returns Número ou null se não puder converter\n *\n * @example\n * castTime('5 min'); // 300 (seconds)\n * castTime('5 min', 'minute'); // 5\n * castTime('100'); // 100\n * castTime(100); // 100\n * castTime('invalid'); // null\n */\nexport function castTime(\n input: unknown,\n targetVariant: TimeUnit = TIME_BASE,\n): number | null {\n // Already a number\n if (typeof input === \"number\") {\n return Number.isFinite(input) ? input : null;\n }\n\n // String parsing\n if (typeof input === \"string\") {\n const parsed = parseTimeString(input);\n if (parsed === null) {\n return null;\n }\n\n // If unit was detected and differs from target, convert\n if (parsed.unit && parsed.unit !== targetVariant) {\n return convertTime(parsed.unit, targetVariant, parsed.value);\n }\n\n return parsed.value;\n }\n\n return null;\n}\n\n/**\n * Faz cast sem conversão (apenas parseia o número)\n *\n * @param input - Valor de entrada\n * @returns Número ou null\n *\n * @example\n * castTimeStrict('5 min'); // 5 (ignora a unidade)\n * castTimeStrict('100'); // 100\n */\nexport function castTimeStrict(input: unknown): number | null {\n if (typeof input === \"number\") {\n return Number.isFinite(input) ? input : null;\n }\n\n if (typeof input === \"string\") {\n const parsed = parseTimeString(input);\n return parsed?.value ?? null;\n }\n\n return null;\n}\n\n/**\n * Versão safe de castTime que retorna Result\n */\nexport function tryCastTime(\n input: unknown,\n targetVariant: TimeUnit = TIME_BASE,\n): Result<number> {\n const result = castTime(input, targetVariant);\n if (result === null) {\n return { ok: false, error: `Cannot cast \"${String(input)}\" to time` };\n }\n return { ok: true, value: result };\n}\n\n// =============================================================================\n// DETECT UNIT\n// =============================================================================\n\n/**\n * Detecta a unidade de tempo de uma string\n *\n * @param input - String com valor e unidade\n * @returns Unidade detectada ou null\n *\n * @example\n * detectTimeUnit('5 min'); // 'minute'\n * detectTimeUnit('2 hours'); // 'hour'\n * detectTimeUnit('100'); // null\n */\nexport function detectTimeUnit(input: string): TimeUnit | null {\n const trimmed = input.trim().toLowerCase();\n\n // Extract unit part (after the number)\n const match = trimmed.match(/^[+-]?[\\d.,\\s]+\\s*(.*)$/);\n if (!match || !match[1]) {\n return null;\n }\n\n const unitStr = match[1].trim();\n if (!unitStr) {\n return null;\n }\n\n // Check direct unit names\n if (unitStr in TIME_UNITS) {\n return unitStr as TimeUnit;\n }\n\n // Check aliases\n if (unitStr in TIME_ALIASES) {\n return TIME_ALIASES[unitStr] as TimeUnit;\n }\n\n // Check symbols (case-sensitive for some)\n for (const [unit, config] of Object.entries(TIME_UNITS)) {\n if (config.symbol.toLowerCase() === unitStr) {\n return unit as TimeUnit;\n }\n }\n\n return null;\n}\n\n// =============================================================================\n// INTERNAL HELPERS\n// =============================================================================\n\ninterface ParsedTime {\n value: number;\n unit: TimeUnit | null;\n}\n\n/**\n * Parseia string de tempo extraindo valor e unidade\n */\nfunction parseTimeString(input: string): ParsedTime | null {\n const trimmed = input.trim();\n if (!trimmed) {\n return null;\n }\n\n // Try to extract number and unit\n const match = trimmed.match(/^([+-]?[\\d.,\\s]+)\\s*(.*)$/);\n if (!match) {\n return null;\n }\n\n const numStr = match[1].replace(/\\s/g, \"\").replace(\",\", \".\");\n const value = parseFloat(numStr);\n\n if (isNaN(value) || !Number.isFinite(value)) {\n return null;\n }\n\n const unitStr = match[2]?.trim().toLowerCase() || \"\";\n let unit: TimeUnit | null = null;\n\n if (unitStr) {\n // Check aliases first\n if (unitStr in TIME_ALIASES) {\n unit = TIME_ALIASES[unitStr] as TimeUnit;\n }\n // Check direct unit names\n else if (unitStr in TIME_UNITS) {\n unit = unitStr as TimeUnit;\n }\n // Check symbols\n else {\n for (const [u, config] of Object.entries(TIME_UNITS)) {\n if (config.symbol.toLowerCase() === unitStr) {\n unit = u as TimeUnit;\n break;\n }\n }\n }\n }\n\n return { value, unit };\n}\n","/**\n * Digital Storage Role - Constants\n *\n * Fatores de conversão, símbolos e aliases para unidades de armazenamento digital.\n *\n * Fontes:\n * - IEC 60027-2 (prefixos binários)\n * - SI Brochure, 9th Edition (2019)\n *\n * IMPORTANTE: Esta biblioteca suporta AMBOS os sistemas:\n * - SI (decimal): kB, MB, GB, TB (base 1000)\n * - IEC (binário): KiB, MiB, GiB, TiB (base 1024)\n */\n\nimport type { SimpleUnitConfig, UnitAliases } from \"../../contracts\";\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport type DigitalUnit =\n // Fundamental\n | \"bit\"\n | \"byte\"\n // IEC Binary (base 1024)\n | \"kibibyte\"\n | \"mebibyte\"\n | \"gibibyte\"\n | \"tebibyte\"\n | \"pebibyte\"\n | \"exbibyte\"\n // SI Decimal (base 1000)\n | \"kilobyte\"\n | \"megabyte\"\n | \"gigabyte\"\n | \"terabyte\"\n | \"petabyte\"\n | \"exabyte\";\n\n// =============================================================================\n// UNITS CONFIG\n// =============================================================================\n\n/**\n * Configuração de cada unidade de armazenamento digital.\n *\n * TODOS os fatores são EXATOS:\n * - IEC: potências de 2 (1024^n)\n * - SI: potências de 10 (1000^n)\n *\n * Convenção:\n * - byte é a BASE (fator = 1)\n * - bit = 1/8 byte (fator = 0.125)\n */\nexport const DIGITAL_UNITS: Record<DigitalUnit, SimpleUnitConfig> = {\n // Fundamental\n bit: {\n factor: 0.125, // 1/8 byte\n symbol: \"b\",\n singular: \"bit\",\n plural: \"bits\",\n },\n byte: {\n factor: 1,\n symbol: \"B\",\n singular: \"byte\",\n plural: \"bytes\",\n },\n\n // IEC Binary (base 1024) - RAM, cache, file systems\n kibibyte: {\n factor: 1024, // 2^10\n symbol: \"KiB\",\n singular: \"kibibyte\",\n plural: \"kibibytes\",\n },\n mebibyte: {\n factor: 1048576, // 2^20\n symbol: \"MiB\",\n singular: \"mebibyte\",\n plural: \"mebibytes\",\n },\n gibibyte: {\n factor: 1073741824, // 2^30\n symbol: \"GiB\",\n singular: \"gibibyte\",\n plural: \"gibibytes\",\n },\n tebibyte: {\n factor: 1099511627776, // 2^40\n symbol: \"TiB\",\n singular: \"tebibyte\",\n plural: \"tebibytes\",\n },\n pebibyte: {\n factor: 1125899906842624, // 2^50\n symbol: \"PiB\",\n singular: \"pebibyte\",\n plural: \"pebibytes\",\n },\n exbibyte: {\n factor: 1152921504606846976, // 2^60\n symbol: \"EiB\",\n singular: \"exbibyte\",\n plural: \"exbibytes\",\n },\n\n // SI Decimal (base 1000) - HD marketing, network speeds\n kilobyte: {\n factor: 1000, // 10^3\n symbol: \"kB\",\n singular: \"kilobyte\",\n plural: \"kilobytes\",\n },\n megabyte: {\n factor: 1000000, // 10^6\n symbol: \"MB\",\n singular: \"megabyte\",\n plural: \"megabytes\",\n },\n gigabyte: {\n factor: 1000000000, // 10^9\n symbol: \"GB\",\n singular: \"gigabyte\",\n plural: \"gigabytes\",\n },\n terabyte: {\n factor: 1000000000000, // 10^12\n symbol: \"TB\",\n singular: \"terabyte\",\n plural: \"terabytes\",\n },\n petabyte: {\n factor: 1000000000000000, // 10^15\n symbol: \"PB\",\n singular: \"petabyte\",\n plural: \"petabytes\",\n },\n exabyte: {\n factor: 1000000000000000000, // 10^18\n symbol: \"EB\",\n singular: \"exabyte\",\n plural: \"exabytes\",\n },\n};\n\n// =============================================================================\n// ALIASES\n// =============================================================================\n\n/**\n * Aliases para reconhecimento de unidades no cast\n */\nexport const DIGITAL_ALIASES: UnitAliases = {\n // bit\n b: \"bit\",\n // byte\n B: \"byte\",\n // kibibyte (IEC)\n KiB: \"kibibyte\",\n // mebibyte (IEC)\n MiB: \"mebibyte\",\n // gibibyte (IEC)\n GiB: \"gibibyte\",\n // tebibyte (IEC)\n TiB: \"tebibyte\",\n // pebibyte (IEC)\n PiB: \"pebibyte\",\n // exbibyte (IEC)\n EiB: \"exbibyte\",\n // kilobyte (SI)\n kB: \"kilobyte\",\n kb: \"kilobyte\",\n // megabyte (SI)\n MB: \"megabyte\",\n // gigabyte (SI)\n GB: \"gigabyte\",\n // terabyte (SI)\n TB: \"terabyte\",\n // petabyte (SI)\n PB: \"petabyte\",\n // exabyte (SI)\n EB: \"exabyte\",\n};\n\n// =============================================================================\n// HELPERS\n// =============================================================================\n\n/** Lista de todas as unidades */\nexport const DIGITAL_UNIT_LIST = Object.keys(DIGITAL_UNITS) as DigitalUnit[];\n\n/** Fatores de conversão (para compatibilidade) */\nexport const DIGITAL_FACTORS: Record<DigitalUnit, number> = Object.fromEntries(\n Object.entries(DIGITAL_UNITS).map(([unit, config]) => [\n unit,\n config.factor ?? 1,\n ]),\n) as Record<DigitalUnit, number>;\n","/**\n * Digital Role - Convert Pillar\n *\n * Conversão entre unidades de armazenamento digital usando hub-and-spoke (via byte).\n *\n * @example\n * import { convertDigital, toBaseDigital, fromBaseDigital } from '@attrx/role-morphic/digital/convert';\n *\n * convertDigital('kilobyte', 'byte', 1); // 1000\n * convertDigital('kibibyte', 'byte', 1); // 1024\n * toBaseDigital('megabyte', 1); // 1000000 (bytes)\n * fromBaseDigital('mebibyte', 1048576); // 1\n */\n\nimport { DIGITAL_UNITS, type DigitalUnit } from \"./constants\";\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport type Result<T> = { ok: true; value: T } | { ok: false; error: string };\n\n// =============================================================================\n// CONSTANTS\n// =============================================================================\n\n/** Unidade base para conversões (hub) */\nexport const DIGITAL_BASE: DigitalUnit = \"byte\";\n\n// =============================================================================\n// CORE CONVERSION\n// =============================================================================\n\n/**\n * Converte valor para a unidade base (byte)\n *\n * @param variant - Unidade de origem\n * @param value - Valor a converter\n * @returns Valor em bytes\n *\n * @example\n * toBaseDigital('kilobyte', 1); // 1000\n * toBaseDigital('kibibyte', 1); // 1024\n */\nexport function toBaseDigital(variant: DigitalUnit, value: number): number {\n const config = DIGITAL_UNITS[variant];\n if (!config) {\n throw new Error(`Unknown digital unit: ${variant}`);\n }\n return value * (config.factor ?? 1);\n}\n\n/**\n * Converte valor da unidade base (byte) para outra unidade\n *\n * @param variant - Unidade de destino\n * @param baseValue - Valor em bytes\n * @returns Valor na unidade de destino\n *\n * @example\n * fromBaseDigital('kilobyte', 1000); // 1\n * fromBaseDigital('kibibyte', 1024); // 1\n */\nexport function fromBaseDigital(variant: DigitalUnit, baseValue: number): number {\n const config = DIGITAL_UNITS[variant];\n if (!config) {\n throw new Error(`Unknown digital unit: ${variant}`);\n }\n return baseValue / (config.factor ?? 1);\n}\n\n/**\n * Converte entre duas unidades de armazenamento digital\n *\n * @param from - Unidade de origem\n * @param to - Unidade de destino\n * @param value - Valor a converter\n * @returns Valor convertido\n *\n * @example\n * convertDigital('kilobyte', 'byte', 1); // 1000\n * convertDigital('kibibyte', 'byte', 1); // 1024\n * convertDigital('gigabyte', 'gibibyte', 1); // ~0.931\n */\nexport function convertDigital(\n from: DigitalUnit,\n to: DigitalUnit,\n value: number,\n): number {\n if (from === to) {\n return value;\n }\n const baseValue = toBaseDigital(from, value);\n return fromBaseDigital(to, baseValue);\n}\n\n/**\n * Versão safe de convertDigital que retorna Result\n *\n * @example\n * tryConvertDigital('kilobyte', 'byte', 1); // { ok: true, value: 1000 }\n * tryConvertDigital('invalid', 'byte', 1); // { ok: false, error: '...' }\n */\nexport function tryConvertDigital(\n from: DigitalUnit,\n to: DigitalUnit,\n value: number,\n): Result<number> {\n try {\n return { ok: true, value: convertDigital(from, to, value) };\n } catch (e) {\n return { ok: false, error: (e as Error).message };\n }\n}\n\n// =============================================================================\n// HELPERS\n// =============================================================================\n\n/**\n * Verifica se uma variante existe\n *\n * @example\n * hasDigitalVariant('byte'); // true\n * hasDigitalVariant('invalid'); // false\n */\nexport function hasDigitalVariant(variant: string): variant is DigitalUnit {\n return variant in DIGITAL_UNITS;\n}\n\n/**\n * Retorna lista de todas as variantes disponíveis\n *\n * @example\n * getDigitalVariants(); // ['bit', 'byte', 'kibibyte', ...]\n */\nexport function getDigitalVariants(): DigitalUnit[] {\n return Object.keys(DIGITAL_UNITS) as DigitalUnit[];\n}\n","/**\n * Digital Role - Cast Pillar\n *\n * Normaliza input sujo para número, com detecção automática de unidade.\n *\n * @example\n * import { castDigital, castDigitalStrict, detectDigitalUnit } from '@attrx/role-morphic/digital/cast';\n *\n * castDigital('1 MB'); // 1000000 (converted to bytes)\n * castDigital('1 MB', 'megabyte'); // 1 (kept as megabytes)\n * castDigitalStrict('100'); // 100 (no conversion)\n * detectDigitalUnit('2 GiB'); // 'gibibyte'\n */\n\nimport { DIGITAL_UNITS, DIGITAL_ALIASES, type DigitalUnit } from \"./constants\";\nimport { convertDigital, DIGITAL_BASE } from \"./convert\";\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport type Result<T> = { ok: true; value: T } | { ok: false; error: string };\n\n// =============================================================================\n// CAST\n// =============================================================================\n\n/**\n * Faz cast de input para número, com conversão opcional para unidade alvo\n *\n * @param input - Valor de entrada (number, string, etc)\n * @param targetVariant - Unidade alvo (default: byte)\n * @returns Número ou null se não puder converter\n *\n * @example\n * castDigital('1 MB'); // 1000000 (bytes)\n * castDigital('1 MB', 'megabyte'); // 1\n * castDigital('100'); // 100\n * castDigital(100); // 100\n * castDigital('invalid'); // null\n */\nexport function castDigital(\n input: unknown,\n targetVariant: DigitalUnit = DIGITAL_BASE,\n): number | null {\n // Already a number\n if (typeof input === \"number\") {\n return Number.isFinite(input) ? input : null;\n }\n\n // String parsing\n if (typeof input === \"string\") {\n const parsed = parseDigitalString(input);\n if (parsed === null) {\n return null;\n }\n\n // If unit was detected and differs from target, convert\n if (parsed.unit && parsed.unit !== targetVariant) {\n return convertDigital(parsed.unit, targetVariant, parsed.value);\n }\n\n return parsed.value;\n }\n\n return null;\n}\n\n/**\n * Faz cast sem conversão (apenas parseia o número)\n *\n * @param input - Valor de entrada\n * @returns Número ou null\n *\n * @example\n * castDigitalStrict('100 MB'); // 100 (ignora a unidade)\n * castDigitalStrict('100'); // 100\n */\nexport function castDigitalStrict(input: unknown): number | null {\n if (typeof input === \"number\") {\n return Number.isFinite(input) ? input : null;\n }\n\n if (typeof input === \"string\") {\n const parsed = parseDigitalString(input);\n return parsed?.value ?? null;\n }\n\n return null;\n}\n\n/**\n * Versão safe de castDigital que retorna Result\n */\nexport function tryCastDigital(\n input: unknown,\n targetVariant: DigitalUnit = DIGITAL_BASE,\n): Result<number> {\n const result = castDigital(input, targetVariant);\n if (result === null) {\n return { ok: false, error: `Cannot cast \"${String(input)}\" to digital storage` };\n }\n return { ok: true, value: result };\n}\n\n// =============================================================================\n// DETECT UNIT\n// =============================================================================\n\n/**\n * Detecta a unidade de armazenamento digital de uma string\n *\n * @param input - String com valor e unidade\n * @returns Unidade detectada ou null\n *\n * @example\n * detectDigitalUnit('100 MB'); // 'megabyte'\n * detectDigitalUnit('2 GiB'); // 'gibibyte'\n * detectDigitalUnit('100'); // null\n */\nexport function detectDigitalUnit(input: string): DigitalUnit | null {\n const trimmed = input.trim();\n\n // Extract unit part (after the number)\n const match = trimmed.match(/^[+-]?[\\d.,\\s]+\\s*(.*)$/);\n if (!match || !match[1]) {\n return null;\n }\n\n const unitStr = match[1].trim();\n if (!unitStr) {\n return null;\n }\n\n const lowerUnitStr = unitStr.toLowerCase();\n\n // Check direct unit names\n if (lowerUnitStr in DIGITAL_UNITS) {\n return lowerUnitStr as DigitalUnit;\n }\n\n // Check aliases (case-sensitive for IEC units like KiB, MiB)\n if (unitStr in DIGITAL_ALIASES) {\n return DIGITAL_ALIASES[unitStr] as DigitalUnit;\n }\n if (lowerUnitStr in DIGITAL_ALIASES) {\n return DIGITAL_ALIASES[lowerUnitStr] as DigitalUnit;\n }\n\n // Check symbols\n for (const [unit, config] of Object.entries(DIGITAL_UNITS)) {\n if (config.symbol === unitStr || config.symbol.toLowerCase() === lowerUnitStr) {\n return unit as DigitalUnit;\n }\n }\n\n return null;\n}\n\n// =============================================================================\n// INTERNAL HELPERS\n// =============================================================================\n\ninterface ParsedDigital {\n value: number;\n unit: DigitalUnit | null;\n}\n\n/**\n * Parseia string de armazenamento digital extraindo valor e unidade\n */\nfunction parseDigitalString(input: string): ParsedDigital | null {\n const trimmed = input.trim();\n if (!trimmed) {\n return null;\n }\n\n // Try to extract number and unit\n const match = trimmed.match(/^([+-]?[\\d.,\\s]+)\\s*(.*)$/);\n if (!match) {\n return null;\n }\n\n const numStr = match[1].replace(/\\s/g, \"\").replace(\",\", \".\");\n const value = parseFloat(numStr);\n\n if (isNaN(value) || !Number.isFinite(value)) {\n return null;\n }\n\n const unitStr = match[2]?.trim() || \"\";\n const lowerUnitStr = unitStr.toLowerCase();\n let unit: DigitalUnit | null = null;\n\n if (unitStr) {\n // Check aliases (case-sensitive for IEC)\n if (unitStr in DIGITAL_ALIASES) {\n unit = DIGITAL_ALIASES[unitStr] as DigitalUnit;\n } else if (lowerUnitStr in DIGITAL_ALIASES) {\n unit = DIGITAL_ALIASES[lowerUnitStr] as DigitalUnit;\n }\n // Check direct unit names\n else if (lowerUnitStr in DIGITAL_UNITS) {\n unit = lowerUnitStr as DigitalUnit;\n }\n // Check symbols\n else {\n for (const [u, config] of Object.entries(DIGITAL_UNITS)) {\n if (config.symbol === unitStr || config.symbol.toLowerCase() === lowerUnitStr) {\n unit = u as DigitalUnit;\n break;\n }\n }\n }\n }\n\n return { value, unit };\n}\n","/**\n * Color Role - Types\n *\n * Tipos para representação de cores nas diferentes variantes.\n */\n\n// =============================================================================\n// BASE TYPE\n// =============================================================================\n\n/**\n * Tipo base para Color: objeto RGBA com valores 0-255 e alpha 0-1\n *\n * @example\n * const red: RGBA = { r: 255, g: 0, b: 0, a: 1 };\n * const semiTransparent: RGBA = { r: 0, g: 0, b: 255, a: 0.5 };\n */\nexport interface RGBA {\n r: number; // 0-255\n g: number; // 0-255\n b: number; // 0-255\n a: number; // 0-1\n}\n\n// =============================================================================\n// VARIANT TYPES\n// =============================================================================\n\n/**\n * Variante Hex\n *\n * @example\n * \"#ff0000\" // RGB (6 chars)\n * \"#ff0000ff\" // RGBA (8 chars)\n * \"#f00\" // RGB shorthand (3 chars)\n * \"#f00f\" // RGBA shorthand (4 chars)\n */\nexport type ColorHex = string;\n\n/**\n * Variante RGB Object\n *\n * @example\n * { r: 255, g: 0, b: 0 }\n * { r: 255, g: 0, b: 0, a: 0.5 }\n */\nexport interface ColorRgbObject {\n r: number;\n g: number;\n b: number;\n a?: number;\n}\n\n/**\n * Variante RGB String\n *\n * @example\n * \"rgb(255, 0, 0)\"\n * \"rgba(255, 0, 0, 0.5)\"\n */\nexport type ColorRgbString = string;\n\n/**\n * Variante HSL Object\n *\n * @example\n * { h: 0, s: 100, l: 50 } // Red\n * { h: 0, s: 100, l: 50, a: 0.5 } // Semi-transparent red\n */\nexport interface ColorHslObject {\n h: number; // 0-360\n s: number; // 0-100\n l: number; // 0-100\n a?: number; // 0-1\n}\n\n/**\n * Variante HSL String\n *\n * @example\n * \"hsl(0, 100%, 50%)\"\n * \"hsla(0, 100%, 50%, 0.5)\"\n */\nexport type ColorHslString = string;\n\n// =============================================================================\n// VARIANT NAMES\n// =============================================================================\n\nexport type ColorVariant =\n | \"hex\"\n | \"rgb_object\"\n | \"rgb_string\"\n | \"hsl_object\"\n | \"hsl_string\";\n\n// =============================================================================\n// FORMAT OPTIONS\n// =============================================================================\n\nimport type { BaseFormatOptions } from \"../../types\";\n\nexport interface ColorFormatOptions extends BaseFormatOptions {\n /** Se true, usa letras maiúsculas para hex */\n uppercase?: boolean;\n\n /** Se true, inclui alpha mesmo quando é 1 */\n includeAlpha?: boolean;\n\n /** Se true, usa formato compacto (shorthand hex, sem espaços em rgb) */\n compact?: boolean;\n}\n\n// =============================================================================\n// NAMED COLORS\n// =============================================================================\n\n/**\n * CSS Named Colors mais comuns\n */\nexport const NAMED_COLORS: Record<string, RGBA> = {\n // Basic colors\n black: { r: 0, g: 0, b: 0, a: 1 },\n white: { r: 255, g: 255, b: 255, a: 1 },\n red: { r: 255, g: 0, b: 0, a: 1 },\n green: { r: 0, g: 128, b: 0, a: 1 },\n blue: { r: 0, g: 0, b: 255, a: 1 },\n yellow: { r: 255, g: 255, b: 0, a: 1 },\n cyan: { r: 0, g: 255, b: 255, a: 1 },\n magenta: { r: 255, g: 0, b: 255, a: 1 },\n\n // Extended colors\n orange: { r: 255, g: 165, b: 0, a: 1 },\n purple: { r: 128, g: 0, b: 128, a: 1 },\n pink: { r: 255, g: 192, b: 203, a: 1 },\n brown: { r: 165, g: 42, b: 42, a: 1 },\n gray: { r: 128, g: 128, b: 128, a: 1 },\n grey: { r: 128, g: 128, b: 128, a: 1 },\n\n // Web colors\n lime: { r: 0, g: 255, b: 0, a: 1 },\n aqua: { r: 0, g: 255, b: 255, a: 1 },\n fuchsia: { r: 255, g: 0, b: 255, a: 1 },\n silver: { r: 192, g: 192, b: 192, a: 1 },\n maroon: { r: 128, g: 0, b: 0, a: 1 },\n olive: { r: 128, g: 128, b: 0, a: 1 },\n navy: { r: 0, g: 0, b: 128, a: 1 },\n teal: { r: 0, g: 128, b: 128, a: 1 },\n\n // Transparent\n transparent: { r: 0, g: 0, b: 0, a: 0 },\n};\n\n// =============================================================================\n// HELPER FUNCTIONS\n// =============================================================================\n\n/**\n * Clamp um valor entre min e max\n */\nexport function clamp(value: number, min: number, max: number): number {\n return Math.min(Math.max(value, min), max);\n}\n\n/**\n * Normaliza um canal RGB para 0-255\n */\nexport function normalizeRgbChannel(value: number): number {\n return clamp(Math.round(value), 0, 255);\n}\n\n/**\n * Normaliza alpha para 0-1\n */\nexport function normalizeAlpha(value: number | undefined): number {\n if (value === undefined) return 1;\n return clamp(value, 0, 1);\n}\n\n/**\n * Converte RGB para HSL\n */\nexport function rgbToHsl(\n r: number,\n g: number,\n b: number,\n): { h: number; s: number; l: number } {\n r /= 255;\n g /= 255;\n b /= 255;\n\n const max = Math.max(r, g, b);\n const min = Math.min(r, g, b);\n const l = (max + min) / 2;\n\n if (max === min) {\n return { h: 0, s: 0, l: l * 100 };\n }\n\n const d = max - min;\n const s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\n\n let h: number;\n switch (max) {\n case r:\n h = ((g - b) / d + (g < b ? 6 : 0)) / 6;\n break;\n case g:\n h = ((b - r) / d + 2) / 6;\n break;\n default:\n h = ((r - g) / d + 4) / 6;\n break;\n }\n\n return {\n h: Math.round(h * 360),\n s: Math.round(s * 100),\n l: Math.round(l * 100),\n };\n}\n\n/**\n * Converte HSL para RGB\n */\nexport function hslToRgb(\n h: number,\n s: number,\n l: number,\n): { r: number; g: number; b: number } {\n h /= 360;\n s /= 100;\n l /= 100;\n\n if (s === 0) {\n const gray = Math.round(l * 255);\n return { r: gray, g: gray, b: gray };\n }\n\n const hue2rgb = (p: number, q: number, t: number): number => {\n if (t < 0) t += 1;\n if (t > 1) t -= 1;\n if (t < 1 / 6) return p + (q - p) * 6 * t;\n if (t < 1 / 2) return q;\n if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;\n return p;\n };\n\n const q = l < 0.5 ? l * (1 + s) : l + s - l * s;\n const p = 2 * l - q;\n\n return {\n r: Math.round(hue2rgb(p, q, h + 1 / 3) * 255),\n g: Math.round(hue2rgb(p, q, h) * 255),\n b: Math.round(hue2rgb(p, q, h - 1 / 3) * 255),\n };\n}\n","/**\n * Color Role - Convert Pillar\n *\n * Conversão entre variantes de cor usando hub-and-spoke (via rgb_object/RGBA).\n *\n * @example\n * import { convertColor, hexToRgba, rgbaToHex } from '@attrx/role-morphic/color/convert';\n *\n * convertColor('hex', 'rgb_object', '#ff0000'); // { r: 255, g: 0, b: 0, a: 1 }\n * convertColor('rgb_object', 'hsl_string', { r: 255, g: 0, b: 0 }); // \"hsl(0, 100%, 50%)\"\n */\n\nimport type { ColorVariant, RGBA, ColorRgbObject, ColorHslObject } from \"./types\";\nimport { rgbToHsl, hslToRgb, normalizeAlpha, normalizeRgbChannel, clamp } from \"./types\";\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport type Result<T> = { ok: true; value: T } | { ok: false; error: string };\n\n// =============================================================================\n// CONSTANTS\n// =============================================================================\n\nexport const COLOR_BASE: ColorVariant = \"rgb_object\";\n\nexport const COLOR_VARIANTS: ColorVariant[] = [\n \"hex\",\n \"rgb_object\",\n \"rgb_string\",\n \"hsl_object\",\n \"hsl_string\",\n];\n\n// =============================================================================\n// TO BASE (→ RGBA)\n// =============================================================================\n\n/**\n * Converte hex para RGBA\n */\nexport function hexToRgba(hex: string): RGBA {\n let h = hex.trim();\n if (h.startsWith(\"#\")) h = h.slice(1);\n\n let r: number, g: number, b: number, a: number;\n\n if (h.length === 3) {\n r = parseInt(h[0] + h[0], 16);\n g = parseInt(h[1] + h[1], 16);\n b = parseInt(h[2] + h[2], 16);\n a = 1;\n } else if (h.length === 4) {\n r = parseInt(h[0] + h[0], 16);\n g = parseInt(h[1] + h[1], 16);\n b = parseInt(h[2] + h[2], 16);\n a = parseInt(h[3] + h[3], 16) / 255;\n } else if (h.length === 6) {\n r = parseInt(h.slice(0, 2), 16);\n g = parseInt(h.slice(2, 4), 16);\n b = parseInt(h.slice(4, 6), 16);\n a = 1;\n } else if (h.length === 8) {\n r = parseInt(h.slice(0, 2), 16);\n g = parseInt(h.slice(2, 4), 16);\n b = parseInt(h.slice(4, 6), 16);\n a = parseInt(h.slice(6, 8), 16) / 255;\n } else {\n throw new Error(`Invalid hex color: ${hex}`);\n }\n\n return { r, g, b, a };\n}\n\n/**\n * Converte RGB object para RGBA\n */\nexport function rgbObjectToRgba(rgb: ColorRgbObject): RGBA {\n return {\n r: normalizeRgbChannel(rgb.r),\n g: normalizeRgbChannel(rgb.g),\n b: normalizeRgbChannel(rgb.b),\n a: normalizeAlpha(rgb.a),\n };\n}\n\n/**\n * Converte RGB string para RGBA\n */\nexport function rgbStringToRgba(rgb: string): RGBA {\n const match = rgb.match(/rgba?\\s*\\(\\s*([\\d.]+)\\s*,\\s*([\\d.]+)\\s*,\\s*([\\d.]+)\\s*(?:,\\s*([\\d.]+)\\s*)?\\)/i);\n if (!match) {\n throw new Error(`Invalid RGB string: ${rgb}`);\n }\n\n return {\n r: normalizeRgbChannel(parseFloat(match[1])),\n g: normalizeRgbChannel(parseFloat(match[2])),\n b: normalizeRgbChannel(parseFloat(match[3])),\n a: match[4] !== undefined ? normalizeAlpha(parseFloat(match[4])) : 1,\n };\n}\n\n/**\n * Converte HSL object para RGBA\n */\nexport function hslObjectToRgba(hsl: ColorHslObject): RGBA {\n const { r, g, b } = hslToRgb(hsl.h, hsl.s, hsl.l);\n return {\n r,\n g,\n b,\n a: normalizeAlpha(hsl.a),\n };\n}\n\n/**\n * Converte HSL string para RGBA\n */\nexport function hslStringToRgba(hsl: string): RGBA {\n const match = hsl.match(/hsla?\\s*\\(\\s*([\\d.]+)\\s*,\\s*([\\d.]+)%?\\s*,\\s*([\\d.]+)%?\\s*(?:,\\s*([\\d.]+)\\s*)?\\)/i);\n if (!match) {\n throw new Error(`Invalid HSL string: ${hsl}`);\n }\n\n const h = parseFloat(match[1]);\n const s = parseFloat(match[2]);\n const l = parseFloat(match[3]);\n const a = match[4] !== undefined ? parseFloat(match[4]) : 1;\n\n const { r, g, b } = hslToRgb(h, s, l);\n return { r, g, b, a: normalizeAlpha(a) };\n}\n\n/**\n * Converte qualquer variante para RGBA (base)\n */\nexport function toBaseColor(variant: ColorVariant, value: unknown): RGBA {\n switch (variant) {\n case \"hex\":\n return hexToRgba(value as string);\n case \"rgb_object\":\n return rgbObjectToRgba(value as ColorRgbObject);\n case \"rgb_string\":\n return rgbStringToRgba(value as string);\n case \"hsl_object\":\n return hslObjectToRgba(value as ColorHslObject);\n case \"hsl_string\":\n return hslStringToRgba(value as string);\n default:\n throw new Error(`Unknown color variant: ${variant}`);\n }\n}\n\n// =============================================================================\n// FROM BASE (RGBA →)\n// =============================================================================\n\n/**\n * Converte RGBA para hex\n */\nexport function rgbaToHex(rgba: RGBA, includeAlpha = false): string {\n const r = rgba.r.toString(16).padStart(2, \"0\");\n const g = rgba.g.toString(16).padStart(2, \"0\");\n const b = rgba.b.toString(16).padStart(2, \"0\");\n\n if (includeAlpha || rgba.a < 1) {\n const a = Math.round(rgba.a * 255)\n .toString(16)\n .padStart(2, \"0\");\n return `#${r}${g}${b}${a}`;\n }\n\n return `#${r}${g}${b}`;\n}\n\n/**\n * Converte RGBA para RGB object\n */\nexport function rgbaToRgbObject(rgba: RGBA): ColorRgbObject {\n if (rgba.a < 1) {\n return { r: rgba.r, g: rgba.g, b: rgba.b, a: rgba.a };\n }\n return { r: rgba.r, g: rgba.g, b: rgba.b };\n}\n\n/**\n * Converte RGBA para RGB string\n */\nexport function rgbaToRgbString(rgba: RGBA): string {\n if (rgba.a < 1) {\n return `rgba(${rgba.r}, ${rgba.g}, ${rgba.b}, ${rgba.a})`;\n }\n return `rgb(${rgba.r}, ${rgba.g}, ${rgba.b})`;\n}\n\n/**\n * Converte RGBA para HSL object\n */\nexport function rgbaToHslObject(rgba: RGBA): ColorHslObject {\n const { h, s, l } = rgbToHsl(rgba.r, rgba.g, rgba.b);\n if (rgba.a < 1) {\n return { h, s, l, a: rgba.a };\n }\n return { h, s, l };\n}\n\n/**\n * Converte RGBA para HSL string\n */\nexport function rgbaToHslString(rgba: RGBA): string {\n const { h, s, l } = rgbToHsl(rgba.r, rgba.g, rgba.b);\n if (rgba.a < 1) {\n return `hsla(${h}, ${s}%, ${l}%, ${rgba.a})`;\n }\n return `hsl(${h}, ${s}%, ${l}%)`;\n}\n\n/**\n * Converte RGBA (base) para qualquer variante\n */\nexport function fromBaseColor(variant: ColorVariant, rgba: RGBA): unknown {\n switch (variant) {\n case \"hex\":\n return rgbaToHex(rgba);\n case \"rgb_object\":\n return rgbaToRgbObject(rgba);\n case \"rgb_string\":\n return rgbaToRgbString(rgba);\n case \"hsl_object\":\n return rgbaToHslObject(rgba);\n case \"hsl_string\":\n return rgbaToHslString(rgba);\n default:\n throw new Error(`Unknown color variant: ${variant}`);\n }\n}\n\n// =============================================================================\n// CONVERT\n// =============================================================================\n\n/**\n * Converte entre duas variantes de cor\n *\n * @param from - Variante de origem\n * @param to - Variante de destino\n * @param value - Valor a converter\n * @returns Valor convertido\n *\n * @example\n * convertColor('hex', 'rgb_object', '#ff0000');\n * // { r: 255, g: 0, b: 0 }\n */\nexport function convertColor<TFrom = unknown, TTo = unknown>(\n from: ColorVariant,\n to: ColorVariant,\n value: TFrom,\n): TTo {\n // Otimização: mesma variante\n if (from === to) {\n return value as unknown as TTo;\n }\n\n // Converte via base (RGBA)\n const rgba = toBaseColor(from, value);\n return fromBaseColor(to, rgba) as TTo;\n}\n\n/**\n * Versão safe de convertColor que retorna Result\n */\nexport function tryConvertColor<TFrom = unknown, TTo = unknown>(\n from: ColorVariant,\n to: ColorVariant,\n value: TFrom,\n): Result<TTo> {\n try {\n const result = convertColor<TFrom, TTo>(from, to, value);\n return { ok: true, value: result };\n } catch (error) {\n return {\n ok: false,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n}\n\n/**\n * Verifica se variante existe\n */\nexport function hasColorVariant(variant: string): variant is ColorVariant {\n return COLOR_VARIANTS.includes(variant as ColorVariant);\n}\n\n/**\n * Retorna lista de variantes\n */\nexport function getColorVariants(): ColorVariant[] {\n return [...COLOR_VARIANTS];\n}\n","/**\n * Color Role - Cast Pillar\n *\n * Normaliza input sujo para uma variante de cor específica.\n *\n * @example\n * import { castColor, tryCastColor, detectColorFormat } from '@attrx/role-morphic/color/cast';\n *\n * castColor('hex', 'red'); // '#ff0000'\n * castColor('rgb_object', '#ff0000'); // { r: 255, g: 0, b: 0 }\n * castColor('hsl_string', { r: 255, g: 0, b: 0 }); // 'hsl(0, 100%, 50%)'\n */\n\nimport type { ColorVariant, RGBA, ColorRgbObject, ColorHslObject } from \"./types\";\nimport { NAMED_COLORS } from \"./types\";\nimport {\n toBaseColor,\n fromBaseColor,\n hexToRgba,\n rgbObjectToRgba,\n rgbStringToRgba,\n hslObjectToRgba,\n hslStringToRgba,\n} from \"./convert\";\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport type Result<T> = { ok: true; value: T } | { ok: false; error: string };\n\n// =============================================================================\n// DETECT FORMAT\n// =============================================================================\n\n/**\n * Detecta o formato de uma string de cor\n *\n * @example\n * detectColorFormat('red'); // 'named'\n * detectColorFormat('#ff0000'); // 'hex'\n * detectColorFormat('rgb(255,0,0)'); // 'rgb_string'\n * detectColorFormat('hsl(0,100%,50%)'); // 'hsl_string'\n */\nexport function detectColorFormat(\n value: string,\n): \"hex\" | \"rgb_string\" | \"hsl_string\" | \"named\" | null {\n const trimmed = value.trim().toLowerCase();\n\n // Named color\n if (NAMED_COLORS[trimmed]) {\n return \"named\";\n }\n\n // Hex\n if (/^#?[0-9a-f]{3,8}$/i.test(trimmed)) {\n return \"hex\";\n }\n\n // RGB string\n if (/^rgba?\\s*\\(/i.test(trimmed)) {\n return \"rgb_string\";\n }\n\n // HSL string\n if (/^hsla?\\s*\\(/i.test(trimmed)) {\n return \"hsl_string\";\n }\n\n return null;\n}\n\n/**\n * Detecta se um objeto é RGB ou HSL\n */\nfunction detectObjectFormat(obj: Record<string, unknown>): \"rgb_object\" | \"hsl_object\" | null {\n if (typeof obj.r === \"number\" && typeof obj.g === \"number\" && typeof obj.b === \"number\") {\n return \"rgb_object\";\n }\n if (typeof obj.h === \"number\" && typeof obj.s === \"number\" && typeof obj.l === \"number\") {\n return \"hsl_object\";\n }\n return null;\n}\n\n// =============================================================================\n// PARSE INPUT\n// =============================================================================\n\n/**\n * Tenta parsear qualquer input para RGBA\n */\nfunction parseToRgba(input: unknown): RGBA | null {\n // Já é RGBA\n if (\n typeof input === \"object\" &&\n input !== null &&\n \"r\" in input &&\n \"g\" in input &&\n \"b\" in input &&\n \"a\" in input\n ) {\n const rgba = input as RGBA;\n if (\n typeof rgba.r === \"number\" &&\n typeof rgba.g === \"number\" &&\n typeof rgba.b === \"number\" &&\n typeof rgba.a === \"number\"\n ) {\n return rgba;\n }\n }\n\n // String\n if (typeof input === \"string\") {\n const trimmed = input.trim();\n\n // Named color\n const namedColor = NAMED_COLORS[trimmed.toLowerCase()];\n if (namedColor) {\n return namedColor;\n }\n\n // Hex\n if (/^#?[0-9a-f]{3,8}$/i.test(trimmed)) {\n try {\n return hexToRgba(trimmed);\n } catch {\n return null;\n }\n }\n\n // RGB string\n if (/^rgba?\\s*\\(/i.test(trimmed)) {\n try {\n return rgbStringToRgba(trimmed);\n } catch {\n return null;\n }\n }\n\n // HSL string\n if (/^hsla?\\s*\\(/i.test(trimmed)) {\n try {\n return hslStringToRgba(trimmed);\n } catch {\n return null;\n }\n }\n\n return null;\n }\n\n // Object\n if (typeof input === \"object\" && input !== null) {\n const format = detectObjectFormat(input as Record<string, unknown>);\n\n if (format === \"rgb_object\") {\n try {\n return rgbObjectToRgba(input as ColorRgbObject);\n } catch {\n return null;\n }\n }\n\n if (format === \"hsl_object\") {\n try {\n return hslObjectToRgba(input as ColorHslObject);\n } catch {\n return null;\n }\n }\n }\n\n return null;\n}\n\n// =============================================================================\n// CAST\n// =============================================================================\n\n/**\n * Faz cast de qualquer input para uma variante de cor\n *\n * @param variant - Variante de destino\n * @param input - Valor de entrada (string, object, etc)\n * @returns Valor na variante de destino ou null se não puder converter\n *\n * @example\n * castColor('hex', 'red'); // '#ff0000'\n * castColor('rgb_object', '#ff0000'); // { r: 255, g: 0, b: 0 }\n * castColor('hsl_string', { r: 255, g: 0, b: 0 }); // 'hsl(0, 100%, 50%)'\n * castColor('hex', 'invalid'); // null\n */\nexport function castColor<T = unknown>(variant: ColorVariant, input: unknown): T | null {\n const rgba = parseToRgba(input);\n if (!rgba) {\n return null;\n }\n\n try {\n return fromBaseColor(variant, rgba) as T;\n } catch {\n return null;\n }\n}\n\n/**\n * Versão safe de castColor que retorna Result\n */\nexport function tryCastColor<T = unknown>(\n variant: ColorVariant,\n input: unknown,\n): Result<T> {\n const result = castColor<T>(variant, input);\n if (result === null) {\n return {\n ok: false,\n error: `Cannot cast \"${String(input)}\" to color variant \"${variant}\"`,\n };\n }\n return { ok: true, value: result };\n}\n\n// =============================================================================\n// CONVENIENCE FUNCTIONS\n// =============================================================================\n\n/**\n * Converte hex para RGB object\n */\nexport function hexToRgb(hex: string): ColorRgbObject | null {\n return castColor<ColorRgbObject>(\"rgb_object\", hex);\n}\n\n/**\n * Converte RGB object para hex\n */\nexport function rgbToHex(rgb: ColorRgbObject): string | null {\n return castColor<string>(\"hex\", rgb);\n}\n\n/**\n * Converte hex para HSL object\n */\nexport function hexToHsl(hex: string): ColorHslObject | null {\n return castColor<ColorHslObject>(\"hsl_object\", hex);\n}\n\n/**\n * Converte HSL object para hex\n */\nexport function hslToHex(hsl: ColorHslObject): string | null {\n return castColor<string>(\"hex\", hsl);\n}\n\n/**\n * Converte RGB string para hex\n */\nexport function rgbStringToHex(rgb: string): string | null {\n return castColor<string>(\"hex\", rgb);\n}\n\n/**\n * Converte hex para RGB string\n */\nexport function hexToRgbString(hex: string): string | null {\n return castColor<string>(\"rgb_string\", hex);\n}\n\n/**\n * Converte HSL string para hex\n */\nexport function hslStringToHex(hsl: string): string | null {\n return castColor<string>(\"hex\", hsl);\n}\n\n/**\n * Converte hex para HSL string\n */\nexport function hexToHslString(hex: string): string | null {\n return castColor<string>(\"hsl_string\", hex);\n}\n\n/**\n * Verifica se uma string é uma cor válida (qualquer formato)\n */\nexport function isColorString(value: string): boolean {\n return parseToRgba(value) !== null;\n}\n\n/**\n * Alias para isColorString - verifica se valor é uma cor válida\n * (Mantido para compatibilidade com API anterior)\n */\nexport function isValidColor(value: string): boolean {\n return isColorString(value);\n}\n","/**\n * Date Role - Cast Pillar\n *\n * Normaliza input sujo para o tipo esperado de cada variante.\n *\n * @example\n * import { castDate, castIso, castTimestamp, castEpoch } from '@attrx/role-morphic/date/cast';\n *\n * castDate('iso', '2024-12-05'); // '2024-12-05T00:00:00.000Z'\n * castDate('timestamp', '2024-12-05'); // 1733356800000\n * castDate('epoch', new Date()); // 1733425800\n */\n\nimport type { DateVariant, DateIso, DateTimestamp, DateEpoch } from \"./types\";\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport type Result<T> = { ok: true; value: T } | { ok: false; error: string };\n\n// =============================================================================\n// CAST ISO\n// =============================================================================\n\n/**\n * Faz cast de input para ISO string\n *\n * @example\n * castIso('2024-12-05'); // '2024-12-05T00:00:00.000Z'\n * castIso(1733425800000); // '2024-12-05T19:30:00.000Z'\n * castIso(new Date()); // ISO string da data atual\n */\nexport function castIso(input: unknown): DateIso | null {\n // Já é string\n if (typeof input === \"string\") {\n const trimmed = input.trim();\n const date = new Date(trimmed);\n if (!isNaN(date.getTime())) {\n return date.toISOString();\n }\n return null;\n }\n\n // Número (timestamp)\n if (typeof input === \"number\") {\n if (!Number.isFinite(input)) return null;\n const date = new Date(input);\n if (!isNaN(date.getTime())) {\n return date.toISOString();\n }\n return null;\n }\n\n // Date object\n if (input instanceof Date) {\n if (isNaN(input.getTime())) return null;\n return input.toISOString();\n }\n\n return null;\n}\n\n// =============================================================================\n// CAST TIMESTAMP\n// =============================================================================\n\n/**\n * Faz cast de input para timestamp (milissegundos)\n *\n * @example\n * castTimestamp('2024-12-05T19:30:00.000Z'); // 1733425800000\n * castTimestamp('1733425800000'); // 1733425800000\n * castTimestamp(new Date()); // timestamp atual\n */\nexport function castTimestamp(input: unknown): DateTimestamp | null {\n // Já é número\n if (typeof input === \"number\") {\n if (!Number.isFinite(input)) return null;\n return input;\n }\n\n // String\n if (typeof input === \"string\") {\n const trimmed = input.trim();\n\n // String numérica pura\n if (/^-?\\d+$/.test(trimmed)) {\n const num = parseInt(trimmed, 10);\n if (Number.isFinite(num)) return num;\n }\n\n // Tenta parsear como ISO date\n const date = new Date(trimmed);\n if (!isNaN(date.getTime())) {\n return date.getTime();\n }\n\n return null;\n }\n\n // Date object\n if (input instanceof Date) {\n const ts = input.getTime();\n return isNaN(ts) ? null : ts;\n }\n\n return null;\n}\n\n// =============================================================================\n// CAST EPOCH\n// =============================================================================\n\n/**\n * Faz cast de input para epoch (segundos)\n *\n * Detecta automaticamente se o input é milissegundos (> 1e11) e converte.\n *\n * @example\n * castEpoch('2024-12-05T19:30:00.000Z'); // 1733425800\n * castEpoch(1733425800000); // 1733425800 (detecta ms)\n * castEpoch(1733425800); // 1733425800\n * castEpoch(new Date()); // epoch atual\n */\nexport function castEpoch(input: unknown): DateEpoch | null {\n // Já é número\n if (typeof input === \"number\") {\n if (!Number.isFinite(input)) return null;\n // Se parece ser milissegundos (> 1e11), converte para segundos\n if (Math.abs(input) > 1e11) {\n return Math.floor(input / 1000);\n }\n return Math.floor(input);\n }\n\n // String\n if (typeof input === \"string\") {\n const trimmed = input.trim();\n\n // String numérica pura\n if (/^-?\\d+$/.test(trimmed)) {\n const num = parseInt(trimmed, 10);\n if (Number.isFinite(num)) {\n // Se parece ser milissegundos (> 1e11), converte para segundos\n if (Math.abs(num) > 1e11) {\n return Math.floor(num / 1000);\n }\n return num;\n }\n }\n\n // Tenta parsear como ISO date e converter\n const date = new Date(trimmed);\n if (!isNaN(date.getTime())) {\n return Math.floor(date.getTime() / 1000);\n }\n\n return null;\n }\n\n // Date object\n if (input instanceof Date) {\n const ts = input.getTime();\n return isNaN(ts) ? null : Math.floor(ts / 1000);\n }\n\n return null;\n}\n\n// =============================================================================\n// MAIN CAST\n// =============================================================================\n\n/**\n * Faz cast de input para uma variante de data\n *\n * @param variant - Variante de destino (\"iso\", \"timestamp\", \"epoch\")\n * @param input - Valor de entrada\n * @returns Valor convertido ou null se não for possível\n *\n * @example\n * castDate('iso', '2024-12-05'); // '2024-12-05T00:00:00.000Z'\n * castDate('timestamp', new Date()); // timestamp atual\n * castDate('epoch', '2024-12-05'); // 1733356800\n */\nexport function castDate<T = unknown>(variant: DateVariant, input: unknown): T | null {\n switch (variant) {\n case \"iso\":\n return castIso(input) as T | null;\n case \"timestamp\":\n return castTimestamp(input) as T | null;\n case \"epoch\":\n return castEpoch(input) as T | null;\n default:\n return null;\n }\n}\n\n/**\n * Versão safe de castDate que retorna Result\n */\nexport function tryCastDate<T = unknown>(\n variant: DateVariant,\n input: unknown\n): Result<T> {\n const result = castDate<T>(variant, input);\n if (result === null) {\n return {\n ok: false,\n error: `Cannot cast \"${String(input)}\" to date variant \"${variant}\"`,\n };\n }\n return { ok: true, value: result };\n}\n\n/**\n * Detecta se um valor parece ser um timestamp em milissegundos ou segundos\n *\n * @returns \"timestamp\" se > 1e11, \"epoch\" caso contrário, null se não for número\n */\nexport function detectDateNumericVariant(value: unknown): \"timestamp\" | \"epoch\" | null {\n if (typeof value !== \"number\" || !Number.isFinite(value)) {\n return null;\n }\n\n // Timestamps em ms geralmente são > 1e12 (após ano 2001)\n // Epochs em segundos são tipicamente < 1e11\n return Math.abs(value) > 1e11 ? \"timestamp\" : \"epoch\";\n}\n","/**\n * Currency Role - Cast Pillar\n *\n * Normaliza input monetário sujo para número.\n * Extrai o valor numérico de strings formatadas como moeda.\n *\n * NÃO infere a moeda - apenas extrai o valor numérico.\n * A moeda deve ser conhecida via metadata.\n *\n * @example\n * import { castCurrency, castCurrencyStrict } from '@attrx/role-morphic/currency/cast';\n *\n * castCurrency('R$ 1.500,50'); // 1500.50\n * castCurrency('$1,000.00'); // 1000\n * castCurrency('€ 99,99'); // 99.99\n * castCurrency('1500'); // 1500\n * castCurrency(1500.50); // 1500.50\n */\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport type Result<T> =\n | { ok: true; value: T }\n | { ok: false; error: string };\n\n// =============================================================================\n// CAST\n// =============================================================================\n\n/**\n * Faz cast de input monetário para número\n *\n * Suporta diversos formatos:\n * - Brasileiro: R$ 1.500,50\n * - Americano: $1,000.00\n * - Europeu: € 99,99 ou 99,99 €\n * - Sem símbolo: 1500.50 ou 1500,50\n *\n * @param input - Valor de entrada (number, string, etc)\n * @returns Número ou null se não puder converter\n *\n * @example\n * castCurrency('R$ 1.500,50'); // 1500.50\n * castCurrency('$1,000.00'); // 1000\n * castCurrency('€ 99,99'); // 99.99\n * castCurrency('1.500,50'); // 1500.50 (brasileiro)\n * castCurrency('1,500.50'); // 1500.50 (americano)\n * castCurrency('-R$ 50,00'); // -50\n * castCurrency('invalid'); // null\n */\nexport function castCurrency(input: unknown): number | null {\n // Já é número\n if (typeof input === \"number\") {\n return Number.isFinite(input) ? input : null;\n }\n\n // String\n if (typeof input === \"string\") {\n return parseCurrencyString(input);\n }\n\n return null;\n}\n\n/**\n * Alias para castCurrency (currency não tem conversão, então strict é igual)\n */\nexport function castCurrencyStrict(input: unknown): number | null {\n return castCurrency(input);\n}\n\n/**\n * Versão safe de castCurrency que retorna Result\n */\nexport function tryCastCurrency(input: unknown): Result<number> {\n const result = castCurrency(input);\n if (result === null) {\n return {\n ok: false,\n error: `Cannot cast \"${String(input)}\" to currency value`,\n };\n }\n return { ok: true, value: result };\n}\n\n// =============================================================================\n// INTERNAL HELPERS\n// =============================================================================\n\n/**\n * Símbolos de moeda conhecidos (para remoção no parse)\n */\nconst CURRENCY_SYMBOL_REGEX = /^[\\s]*([A-Z]{1,3}\\$?|[R$€£¥₹₩₽₺CHF]+)[\\s]*/i;\nconst CURRENCY_SYMBOL_SUFFIX_REGEX = /[\\s]*([€₽])[\\s]*$/;\n\n/**\n * Parseia string monetária para número\n */\nfunction parseCurrencyString(input: string): number | null {\n let str = input.trim();\n\n if (!str) {\n return null;\n }\n\n // Detecta sinal negativo (pode estar antes do símbolo)\n let isNegative = false;\n if (str.startsWith(\"-\")) {\n isNegative = true;\n str = str.slice(1).trim();\n } else if (str.startsWith(\"(\") && str.endsWith(\")\")) {\n // Formato contábil: (1,000.00) = -1000\n isNegative = true;\n str = str.slice(1, -1).trim();\n }\n\n // Remove símbolo de moeda do início\n str = str.replace(CURRENCY_SYMBOL_REGEX, \"\");\n\n // Remove símbolo de moeda do final (ex: 100 €)\n str = str.replace(CURRENCY_SYMBOL_SUFFIX_REGEX, \"\");\n\n str = str.trim();\n\n if (!str) {\n return null;\n }\n\n // Parseia o número\n const numValue = parseNumber(str);\n\n if (numValue === null) {\n return null;\n }\n\n return isNegative ? -numValue : numValue;\n}\n\n/**\n * Parseia string numérica considerando formatos brasileiro e americano\n *\n * Detecta automaticamente o formato baseado nos separadores:\n * - 1.000,50 → brasileiro → 1000.50\n * - 1,000.50 → americano → 1000.50\n * - 1.000 → ambíguo (assume milhar) → 1000\n * - 1,50 → brasileiro decimal → 1.50\n */\nfunction parseNumber(numStr: string): number | null {\n // Remove espaços\n numStr = numStr.replace(/\\s/g, \"\");\n\n // Remove caracteres não numéricos exceto . , - +\n if (!/^[+-]?[\\d.,]+$/.test(numStr)) {\n return null;\n }\n\n const lastComma = numStr.lastIndexOf(\",\");\n const lastDot = numStr.lastIndexOf(\".\");\n const hasComma = lastComma !== -1;\n const hasDot = lastDot !== -1;\n\n if (hasComma && hasDot) {\n if (lastComma > lastDot) {\n // Brasileiro: 1.000,50 → vírgula é decimal\n numStr = numStr.replace(/\\./g, \"\").replace(\",\", \".\");\n } else {\n // Americano: 1,000.50 → ponto é decimal\n numStr = numStr.replace(/,/g, \"\");\n }\n } else if (hasComma && !hasDot) {\n // Só vírgulas: detecta se é milhar ou decimal\n const parts = numStr.split(\",\");\n const afterComma = parts.slice(1);\n\n // Se tem múltiplas vírgulas OU parte após vírgula tem 3 dígitos = milhar\n if (afterComma.length > 1 || (afterComma.length === 1 && afterComma[0].length === 3 && parts[0].length <= 3)) {\n // Milhar brasileiro: 1,000,000 ou 1,000\n numStr = numStr.replace(/,/g, \"\");\n } else {\n // Decimal brasileiro: 1,50\n numStr = numStr.replace(\",\", \".\");\n }\n } else if (!hasComma && hasDot) {\n // Só pontos\n const parts = numStr.split(\".\");\n const afterDot = parts.slice(1);\n\n // Múltiplos pontos = milhar brasileiro: 1.000.000\n if (afterDot.length > 1) {\n numStr = numStr.replace(/\\./g, \"\");\n } else if (afterDot.length === 1 && afterDot[0].length === 3) {\n // Único ponto com exatamente 3 dígitos após = milhar (1.500 → 1500)\n // Em contexto monetário, 1.500 é quase sempre milhar, não 1.5\n numStr = numStr.replace(/\\./g, \"\");\n }\n // Outros casos: decimal americano (1.50, 1000.50)\n }\n\n const value = parseFloat(numStr);\n return isNaN(value) ? null : value;\n}\n"]}