// Contract 5.3 §31.4. Discovery and rendering share this resolver. export function resolveSurfaceURL(value, exhibitBaseUrl) { if (typeof value !== 'string' || !value.trim() || value !== value.trim() || /[\u0000-\u001f\u007f]/.test(value) || /^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(value) || value.startsWith('//')) { throw new Error('Surface URL must be a same-origin-relative reference (§31.4).'); } const base = new URL(exhibitBaseUrl); const resolved = new URL(value, base); if (!['http:', 'https:'].includes(base.protocol) || resolved.origin !== base.origin || resolved.username || resolved.password) { throw new Error('Surface URL must resolve same-origin with the supplying HTTP exhibit (§31.4).'); } return resolved.href; }