| 412 | ]); |
| 413 | |
| 414 | const normalizeGoogleClassifications = ( |
| 415 | family: GoogleFamily, |
| 416 | ): FontClassification[] => { |
| 417 | const classifications = new Set<FontClassification>(); |
| 418 | for (const value of [family.stroke, ...family.classifications]) { |
| 419 | if (!value) continue; |
| 420 | const classification = GOOGLE_CLASSIFICATION_MAP[value]; |
| 421 | if (!classification) { |
| 422 | throw new Error( |
| 423 | `${family.name} has unsupported Google classification ${value}`, |
| 424 | ); |
| 425 | } |
| 426 | classifications.add(classification); |
| 427 | } |
| 428 | |
| 429 | const category = GOOGLE_CLASSIFICATION_MAP[family.category]; |
| 430 | if (!category) { |
| 431 | throw new Error( |
| 432 | `${family.name} has unsupported Google category ${family.category}`, |
| 433 | ); |
| 434 | } |
| 435 | if ( |
| 436 | !STRUCTURAL_CLASSIFICATIONS.has(category) || |
| 437 | ![...classifications].some((value) => STRUCTURAL_CLASSIFICATIONS.has(value)) |
| 438 | ) { |
| 439 | classifications.add(category); |
| 440 | } |
| 441 | return [...classifications].toSorted(compareStrings); |
| 442 | }; |
| 443 | |
| 444 | // Google scores degrees and variable coordinates; Fontsource publishes only |
| 445 | // strong whole-family assertions as binary discovery tags. |