@singi-labs/sifa-sdk 0.18.9 → 0.18.11
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.
- package/dist/{index-CTzpbW81.d.cts → index-DIwi3bpk.d.cts} +17 -9
- package/dist/{index-CTzpbW81.d.ts → index-DIwi3bpk.d.ts} +17 -9
- package/dist/index.cjs +8 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +35 -13
- package/dist/index.d.ts +35 -13
- package/dist/index.js +8 -3
- package/dist/index.js.map +1 -1
- package/dist/jsonld/index.cjs.map +1 -1
- package/dist/jsonld/index.d.cts +1 -1
- package/dist/jsonld/index.d.ts +1 -1
- package/dist/jsonld/index.js.map +1 -1
- package/dist/{network-map-CKTFPnYE.d.cts → network-map-CH37aj_Q.d.cts} +4 -4
- package/dist/{network-map-BfjOE-C3.d.ts → network-map-CMod-9od.d.ts} +4 -4
- package/dist/{org-CPEFdMmo.d.cts → org-3gFPQ_pC.d.cts} +2 -2
- package/dist/{org-BoLWIj_W.d.ts → org-CTSJ5zTZ.d.ts} +2 -2
- package/dist/{profile-summary-C557t4hr.d.cts → profile-summary-BnydsN4P.d.cts} +1 -1
- package/dist/{profile-summary-Bj_vVxkv.d.ts → profile-summary-H-R1juYp.d.ts} +1 -1
- package/dist/query/fetchers/index.d.cts +6 -6
- package/dist/query/fetchers/index.d.ts +6 -6
- package/dist/query/hooks/index.d.cts +5 -5
- package/dist/query/hooks/index.d.ts +5 -5
- package/dist/query/index.d.cts +8 -8
- package/dist/query/index.d.ts +8 -8
- package/dist/resume/index.cjs.map +1 -1
- package/dist/resume/index.d.cts +1 -1
- package/dist/resume/index.d.ts +1 -1
- package/dist/resume/index.js.map +1 -1
- package/dist/{types-DAEkBwRB.d.cts → types-Co7D0VfD.d.ts} +14 -6
- package/dist/{types-zjv3qDWz.d.ts → types-LElwqDU4.d.cts} +14 -6
- package/dist/{use-org-notification-emails-5oxcxXP9.d.cts → use-org-notification-emails-CdRgTAj4.d.cts} +3 -3
- package/dist/{use-org-notification-emails-LVo7z1M9.d.ts → use-org-notification-emails-J29DcsSu.d.ts} +3 -3
- package/package.json +1 -1
package/dist/jsonld/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/jsonld/term-mappings.json","../../src/jsonld/terms.ts","../../src/format/location-utils.ts","../../src/logic/primary-position.ts","../../src/profile/section-model.ts","../../src/jsonld/url.ts","../../src/jsonld/profile.ts","../../src/format/doi.ts","../../src/format/talk-slug.ts","../../src/jsonld/works.ts","../../src/jsonld/works-graph.ts"],"names":["identity","visible"],"mappings":"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","file":"index.js","sourcesContent":["{\n \"$schema\": \"https://sifa.id/schemas/term-mappings/v1.json\",\n \"version\": \"1.0.0\",\n \"description\": \"Reconciliation between id.sifa.* lexicon terms and existing RDF vocabularies. RDF is used here as vocabulary only: Sifa records are Lexicon JSON on the AT Protocol, and nothing here changes how they are stored or transmitted. Match strengths use SKOS mapping relations.\",\n \"vocabularies\": {\n \"schema\": \"https://schema.org/\",\n \"bibo\": \"http://purl.org/ontology/bibo/\",\n \"dcterms\": \"http://purl.org/dc/terms/\",\n \"foaf\": \"http://xmlns.com/foaf/0.1/\",\n \"org\": \"http://www.w3.org/ns/org#\",\n \"prism\": \"http://prismstandard.org/namespaces/basic/2.1/\",\n \"event\": \"http://purl.org/NET/c4dm/event.owl#\",\n \"skos\": \"http://www.w3.org/2004/02/skos/core#\"\n },\n \"mappings\": [\n {\n \"lexicon\": \"id.sifa.org.profile\",\n \"match\": \"exactMatch\",\n \"terms\": [\"schema:Organization\", \"org:FormalOrganization\"],\n \"note\": \"ROR is the value anchor.\"\n },\n {\n \"lexicon\": \"id.sifa.profile.certification\",\n \"match\": \"exactMatch\",\n \"terms\": [\"schema:EducationalOccupationalCredential\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.certification\",\n \"field\": \"credentialUrl\",\n \"match\": \"exactMatch\",\n \"terms\": [\"schema:url\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.certification\",\n \"field\": \"expiresAt\",\n \"match\": \"exactMatch\",\n \"terms\": [\"schema:validUntil\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.course\",\n \"match\": \"exactMatch\",\n \"terms\": [\"schema:Course\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.course\",\n \"field\": \"number\",\n \"match\": \"exactMatch\",\n \"terms\": [\"schema:courseCode\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.education\",\n \"match\": \"closeMatch\",\n \"terms\": [\"schema:EducationalOccupationalCredential\"],\n \"note\": \"One record maps to two schema.org assertions: alumniOf for the institution and hasCredential for the degree.\"\n },\n {\n \"lexicon\": \"id.sifa.profile.education\",\n \"field\": \"degree\",\n \"match\": \"closeMatch\",\n \"terms\": [\"schema:hasCredential\", \"bibo:degree\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.education\",\n \"field\": \"fieldOfStudy\",\n \"match\": \"closeMatch\",\n \"terms\": [\"schema:educationalCredentialAwarded\"],\n \"note\": \"ISCED-F is the value anchor.\"\n },\n {\n \"lexicon\": \"id.sifa.profile.education\",\n \"field\": \"institution\",\n \"match\": \"exactMatch\",\n \"terms\": [\"schema:alumniOf\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.externalAccount\",\n \"match\": \"exactMatch\",\n \"terms\": [\"schema:sameAs\", \"foaf:account\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.honor\",\n \"match\": \"broadMatch\",\n \"terms\": [\"schema:award\"],\n \"note\": \"schema:award is a bare string, so issuer and date are lost. No better term exists in BIBO either.\"\n },\n {\n \"lexicon\": \"id.sifa.profile.involvement\",\n \"match\": \"broadMatch\",\n \"terms\": [\"org:Membership\"],\n \"note\": \"The kind known values have no external equivalent.\"\n },\n {\n \"lexicon\": \"id.sifa.profile.language\",\n \"match\": \"exactMatch\",\n \"terms\": [\"schema:knowsLanguage\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.position\",\n \"match\": \"closeMatch\",\n \"terms\": [\"org:Membership\", \"schema:OrganizationRole\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.position\",\n \"field\": \"company\",\n \"match\": \"exactMatch\",\n \"terms\": [\"org:organization\", \"schema:worksFor\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.position\",\n \"field\": \"description\",\n \"match\": \"exactMatch\",\n \"terms\": [\"dcterms:description\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.position\",\n \"field\": \"employmentType\",\n \"match\": \"closeMatch\",\n \"terms\": [\"schema:employmentType\"],\n \"note\": \"schema:employmentType is free text. ESCO is the better value anchor.\"\n },\n {\n \"lexicon\": \"id.sifa.profile.position\",\n \"field\": \"endedAt\",\n \"match\": \"exactMatch\",\n \"terms\": [\"schema:endDate\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.position\",\n \"field\": \"entityRef\",\n \"match\": \"closeMatch\",\n \"terms\": [\"schema:sameAs\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.position\",\n \"field\": \"location\",\n \"match\": \"exactMatch\",\n \"terms\": [\"schema:jobLocation\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.position\",\n \"field\": \"startedAt\",\n \"match\": \"exactMatch\",\n \"terms\": [\"schema:startDate\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.position\",\n \"field\": \"title\",\n \"match\": \"exactMatch\",\n \"terms\": [\"org:role\", \"schema:roleName\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.position\",\n \"field\": \"workplaceType\",\n \"match\": \"narrowMatch\",\n \"terms\": [\"schema:jobLocationType\"],\n \"note\": \"schema.org models only a remote flag; Sifa distinguishes onSite, remote, and hybrid.\"\n },\n {\n \"lexicon\": \"id.sifa.profile.presentation\",\n \"match\": \"closeMatch\",\n \"terms\": [\"bibo:Slideshow\", \"schema:PresentationDigitalDocument\"],\n \"note\": \"Neither term carries the \\\"reusable, deliverable more than once\\\" semantics of the Sifa record.\"\n },\n {\n \"lexicon\": \"id.sifa.profile.presentation\",\n \"field\": \"coverImage\",\n \"match\": \"exactMatch\",\n \"terms\": [\"schema:image\", \"foaf:depiction\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.presentation\",\n \"field\": \"description\",\n \"match\": \"exactMatch\",\n \"terms\": [\"bibo:abstract\", \"schema:abstract\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.presentation\",\n \"field\": \"duration\",\n \"match\": \"narrowMatch\",\n \"terms\": [\"schema:timeRequired\"],\n \"note\": \"The lexicon models a range; schema:timeRequired is a single ISO 8601 duration.\"\n },\n {\n \"lexicon\": \"id.sifa.profile.presentation\",\n \"field\": \"intendedAudiences\",\n \"match\": \"closeMatch\",\n \"terms\": [\"schema:audience\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.presentation\",\n \"field\": \"title\",\n \"match\": \"exactMatch\",\n \"terms\": [\"dcterms:title\", \"schema:name\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.presentation\",\n \"field\": \"writeupRef\",\n \"match\": \"closeMatch\",\n \"terms\": [\"dcterms:isReferencedBy\", \"schema:subjectOf\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.presentationDelivery\",\n \"match\": \"closeMatch\",\n \"terms\": [\"schema:Event\", \"event:Event\"],\n \"note\": \"BIBO models this relation as bibo:Slideshow bibo:presentedAt event:Event.\"\n },\n {\n \"lexicon\": \"id.sifa.profile.presentationDelivery\",\n \"field\": \"address\",\n \"match\": \"exactMatch\",\n \"terms\": [\"schema:location\", \"event:place\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.presentationDelivery\",\n \"field\": \"coSpeakers\",\n \"match\": \"exactMatch\",\n \"terms\": [\"schema:performer\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.presentationDelivery\",\n \"field\": \"date\",\n \"match\": \"exactMatch\",\n \"terms\": [\"schema:startDate\", \"event:time\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.presentationDelivery\",\n \"field\": \"eventName\",\n \"match\": \"closeMatch\",\n \"terms\": [\"schema:superEvent\", \"bibo:Conference\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.presentationDelivery\",\n \"field\": \"mode\",\n \"match\": \"exactMatch\",\n \"terms\": [\"schema:eventAttendanceMode\"],\n \"note\": \"The community.lexicon.calendar.event known values are already one-to-one with the schema.org enumeration.\"\n },\n {\n \"lexicon\": \"id.sifa.profile.presentationDelivery\",\n \"field\": \"presentationRef\",\n \"match\": \"closeMatch\",\n \"terms\": [\"bibo:presentedAt\", \"schema:workPerformed\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.presentationDelivery\",\n \"field\": \"role\",\n \"match\": \"closeMatch\",\n \"terms\": [\"bibo:performer\", \"schema:performer\"],\n \"note\": \"No external vocabulary distinguishes presenter, panelist, keynote, workshop and host at this granularity.\"\n },\n {\n \"lexicon\": \"id.sifa.profile.presentationDelivery\",\n \"field\": \"status\",\n \"match\": \"exactMatch\",\n \"terms\": [\"schema:eventStatus\"],\n \"note\": \"As with mode, already one-to-one with the schema.org enumeration.\"\n },\n {\n \"lexicon\": \"id.sifa.profile.presentationDelivery\",\n \"field\": \"title\",\n \"match\": \"exactMatch\",\n \"terms\": [\"dcterms:title\", \"schema:name\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.project\",\n \"match\": \"exactMatch\",\n \"terms\": [\"schema:Project\", \"foaf:Project\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.publication\",\n \"match\": \"broadMatch\",\n \"terms\": [\"bibo:Document\", \"schema:CreativeWork\"],\n \"note\": \"Refine to bibo:AcademicArticle, bibo:Book, bibo:Report or bibo:Thesis when a resource type is known. COAR is the value anchor.\"\n },\n {\n \"lexicon\": \"id.sifa.profile.publication\",\n \"field\": \"authors\",\n \"match\": \"exactMatch\",\n \"terms\": [\"bibo:authorList\", \"schema:author\"],\n \"note\": \"bibo:authorList is an ordered rdf:List and preserves author order, which schema:author does not guarantee.\"\n },\n {\n \"lexicon\": \"id.sifa.profile.publication\",\n \"field\": \"description\",\n \"match\": \"exactMatch\",\n \"terms\": [\"bibo:abstract\", \"schema:abstract\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.publication\",\n \"field\": \"publishedAt\",\n \"match\": \"exactMatch\",\n \"terms\": [\"dcterms:issued\", \"schema:datePublished\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.publication\",\n \"field\": \"publisher\",\n \"match\": \"exactMatch\",\n \"terms\": [\"dcterms:publisher\", \"schema:publisher\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.publication\",\n \"field\": \"subtitle\",\n \"match\": \"closeMatch\",\n \"terms\": [\"schema:alternativeHeadline\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.publication\",\n \"field\": \"title\",\n \"match\": \"exactMatch\",\n \"terms\": [\"dcterms:title\", \"schema:name\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.publication\",\n \"field\": \"url\",\n \"match\": \"exactMatch\",\n \"terms\": [\"bibo:uri\", \"schema:url\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.self\",\n \"match\": \"exactMatch\",\n \"terms\": [\"schema:Person\", \"foaf:Person\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.self\",\n \"field\": \"about\",\n \"match\": \"exactMatch\",\n \"terms\": [\"schema:description\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.self\",\n \"field\": \"avatar\",\n \"match\": \"exactMatch\",\n \"terms\": [\"schema:image\", \"foaf:depiction\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.self\",\n \"field\": \"displayName\",\n \"match\": \"exactMatch\",\n \"terms\": [\"schema:name\", \"foaf:name\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.self\",\n \"field\": \"familyName\",\n \"match\": \"exactMatch\",\n \"terms\": [\"schema:familyName\", \"foaf:family_name\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.self\",\n \"field\": \"givenName\",\n \"match\": \"exactMatch\",\n \"terms\": [\"schema:givenName\", \"foaf:givenname\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.self\",\n \"field\": \"headline\",\n \"match\": \"closeMatch\",\n \"terms\": [\"schema:jobTitle\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.self\",\n \"field\": \"location\",\n \"match\": \"closeMatch\",\n \"terms\": [\"schema:homeLocation\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.skill\",\n \"match\": \"closeMatch\",\n \"terms\": [\"schema:knowsAbout\", \"schema:DefinedTerm\"],\n \"note\": \"ESCO is the value anchor.\"\n },\n {\n \"lexicon\": \"id.sifa.profile.volunteering\",\n \"match\": \"closeMatch\",\n \"terms\": [\"org:Membership\", \"schema:OrganizationRole\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.publication\",\n \"field\": \"doi\",\n \"terms\": [\"bibo:doi\", \"prism:doi\"],\n \"match\": \"exactMatch\",\n \"note\": \"Present on the AppView view type (ORCID-sourced), not yet on the id.sifa.profile.publication lexicon, so user-authored publications cannot carry one.\"\n }\n ],\n \"unmapped\": [\n {\n \"lexicon\": \"id.sifa.profile.self\",\n \"field\": \"pronouns\",\n \"reason\": \"No stable external term. schema.org has no pronouns property.\"\n },\n {\n \"lexicon\": \"id.sifa.profile.self\",\n \"field\": \"discoverable\",\n \"reason\": \"Sifa indexing control, not a fact about the person.\"\n },\n {\n \"lexicon\": \"id.sifa.profile.position\",\n \"field\": \"isPrimary\",\n \"reason\": \"Sifa display ordering concern.\"\n },\n {\n \"lexicon\": \"id.sifa.profile.education\",\n \"field\": \"grade\",\n \"reason\": \"No comparable external term; grading scales are not portable.\"\n },\n {\n \"lexicon\": \"id.sifa.profile.language\",\n \"field\": \"proficiency\",\n \"reason\": \"The known values are CEFR-shaped but not CEFR-named. Map only; renaming a published lexicon for a cosmetic gain is not worth the break.\"\n },\n {\n \"lexicon\": \"id.sifa.confirmation\",\n \"reason\": \"A record affirming another record is reification. schema:Review and schema:ClaimReview both imply an evaluation that a confirmation does not make.\"\n },\n {\n \"lexicon\": \"id.sifa.endorsement\",\n \"reason\": \"Same reification problem as confirmation. Any mapping that lets a consumer aggregate endorsements into a score works against the descriptive-only trust model.\"\n },\n {\n \"lexicon\": \"id.sifa.graph.connection\",\n \"reason\": \"foaf:knows carries no consent semantics. A Sifa connection is bilateral and confirmed; flattening it to foaf:knows would misrepresent an unconfirmed acquaintance claim as mutual.\"\n },\n {\n \"lexicon\": \"id.sifa.graph.follow\",\n \"reason\": \"See id.sifa.graph.connection.\"\n },\n {\n \"lexicon\": \"id.sifa.meeting\",\n \"reason\": \"Attestation semantics; same reification problem as confirmation.\"\n }\n ]\n}\n","/**\n * Reconciliation between `id.sifa.*` lexicon terms and existing RDF\n * vocabularies.\n *\n * The facts live in sifa-lexicons, as `x-skos:*` annotations on the lexicon\n * defs and properties. Those annotations are published to the authority PDS,\n * so a third party resolving `id.sifa.*` already reads them; that makes the\n * lexicons the source of truth and `./term-mappings.json` a derived copy,\n * refreshed by `scripts/sync-term-mappings.mjs` and drift-checked in CI.\n *\n * To change a mapping, change the lexicon, not this file.\n *\n * Scope note: RDF is adopted here as *vocabulary only*. Sifa records are\n * Lexicon JSON on the AT Protocol; nothing in this module changes how records\n * are stored or transmitted. A mapping is a one-directional annotation over a\n * lexicon designed on its own merits, never a constraint on lexicon design.\n * When a term does not fit, the correct answer is `noMatch`, not a different\n * lexicon.\n */\n\nimport document from './term-mappings.json';\n\n/** Vocabulary prefix -> namespace IRI. */\nexport const VOCABULARIES: Readonly<Record<string, string>> = document.vocabularies;\n\nexport type VocabularyPrefix = keyof typeof document.vocabularies;\n\n/**\n * Strength of a mapping, using SKOS mapping relations so the table is itself\n * expressible as RDF.\n *\n * `noMatch` is not the absence of an entry. It is a deliberate statement that\n * no external term should be used for this concept, and it carries a reason.\n */\nexport type MatchStrength =\n 'exactMatch' | 'closeMatch' | 'broadMatch' | 'narrowMatch' | 'relatedMatch' | 'noMatch';\n\nexport interface TermMapping {\n /** Lexicon NSID, e.g. `id.sifa.profile.presentation`. */\n readonly lexicon: string;\n /**\n * Field name within the record. Omitted for a record-level class mapping\n * (what the record *is*, rather than what one of its fields means).\n */\n readonly field?: string;\n /** CURIEs, e.g. `dcterms:title`. Empty when `match` is `noMatch`. */\n readonly terms: readonly string[];\n readonly match: MatchStrength;\n /** Rationale. Always present when `match` is `noMatch`. */\n readonly note?: string;\n}\n\ninterface RawMapping {\n lexicon: string;\n field?: string;\n terms: string[];\n match: string;\n note?: string;\n}\n\ninterface RawUnmapped {\n lexicon: string;\n field?: string;\n reason: string;\n}\n\n/**\n * Every reconciliation Sifa asserts, including the deliberate non-mappings.\n *\n * The published document splits these into `mappings` and `unmapped`, which\n * reads better over the wire. Callers here want one list, so they are\n * flattened back together.\n */\nexport const TERM_MAPPINGS: readonly TermMapping[] = [\n ...(document.mappings as RawMapping[]).map((m): TermMapping => ({\n lexicon: m.lexicon,\n ...(m.field ? { field: m.field } : {}),\n terms: m.terms,\n match: m.match as MatchStrength,\n ...(m.note ? { note: m.note } : {}),\n })),\n ...(document.unmapped as RawUnmapped[]).map((u): TermMapping => ({\n lexicon: u.lexicon,\n ...(u.field ? { field: u.field } : {}),\n terms: [],\n match: 'noMatch',\n note: u.reason,\n })),\n];\n\n/**\n * Expand a CURIE (`dcterms:title`) to a full IRI. Returns null for an unknown\n * prefix rather than guessing a namespace.\n */\nexport function expandCurie(curie: string): string | null {\n const separator = curie.indexOf(':');\n if (separator <= 0) return null;\n const prefix = curie.slice(0, separator);\n const local = curie.slice(separator + 1);\n if (!local) return null;\n if (!Object.prototype.hasOwnProperty.call(VOCABULARIES, prefix)) return null;\n return `${VOCABULARIES[prefix]}${local}`;\n}\n\n/** All mappings declared for one lexicon NSID, record level and field level. */\nexport function mappingsForLexicon(nsid: string): readonly TermMapping[] {\n return TERM_MAPPINGS.filter((m) => m.lexicon === nsid);\n}\n\n/** True when Sifa has deliberately declined to map this lexicon or field. */\nexport function isDeliberatelyUnmapped(nsid: string, field?: string): boolean {\n return TERM_MAPPINGS.some(\n (m) => m.lexicon === nsid && m.field === field && m.match === 'noMatch',\n );\n}\n","import type { LocationValue } from '../types/index.js';\n\n/**\n * Format a LocationValue for display.\n *\n * Prefers `locality` (the community.lexicon.location.address field) and\n * falls back to the legacy `city` slot so values produced before the\n * sifa-api alias migration still render correctly during the additive\n * transition window.\n */\nexport function formatLocation(loc: LocationValue | null | undefined): string {\n if (!loc) return '';\n const locality = loc.locality ?? loc.city;\n const parts = [locality, loc.region, loc.country].filter(Boolean);\n if (loc.postalCode && !locality) {\n return `${loc.postalCode}, ${loc.country}`;\n }\n return parts.join(', ');\n}\n\n/** Parse a display string back into a LocationValue (best-effort for legacy data) */\nexport function parseLocationString(str: string): LocationValue | null {\n if (!str.trim()) return null;\n const parts = str\n .split(',')\n .map((p) => p.trim())\n .filter(Boolean);\n if (parts.length >= 3) {\n return {\n city: parts[0],\n region: parts[1],\n country: parts[parts.length - 1]!,\n };\n }\n if (parts.length === 2) {\n return {\n city: parts[0],\n country: parts[1]!,\n };\n }\n return { country: parts[0]! };\n}\n\n/** Convert ISO 3166-1 alpha-2 country code to flag emoji */\nexport function countryCodeToFlag(code: string | undefined): string {\n if (!code || code.length !== 2) return '';\n const upper = code.toUpperCase();\n const a = upper.codePointAt(0);\n const b = upper.codePointAt(1);\n if (a === undefined || b === undefined) return '';\n return String.fromCodePoint(a - 0x41 + 0x1f1e6, b - 0x41 + 0x1f1e6);\n}\n","/**\n * Canonical rule for picking the \"primary\" position to surface on profile cards,\n * social previews, and structured-data outputs.\n *\n * Without this shared helper, different surfaces (visible hero, OG image,\n * <meta description>, JSON-LD) re-derived \"primary\" inconsistently and diverged\n * for users with multiple concurrent roles.\n *\n * A `hidden` position is one the user chose not to show on their public profile.\n * It is never surfaced as the featured role — hidden wins over `primary`, so a\n * role flagged both hidden and primary is excluded rather than featured.\n *\n * Rules (in order):\n * 1. A position the user explicitly flagged `primary` AND that is still active AND not hidden.\n * 2. Otherwise, the active, non-hidden position with the most recent `startedAt`.\n * 3. Otherwise, undefined (no eligible position).\n */\n\nexport interface PrimaryPositionCandidate {\n startedAt?: string;\n endedAt?: string;\n primary?: boolean;\n hidden?: boolean;\n}\n\nexport function pickPrimaryPosition<T extends PrimaryPositionCandidate>(\n positions: readonly T[] | undefined,\n): T | undefined {\n if (!positions || positions.length === 0) return undefined;\n\n const active = positions.filter((p) => !p.endedAt && !p.hidden);\n if (active.length === 0) return undefined;\n\n const flagged = active.find((p) => p.primary === true);\n if (flagged) return flagged;\n\n return [...active].sort((a, b) => (b.startedAt ?? '').localeCompare(a.startedAt ?? ''))[0];\n}\n","/**\n * Shared, single-source-of-truth model for which profile sections render, in\n * what order, their nav grouping, and which items a given viewer may see.\n *\n * Every Sifa profile surface builds on this: the HTML profile page, the\n * Markdown / DOCX / print exports, and the standalone personal-site renderer.\n * Adding a section to {@link ALL_SECTIONS} makes it appear everywhere (the\n * exports drive presence + order from here, and {@link SECTION_LABELS} is an\n * exhaustive `Record<SectionId, string>`, so a new id is a compile error until\n * it has a label).\n *\n * The per-section sorts live in `./section-sorts.js`, built on the same SDK\n * date extractors the HTML section components use, so the surfaces cannot\n * diverge on ordering.\n */\n\nimport type { Profile } from '../types/index.js';\n\n/**\n * Side-nav groups, in display order. Each labels a contiguous run of sections\n * in {@link ALL_SECTIONS}. `labelKey` resolves against the consumer's `sections`\n * i18n namespace.\n */\nexport const SECTION_GROUPS = [\n { id: 'overview', labelKey: 'groupOverview' },\n { id: 'experience', labelKey: 'groupExperience' },\n { id: 'qualifications', labelKey: 'groupQualifications' },\n { id: 'more', labelKey: 'groupMore' },\n] as const;\n\nexport type SectionGroupId = (typeof SECTION_GROUPS)[number]['id'];\n\n/**\n * Profile body sections in render + nav order (evidence-first): identity and\n * activity lead, then living work (career, skills, projects, talks,\n * publications), then the formal record (credentials, education, courses), then\n * the rest. `ns` selects the consumer's i18n namespace for `labelKey`; `group`\n * ties the section to a {@link SECTION_GROUPS} header.\n */\nexport const ALL_SECTIONS = [\n { id: 'about', labelKey: 'about', ns: 'profile' as const, group: 'overview' as const },\n { id: 'career', labelKey: 'career', ns: 'sections' as const, group: 'experience' as const },\n { id: 'skills', labelKey: 'skills', ns: 'sections' as const, group: 'experience' as const },\n { id: 'projects', labelKey: 'projects', ns: 'sections' as const, group: 'experience' as const },\n {\n id: 'presentations',\n labelKey: 'talksAndSessions',\n ns: 'sections' as const,\n group: 'experience' as const,\n },\n {\n id: 'publications',\n labelKey: 'publications',\n ns: 'sections' as const,\n group: 'experience' as const,\n },\n {\n id: 'credentials',\n labelKey: 'credentials',\n ns: 'sections' as const,\n group: 'qualifications' as const,\n },\n {\n id: 'education',\n labelKey: 'education',\n ns: 'sections' as const,\n group: 'qualifications' as const,\n },\n { id: 'courses', labelKey: 'courses', ns: 'sections' as const, group: 'qualifications' as const },\n { id: 'awards', labelKey: 'awards', ns: 'sections' as const, group: 'more' as const },\n { id: 'involvement', labelKey: 'involvement', ns: 'sections' as const, group: 'more' as const },\n // Its own section rather than a group under involvement: that record is about\n // work contributed, this one about capital deployed.\n { id: 'investments', labelKey: 'investments', ns: 'sections' as const, group: 'more' as const },\n { id: 'languages', labelKey: 'languages', ns: 'sections' as const, group: 'more' as const },\n {\n id: 'other-profiles',\n labelKey: 'otherProfiles',\n ns: 'sections' as const,\n group: 'more' as const,\n },\n] as const;\n\n/** Every profile section id, in canonical render order. */\nexport type SectionId = (typeof ALL_SECTIONS)[number]['id'];\n\n/** Whether a section has content for a given profile (used to hide empty nav entries for visitors). */\nexport function isSectionPopulated(profile: Profile, id: string): boolean {\n switch (id) {\n case 'about':\n return Boolean(profile.about && profile.headline);\n case 'career':\n return Boolean(profile.positions?.length);\n case 'education':\n return Boolean(profile.education?.length);\n case 'courses':\n return Boolean(profile.courses?.length);\n case 'skills':\n return Boolean(profile.skills?.length);\n case 'projects':\n return Boolean(profile.projects?.length);\n case 'credentials':\n return Boolean(profile.certifications?.length);\n case 'publications':\n return Boolean(profile.publications?.length);\n case 'presentations':\n return (\n Boolean(profile.presentations?.length) || Boolean(profile.presentationDeliveries?.length)\n );\n case 'involvement':\n return Boolean(profile.involvement?.length);\n case 'investments':\n return Boolean(profile.investments?.length);\n case 'awards':\n return Boolean(profile.honors?.length);\n case 'languages':\n return Boolean(profile.languages?.length);\n case 'other-profiles':\n return Boolean(profile.externalAccounts?.length);\n default:\n return false;\n }\n}\n\n/**\n * The section ids a given viewer should see, in {@link ALL_SECTIONS} order.\n * Owners see every section; visitors only see populated ones.\n */\nexport function getVisibleSectionIds(profile: Profile, isOwnProfile: boolean): SectionId[] {\n return ALL_SECTIONS.map((s) => s.id).filter(\n (id) => isOwnProfile || isSectionPopulated(profile, id),\n );\n}\n\n/** Drop items the owner has hidden from visitors. */\nexport function filterHidden<T extends { hidden?: boolean }>(items: T[] | undefined): T[] {\n return (items ?? []).filter((i) => !i.hidden);\n}\n\n/**\n * Items visible to a given viewer: owners see their own hidden items, visitors\n * do not. Shared by every export format (markdown, docx, print) and the public\n * `.md` route so the hidden rule lives in one place.\n */\nexport function visibleItems<T extends { hidden?: boolean }>(\n items: T[] | undefined,\n isOwnProfile: boolean,\n): T[] {\n return isOwnProfile ? (items ?? []) : filterHidden(items);\n}\n\n/**\n * English heading text for each section, keyed by {@link SectionId} (e.g.\n * `other-profiles` renders as \"Links\"). Exhaustive `Record<SectionId, string>`:\n * adding a section to {@link ALL_SECTIONS} without a label here is a compile\n * error, so a section can never silently render without (or with a stale)\n * heading. Consumers with i18n resolve their own localized labels via\n * `labelKey`; this is the canonical English fallback used by the exports.\n */\nexport const SECTION_LABELS: Record<SectionId, string> = {\n about: 'About',\n career: 'Career',\n skills: 'Skills',\n projects: 'Projects',\n presentations: 'Talks & sessions',\n publications: 'Publications',\n credentials: 'Credentials',\n education: 'Education',\n courses: 'Courses',\n awards: 'Awards',\n involvement: 'Involvement',\n investments: 'Investments',\n languages: 'Languages',\n 'other-profiles': 'Links',\n};\n","/** Shared URL helpers for the JSON-LD emitters. */\n\nexport const DEFAULT_BASE_URL = 'https://sifa.id';\n\n/**\n * Drop trailing slashes from a caller-supplied base URL.\n *\n * Written as a scan rather than `replace(/\\/+$/, '')` on purpose: the regex\n * form is a polynomial-backtracking hazard on input the library does not\n * control (CodeQL js/polynomial-redos). This runs in linear time.\n */\nexport function normaliseBaseUrl(baseUrl: string | undefined): string {\n const value = baseUrl ?? DEFAULT_BASE_URL;\n let end = value.length;\n while (end > 0 && value.charCodeAt(end - 1) === 0x2f) end -= 1;\n return value.slice(0, end);\n}\n\nexport function profileUrl(baseUrl: string, handle: string): string {\n return `${baseUrl}/p/${handle}`;\n}\n","/**\n * Schema.org JSON-LD for a Sifa profile.\n *\n * Ported from sifa-web's `src/lib/jsonld.ts` so that sifa.id, page.sifa.id and\n * any future consumer emit the same graph from one implementation. Term choices\n * are recorded in `./terms.js`.\n *\n * These are pure functions: no fetching, no DOM, no framework.\n */\n\nimport { formatLocation } from '../format/location-utils.js';\nimport { pickPrimaryPosition } from '../logic/primary-position.js';\nimport { filterHidden } from '../profile/section-model.js';\nimport type { LocationValue } from '../types/index.js';\nimport { normaliseBaseUrl } from './url.js';\n\n/**\n * Maximum number of skills emitted into `knowsAbout`. The rendered profile\n * still shows every skill; only this structured-data slot is capped so a\n * profile with many skills does not read as keyword stuffing.\n */\nconst MAX_KNOWS_ABOUT = 20;\n\n/**\n * Treat headlines and about text as meaningful only when they contain at least\n * one letter or digit. Profiles carry headlines that are a single emoji and\n * about fields that are a zero-width space; feeding those to `jobTitle` or\n * `description` produces garbage for crawlers.\n */\nconst MEANINGFUL_TEXT_RE = /[\\p{L}\\p{N}]/u;\n\nexport type Sanitizer = (input: string) => string;\n\nexport interface JsonLdOptions {\n /** Canonical origin for profile URLs. Defaults to `https://sifa.id`. */\n readonly baseUrl?: string;\n /** Applied to every user-authored string. Defaults to identity. */\n readonly sanitize?: Sanitizer;\n /**\n * Absolute URL of the page this graph describes, used for `url` and `@id`.\n * Defaults to `${baseUrl}/p/${handle}`. Personal sites can be served from an\n * arbitrary host, including a self-hosted custom domain, where that default\n * path is not where the page lives.\n */\n readonly canonicalUrl?: string;\n}\n\n/**\n * Structural input for the emitters.\n *\n * Deliberately looser than `Profile`: it accepts a `Profile` unchanged, but\n * also the partial shapes held by consumers that render a subset (page.sifa.id)\n * without forcing them to fabricate required fields.\n */\nexport interface JsonLdProfileInput {\n readonly handle: string;\n readonly displayName?: string;\n readonly givenName?: string;\n readonly familyName?: string;\n readonly headline?: string;\n readonly about?: string;\n readonly avatar?: string;\n readonly website?: string;\n readonly location?: LocationValue | null;\n readonly updatedAt?: string;\n readonly positions?: readonly JsonLdPosition[];\n readonly education?: readonly JsonLdEducation[];\n readonly skills?: readonly JsonLdSkill[];\n readonly certifications?: readonly JsonLdCertification[];\n readonly volunteering?: readonly JsonLdVolunteering[];\n readonly honors?: readonly JsonLdHonor[];\n readonly languages?: readonly JsonLdLanguage[];\n readonly verifiedAccounts?: readonly { platform: string; identifier: string; url?: string }[];\n readonly activeApps?: readonly { id: string }[];\n /** Only the length is read, to decide which section anchors to advertise. */\n readonly projects?: readonly unknown[];\n readonly publications?: readonly unknown[];\n readonly courses?: readonly unknown[];\n readonly externalAccounts?: readonly unknown[];\n /**\n * Dual-facet accounts: one DID presenting as both a person and a company.\n * Only the opted-in case is emitted, see `buildPersonJsonLd`.\n */\n readonly org?: {\n readonly personalProfileVisible?: boolean;\n readonly orgProfile?: { readonly name?: string } | null;\n } | null;\n}\n\ninterface Hideable {\n readonly hidden?: boolean;\n}\nexport interface JsonLdPosition extends Hideable {\n readonly company?: string;\n /**\n * Current canonical name of the linked company entity, resolved by the\n * AppView at read time. Preferred over the free-text `company` snapshot for\n * `worksFor.name` so structured data names the corrected (and decoded) entity.\n */\n readonly entityName?: string;\n readonly title?: string;\n readonly startedAt?: string;\n readonly endedAt?: string;\n readonly description?: string;\n readonly primary?: boolean;\n}\nexport interface JsonLdEducation extends Hideable {\n readonly institution?: string;\n readonly degree?: string;\n readonly fieldOfStudy?: string;\n}\nexport interface JsonLdSkill extends Hideable {\n readonly name?: string;\n readonly endorsementCount?: number;\n}\nexport interface JsonLdCertification extends Hideable {\n readonly name?: string;\n readonly authority?: string;\n readonly issuingOrg?: string;\n readonly credentialUrl?: string;\n}\nexport interface JsonLdVolunteering extends Hideable {\n readonly organization?: string;\n readonly role?: string;\n readonly startDate?: string;\n readonly endDate?: string;\n}\nexport interface JsonLdHonor extends Hideable {\n readonly title?: string;\n}\nexport interface JsonLdLanguage extends Hideable {\n readonly language?: string;\n}\n\nconst identity: Sanitizer = (input) => input;\n\nfunction hasMeaningfulText(value: string | undefined | null): value is string {\n return typeof value === 'string' && MEANINGFUL_TEXT_RE.test(value);\n}\n\n/** `filterHidden` takes a mutable array; the input types are readonly. */\nfunction visible<T extends Hideable>(items: readonly T[] | undefined): T[] {\n return filterHidden(items ? [...items] : undefined);\n}\n\n/**\n * Selects and ranks the skills surfaced in `knowsAbout`. Ordered by endorsement\n * count descending, a missing count counting as zero, ties preserving input\n * order. Returns undefined when no named skill exists so the property is\n * omitted entirely rather than emitted empty.\n */\nfunction rankKnowsAbout(\n skills: readonly JsonLdSkill[] | undefined,\n s: Sanitizer,\n): string[] | undefined {\n const ranked = visible(skills)\n .filter((sk): sk is JsonLdSkill & { name: string } => Boolean(sk.name))\n .sort((a, b) => (b.endorsementCount ?? 0) - (a.endorsementCount ?? 0))\n .slice(0, MAX_KNOWS_ABOUT)\n .map((sk) => s(sk.name));\n\n return ranked.length > 0 ? ranked : undefined;\n}\n\nfunction buildSameAs(profile: JsonLdProfileInput): string[] {\n const sameAs: string[] = [];\n\n // ATproto is multi-app: a Sifa identity may hold no Bluesky records at all.\n // Only link bsky.app when activeApps confirms Bluesky presence, otherwise the\n // link points at an empty profile and weakens entity resolution rather than\n // strengthening it.\n const hasBluesky = profile.activeApps?.some((a) => a.id === 'bluesky') ?? false;\n if (hasBluesky) sameAs.push(`https://bsky.app/profile/${profile.handle}`);\n\n if (profile.website) {\n const url = profile.website.startsWith('http') ? profile.website : `https://${profile.website}`;\n if (!sameAs.includes(url)) sameAs.push(url);\n }\n\n for (const account of profile.verifiedAccounts ?? []) {\n if (account.url && !sameAs.includes(account.url)) sameAs.push(account.url);\n }\n\n return sameAs;\n}\n\nfunction buildHomeLocation(location: LocationValue, s: Sanitizer) {\n // Emit the address sub-object when either a country code or a locality is\n // present. Locality prefers the community-shape `locality` with a fallback to\n // the legacy `city` so output stays correct whichever shape the AppView emits.\n const addressLocality = location.locality ?? location.city;\n const addressCountry = location.countryCode;\n const hasAddress = Boolean(addressLocality) || Boolean(addressCountry);\n\n return {\n '@type': 'Place' as const,\n name: s(formatLocation(location)),\n ...(hasAddress && {\n address: {\n '@type': 'PostalAddress' as const,\n ...(addressLocality && { addressLocality: s(addressLocality) }),\n ...(addressCountry && { addressCountry }),\n },\n }),\n };\n}\n\nexport function buildPersonJsonLd(profile: JsonLdProfileInput, options: JsonLdOptions = {}) {\n const s = options.sanitize ?? identity;\n const baseUrl = normaliseBaseUrl(options.baseUrl);\n // The own-company link below deliberately keeps the baseUrl origin: a /c/\n // page lives on Sifa even when the personal site does not.\n const canonical = options.canonicalUrl ?? `${baseUrl}/p/${profile.handle}`;\n\n const positions = visible(profile.positions);\n const currentPosition = pickPrimaryPosition(positions);\n const knowsAbout = rankKnowsAbout(profile.skills, s);\n const sameAs = buildSameAs(profile);\n\n const hasCredential = [\n ...visible(profile.education)\n .filter((e) => e.degree)\n .map((e) => ({\n '@type': 'EducationalOccupationalCredential' as const,\n credentialCategory: 'degree' as const,\n name: [e.degree, e.fieldOfStudy].filter(Boolean).join(' '),\n ...(e.institution && {\n recognizedBy: { '@type': 'EducationalOrganization' as const, name: s(e.institution) },\n }),\n })),\n ...visible(profile.certifications)\n .filter((c) => c.name)\n .map((c) => ({\n '@type': 'EducationalOccupationalCredential' as const,\n name: s(c.name!),\n ...((c.authority ?? c.issuingOrg) && {\n recognizedBy: {\n '@type': 'Organization' as const,\n name: s((c.authority ?? c.issuingOrg)!),\n },\n }),\n ...(c.credentialUrl && { url: c.credentialUrl }),\n })),\n ];\n\n // Prefer the structured name when both halves are present so `name` stays\n // consistent with the explicit givenName/familyName properties.\n const givenTrimmed = profile.givenName?.trim();\n const familyTrimmed = profile.familyName?.trim();\n const structuredName =\n givenTrimmed && familyTrimmed ? `${givenTrimmed} ${familyTrimmed}` : undefined;\n\n // A sole trader who kept both faces is one legal person and one business on\n // a single DID. Without an explicit link a crawler reads the /p/ Person and\n // the /c/ Organization as two unrelated entities that happen to share a\n // domain. The company goes first: it is the account's own business, ahead of\n // any self-reported position elsewhere.\n const ownCompany =\n profile.org?.personalProfileVisible && profile.org.orgProfile\n ? {\n '@type': 'Organization' as const,\n '@id': `${baseUrl}/c/${profile.handle}`,\n name: s(profile.org.orgProfile.name ?? profile.handle),\n }\n : null;\n const worksFor = [\n ...(ownCompany ? [ownCompany] : []),\n ...positions\n .filter((p) => p.entityName ?? p.company)\n .map((p) => ({\n '@type': 'Organization' as const,\n name: s((p.entityName ?? p.company)!),\n ...(p.title && {\n member: {\n '@type': 'OrganizationRole' as const,\n roleName: s(p.title),\n ...(p.startedAt && { startDate: p.startedAt }),\n ...(p.endedAt && { endDate: p.endedAt }),\n },\n }),\n })),\n ];\n\n const awards = visible(profile.honors)\n .filter((h) => h.title)\n .map((h) => s(h.title!));\n const languages = visible(profile.languages)\n .filter((l) => l.language)\n .map((l) => l.language!);\n\n return {\n '@context': 'https://schema.org',\n '@type': 'Person',\n // Stable identifier so a /c/ Organization's `founder` can point back here.\n '@id': canonical,\n name: s(structuredName ?? profile.displayName ?? profile.handle),\n ...(givenTrimmed && { givenName: s(givenTrimmed) }),\n ...(familyTrimmed && { familyName: s(familyTrimmed) }),\n jobTitle: hasMeaningfulText(profile.headline)\n ? s(profile.headline)\n : currentPosition?.title\n ? s(currentPosition.title)\n : undefined,\n description: hasMeaningfulText(profile.about) ? s(profile.about) : undefined,\n alternateName: `@${profile.handle}`,\n url: canonical,\n image: profile.avatar ?? undefined,\n ...(profile.location && { homeLocation: buildHomeLocation(profile.location, s) }),\n ...(worksFor.length > 0 && { worksFor }),\n ...(visible(profile.education).length > 0 && {\n alumniOf: visible(profile.education)\n .filter((e) => e.institution)\n .map((e) => ({ '@type': 'EducationalOrganization' as const, name: s(e.institution!) })),\n }),\n ...(hasCredential.length > 0 && { hasCredential }),\n ...(visible(profile.volunteering).length > 0 && {\n memberOf: visible(profile.volunteering)\n .filter((v) => v.organization)\n .map((v) => ({\n '@type': 'OrganizationRole' as const,\n memberOf: { '@type': 'Organization' as const, name: s(v.organization!) },\n ...(v.role && { roleName: s(v.role) }),\n ...(v.startDate && { startDate: v.startDate }),\n ...(v.endDate && { endDate: v.endDate }),\n })),\n }),\n ...(awards.length > 0 && { award: awards }),\n ...(languages.length > 0 && { knowsLanguage: languages }),\n ...(knowsAbout && { knowsAbout }),\n ...(sameAs.length > 0 && { sameAs }),\n };\n}\n\n/**\n * Section anchors are a soft public API: third-party tools link to `#career`,\n * `#languages` and friends. Renaming one is a breaking change. Each id MUST\n * match the DOM id rendered by the consuming app.\n */\nconst PROFILE_SECTION_HAS_PART: readonly {\n id: string;\n label: string;\n populated: (p: JsonLdProfileInput) => boolean;\n}[] = [\n { id: 'about', label: 'About', populated: (p) => Boolean(p.about && p.headline) },\n { id: 'career', label: 'Career', populated: (p) => visible(p.positions).length > 0 },\n { id: 'education', label: 'Education', populated: (p) => visible(p.education).length > 0 },\n { id: 'projects', label: 'Projects', populated: (p) => (p.projects?.length ?? 0) > 0 },\n {\n id: 'credentials',\n label: 'Credentials',\n populated: (p) => visible(p.certifications).length > 0,\n },\n {\n id: 'publications',\n label: 'Publications',\n populated: (p) => (p.publications?.length ?? 0) > 0,\n },\n {\n id: 'volunteering',\n label: 'Volunteering',\n populated: (p) => visible(p.volunteering).length > 0,\n },\n { id: 'awards', label: 'Awards', populated: (p) => visible(p.honors).length > 0 },\n { id: 'languages', label: 'Languages', populated: (p) => visible(p.languages).length > 0 },\n { id: 'skills', label: 'Skills', populated: (p) => visible(p.skills).length > 0 },\n {\n id: 'other-profiles',\n label: 'Other profiles',\n populated: (p) => (p.externalAccounts?.length ?? 0) > 0,\n },\n];\n\nexport function buildProfilePageJsonLd(profile: JsonLdProfileInput, options: JsonLdOptions = {}) {\n const person = buildPersonJsonLd(profile, options);\n const { '@context': _context, ...personWithoutContext } = person;\n\n const url = options.canonicalUrl ?? `${normaliseBaseUrl(options.baseUrl)}/p/${profile.handle}`;\n const hasPart = PROFILE_SECTION_HAS_PART.filter((section) => section.populated(profile)).map(\n (section) => ({\n '@type': 'WebPageElement' as const,\n name: section.label,\n url: `${url}#${section.id}`,\n }),\n );\n\n return {\n '@context': 'https://schema.org',\n '@type': 'ProfilePage' as const,\n url,\n ...(profile.updatedAt && { dateModified: profile.updatedAt }),\n mainEntity: personWithoutContext,\n ...(hasPart.length > 0 && { hasPart }),\n };\n}\n\nexport function buildBreadcrumbListJsonLd(\n profile: Pick<JsonLdProfileInput, 'handle' | 'displayName'>,\n options: JsonLdOptions = {},\n) {\n const s = options.sanitize ?? identity;\n const baseUrl = normaliseBaseUrl(options.baseUrl);\n const name = s(profile.displayName ?? profile.handle);\n\n return {\n '@context': 'https://schema.org',\n '@type': 'BreadcrumbList' as const,\n itemListElement: [\n { '@type': 'ListItem' as const, position: 1, name: 'Sifa', item: `${baseUrl}/` },\n {\n '@type': 'ListItem' as const,\n position: 2,\n name,\n item: `${baseUrl}/p/${profile.handle}`,\n },\n ],\n };\n}\n","/**\n * Reduce a DOI to its bare form: `10.1234/example`, never\n * `https://doi.org/10.1234/example` and never `doi:10.1234/example`.\n *\n * A DOI inside a URL is a link. Bare, it is an identifier, which is what lets\n * two records describing one publication be matched on it. The lexicon stores\n * the bare form for that reason.\n *\n * People paste the resolver URL, because that is what a publisher page and a\n * citation manager both hand you, and citations carry the `doi:` scheme.\n * Normalizing on the way in is the difference between a field that dedupes and\n * a field holding three spellings of one value.\n *\n * Input that is not a DOI at all is trimmed and returned as-is. This is a\n * normalizer, not a validator: rejecting here would fail a write over a field\n * nothing depends on, and older registrants produce shapes worth not policing.\n */\nexport function normalizeDoi(value: string): string {\n return value\n .trim()\n .replace(/^https?:\\/\\/(dx\\.)?doi\\.org\\//i, '')\n .replace(/^doi:\\s*/i, '');\n}\n","/**\n * Slug helpers for talk-page URLs. Pure and offline: a talk page lives at a\n * path like `/{slug}-{rkey}`, where the slug is a human-readable, SEO-friendly\n * rendering of the title and the rkey is the record's stable identifier.\n * Because TIDs never contain a `-`, the rkey can always be recovered as the\n * substring after the final `-`.\n */\n\n/** Maximum slug length before the trailing rkey is appended. */\nconst MAX_SLUG_LENGTH = 60;\n\n/** Combining diacritical marks left behind by NFKD decomposition (U+0300–U+036F). */\nconst COMBINING_MARKS = /[̀-ͯ]/g;\n\n/**\n * Render a title as a URL slug: lowercased, diacritics stripped, runs of\n * non-alphanumerics collapsed to a single `-`, trimmed, and capped at 60 chars.\n * Returns `''` for an empty or whitespace-only title.\n */\nexport function slugifyTitle(title: string): string {\n const slug = title\n .normalize('NFKD')\n // Strip combining marks left by NFKD decomposition (é -> e).\n .replace(COMBINING_MARKS, '')\n .toLowerCase()\n // Collapse any run of non-alphanumerics into a single hyphen.\n .replace(/[^a-z0-9]+/g, '-')\n // Collapse repeated hyphens.\n .replace(/-+/g, '-')\n // Trim leading/trailing hyphens.\n .replace(/^-+|-+$/g, '');\n // Cap length, then trim a trailing hyphen the cut may have exposed.\n return slug.slice(0, MAX_SLUG_LENGTH).replace(/-+$/g, '');\n}\n\n/**\n * Build the talk-page path segment `${slug}-${rkey}`, or just `rkey` when the\n * title produces an empty slug.\n */\nexport function buildTalkSlug(title: string, rkey: string): string {\n const slug = slugifyTitle(title);\n return slug ? `${slug}-${rkey}` : rkey;\n}\n\n/**\n * Recover the rkey from a talk-page segment: the substring after the final `-`\n * (TIDs contain no `-`). Returns the whole segment when there is no `-`.\n */\nexport function parseTalkRkey(segment: string): string {\n const idx = segment.lastIndexOf('-');\n return idx === -1 ? segment : segment.slice(idx + 1);\n}\n","/**\n * Schema.org JSON-LD for the things a person made: talks, publications,\n * courses and projects.\n *\n * These collections carried no structured data before this module existed;\n * a talk page emitted a four-property `CreativeWork` and publications,\n * courses and projects emitted nothing at all. Term choices are recorded in\n * `./terms.js`.\n */\n\nimport { normalizeDoi } from '../format/doi.js';\nimport { buildTalkSlug } from '../format/talk-slug.js';\nimport { filterHidden } from '../profile/section-model.js';\nimport { normaliseBaseUrl, profileUrl } from './url.js';\n\nconst DOI_RESOLVER = 'https://doi.org/';\nconst ORCID_RESOLVER = 'https://orcid.org/';\n\nexport interface WorksOptions {\n readonly baseUrl?: string;\n readonly sanitize?: (input: string) => string;\n}\n\n/** Minimal identity for the profile owner a work is attributed to. */\nexport interface WorkAuthor {\n readonly handle: string;\n readonly displayName?: string;\n}\n\n/**\n * A person named on somebody else's record. `confirmed` is load bearing: an\n * unconfirmed claim is a claim, not a fact, and must never be laundered into\n * structured data as a schema.org Person.\n */\ninterface NamedActor {\n readonly did?: string;\n readonly handle?: string;\n readonly displayName?: string;\n readonly confirmed?: boolean;\n}\n\ninterface PersonNode {\n readonly '@type': 'Person';\n readonly name: string;\n readonly url?: string;\n readonly sameAs?: string[];\n}\n\nconst identity = (input: string) => input;\n\nfunction authorNode(author: WorkAuthor, baseUrl: string, s: (v: string) => string): PersonNode {\n return {\n '@type': 'Person',\n name: s(author.displayName ?? author.handle),\n url: profileUrl(baseUrl, author.handle),\n };\n}\n\n/**\n * Confirmed named actors only, mapped to Person nodes. Anyone unconfirmed is\n * dropped entirely rather than degraded to a bare handle, because even a handle\n * in structured data asserts the association.\n */\nfunction confirmedActorNodes(\n actors: readonly NamedActor[] | undefined,\n baseUrl: string,\n s: (v: string) => string,\n): PersonNode[] {\n return (actors ?? [])\n .filter((a) => a.confirmed === true && Boolean(a.handle))\n .map((a) => ({\n '@type': 'Person' as const,\n name: s(a.displayName ?? a.handle!),\n url: profileUrl(baseUrl, a.handle!),\n }));\n}\n\n/** `filterHidden` takes a mutable array; inputs here are readonly. */\nfunction visible<T extends { hidden?: boolean }>(items: readonly T[] | undefined): T[] {\n return filterHidden(items ? [...items] : undefined);\n}\n\n// ---------------------------------------------------------------------------\n// Presentations\n// ---------------------------------------------------------------------------\n\n/**\n * The community calendar known values are already one-to-one with the\n * schema.org enumerations. An unrecognised value is left off rather than\n * guessed: a wrong attendance mode is worse than a missing one.\n */\nconst ATTENDANCE_MODE: Readonly<Record<string, string>> = {\n 'community.lexicon.calendar.event#inperson': 'https://schema.org/OfflineEventAttendanceMode',\n 'community.lexicon.calendar.event#virtual': 'https://schema.org/OnlineEventAttendanceMode',\n 'community.lexicon.calendar.event#hybrid': 'https://schema.org/MixedEventAttendanceMode',\n};\n\n/**\n * `#planned` is intentionally absent: schema.org has no equivalent, and mapping\n * it to EventScheduled would assert a commitment the record does not make.\n */\nconst EVENT_STATUS: Readonly<Record<string, string>> = {\n 'community.lexicon.calendar.event#scheduled': 'https://schema.org/EventScheduled',\n 'community.lexicon.calendar.event#cancelled': 'https://schema.org/EventCancelled',\n 'community.lexicon.calendar.event#postponed': 'https://schema.org/EventPostponed',\n 'community.lexicon.calendar.event#rescheduled': 'https://schema.org/EventRescheduled',\n};\n\nconst LINK_SLIDES = 'id.sifa.defs#linkSlides';\nconst LINK_RECORDING = 'id.sifa.defs#linkRecording';\n\nexport interface PresentationLinkInput {\n readonly uri: string;\n readonly label?: string;\n readonly type?: string;\n}\n\nexport interface PresentationDeliveryInput {\n readonly rkey: string;\n readonly title?: string | null;\n readonly role?: string | null;\n readonly eventName?: string | null;\n readonly date?: string | null;\n readonly location?: string | null;\n readonly locationLocality?: string | null;\n readonly locationRegion?: string | null;\n readonly countryCode?: string | null;\n readonly mode?: string | null;\n readonly status?: string | null;\n readonly links?: readonly PresentationLinkInput[];\n readonly coSpeakers?: readonly NamedActor[];\n readonly hidden?: boolean;\n}\n\nexport interface PresentationInput {\n readonly rkey: string;\n readonly title: string;\n readonly description?: string | null;\n readonly duration?: { minMinutes: number; maxMinutes?: number } | null;\n readonly coverImageUrl?: string | null;\n readonly links?: readonly PresentationLinkInput[];\n readonly deliveries?: readonly PresentationDeliveryInput[];\n readonly hidden?: boolean;\n}\n\nfunction lookup(table: Readonly<Record<string, string>>, key: string | null | undefined) {\n if (!key) return undefined;\n return Object.prototype.hasOwnProperty.call(table, key) ? table[key] : undefined;\n}\n\nfunction deliveryPlace(delivery: PresentationDeliveryInput, s: (v: string) => string) {\n const addressLocality = delivery.locationLocality ?? undefined;\n const addressRegion = delivery.locationRegion ?? undefined;\n const addressCountry = delivery.countryCode ?? undefined;\n\n if (addressLocality || addressRegion || addressCountry) {\n return {\n '@type': 'Place' as const,\n address: {\n '@type': 'PostalAddress' as const,\n ...(addressLocality && { addressLocality: s(addressLocality) }),\n ...(addressRegion && { addressRegion: s(addressRegion) }),\n ...(addressCountry && { addressCountry }),\n },\n };\n }\n\n // Legacy free-text location, kept so deliveries recorded before the\n // structured address field still say where they happened.\n if (delivery.location) {\n return { '@type': 'Place' as const, name: s(delivery.location) };\n }\n\n return undefined;\n}\n\nfunction linkOfType(links: readonly PresentationLinkInput[] | undefined, type: string) {\n return links?.find((l) => l.type === type)?.uri;\n}\n\nexport function buildPresentationJsonLd(\n presentation: PresentationInput,\n author: WorkAuthor,\n options: WorksOptions = {},\n) {\n const s = options.sanitize ?? identity;\n const baseUrl = normaliseBaseUrl(options.baseUrl);\n const speaker = authorNode(author, baseUrl, s);\n\n const events = visible(presentation.deliveries).map((delivery) => {\n const place = deliveryPlace(delivery, s);\n const recording = linkOfType(delivery.links, LINK_RECORDING);\n const slides =\n linkOfType(delivery.links, LINK_SLIDES) ?? linkOfType(presentation.links, LINK_SLIDES);\n\n return {\n '@type': 'Event' as const,\n name: s(delivery.eventName ?? delivery.title ?? presentation.title),\n ...(delivery.date && { startDate: delivery.date }),\n ...(place && { location: place }),\n ...(lookup(ATTENDANCE_MODE, delivery.mode) && {\n eventAttendanceMode: lookup(ATTENDANCE_MODE, delivery.mode),\n }),\n ...(lookup(EVENT_STATUS, delivery.status) && {\n eventStatus: lookup(EVENT_STATUS, delivery.status),\n }),\n performer: [speaker, ...confirmedActorNodes(delivery.coSpeakers, baseUrl, s)],\n ...(recording && { recordedIn: { '@type': 'VideoObject' as const, url: recording } }),\n ...(slides && {\n workFeatured: { '@type': 'PresentationDigitalDocument' as const, url: slides },\n }),\n };\n });\n\n return {\n '@context': 'https://schema.org',\n '@type': 'PresentationDigitalDocument' as const,\n name: s(presentation.title),\n ...(presentation.description && { abstract: s(presentation.description) }),\n ...(presentation.duration && { timeRequired: `PT${presentation.duration.minMinutes}M` }),\n ...(presentation.coverImageUrl && { image: presentation.coverImageUrl }),\n author: speaker,\n url: `${baseUrl}/p/${author.handle}/talk/${buildTalkSlug(presentation.title, presentation.rkey)}`,\n ...(events.length > 0 && { subjectOf: events }),\n };\n}\n\n// ---------------------------------------------------------------------------\n// Publications\n// ---------------------------------------------------------------------------\n\nexport interface PublicationContributorInput {\n readonly name: string;\n readonly orcidId?: string;\n readonly handle?: string;\n}\n\nexport interface PublicationInput {\n readonly rkey: string;\n readonly title: string;\n readonly subtitle?: string;\n readonly publisher?: string;\n readonly date?: string;\n readonly url?: string;\n readonly description?: string;\n readonly doi?: string;\n readonly contributors?: readonly PublicationContributorInput[];\n readonly hidden?: boolean;\n}\n\nexport function buildPublicationJsonLd(\n publication: PublicationInput,\n author: WorkAuthor,\n options: WorksOptions = {},\n) {\n const s = options.sanitize ?? identity;\n const baseUrl = normaliseBaseUrl(options.baseUrl);\n\n // Contributor order is meaningful in scholarly work, so it is preserved as\n // given rather than sorted or deduplicated.\n const authors: PersonNode[] =\n publication.contributors && publication.contributors.length > 0\n ? publication.contributors.map((c) => ({\n '@type': 'Person' as const,\n name: s(c.name),\n ...(c.handle && { url: profileUrl(baseUrl, c.handle) }),\n ...(c.orcidId && { sameAs: [`${ORCID_RESOLVER}${c.orcidId}`] }),\n }))\n : [authorNode(author, baseUrl, s)];\n\n const doi = publication.doi ? normalizeDoi(publication.doi) : undefined;\n\n return {\n '@context': 'https://schema.org',\n '@type': 'ScholarlyArticle' as const,\n name: s(publication.title),\n ...(publication.subtitle && { alternativeHeadline: s(publication.subtitle) }),\n ...(publication.description && { abstract: s(publication.description) }),\n ...(publication.publisher && {\n publisher: { '@type': 'Organization' as const, name: s(publication.publisher) },\n }),\n ...(publication.date && { datePublished: publication.date }),\n ...(publication.url && { url: publication.url }),\n author: authors,\n ...(doi && {\n identifier: { '@type': 'PropertyValue' as const, propertyID: 'DOI', value: doi },\n sameAs: [`${DOI_RESOLVER}${doi}`],\n }),\n };\n}\n\n// ---------------------------------------------------------------------------\n// Courses and projects\n// ---------------------------------------------------------------------------\n\nexport interface CourseInput {\n readonly rkey: string;\n readonly name: string;\n readonly number?: string;\n readonly institution?: string;\n readonly hidden?: boolean;\n}\n\nexport function buildCourseJsonLd(course: CourseInput, options: WorksOptions = {}) {\n const s = options.sanitize ?? identity;\n return {\n '@context': 'https://schema.org',\n '@type': 'Course' as const,\n name: s(course.name),\n ...(course.number && { courseCode: s(course.number) }),\n ...(course.institution && {\n provider: { '@type': 'EducationalOrganization' as const, name: s(course.institution) },\n }),\n };\n}\n\nexport interface ProjectInput {\n readonly rkey: string;\n readonly name: string;\n readonly description?: string;\n readonly url?: string;\n readonly startDate?: string;\n readonly endDate?: string;\n readonly members?: readonly NamedActor[];\n readonly hidden?: boolean;\n}\n\nexport function buildProjectJsonLd(\n project: ProjectInput,\n author: WorkAuthor,\n options: WorksOptions = {},\n) {\n const s = options.sanitize ?? identity;\n const baseUrl = normaliseBaseUrl(options.baseUrl);\n const members = confirmedActorNodes(project.members, baseUrl, s);\n\n return {\n '@context': 'https://schema.org',\n '@type': 'Project' as const,\n name: s(project.name),\n ...(project.description && { description: s(project.description) }),\n ...(project.url && { url: project.url }),\n ...(project.startDate && { startDate: project.startDate }),\n ...(project.endDate && { endDate: project.endDate }),\n member: [authorNode(author, baseUrl, s), ...members],\n };\n}\n","/**\n * The works on a profile as one JSON-LD `@graph`.\n *\n * A profile page already emits a `ProfilePage` whose `mainEntity` is the\n * Person. Publications, talks, courses and projects are separate entities\n * rather than properties of that Person, so they go in their own block and\n * point back at the Person by `@id` instead of repeating the whole node.\n */\n\nimport { filterHidden } from '../profile/section-model.js';\nimport type { JsonLdOptions } from './profile.js';\nimport { normaliseBaseUrl } from './url.js';\nimport {\n buildCourseJsonLd,\n buildPresentationJsonLd,\n buildProjectJsonLd,\n buildPublicationJsonLd,\n type CourseInput,\n type PresentationInput,\n type ProjectInput,\n type PublicationInput,\n type WorkAuthor,\n} from './works.js';\n\nexport interface ProfileWorksInput {\n readonly handle: string;\n readonly publications?: readonly PublicationInput[];\n readonly presentations?: readonly PresentationInput[];\n readonly courses?: readonly CourseInput[];\n readonly projects?: readonly ProjectInput[];\n}\n\n/** `filterHidden` takes a mutable array; inputs here are readonly. */\nfunction visible<T extends { hidden?: boolean }>(items: readonly T[] | undefined): T[] {\n return filterHidden(items ? [...items] : undefined);\n}\n\n/**\n * Returns null when there is nothing to say, so a caller can skip the script\n * block entirely rather than emitting an empty graph.\n */\nexport function buildProfileWorksJsonLd(\n profile: ProfileWorksInput,\n author: WorkAuthor,\n options: JsonLdOptions = {},\n) {\n const personId =\n options.canonicalUrl ?? `${normaliseBaseUrl(options.baseUrl)}/p/${profile.handle}`;\n\n // Each work is built by its own emitter, then its `@context` is dropped: the\n // graph carries one context for every node in it.\n const strip = <T extends { '@context': string }>(node: T) => {\n const { '@context': _context, ...rest } = node;\n return rest;\n };\n\n // The Person is emitted in full by the ProfilePage block. Referencing it by\n // `@id` keeps one Person in the graph rather than several partial copies for\n // a consumer to reconcile.\n const authorRef = [{ '@id': personId }];\n\n const graph: Record<string, unknown>[] = [\n ...visible(profile.publications).map((p) => ({\n ...strip(buildPublicationJsonLd(p, author, options)),\n author: authorRef,\n })),\n ...visible(profile.presentations).map((p) => ({\n ...strip(buildPresentationJsonLd(p, author, options)),\n author: authorRef,\n })),\n ...visible(profile.courses).map((c) => strip(buildCourseJsonLd(c, options))),\n ...visible(profile.projects).map((p) => ({\n ...strip(buildProjectJsonLd(p, author, options)),\n member: authorRef,\n })),\n ];\n\n if (graph.length === 0) return null;\n\n return { '@context': 'https://schema.org', '@graph': graph };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/jsonld/term-mappings.json","../../src/jsonld/terms.ts","../../src/format/location-utils.ts","../../src/logic/primary-position.ts","../../src/profile/section-model.ts","../../src/jsonld/url.ts","../../src/jsonld/profile.ts","../../src/format/doi.ts","../../src/format/talk-slug.ts","../../src/jsonld/works.ts","../../src/jsonld/works-graph.ts"],"names":["identity","visible"],"mappings":"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","file":"index.js","sourcesContent":["{\n \"$schema\": \"https://sifa.id/schemas/term-mappings/v1.json\",\n \"version\": \"1.0.0\",\n \"description\": \"Reconciliation between id.sifa.* lexicon terms and existing RDF vocabularies. RDF is used here as vocabulary only: Sifa records are Lexicon JSON on the AT Protocol, and nothing here changes how they are stored or transmitted. Match strengths use SKOS mapping relations.\",\n \"vocabularies\": {\n \"schema\": \"https://schema.org/\",\n \"bibo\": \"http://purl.org/ontology/bibo/\",\n \"dcterms\": \"http://purl.org/dc/terms/\",\n \"foaf\": \"http://xmlns.com/foaf/0.1/\",\n \"org\": \"http://www.w3.org/ns/org#\",\n \"prism\": \"http://prismstandard.org/namespaces/basic/2.1/\",\n \"event\": \"http://purl.org/NET/c4dm/event.owl#\",\n \"skos\": \"http://www.w3.org/2004/02/skos/core#\"\n },\n \"mappings\": [\n {\n \"lexicon\": \"id.sifa.org.profile\",\n \"match\": \"exactMatch\",\n \"terms\": [\"schema:Organization\", \"org:FormalOrganization\"],\n \"note\": \"ROR is the value anchor.\"\n },\n {\n \"lexicon\": \"id.sifa.profile.certification\",\n \"match\": \"exactMatch\",\n \"terms\": [\"schema:EducationalOccupationalCredential\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.certification\",\n \"field\": \"credentialUrl\",\n \"match\": \"exactMatch\",\n \"terms\": [\"schema:url\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.certification\",\n \"field\": \"expiresAt\",\n \"match\": \"exactMatch\",\n \"terms\": [\"schema:validUntil\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.course\",\n \"match\": \"exactMatch\",\n \"terms\": [\"schema:Course\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.course\",\n \"field\": \"number\",\n \"match\": \"exactMatch\",\n \"terms\": [\"schema:courseCode\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.education\",\n \"match\": \"closeMatch\",\n \"terms\": [\"schema:EducationalOccupationalCredential\"],\n \"note\": \"One record maps to two schema.org assertions: alumniOf for the institution and hasCredential for the degree.\"\n },\n {\n \"lexicon\": \"id.sifa.profile.education\",\n \"field\": \"degree\",\n \"match\": \"closeMatch\",\n \"terms\": [\"schema:hasCredential\", \"bibo:degree\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.education\",\n \"field\": \"fieldOfStudy\",\n \"match\": \"closeMatch\",\n \"terms\": [\"schema:educationalCredentialAwarded\"],\n \"note\": \"ISCED-F is the value anchor.\"\n },\n {\n \"lexicon\": \"id.sifa.profile.education\",\n \"field\": \"institution\",\n \"match\": \"exactMatch\",\n \"terms\": [\"schema:alumniOf\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.externalAccount\",\n \"match\": \"exactMatch\",\n \"terms\": [\"schema:sameAs\", \"foaf:account\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.honor\",\n \"match\": \"broadMatch\",\n \"terms\": [\"schema:award\"],\n \"note\": \"schema:award is a bare string, so issuer and date are lost. No better term exists in BIBO either.\"\n },\n {\n \"lexicon\": \"id.sifa.profile.involvement\",\n \"match\": \"broadMatch\",\n \"terms\": [\"org:Membership\"],\n \"note\": \"The kind known values have no external equivalent.\"\n },\n {\n \"lexicon\": \"id.sifa.profile.language\",\n \"match\": \"exactMatch\",\n \"terms\": [\"schema:knowsLanguage\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.position\",\n \"match\": \"closeMatch\",\n \"terms\": [\"org:Membership\", \"schema:OrganizationRole\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.position\",\n \"field\": \"company\",\n \"match\": \"exactMatch\",\n \"terms\": [\"org:organization\", \"schema:worksFor\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.position\",\n \"field\": \"description\",\n \"match\": \"exactMatch\",\n \"terms\": [\"dcterms:description\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.position\",\n \"field\": \"employmentType\",\n \"match\": \"closeMatch\",\n \"terms\": [\"schema:employmentType\"],\n \"note\": \"schema:employmentType is free text. ESCO is the better value anchor.\"\n },\n {\n \"lexicon\": \"id.sifa.profile.position\",\n \"field\": \"endedAt\",\n \"match\": \"exactMatch\",\n \"terms\": [\"schema:endDate\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.position\",\n \"field\": \"entityRef\",\n \"match\": \"closeMatch\",\n \"terms\": [\"schema:sameAs\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.position\",\n \"field\": \"location\",\n \"match\": \"exactMatch\",\n \"terms\": [\"schema:jobLocation\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.position\",\n \"field\": \"startedAt\",\n \"match\": \"exactMatch\",\n \"terms\": [\"schema:startDate\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.position\",\n \"field\": \"title\",\n \"match\": \"exactMatch\",\n \"terms\": [\"org:role\", \"schema:roleName\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.position\",\n \"field\": \"workplaceType\",\n \"match\": \"narrowMatch\",\n \"terms\": [\"schema:jobLocationType\"],\n \"note\": \"schema.org models only a remote flag; Sifa distinguishes onSite, remote, and hybrid.\"\n },\n {\n \"lexicon\": \"id.sifa.profile.presentation\",\n \"match\": \"closeMatch\",\n \"terms\": [\"bibo:Slideshow\", \"schema:PresentationDigitalDocument\"],\n \"note\": \"Neither term carries the \\\"reusable, deliverable more than once\\\" semantics of the Sifa record.\"\n },\n {\n \"lexicon\": \"id.sifa.profile.presentation\",\n \"field\": \"coverImage\",\n \"match\": \"exactMatch\",\n \"terms\": [\"schema:image\", \"foaf:depiction\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.presentation\",\n \"field\": \"description\",\n \"match\": \"exactMatch\",\n \"terms\": [\"bibo:abstract\", \"schema:abstract\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.presentation\",\n \"field\": \"duration\",\n \"match\": \"narrowMatch\",\n \"terms\": [\"schema:timeRequired\"],\n \"note\": \"The lexicon models a range; schema:timeRequired is a single ISO 8601 duration.\"\n },\n {\n \"lexicon\": \"id.sifa.profile.presentation\",\n \"field\": \"intendedAudiences\",\n \"match\": \"closeMatch\",\n \"terms\": [\"schema:audience\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.presentation\",\n \"field\": \"title\",\n \"match\": \"exactMatch\",\n \"terms\": [\"dcterms:title\", \"schema:name\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.presentation\",\n \"field\": \"writeupRef\",\n \"match\": \"closeMatch\",\n \"terms\": [\"dcterms:isReferencedBy\", \"schema:subjectOf\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.presentationDelivery\",\n \"match\": \"closeMatch\",\n \"terms\": [\"schema:Event\", \"event:Event\"],\n \"note\": \"BIBO models this relation as bibo:Slideshow bibo:presentedAt event:Event.\"\n },\n {\n \"lexicon\": \"id.sifa.profile.presentationDelivery\",\n \"field\": \"address\",\n \"match\": \"exactMatch\",\n \"terms\": [\"schema:location\", \"event:place\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.presentationDelivery\",\n \"field\": \"coSpeakers\",\n \"match\": \"exactMatch\",\n \"terms\": [\"schema:performer\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.presentationDelivery\",\n \"field\": \"date\",\n \"match\": \"exactMatch\",\n \"terms\": [\"schema:startDate\", \"event:time\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.presentationDelivery\",\n \"field\": \"eventName\",\n \"match\": \"closeMatch\",\n \"terms\": [\"schema:superEvent\", \"bibo:Conference\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.presentationDelivery\",\n \"field\": \"mode\",\n \"match\": \"exactMatch\",\n \"terms\": [\"schema:eventAttendanceMode\"],\n \"note\": \"The community.lexicon.calendar.event known values are already one-to-one with the schema.org enumeration.\"\n },\n {\n \"lexicon\": \"id.sifa.profile.presentationDelivery\",\n \"field\": \"presentationRef\",\n \"match\": \"closeMatch\",\n \"terms\": [\"bibo:presentedAt\", \"schema:workPerformed\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.presentationDelivery\",\n \"field\": \"role\",\n \"match\": \"closeMatch\",\n \"terms\": [\"bibo:performer\", \"schema:performer\"],\n \"note\": \"No external vocabulary distinguishes presenter, panelist, keynote, workshop and host at this granularity.\"\n },\n {\n \"lexicon\": \"id.sifa.profile.presentationDelivery\",\n \"field\": \"status\",\n \"match\": \"exactMatch\",\n \"terms\": [\"schema:eventStatus\"],\n \"note\": \"As with mode, already one-to-one with the schema.org enumeration.\"\n },\n {\n \"lexicon\": \"id.sifa.profile.presentationDelivery\",\n \"field\": \"title\",\n \"match\": \"exactMatch\",\n \"terms\": [\"dcterms:title\", \"schema:name\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.project\",\n \"match\": \"exactMatch\",\n \"terms\": [\"schema:Project\", \"foaf:Project\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.publication\",\n \"match\": \"broadMatch\",\n \"terms\": [\"bibo:Document\", \"schema:CreativeWork\"],\n \"note\": \"Refine to bibo:AcademicArticle, bibo:Book, bibo:Report or bibo:Thesis when a resource type is known. COAR is the value anchor.\"\n },\n {\n \"lexicon\": \"id.sifa.profile.publication\",\n \"field\": \"authors\",\n \"match\": \"exactMatch\",\n \"terms\": [\"bibo:authorList\", \"schema:author\"],\n \"note\": \"bibo:authorList is an ordered rdf:List and preserves author order, which schema:author does not guarantee.\"\n },\n {\n \"lexicon\": \"id.sifa.profile.publication\",\n \"field\": \"description\",\n \"match\": \"exactMatch\",\n \"terms\": [\"bibo:abstract\", \"schema:abstract\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.publication\",\n \"field\": \"publishedAt\",\n \"match\": \"exactMatch\",\n \"terms\": [\"dcterms:issued\", \"schema:datePublished\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.publication\",\n \"field\": \"publisher\",\n \"match\": \"exactMatch\",\n \"terms\": [\"dcterms:publisher\", \"schema:publisher\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.publication\",\n \"field\": \"subtitle\",\n \"match\": \"closeMatch\",\n \"terms\": [\"schema:alternativeHeadline\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.publication\",\n \"field\": \"title\",\n \"match\": \"exactMatch\",\n \"terms\": [\"dcterms:title\", \"schema:name\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.publication\",\n \"field\": \"url\",\n \"match\": \"exactMatch\",\n \"terms\": [\"bibo:uri\", \"schema:url\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.self\",\n \"match\": \"exactMatch\",\n \"terms\": [\"schema:Person\", \"foaf:Person\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.self\",\n \"field\": \"about\",\n \"match\": \"exactMatch\",\n \"terms\": [\"schema:description\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.self\",\n \"field\": \"avatar\",\n \"match\": \"exactMatch\",\n \"terms\": [\"schema:image\", \"foaf:depiction\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.self\",\n \"field\": \"displayName\",\n \"match\": \"exactMatch\",\n \"terms\": [\"schema:name\", \"foaf:name\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.self\",\n \"field\": \"familyName\",\n \"match\": \"exactMatch\",\n \"terms\": [\"schema:familyName\", \"foaf:family_name\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.self\",\n \"field\": \"givenName\",\n \"match\": \"exactMatch\",\n \"terms\": [\"schema:givenName\", \"foaf:givenname\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.self\",\n \"field\": \"headline\",\n \"match\": \"closeMatch\",\n \"terms\": [\"schema:jobTitle\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.self\",\n \"field\": \"location\",\n \"match\": \"closeMatch\",\n \"terms\": [\"schema:homeLocation\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.skill\",\n \"match\": \"closeMatch\",\n \"terms\": [\"schema:knowsAbout\", \"schema:DefinedTerm\"],\n \"note\": \"ESCO is the value anchor.\"\n },\n {\n \"lexicon\": \"id.sifa.profile.volunteering\",\n \"match\": \"closeMatch\",\n \"terms\": [\"org:Membership\", \"schema:OrganizationRole\"]\n },\n {\n \"lexicon\": \"id.sifa.profile.publication\",\n \"field\": \"doi\",\n \"terms\": [\"bibo:doi\", \"prism:doi\"],\n \"match\": \"exactMatch\",\n \"note\": \"Present on the AppView view type (ORCID-sourced), not yet on the id.sifa.profile.publication lexicon, so user-authored publications cannot carry one.\"\n }\n ],\n \"unmapped\": [\n {\n \"lexicon\": \"id.sifa.profile.self\",\n \"field\": \"pronouns\",\n \"reason\": \"No stable external term. schema.org has no pronouns property.\"\n },\n {\n \"lexicon\": \"id.sifa.profile.self\",\n \"field\": \"discoverable\",\n \"reason\": \"Sifa indexing control, not a fact about the person.\"\n },\n {\n \"lexicon\": \"id.sifa.profile.position\",\n \"field\": \"isPrimary\",\n \"reason\": \"Sifa display ordering concern.\"\n },\n {\n \"lexicon\": \"id.sifa.profile.education\",\n \"field\": \"grade\",\n \"reason\": \"No comparable external term; grading scales are not portable.\"\n },\n {\n \"lexicon\": \"id.sifa.profile.language\",\n \"field\": \"proficiency\",\n \"reason\": \"The known values are CEFR-shaped but not CEFR-named. Map only; renaming a published lexicon for a cosmetic gain is not worth the break.\"\n },\n {\n \"lexicon\": \"id.sifa.confirmation\",\n \"reason\": \"A record affirming another record is reification. schema:Review and schema:ClaimReview both imply an evaluation that a confirmation does not make.\"\n },\n {\n \"lexicon\": \"id.sifa.endorsement\",\n \"reason\": \"Same reification problem as confirmation. Any mapping that lets a consumer aggregate endorsements into a score works against the descriptive-only trust model.\"\n },\n {\n \"lexicon\": \"id.sifa.graph.connection\",\n \"reason\": \"foaf:knows carries no consent semantics. A Sifa connection is bilateral and confirmed; flattening it to foaf:knows would misrepresent an unconfirmed acquaintance claim as mutual.\"\n },\n {\n \"lexicon\": \"id.sifa.graph.follow\",\n \"reason\": \"See id.sifa.graph.connection.\"\n },\n {\n \"lexicon\": \"id.sifa.meeting\",\n \"reason\": \"Attestation semantics; same reification problem as confirmation.\"\n }\n ]\n}\n","/**\n * Reconciliation between `id.sifa.*` lexicon terms and existing RDF\n * vocabularies.\n *\n * The facts live in sifa-lexicons, as `x-skos:*` annotations on the lexicon\n * defs and properties. Those annotations are published to the authority PDS,\n * so a third party resolving `id.sifa.*` already reads them; that makes the\n * lexicons the source of truth and `./term-mappings.json` a derived copy,\n * refreshed by `scripts/sync-term-mappings.mjs` and drift-checked in CI.\n *\n * To change a mapping, change the lexicon, not this file.\n *\n * Scope note: RDF is adopted here as *vocabulary only*. Sifa records are\n * Lexicon JSON on the AT Protocol; nothing in this module changes how records\n * are stored or transmitted. A mapping is a one-directional annotation over a\n * lexicon designed on its own merits, never a constraint on lexicon design.\n * When a term does not fit, the correct answer is `noMatch`, not a different\n * lexicon.\n */\n\nimport document from './term-mappings.json';\n\n/** Vocabulary prefix -> namespace IRI. */\nexport const VOCABULARIES: Readonly<Record<string, string>> = document.vocabularies;\n\nexport type VocabularyPrefix = keyof typeof document.vocabularies;\n\n/**\n * Strength of a mapping, using SKOS mapping relations so the table is itself\n * expressible as RDF.\n *\n * `noMatch` is not the absence of an entry. It is a deliberate statement that\n * no external term should be used for this concept, and it carries a reason.\n */\nexport type MatchStrength =\n 'exactMatch' | 'closeMatch' | 'broadMatch' | 'narrowMatch' | 'relatedMatch' | 'noMatch';\n\nexport interface TermMapping {\n /** Lexicon NSID, e.g. `id.sifa.profile.presentation`. */\n readonly lexicon: string;\n /**\n * Field name within the record. Omitted for a record-level class mapping\n * (what the record *is*, rather than what one of its fields means).\n */\n readonly field?: string;\n /** CURIEs, e.g. `dcterms:title`. Empty when `match` is `noMatch`. */\n readonly terms: readonly string[];\n readonly match: MatchStrength;\n /** Rationale. Always present when `match` is `noMatch`. */\n readonly note?: string;\n}\n\ninterface RawMapping {\n lexicon: string;\n field?: string;\n terms: string[];\n match: string;\n note?: string;\n}\n\ninterface RawUnmapped {\n lexicon: string;\n field?: string;\n reason: string;\n}\n\n/**\n * Every reconciliation Sifa asserts, including the deliberate non-mappings.\n *\n * The published document splits these into `mappings` and `unmapped`, which\n * reads better over the wire. Callers here want one list, so they are\n * flattened back together.\n */\nexport const TERM_MAPPINGS: readonly TermMapping[] = [\n ...(document.mappings as RawMapping[]).map((m): TermMapping => ({\n lexicon: m.lexicon,\n ...(m.field ? { field: m.field } : {}),\n terms: m.terms,\n match: m.match as MatchStrength,\n ...(m.note ? { note: m.note } : {}),\n })),\n ...(document.unmapped as RawUnmapped[]).map((u): TermMapping => ({\n lexicon: u.lexicon,\n ...(u.field ? { field: u.field } : {}),\n terms: [],\n match: 'noMatch',\n note: u.reason,\n })),\n];\n\n/**\n * Expand a CURIE (`dcterms:title`) to a full IRI. Returns null for an unknown\n * prefix rather than guessing a namespace.\n */\nexport function expandCurie(curie: string): string | null {\n const separator = curie.indexOf(':');\n if (separator <= 0) return null;\n const prefix = curie.slice(0, separator);\n const local = curie.slice(separator + 1);\n if (!local) return null;\n if (!Object.prototype.hasOwnProperty.call(VOCABULARIES, prefix)) return null;\n return `${VOCABULARIES[prefix]}${local}`;\n}\n\n/** All mappings declared for one lexicon NSID, record level and field level. */\nexport function mappingsForLexicon(nsid: string): readonly TermMapping[] {\n return TERM_MAPPINGS.filter((m) => m.lexicon === nsid);\n}\n\n/** True when Sifa has deliberately declined to map this lexicon or field. */\nexport function isDeliberatelyUnmapped(nsid: string, field?: string): boolean {\n return TERM_MAPPINGS.some(\n (m) => m.lexicon === nsid && m.field === field && m.match === 'noMatch',\n );\n}\n","import type { LocationValue } from '../types/index.js';\n\n/**\n * Format a LocationValue for display.\n *\n * Prefers `locality` (the community.lexicon.location.address field) and\n * falls back to the legacy `city` slot so values produced before the\n * sifa-api alias migration still render correctly during the additive\n * transition window.\n */\nexport function formatLocation(loc: LocationValue | null | undefined): string {\n if (!loc) return '';\n const locality = loc.locality ?? loc.city;\n const parts = [locality, loc.region, loc.country].filter(Boolean);\n if (loc.postalCode && !locality) {\n return `${loc.postalCode}, ${loc.country}`;\n }\n return parts.join(', ');\n}\n\n/** Parse a display string back into a LocationValue (best-effort for legacy data) */\nexport function parseLocationString(str: string): LocationValue | null {\n if (!str.trim()) return null;\n const parts = str\n .split(',')\n .map((p) => p.trim())\n .filter(Boolean);\n if (parts.length >= 3) {\n return {\n city: parts[0],\n region: parts[1],\n country: parts[parts.length - 1]!,\n };\n }\n if (parts.length === 2) {\n return {\n city: parts[0],\n country: parts[1]!,\n };\n }\n return { country: parts[0]! };\n}\n\n/** Convert ISO 3166-1 alpha-2 country code to flag emoji */\nexport function countryCodeToFlag(code: string | undefined): string {\n if (!code || code.length !== 2) return '';\n const upper = code.toUpperCase();\n const a = upper.codePointAt(0);\n const b = upper.codePointAt(1);\n if (a === undefined || b === undefined) return '';\n return String.fromCodePoint(a - 0x41 + 0x1f1e6, b - 0x41 + 0x1f1e6);\n}\n","/**\n * Canonical rule for picking the \"primary\" position to surface on profile cards,\n * social previews, and structured-data outputs.\n *\n * Without this shared helper, different surfaces (visible hero, OG image,\n * <meta description>, JSON-LD) re-derived \"primary\" inconsistently and diverged\n * for users with multiple concurrent roles.\n *\n * A `hidden` position is one the user chose not to show on their public profile.\n * It is never surfaced as the featured role — hidden wins over `primary`, so a\n * role flagged both hidden and primary is excluded rather than featured.\n *\n * Rules (in order):\n * 1. A position the user explicitly flagged `primary` AND that is still active AND not hidden.\n * 2. Otherwise, the active, non-hidden position with the most recent `startedAt`.\n * 3. Otherwise, undefined (no eligible position).\n */\n\nexport interface PrimaryPositionCandidate {\n startedAt?: string;\n endedAt?: string;\n primary?: boolean;\n hidden?: boolean;\n}\n\nexport function pickPrimaryPosition<T extends PrimaryPositionCandidate>(\n positions: readonly T[] | undefined,\n): T | undefined {\n if (!positions || positions.length === 0) return undefined;\n\n const active = positions.filter((p) => !p.endedAt && !p.hidden);\n if (active.length === 0) return undefined;\n\n const flagged = active.find((p) => p.primary === true);\n if (flagged) return flagged;\n\n return [...active].sort((a, b) => (b.startedAt ?? '').localeCompare(a.startedAt ?? ''))[0];\n}\n","/**\n * Shared, single-source-of-truth model for which profile sections render, in\n * what order, their nav grouping, and which items a given viewer may see.\n *\n * Every Sifa profile surface builds on this: the HTML profile page, the\n * Markdown / DOCX / print exports, and the standalone personal-site renderer.\n * Adding a section to {@link ALL_SECTIONS} makes it appear everywhere (the\n * exports drive presence + order from here, and {@link SECTION_LABELS} is an\n * exhaustive `Record<SectionId, string>`, so a new id is a compile error until\n * it has a label).\n *\n * The per-section sorts live in `./section-sorts.js`, built on the same SDK\n * date extractors the HTML section components use, so the surfaces cannot\n * diverge on ordering.\n */\n\nimport type { Profile } from '../types/index.js';\n\n/**\n * Side-nav groups, in display order. Each labels a contiguous run of sections\n * in {@link ALL_SECTIONS}. `labelKey` resolves against the consumer's `sections`\n * i18n namespace.\n */\nexport const SECTION_GROUPS = [\n { id: 'overview', labelKey: 'groupOverview' },\n { id: 'experience', labelKey: 'groupExperience' },\n { id: 'qualifications', labelKey: 'groupQualifications' },\n { id: 'more', labelKey: 'groupMore' },\n] as const;\n\nexport type SectionGroupId = (typeof SECTION_GROUPS)[number]['id'];\n\n/**\n * Profile body sections in render + nav order (evidence-first): identity and\n * activity lead, then living work (career, projects, talks, publications, then\n * skills), then the formal record (credentials, education, courses), then the\n * rest. `ns` selects the consumer's i18n namespace for `labelKey`; `group`\n * ties the section to a {@link SECTION_GROUPS} header.\n */\nexport const ALL_SECTIONS = [\n { id: 'about', labelKey: 'about', ns: 'profile' as const, group: 'overview' as const },\n { id: 'career', labelKey: 'career', ns: 'sections' as const, group: 'experience' as const },\n { id: 'projects', labelKey: 'projects', ns: 'sections' as const, group: 'experience' as const },\n {\n id: 'presentations',\n labelKey: 'talksAndSessions',\n ns: 'sections' as const,\n group: 'experience' as const,\n },\n {\n id: 'publications',\n labelKey: 'publications',\n ns: 'sections' as const,\n group: 'experience' as const,\n },\n { id: 'skills', labelKey: 'skills', ns: 'sections' as const, group: 'experience' as const },\n {\n id: 'credentials',\n labelKey: 'credentials',\n ns: 'sections' as const,\n group: 'qualifications' as const,\n },\n {\n id: 'education',\n labelKey: 'education',\n ns: 'sections' as const,\n group: 'qualifications' as const,\n },\n { id: 'courses', labelKey: 'courses', ns: 'sections' as const, group: 'qualifications' as const },\n { id: 'awards', labelKey: 'awards', ns: 'sections' as const, group: 'more' as const },\n { id: 'involvement', labelKey: 'involvement', ns: 'sections' as const, group: 'more' as const },\n // Its own section rather than a group under involvement: that record is about\n // work contributed, this one about capital deployed.\n { id: 'investments', labelKey: 'investments', ns: 'sections' as const, group: 'more' as const },\n { id: 'languages', labelKey: 'languages', ns: 'sections' as const, group: 'more' as const },\n {\n id: 'other-profiles',\n labelKey: 'otherProfiles',\n ns: 'sections' as const,\n group: 'more' as const,\n },\n] as const;\n\n/** Every profile section id, in canonical render order. */\nexport type SectionId = (typeof ALL_SECTIONS)[number]['id'];\n\n/** Whether a section has content for a given profile (used to hide empty nav entries for visitors). */\nexport function isSectionPopulated(profile: Profile, id: string): boolean {\n switch (id) {\n case 'about':\n return Boolean(profile.about && profile.headline);\n case 'career':\n return Boolean(profile.positions?.length);\n case 'education':\n return Boolean(profile.education?.length);\n case 'courses':\n return Boolean(profile.courses?.length);\n case 'skills':\n return Boolean(profile.skills?.length);\n case 'projects':\n return Boolean(profile.projects?.length);\n case 'credentials':\n return Boolean(profile.certifications?.length);\n case 'publications':\n return Boolean(profile.publications?.length);\n case 'presentations':\n return (\n Boolean(profile.presentations?.length) || Boolean(profile.presentationDeliveries?.length)\n );\n case 'involvement':\n return Boolean(profile.involvement?.length);\n case 'investments':\n return Boolean(profile.investments?.length);\n case 'awards':\n return Boolean(profile.honors?.length);\n case 'languages':\n return Boolean(profile.languages?.length);\n case 'other-profiles':\n return Boolean(profile.externalAccounts?.length);\n default:\n return false;\n }\n}\n\n/**\n * The section ids a given viewer should see, in {@link ALL_SECTIONS} order.\n * Owners see every section; visitors only see populated ones.\n */\nexport function getVisibleSectionIds(profile: Profile, isOwnProfile: boolean): SectionId[] {\n return ALL_SECTIONS.map((s) => s.id).filter(\n (id) => isOwnProfile || isSectionPopulated(profile, id),\n );\n}\n\n/** Drop items the owner has hidden from visitors. */\nexport function filterHidden<T extends { hidden?: boolean }>(items: T[] | undefined): T[] {\n return (items ?? []).filter((i) => !i.hidden);\n}\n\n/**\n * Items visible to a given viewer: owners see their own hidden items, visitors\n * do not. Shared by every export format (markdown, docx, print) and the public\n * `.md` route so the hidden rule lives in one place.\n */\nexport function visibleItems<T extends { hidden?: boolean }>(\n items: T[] | undefined,\n isOwnProfile: boolean,\n): T[] {\n return isOwnProfile ? (items ?? []) : filterHidden(items);\n}\n\n/**\n * English heading text for each section, keyed by {@link SectionId} (e.g.\n * `other-profiles` renders as \"Links\"). Exhaustive `Record<SectionId, string>`:\n * adding a section to {@link ALL_SECTIONS} without a label here is a compile\n * error, so a section can never silently render without (or with a stale)\n * heading. Consumers with i18n resolve their own localized labels via\n * `labelKey`; this is the canonical English fallback used by the exports.\n */\nexport const SECTION_LABELS: Record<SectionId, string> = {\n about: 'About',\n career: 'Career',\n skills: 'Skills',\n projects: 'Projects',\n presentations: 'Talks & sessions',\n publications: 'Publications',\n credentials: 'Credentials',\n education: 'Education',\n courses: 'Courses',\n awards: 'Awards',\n involvement: 'Involvement',\n investments: 'Investments',\n languages: 'Languages',\n 'other-profiles': 'Links',\n};\n","/** Shared URL helpers for the JSON-LD emitters. */\n\nexport const DEFAULT_BASE_URL = 'https://sifa.id';\n\n/**\n * Drop trailing slashes from a caller-supplied base URL.\n *\n * Written as a scan rather than `replace(/\\/+$/, '')` on purpose: the regex\n * form is a polynomial-backtracking hazard on input the library does not\n * control (CodeQL js/polynomial-redos). This runs in linear time.\n */\nexport function normaliseBaseUrl(baseUrl: string | undefined): string {\n const value = baseUrl ?? DEFAULT_BASE_URL;\n let end = value.length;\n while (end > 0 && value.charCodeAt(end - 1) === 0x2f) end -= 1;\n return value.slice(0, end);\n}\n\nexport function profileUrl(baseUrl: string, handle: string): string {\n return `${baseUrl}/p/${handle}`;\n}\n","/**\n * Schema.org JSON-LD for a Sifa profile.\n *\n * Ported from sifa-web's `src/lib/jsonld.ts` so that sifa.id, page.sifa.id and\n * any future consumer emit the same graph from one implementation. Term choices\n * are recorded in `./terms.js`.\n *\n * These are pure functions: no fetching, no DOM, no framework.\n */\n\nimport { formatLocation } from '../format/location-utils.js';\nimport { pickPrimaryPosition } from '../logic/primary-position.js';\nimport { filterHidden } from '../profile/section-model.js';\nimport type { LocationValue } from '../types/index.js';\nimport { normaliseBaseUrl } from './url.js';\n\n/**\n * Maximum number of skills emitted into `knowsAbout`. The rendered profile\n * still shows every skill; only this structured-data slot is capped so a\n * profile with many skills does not read as keyword stuffing.\n */\nconst MAX_KNOWS_ABOUT = 20;\n\n/**\n * Treat headlines and about text as meaningful only when they contain at least\n * one letter or digit. Profiles carry headlines that are a single emoji and\n * about fields that are a zero-width space; feeding those to `jobTitle` or\n * `description` produces garbage for crawlers.\n */\nconst MEANINGFUL_TEXT_RE = /[\\p{L}\\p{N}]/u;\n\nexport type Sanitizer = (input: string) => string;\n\nexport interface JsonLdOptions {\n /** Canonical origin for profile URLs. Defaults to `https://sifa.id`. */\n readonly baseUrl?: string;\n /** Applied to every user-authored string. Defaults to identity. */\n readonly sanitize?: Sanitizer;\n /**\n * Absolute URL of the page this graph describes, used for `url` and `@id`.\n * Defaults to `${baseUrl}/p/${handle}`. Personal sites can be served from an\n * arbitrary host, including a self-hosted custom domain, where that default\n * path is not where the page lives.\n */\n readonly canonicalUrl?: string;\n}\n\n/**\n * Structural input for the emitters.\n *\n * Deliberately looser than `Profile`: it accepts a `Profile` unchanged, but\n * also the partial shapes held by consumers that render a subset (page.sifa.id)\n * without forcing them to fabricate required fields.\n */\nexport interface JsonLdProfileInput {\n readonly handle: string;\n readonly displayName?: string;\n readonly givenName?: string;\n readonly familyName?: string;\n readonly headline?: string;\n readonly about?: string;\n readonly avatar?: string;\n readonly website?: string;\n readonly location?: LocationValue | null;\n readonly updatedAt?: string;\n readonly positions?: readonly JsonLdPosition[];\n readonly education?: readonly JsonLdEducation[];\n readonly skills?: readonly JsonLdSkill[];\n readonly certifications?: readonly JsonLdCertification[];\n readonly volunteering?: readonly JsonLdVolunteering[];\n readonly honors?: readonly JsonLdHonor[];\n readonly languages?: readonly JsonLdLanguage[];\n readonly verifiedAccounts?: readonly { platform: string; identifier: string; url?: string }[];\n readonly activeApps?: readonly { id: string }[];\n /** Only the length is read, to decide which section anchors to advertise. */\n readonly projects?: readonly unknown[];\n readonly publications?: readonly unknown[];\n readonly courses?: readonly unknown[];\n readonly externalAccounts?: readonly unknown[];\n /**\n * Dual-facet accounts: one DID presenting as both a person and a company.\n * Only the opted-in case is emitted, see `buildPersonJsonLd`.\n */\n readonly org?: {\n readonly personalProfileVisible?: boolean;\n readonly orgProfile?: { readonly name?: string } | null;\n } | null;\n}\n\ninterface Hideable {\n readonly hidden?: boolean;\n}\nexport interface JsonLdPosition extends Hideable {\n readonly company?: string;\n /**\n * Current canonical name of the linked company entity, resolved by the\n * AppView at read time. Preferred over the free-text `company` snapshot for\n * `worksFor.name` so structured data names the corrected (and decoded) entity.\n */\n readonly entityName?: string;\n readonly title?: string;\n readonly startedAt?: string;\n readonly endedAt?: string;\n readonly description?: string;\n readonly primary?: boolean;\n}\nexport interface JsonLdEducation extends Hideable {\n readonly institution?: string;\n readonly degree?: string;\n readonly fieldOfStudy?: string;\n}\nexport interface JsonLdSkill extends Hideable {\n readonly name?: string;\n readonly endorsementCount?: number;\n}\nexport interface JsonLdCertification extends Hideable {\n readonly name?: string;\n readonly authority?: string;\n readonly issuingOrg?: string;\n readonly credentialUrl?: string;\n}\nexport interface JsonLdVolunteering extends Hideable {\n readonly organization?: string;\n readonly role?: string;\n readonly startDate?: string;\n readonly endDate?: string;\n}\nexport interface JsonLdHonor extends Hideable {\n readonly title?: string;\n}\nexport interface JsonLdLanguage extends Hideable {\n readonly language?: string;\n}\n\nconst identity: Sanitizer = (input) => input;\n\nfunction hasMeaningfulText(value: string | undefined | null): value is string {\n return typeof value === 'string' && MEANINGFUL_TEXT_RE.test(value);\n}\n\n/** `filterHidden` takes a mutable array; the input types are readonly. */\nfunction visible<T extends Hideable>(items: readonly T[] | undefined): T[] {\n return filterHidden(items ? [...items] : undefined);\n}\n\n/**\n * Selects and ranks the skills surfaced in `knowsAbout`. Ordered by endorsement\n * count descending, a missing count counting as zero, ties preserving input\n * order. Returns undefined when no named skill exists so the property is\n * omitted entirely rather than emitted empty.\n */\nfunction rankKnowsAbout(\n skills: readonly JsonLdSkill[] | undefined,\n s: Sanitizer,\n): string[] | undefined {\n const ranked = visible(skills)\n .filter((sk): sk is JsonLdSkill & { name: string } => Boolean(sk.name))\n .sort((a, b) => (b.endorsementCount ?? 0) - (a.endorsementCount ?? 0))\n .slice(0, MAX_KNOWS_ABOUT)\n .map((sk) => s(sk.name));\n\n return ranked.length > 0 ? ranked : undefined;\n}\n\nfunction buildSameAs(profile: JsonLdProfileInput): string[] {\n const sameAs: string[] = [];\n\n // ATproto is multi-app: a Sifa identity may hold no Bluesky records at all.\n // Only link bsky.app when activeApps confirms Bluesky presence, otherwise the\n // link points at an empty profile and weakens entity resolution rather than\n // strengthening it.\n const hasBluesky = profile.activeApps?.some((a) => a.id === 'bluesky') ?? false;\n if (hasBluesky) sameAs.push(`https://bsky.app/profile/${profile.handle}`);\n\n if (profile.website) {\n const url = profile.website.startsWith('http') ? profile.website : `https://${profile.website}`;\n if (!sameAs.includes(url)) sameAs.push(url);\n }\n\n for (const account of profile.verifiedAccounts ?? []) {\n if (account.url && !sameAs.includes(account.url)) sameAs.push(account.url);\n }\n\n return sameAs;\n}\n\nfunction buildHomeLocation(location: LocationValue, s: Sanitizer) {\n // Emit the address sub-object when either a country code or a locality is\n // present. Locality prefers the community-shape `locality` with a fallback to\n // the legacy `city` so output stays correct whichever shape the AppView emits.\n const addressLocality = location.locality ?? location.city;\n const addressCountry = location.countryCode;\n const hasAddress = Boolean(addressLocality) || Boolean(addressCountry);\n\n return {\n '@type': 'Place' as const,\n name: s(formatLocation(location)),\n ...(hasAddress && {\n address: {\n '@type': 'PostalAddress' as const,\n ...(addressLocality && { addressLocality: s(addressLocality) }),\n ...(addressCountry && { addressCountry }),\n },\n }),\n };\n}\n\nexport function buildPersonJsonLd(profile: JsonLdProfileInput, options: JsonLdOptions = {}) {\n const s = options.sanitize ?? identity;\n const baseUrl = normaliseBaseUrl(options.baseUrl);\n // The own-company link below deliberately keeps the baseUrl origin: a /c/\n // page lives on Sifa even when the personal site does not.\n const canonical = options.canonicalUrl ?? `${baseUrl}/p/${profile.handle}`;\n\n const positions = visible(profile.positions);\n const currentPosition = pickPrimaryPosition(positions);\n const knowsAbout = rankKnowsAbout(profile.skills, s);\n const sameAs = buildSameAs(profile);\n\n const hasCredential = [\n ...visible(profile.education)\n .filter((e) => e.degree)\n .map((e) => ({\n '@type': 'EducationalOccupationalCredential' as const,\n credentialCategory: 'degree' as const,\n name: [e.degree, e.fieldOfStudy].filter(Boolean).join(' '),\n ...(e.institution && {\n recognizedBy: { '@type': 'EducationalOrganization' as const, name: s(e.institution) },\n }),\n })),\n ...visible(profile.certifications)\n .filter((c) => c.name)\n .map((c) => ({\n '@type': 'EducationalOccupationalCredential' as const,\n name: s(c.name!),\n ...((c.authority ?? c.issuingOrg) && {\n recognizedBy: {\n '@type': 'Organization' as const,\n name: s((c.authority ?? c.issuingOrg)!),\n },\n }),\n ...(c.credentialUrl && { url: c.credentialUrl }),\n })),\n ];\n\n // Prefer the structured name when both halves are present so `name` stays\n // consistent with the explicit givenName/familyName properties.\n const givenTrimmed = profile.givenName?.trim();\n const familyTrimmed = profile.familyName?.trim();\n const structuredName =\n givenTrimmed && familyTrimmed ? `${givenTrimmed} ${familyTrimmed}` : undefined;\n\n // A sole trader who kept both faces is one legal person and one business on\n // a single DID. Without an explicit link a crawler reads the /p/ Person and\n // the /c/ Organization as two unrelated entities that happen to share a\n // domain. The company goes first: it is the account's own business, ahead of\n // any self-reported position elsewhere.\n const ownCompany =\n profile.org?.personalProfileVisible && profile.org.orgProfile\n ? {\n '@type': 'Organization' as const,\n '@id': `${baseUrl}/c/${profile.handle}`,\n name: s(profile.org.orgProfile.name ?? profile.handle),\n }\n : null;\n const worksFor = [\n ...(ownCompany ? [ownCompany] : []),\n ...positions\n .filter((p) => p.entityName ?? p.company)\n .map((p) => ({\n '@type': 'Organization' as const,\n name: s((p.entityName ?? p.company)!),\n ...(p.title && {\n member: {\n '@type': 'OrganizationRole' as const,\n roleName: s(p.title),\n ...(p.startedAt && { startDate: p.startedAt }),\n ...(p.endedAt && { endDate: p.endedAt }),\n },\n }),\n })),\n ];\n\n const awards = visible(profile.honors)\n .filter((h) => h.title)\n .map((h) => s(h.title!));\n const languages = visible(profile.languages)\n .filter((l) => l.language)\n .map((l) => l.language!);\n\n return {\n '@context': 'https://schema.org',\n '@type': 'Person',\n // Stable identifier so a /c/ Organization's `founder` can point back here.\n '@id': canonical,\n name: s(structuredName ?? profile.displayName ?? profile.handle),\n ...(givenTrimmed && { givenName: s(givenTrimmed) }),\n ...(familyTrimmed && { familyName: s(familyTrimmed) }),\n jobTitle: hasMeaningfulText(profile.headline)\n ? s(profile.headline)\n : currentPosition?.title\n ? s(currentPosition.title)\n : undefined,\n description: hasMeaningfulText(profile.about) ? s(profile.about) : undefined,\n alternateName: `@${profile.handle}`,\n url: canonical,\n image: profile.avatar ?? undefined,\n ...(profile.location && { homeLocation: buildHomeLocation(profile.location, s) }),\n ...(worksFor.length > 0 && { worksFor }),\n ...(visible(profile.education).length > 0 && {\n alumniOf: visible(profile.education)\n .filter((e) => e.institution)\n .map((e) => ({ '@type': 'EducationalOrganization' as const, name: s(e.institution!) })),\n }),\n ...(hasCredential.length > 0 && { hasCredential }),\n ...(visible(profile.volunteering).length > 0 && {\n memberOf: visible(profile.volunteering)\n .filter((v) => v.organization)\n .map((v) => ({\n '@type': 'OrganizationRole' as const,\n memberOf: { '@type': 'Organization' as const, name: s(v.organization!) },\n ...(v.role && { roleName: s(v.role) }),\n ...(v.startDate && { startDate: v.startDate }),\n ...(v.endDate && { endDate: v.endDate }),\n })),\n }),\n ...(awards.length > 0 && { award: awards }),\n ...(languages.length > 0 && { knowsLanguage: languages }),\n ...(knowsAbout && { knowsAbout }),\n ...(sameAs.length > 0 && { sameAs }),\n };\n}\n\n/**\n * Section anchors are a soft public API: third-party tools link to `#career`,\n * `#languages` and friends. Renaming one is a breaking change. Each id MUST\n * match the DOM id rendered by the consuming app.\n */\nconst PROFILE_SECTION_HAS_PART: readonly {\n id: string;\n label: string;\n populated: (p: JsonLdProfileInput) => boolean;\n}[] = [\n { id: 'about', label: 'About', populated: (p) => Boolean(p.about && p.headline) },\n { id: 'career', label: 'Career', populated: (p) => visible(p.positions).length > 0 },\n { id: 'education', label: 'Education', populated: (p) => visible(p.education).length > 0 },\n { id: 'projects', label: 'Projects', populated: (p) => (p.projects?.length ?? 0) > 0 },\n {\n id: 'credentials',\n label: 'Credentials',\n populated: (p) => visible(p.certifications).length > 0,\n },\n {\n id: 'publications',\n label: 'Publications',\n populated: (p) => (p.publications?.length ?? 0) > 0,\n },\n {\n id: 'volunteering',\n label: 'Volunteering',\n populated: (p) => visible(p.volunteering).length > 0,\n },\n { id: 'awards', label: 'Awards', populated: (p) => visible(p.honors).length > 0 },\n { id: 'languages', label: 'Languages', populated: (p) => visible(p.languages).length > 0 },\n { id: 'skills', label: 'Skills', populated: (p) => visible(p.skills).length > 0 },\n {\n id: 'other-profiles',\n label: 'Other profiles',\n populated: (p) => (p.externalAccounts?.length ?? 0) > 0,\n },\n];\n\nexport function buildProfilePageJsonLd(profile: JsonLdProfileInput, options: JsonLdOptions = {}) {\n const person = buildPersonJsonLd(profile, options);\n const { '@context': _context, ...personWithoutContext } = person;\n\n const url = options.canonicalUrl ?? `${normaliseBaseUrl(options.baseUrl)}/p/${profile.handle}`;\n const hasPart = PROFILE_SECTION_HAS_PART.filter((section) => section.populated(profile)).map(\n (section) => ({\n '@type': 'WebPageElement' as const,\n name: section.label,\n url: `${url}#${section.id}`,\n }),\n );\n\n return {\n '@context': 'https://schema.org',\n '@type': 'ProfilePage' as const,\n url,\n ...(profile.updatedAt && { dateModified: profile.updatedAt }),\n mainEntity: personWithoutContext,\n ...(hasPart.length > 0 && { hasPart }),\n };\n}\n\nexport function buildBreadcrumbListJsonLd(\n profile: Pick<JsonLdProfileInput, 'handle' | 'displayName'>,\n options: JsonLdOptions = {},\n) {\n const s = options.sanitize ?? identity;\n const baseUrl = normaliseBaseUrl(options.baseUrl);\n const name = s(profile.displayName ?? profile.handle);\n\n return {\n '@context': 'https://schema.org',\n '@type': 'BreadcrumbList' as const,\n itemListElement: [\n { '@type': 'ListItem' as const, position: 1, name: 'Sifa', item: `${baseUrl}/` },\n {\n '@type': 'ListItem' as const,\n position: 2,\n name,\n item: `${baseUrl}/p/${profile.handle}`,\n },\n ],\n };\n}\n","/**\n * Reduce a DOI to its bare form: `10.1234/example`, never\n * `https://doi.org/10.1234/example` and never `doi:10.1234/example`.\n *\n * A DOI inside a URL is a link. Bare, it is an identifier, which is what lets\n * two records describing one publication be matched on it. The lexicon stores\n * the bare form for that reason.\n *\n * People paste the resolver URL, because that is what a publisher page and a\n * citation manager both hand you, and citations carry the `doi:` scheme.\n * Normalizing on the way in is the difference between a field that dedupes and\n * a field holding three spellings of one value.\n *\n * Input that is not a DOI at all is trimmed and returned as-is. This is a\n * normalizer, not a validator: rejecting here would fail a write over a field\n * nothing depends on, and older registrants produce shapes worth not policing.\n */\nexport function normalizeDoi(value: string): string {\n return value\n .trim()\n .replace(/^https?:\\/\\/(dx\\.)?doi\\.org\\//i, '')\n .replace(/^doi:\\s*/i, '');\n}\n","/**\n * Slug helpers for talk-page URLs. Pure and offline: a talk page lives at a\n * path like `/{slug}-{rkey}`, where the slug is a human-readable, SEO-friendly\n * rendering of the title and the rkey is the record's stable identifier.\n * Because TIDs never contain a `-`, the rkey can always be recovered as the\n * substring after the final `-`.\n */\n\n/** Maximum slug length before the trailing rkey is appended. */\nconst MAX_SLUG_LENGTH = 60;\n\n/** Combining diacritical marks left behind by NFKD decomposition (U+0300–U+036F). */\nconst COMBINING_MARKS = /[̀-ͯ]/g;\n\n/**\n * Render a title as a URL slug: lowercased, diacritics stripped, runs of\n * non-alphanumerics collapsed to a single `-`, trimmed, and capped at 60 chars.\n * Returns `''` for an empty or whitespace-only title.\n */\nexport function slugifyTitle(title: string): string {\n const slug = title\n .normalize('NFKD')\n // Strip combining marks left by NFKD decomposition (é -> e).\n .replace(COMBINING_MARKS, '')\n .toLowerCase()\n // Collapse any run of non-alphanumerics into a single hyphen.\n .replace(/[^a-z0-9]+/g, '-')\n // Collapse repeated hyphens.\n .replace(/-+/g, '-')\n // Trim leading/trailing hyphens.\n .replace(/^-+|-+$/g, '');\n // Cap length, then trim a trailing hyphen the cut may have exposed.\n return slug.slice(0, MAX_SLUG_LENGTH).replace(/-+$/g, '');\n}\n\n/**\n * Build the talk-page path segment `${slug}-${rkey}`, or just `rkey` when the\n * title produces an empty slug.\n */\nexport function buildTalkSlug(title: string, rkey: string): string {\n const slug = slugifyTitle(title);\n return slug ? `${slug}-${rkey}` : rkey;\n}\n\n/**\n * Recover the rkey from a talk-page segment: the substring after the final `-`\n * (TIDs contain no `-`). Returns the whole segment when there is no `-`.\n */\nexport function parseTalkRkey(segment: string): string {\n const idx = segment.lastIndexOf('-');\n return idx === -1 ? segment : segment.slice(idx + 1);\n}\n","/**\n * Schema.org JSON-LD for the things a person made: talks, publications,\n * courses and projects.\n *\n * These collections carried no structured data before this module existed;\n * a talk page emitted a four-property `CreativeWork` and publications,\n * courses and projects emitted nothing at all. Term choices are recorded in\n * `./terms.js`.\n */\n\nimport { normalizeDoi } from '../format/doi.js';\nimport { buildTalkSlug } from '../format/talk-slug.js';\nimport { filterHidden } from '../profile/section-model.js';\nimport { normaliseBaseUrl, profileUrl } from './url.js';\n\nconst DOI_RESOLVER = 'https://doi.org/';\nconst ORCID_RESOLVER = 'https://orcid.org/';\n\nexport interface WorksOptions {\n readonly baseUrl?: string;\n readonly sanitize?: (input: string) => string;\n}\n\n/** Minimal identity for the profile owner a work is attributed to. */\nexport interface WorkAuthor {\n readonly handle: string;\n readonly displayName?: string;\n}\n\n/**\n * A person named on somebody else's record. `confirmed` is load bearing: an\n * unconfirmed claim is a claim, not a fact, and must never be laundered into\n * structured data as a schema.org Person.\n */\ninterface NamedActor {\n readonly did?: string;\n readonly handle?: string;\n readonly displayName?: string;\n readonly confirmed?: boolean;\n}\n\ninterface PersonNode {\n readonly '@type': 'Person';\n readonly name: string;\n readonly url?: string;\n readonly sameAs?: string[];\n}\n\nconst identity = (input: string) => input;\n\nfunction authorNode(author: WorkAuthor, baseUrl: string, s: (v: string) => string): PersonNode {\n return {\n '@type': 'Person',\n name: s(author.displayName ?? author.handle),\n url: profileUrl(baseUrl, author.handle),\n };\n}\n\n/**\n * Confirmed named actors only, mapped to Person nodes. Anyone unconfirmed is\n * dropped entirely rather than degraded to a bare handle, because even a handle\n * in structured data asserts the association.\n */\nfunction confirmedActorNodes(\n actors: readonly NamedActor[] | undefined,\n baseUrl: string,\n s: (v: string) => string,\n): PersonNode[] {\n return (actors ?? [])\n .filter((a) => a.confirmed === true && Boolean(a.handle))\n .map((a) => ({\n '@type': 'Person' as const,\n name: s(a.displayName ?? a.handle!),\n url: profileUrl(baseUrl, a.handle!),\n }));\n}\n\n/** `filterHidden` takes a mutable array; inputs here are readonly. */\nfunction visible<T extends { hidden?: boolean }>(items: readonly T[] | undefined): T[] {\n return filterHidden(items ? [...items] : undefined);\n}\n\n// ---------------------------------------------------------------------------\n// Presentations\n// ---------------------------------------------------------------------------\n\n/**\n * The community calendar known values are already one-to-one with the\n * schema.org enumerations. An unrecognised value is left off rather than\n * guessed: a wrong attendance mode is worse than a missing one.\n */\nconst ATTENDANCE_MODE: Readonly<Record<string, string>> = {\n 'community.lexicon.calendar.event#inperson': 'https://schema.org/OfflineEventAttendanceMode',\n 'community.lexicon.calendar.event#virtual': 'https://schema.org/OnlineEventAttendanceMode',\n 'community.lexicon.calendar.event#hybrid': 'https://schema.org/MixedEventAttendanceMode',\n};\n\n/**\n * `#planned` is intentionally absent: schema.org has no equivalent, and mapping\n * it to EventScheduled would assert a commitment the record does not make.\n */\nconst EVENT_STATUS: Readonly<Record<string, string>> = {\n 'community.lexicon.calendar.event#scheduled': 'https://schema.org/EventScheduled',\n 'community.lexicon.calendar.event#cancelled': 'https://schema.org/EventCancelled',\n 'community.lexicon.calendar.event#postponed': 'https://schema.org/EventPostponed',\n 'community.lexicon.calendar.event#rescheduled': 'https://schema.org/EventRescheduled',\n};\n\nconst LINK_SLIDES = 'id.sifa.defs#linkSlides';\nconst LINK_RECORDING = 'id.sifa.defs#linkRecording';\n\nexport interface PresentationLinkInput {\n readonly uri: string;\n readonly label?: string;\n readonly type?: string;\n}\n\nexport interface PresentationDeliveryInput {\n readonly rkey: string;\n readonly title?: string | null;\n readonly role?: string | null;\n readonly eventName?: string | null;\n readonly date?: string | null;\n readonly location?: string | null;\n readonly locationLocality?: string | null;\n readonly locationRegion?: string | null;\n readonly countryCode?: string | null;\n readonly mode?: string | null;\n readonly status?: string | null;\n readonly links?: readonly PresentationLinkInput[];\n readonly coSpeakers?: readonly NamedActor[];\n readonly hidden?: boolean;\n}\n\nexport interface PresentationInput {\n readonly rkey: string;\n readonly title: string;\n readonly description?: string | null;\n readonly duration?: { minMinutes: number; maxMinutes?: number } | null;\n readonly coverImageUrl?: string | null;\n readonly links?: readonly PresentationLinkInput[];\n readonly deliveries?: readonly PresentationDeliveryInput[];\n readonly hidden?: boolean;\n}\n\nfunction lookup(table: Readonly<Record<string, string>>, key: string | null | undefined) {\n if (!key) return undefined;\n return Object.prototype.hasOwnProperty.call(table, key) ? table[key] : undefined;\n}\n\nfunction deliveryPlace(delivery: PresentationDeliveryInput, s: (v: string) => string) {\n const addressLocality = delivery.locationLocality ?? undefined;\n const addressRegion = delivery.locationRegion ?? undefined;\n const addressCountry = delivery.countryCode ?? undefined;\n\n if (addressLocality || addressRegion || addressCountry) {\n return {\n '@type': 'Place' as const,\n address: {\n '@type': 'PostalAddress' as const,\n ...(addressLocality && { addressLocality: s(addressLocality) }),\n ...(addressRegion && { addressRegion: s(addressRegion) }),\n ...(addressCountry && { addressCountry }),\n },\n };\n }\n\n // Legacy free-text location, kept so deliveries recorded before the\n // structured address field still say where they happened.\n if (delivery.location) {\n return { '@type': 'Place' as const, name: s(delivery.location) };\n }\n\n return undefined;\n}\n\nfunction linkOfType(links: readonly PresentationLinkInput[] | undefined, type: string) {\n return links?.find((l) => l.type === type)?.uri;\n}\n\nexport function buildPresentationJsonLd(\n presentation: PresentationInput,\n author: WorkAuthor,\n options: WorksOptions = {},\n) {\n const s = options.sanitize ?? identity;\n const baseUrl = normaliseBaseUrl(options.baseUrl);\n const speaker = authorNode(author, baseUrl, s);\n\n const events = visible(presentation.deliveries).map((delivery) => {\n const place = deliveryPlace(delivery, s);\n const recording = linkOfType(delivery.links, LINK_RECORDING);\n const slides =\n linkOfType(delivery.links, LINK_SLIDES) ?? linkOfType(presentation.links, LINK_SLIDES);\n\n return {\n '@type': 'Event' as const,\n name: s(delivery.eventName ?? delivery.title ?? presentation.title),\n ...(delivery.date && { startDate: delivery.date }),\n ...(place && { location: place }),\n ...(lookup(ATTENDANCE_MODE, delivery.mode) && {\n eventAttendanceMode: lookup(ATTENDANCE_MODE, delivery.mode),\n }),\n ...(lookup(EVENT_STATUS, delivery.status) && {\n eventStatus: lookup(EVENT_STATUS, delivery.status),\n }),\n performer: [speaker, ...confirmedActorNodes(delivery.coSpeakers, baseUrl, s)],\n ...(recording && { recordedIn: { '@type': 'VideoObject' as const, url: recording } }),\n ...(slides && {\n workFeatured: { '@type': 'PresentationDigitalDocument' as const, url: slides },\n }),\n };\n });\n\n return {\n '@context': 'https://schema.org',\n '@type': 'PresentationDigitalDocument' as const,\n name: s(presentation.title),\n ...(presentation.description && { abstract: s(presentation.description) }),\n ...(presentation.duration && { timeRequired: `PT${presentation.duration.minMinutes}M` }),\n ...(presentation.coverImageUrl && { image: presentation.coverImageUrl }),\n author: speaker,\n url: `${baseUrl}/p/${author.handle}/talk/${buildTalkSlug(presentation.title, presentation.rkey)}`,\n ...(events.length > 0 && { subjectOf: events }),\n };\n}\n\n// ---------------------------------------------------------------------------\n// Publications\n// ---------------------------------------------------------------------------\n\nexport interface PublicationContributorInput {\n readonly name: string;\n readonly orcidId?: string;\n readonly handle?: string;\n}\n\nexport interface PublicationInput {\n readonly rkey: string;\n readonly title: string;\n readonly subtitle?: string;\n readonly publisher?: string;\n readonly date?: string;\n readonly url?: string;\n readonly description?: string;\n readonly doi?: string;\n readonly contributors?: readonly PublicationContributorInput[];\n readonly hidden?: boolean;\n}\n\nexport function buildPublicationJsonLd(\n publication: PublicationInput,\n author: WorkAuthor,\n options: WorksOptions = {},\n) {\n const s = options.sanitize ?? identity;\n const baseUrl = normaliseBaseUrl(options.baseUrl);\n\n // Contributor order is meaningful in scholarly work, so it is preserved as\n // given rather than sorted or deduplicated.\n const authors: PersonNode[] =\n publication.contributors && publication.contributors.length > 0\n ? publication.contributors.map((c) => ({\n '@type': 'Person' as const,\n name: s(c.name),\n ...(c.handle && { url: profileUrl(baseUrl, c.handle) }),\n ...(c.orcidId && { sameAs: [`${ORCID_RESOLVER}${c.orcidId}`] }),\n }))\n : [authorNode(author, baseUrl, s)];\n\n const doi = publication.doi ? normalizeDoi(publication.doi) : undefined;\n\n return {\n '@context': 'https://schema.org',\n '@type': 'ScholarlyArticle' as const,\n name: s(publication.title),\n ...(publication.subtitle && { alternativeHeadline: s(publication.subtitle) }),\n ...(publication.description && { abstract: s(publication.description) }),\n ...(publication.publisher && {\n publisher: { '@type': 'Organization' as const, name: s(publication.publisher) },\n }),\n ...(publication.date && { datePublished: publication.date }),\n ...(publication.url && { url: publication.url }),\n author: authors,\n ...(doi && {\n identifier: { '@type': 'PropertyValue' as const, propertyID: 'DOI', value: doi },\n sameAs: [`${DOI_RESOLVER}${doi}`],\n }),\n };\n}\n\n// ---------------------------------------------------------------------------\n// Courses and projects\n// ---------------------------------------------------------------------------\n\nexport interface CourseInput {\n readonly rkey: string;\n readonly name: string;\n readonly number?: string;\n readonly institution?: string;\n readonly hidden?: boolean;\n}\n\nexport function buildCourseJsonLd(course: CourseInput, options: WorksOptions = {}) {\n const s = options.sanitize ?? identity;\n return {\n '@context': 'https://schema.org',\n '@type': 'Course' as const,\n name: s(course.name),\n ...(course.number && { courseCode: s(course.number) }),\n ...(course.institution && {\n provider: { '@type': 'EducationalOrganization' as const, name: s(course.institution) },\n }),\n };\n}\n\nexport interface ProjectInput {\n readonly rkey: string;\n readonly name: string;\n readonly description?: string;\n readonly url?: string;\n readonly startDate?: string;\n readonly endDate?: string;\n readonly members?: readonly NamedActor[];\n readonly hidden?: boolean;\n}\n\nexport function buildProjectJsonLd(\n project: ProjectInput,\n author: WorkAuthor,\n options: WorksOptions = {},\n) {\n const s = options.sanitize ?? identity;\n const baseUrl = normaliseBaseUrl(options.baseUrl);\n const members = confirmedActorNodes(project.members, baseUrl, s);\n\n return {\n '@context': 'https://schema.org',\n '@type': 'Project' as const,\n name: s(project.name),\n ...(project.description && { description: s(project.description) }),\n ...(project.url && { url: project.url }),\n ...(project.startDate && { startDate: project.startDate }),\n ...(project.endDate && { endDate: project.endDate }),\n member: [authorNode(author, baseUrl, s), ...members],\n };\n}\n","/**\n * The works on a profile as one JSON-LD `@graph`.\n *\n * A profile page already emits a `ProfilePage` whose `mainEntity` is the\n * Person. Publications, talks, courses and projects are separate entities\n * rather than properties of that Person, so they go in their own block and\n * point back at the Person by `@id` instead of repeating the whole node.\n */\n\nimport { filterHidden } from '../profile/section-model.js';\nimport type { JsonLdOptions } from './profile.js';\nimport { normaliseBaseUrl } from './url.js';\nimport {\n buildCourseJsonLd,\n buildPresentationJsonLd,\n buildProjectJsonLd,\n buildPublicationJsonLd,\n type CourseInput,\n type PresentationInput,\n type ProjectInput,\n type PublicationInput,\n type WorkAuthor,\n} from './works.js';\n\nexport interface ProfileWorksInput {\n readonly handle: string;\n readonly publications?: readonly PublicationInput[];\n readonly presentations?: readonly PresentationInput[];\n readonly courses?: readonly CourseInput[];\n readonly projects?: readonly ProjectInput[];\n}\n\n/** `filterHidden` takes a mutable array; inputs here are readonly. */\nfunction visible<T extends { hidden?: boolean }>(items: readonly T[] | undefined): T[] {\n return filterHidden(items ? [...items] : undefined);\n}\n\n/**\n * Returns null when there is nothing to say, so a caller can skip the script\n * block entirely rather than emitting an empty graph.\n */\nexport function buildProfileWorksJsonLd(\n profile: ProfileWorksInput,\n author: WorkAuthor,\n options: JsonLdOptions = {},\n) {\n const personId =\n options.canonicalUrl ?? `${normaliseBaseUrl(options.baseUrl)}/p/${profile.handle}`;\n\n // Each work is built by its own emitter, then its `@context` is dropped: the\n // graph carries one context for every node in it.\n const strip = <T extends { '@context': string }>(node: T) => {\n const { '@context': _context, ...rest } = node;\n return rest;\n };\n\n // The Person is emitted in full by the ProfilePage block. Referencing it by\n // `@id` keeps one Person in the graph rather than several partial copies for\n // a consumer to reconcile.\n const authorRef = [{ '@id': personId }];\n\n const graph: Record<string, unknown>[] = [\n ...visible(profile.publications).map((p) => ({\n ...strip(buildPublicationJsonLd(p, author, options)),\n author: authorRef,\n })),\n ...visible(profile.presentations).map((p) => ({\n ...strip(buildPresentationJsonLd(p, author, options)),\n author: authorRef,\n })),\n ...visible(profile.courses).map((c) => strip(buildCourseJsonLd(c, options))),\n ...visible(profile.projects).map((p) => ({\n ...strip(buildProjectJsonLd(p, author, options)),\n member: authorRef,\n })),\n ];\n\n if (graph.length === 0) return null;\n\n return { '@context': 'https://schema.org', '@graph': graph };\n}\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { c as Profile, d as ProfilePosition, S as SkillRef, w as PresentationLinkView } from './index-
|
|
2
|
-
import { S as SifaApiConfig, A as ApiFetchOptions, C as CreateResult, W as WriteResult } from './org-
|
|
3
|
-
import { n as ProfileView } from './types-
|
|
4
|
-
import { S as SummarizeProfileViewOptions, P as ProfileSummary } from './profile-summary-
|
|
1
|
+
import { c as Profile, d as ProfilePosition, S as SkillRef, w as PresentationLinkView } from './index-DIwi3bpk.cjs';
|
|
2
|
+
import { S as SifaApiConfig, A as ApiFetchOptions, C as CreateResult, W as WriteResult } from './org-3gFPQ_pC.cjs';
|
|
3
|
+
import { n as ProfileView } from './types-LElwqDU4.cjs';
|
|
4
|
+
import { S as SummarizeProfileViewOptions, P as ProfileSummary } from './profile-summary-BnydsN4P.cjs';
|
|
5
5
|
import { j as EntitySearchResponse, E as EntitySearchResult, d as EntityMintDomainResponse, h as EntityResolveDomainResponse, m as EntitySelectRequest, o as EntitySelectResponse } from './feed-BMm9Pkew.cjs';
|
|
6
6
|
|
|
7
7
|
/**
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { c as Profile, d as ProfilePosition, S as SkillRef, w as PresentationLinkView } from './index-
|
|
2
|
-
import { S as SifaApiConfig, A as ApiFetchOptions, C as CreateResult, W as WriteResult } from './org-
|
|
3
|
-
import { n as ProfileView } from './types-
|
|
4
|
-
import { S as SummarizeProfileViewOptions, P as ProfileSummary } from './profile-summary-
|
|
1
|
+
import { c as Profile, d as ProfilePosition, S as SkillRef, w as PresentationLinkView } from './index-DIwi3bpk.js';
|
|
2
|
+
import { S as SifaApiConfig, A as ApiFetchOptions, C as CreateResult, W as WriteResult } from './org-CTSJ5zTZ.js';
|
|
3
|
+
import { n as ProfileView } from './types-Co7D0VfD.js';
|
|
4
|
+
import { S as SummarizeProfileViewOptions, P as ProfileSummary } from './profile-summary-H-R1juYp.js';
|
|
5
5
|
import { j as EntitySearchResponse, E as EntitySearchResult, d as EntityMintDomainResponse, h as EntityResolveDomainResponse, m as EntitySelectRequest, o as EntitySelectResponse } from './feed-BMm9Pkew.js';
|
|
6
6
|
|
|
7
7
|
/**
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { p as ExternalAccount, Q as SkillSuggestion } from './index-
|
|
1
|
+
import { p as ExternalAccount, Q as SkillSuggestion } from './index-DIwi3bpk.cjs';
|
|
2
2
|
import { y as FollowFeedPage, B as FollowProfileItem, q as FeatureAllowlistEntry, s as FeatureFlag } from './feed-BMm9Pkew.cjs';
|
|
3
|
-
import { b as ActivityLabel, t as RepoDeleteResult, w as RepoInventory } from './types-
|
|
3
|
+
import { b as ActivityLabel, t as RepoDeleteResult, w as RepoInventory } from './types-LElwqDU4.cjs';
|
|
4
4
|
import { z } from 'zod';
|
|
5
5
|
import { d as OrgNotificationEmailRequestInput, b as OrgDomainChallengeRequestInput, O as OrgClaimRequestInput, a as OrgProfileUpdateRequestInput, c as OrgDomainVerifyRequestInput } from './org-settings-CZ_tmAYl.cjs';
|
|
6
6
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { p as ExternalAccount, Q as SkillSuggestion } from './index-
|
|
1
|
+
import { p as ExternalAccount, Q as SkillSuggestion } from './index-DIwi3bpk.js';
|
|
2
2
|
import { y as FollowFeedPage, B as FollowProfileItem, q as FeatureAllowlistEntry, s as FeatureFlag } from './feed-BMm9Pkew.js';
|
|
3
|
-
import { b as ActivityLabel, t as RepoDeleteResult, w as RepoInventory } from './types-
|
|
3
|
+
import { b as ActivityLabel, t as RepoDeleteResult, w as RepoInventory } from './types-Co7D0VfD.js';
|
|
4
4
|
import { z } from 'zod';
|
|
5
5
|
import { d as OrgNotificationEmailRequestInput, b as OrgDomainChallengeRequestInput, O as OrgClaimRequestInput, a as OrgProfileUpdateRequestInput, c as OrgDomainVerifyRequestInput } from './org-settings-CZ_tmAYl.js';
|
|
6
6
|
|