resuml 3.0.0 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/ats/checks/parsing.ts","../src/ats/i18n/en.ts","../src/ats/i18n/de.ts","../src/ats/i18n/index.ts","../src/ats/checks/yoe.ts","../src/ats/checks/recruiter.ts","../src/ats/jdMatcher.ts","../src/ats/checks/match.ts","../src/ats/scoring.ts","../src/utils/config.ts","../src/ats/index.ts"],"sourcesContent":["import type { ResumeSchema } from '../../types/resume';\nimport type { CheckResult } from '../types';\n\ntype CheckFn = (resume: ResumeSchema, language: string) => CheckResult;\n\nconst ISO_DATE = /^\\d{4}(-\\d{2})?(-\\d{2})?$/;\n\nexport const conventionalSections: CheckFn = (resume) => {\n const required = ['basics', 'work', 'education'] as const;\n const missing = required.filter((s) => {\n const v = resume[s];\n if (Array.isArray(v)) return v.length === 0;\n return v === undefined;\n });\n const passed = missing.length === 0;\n return {\n id: 'conventional-sections',\n tier: 'parsing',\n weight: 'high',\n status: passed ? 'pass' : 'fail',\n score: Math.round(((required.length - missing.length) / required.length) * 100),\n message: passed\n ? 'All conventional sections present.'\n : `Missing required sections: ${missing.join(', ')}.`,\n hints: passed ? [] : [`Add ${missing.join(', ')} to your YAML.`],\n };\n};\n\nexport const dateFormatConsistency: CheckFn = (resume) => {\n const all: { date: string; where: string }[] = [];\n for (const w of resume.work || []) {\n if (w.startDate) all.push({ date: w.startDate, where: `work \"${w.name || ''}\".startDate` });\n if (w.endDate) all.push({ date: w.endDate, where: `work \"${w.name || ''}\".endDate` });\n }\n for (const e of resume.education || []) {\n if (e.startDate)\n all.push({ date: e.startDate, where: `education \"${e.institution || ''}\".startDate` });\n if (e.endDate)\n all.push({ date: e.endDate, where: `education \"${e.institution || ''}\".endDate` });\n }\n if (all.length === 0) {\n return {\n id: 'date-format-consistency',\n tier: 'parsing',\n weight: 'medium',\n status: 'skipped',\n score: 0,\n message: 'No dates to check.',\n hints: [],\n };\n }\n const bad = all.filter((d) => !ISO_DATE.test(d.date));\n const passed = bad.length === 0;\n return {\n id: 'date-format-consistency',\n tier: 'parsing',\n weight: 'medium',\n status: passed ? 'pass' : bad.length <= 1 ? 'warn' : 'fail',\n score: Math.round(((all.length - bad.length) / all.length) * 100),\n message: passed\n ? 'All dates use ISO-8601 format.'\n : `Non-ISO dates: ${bad\n .slice(0, 3)\n .map((b) => `${b.where}=${b.date}`)\n .join('; ')}.`,\n hints: passed ? [] : ['Use YYYY-MM or YYYY-MM-DD for every date field.'],\n };\n};\n\nexport const contactInBody: CheckFn = (resume) => {\n const b = resume.basics;\n const checks: { ok: boolean; field: string }[] = [\n { ok: !!b?.name, field: 'name' },\n { ok: !!b?.email, field: 'email' },\n { ok: !!b?.phone, field: 'phone' },\n { ok: !!b?.location?.city, field: 'location.city' },\n ];\n const missing = checks.filter((c) => !c.ok).map((c) => c.field);\n const passed = missing.length === 0;\n return {\n id: 'contact-in-body',\n tier: 'parsing',\n weight: 'high',\n status: passed ? 'pass' : 'fail',\n score: Math.round(((checks.length - missing.length) / checks.length) * 100),\n message: passed\n ? 'Contact information present in basics.'\n : `Missing contact fields: ${missing.join(', ')}.`,\n hints: passed ? [] : [`Add ${missing.join(', ')} to basics.`],\n };\n};\n\nexport const reverseChronOrder: CheckFn = (resume) => {\n const work = resume.work || [];\n if (work.length < 2) {\n return {\n id: 'reverse-chron-order',\n tier: 'parsing',\n weight: 'medium',\n status: 'skipped',\n score: 100,\n message: 'Single or no work entry.',\n hints: [],\n };\n }\n let outOfOrder = 0;\n for (let i = 0; i < work.length - 1; i++) {\n const curr = work[i];\n const next = work[i + 1];\n const a = curr?.startDate || '';\n const b = next?.startDate || '';\n if (a && b && a < b) outOfOrder++;\n }\n const passed = outOfOrder === 0;\n return {\n id: 'reverse-chron-order',\n tier: 'parsing',\n weight: 'medium',\n status: passed ? 'pass' : 'fail',\n score: passed ? 100 : Math.max(0, 100 - outOfOrder * 50),\n message: passed\n ? 'Work entries in reverse-chronological order.'\n : `${outOfOrder} pair(s) out of reverse-chronological order.`,\n hints: passed ? [] : ['Reorder work[] so the most recent role is first.'],\n };\n};\n\nexport const educationComplete: CheckFn = (resume) => {\n const edu = resume.education || [];\n if (edu.length === 0) {\n return {\n id: 'education-complete',\n tier: 'parsing',\n weight: 'low',\n status: 'fail',\n score: 0,\n message: 'No education entries.',\n hints: ['Add at least one education entry with institution, area, and studyType.'],\n };\n }\n const incomplete = edu.filter((e) => !e.institution || !e.area || !e.studyType);\n const passed = incomplete.length === 0;\n return {\n id: 'education-complete',\n tier: 'parsing',\n weight: 'low',\n status: passed ? 'pass' : 'fail',\n score: Math.round(((edu.length - incomplete.length) / edu.length) * 100),\n message: passed\n ? 'All education entries complete.'\n : `${incomplete.length} education entry(ies) missing institution/area/studyType.`,\n hints: passed ? [] : ['Fill in institution, area and studyType for every education entry.'],\n };\n};\n\nexport const allParsingChecks = [\n conventionalSections,\n dateFormatConsistency,\n contactInBody,\n reverseChronOrder,\n educationComplete,\n];\n","export interface LanguageData {\n actionVerbs: string[];\n pronouns: string[];\n stopWords: string[];\n}\n\nconst en: LanguageData = {\n actionVerbs: [\n // Leadership & Management\n 'achieved',\n 'administered',\n 'advanced',\n 'allocated',\n 'approved',\n 'assigned',\n 'authorized',\n 'chaired',\n 'consolidated',\n 'coordinated',\n 'delegated',\n 'directed',\n 'established',\n 'executed',\n 'headed',\n 'hired',\n 'hosted',\n 'led',\n 'managed',\n 'mentored',\n 'motivated',\n 'orchestrated',\n 'organized',\n 'oversaw',\n 'planned',\n 'presided',\n 'prioritized',\n 'produced',\n 'recruited',\n 'spearheaded',\n 'supervised',\n // Technical & Engineering\n 'architected',\n 'automated',\n 'built',\n 'coded',\n 'configured',\n 'debugged',\n 'deployed',\n 'designed',\n 'developed',\n 'devised',\n 'engineered',\n 'implemented',\n 'installed',\n 'integrated',\n 'launched',\n 'maintained',\n 'migrated',\n 'modernized',\n 'optimized',\n 'overhauled',\n 'programmed',\n 'prototyped',\n 'refactored',\n 'reengineered',\n 'resolved',\n 'restructured',\n 'revamped',\n 'scaled',\n 'shipped',\n 'standardized',\n 'streamlined',\n 'tested',\n 'troubleshot',\n 'upgraded',\n // Achievement & Impact\n 'accelerated',\n 'accomplished',\n 'boosted',\n 'completed',\n 'contributed',\n 'converted',\n 'decreased',\n 'delivered',\n 'doubled',\n 'earned',\n 'eliminated',\n 'exceeded',\n 'expanded',\n 'expedited',\n 'generated',\n 'grew',\n 'improved',\n 'increased',\n 'maximized',\n 'minimized',\n 'outperformed',\n 'pioneered',\n 'recovered',\n 'reduced',\n 'saved',\n 'simplified',\n 'solved',\n 'surpassed',\n 'transformed',\n 'tripled',\n // Communication & Collaboration\n 'advised',\n 'advocated',\n 'briefed',\n 'collaborated',\n 'communicated',\n 'consulted',\n 'convinced',\n 'counseled',\n 'defined',\n 'demonstrated',\n 'documented',\n 'educated',\n 'facilitated',\n 'guided',\n 'influenced',\n 'informed',\n 'instructed',\n 'liaised',\n 'negotiated',\n 'partnered',\n 'persuaded',\n 'presented',\n 'promoted',\n 'proposed',\n 'published',\n 'recommended',\n 'represented',\n 'trained',\n // Analysis & Research\n 'analyzed',\n 'assessed',\n 'audited',\n 'benchmarked',\n 'calculated',\n 'compared',\n 'compiled',\n 'conducted',\n 'discovered',\n 'evaluated',\n 'examined',\n 'explored',\n 'forecasted',\n 'identified',\n 'inspected',\n 'interpreted',\n 'investigated',\n 'mapped',\n 'measured',\n 'modeled',\n 'monitored',\n 'quantified',\n 'researched',\n 'reviewed',\n 'surveyed',\n 'synthesized',\n 'tracked',\n 'validated',\n 'verified',\n // Creation & Innovation\n 'conceptualized',\n 'crafted',\n 'created',\n 'customized',\n 'formulated',\n 'founded',\n 'initiated',\n 'innovated',\n 'introduced',\n 'invented',\n 'originated',\n 'shaped',\n ],\n pronouns: ['i', 'me', 'my', 'mine', 'myself', 'we', 'our', 'ours'],\n stopWords: [\n // Articles & determiners\n 'a',\n 'an',\n 'the',\n 'and',\n 'or',\n 'but',\n 'in',\n 'on',\n 'at',\n 'to',\n 'for',\n 'of',\n 'with',\n 'by',\n 'from',\n 'is',\n 'was',\n 'are',\n 'were',\n 'be',\n 'been',\n 'being',\n 'have',\n 'has',\n 'had',\n 'do',\n 'does',\n 'did',\n 'will',\n 'would',\n 'could',\n 'should',\n 'may',\n 'might',\n 'shall',\n 'can',\n 'this',\n 'that',\n 'these',\n 'those',\n 'it',\n 'its',\n 'as',\n 'if',\n 'not',\n 'no',\n 'so',\n 'up',\n 'out',\n 'about',\n 'into',\n 'over',\n 'after',\n 'before',\n 'between',\n 'under',\n 'above',\n 'below',\n 'all',\n 'each',\n 'every',\n 'both',\n 'few',\n 'more',\n 'most',\n 'other',\n 'some',\n 'such',\n 'than',\n 'too',\n 'very',\n // Pronouns & possessives (also checked by pronoun check, but filter from JD keywords)\n 'you',\n 'your',\n 'yours',\n 'yourself',\n 'we',\n 'our',\n 'ours',\n 'ourselves',\n 'they',\n 'them',\n 'their',\n 'theirs',\n 'he',\n 'she',\n 'his',\n 'her',\n 'hers',\n 'who',\n 'whom',\n 'whose',\n 'which',\n 'what',\n 'where',\n 'when',\n 'how',\n 'why',\n // Common JD filler words (not meaningful for skill matching)\n 'able',\n 'also',\n 'across',\n 'already',\n 'always',\n 'among',\n 'any',\n 'apply',\n 'become',\n 'believe',\n 'best',\n 'bring',\n 'change',\n 'come',\n 'committed',\n 'company',\n 'comfortable',\n 'critical',\n 'current',\n 'day',\n 'desired',\n 'either',\n 'end',\n 'ensure',\n 'environment',\n 'equal',\n 'even',\n 'excellent',\n 'exciting',\n 'exceptional',\n 'expected',\n 'experience',\n 'fast',\n 'field',\n 'find',\n 'first',\n 'focused',\n 'follow',\n 'get',\n 'give',\n 'go',\n 'going',\n 'good',\n 'great',\n 'group',\n 'grow',\n 'growing',\n 'growth',\n 'help',\n 'here',\n 'high',\n 'highly',\n 'ideal',\n 'impact',\n 'important',\n 'include',\n 'includes',\n 'including',\n 'industry',\n 'interested',\n 'job',\n 'join',\n 'just',\n 'keep',\n 'key',\n 'know',\n 'large',\n 'latest',\n 'lead',\n 'level',\n 'like',\n 'location',\n 'long',\n 'look',\n 'looking',\n 'love',\n 'make',\n 'many',\n 'much',\n 'must',\n 'need',\n 'new',\n 'next',\n 'offer',\n 'one',\n 'only',\n 'open',\n 'opportunity',\n 'order',\n 'others',\n 'own',\n 'pace',\n 'part',\n 'partner',\n 'passionate',\n 'people',\n 'per',\n 'play',\n 'plus',\n 'position',\n 'preferred',\n 'provide',\n 'put',\n 'qualifications',\n 'quickly',\n 'range',\n 'related',\n 'required',\n 'requirements',\n 'requirement',\n 'responsible',\n 'responsibilities',\n 'responsibility',\n 'result',\n 'right',\n 'role',\n 'run',\n 'same',\n 'see',\n 'seek',\n 'seeking',\n 'set',\n 'several',\n 'since',\n 'skills',\n 'someone',\n 'start',\n 'state',\n 'still',\n 'strong',\n 'success',\n 'successful',\n 'support',\n 'sure',\n 'take',\n 'team',\n 'then',\n 'there',\n 'thing',\n 'think',\n 'through',\n 'time',\n 'together',\n 'top',\n 'truly',\n 'try',\n 'two',\n 'type',\n 'use',\n 'used',\n 'using',\n 'value',\n 'want',\n 'way',\n 'well',\n 'while',\n 'within',\n 'without',\n 'work',\n 'working',\n 'world',\n 'would',\n 'year',\n 'years',\n // Section headers & structural words (not technical skills)\n 'description',\n 'overview',\n 'summary',\n 'duties',\n 'bachelor',\n 'bachelors',\n 'master',\n 'masters',\n 'degree',\n 'phd',\n 'minimum',\n 'preferred',\n 'implement',\n 'process',\n 'robust',\n 'consistent',\n 'operations',\n // URL/email/domain fragments\n 'http',\n 'https',\n 'www',\n 'com',\n 'org',\n 'net',\n 'mailto',\n // Resume/YAML schema field names (in case raw YAML is pasted)\n 'name',\n 'keywords',\n 'highlights',\n 'startdate',\n 'enddate',\n 'website',\n 'profiles',\n 'basics',\n 'position',\n 'institution',\n 'studytype',\n 'fluency',\n 'issuer',\n 'network',\n 'username',\n 'countrycode',\n 'region',\n // Generic nouns that aren't skills\n 'product',\n 'company',\n 'service',\n 'services',\n 'platform',\n 'solutions',\n 'ability',\n 'opportunity',\n 'candidate',\n 'applicant',\n 'position',\n 'salary',\n 'compensation',\n 'benefits',\n 'perks',\n 'bonus',\n 'development',\n 'management',\n 'knowledge',\n 'modern',\n 'advanced',\n 'practices',\n 'nice',\n 'technologies',\n 'technology',\n 'frameworks',\n 'framework',\n 'tools',\n 'data',\n 'based',\n 'contribute',\n 'contributions',\n 'migration',\n 'leading',\n 'source',\n 'visit',\n // Common verbs & verb forms (not technical skills, supplement action verbs list)\n 'collaborate',\n 'collaborating',\n 'collaboratively',\n 'communicate',\n 'communicating',\n 'contributing',\n 'coordinate',\n 'coordinating',\n 'demonstrate',\n 'demonstrating',\n 'design',\n 'designing',\n 'designed',\n 'develop',\n 'developing',\n 'developed',\n 'drive',\n 'driving',\n 'driven',\n 'enable',\n 'enabling',\n 'evaluate',\n 'evaluating',\n 'execute',\n 'executing',\n 'facilitate',\n 'facilitating',\n 'identify',\n 'identifying',\n 'influence',\n 'influencing',\n 'interact',\n 'interacting',\n 'lead',\n 'leverage',\n 'leveraging',\n 'manage',\n 'managing',\n 'mentor',\n 'mentoring',\n 'operate',\n 'operating',\n 'optimize',\n 'optimizing',\n 'participate',\n 'participating',\n 'report',\n 'reporting',\n 'solve',\n 'solving',\n 'understand',\n 'understanding',\n // Common adjectives & descriptors (not technical skills)\n 'fluent',\n 'proficient',\n 'deep',\n 'solid',\n 'proven',\n 'hands-on',\n 'detail-oriented',\n 'results-driven',\n 'self-motivated',\n 'proactive',\n 'creative',\n 'innovative',\n 'dynamic',\n 'strategic',\n 'analytical',\n 'collaborative',\n 'effective',\n 'efficient',\n 'reliable',\n 'flexible',\n 'adaptable',\n 'motivated',\n 'dedicated',\n 'capable',\n 'qualified',\n 'diverse',\n 'inclusive',\n 'global',\n 'local',\n 'remote',\n 'hybrid',\n 'onsite',\n 'full-time',\n 'part-time',\n 'contract',\n 'permanent',\n // Role titles & department names (not skills themselves)\n 'designer',\n 'designers',\n 'developer',\n 'developers',\n 'engineer',\n 'engineers',\n 'manager',\n 'managers',\n 'director',\n 'analyst',\n 'analysts',\n 'architect',\n 'architects',\n 'consultant',\n 'consultants',\n 'specialist',\n 'specialists',\n 'coordinator',\n 'lead',\n 'principal',\n 'staff',\n 'junior',\n 'mid',\n 'department',\n 'organization',\n 'division',\n 'stakeholder',\n 'stakeholders',\n 'client',\n 'clients',\n 'customer',\n 'customers',\n // Date & time words\n 'date',\n 'dates',\n 'month',\n 'months',\n 'week',\n 'weeks',\n 'daily',\n 'weekly',\n 'monthly',\n 'quarterly',\n 'annual',\n 'annually',\n // More generic words that aren't skills\n 'code',\n 'coding',\n 'url',\n 'contact',\n 'information',\n 'apply',\n 'application',\n 'review',\n 'reviews',\n 'quality',\n 'scale',\n 'scalable',\n 'system',\n 'systems',\n 'solution',\n 'feature',\n 'features',\n 'project',\n 'projects',\n 'build',\n 'building',\n 'deliver',\n 'delivery',\n 'cross-functional',\n ],\n};\n\nexport default en;\n","import type { LanguageData } from './en';\n\nconst de: LanguageData = {\n actionVerbs: [\n // Führung & Management\n 'geleitet',\n 'geführt',\n 'koordiniert',\n 'organisiert',\n 'verwaltet',\n 'delegiert',\n 'beaufsichtigt',\n 'betreut',\n 'eingestellt',\n 'motiviert',\n 'verantwortet',\n 'gesteuert',\n 'überwacht',\n 'priorisiert',\n 'geplant',\n // Technik & Entwicklung\n 'entwickelt',\n 'implementiert',\n 'programmiert',\n 'konfiguriert',\n 'automatisiert',\n 'deployt',\n 'gebaut',\n 'entworfen',\n 'integriert',\n 'migriert',\n 'modernisiert',\n 'optimiert',\n 'refaktoriert',\n 'skaliert',\n 'standardisiert',\n 'getestet',\n 'aufgebaut',\n 'eingeführt',\n 'bereitgestellt',\n 'umgesetzt',\n // Leistung & Ergebnisse\n 'verbessert',\n 'gesteigert',\n 'reduziert',\n 'beschleunigt',\n 'erreicht',\n 'übertroffen',\n 'erweitert',\n 'vereinfacht',\n 'gelöst',\n 'transformiert',\n 'erhöht',\n 'verdoppelt',\n 'verdreifacht',\n 'generiert',\n 'gespart',\n 'maximiert',\n 'minimiert',\n 'eliminiert',\n 'geliefert',\n 'abgeschlossen',\n // Kommunikation & Zusammenarbeit\n 'beraten',\n 'präsentiert',\n 'dokumentiert',\n 'geschult',\n 'trainiert',\n 'vermittelt',\n 'kommuniziert',\n 'verhandelt',\n 'zusammengearbeitet',\n 'unterstützt',\n 'gefördert',\n 'empfohlen',\n 'vorgestellt',\n 'publiziert',\n // Analyse & Forschung\n 'analysiert',\n 'bewertet',\n 'evaluiert',\n 'untersucht',\n 'erforscht',\n 'identifiziert',\n 'gemessen',\n 'überwacht',\n 'validiert',\n 'verifiziert',\n 'geprüft',\n 'verglichen',\n 'recherchiert',\n 'quantifiziert',\n // Kreation & Innovation\n 'konzipiert',\n 'erstellt',\n 'gestaltet',\n 'initiiert',\n 'innoviert',\n 'eingeführt',\n 'gegründet',\n 'formuliert',\n ],\n pronouns: [\n 'ich',\n 'mich',\n 'mir',\n 'mein',\n 'meine',\n 'meinem',\n 'meiner',\n 'meines',\n 'wir',\n 'unser',\n 'unsere',\n ],\n stopWords: [\n 'ein',\n 'eine',\n 'einer',\n 'eines',\n 'einem',\n 'der',\n 'die',\n 'das',\n 'den',\n 'dem',\n 'des',\n 'und',\n 'oder',\n 'aber',\n 'in',\n 'an',\n 'auf',\n 'zu',\n 'für',\n 'von',\n 'mit',\n 'bei',\n 'aus',\n 'ist',\n 'war',\n 'sind',\n 'waren',\n 'wird',\n 'wurde',\n 'werden',\n 'hat',\n 'hatte',\n 'haben',\n 'hatten',\n 'sein',\n 'kann',\n 'könnte',\n 'soll',\n 'sollte',\n 'muss',\n 'musste',\n 'darf',\n 'diese',\n 'dieser',\n 'dieses',\n 'diesem',\n 'diesen',\n 'als',\n 'wenn',\n 'nicht',\n 'kein',\n 'keine',\n 'so',\n 'auch',\n 'noch',\n 'schon',\n 'nach',\n 'vor',\n 'über',\n 'unter',\n 'zwischen',\n 'durch',\n 'ohne',\n 'um',\n 'bis',\n 'alle',\n 'jede',\n 'jeder',\n 'jedes',\n 'mehr',\n 'viel',\n 'sehr',\n ],\n};\n\nexport default de;\n","import en from './en';\nimport de from './de';\nimport type { LanguageData } from './en';\n\nexport type { LanguageData };\n\nconst languages: Record<string, LanguageData> = { en, de };\n\nexport function getLanguageData(language: string): LanguageData {\n return languages[language] ?? languages['en'] ?? en;\n}\n","import type { ResumeSchema } from '../../types/resume';\n\nexport function computeYoeYears(work: ResumeSchema['work']): number {\n const ranges = (work || [])\n .filter((w) => w.startDate)\n .map((w) => {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const s = new Date(w.startDate!).getTime();\n const e = w.endDate ? new Date(w.endDate).getTime() : Date.now();\n return [s, e] as [number, number];\n })\n .sort((a, b) => a[0] - b[0]);\n if (ranges.length === 0) return 0;\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const merged: [number, number][] = [ranges[0]!];\n for (let i = 1; i < ranges.length; i++) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const last = merged[merged.length - 1]!;\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const curr = ranges[i]!;\n if (curr[0] <= last[1]) last[1] = Math.max(last[1], curr[1]);\n else merged.push(curr);\n }\n const ms = merged.reduce((sum, [s, e]) => sum + (e - s), 0);\n return ms / (1000 * 60 * 60 * 24 * 365.25);\n}\n","import type { ResumeSchema } from '../../types/resume';\nimport type { CheckResult, AtsConfig } from '../types';\nimport { getLanguageData } from '../i18n/index';\nimport { computeYoeYears } from './yoe';\n\ntype CheckFn = (resume: ResumeSchema, language: string, cfg: AtsConfig) => CheckResult;\n\nconst wordCount = (s: string) => s.trim().split(/\\s+/).filter(Boolean).length;\nconst firstWord = (s: string) =>\n s\n .trim()\n .split(/\\s+/)[0]\n ?.toLowerCase()\n .replace(/[^a-zA-ZäöüßÄÖÜàáâãéèêëíìîïóòôõúùûñç]/g, '') || '';\n\nfunction isSenior(resume: ResumeSchema, cfg: AtsConfig): boolean {\n return computeYoeYears(resume.work) >= cfg.thresholds.seniorYoeCutoff;\n}\n\nexport const summaryLength: CheckFn = (resume) => {\n const s = resume.basics?.summary?.trim();\n if (!s) {\n return {\n id: 'summary-length',\n tier: 'recruiter',\n weight: 'medium',\n status: 'fail',\n score: 0,\n message: 'No professional summary.',\n hints: ['Add a 2-4 sentence summary (20-50 words) to basics.summary.'],\n };\n }\n const w = wordCount(s);\n if (w >= 20 && w <= 50) {\n return {\n id: 'summary-length',\n tier: 'recruiter',\n weight: 'medium',\n status: 'pass',\n score: 100,\n message: `Summary length good (${w} words).`,\n hints: [],\n };\n }\n if (w >= 10 && w <= 80) {\n return {\n id: 'summary-length',\n tier: 'recruiter',\n weight: 'medium',\n status: 'warn',\n score: 70,\n message: `Summary ${w < 20 ? 'short' : 'long'} (${w} words). Aim for 20-50.`,\n hints: [w < 20 ? 'Expand to 20-50 words.' : 'Trim to the most impactful 20-50 words.'],\n };\n }\n return {\n id: 'summary-length',\n tier: 'recruiter',\n weight: 'medium',\n status: 'fail',\n score: Math.max(0, 100 - Math.abs(w - 35) * 2),\n message: `Summary length ${w} words is far from target.`,\n hints: ['Rewrite the summary in 2-4 sentences (20-50 words).'],\n };\n};\n\nexport const actionVerbStart: CheckFn = (resume, language) => {\n const verbs = new Set(getLanguageData(language).actionVerbs);\n const all: { text: string; path: string }[] = [];\n (resume.work || []).forEach((w, i) => {\n (w.highlights || []).forEach((h, j) =>\n all.push({ text: h, path: `work[${i}].highlights[${j}]` })\n );\n });\n (resume.projects || []).forEach((p, i) => {\n (p.highlights || []).forEach((h, j) =>\n all.push({ text: h, path: `projects[${i}].highlights[${j}]` })\n );\n });\n if (all.length === 0) {\n return {\n id: 'action-verb-start',\n tier: 'recruiter',\n weight: 'medium',\n status: 'skipped',\n score: 0,\n message: 'No highlights.',\n hints: [],\n };\n }\n const without = all.filter((h) => !verbs.has(firstWord(h.text)));\n const passed = without.length === 0;\n return {\n id: 'action-verb-start',\n tier: 'recruiter',\n weight: 'medium',\n status: passed ? 'pass' : without.length / all.length > 0.3 ? 'fail' : 'warn',\n score: Math.round(((all.length - without.length) / all.length) * 100),\n message: passed\n ? 'All highlights start with action verbs.'\n : `${without.length} of ${all.length} highlights miss an action verb.`,\n hints: passed\n ? []\n : without\n .slice(0, 3)\n .map((h) => `${h.path}: start with an action verb instead of \"${firstWord(h.text)}\".`),\n };\n};\n\nconst QUANT_RE =\n /\\d+%?|\\$[\\d,]+|[\\d,]+\\+?\\s*(users|clients|customers|people|team|members|projects|applications|servers|services|endpoints|requests|transactions)/i;\n\nexport const quantificationDensity: CheckFn = (resume) => {\n const all: { text: string; path: string }[] = [];\n (resume.work || []).forEach((w, i) => {\n (w.highlights || []).forEach((h, j) =>\n all.push({ text: h, path: `work[${i}].highlights[${j}]` })\n );\n });\n (resume.projects || []).forEach((p, i) => {\n (p.highlights || []).forEach((h, j) =>\n all.push({ text: h, path: `projects[${i}].highlights[${j}]` })\n );\n });\n if (all.length === 0) {\n return {\n id: 'quantification-density',\n tier: 'recruiter',\n weight: 'high',\n status: 'skipped',\n score: 0,\n message: 'No highlights.',\n hints: [],\n };\n }\n const quantified = all.filter((h) => QUANT_RE.test(h.text));\n const ratio = quantified.length / all.length;\n const status = ratio >= 0.5 ? 'pass' : ratio >= 0.3 ? 'warn' : 'fail';\n return {\n id: 'quantification-density',\n tier: 'recruiter',\n weight: 'high',\n status,\n score: Math.min(100, Math.round(ratio * 200)),\n message: `${quantified.length}/${all.length} highlights quantified (${Math.round(ratio * 100)}%).`,\n hints:\n status === 'pass'\n ? []\n : all\n .filter((h) => !QUANT_RE.test(h.text))\n .slice(0, 3)\n .map((h) => `${h.path}: add a number/metric.`),\n };\n};\n\nexport const pronounLeakage: CheckFn = (resume, language) => {\n const set = new Set(getLanguageData(language).pronouns);\n const blocks: { text: string; path: string }[] = [];\n if (resume.basics?.summary) blocks.push({ text: resume.basics.summary, path: 'basics.summary' });\n (resume.work || []).forEach((w, i) => {\n if (w.summary) blocks.push({ text: w.summary, path: `work[${i}].summary` });\n (w.highlights || []).forEach((h, j) =>\n blocks.push({ text: h, path: `work[${i}].highlights[${j}]` })\n );\n });\n const hits: { pronoun: string; path: string }[] = [];\n for (const b of blocks) {\n for (const w of b.text.toLowerCase().split(/\\s+/)) {\n const clean = w.replace(/[^a-zA-ZäöüßÄÖÜ]/g, '');\n if (set.has(clean)) hits.push({ pronoun: clean, path: b.path });\n }\n }\n const passed = hits.length === 0;\n return {\n id: 'pronoun-leakage',\n tier: 'recruiter',\n weight: 'low',\n status: passed ? 'pass' : hits.length > 3 ? 'fail' : 'warn',\n score: passed ? 100 : Math.max(0, 100 - hits.length * 15),\n message: passed\n ? 'No first-person pronouns.'\n : `${hits.length} pronoun(s): ${[...new Set(hits.map((h) => h.pronoun))].join(', ')}.`,\n hints: passed\n ? []\n : hits.slice(0, 3).map((h) => `${h.path}: drop \"${h.pronoun}\" (convention, not ATS).`),\n };\n};\n\nexport const bulletsPerRole: CheckFn = (resume, _l, cfg) => {\n const work = resume.work || [];\n if (work.length === 0) {\n return {\n id: 'bullets-per-role',\n tier: 'recruiter',\n weight: 'medium',\n status: 'skipped',\n score: 0,\n message: 'No work entries.',\n hints: [],\n };\n }\n const senior = isSenior(resume, cfg);\n const min = cfg.thresholds.bulletsPerRole.min;\n const max = senior ? cfg.thresholds.bulletsPerRole.seniorMax : cfg.thresholds.bulletsPerRole.max;\n const offenders: { path: string; n: number }[] = [];\n work.forEach((w, i) => {\n const n = (w.highlights || []).length;\n if (n < min || n > max) offenders.push({ path: `work[${i}]`, n });\n });\n const passed = offenders.length === 0;\n return {\n id: 'bullets-per-role',\n tier: 'recruiter',\n weight: 'medium',\n status: passed\n ? 'pass'\n : work.length === 1\n ? 'warn'\n : offenders.length > work.length / 2\n ? 'fail'\n : 'warn',\n score: Math.round(((work.length - offenders.length) / work.length) * 100),\n message: passed\n ? `All roles have ${min}-${max} highlights.`\n : `${offenders.length} role(s) outside ${min}-${max} highlights.`,\n hints: passed\n ? []\n : offenders.slice(0, 3).map((o) => `${o.path}: ${o.n} highlights, target ${min}-${max}.`),\n };\n};\n\nexport const wordCountTotal: CheckFn = (resume, _l, cfg) => {\n const senior = isSenior(resume, cfg);\n const min = cfg.thresholds.wordCount.min;\n const max = senior ? cfg.thresholds.wordCount.seniorMax : cfg.thresholds.wordCount.max;\n const parts: string[] = [];\n if (resume.basics?.summary) parts.push(resume.basics.summary);\n for (const w of resume.work || []) {\n if (w.summary) parts.push(w.summary);\n parts.push(...(w.highlights || []));\n }\n for (const p of resume.projects || []) {\n if (p.description) parts.push(p.description);\n parts.push(...(p.highlights || []));\n }\n const total = wordCount(parts.join(' '));\n const passed = total >= min && total <= max;\n const status = passed ? 'pass' : total < min * 0.7 || total > max * 1.5 ? 'fail' : 'warn';\n return {\n id: 'word-count-total',\n tier: 'recruiter',\n weight: 'low',\n status,\n score: passed ? 100 : Math.max(0, 100 - Math.round(Math.abs(total - (min + max) / 2) / 10)),\n message: `Resume body: ${total} words (target ${min}-${max}${senior ? ', senior' : ''}).`,\n hints: passed\n ? []\n : [total < min ? 'Add more depth to highlights.' : 'Trim less impactful highlights.'],\n };\n};\n\nexport const highlightLength: CheckFn = (resume) => {\n const all: { text: string; path: string }[] = [];\n (resume.work || []).forEach((w, i) => {\n (w.highlights || []).forEach((h, j) =>\n all.push({ text: h, path: `work[${i}].highlights[${j}]` })\n );\n });\n if (all.length === 0) {\n return {\n id: 'highlight-length',\n tier: 'recruiter',\n weight: 'low',\n status: 'skipped',\n score: 0,\n message: 'No highlights.',\n hints: [],\n };\n }\n const long = all.filter((h) => wordCount(h.text) > 30);\n const passed = long.length === 0;\n return {\n id: 'highlight-length',\n tier: 'recruiter',\n weight: 'low',\n status: passed ? 'pass' : long.length / all.length > 0.3 ? 'fail' : 'warn',\n score: Math.round(((all.length - long.length) / all.length) * 100),\n message: passed\n ? 'All highlights at most 30 words.'\n : `${long.length} highlight(s) over 30 words.`,\n hints: passed ? [] : long.slice(0, 3).map((h) => `${h.path}: trim to 30 words or fewer.`),\n };\n};\n\nfunction isLinkedInUrl(url: string | undefined): boolean {\n if (!url) return false;\n try {\n const host = new URL(url).hostname.toLowerCase();\n return host === 'linkedin.com' || host.endsWith('.linkedin.com');\n } catch {\n return false;\n }\n}\n\nexport const hasLinkedin: CheckFn = (resume) => {\n const profiles = resume.basics?.profiles || [];\n const found = profiles.some(\n (p) => p.network?.toLowerCase() === 'linkedin' || isLinkedInUrl(p.url)\n );\n return {\n id: 'has-linkedin',\n tier: 'recruiter',\n weight: 'low',\n status: found ? 'pass' : 'warn',\n score: found ? 100 : 0,\n message: found ? 'LinkedIn profile present.' : 'No LinkedIn profile.',\n hints: found ? [] : ['Add a LinkedIn profile to basics.profiles.'],\n };\n};\n\nexport const skillsPopulated: CheckFn = (resume) => {\n const skills = resume.skills || [];\n const withKeywords = skills.filter((s) => (s.keywords?.length ?? 0) > 0);\n const passed = withKeywords.length >= 3;\n return {\n id: 'skills-populated',\n tier: 'recruiter',\n weight: 'medium',\n status: passed ? 'pass' : withKeywords.length < 2 ? 'fail' : 'warn',\n score: Math.min(100, Math.round((withKeywords.length / 3) * 100)),\n message: passed\n ? `${withKeywords.length} skill categories with keywords.`\n : `Only ${withKeywords.length} skill categories with keywords (need 3+).`,\n hints: passed ? [] : ['Add at least 3 skill categories with keywords.'],\n };\n};\n\nexport const allRecruiterChecks = [\n summaryLength,\n actionVerbStart,\n quantificationDensity,\n pronounLeakage,\n bulletsPerRole,\n wordCountTotal,\n highlightLength,\n hasLinkedin,\n skillsPopulated,\n];\n","import type { ResumeSchema } from '../types/resume';\nimport { getSkillIndex, type SkillMatch } from './skills';\n\ninterface AtsKeywordMatch {\n matched: string[];\n missing: string[];\n extra: string[];\n matchPercentage: number;\n}\n\n/**\n * Extract text content from a resume for skill matching.\n */\nfunction extractResumeText(resume: ResumeSchema): string {\n const parts: string[] = [];\n\n if (resume.basics?.summary) parts.push(resume.basics.summary);\n if (resume.basics?.label) parts.push(resume.basics.label);\n\n for (const w of resume.work || []) {\n if (w.position) parts.push(w.position);\n if (w.summary) parts.push(w.summary);\n parts.push(...(w.highlights || []));\n }\n for (const s of resume.skills || []) {\n if (s.name) parts.push(s.name);\n parts.push(...(s.keywords || []));\n }\n for (const p of resume.projects || []) {\n if (p.name) parts.push(p.name);\n if (p.description) parts.push(p.description);\n parts.push(...(p.highlights || []));\n }\n for (const e of resume.education || []) {\n if (e.area) parts.push(e.area);\n if (e.studyType) parts.push(e.studyType);\n parts.push(...(e.courses || []));\n }\n for (const c of resume.certificates || []) {\n if (c.name) parts.push(c.name);\n }\n\n return parts.join(' ');\n}\n\n/**\n * Split JD into sections and identify which contain the actual requirements.\n * Skills mentioned in requirement sections get prioritized over skills only\n * mentioned in the company-blurb / benefits sections.\n */\nfunction splitJdSections(text: string): { requirementText: string; fullText: string } {\n const lines = text.split('\\n');\n const reqPatterns =\n /^(required|requirements?|minimum|preferred|qualifications?|must[\\s-]have|nice[\\s-]to[\\s-]have|what you.?ll|what we.?re looking|skills|technical|you.?ll need|responsibilities|you will)/i;\n const nonReqPatterns =\n /^(about|summary|who we are|our (company|team|mission)|description|overview|benefits|perks|compensation|salary)/i;\n\n let inReqSection = false;\n const reqLines: string[] = [];\n\n for (const line of lines) {\n const header = line\n .trim()\n .replace(/[:#*-]/g, '')\n .trim();\n if (reqPatterns.test(header)) inReqSection = true;\n else if (nonReqPatterns.test(header)) inReqSection = false;\n if (inReqSection) reqLines.push(line);\n }\n\n return {\n requirementText: reqLines.join('\\n'),\n fullText: text,\n };\n}\n\n/**\n * Rank skills found in the JD. Gives precedence to skills that appear in\n * requirement sections, are flagged as \"hot technologies\" by O*NET, or\n * appear multiple times.\n */\ninterface RankedSkill {\n canonical: string;\n occurrences: number;\n inRequirementSection: boolean;\n hot: boolean;\n score: number;\n}\n\nfunction rankSkills(fullMatches: SkillMatch[], requirementMatches: SkillMatch[]): RankedSkill[] {\n const reqIds = new Set(requirementMatches.map((m) => m.skill.id));\n return fullMatches\n .map((m) => {\n const inRequirementSection = reqIds.has(m.skill.id);\n const score =\n m.occurrences * 1.0 + (inRequirementSection ? 3.0 : 0) + (m.skill.hot ? 1.5 : 0);\n return {\n canonical: m.skill.canonical,\n occurrences: m.occurrences,\n inRequirementSection,\n hot: m.skill.hot,\n score,\n };\n })\n .sort((a, b) => {\n if (a.inRequirementSection !== b.inRequirementSection) return a.inRequirementSection ? -1 : 1;\n if (a.score !== b.score) return b.score - a.score;\n return a.canonical.localeCompare(b.canonical);\n });\n}\n\n/**\n * Match a job description against a resume using the bundled skills taxonomy.\n *\n * Extraction is positive-filter: only terms recognised as known skills surface\n * as keywords, so prose verbs (\"actually\", \"ship\", \"move\"), contractions\n * (\"doesn't\" → \"doesn\") and generic nouns never leak through.\n */\nexport function matchJobDescription(\n resume: ResumeSchema,\n jobDescription: string,\n _language: string = 'en'\n): AtsKeywordMatch {\n if (!jobDescription.trim()) {\n return { matched: [], missing: [], extra: [], matchPercentage: 0 };\n }\n\n const skillIndex = getSkillIndex();\n\n // Extract skills from the full JD + requirement-only section\n const fullMatches = skillIndex.scan(jobDescription);\n const { requirementText } = splitJdSections(jobDescription);\n const requirementMatches = requirementText.trim()\n ? skillIndex.scan(requirementText)\n : fullMatches;\n\n // Rank and cap: top 25 most relevant skills, prioritising requirements + hot\n const ranked = rankSkills(fullMatches, requirementMatches).slice(0, 25);\n\n // Skills in the resume\n const resumeText = extractResumeText(resume);\n const resumeMatches = skillIndex.scan(resumeText);\n const resumeSkillIds = new Set(resumeMatches.map((m) => m.skill.id));\n\n const matched: string[] = [];\n const missing: string[] = [];\n for (const r of ranked) {\n // Find the skill object by canonical name to resolve id\n const match = fullMatches.find((m) => m.skill.canonical === r.canonical);\n if (!match) continue;\n if (resumeSkillIds.has(match.skill.id)) matched.push(r.canonical);\n else missing.push(r.canonical);\n }\n\n const matchPercentage =\n ranked.length > 0 ? Math.round((matched.length / ranked.length) * 100) : 0;\n\n // Resume skills not referenced by the JD\n const jdSkillIds = new Set(fullMatches.map((m) => m.skill.id));\n const extra: string[] = [];\n for (const m of resumeMatches) {\n if (!jdSkillIds.has(m.skill.id)) extra.push(m.skill.canonical);\n }\n // Cap extras to avoid overwhelming the UI\n extra.splice(25);\n\n return { matched, missing, extra, matchPercentage };\n}\n","import type { ResumeSchema } from '../../types/resume';\nimport type { CheckResult, KnockoutSignal } from '../types';\nimport { matchJobDescription } from '../jdMatcher';\nimport { computeYoeYears } from './yoe';\n\ninterface MatchOpts {\n jobDescription?: string;\n}\n\ntype MatchCheckFn = (resume: ResumeSchema, language: string, opts: MatchOpts) => CheckResult;\n\nconst SENIORITY = /\\b(junior|senior|lead|staff|principal|head of|vp|chief)\\b/gi;\nconst STOPWORDS = new Set([\n 'a',\n 'an',\n 'the',\n 'of',\n 'at',\n 'for',\n 'in',\n 'on',\n 'to',\n 'with',\n 'and',\n 'or',\n]);\n\nfunction tokenize(s: string): string[] {\n return s\n .toLowerCase()\n .replace(SENIORITY, '')\n .replace(/[^a-z0-9 ]/g, ' ')\n .split(/\\s+/)\n .filter((w) => w && !STOPWORDS.has(w));\n}\n\nfunction jaccard(a: string[], b: string[]): number {\n const A = new Set(a),\n B = new Set(b);\n let inter = 0;\n for (const x of A) if (B.has(x)) inter++;\n const union = A.size + B.size - inter;\n return union === 0 ? 0 : inter / union;\n}\n\nfunction trimTitle(t: string): string {\n // Drop trailing \", X\" or \" - X\" segments that bring company/team noise into Jaccard.\n return t\n .trim()\n .replace(/\\s*[,\\-–—]\\s.*$/, '')\n .trim();\n}\n\nfunction extractJdTitle(jd: string): string | undefined {\n const lines = jd.split('\\n').slice(0, 8);\n for (const l of lines) {\n const m =\n l.match(/(?:role|position|title)[\\s:-]+(.+)/i) ||\n l.match(/looking for (?:an? )?(.+?)(?:\\s+with|\\s+to|$)/i);\n if (m?.[1]) return trimTitle(m[1]);\n }\n const fallback = lines.find((l) =>\n /\\b(engineer|developer|manager|designer|analyst|scientist|architect|lead)\\b/i.test(l)\n );\n return fallback ? trimTitle(fallback) : undefined;\n}\n\nexport const titleAlignment: MatchCheckFn = (resume, _l, { jobDescription }) => {\n if (!jobDescription) {\n return {\n id: 'title-alignment',\n tier: 'match',\n weight: 'high',\n status: 'skipped',\n score: 0,\n message: 'No JD.',\n hints: [],\n };\n }\n const resumeTitle = resume.work?.[0]?.position || resume.basics?.label;\n const jdTitle = extractJdTitle(jobDescription);\n if (!resumeTitle || !jdTitle) {\n return {\n id: 'title-alignment',\n tier: 'match',\n weight: 'high',\n status: 'warn',\n score: 50,\n message: 'Could not extract title from JD or resume.',\n hints: ['Set basics.label to your target title.'],\n };\n }\n const j = jaccard(tokenize(resumeTitle), tokenize(jdTitle));\n const status = j >= 0.6 ? 'pass' : j >= 0.3 ? 'warn' : 'fail';\n return {\n id: 'title-alignment',\n tier: 'match',\n weight: 'high',\n status,\n score: Math.round(j * 100),\n message: `Title overlap ${Math.round(j * 100)}% (resume \"${resumeTitle}\" vs JD \"${jdTitle}\").`,\n hints: status === 'pass' ? [] : [`Consider aligning basics.label closer to \"${jdTitle}\".`],\n };\n};\n\nconst EDU_RE = {\n 3: /\\b(phd|ph\\.?d|doctorate|doctoral)\\b/i,\n 2: /\\b(master|m\\.?s|m\\.?a|mba|graduate degree)\\b/i,\n 1: /\\b(bachelor|b\\.?s|b\\.?a|undergraduate)\\b/i,\n} as const;\n\nfunction eduLevel(text: string): number {\n if (!text) return 0;\n if (EDU_RE[3].test(text)) return 3;\n if (EDU_RE[2].test(text)) return 2;\n if (EDU_RE[1].test(text)) return 1;\n return 0;\n}\n\nexport const educationLevel: MatchCheckFn = (resume, _l, { jobDescription }) => {\n if (!jobDescription) {\n return {\n id: 'education-level',\n tier: 'match',\n weight: 'medium',\n status: 'skipped',\n score: 0,\n message: 'No JD.',\n hints: [],\n };\n }\n const required = eduLevel(jobDescription);\n if (required === 0) {\n return {\n id: 'education-level',\n tier: 'match',\n weight: 'medium',\n status: 'skipped',\n score: 0,\n message: 'JD does not specify education level.',\n hints: [],\n };\n }\n const have = Math.max(0, ...(resume.education || []).map((e) => eduLevel(e.studyType || '')));\n const passed = have >= required;\n return {\n id: 'education-level',\n tier: 'match',\n weight: 'medium',\n status: passed ? 'pass' : 'fail',\n score: passed ? 100 : Math.round((have / required) * 100),\n message: `Resume level ${have}, JD required ${required}.`,\n hints: passed ? [] : ['JD requires a higher degree level than the resume reports.'],\n };\n};\n\nconst YOE_RE = /(\\d+)\\s*(?:\\+|[-–—]\\s*\\d+|to\\s*\\d+)?\\s*years?/i;\n\nexport const yoeMatch: MatchCheckFn = (resume, _l, { jobDescription }) => {\n if (!jobDescription) {\n return {\n id: 'yoe-match',\n tier: 'match',\n weight: 'high',\n status: 'skipped',\n score: 0,\n message: 'No JD.',\n hints: [],\n };\n }\n const m = jobDescription.match(YOE_RE);\n if (!m) {\n return {\n id: 'yoe-match',\n tier: 'match',\n weight: 'high',\n status: 'skipped',\n score: 0,\n message: 'JD does not specify years requirement.',\n hints: [],\n };\n }\n const required = parseInt(m[1] ?? '0', 10);\n const have = Math.floor(computeYoeYears(resume.work || []));\n const status = have >= required ? 'pass' : have >= required - 1 ? 'warn' : 'fail';\n return {\n id: 'yoe-match',\n tier: 'match',\n weight: 'high',\n status,\n score: Math.min(100, Math.round((have / required) * 100)),\n message: `${have} YOE detected vs ${required} required.`,\n hints:\n status === 'pass' ? [] : ['Highlight relevant earlier roles or projects to fill the gap.'],\n };\n};\n\nexport const hardSkillOverlap: MatchCheckFn = (resume, language, { jobDescription }) => {\n if (!jobDescription) {\n return {\n id: 'hard-skill-overlap',\n tier: 'match',\n weight: 'high',\n status: 'skipped',\n score: 0,\n message: 'No JD.',\n hints: [],\n };\n }\n const km = matchJobDescription(resume, jobDescription, language);\n const pct = km.matchPercentage;\n const status = pct >= 70 ? 'pass' : pct >= 50 ? 'warn' : 'fail';\n return {\n id: 'hard-skill-overlap',\n tier: 'match',\n weight: 'high',\n status,\n score: pct,\n message: `${km.matched.length}/${km.matched.length + km.missing.length} hard skills matched (${pct}%).`,\n hints:\n status === 'pass'\n ? []\n : km.missing.slice(0, 5).map((s) => `Add evidence of \"${s}\" to skills/highlights.`),\n };\n};\n\nexport const allMatchChecks = [hardSkillOverlap, titleAlignment, educationLevel, yoeMatch];\n\ninterface KnockoutPattern {\n signal: string;\n jdPattern: RegExp;\n resumeMatch: (r: ResumeSchema, m: RegExpMatchArray) => boolean;\n recommendation: string;\n}\n\nconst KNOCKOUTS: KnockoutPattern[] = [\n {\n signal: 'work-auth',\n jdPattern:\n /(work\\s*auth|authorization to work|right to work|us citizen|green card|h-?1b|visa sponsorship)/i,\n resumeMatch: (r) =>\n /(work auth|authorized|citizen|green card|visa)/i.test(r.basics?.summary || ''),\n recommendation: 'Confirm authorization status in the application form.',\n },\n {\n signal: 'location',\n jdPattern: /(must be located|on-?site|relocate|based in)\\s+([a-zA-Z ,]+)/i,\n resumeMatch: (r, m) => {\n const jdLoc = (m[2] ?? '').toLowerCase().trim();\n const resumeCity = (r.basics?.location?.city ?? '').toLowerCase().trim();\n if (!jdLoc || !resumeCity) return false;\n return jdLoc.includes(resumeCity) || resumeCity.includes(jdLoc.split(/[, ]+/)[0] ?? '');\n },\n recommendation: 'Verify location requirement against your basics.location.city.',\n },\n {\n signal: 'clearance',\n jdPattern: /(ts\\/sci|secret clearance|security clearance|active clearance)/i,\n resumeMatch: (r) => /clearance/i.test(JSON.stringify(r)),\n recommendation: 'Confirm clearance level on the application form.',\n },\n {\n signal: 'certification',\n jdPattern: /(cissp|aws certified|pmp|ccna|cpa|required certification)/i,\n resumeMatch: (r) => (r.certificates?.length ?? 0) > 0,\n recommendation: 'List required certificates in the certificates section if held.',\n },\n];\n\nexport function extractKnockouts(resume: ResumeSchema, jobDescription: string): KnockoutSignal[] {\n const out: KnockoutSignal[] = [];\n for (const k of KNOCKOUTS) {\n const m = jobDescription.match(k.jdPattern);\n if (!m) continue;\n if (k.resumeMatch(resume, m)) continue;\n out.push({\n signal: k.signal,\n evidence: `JD: \"${m[0]}\"; resume silent.`,\n recommendation: k.recommendation,\n });\n }\n return out;\n}\n","import type { CheckResult, AtsRating, Grade, AtsConfig } from './types';\n\nconst weightMultiplier: Record<'high' | 'medium' | 'low', number> = {\n high: 3,\n medium: 2,\n low: 1,\n};\n\nexport function gradeFromScore(score: number, t: AtsConfig['thresholds']['grade']): Grade {\n if (score >= t.A) return 'A';\n if (score >= t.B) return 'B';\n if (score >= t.C) return 'C';\n if (score >= t.D) return 'D';\n return 'F';\n}\n\nexport function computeTierScore(checks: CheckResult[]): number {\n const active = checks.filter((c) => c.status !== 'skipped');\n if (active.length === 0) return 0;\n let weighted = 0;\n let total = 0;\n for (const c of active) {\n const m = weightMultiplier[c.weight];\n weighted += c.score * m;\n total += 100 * m;\n }\n return total > 0 ? Math.round((weighted / total) * 100) : 0;\n}\n\nexport function computeTotalScore(\n tiers: { parsing: number; match?: number; recruiter: number },\n weights: AtsConfig['weights']['tiers']\n): number {\n if (tiers.match === undefined) {\n const sum = weights.parsing + weights.recruiter;\n const wp = weights.parsing / sum;\n const wr = weights.recruiter / sum;\n return Math.round(\n tiers.parsing * (sum === 50 ? 0.4 : wp) + tiers.recruiter * (sum === 50 ? 0.6 : wr)\n );\n }\n const sum = weights.parsing + weights.match + weights.recruiter;\n return Math.round(\n (tiers.parsing * weights.parsing +\n tiers.match * weights.match +\n tiers.recruiter * weights.recruiter) /\n sum\n );\n}\n\nexport function scoreToRating(score: number, t: AtsConfig['thresholds']['rating']): AtsRating {\n if (score >= t.excellent) return 'excellent';\n if (score >= t.good) return 'good';\n if (score >= t.needsWork) return 'needs-work';\n return 'poor';\n}\n\nexport function generateSummary(\n score: number,\n rating: AtsRating,\n hasJd: boolean,\n knockouts: number\n): string {\n const ratingLabel = {\n excellent: 'Excellent',\n good: 'Good',\n 'needs-work': 'Needs Work',\n poor: 'Poor',\n }[rating];\n const knockoutNote =\n knockouts > 0 ? ` ${knockouts} knockout signal${knockouts === 1 ? '' : 's'} flagged.` : '';\n return `ATS ${score}/100 (${ratingLabel}).${hasJd ? ' Includes JD match.' : ''}${knockoutNote}`;\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport yaml from 'yaml';\nimport { z } from 'zod';\nimport merge from 'lodash.merge';\nimport type { AtsConfig } from '../ats/types';\n\nconst weightEnum = z.enum(['high', 'medium', 'low']);\n\nconst atsConfigSchema = z.object({\n weights: z\n .object({\n tiers: z\n .object({\n parsing: z.number().int().min(0).max(100),\n match: z.number().int().min(0).max(100),\n recruiter: z.number().int().min(0).max(100),\n })\n .partial()\n .optional(),\n checks: z.record(z.string(), weightEnum).optional(),\n })\n .partial()\n .optional(),\n thresholds: z\n .object({\n rating: z\n .object({\n excellent: z.number(),\n good: z.number(),\n needsWork: z.number(),\n })\n .partial()\n .optional(),\n grade: z\n .object({ A: z.number(), B: z.number(), C: z.number(), D: z.number() })\n .partial()\n .optional(),\n seniorYoeCutoff: z.number().int().min(0).optional(),\n wordCount: z\n .object({ min: z.number(), max: z.number(), seniorMax: z.number() })\n .partial()\n .optional(),\n bulletsPerRole: z\n .object({ min: z.number(), max: z.number(), seniorMax: z.number() })\n .partial()\n .optional(),\n })\n .partial()\n .optional(),\n disable: z.array(z.string()).optional(),\n locale: z.string().optional(),\n});\n\nconst fileSchema = z.object({ ats: atsConfigSchema.optional() });\n\nexport const defaultConfig: AtsConfig = {\n weights: {\n tiers: { parsing: 30, match: 50, recruiter: 20 },\n checks: {},\n },\n thresholds: {\n rating: { excellent: 90, good: 75, needsWork: 60 },\n grade: { A: 90, B: 80, C: 70, D: 60 },\n seniorYoeCutoff: 10,\n wordCount: { min: 400, max: 800, seniorMax: 1600 },\n bulletsPerRole: { min: 3, max: 6, seniorMax: 10 },\n },\n disable: [],\n locale: 'en',\n};\n\nexport interface LoadConfigOptions {\n cwd?: string;\n configPath?: string;\n}\n\nexport function loadConfig(opts: LoadConfigOptions = {}): AtsConfig {\n const cwd = opts.cwd ?? process.cwd();\n const file = opts.configPath ?? path.join(cwd, 'resuml.config.yaml');\n if (!fs.existsSync(file)) return defaultConfig;\n\n const raw = fs.readFileSync(file, 'utf8');\n const parsed = (yaml.parse(raw) as unknown) ?? {};\n const result = fileSchema.safeParse(parsed);\n if (!result.success) {\n const issue = result.error.issues[0];\n const where = issue?.path.join('.') ?? '<root>';\n throw new Error(`Invalid resuml.config.yaml at \"${where}\": ${issue?.message}`);\n }\n return merge({}, defaultConfig, result.data.ats ?? {});\n}\n\nexport function effectiveWeight(\n checkId: string,\n defaultWeight: 'high' | 'medium' | 'low',\n config: AtsConfig\n): 'high' | 'medium' | 'low' {\n return config.weights.checks[checkId] ?? defaultWeight;\n}\n","import type { ResumeSchema } from '../types/resume';\nimport type {\n TieredAtsResult,\n AtsOptions,\n CheckResult,\n TierResult,\n Tier,\n AtsConfig,\n KnockoutSignal,\n} from './types';\nimport { allParsingChecks } from './checks/parsing';\nimport { allRecruiterChecks } from './checks/recruiter';\nimport { allMatchChecks, extractKnockouts } from './checks/match';\nimport {\n computeTierScore,\n computeTotalScore,\n gradeFromScore,\n scoreToRating,\n generateSummary,\n} from './scoring';\nimport { defaultConfig, effectiveWeight } from '../utils/config';\n\nfunction applyConfig(checks: CheckResult[], cfg: AtsConfig): CheckResult[] {\n return checks\n .filter((c) => !cfg.disable.includes(c.id))\n .map((c) => ({ ...c, weight: effectiveWeight(c.id, c.weight, cfg) }));\n}\n\nfunction buildTier(_tier: Tier, checks: CheckResult[], cfg: AtsConfig): TierResult {\n const filtered = applyConfig(checks, cfg);\n const score = computeTierScore(filtered);\n return {\n score,\n grade: gradeFromScore(score, cfg.thresholds.grade),\n checks: filtered,\n };\n}\n\nexport function analyzeAts(resume: ResumeSchema, options: AtsOptions = {}): TieredAtsResult {\n const cfg = options.config ?? defaultConfig;\n const language = options.language ?? cfg.locale;\n\n const parsingChecks = allParsingChecks.map((fn) => fn(resume, language));\n\n const recruiterChecks = allRecruiterChecks.map((fn) => fn(resume, language, cfg));\n\n const parsing = buildTier('parsing', parsingChecks, cfg);\n const recruiter = buildTier('recruiter', recruiterChecks, cfg);\n\n let match: TierResult | undefined;\n let knockouts: KnockoutSignal[] = [];\n if (options.jobDescription) {\n const matchChecks = allMatchChecks.map((fn) =>\n fn(resume, language, { jobDescription: options.jobDescription })\n );\n match = buildTier('match', matchChecks, cfg);\n knockouts = extractKnockouts(resume, options.jobDescription);\n }\n\n const totalScore = computeTotalScore(\n { parsing: parsing.score, match: match?.score, recruiter: recruiter.score },\n cfg.weights.tiers\n );\n const rating = scoreToRating(totalScore, cfg.thresholds.rating);\n const summary = generateSummary(totalScore, rating, !!options.jobDescription, knockouts.length);\n\n return {\n score: totalScore,\n rating,\n tiers: match ? { parsing, match, recruiter } : { parsing, recruiter },\n knockouts,\n summary,\n };\n}\n\nexport type { TieredAtsResult, AtsOptions, CheckResult, TierResult, KnockoutSignal } from './types';\n"],"mappings":"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A;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;AC3JA,IAAM,KAAmB;AAAA,EACvB,aAAa;AAAA;AAAA,IAEX;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAEA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAEA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAEA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAEA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAEA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,UAAU,CAAC,KAAK,MAAM,MAAM,QAAQ,UAAU,MAAM,OAAO,MAAM;AAAA,EACjE,WAAW;AAAA;AAAA,IAET;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAEA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAEA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAEA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAEA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAEA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAEA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAEA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAEA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAEA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAEA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAEA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,IAAO,aAAQ;;;AChrBf,IAAM,KAAmB;AAAA,EACvB,aAAa;AAAA;AAAA,IAEX;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAEA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAEA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAEA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAEA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAEA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,UAAU;AAAA,IACR;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,WAAW;AAAA,IACT;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,I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","names":["sum"]}