@skhema/web-component 0.0.10 → 0.0.12

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.
@@ -1 +1 @@
1
- {"version":3,"file":"SkhemaElement.d.ts","sourceRoot":"","sources":["../../src/components/SkhemaElement.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAkB,WAAW,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AA8T9G,qBAAa,aAAc,SAAQ,WAAW;IAC5C,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,WAAW,CAA4B;IAC/C,OAAO,CAAC,kBAAkB,CAAS;;IAOnC,MAAM,KAAK,kBAAkB,IAAI,CAAC,MAAM,uBAAuB,CAAC,EAAE,CAEjE;IAED,iBAAiB;IAYjB,wBAAwB,CAAC,KAAK,EAAE,MAAM,uBAAuB,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAM/G,OAAO,CAAC,MAAM;IA4Bd,OAAO,CAAC,UAAU;IAIlB,OAAO,CAAC,aAAa;IAiErB,OAAO,CAAC,qBAAqB;IAQ7B,OAAO,CAAC,WAAW;IASnB,OAAO,CAAC,WAAW;IAuBnB,OAAO,CAAC,iBAAiB;YAoBX,SAAS;YAsBT,eAAe;IAgBtB,cAAc,IAAI,WAAW,GAAG,IAAI;IAIpC,OAAO,IAAI,IAAI;CAGvB;AAGD,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,mBAAoB,SAAQ,qBAAqB;KAAG;IAE9D,UAAU,GAAG,CAAC;QACZ,UAAU,iBAAiB;YACzB,gBAAgB,EAAE,OAAO,CAAC,uBAAuB,CAAC,GAAG;gBACnD,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;aACpB,CAAC;SACH;KACF;CACF"}
1
+ {"version":3,"file":"SkhemaElement.d.ts","sourceRoot":"","sources":["../../src/components/SkhemaElement.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAkB,WAAW,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AA+T9G,qBAAa,aAAc,SAAQ,WAAW;IAC5C,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,WAAW,CAA4B;IAC/C,OAAO,CAAC,kBAAkB,CAAS;;IAOnC,MAAM,KAAK,kBAAkB,IAAI,CAAC,MAAM,uBAAuB,CAAC,EAAE,CAEjE;IAED,iBAAiB;IAYjB,wBAAwB,CAAC,KAAK,EAAE,MAAM,uBAAuB,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAM/G,OAAO,CAAC,MAAM;IA4Bd,OAAO,CAAC,UAAU;IAIlB,OAAO,CAAC,aAAa;IAiErB,OAAO,CAAC,qBAAqB;IAQ7B,OAAO,CAAC,WAAW;IASnB,OAAO,CAAC,WAAW;IAuBnB,OAAO,CAAC,iBAAiB;YAoBX,SAAS;YAsBT,eAAe;IAgBtB,cAAc,IAAI,WAAW,GAAG,IAAI;IAIpC,OAAO,IAAI,IAAI;CAGvB;AAGD,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,mBAAoB,SAAQ,qBAAqB;KAAG;IAE9D,UAAU,GAAG,CAAC;QACZ,UAAU,iBAAiB;YACzB,gBAAgB,EAAE,OAAO,CAAC,uBAAuB,CAAC,GAAG;gBACnD,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;aACpB,CAAC;SACH;KACF;CACF"}
package/dist/index.cjs CHANGED
@@ -35,16 +35,6 @@ function getElementTypeAcronym(elementType) {
35
35
  const type = Object.values(types.ELEMENT_TYPES).find((t) => t.value === elementType);
36
36
  return (type == null ? void 0 : type.acronym) || elementType.substring(0, 2).toUpperCase();
37
37
  }
38
- function generateContentHash$1(content) {
39
- let hash = 0;
40
- const cleanContent = content.trim().substring(0, 200);
41
- for (let i = 0; i < cleanContent.length; i++) {
42
- const char = cleanContent.charCodeAt(i);
43
- hash = (hash << 5) - hash + char;
44
- hash = hash & hash;
45
- }
46
- return Math.abs(hash).toString(36).substring(0, 12);
47
- }
48
38
  async function trackEmbedLoad(analytics) {
49
39
  try {
50
40
  const data = new URLSearchParams({
@@ -62,6 +52,7 @@ async function trackEmbedLoad(analytics) {
62
52
  fetch("https://api.skhema.com/api:XGdoUqHx/component/embed", {
63
53
  method: "POST",
64
54
  body: data,
55
+ credentials: "omit",
65
56
  keepalive: true
66
57
  }).catch(() => {
67
58
  });
@@ -92,6 +83,7 @@ async function trackClick(contentData) {
92
83
  method: "POST",
93
84
  headers: { "Content-Type": "application/json" },
94
85
  body: JSON.stringify(data),
86
+ credentials: "omit",
95
87
  keepalive: true
96
88
  }).catch(() => {
97
89
  });
@@ -104,6 +96,16 @@ function shouldTrackAnalytics(element) {
104
96
  const trackAnalytics = element.getAttribute("track-analytics");
105
97
  return trackAnalytics !== "false";
106
98
  }
99
+ function generateContentHash(content) {
100
+ let hash = 0;
101
+ const cleanContent = content.trim().substring(0, 200);
102
+ for (let i = 0; i < cleanContent.length; i++) {
103
+ const char = cleanContent.charCodeAt(i);
104
+ hash = (hash << 5) - hash + char;
105
+ hash = hash & hash;
106
+ }
107
+ return Math.abs(hash).toString(36).substring(0, 12);
108
+ }
107
109
  function generateStructuredData(content, elementType, contributorId, sourceUrl) {
108
110
  return {
109
111
  "@context": "https://schema.org",
@@ -127,7 +129,7 @@ function generateStructuredData(content, elementType, contributorId, sourceUrl)
127
129
  };
128
130
  }
129
131
  function generateRedirectUrl(content, elementType, contributorId, options = {}) {
130
- const baseUrl = options.baseUrl || "https://api.skhema.com/api:XGdoUqHx/component/redirect";
132
+ const baseUrl = options.baseUrl || "https://app.skhema.com/save";
131
133
  const contentHash = generateContentHash(content);
132
134
  const sourceUrl = encodeURIComponent(window.location.href);
133
135
  const timestamp = Date.now();
@@ -141,9 +143,6 @@ function generateRedirectUrl(content, elementType, contributorId, options = {})
141
143
  });
142
144
  return `${baseUrl}?contributor_id=${contributorId}&element_type=${elementType}&content_hash=${contentHash}&${params.toString()}`;
143
145
  }
144
- function generateContentHash(content) {
145
- return btoa(content.substring(0, 50)).replace(/[^a-zA-Z0-9]/g, "").substring(0, 12);
146
- }
147
146
  function createMetaTags(content, elementType, contributorId) {
148
147
  const label = getElementTypeLabel(elementType);
149
148
  return `
@@ -515,7 +514,7 @@ class SkhemaElement extends HTMLElement {
515
514
  contributor_id: validation.contributorId,
516
515
  element_type: validation.elementType,
517
516
  content,
518
- content_hash: generateContentHash$1(content),
517
+ content_hash: generateContentHash(content),
519
518
  source_url: this.getAttribute("source-url") || window.location.href,
520
519
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
521
520
  page_title: document.title
@@ -666,7 +665,6 @@ if (typeof window !== "undefined" && !customElements.get("skhema-element")) {
666
665
  }
667
666
  exports.SkhemaElement = SkhemaElement;
668
667
  exports.default = SkhemaElement;
669
- exports.generateContentHash = generateContentHash$1;
670
668
  exports.generateRedirectUrl = generateRedirectUrl;
671
669
  exports.generateStructuredData = generateStructuredData;
672
670
  exports.getElementTypeAcronym = getElementTypeAcronym;
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../src/utils/validation.ts","../src/utils/analytics.ts","../src/utils/seo.ts","../src/components/SkhemaElement.ts","../src/index.ts"],"sourcesContent":["import { ELEMENT_TYPES } from '@skhema/types';\nimport type { ElementValue } from '@skhema/types';\n\nexport function isValidElementType(elementType: string): elementType is ElementValue {\n const validTypes = Object.values(ELEMENT_TYPES).map(type => type.value);\n return validTypes.includes(elementType as ElementValue);\n}\n\nexport function validateAttributes(element: HTMLElement): {\n isValid: boolean;\n errors: string[];\n elementType?: ElementValue;\n contributorId?: string;\n} {\n const errors: string[] = [];\n \n const elementType = element.getAttribute('element-type');\n const contributorId = element.getAttribute('contributor-id');\n \n if (!elementType) {\n errors.push('Missing required attribute: element-type');\n } else if (!isValidElementType(elementType)) {\n const validTypes = Object.values(ELEMENT_TYPES).map(t => t.value).join(', ');\n errors.push(`Invalid element-type \"${elementType}\". Valid types: ${validTypes}`);\n }\n \n if (!contributorId) {\n errors.push('Missing required attribute: contributor-id');\n } else if (contributorId.trim().length === 0) {\n errors.push('contributor-id cannot be empty');\n }\n \n return {\n isValid: errors.length === 0,\n errors,\n elementType: isValidElementType(elementType || '') ? elementType as ElementValue : undefined,\n contributorId: contributorId || undefined\n };\n}\n\nexport function getElementTypeLabel(elementType: ElementValue): string {\n const type = Object.values(ELEMENT_TYPES).find(t => t.value === elementType);\n return type?.label || elementType;\n}\n\nexport function getElementTypeAcronym(elementType: ElementValue): string {\n const type = Object.values(ELEMENT_TYPES).find(t => t.value === elementType);\n return type?.acronym || elementType.substring(0, 2).toUpperCase();\n}","import type { EmbedAnalytics, ContentData } from '../components/types.js';\n\nexport function generateContentHash(content: string): string {\n // Simple hash function for content identification\n let hash = 0;\n const cleanContent = content.trim().substring(0, 200);\n \n for (let i = 0; i < cleanContent.length; i++) {\n const char = cleanContent.charCodeAt(i);\n hash = ((hash << 5) - hash) + char;\n hash = hash & hash; // Convert to 32bit integer\n }\n \n return Math.abs(hash).toString(36).substring(0, 12);\n}\n\nexport async function trackEmbedLoad(analytics: EmbedAnalytics): Promise<void> {\n try {\n const data = new URLSearchParams({\n contributor_id: analytics.contributorId,\n element_type: analytics.elementType,\n content_hash: analytics.contentHash,\n page_url: analytics.pageUrl,\n page_title: analytics.pageTitle || '',\n timestamp: analytics.timestamp.toString(),\n user_agent: analytics.userAgent || ''\n });\n\n // Use beacon for reliability\n if (navigator.sendBeacon) {\n navigator.sendBeacon('https://api.skhema.com/api:XGdoUqHx/component/embed', data);\n } else {\n // Fallback to fetch\n fetch('https://api.skhema.com/api:XGdoUqHx/component/embed', {\n method: 'POST',\n body: data,\n keepalive: true\n }).catch(() => {\n // Fail silently - analytics shouldn't break the component\n });\n }\n } catch (error) {\n // Fail silently\n console.debug('Analytics tracking failed:', error);\n }\n}\n\nexport async function trackClick(contentData: ContentData): Promise<void> {\n try {\n const data = {\n contributor_id: contentData.contributor_id,\n element_type: contentData.element_type,\n content_hash: contentData.content_hash,\n source_url: contentData.source_url,\n timestamp: contentData.timestamp\n };\n\n if (navigator.sendBeacon) {\n const blob = new Blob([JSON.stringify(data)], {\n type: 'application/json'\n });\n navigator.sendBeacon(\n 'https://api.skhema.com/api:XGdoUqHx/component/click',\n blob\n );\n } else {\n fetch('https://api.skhema.com/api:XGdoUqHx/component/click', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(data),\n keepalive: true\n }).catch(() => {\n // Fail silently\n });\n }\n } catch (error) {\n console.debug('Click tracking failed:', error);\n }\n}\n\nexport function shouldTrackAnalytics(element: HTMLElement): boolean {\n const trackAnalytics = element.getAttribute('track-analytics');\n return trackAnalytics !== 'false';\n}","import type { ElementValue } from '@skhema/types';\nimport { getElementTypeLabel } from './validation.js';\n\nexport function generateStructuredData(\n content: string,\n elementType: ElementValue,\n contributorId: string,\n sourceUrl: string\n): object {\n return {\n \"@context\": \"https://schema.org\",\n \"@type\": \"AnalysisContent\",\n \"text\": content,\n \"analysisType\": elementType,\n \"category\": getElementTypeLabel(elementType),\n \"contributor\": contributorId,\n \"url\": generateRedirectUrl(content, elementType, contributorId),\n \"provider\": {\n \"@type\": \"Organization\",\n \"name\": \"Skhema\",\n \"url\": \"https://skhema.com\"\n },\n \"isPartOf\": {\n \"@type\": \"WebPage\",\n \"url\": sourceUrl\n },\n \"dateCreated\": new Date().toISOString(),\n \"platform\": \"Skhema\"\n };\n}\n\nexport function generateRedirectUrl(\n content: string,\n elementType: ElementValue,\n contributorId: string,\n options: {\n baseUrl?: string;\n utmSource?: string;\n utmMedium?: string;\n utmCampaign?: string;\n } = {}\n): string {\n const baseUrl = options.baseUrl || 'https://api.skhema.com/api:XGdoUqHx/component/redirect'; // @TODO: change to actual redirect URL\n const contentHash = generateContentHash(content);\n const sourceUrl = encodeURIComponent(window.location.href);\n const timestamp = Date.now();\n \n const params = new URLSearchParams({\n source: sourceUrl,\n t: timestamp.toString(),\n utm_source: options.utmSource || 'web_component',\n utm_medium: options.utmMedium || 'embedded',\n utm_campaign: options.utmCampaign || elementType,\n utm_content: contributorId\n });\n \n \n return `${baseUrl}?contributor_id=${contributorId}&element_type=${elementType}&content_hash=${contentHash}&${params.toString()}`;\n // return `${baseUrl}/contributor_id=${contributorId}&element_type=${elementType}&content_hash=${contentHash}?${params.toString()}`;\n}\n\nfunction generateContentHash(content: string): string {\n // Simple hash for URL generation\n return btoa(content.substring(0, 50))\n .replace(/[^a-zA-Z0-9]/g, '')\n .substring(0, 12);\n}\n\nexport function createMetaTags(\n content: string,\n elementType: ElementValue,\n contributorId: string\n): string {\n const label = getElementTypeLabel(elementType);\n \n return `\n <div itemscope itemtype=\"https://schema.org/AnalysisContent\" style=\"display:none;\">\n <meta itemprop=\"analysisType\" content=\"${elementType}\">\n <meta itemprop=\"text\" content=\"${content}\">\n <meta itemprop=\"contributor\" content=\"${contributorId}\">\n <meta itemprop=\"category\" content=\"${label}\">\n <meta itemprop=\"platform\" content=\"Skhema\">\n </div>\n `;\n}\n\nexport function createAriaAttributes(elementType: ElementValue): Record<string, string> {\n const label = getElementTypeLabel(elementType);\n \n return {\n 'role': 'article',\n 'aria-label': `${label} - Strategic insight`,\n 'aria-describedby': 'skhema-description'\n };\n}","import type { SkhemaElementAttributes, EmbedAnalytics, ContentData, SkhemaElementEventMap } from './types.js';\nimport { validateAttributes, getElementTypeLabel } from '../utils/validation.js';\nimport { generateContentHash, trackEmbedLoad, trackClick, shouldTrackAnalytics } from '../utils/analytics.js';\nimport { generateStructuredData, generateRedirectUrl, createMetaTags, createAriaAttributes } from '../utils/seo.js';\n\n// Inline styles matching Skhema UI library design system\nconst styles = `\n:host {\n /* Skhema Brand Colors - matching UI library */\n --skhema-primary: hsl(344 57% 54%); /* #cd476a */\n --skhema-primary-hover: hsl(344 50% 47%); /* #b53d5e */\n --skhema-primary-pressed: hsl(343 50% 41%); /* #9d3552 */\n --skhema-secondary: hsl(345 100% 75%); /* #ff82a2 */\n --skhema-gradient: linear-gradient(135deg, hsl(344 57% 54%) 0%, hsl(345 100% 75%) 100%);\n \n /* Light mode colors */\n --skhema-bg: hsl(0 0% 100%);\n --skhema-card: hsl(0 0% 100%);\n --skhema-border: hsl(214.3 31.8% 91.4%);\n --skhema-text: hsl(222.2 84% 4.9%);\n --skhema-text-muted: hsl(215.4 16.3% 46.9%);\n --skhema-accent: hsl(210 40% 96%);\n \n /* Shadows matching UI library */\n --skhema-shadow: 0 1px 3px 0 hsl(0 0 0 / 0.1), 0 1px 2px -1px hsl(0 0 0 / 0.1);\n --skhema-shadow-md: 0 4px 6px -1px hsl(0 0 0 / 0.1), 0 2px 4px -2px hsl(0 0 0 / 0.1);\n --skhema-shadow-lg: 0 10px 15px -3px hsl(0 0 0 / 0.1), 0 4px 6px -4px hsl(0 0 0 / 0.1);\n --skhema-radius: 0.375rem;\n \n display: block;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Inter', sans-serif;\n line-height: 1.5;\n color: var(--skhema-text);\n}\n\n:host([theme=\"dark\"]) {\n /* Dark mode colors */\n --skhema-bg: hsl(222.2 84% 4.9%);\n --skhema-card: hsl(222.2 84% 4.9%);\n --skhema-border: hsl(217.2 32.6% 17.5%);\n --skhema-text: hsl(210 40% 98%);\n --skhema-text-muted: hsl(215 20.2% 65.1%);\n --skhema-accent: hsl(217.2 32.6% 17.5%);\n}\n\n/* Main component card - inspired by your design */\n.skhema-insight-card {\n position: relative;\n background: var(--skhema-card);\n border: 1px solid var(--skhema-border);\n border-radius: calc(var(--skhema-radius) * 2);\n padding: 16px;\n box-shadow: var(--skhema-shadow);\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n max-width: 600px;\n margin: 8px 0;\n}\n\n.skhema-insight-card:hover {\n box-shadow: var(--skhema-shadow-lg);\n border-color: var(--skhema-primary);\n transform: translateY(-1px);\n}\n\n/* Header section with contributor info */\n.skhema-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 12px;\n gap: 12px;\n}\n\n.skhema-contributor {\n display: flex;\n align-items: center;\n gap: 8px;\n flex: 1;\n}\n\n.skhema-avatar {\n width: 32px;\n height: 32px;\n border-radius: 50%;\n background: var(--skhema-gradient);\n display: flex;\n align-items: center;\n justify-content: center;\n font-weight: 600;\n font-size: 14px;\n color: white;\n flex-shrink: 0;\n}\n\n.skhema-contributor-info {\n min-width: 0;\n flex: 1;\n}\n\n.skhema-contributor-name {\n font-weight: 500;\n font-size: 14px;\n color: var(--skhema-text);\n margin: 0;\n line-height: 1.2;\n}\n\n.skhema-contributor-role {\n font-size: 12px;\n color: var(--skhema-text-muted);\n margin: 0;\n line-height: 1.2;\n}\n\n/* Element type badge */\n.skhema-element-badge {\n display: inline-flex;\n align-items: center;\n padding: 4px 8px;\n background: var(--skhema-accent);\n border: 1px solid var(--skhema-border);\n border-radius: var(--skhema-radius);\n font-size: 11px;\n font-weight: 500;\n color: var(--skhema-text-muted);\n text-transform: capitalize;\n white-space: nowrap;\n flex-shrink: 0;\n}\n\n/* Content section */\n.skhema-content {\n margin: 12px 0 16px 0;\n padding: 0;\n}\n\n.skhema-content-text {\n font-size: 15px;\n line-height: 1.6;\n color: var(--skhema-text);\n margin: 0;\n font-style: italic;\n position: relative;\n}\n\n.skhema-content-text::before {\n content: '\"';\n color: var(--skhema-primary);\n font-size: 20px;\n font-weight: 600;\n margin-right: 4px;\n}\n\n.skhema-content-text::after {\n content: '\"';\n color: var(--skhema-primary);\n font-size: 20px;\n font-weight: 600;\n margin-left: 4px;\n}\n\n/* Footer section */\n.skhema-footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n padding-top: 12px;\n border-top: 1px solid var(--skhema-border);\n}\n\n.skhema-attribution {\n font-size: 11px;\n color: var(--skhema-text-muted);\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.skhema-attribution a {\n color: var(--skhema-primary);\n text-decoration: none;\n font-weight: 500;\n}\n\n.skhema-attribution a:hover {\n text-decoration: underline;\n}\n\n/* Save button with gradient and arrow */\n.skhema-save-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n background: var(--skhema-gradient);\n color: white;\n border: none;\n padding: 8px 16px;\n border-radius: var(--skhema-radius);\n font-size: 13px;\n font-weight: 500;\n text-decoration: none;\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n box-shadow: var(--skhema-shadow);\n white-space: nowrap;\n}\n\n.skhema-save-btn:hover {\n transform: translateY(-1px);\n box-shadow: var(--skhema-shadow-md);\n}\n\n.skhema-save-btn:active {\n transform: translateY(0);\n}\n\n.skhema-save-btn:focus {\n outline: 2px solid var(--skhema-primary);\n outline-offset: 2px;\n}\n\n.skhema-save-btn::after {\n content: '→';\n transition: transform 0.2s ease;\n}\n\n.skhema-save-btn:hover::after {\n transform: translateX(2px);\n}\n\n/* Error state */\n.skhema-error {\n background: hsl(0 93% 94%);\n border: 1px solid hsl(0 84% 60%);\n color: hsl(0 74% 42%);\n padding: 12px;\n border-radius: var(--skhema-radius);\n font-size: 13px;\n}\n\n.skhema-error-title {\n font-weight: 600;\n margin-bottom: 8px;\n}\n\n.skhema-error-list {\n margin: 0;\n padding-left: 16px;\n}\n\n/* Loading state */\n.skhema-loading {\n background: var(--skhema-accent);\n border: 1px solid var(--skhema-border);\n padding: 12px;\n border-radius: var(--skhema-radius);\n color: var(--skhema-text-muted);\n font-size: 13px;\n text-align: center;\n}\n\n.skhema-loading::after {\n content: '...';\n animation: loading 1.5s infinite;\n}\n\n@keyframes loading {\n 0%, 33% { content: '...'; }\n 66% { content: '..'; }\n 100% { content: '.'; }\n}\n\n/* Responsive design */\n@media (max-width: 640px) {\n .skhema-insight-card {\n margin: 4px 0;\n padding: 12px;\n }\n \n .skhema-header {\n flex-direction: column;\n align-items: flex-start;\n gap: 8px;\n }\n \n .skhema-footer {\n flex-direction: column;\n align-items: stretch;\n gap: 8px;\n }\n \n .skhema-save-btn {\n justify-content: center;\n }\n}\n\n/* Accessibility */\n@media (prefers-reduced-motion: reduce) {\n .skhema-insight-card,\n .skhema-save-btn {\n transition: none;\n }\n \n .skhema-save-btn::after {\n transition: none;\n }\n \n .skhema-save-btn:hover::after {\n transform: none;\n }\n}\n\n.skhema-structured-data {\n display: none !important;\n}\n`;\n\nexport class SkhemaElement extends HTMLElement {\n private shadow: ShadowRoot;\n private contentData: ContentData | null = null;\n private componentConnected = false;\n\n constructor() {\n super();\n this.shadow = this.attachShadow({ mode: 'closed' });\n }\n\n static get observedAttributes(): (keyof SkhemaElementAttributes)[] {\n return ['element-type', 'contributor-id', 'content', 'source-url', 'theme', 'track-analytics'];\n }\n\n connectedCallback() {\n if (this.componentConnected) return;\n this.componentConnected = true;\n \n try {\n this.render();\n this.trackLoad();\n } catch (error) {\n this.renderError('Failed to initialize component', error);\n }\n }\n\n attributeChangedCallback(_name: keyof SkhemaElementAttributes, oldValue: string | null, newValue: string | null) {\n if (oldValue !== newValue && this.componentConnected) {\n this.render();\n }\n }\n\n private render() {\n const validation = validateAttributes(this as HTMLElement);\n \n if (!validation.isValid) {\n this.renderError('Invalid component attributes', validation.errors);\n return;\n }\n\n const content = this.getContent();\n if (!content.trim()) {\n this.renderError('Component requires content', ['Add content between the opening and closing tags, or use the content attribute']);\n return;\n }\n\n this.contentData = {\n contributor_id: validation.contributorId!,\n element_type: validation.elementType!,\n content: content,\n content_hash: generateContentHash(content),\n source_url: this.getAttribute('source-url') || window.location.href,\n timestamp: new Date().toISOString(),\n page_title: document.title\n };\n\n this.renderContent();\n this.addStructuredData();\n }\n\n private getContent(): string {\n return this.getAttribute('content') || this.textContent || '';\n }\n\n private renderContent() {\n if (!this.contentData) return;\n\n const { element_type, contributor_id, content } = this.contentData;\n const label = getElementTypeLabel(element_type);\n const redirectUrl = generateRedirectUrl(content, element_type, contributor_id);\n const theme = this.getAttribute('theme') || 'auto';\n\n // Generate contributor display name and initials\n const displayName = this.formatContributorName(contributor_id);\n const initials = this.getInitials(displayName);\n\n // Set ARIA attributes on host element\n const ariaAttrs = createAriaAttributes(element_type);\n Object.entries(ariaAttrs).forEach(([key, value]) => {\n this.setAttribute(key, value);\n });\n\n this.shadow.innerHTML = `\n <style>${styles}</style>\n \n <div class=\"skhema-insight-card\" data-theme=\"${theme}\">\n <div class=\"skhema-header\">\n <div class=\"skhema-contributor\">\n <div class=\"skhema-avatar\" title=\"${displayName}\">\n ${initials}\n </div>\n <div class=\"skhema-contributor-info\">\n <div class=\"skhema-contributor-name\">${displayName}</div>\n <div class=\"skhema-contributor-role\">Strategy Insight</div>\n </div>\n </div>\n <div class=\"skhema-element-badge\" title=\"${label}\">\n ${label}\n </div>\n </div>\n \n <div class=\"skhema-content\">\n <div class=\"skhema-content-text\">${content}</div>\n </div>\n \n <div class=\"skhema-footer\">\n <div class=\"skhema-attribution\">\n Powered by <a href=\"https://skhema.com\" target=\"_blank\" rel=\"noopener noreferrer\">Skhema</a>\n </div>\n <a href=\"${redirectUrl}\" \n class=\"skhema-save-btn\" \n target=\"_blank\"\n rel=\"noopener noreferrer\"\n title=\"Save this insight to Skhema\">\n Save to Skhema\n </a>\n </div>\n </div>\n `;\n\n // Add click event listener\n const saveBtn = this.shadow.querySelector('.skhema-save-btn') as HTMLAnchorElement;\n if (saveBtn) {\n saveBtn.addEventListener('click', (event) => {\n this.handleSaveClick(event);\n });\n }\n }\n\n private formatContributorName(contributorId: string): string {\n // Convert contributor_id to display name\n return contributorId\n .split(/[_-]/)\n .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join(' ');\n }\n\n private getInitials(name: string): string {\n return name\n .split(' ')\n .map(word => word.charAt(0))\n .join('')\n .toUpperCase()\n .substring(0, 2);\n }\n\n private renderError(title: string, errors: string | string[] | any) {\n const errorList = Array.isArray(errors) ? errors : [String(errors)];\n \n this.shadow.innerHTML = `\n <style>${styles}</style>\n \n <div class=\"skhema-insight-card\">\n <div class=\"skhema-error\">\n <div class=\"skhema-error-title\">Skhema Component Error: ${title}</div>\n <ul class=\"skhema-error-list\">\n ${errorList.map(error => `<li>${error}</li>`).join('')}\n </ul>\n </div>\n </div>\n `;\n\n // Dispatch error event\n this.dispatchEvent(new CustomEvent('skhema:error', {\n detail: { error: title, details: errors },\n bubbles: true\n }));\n }\n\n private addStructuredData() {\n if (!this.contentData) return;\n\n const { content, element_type, contributor_id, source_url } = this.contentData;\n \n // Add structured data to the document head\n const structuredData = generateStructuredData(content, element_type, contributor_id, source_url);\n const script = document.createElement('script');\n script.type = 'application/ld+json';\n script.textContent = JSON.stringify(structuredData);\n script.className = 'skhema-structured-data';\n document.head.appendChild(script);\n\n // Add meta tags for SEO\n const metaDiv = document.createElement('div');\n metaDiv.innerHTML = createMetaTags(content, element_type, contributor_id);\n metaDiv.className = 'skhema-structured-data';\n document.body.appendChild(metaDiv);\n }\n\n private async trackLoad() {\n if (!shouldTrackAnalytics(this as HTMLElement) || !this.contentData) return;\n\n const analytics: EmbedAnalytics = {\n contributorId: this.contentData.contributor_id,\n elementType: this.contentData.element_type,\n contentHash: this.contentData.content_hash,\n pageUrl: window.location.href,\n pageTitle: document.title,\n timestamp: Date.now(),\n userAgent: navigator.userAgent\n };\n\n await trackEmbedLoad(analytics);\n\n // Dispatch load event\n this.dispatchEvent(new CustomEvent('skhema:load', {\n detail: analytics,\n bubbles: true\n }));\n }\n\n private async handleSaveClick(_event: Event) {\n if (!this.contentData) return;\n\n // Track click analytics\n if (shouldTrackAnalytics(this as HTMLElement)) {\n await trackClick(this.contentData);\n }\n\n // Dispatch click event\n this.dispatchEvent(new CustomEvent('skhema:click', {\n detail: this.contentData,\n bubbles: true\n }));\n }\n\n // Public API methods\n public getContentData(): ContentData | null {\n return this.contentData;\n }\n\n public refresh(): void {\n this.render();\n }\n}\n\n// Type augmentation for custom events and JSX elements\ndeclare global {\n interface HTMLElementEventMap extends SkhemaElementEventMap {}\n \n namespace JSX {\n interface IntrinsicElements {\n 'skhema-element': Partial<SkhemaElementAttributes> & {\n [key: string]: any;\n };\n }\n }\n}","import { SkhemaElement } from './components/SkhemaElement.js';\n\n// Export the component class\nexport { SkhemaElement };\n\n// Export types for TypeScript users\nexport type {\n SkhemaElementAttributes,\n EmbedAnalytics,\n ContentData,\n SkhemaElementEventMap\n} from './components/types.js';\n\n// Export utilities\nexport {\n isValidElementType,\n validateAttributes,\n getElementTypeLabel,\n getElementTypeAcronym\n} from './utils/validation.js';\n\nexport {\n generateContentHash,\n shouldTrackAnalytics\n} from './utils/analytics.js';\n\nexport {\n generateStructuredData,\n generateRedirectUrl\n} from './utils/seo.js';\n\n// Manual registration function for consuming applications\nexport function registerSkhemaElement() {\n if (typeof window !== 'undefined' && !customElements.get('skhema-element')) {\n customElements.define('skhema-element', SkhemaElement as CustomElementConstructor);\n }\n}\n\n// Auto-register in browser environments (can be tree-shaken if not needed)\nif (typeof window !== 'undefined' && !customElements.get('skhema-element')) {\n customElements.define('skhema-element', SkhemaElement as CustomElementConstructor);\n}\n\n// Default export for convenience\nexport default SkhemaElement;"],"names":["ELEMENT_TYPES","generateContentHash"],"mappings":"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CxFA,MAAM,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;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"}
1
+ {"version":3,"file":"index.cjs","sources":["../src/utils/validation.ts","../src/utils/analytics.ts","../src/utils/hash.ts","../src/utils/seo.ts","../src/components/SkhemaElement.ts","../src/index.ts"],"sourcesContent":["import { ELEMENT_TYPES } from '@skhema/types';\nimport type { ElementValue } from '@skhema/types';\n\nexport function isValidElementType(elementType: string): elementType is ElementValue {\n const validTypes = Object.values(ELEMENT_TYPES).map(type => type.value);\n return validTypes.includes(elementType as ElementValue);\n}\n\nexport function validateAttributes(element: HTMLElement): {\n isValid: boolean;\n errors: string[];\n elementType?: ElementValue;\n contributorId?: string;\n} {\n const errors: string[] = [];\n \n const elementType = element.getAttribute('element-type');\n const contributorId = element.getAttribute('contributor-id');\n \n if (!elementType) {\n errors.push('Missing required attribute: element-type');\n } else if (!isValidElementType(elementType)) {\n const validTypes = Object.values(ELEMENT_TYPES).map(t => t.value).join(', ');\n errors.push(`Invalid element-type \"${elementType}\". Valid types: ${validTypes}`);\n }\n \n if (!contributorId) {\n errors.push('Missing required attribute: contributor-id');\n } else if (contributorId.trim().length === 0) {\n errors.push('contributor-id cannot be empty');\n }\n \n return {\n isValid: errors.length === 0,\n errors,\n elementType: isValidElementType(elementType || '') ? elementType as ElementValue : undefined,\n contributorId: contributorId || undefined\n };\n}\n\nexport function getElementTypeLabel(elementType: ElementValue): string {\n const type = Object.values(ELEMENT_TYPES).find(t => t.value === elementType);\n return type?.label || elementType;\n}\n\nexport function getElementTypeAcronym(elementType: ElementValue): string {\n const type = Object.values(ELEMENT_TYPES).find(t => t.value === elementType);\n return type?.acronym || elementType.substring(0, 2).toUpperCase();\n}","import type { EmbedAnalytics, ContentData } from '../components/types.js';\n\n\nexport async function trackEmbedLoad(analytics: EmbedAnalytics): Promise<void> {\n try {\n const data = new URLSearchParams({\n contributor_id: analytics.contributorId,\n element_type: analytics.elementType,\n content_hash: analytics.contentHash,\n page_url: analytics.pageUrl,\n page_title: analytics.pageTitle || '',\n timestamp: analytics.timestamp.toString(),\n user_agent: analytics.userAgent || ''\n });\n\n // Use beacon for reliability\n if (navigator.sendBeacon) {\n navigator.sendBeacon('https://api.skhema.com/api:XGdoUqHx/component/embed', data);\n } else {\n // Fallback to fetch\n fetch('https://api.skhema.com/api:XGdoUqHx/component/embed', {\n method: 'POST',\n body: data,\n credentials: 'omit',\n keepalive: true\n }).catch(() => {\n // Fail silently - analytics shouldn't break the component\n });\n }\n } catch (error) {\n // Fail silently\n console.debug('Analytics tracking failed:', error);\n }\n}\n\nexport async function trackClick(contentData: ContentData): Promise<void> {\n try {\n const data = {\n contributor_id: contentData.contributor_id,\n element_type: contentData.element_type,\n content_hash: contentData.content_hash,\n source_url: contentData.source_url,\n timestamp: contentData.timestamp\n };\n\n if (navigator.sendBeacon) {\n const blob = new Blob([JSON.stringify(data)], {\n type: 'application/json'\n });\n navigator.sendBeacon(\n 'https://api.skhema.com/api:XGdoUqHx/component/click',\n blob\n );\n } else {\n fetch('https://api.skhema.com/api:XGdoUqHx/component/click', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(data),\n credentials: 'omit',\n keepalive: true\n }).catch(() => {\n // Fail silently\n });\n }\n } catch (error) {\n console.debug('Click tracking failed:', error);\n }\n}\n\nexport function shouldTrackAnalytics(element: HTMLElement): boolean {\n const trackAnalytics = element.getAttribute('track-analytics');\n return trackAnalytics !== 'false';\n}","export function generateContentHash(content: string): string {\n // Simple hash function for content identification\n let hash = 0;\n const cleanContent = content.trim().substring(0, 200);\n \n for (let i = 0; i < cleanContent.length; i++) {\n const char = cleanContent.charCodeAt(i);\n hash = ((hash << 5) - hash) + char;\n hash = hash & hash; // Convert to 32bit integer\n }\n \n return Math.abs(hash).toString(36).substring(0, 12);\n}","import type { ElementValue } from '@skhema/types';\nimport { getElementTypeLabel } from './validation.js';\nimport { generateContentHash } from './hash.js';\n\nexport function generateStructuredData(\n content: string,\n elementType: ElementValue,\n contributorId: string,\n sourceUrl: string\n): object {\n return {\n \"@context\": \"https://schema.org\",\n \"@type\": \"AnalysisContent\",\n \"text\": content,\n \"analysisType\": elementType,\n \"category\": getElementTypeLabel(elementType),\n \"contributor\": contributorId,\n \"url\": generateRedirectUrl(content, elementType, contributorId),\n \"provider\": {\n \"@type\": \"Organization\",\n \"name\": \"Skhema\",\n \"url\": \"https://skhema.com\"\n },\n \"isPartOf\": {\n \"@type\": \"WebPage\",\n \"url\": sourceUrl\n },\n \"dateCreated\": new Date().toISOString(),\n \"platform\": \"Skhema\"\n };\n}\n\nexport function generateRedirectUrl(\n content: string,\n elementType: ElementValue,\n contributorId: string,\n options: {\n baseUrl?: string;\n utmSource?: string;\n utmMedium?: string;\n utmCampaign?: string;\n } = {}\n): string {\n const baseUrl = options.baseUrl || 'https://app.skhema.com/save'; // This page will handle the authentication and content saving\n const contentHash = generateContentHash(content);\n const sourceUrl = encodeURIComponent(window.location.href);\n const timestamp = Date.now();\n \n const params = new URLSearchParams({\n source: sourceUrl,\n t: timestamp.toString(),\n utm_source: options.utmSource || 'web_component',\n utm_medium: options.utmMedium || 'embedded',\n utm_campaign: options.utmCampaign || elementType,\n utm_content: contributorId\n });\n \n \n return `${baseUrl}?contributor_id=${contributorId}&element_type=${elementType}&content_hash=${contentHash}&${params.toString()}`;\n // return `${baseUrl}/contributor_id=${contributorId}&element_type=${elementType}&content_hash=${contentHash}?${params.toString()}`;\n}\n\n\nexport function createMetaTags(\n content: string,\n elementType: ElementValue,\n contributorId: string\n): string {\n const label = getElementTypeLabel(elementType);\n \n return `\n <div itemscope itemtype=\"https://schema.org/AnalysisContent\" style=\"display:none;\">\n <meta itemprop=\"analysisType\" content=\"${elementType}\">\n <meta itemprop=\"text\" content=\"${content}\">\n <meta itemprop=\"contributor\" content=\"${contributorId}\">\n <meta itemprop=\"category\" content=\"${label}\">\n <meta itemprop=\"platform\" content=\"Skhema\">\n </div>\n `;\n}\n\nexport function createAriaAttributes(elementType: ElementValue): Record<string, string> {\n const label = getElementTypeLabel(elementType);\n \n return {\n 'role': 'article',\n 'aria-label': `${label} - Strategic insight`,\n 'aria-describedby': 'skhema-description'\n };\n}","import type { SkhemaElementAttributes, EmbedAnalytics, ContentData, SkhemaElementEventMap } from './types.js';\nimport { validateAttributes, getElementTypeLabel } from '../utils/validation.js';\nimport { trackEmbedLoad, trackClick, shouldTrackAnalytics } from '../utils/analytics.js';\nimport { generateContentHash } from '../utils/hash.js';\nimport { generateStructuredData, generateRedirectUrl, createMetaTags, createAriaAttributes } from '../utils/seo.js';\n\n// Inline styles matching Skhema UI library design system\nconst styles = `\n:host {\n /* Skhema Brand Colors - matching UI library */\n --skhema-primary: hsl(344 57% 54%); /* #cd476a */\n --skhema-primary-hover: hsl(344 50% 47%); /* #b53d5e */\n --skhema-primary-pressed: hsl(343 50% 41%); /* #9d3552 */\n --skhema-secondary: hsl(345 100% 75%); /* #ff82a2 */\n --skhema-gradient: linear-gradient(135deg, hsl(344 57% 54%) 0%, hsl(345 100% 75%) 100%);\n \n /* Light mode colors */\n --skhema-bg: hsl(0 0% 100%);\n --skhema-card: hsl(0 0% 100%);\n --skhema-border: hsl(214.3 31.8% 91.4%);\n --skhema-text: hsl(222.2 84% 4.9%);\n --skhema-text-muted: hsl(215.4 16.3% 46.9%);\n --skhema-accent: hsl(210 40% 96%);\n \n /* Shadows matching UI library */\n --skhema-shadow: 0 1px 3px 0 hsl(0 0 0 / 0.1), 0 1px 2px -1px hsl(0 0 0 / 0.1);\n --skhema-shadow-md: 0 4px 6px -1px hsl(0 0 0 / 0.1), 0 2px 4px -2px hsl(0 0 0 / 0.1);\n --skhema-shadow-lg: 0 10px 15px -3px hsl(0 0 0 / 0.1), 0 4px 6px -4px hsl(0 0 0 / 0.1);\n --skhema-radius: 0.375rem;\n \n display: block;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Inter', sans-serif;\n line-height: 1.5;\n color: var(--skhema-text);\n}\n\n:host([theme=\"dark\"]) {\n /* Dark mode colors */\n --skhema-bg: hsl(222.2 84% 4.9%);\n --skhema-card: hsl(222.2 84% 4.9%);\n --skhema-border: hsl(217.2 32.6% 17.5%);\n --skhema-text: hsl(210 40% 98%);\n --skhema-text-muted: hsl(215 20.2% 65.1%);\n --skhema-accent: hsl(217.2 32.6% 17.5%);\n}\n\n/* Main component card - inspired by your design */\n.skhema-insight-card {\n position: relative;\n background: var(--skhema-card);\n border: 1px solid var(--skhema-border);\n border-radius: calc(var(--skhema-radius) * 2);\n padding: 16px;\n box-shadow: var(--skhema-shadow);\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n max-width: 600px;\n margin: 8px 0;\n}\n\n.skhema-insight-card:hover {\n box-shadow: var(--skhema-shadow-lg);\n border-color: var(--skhema-primary);\n transform: translateY(-1px);\n}\n\n/* Header section with contributor info */\n.skhema-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 12px;\n gap: 12px;\n}\n\n.skhema-contributor {\n display: flex;\n align-items: center;\n gap: 8px;\n flex: 1;\n}\n\n.skhema-avatar {\n width: 32px;\n height: 32px;\n border-radius: 50%;\n background: var(--skhema-gradient);\n display: flex;\n align-items: center;\n justify-content: center;\n font-weight: 600;\n font-size: 14px;\n color: white;\n flex-shrink: 0;\n}\n\n.skhema-contributor-info {\n min-width: 0;\n flex: 1;\n}\n\n.skhema-contributor-name {\n font-weight: 500;\n font-size: 14px;\n color: var(--skhema-text);\n margin: 0;\n line-height: 1.2;\n}\n\n.skhema-contributor-role {\n font-size: 12px;\n color: var(--skhema-text-muted);\n margin: 0;\n line-height: 1.2;\n}\n\n/* Element type badge */\n.skhema-element-badge {\n display: inline-flex;\n align-items: center;\n padding: 4px 8px;\n background: var(--skhema-accent);\n border: 1px solid var(--skhema-border);\n border-radius: var(--skhema-radius);\n font-size: 11px;\n font-weight: 500;\n color: var(--skhema-text-muted);\n text-transform: capitalize;\n white-space: nowrap;\n flex-shrink: 0;\n}\n\n/* Content section */\n.skhema-content {\n margin: 12px 0 16px 0;\n padding: 0;\n}\n\n.skhema-content-text {\n font-size: 15px;\n line-height: 1.6;\n color: var(--skhema-text);\n margin: 0;\n font-style: italic;\n position: relative;\n}\n\n.skhema-content-text::before {\n content: '\"';\n color: var(--skhema-primary);\n font-size: 20px;\n font-weight: 600;\n margin-right: 4px;\n}\n\n.skhema-content-text::after {\n content: '\"';\n color: var(--skhema-primary);\n font-size: 20px;\n font-weight: 600;\n margin-left: 4px;\n}\n\n/* Footer section */\n.skhema-footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n padding-top: 12px;\n border-top: 1px solid var(--skhema-border);\n}\n\n.skhema-attribution {\n font-size: 11px;\n color: var(--skhema-text-muted);\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.skhema-attribution a {\n color: var(--skhema-primary);\n text-decoration: none;\n font-weight: 500;\n}\n\n.skhema-attribution a:hover {\n text-decoration: underline;\n}\n\n/* Save button with gradient and arrow */\n.skhema-save-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n background: var(--skhema-gradient);\n color: white;\n border: none;\n padding: 8px 16px;\n border-radius: var(--skhema-radius);\n font-size: 13px;\n font-weight: 500;\n text-decoration: none;\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n box-shadow: var(--skhema-shadow);\n white-space: nowrap;\n}\n\n.skhema-save-btn:hover {\n transform: translateY(-1px);\n box-shadow: var(--skhema-shadow-md);\n}\n\n.skhema-save-btn:active {\n transform: translateY(0);\n}\n\n.skhema-save-btn:focus {\n outline: 2px solid var(--skhema-primary);\n outline-offset: 2px;\n}\n\n.skhema-save-btn::after {\n content: '→';\n transition: transform 0.2s ease;\n}\n\n.skhema-save-btn:hover::after {\n transform: translateX(2px);\n}\n\n/* Error state */\n.skhema-error {\n background: hsl(0 93% 94%);\n border: 1px solid hsl(0 84% 60%);\n color: hsl(0 74% 42%);\n padding: 12px;\n border-radius: var(--skhema-radius);\n font-size: 13px;\n}\n\n.skhema-error-title {\n font-weight: 600;\n margin-bottom: 8px;\n}\n\n.skhema-error-list {\n margin: 0;\n padding-left: 16px;\n}\n\n/* Loading state */\n.skhema-loading {\n background: var(--skhema-accent);\n border: 1px solid var(--skhema-border);\n padding: 12px;\n border-radius: var(--skhema-radius);\n color: var(--skhema-text-muted);\n font-size: 13px;\n text-align: center;\n}\n\n.skhema-loading::after {\n content: '...';\n animation: loading 1.5s infinite;\n}\n\n@keyframes loading {\n 0%, 33% { content: '...'; }\n 66% { content: '..'; }\n 100% { content: '.'; }\n}\n\n/* Responsive design */\n@media (max-width: 640px) {\n .skhema-insight-card {\n margin: 4px 0;\n padding: 12px;\n }\n \n .skhema-header {\n flex-direction: column;\n align-items: flex-start;\n gap: 8px;\n }\n \n .skhema-footer {\n flex-direction: column;\n align-items: stretch;\n gap: 8px;\n }\n \n .skhema-save-btn {\n justify-content: center;\n }\n}\n\n/* Accessibility */\n@media (prefers-reduced-motion: reduce) {\n .skhema-insight-card,\n .skhema-save-btn {\n transition: none;\n }\n \n .skhema-save-btn::after {\n transition: none;\n }\n \n .skhema-save-btn:hover::after {\n transform: none;\n }\n}\n\n.skhema-structured-data {\n display: none !important;\n}\n`;\n\nexport class SkhemaElement extends HTMLElement {\n private shadow: ShadowRoot;\n private contentData: ContentData | null = null;\n private componentConnected = false;\n\n constructor() {\n super();\n this.shadow = this.attachShadow({ mode: 'closed' });\n }\n\n static get observedAttributes(): (keyof SkhemaElementAttributes)[] {\n return ['element-type', 'contributor-id', 'content', 'source-url', 'theme', 'track-analytics'];\n }\n\n connectedCallback() {\n if (this.componentConnected) return;\n this.componentConnected = true;\n \n try {\n this.render();\n this.trackLoad();\n } catch (error) {\n this.renderError('Failed to initialize component', error);\n }\n }\n\n attributeChangedCallback(_name: keyof SkhemaElementAttributes, oldValue: string | null, newValue: string | null) {\n if (oldValue !== newValue && this.componentConnected) {\n this.render();\n }\n }\n\n private render() {\n const validation = validateAttributes(this as HTMLElement);\n \n if (!validation.isValid) {\n this.renderError('Invalid component attributes', validation.errors);\n return;\n }\n\n const content = this.getContent();\n if (!content.trim()) {\n this.renderError('Component requires content', ['Add content between the opening and closing tags, or use the content attribute']);\n return;\n }\n\n this.contentData = {\n contributor_id: validation.contributorId!,\n element_type: validation.elementType!,\n content: content,\n content_hash: generateContentHash(content),\n source_url: this.getAttribute('source-url') || window.location.href,\n timestamp: new Date().toISOString(),\n page_title: document.title\n };\n\n this.renderContent();\n this.addStructuredData();\n }\n\n private getContent(): string {\n return this.getAttribute('content') || this.textContent || '';\n }\n\n private renderContent() {\n if (!this.contentData) return;\n\n const { element_type, contributor_id, content } = this.contentData;\n const label = getElementTypeLabel(element_type);\n const redirectUrl = generateRedirectUrl(content, element_type, contributor_id);\n const theme = this.getAttribute('theme') || 'auto';\n\n // Generate contributor display name and initials\n const displayName = this.formatContributorName(contributor_id);\n const initials = this.getInitials(displayName);\n\n // Set ARIA attributes on host element\n const ariaAttrs = createAriaAttributes(element_type);\n Object.entries(ariaAttrs).forEach(([key, value]) => {\n this.setAttribute(key, value);\n });\n\n this.shadow.innerHTML = `\n <style>${styles}</style>\n \n <div class=\"skhema-insight-card\" data-theme=\"${theme}\">\n <div class=\"skhema-header\">\n <div class=\"skhema-contributor\">\n <div class=\"skhema-avatar\" title=\"${displayName}\">\n ${initials}\n </div>\n <div class=\"skhema-contributor-info\">\n <div class=\"skhema-contributor-name\">${displayName}</div>\n <div class=\"skhema-contributor-role\">Strategy Insight</div>\n </div>\n </div>\n <div class=\"skhema-element-badge\" title=\"${label}\">\n ${label}\n </div>\n </div>\n \n <div class=\"skhema-content\">\n <div class=\"skhema-content-text\">${content}</div>\n </div>\n \n <div class=\"skhema-footer\">\n <div class=\"skhema-attribution\">\n Powered by <a href=\"https://skhema.com\" target=\"_blank\" rel=\"noopener noreferrer\">Skhema</a>\n </div>\n <a href=\"${redirectUrl}\" \n class=\"skhema-save-btn\" \n target=\"_blank\"\n rel=\"noopener noreferrer\"\n title=\"Save this insight to Skhema\">\n Save to Skhema\n </a>\n </div>\n </div>\n `;\n\n // Add click event listener\n const saveBtn = this.shadow.querySelector('.skhema-save-btn') as HTMLAnchorElement;\n if (saveBtn) {\n saveBtn.addEventListener('click', (event) => {\n this.handleSaveClick(event);\n });\n }\n }\n\n private formatContributorName(contributorId: string): string {\n // Convert contributor_id to display name\n return contributorId\n .split(/[_-]/)\n .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join(' ');\n }\n\n private getInitials(name: string): string {\n return name\n .split(' ')\n .map(word => word.charAt(0))\n .join('')\n .toUpperCase()\n .substring(0, 2);\n }\n\n private renderError(title: string, errors: string | string[] | any) {\n const errorList = Array.isArray(errors) ? errors : [String(errors)];\n \n this.shadow.innerHTML = `\n <style>${styles}</style>\n \n <div class=\"skhema-insight-card\">\n <div class=\"skhema-error\">\n <div class=\"skhema-error-title\">Skhema Component Error: ${title}</div>\n <ul class=\"skhema-error-list\">\n ${errorList.map(error => `<li>${error}</li>`).join('')}\n </ul>\n </div>\n </div>\n `;\n\n // Dispatch error event\n this.dispatchEvent(new CustomEvent('skhema:error', {\n detail: { error: title, details: errors },\n bubbles: true\n }));\n }\n\n private addStructuredData() {\n if (!this.contentData) return;\n\n const { content, element_type, contributor_id, source_url } = this.contentData;\n \n // Add structured data to the document head\n const structuredData = generateStructuredData(content, element_type, contributor_id, source_url);\n const script = document.createElement('script');\n script.type = 'application/ld+json';\n script.textContent = JSON.stringify(structuredData);\n script.className = 'skhema-structured-data';\n document.head.appendChild(script);\n\n // Add meta tags for SEO\n const metaDiv = document.createElement('div');\n metaDiv.innerHTML = createMetaTags(content, element_type, contributor_id);\n metaDiv.className = 'skhema-structured-data';\n document.body.appendChild(metaDiv);\n }\n\n private async trackLoad() {\n if (!shouldTrackAnalytics(this as HTMLElement) || !this.contentData) return;\n\n const analytics: EmbedAnalytics = {\n contributorId: this.contentData.contributor_id,\n elementType: this.contentData.element_type,\n contentHash: this.contentData.content_hash,\n pageUrl: window.location.href,\n pageTitle: document.title,\n timestamp: Date.now(),\n userAgent: navigator.userAgent\n };\n\n await trackEmbedLoad(analytics);\n\n // Dispatch load event\n this.dispatchEvent(new CustomEvent('skhema:load', {\n detail: analytics,\n bubbles: true\n }));\n }\n\n private async handleSaveClick(_event: Event) {\n if (!this.contentData) return;\n\n // Track click analytics\n if (shouldTrackAnalytics(this as HTMLElement)) {\n await trackClick(this.contentData);\n }\n\n // Dispatch click event\n this.dispatchEvent(new CustomEvent('skhema:click', {\n detail: this.contentData,\n bubbles: true\n }));\n }\n\n // Public API methods\n public getContentData(): ContentData | null {\n return this.contentData;\n }\n\n public refresh(): void {\n this.render();\n }\n}\n\n// Type augmentation for custom events and JSX elements\ndeclare global {\n interface HTMLElementEventMap extends SkhemaElementEventMap {}\n \n namespace JSX {\n interface IntrinsicElements {\n 'skhema-element': Partial<SkhemaElementAttributes> & {\n [key: string]: any;\n };\n }\n }\n}","import { SkhemaElement } from './components/SkhemaElement.js';\n\n// Export the component class\nexport { SkhemaElement };\n\n// Export types for TypeScript users\nexport type {\n SkhemaElementAttributes,\n EmbedAnalytics,\n ContentData,\n SkhemaElementEventMap\n} from './components/types.js';\n\n// Export utilities\nexport {\n isValidElementType,\n validateAttributes,\n getElementTypeLabel,\n getElementTypeAcronym\n} from './utils/validation.js';\n\nexport {\n // Removed generateContentHash\n shouldTrackAnalytics\n} from './utils/analytics.js';\n\nexport {\n generateStructuredData,\n generateRedirectUrl\n} from './utils/seo.js';\n\n// Manual registration function for consuming applications\nexport function registerSkhemaElement() {\n if (typeof window !== 'undefined' && !customElements.get('skhema-element')) {\n customElements.define('skhema-element', SkhemaElement as CustomElementConstructor);\n }\n}\n\n// Auto-register in browser environments (can be tree-shaken if not needed)\nif (typeof window !== 'undefined' && !customElements.get('skhema-element')) {\n customElements.define('skhema-element', SkhemaElement as CustomElementConstructor);\n}\n\n// Default export for convenience\nexport default SkhemaElement;"],"names":["ELEMENT_TYPES"],"mappings":"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AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;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"}
package/dist/index.d.ts CHANGED
@@ -3,7 +3,7 @@ import { SkhemaElement } from './components/SkhemaElement.js';
3
3
  export { SkhemaElement };
4
4
  export type { SkhemaElementAttributes, EmbedAnalytics, ContentData, SkhemaElementEventMap } from './components/types.js';
5
5
  export { isValidElementType, validateAttributes, getElementTypeLabel, getElementTypeAcronym } from './utils/validation.js';
6
- export { generateContentHash, shouldTrackAnalytics } from './utils/analytics.js';
6
+ export { shouldTrackAnalytics } from './utils/analytics.js';
7
7
  export { generateStructuredData, generateRedirectUrl } from './utils/seo.js';
8
8
  export declare function registerSkhemaElement(): void;
9
9
  export default SkhemaElement;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAG9D,OAAO,EAAE,aAAa,EAAE,CAAC;AAGzB,YAAY,EACV,uBAAuB,EACvB,cAAc,EACd,WAAW,EACX,qBAAqB,EACtB,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EACL,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,EACnB,qBAAqB,EACtB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACrB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACL,sBAAsB,EACtB,mBAAmB,EACpB,MAAM,gBAAgB,CAAC;AAGxB,wBAAgB,qBAAqB,SAIpC;AAQD,eAAe,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAG9D,OAAO,EAAE,aAAa,EAAE,CAAC;AAGzB,YAAY,EACV,uBAAuB,EACvB,cAAc,EACd,WAAW,EACX,qBAAqB,EACtB,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EACL,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,EACnB,qBAAqB,EACtB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAEL,oBAAoB,EACrB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACL,sBAAsB,EACtB,mBAAmB,EACpB,MAAM,gBAAgB,CAAC;AAGxB,wBAAgB,qBAAqB,SAIpC;AAQD,eAAe,aAAa,CAAC"}
package/dist/index.es.js CHANGED
@@ -33,16 +33,6 @@ function getElementTypeAcronym(elementType) {
33
33
  const type = Object.values(ELEMENT_TYPES).find((t) => t.value === elementType);
34
34
  return (type == null ? void 0 : type.acronym) || elementType.substring(0, 2).toUpperCase();
35
35
  }
36
- function generateContentHash$1(content) {
37
- let hash = 0;
38
- const cleanContent = content.trim().substring(0, 200);
39
- for (let i = 0; i < cleanContent.length; i++) {
40
- const char = cleanContent.charCodeAt(i);
41
- hash = (hash << 5) - hash + char;
42
- hash = hash & hash;
43
- }
44
- return Math.abs(hash).toString(36).substring(0, 12);
45
- }
46
36
  async function trackEmbedLoad(analytics) {
47
37
  try {
48
38
  const data = new URLSearchParams({
@@ -60,6 +50,7 @@ async function trackEmbedLoad(analytics) {
60
50
  fetch("https://api.skhema.com/api:XGdoUqHx/component/embed", {
61
51
  method: "POST",
62
52
  body: data,
53
+ credentials: "omit",
63
54
  keepalive: true
64
55
  }).catch(() => {
65
56
  });
@@ -90,6 +81,7 @@ async function trackClick(contentData) {
90
81
  method: "POST",
91
82
  headers: { "Content-Type": "application/json" },
92
83
  body: JSON.stringify(data),
84
+ credentials: "omit",
93
85
  keepalive: true
94
86
  }).catch(() => {
95
87
  });
@@ -102,6 +94,16 @@ function shouldTrackAnalytics(element) {
102
94
  const trackAnalytics = element.getAttribute("track-analytics");
103
95
  return trackAnalytics !== "false";
104
96
  }
97
+ function generateContentHash(content) {
98
+ let hash = 0;
99
+ const cleanContent = content.trim().substring(0, 200);
100
+ for (let i = 0; i < cleanContent.length; i++) {
101
+ const char = cleanContent.charCodeAt(i);
102
+ hash = (hash << 5) - hash + char;
103
+ hash = hash & hash;
104
+ }
105
+ return Math.abs(hash).toString(36).substring(0, 12);
106
+ }
105
107
  function generateStructuredData(content, elementType, contributorId, sourceUrl) {
106
108
  return {
107
109
  "@context": "https://schema.org",
@@ -125,7 +127,7 @@ function generateStructuredData(content, elementType, contributorId, sourceUrl)
125
127
  };
126
128
  }
127
129
  function generateRedirectUrl(content, elementType, contributorId, options = {}) {
128
- const baseUrl = options.baseUrl || "https://api.skhema.com/api:XGdoUqHx/component/redirect";
130
+ const baseUrl = options.baseUrl || "https://app.skhema.com/save";
129
131
  const contentHash = generateContentHash(content);
130
132
  const sourceUrl = encodeURIComponent(window.location.href);
131
133
  const timestamp = Date.now();
@@ -139,9 +141,6 @@ function generateRedirectUrl(content, elementType, contributorId, options = {})
139
141
  });
140
142
  return `${baseUrl}?contributor_id=${contributorId}&element_type=${elementType}&content_hash=${contentHash}&${params.toString()}`;
141
143
  }
142
- function generateContentHash(content) {
143
- return btoa(content.substring(0, 50)).replace(/[^a-zA-Z0-9]/g, "").substring(0, 12);
144
- }
145
144
  function createMetaTags(content, elementType, contributorId) {
146
145
  const label = getElementTypeLabel(elementType);
147
146
  return `
@@ -513,7 +512,7 @@ class SkhemaElement extends HTMLElement {
513
512
  contributor_id: validation.contributorId,
514
513
  element_type: validation.elementType,
515
514
  content,
516
- content_hash: generateContentHash$1(content),
515
+ content_hash: generateContentHash(content),
517
516
  source_url: this.getAttribute("source-url") || window.location.href,
518
517
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
519
518
  page_title: document.title
@@ -665,7 +664,6 @@ if (typeof window !== "undefined" && !customElements.get("skhema-element")) {
665
664
  export {
666
665
  SkhemaElement,
667
666
  SkhemaElement as default,
668
- generateContentHash$1 as generateContentHash,
669
667
  generateRedirectUrl,
670
668
  generateStructuredData,
671
669
  getElementTypeAcronym,
@@ -1 +1 @@
1
- {"version":3,"file":"index.es.js","sources":["../src/utils/validation.ts","../src/utils/analytics.ts","../src/utils/seo.ts","../src/components/SkhemaElement.ts","../src/index.ts"],"sourcesContent":["import { ELEMENT_TYPES } from '@skhema/types';\nimport type { ElementValue } from '@skhema/types';\n\nexport function isValidElementType(elementType: string): elementType is ElementValue {\n const validTypes = Object.values(ELEMENT_TYPES).map(type => type.value);\n return validTypes.includes(elementType as ElementValue);\n}\n\nexport function validateAttributes(element: HTMLElement): {\n isValid: boolean;\n errors: string[];\n elementType?: ElementValue;\n contributorId?: string;\n} {\n const errors: string[] = [];\n \n const elementType = element.getAttribute('element-type');\n const contributorId = element.getAttribute('contributor-id');\n \n if (!elementType) {\n errors.push('Missing required attribute: element-type');\n } else if (!isValidElementType(elementType)) {\n const validTypes = Object.values(ELEMENT_TYPES).map(t => t.value).join(', ');\n errors.push(`Invalid element-type \"${elementType}\". Valid types: ${validTypes}`);\n }\n \n if (!contributorId) {\n errors.push('Missing required attribute: contributor-id');\n } else if (contributorId.trim().length === 0) {\n errors.push('contributor-id cannot be empty');\n }\n \n return {\n isValid: errors.length === 0,\n errors,\n elementType: isValidElementType(elementType || '') ? elementType as ElementValue : undefined,\n contributorId: contributorId || undefined\n };\n}\n\nexport function getElementTypeLabel(elementType: ElementValue): string {\n const type = Object.values(ELEMENT_TYPES).find(t => t.value === elementType);\n return type?.label || elementType;\n}\n\nexport function getElementTypeAcronym(elementType: ElementValue): string {\n const type = Object.values(ELEMENT_TYPES).find(t => t.value === elementType);\n return type?.acronym || elementType.substring(0, 2).toUpperCase();\n}","import type { EmbedAnalytics, ContentData } from '../components/types.js';\n\nexport function generateContentHash(content: string): string {\n // Simple hash function for content identification\n let hash = 0;\n const cleanContent = content.trim().substring(0, 200);\n \n for (let i = 0; i < cleanContent.length; i++) {\n const char = cleanContent.charCodeAt(i);\n hash = ((hash << 5) - hash) + char;\n hash = hash & hash; // Convert to 32bit integer\n }\n \n return Math.abs(hash).toString(36).substring(0, 12);\n}\n\nexport async function trackEmbedLoad(analytics: EmbedAnalytics): Promise<void> {\n try {\n const data = new URLSearchParams({\n contributor_id: analytics.contributorId,\n element_type: analytics.elementType,\n content_hash: analytics.contentHash,\n page_url: analytics.pageUrl,\n page_title: analytics.pageTitle || '',\n timestamp: analytics.timestamp.toString(),\n user_agent: analytics.userAgent || ''\n });\n\n // Use beacon for reliability\n if (navigator.sendBeacon) {\n navigator.sendBeacon('https://api.skhema.com/api:XGdoUqHx/component/embed', data);\n } else {\n // Fallback to fetch\n fetch('https://api.skhema.com/api:XGdoUqHx/component/embed', {\n method: 'POST',\n body: data,\n keepalive: true\n }).catch(() => {\n // Fail silently - analytics shouldn't break the component\n });\n }\n } catch (error) {\n // Fail silently\n console.debug('Analytics tracking failed:', error);\n }\n}\n\nexport async function trackClick(contentData: ContentData): Promise<void> {\n try {\n const data = {\n contributor_id: contentData.contributor_id,\n element_type: contentData.element_type,\n content_hash: contentData.content_hash,\n source_url: contentData.source_url,\n timestamp: contentData.timestamp\n };\n\n if (navigator.sendBeacon) {\n const blob = new Blob([JSON.stringify(data)], {\n type: 'application/json'\n });\n navigator.sendBeacon(\n 'https://api.skhema.com/api:XGdoUqHx/component/click',\n blob\n );\n } else {\n fetch('https://api.skhema.com/api:XGdoUqHx/component/click', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(data),\n keepalive: true\n }).catch(() => {\n // Fail silently\n });\n }\n } catch (error) {\n console.debug('Click tracking failed:', error);\n }\n}\n\nexport function shouldTrackAnalytics(element: HTMLElement): boolean {\n const trackAnalytics = element.getAttribute('track-analytics');\n return trackAnalytics !== 'false';\n}","import type { ElementValue } from '@skhema/types';\nimport { getElementTypeLabel } from './validation.js';\n\nexport function generateStructuredData(\n content: string,\n elementType: ElementValue,\n contributorId: string,\n sourceUrl: string\n): object {\n return {\n \"@context\": \"https://schema.org\",\n \"@type\": \"AnalysisContent\",\n \"text\": content,\n \"analysisType\": elementType,\n \"category\": getElementTypeLabel(elementType),\n \"contributor\": contributorId,\n \"url\": generateRedirectUrl(content, elementType, contributorId),\n \"provider\": {\n \"@type\": \"Organization\",\n \"name\": \"Skhema\",\n \"url\": \"https://skhema.com\"\n },\n \"isPartOf\": {\n \"@type\": \"WebPage\",\n \"url\": sourceUrl\n },\n \"dateCreated\": new Date().toISOString(),\n \"platform\": \"Skhema\"\n };\n}\n\nexport function generateRedirectUrl(\n content: string,\n elementType: ElementValue,\n contributorId: string,\n options: {\n baseUrl?: string;\n utmSource?: string;\n utmMedium?: string;\n utmCampaign?: string;\n } = {}\n): string {\n const baseUrl = options.baseUrl || 'https://api.skhema.com/api:XGdoUqHx/component/redirect'; // @TODO: change to actual redirect URL\n const contentHash = generateContentHash(content);\n const sourceUrl = encodeURIComponent(window.location.href);\n const timestamp = Date.now();\n \n const params = new URLSearchParams({\n source: sourceUrl,\n t: timestamp.toString(),\n utm_source: options.utmSource || 'web_component',\n utm_medium: options.utmMedium || 'embedded',\n utm_campaign: options.utmCampaign || elementType,\n utm_content: contributorId\n });\n \n \n return `${baseUrl}?contributor_id=${contributorId}&element_type=${elementType}&content_hash=${contentHash}&${params.toString()}`;\n // return `${baseUrl}/contributor_id=${contributorId}&element_type=${elementType}&content_hash=${contentHash}?${params.toString()}`;\n}\n\nfunction generateContentHash(content: string): string {\n // Simple hash for URL generation\n return btoa(content.substring(0, 50))\n .replace(/[^a-zA-Z0-9]/g, '')\n .substring(0, 12);\n}\n\nexport function createMetaTags(\n content: string,\n elementType: ElementValue,\n contributorId: string\n): string {\n const label = getElementTypeLabel(elementType);\n \n return `\n <div itemscope itemtype=\"https://schema.org/AnalysisContent\" style=\"display:none;\">\n <meta itemprop=\"analysisType\" content=\"${elementType}\">\n <meta itemprop=\"text\" content=\"${content}\">\n <meta itemprop=\"contributor\" content=\"${contributorId}\">\n <meta itemprop=\"category\" content=\"${label}\">\n <meta itemprop=\"platform\" content=\"Skhema\">\n </div>\n `;\n}\n\nexport function createAriaAttributes(elementType: ElementValue): Record<string, string> {\n const label = getElementTypeLabel(elementType);\n \n return {\n 'role': 'article',\n 'aria-label': `${label} - Strategic insight`,\n 'aria-describedby': 'skhema-description'\n };\n}","import type { SkhemaElementAttributes, EmbedAnalytics, ContentData, SkhemaElementEventMap } from './types.js';\nimport { validateAttributes, getElementTypeLabel } from '../utils/validation.js';\nimport { generateContentHash, trackEmbedLoad, trackClick, shouldTrackAnalytics } from '../utils/analytics.js';\nimport { generateStructuredData, generateRedirectUrl, createMetaTags, createAriaAttributes } from '../utils/seo.js';\n\n// Inline styles matching Skhema UI library design system\nconst styles = `\n:host {\n /* Skhema Brand Colors - matching UI library */\n --skhema-primary: hsl(344 57% 54%); /* #cd476a */\n --skhema-primary-hover: hsl(344 50% 47%); /* #b53d5e */\n --skhema-primary-pressed: hsl(343 50% 41%); /* #9d3552 */\n --skhema-secondary: hsl(345 100% 75%); /* #ff82a2 */\n --skhema-gradient: linear-gradient(135deg, hsl(344 57% 54%) 0%, hsl(345 100% 75%) 100%);\n \n /* Light mode colors */\n --skhema-bg: hsl(0 0% 100%);\n --skhema-card: hsl(0 0% 100%);\n --skhema-border: hsl(214.3 31.8% 91.4%);\n --skhema-text: hsl(222.2 84% 4.9%);\n --skhema-text-muted: hsl(215.4 16.3% 46.9%);\n --skhema-accent: hsl(210 40% 96%);\n \n /* Shadows matching UI library */\n --skhema-shadow: 0 1px 3px 0 hsl(0 0 0 / 0.1), 0 1px 2px -1px hsl(0 0 0 / 0.1);\n --skhema-shadow-md: 0 4px 6px -1px hsl(0 0 0 / 0.1), 0 2px 4px -2px hsl(0 0 0 / 0.1);\n --skhema-shadow-lg: 0 10px 15px -3px hsl(0 0 0 / 0.1), 0 4px 6px -4px hsl(0 0 0 / 0.1);\n --skhema-radius: 0.375rem;\n \n display: block;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Inter', sans-serif;\n line-height: 1.5;\n color: var(--skhema-text);\n}\n\n:host([theme=\"dark\"]) {\n /* Dark mode colors */\n --skhema-bg: hsl(222.2 84% 4.9%);\n --skhema-card: hsl(222.2 84% 4.9%);\n --skhema-border: hsl(217.2 32.6% 17.5%);\n --skhema-text: hsl(210 40% 98%);\n --skhema-text-muted: hsl(215 20.2% 65.1%);\n --skhema-accent: hsl(217.2 32.6% 17.5%);\n}\n\n/* Main component card - inspired by your design */\n.skhema-insight-card {\n position: relative;\n background: var(--skhema-card);\n border: 1px solid var(--skhema-border);\n border-radius: calc(var(--skhema-radius) * 2);\n padding: 16px;\n box-shadow: var(--skhema-shadow);\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n max-width: 600px;\n margin: 8px 0;\n}\n\n.skhema-insight-card:hover {\n box-shadow: var(--skhema-shadow-lg);\n border-color: var(--skhema-primary);\n transform: translateY(-1px);\n}\n\n/* Header section with contributor info */\n.skhema-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 12px;\n gap: 12px;\n}\n\n.skhema-contributor {\n display: flex;\n align-items: center;\n gap: 8px;\n flex: 1;\n}\n\n.skhema-avatar {\n width: 32px;\n height: 32px;\n border-radius: 50%;\n background: var(--skhema-gradient);\n display: flex;\n align-items: center;\n justify-content: center;\n font-weight: 600;\n font-size: 14px;\n color: white;\n flex-shrink: 0;\n}\n\n.skhema-contributor-info {\n min-width: 0;\n flex: 1;\n}\n\n.skhema-contributor-name {\n font-weight: 500;\n font-size: 14px;\n color: var(--skhema-text);\n margin: 0;\n line-height: 1.2;\n}\n\n.skhema-contributor-role {\n font-size: 12px;\n color: var(--skhema-text-muted);\n margin: 0;\n line-height: 1.2;\n}\n\n/* Element type badge */\n.skhema-element-badge {\n display: inline-flex;\n align-items: center;\n padding: 4px 8px;\n background: var(--skhema-accent);\n border: 1px solid var(--skhema-border);\n border-radius: var(--skhema-radius);\n font-size: 11px;\n font-weight: 500;\n color: var(--skhema-text-muted);\n text-transform: capitalize;\n white-space: nowrap;\n flex-shrink: 0;\n}\n\n/* Content section */\n.skhema-content {\n margin: 12px 0 16px 0;\n padding: 0;\n}\n\n.skhema-content-text {\n font-size: 15px;\n line-height: 1.6;\n color: var(--skhema-text);\n margin: 0;\n font-style: italic;\n position: relative;\n}\n\n.skhema-content-text::before {\n content: '\"';\n color: var(--skhema-primary);\n font-size: 20px;\n font-weight: 600;\n margin-right: 4px;\n}\n\n.skhema-content-text::after {\n content: '\"';\n color: var(--skhema-primary);\n font-size: 20px;\n font-weight: 600;\n margin-left: 4px;\n}\n\n/* Footer section */\n.skhema-footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n padding-top: 12px;\n border-top: 1px solid var(--skhema-border);\n}\n\n.skhema-attribution {\n font-size: 11px;\n color: var(--skhema-text-muted);\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.skhema-attribution a {\n color: var(--skhema-primary);\n text-decoration: none;\n font-weight: 500;\n}\n\n.skhema-attribution a:hover {\n text-decoration: underline;\n}\n\n/* Save button with gradient and arrow */\n.skhema-save-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n background: var(--skhema-gradient);\n color: white;\n border: none;\n padding: 8px 16px;\n border-radius: var(--skhema-radius);\n font-size: 13px;\n font-weight: 500;\n text-decoration: none;\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n box-shadow: var(--skhema-shadow);\n white-space: nowrap;\n}\n\n.skhema-save-btn:hover {\n transform: translateY(-1px);\n box-shadow: var(--skhema-shadow-md);\n}\n\n.skhema-save-btn:active {\n transform: translateY(0);\n}\n\n.skhema-save-btn:focus {\n outline: 2px solid var(--skhema-primary);\n outline-offset: 2px;\n}\n\n.skhema-save-btn::after {\n content: '→';\n transition: transform 0.2s ease;\n}\n\n.skhema-save-btn:hover::after {\n transform: translateX(2px);\n}\n\n/* Error state */\n.skhema-error {\n background: hsl(0 93% 94%);\n border: 1px solid hsl(0 84% 60%);\n color: hsl(0 74% 42%);\n padding: 12px;\n border-radius: var(--skhema-radius);\n font-size: 13px;\n}\n\n.skhema-error-title {\n font-weight: 600;\n margin-bottom: 8px;\n}\n\n.skhema-error-list {\n margin: 0;\n padding-left: 16px;\n}\n\n/* Loading state */\n.skhema-loading {\n background: var(--skhema-accent);\n border: 1px solid var(--skhema-border);\n padding: 12px;\n border-radius: var(--skhema-radius);\n color: var(--skhema-text-muted);\n font-size: 13px;\n text-align: center;\n}\n\n.skhema-loading::after {\n content: '...';\n animation: loading 1.5s infinite;\n}\n\n@keyframes loading {\n 0%, 33% { content: '...'; }\n 66% { content: '..'; }\n 100% { content: '.'; }\n}\n\n/* Responsive design */\n@media (max-width: 640px) {\n .skhema-insight-card {\n margin: 4px 0;\n padding: 12px;\n }\n \n .skhema-header {\n flex-direction: column;\n align-items: flex-start;\n gap: 8px;\n }\n \n .skhema-footer {\n flex-direction: column;\n align-items: stretch;\n gap: 8px;\n }\n \n .skhema-save-btn {\n justify-content: center;\n }\n}\n\n/* Accessibility */\n@media (prefers-reduced-motion: reduce) {\n .skhema-insight-card,\n .skhema-save-btn {\n transition: none;\n }\n \n .skhema-save-btn::after {\n transition: none;\n }\n \n .skhema-save-btn:hover::after {\n transform: none;\n }\n}\n\n.skhema-structured-data {\n display: none !important;\n}\n`;\n\nexport class SkhemaElement extends HTMLElement {\n private shadow: ShadowRoot;\n private contentData: ContentData | null = null;\n private componentConnected = false;\n\n constructor() {\n super();\n this.shadow = this.attachShadow({ mode: 'closed' });\n }\n\n static get observedAttributes(): (keyof SkhemaElementAttributes)[] {\n return ['element-type', 'contributor-id', 'content', 'source-url', 'theme', 'track-analytics'];\n }\n\n connectedCallback() {\n if (this.componentConnected) return;\n this.componentConnected = true;\n \n try {\n this.render();\n this.trackLoad();\n } catch (error) {\n this.renderError('Failed to initialize component', error);\n }\n }\n\n attributeChangedCallback(_name: keyof SkhemaElementAttributes, oldValue: string | null, newValue: string | null) {\n if (oldValue !== newValue && this.componentConnected) {\n this.render();\n }\n }\n\n private render() {\n const validation = validateAttributes(this as HTMLElement);\n \n if (!validation.isValid) {\n this.renderError('Invalid component attributes', validation.errors);\n return;\n }\n\n const content = this.getContent();\n if (!content.trim()) {\n this.renderError('Component requires content', ['Add content between the opening and closing tags, or use the content attribute']);\n return;\n }\n\n this.contentData = {\n contributor_id: validation.contributorId!,\n element_type: validation.elementType!,\n content: content,\n content_hash: generateContentHash(content),\n source_url: this.getAttribute('source-url') || window.location.href,\n timestamp: new Date().toISOString(),\n page_title: document.title\n };\n\n this.renderContent();\n this.addStructuredData();\n }\n\n private getContent(): string {\n return this.getAttribute('content') || this.textContent || '';\n }\n\n private renderContent() {\n if (!this.contentData) return;\n\n const { element_type, contributor_id, content } = this.contentData;\n const label = getElementTypeLabel(element_type);\n const redirectUrl = generateRedirectUrl(content, element_type, contributor_id);\n const theme = this.getAttribute('theme') || 'auto';\n\n // Generate contributor display name and initials\n const displayName = this.formatContributorName(contributor_id);\n const initials = this.getInitials(displayName);\n\n // Set ARIA attributes on host element\n const ariaAttrs = createAriaAttributes(element_type);\n Object.entries(ariaAttrs).forEach(([key, value]) => {\n this.setAttribute(key, value);\n });\n\n this.shadow.innerHTML = `\n <style>${styles}</style>\n \n <div class=\"skhema-insight-card\" data-theme=\"${theme}\">\n <div class=\"skhema-header\">\n <div class=\"skhema-contributor\">\n <div class=\"skhema-avatar\" title=\"${displayName}\">\n ${initials}\n </div>\n <div class=\"skhema-contributor-info\">\n <div class=\"skhema-contributor-name\">${displayName}</div>\n <div class=\"skhema-contributor-role\">Strategy Insight</div>\n </div>\n </div>\n <div class=\"skhema-element-badge\" title=\"${label}\">\n ${label}\n </div>\n </div>\n \n <div class=\"skhema-content\">\n <div class=\"skhema-content-text\">${content}</div>\n </div>\n \n <div class=\"skhema-footer\">\n <div class=\"skhema-attribution\">\n Powered by <a href=\"https://skhema.com\" target=\"_blank\" rel=\"noopener noreferrer\">Skhema</a>\n </div>\n <a href=\"${redirectUrl}\" \n class=\"skhema-save-btn\" \n target=\"_blank\"\n rel=\"noopener noreferrer\"\n title=\"Save this insight to Skhema\">\n Save to Skhema\n </a>\n </div>\n </div>\n `;\n\n // Add click event listener\n const saveBtn = this.shadow.querySelector('.skhema-save-btn') as HTMLAnchorElement;\n if (saveBtn) {\n saveBtn.addEventListener('click', (event) => {\n this.handleSaveClick(event);\n });\n }\n }\n\n private formatContributorName(contributorId: string): string {\n // Convert contributor_id to display name\n return contributorId\n .split(/[_-]/)\n .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join(' ');\n }\n\n private getInitials(name: string): string {\n return name\n .split(' ')\n .map(word => word.charAt(0))\n .join('')\n .toUpperCase()\n .substring(0, 2);\n }\n\n private renderError(title: string, errors: string | string[] | any) {\n const errorList = Array.isArray(errors) ? errors : [String(errors)];\n \n this.shadow.innerHTML = `\n <style>${styles}</style>\n \n <div class=\"skhema-insight-card\">\n <div class=\"skhema-error\">\n <div class=\"skhema-error-title\">Skhema Component Error: ${title}</div>\n <ul class=\"skhema-error-list\">\n ${errorList.map(error => `<li>${error}</li>`).join('')}\n </ul>\n </div>\n </div>\n `;\n\n // Dispatch error event\n this.dispatchEvent(new CustomEvent('skhema:error', {\n detail: { error: title, details: errors },\n bubbles: true\n }));\n }\n\n private addStructuredData() {\n if (!this.contentData) return;\n\n const { content, element_type, contributor_id, source_url } = this.contentData;\n \n // Add structured data to the document head\n const structuredData = generateStructuredData(content, element_type, contributor_id, source_url);\n const script = document.createElement('script');\n script.type = 'application/ld+json';\n script.textContent = JSON.stringify(structuredData);\n script.className = 'skhema-structured-data';\n document.head.appendChild(script);\n\n // Add meta tags for SEO\n const metaDiv = document.createElement('div');\n metaDiv.innerHTML = createMetaTags(content, element_type, contributor_id);\n metaDiv.className = 'skhema-structured-data';\n document.body.appendChild(metaDiv);\n }\n\n private async trackLoad() {\n if (!shouldTrackAnalytics(this as HTMLElement) || !this.contentData) return;\n\n const analytics: EmbedAnalytics = {\n contributorId: this.contentData.contributor_id,\n elementType: this.contentData.element_type,\n contentHash: this.contentData.content_hash,\n pageUrl: window.location.href,\n pageTitle: document.title,\n timestamp: Date.now(),\n userAgent: navigator.userAgent\n };\n\n await trackEmbedLoad(analytics);\n\n // Dispatch load event\n this.dispatchEvent(new CustomEvent('skhema:load', {\n detail: analytics,\n bubbles: true\n }));\n }\n\n private async handleSaveClick(_event: Event) {\n if (!this.contentData) return;\n\n // Track click analytics\n if (shouldTrackAnalytics(this as HTMLElement)) {\n await trackClick(this.contentData);\n }\n\n // Dispatch click event\n this.dispatchEvent(new CustomEvent('skhema:click', {\n detail: this.contentData,\n bubbles: true\n }));\n }\n\n // Public API methods\n public getContentData(): ContentData | null {\n return this.contentData;\n }\n\n public refresh(): void {\n this.render();\n }\n}\n\n// Type augmentation for custom events and JSX elements\ndeclare global {\n interface HTMLElementEventMap extends SkhemaElementEventMap {}\n \n namespace JSX {\n interface IntrinsicElements {\n 'skhema-element': Partial<SkhemaElementAttributes> & {\n [key: string]: any;\n };\n }\n }\n}","import { SkhemaElement } from './components/SkhemaElement.js';\n\n// Export the component class\nexport { SkhemaElement };\n\n// Export types for TypeScript users\nexport type {\n SkhemaElementAttributes,\n EmbedAnalytics,\n ContentData,\n SkhemaElementEventMap\n} from './components/types.js';\n\n// Export utilities\nexport {\n isValidElementType,\n validateAttributes,\n getElementTypeLabel,\n getElementTypeAcronym\n} from './utils/validation.js';\n\nexport {\n generateContentHash,\n shouldTrackAnalytics\n} from './utils/analytics.js';\n\nexport {\n generateStructuredData,\n generateRedirectUrl\n} from './utils/seo.js';\n\n// Manual registration function for consuming applications\nexport function registerSkhemaElement() {\n if (typeof window !== 'undefined' && !customElements.get('skhema-element')) {\n customElements.define('skhema-element', SkhemaElement as CustomElementConstructor);\n }\n}\n\n// Auto-register in browser environments (can be tree-shaken if not needed)\nif (typeof window !== 'undefined' && !customElements.get('skhema-element')) {\n customElements.define('skhema-element', SkhemaElement as CustomElementConstructor);\n}\n\n// Default export for convenience\nexport default SkhemaElement;"],"names":["generateContentHash"],"mappings":"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AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAwTR,MAAM,sBAAsB,YAAY;AAAA,EAK7C,cAAc;AACZ,UAAA;AAJF,SAAQ,cAAkC;AAC1C,SAAQ,qBAAqB;AAI3B,SAAK,SAAS,KAAK,aAAa,EAAE,MAAM,UAAU;AAAA,EACpD;AAAA,EAEA,WAAW,qBAAwD;AACjE,WAAO,CAAC,gBAAgB,kBAAkB,WAAW,cAAc,SAAS,iBAAiB;AAAA,EAC/F;AAAA,EAEA,oBAAoB;AAClB,QAAI,KAAK,mBAAoB;AAC7B,SAAK,qBAAqB;AAE1B,QAAI;AACF,WAAK,OAAA;AACL,WAAK,UAAA;AAAA,IACP,SAAS,OAAO;AACd,WAAK,YAAY,kCAAkC,KAAK;AAAA,IAC1D;AAAA,EACF;AAAA,EAEA,yBAAyB,OAAsC,UAAyB,UAAyB;AAC/G,QAAI,aAAa,YAAY,KAAK,oBAAoB;AACpD,WAAK,OAAA;AAAA,IACP;AAAA,EACF;AAAA,EAEQ,SAAS;AACf,UAAM,aAAa,mBAAmB,IAAmB;AAEzD,QAAI,CAAC,WAAW,SAAS;AACvB,WAAK,YAAY,gCAAgC,WAAW,MAAM;AAClE;AAAA,IACF;AAEA,UAAM,UAAU,KAAK,WAAA;AACrB,QAAI,CAAC,QAAQ,QAAQ;AACnB,WAAK,YAAY,8BAA8B,CAAC,gFAAgF,CAAC;AACjI;AAAA,IACF;AAEA,SAAK,cAAc;AAAA,MACjB,gBAAgB,WAAW;AAAA,MAC3B,cAAc,WAAW;AAAA,MACzB;AAAA,MACA,cAAcA,sBAAoB,OAAO;AAAA,MACzC,YAAY,KAAK,aAAa,YAAY,KAAK,OAAO,SAAS;AAAA,MAC/D,YAAW,oBAAI,KAAA,GAAO,YAAA;AAAA,MACtB,YAAY,SAAS;AAAA,IAAA;AAGvB,SAAK,cAAA;AACL,SAAK,kBAAA;AAAA,EACP;AAAA,EAEQ,aAAqB;AAC3B,WAAO,KAAK,aAAa,SAAS,KAAK,KAAK,eAAe;AAAA,EAC7D;AAAA,EAEQ,gBAAgB;AACtB,QAAI,CAAC,KAAK,YAAa;AAEvB,UAAM,EAAE,cAAc,gBAAgB,QAAA,IAAY,KAAK;AACvD,UAAM,QAAQ,oBAAoB,YAAY;AAC9C,UAAM,cAAc,oBAAoB,SAAS,cAAc,cAAc;AAC7E,UAAM,QAAQ,KAAK,aAAa,OAAO,KAAK;AAG5C,UAAM,cAAc,KAAK,sBAAsB,cAAc;AAC7D,UAAM,WAAW,KAAK,YAAY,WAAW;AAG7C,UAAM,YAAY,qBAAqB,YAAY;AACnD,WAAO,QAAQ,SAAS,EAAE,QAAQ,CAAC,CAAC,KAAK,KAAK,MAAM;AAClD,WAAK,aAAa,KAAK,KAAK;AAAA,IAC9B,CAAC;AAED,SAAK,OAAO,YAAY;AAAA,eACb,MAAM;AAAA;AAAA,qDAEgC,KAAK;AAAA;AAAA;AAAA,gDAGV,WAAW;AAAA,gBAC3C,QAAQ;AAAA;AAAA;AAAA,qDAG6B,WAAW;AAAA;AAAA;AAAA;AAAA,qDAIX,KAAK;AAAA,cAC5C,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA,6CAK0B,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qBAO/B,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAY5B,UAAM,UAAU,KAAK,OAAO,cAAc,kBAAkB;AAC5D,QAAI,SAAS;AACX,cAAQ,iBAAiB,SAAS,CAAC,UAAU;AAC3C,aAAK,gBAAgB,KAAK;AAAA,MAC5B,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEQ,sBAAsB,eAA+B;AAE3D,WAAO,cACJ,MAAM,MAAM,EACZ,IAAI,CAAA,SAAQ,KAAK,OAAO,CAAC,EAAE,gBAAgB,KAAK,MAAM,CAAC,EAAE,aAAa,EACtE,KAAK,GAAG;AAAA,EACb;AAAA,EAEQ,YAAY,MAAsB;AACxC,WAAO,KACJ,MAAM,GAAG,EACT,IAAI,CAAA,SAAQ,KAAK,OAAO,CAAC,CAAC,EAC1B,KAAK,EAAE,EACP,cACA,UAAU,GAAG,CAAC;AAAA,EACnB;AAAA,EAEQ,YAAY,OAAe,QAAiC;AAClE,UAAM,YAAY,MAAM,QAAQ,MAAM,IAAI,SAAS,CAAC,OAAO,MAAM,CAAC;AAElE,SAAK,OAAO,YAAY;AAAA,eACb,MAAM;AAAA;AAAA;AAAA;AAAA,oEAI+C,KAAK;AAAA;AAAA,cAE3D,UAAU,IAAI,CAAA,UAAS,OAAO,KAAK,OAAO,EAAE,KAAK,EAAE,CAAC;AAAA;AAAA;AAAA;AAAA;AAO9D,SAAK,cAAc,IAAI,YAAY,gBAAgB;AAAA,MACjD,QAAQ,EAAE,OAAO,OAAO,SAAS,OAAA;AAAA,MACjC,SAAS;AAAA,IAAA,CACV,CAAC;AAAA,EACJ;AAAA,EAEQ,oBAAoB;AAC1B,QAAI,CAAC,KAAK,YAAa;AAEvB,UAAM,EAAE,SAAS,cAAc,gBAAgB,WAAA,IAAe,KAAK;AAGnE,UAAM,iBAAiB,uBAAuB,SAAS,cAAc,gBAAgB,UAAU;AAC/F,UAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,WAAO,OAAO;AACd,WAAO,cAAc,KAAK,UAAU,cAAc;AAClD,WAAO,YAAY;AACnB,aAAS,KAAK,YAAY,MAAM;AAGhC,UAAM,UAAU,SAAS,cAAc,KAAK;AAC5C,YAAQ,YAAY,eAAe,SAAS,cAAc,cAAc;AACxE,YAAQ,YAAY;AACpB,aAAS,KAAK,YAAY,OAAO;AAAA,EACnC;AAAA,EAEA,MAAc,YAAY;AACxB,QAAI,CAAC,qBAAqB,IAAmB,KAAK,CAAC,KAAK,YAAa;AAErE,UAAM,YAA4B;AAAA,MAChC,eAAe,KAAK,YAAY;AAAA,MAChC,aAAa,KAAK,YAAY;AAAA,MAC9B,aAAa,KAAK,YAAY;AAAA,MAC9B,SAAS,OAAO,SAAS;AAAA,MACzB,WAAW,SAAS;AAAA,MACpB,WAAW,KAAK,IAAA;AAAA,MAChB,WAAW,UAAU;AAAA,IAAA;AAGvB,UAAM,eAAe,SAAS;AAG9B,SAAK,cAAc,IAAI,YAAY,eAAe;AAAA,MAChD,QAAQ;AAAA,MACR,SAAS;AAAA,IAAA,CACV,CAAC;AAAA,EACJ;AAAA,EAEA,MAAc,gBAAgB,QAAe;AAC3C,QAAI,CAAC,KAAK,YAAa;AAGvB,QAAI,qBAAqB,IAAmB,GAAG;AAC7C,YAAM,WAAW,KAAK,WAAW;AAAA,IACnC;AAGA,SAAK,cAAc,IAAI,YAAY,gBAAgB;AAAA,MACjD,QAAQ,KAAK;AAAA,MACb,SAAS;AAAA,IAAA,CACV,CAAC;AAAA,EACJ;AAAA;AAAA,EAGO,iBAAqC;AAC1C,WAAO,KAAK;AAAA,EACd;AAAA,EAEO,UAAgB;AACrB,SAAK,OAAA;AAAA,EACP;AACF;ACxgBO,SAAS,wBAAwB;AACtC,MAAI,OAAO,WAAW,eAAe,CAAC,eAAe,IAAI,gBAAgB,GAAG;AAC1E,mBAAe,OAAO,kBAAkB,aAAyC;AAAA,EACnF;AACF;AAGA,IAAI,OAAO,WAAW,eAAe,CAAC,eAAe,IAAI,gBAAgB,GAAG;AAC1E,iBAAe,OAAO,kBAAkB,aAAyC;AACnF;"}
1
+ {"version":3,"file":"index.es.js","sources":["../src/utils/validation.ts","../src/utils/analytics.ts","../src/utils/hash.ts","../src/utils/seo.ts","../src/components/SkhemaElement.ts","../src/index.ts"],"sourcesContent":["import { ELEMENT_TYPES } from '@skhema/types';\nimport type { ElementValue } from '@skhema/types';\n\nexport function isValidElementType(elementType: string): elementType is ElementValue {\n const validTypes = Object.values(ELEMENT_TYPES).map(type => type.value);\n return validTypes.includes(elementType as ElementValue);\n}\n\nexport function validateAttributes(element: HTMLElement): {\n isValid: boolean;\n errors: string[];\n elementType?: ElementValue;\n contributorId?: string;\n} {\n const errors: string[] = [];\n \n const elementType = element.getAttribute('element-type');\n const contributorId = element.getAttribute('contributor-id');\n \n if (!elementType) {\n errors.push('Missing required attribute: element-type');\n } else if (!isValidElementType(elementType)) {\n const validTypes = Object.values(ELEMENT_TYPES).map(t => t.value).join(', ');\n errors.push(`Invalid element-type \"${elementType}\". Valid types: ${validTypes}`);\n }\n \n if (!contributorId) {\n errors.push('Missing required attribute: contributor-id');\n } else if (contributorId.trim().length === 0) {\n errors.push('contributor-id cannot be empty');\n }\n \n return {\n isValid: errors.length === 0,\n errors,\n elementType: isValidElementType(elementType || '') ? elementType as ElementValue : undefined,\n contributorId: contributorId || undefined\n };\n}\n\nexport function getElementTypeLabel(elementType: ElementValue): string {\n const type = Object.values(ELEMENT_TYPES).find(t => t.value === elementType);\n return type?.label || elementType;\n}\n\nexport function getElementTypeAcronym(elementType: ElementValue): string {\n const type = Object.values(ELEMENT_TYPES).find(t => t.value === elementType);\n return type?.acronym || elementType.substring(0, 2).toUpperCase();\n}","import type { EmbedAnalytics, ContentData } from '../components/types.js';\n\n\nexport async function trackEmbedLoad(analytics: EmbedAnalytics): Promise<void> {\n try {\n const data = new URLSearchParams({\n contributor_id: analytics.contributorId,\n element_type: analytics.elementType,\n content_hash: analytics.contentHash,\n page_url: analytics.pageUrl,\n page_title: analytics.pageTitle || '',\n timestamp: analytics.timestamp.toString(),\n user_agent: analytics.userAgent || ''\n });\n\n // Use beacon for reliability\n if (navigator.sendBeacon) {\n navigator.sendBeacon('https://api.skhema.com/api:XGdoUqHx/component/embed', data);\n } else {\n // Fallback to fetch\n fetch('https://api.skhema.com/api:XGdoUqHx/component/embed', {\n method: 'POST',\n body: data,\n credentials: 'omit',\n keepalive: true\n }).catch(() => {\n // Fail silently - analytics shouldn't break the component\n });\n }\n } catch (error) {\n // Fail silently\n console.debug('Analytics tracking failed:', error);\n }\n}\n\nexport async function trackClick(contentData: ContentData): Promise<void> {\n try {\n const data = {\n contributor_id: contentData.contributor_id,\n element_type: contentData.element_type,\n content_hash: contentData.content_hash,\n source_url: contentData.source_url,\n timestamp: contentData.timestamp\n };\n\n if (navigator.sendBeacon) {\n const blob = new Blob([JSON.stringify(data)], {\n type: 'application/json'\n });\n navigator.sendBeacon(\n 'https://api.skhema.com/api:XGdoUqHx/component/click',\n blob\n );\n } else {\n fetch('https://api.skhema.com/api:XGdoUqHx/component/click', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(data),\n credentials: 'omit',\n keepalive: true\n }).catch(() => {\n // Fail silently\n });\n }\n } catch (error) {\n console.debug('Click tracking failed:', error);\n }\n}\n\nexport function shouldTrackAnalytics(element: HTMLElement): boolean {\n const trackAnalytics = element.getAttribute('track-analytics');\n return trackAnalytics !== 'false';\n}","export function generateContentHash(content: string): string {\n // Simple hash function for content identification\n let hash = 0;\n const cleanContent = content.trim().substring(0, 200);\n \n for (let i = 0; i < cleanContent.length; i++) {\n const char = cleanContent.charCodeAt(i);\n hash = ((hash << 5) - hash) + char;\n hash = hash & hash; // Convert to 32bit integer\n }\n \n return Math.abs(hash).toString(36).substring(0, 12);\n}","import type { ElementValue } from '@skhema/types';\nimport { getElementTypeLabel } from './validation.js';\nimport { generateContentHash } from './hash.js';\n\nexport function generateStructuredData(\n content: string,\n elementType: ElementValue,\n contributorId: string,\n sourceUrl: string\n): object {\n return {\n \"@context\": \"https://schema.org\",\n \"@type\": \"AnalysisContent\",\n \"text\": content,\n \"analysisType\": elementType,\n \"category\": getElementTypeLabel(elementType),\n \"contributor\": contributorId,\n \"url\": generateRedirectUrl(content, elementType, contributorId),\n \"provider\": {\n \"@type\": \"Organization\",\n \"name\": \"Skhema\",\n \"url\": \"https://skhema.com\"\n },\n \"isPartOf\": {\n \"@type\": \"WebPage\",\n \"url\": sourceUrl\n },\n \"dateCreated\": new Date().toISOString(),\n \"platform\": \"Skhema\"\n };\n}\n\nexport function generateRedirectUrl(\n content: string,\n elementType: ElementValue,\n contributorId: string,\n options: {\n baseUrl?: string;\n utmSource?: string;\n utmMedium?: string;\n utmCampaign?: string;\n } = {}\n): string {\n const baseUrl = options.baseUrl || 'https://app.skhema.com/save'; // This page will handle the authentication and content saving\n const contentHash = generateContentHash(content);\n const sourceUrl = encodeURIComponent(window.location.href);\n const timestamp = Date.now();\n \n const params = new URLSearchParams({\n source: sourceUrl,\n t: timestamp.toString(),\n utm_source: options.utmSource || 'web_component',\n utm_medium: options.utmMedium || 'embedded',\n utm_campaign: options.utmCampaign || elementType,\n utm_content: contributorId\n });\n \n \n return `${baseUrl}?contributor_id=${contributorId}&element_type=${elementType}&content_hash=${contentHash}&${params.toString()}`;\n // return `${baseUrl}/contributor_id=${contributorId}&element_type=${elementType}&content_hash=${contentHash}?${params.toString()}`;\n}\n\n\nexport function createMetaTags(\n content: string,\n elementType: ElementValue,\n contributorId: string\n): string {\n const label = getElementTypeLabel(elementType);\n \n return `\n <div itemscope itemtype=\"https://schema.org/AnalysisContent\" style=\"display:none;\">\n <meta itemprop=\"analysisType\" content=\"${elementType}\">\n <meta itemprop=\"text\" content=\"${content}\">\n <meta itemprop=\"contributor\" content=\"${contributorId}\">\n <meta itemprop=\"category\" content=\"${label}\">\n <meta itemprop=\"platform\" content=\"Skhema\">\n </div>\n `;\n}\n\nexport function createAriaAttributes(elementType: ElementValue): Record<string, string> {\n const label = getElementTypeLabel(elementType);\n \n return {\n 'role': 'article',\n 'aria-label': `${label} - Strategic insight`,\n 'aria-describedby': 'skhema-description'\n };\n}","import type { SkhemaElementAttributes, EmbedAnalytics, ContentData, SkhemaElementEventMap } from './types.js';\nimport { validateAttributes, getElementTypeLabel } from '../utils/validation.js';\nimport { trackEmbedLoad, trackClick, shouldTrackAnalytics } from '../utils/analytics.js';\nimport { generateContentHash } from '../utils/hash.js';\nimport { generateStructuredData, generateRedirectUrl, createMetaTags, createAriaAttributes } from '../utils/seo.js';\n\n// Inline styles matching Skhema UI library design system\nconst styles = `\n:host {\n /* Skhema Brand Colors - matching UI library */\n --skhema-primary: hsl(344 57% 54%); /* #cd476a */\n --skhema-primary-hover: hsl(344 50% 47%); /* #b53d5e */\n --skhema-primary-pressed: hsl(343 50% 41%); /* #9d3552 */\n --skhema-secondary: hsl(345 100% 75%); /* #ff82a2 */\n --skhema-gradient: linear-gradient(135deg, hsl(344 57% 54%) 0%, hsl(345 100% 75%) 100%);\n \n /* Light mode colors */\n --skhema-bg: hsl(0 0% 100%);\n --skhema-card: hsl(0 0% 100%);\n --skhema-border: hsl(214.3 31.8% 91.4%);\n --skhema-text: hsl(222.2 84% 4.9%);\n --skhema-text-muted: hsl(215.4 16.3% 46.9%);\n --skhema-accent: hsl(210 40% 96%);\n \n /* Shadows matching UI library */\n --skhema-shadow: 0 1px 3px 0 hsl(0 0 0 / 0.1), 0 1px 2px -1px hsl(0 0 0 / 0.1);\n --skhema-shadow-md: 0 4px 6px -1px hsl(0 0 0 / 0.1), 0 2px 4px -2px hsl(0 0 0 / 0.1);\n --skhema-shadow-lg: 0 10px 15px -3px hsl(0 0 0 / 0.1), 0 4px 6px -4px hsl(0 0 0 / 0.1);\n --skhema-radius: 0.375rem;\n \n display: block;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Inter', sans-serif;\n line-height: 1.5;\n color: var(--skhema-text);\n}\n\n:host([theme=\"dark\"]) {\n /* Dark mode colors */\n --skhema-bg: hsl(222.2 84% 4.9%);\n --skhema-card: hsl(222.2 84% 4.9%);\n --skhema-border: hsl(217.2 32.6% 17.5%);\n --skhema-text: hsl(210 40% 98%);\n --skhema-text-muted: hsl(215 20.2% 65.1%);\n --skhema-accent: hsl(217.2 32.6% 17.5%);\n}\n\n/* Main component card - inspired by your design */\n.skhema-insight-card {\n position: relative;\n background: var(--skhema-card);\n border: 1px solid var(--skhema-border);\n border-radius: calc(var(--skhema-radius) * 2);\n padding: 16px;\n box-shadow: var(--skhema-shadow);\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n max-width: 600px;\n margin: 8px 0;\n}\n\n.skhema-insight-card:hover {\n box-shadow: var(--skhema-shadow-lg);\n border-color: var(--skhema-primary);\n transform: translateY(-1px);\n}\n\n/* Header section with contributor info */\n.skhema-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 12px;\n gap: 12px;\n}\n\n.skhema-contributor {\n display: flex;\n align-items: center;\n gap: 8px;\n flex: 1;\n}\n\n.skhema-avatar {\n width: 32px;\n height: 32px;\n border-radius: 50%;\n background: var(--skhema-gradient);\n display: flex;\n align-items: center;\n justify-content: center;\n font-weight: 600;\n font-size: 14px;\n color: white;\n flex-shrink: 0;\n}\n\n.skhema-contributor-info {\n min-width: 0;\n flex: 1;\n}\n\n.skhema-contributor-name {\n font-weight: 500;\n font-size: 14px;\n color: var(--skhema-text);\n margin: 0;\n line-height: 1.2;\n}\n\n.skhema-contributor-role {\n font-size: 12px;\n color: var(--skhema-text-muted);\n margin: 0;\n line-height: 1.2;\n}\n\n/* Element type badge */\n.skhema-element-badge {\n display: inline-flex;\n align-items: center;\n padding: 4px 8px;\n background: var(--skhema-accent);\n border: 1px solid var(--skhema-border);\n border-radius: var(--skhema-radius);\n font-size: 11px;\n font-weight: 500;\n color: var(--skhema-text-muted);\n text-transform: capitalize;\n white-space: nowrap;\n flex-shrink: 0;\n}\n\n/* Content section */\n.skhema-content {\n margin: 12px 0 16px 0;\n padding: 0;\n}\n\n.skhema-content-text {\n font-size: 15px;\n line-height: 1.6;\n color: var(--skhema-text);\n margin: 0;\n font-style: italic;\n position: relative;\n}\n\n.skhema-content-text::before {\n content: '\"';\n color: var(--skhema-primary);\n font-size: 20px;\n font-weight: 600;\n margin-right: 4px;\n}\n\n.skhema-content-text::after {\n content: '\"';\n color: var(--skhema-primary);\n font-size: 20px;\n font-weight: 600;\n margin-left: 4px;\n}\n\n/* Footer section */\n.skhema-footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n padding-top: 12px;\n border-top: 1px solid var(--skhema-border);\n}\n\n.skhema-attribution {\n font-size: 11px;\n color: var(--skhema-text-muted);\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.skhema-attribution a {\n color: var(--skhema-primary);\n text-decoration: none;\n font-weight: 500;\n}\n\n.skhema-attribution a:hover {\n text-decoration: underline;\n}\n\n/* Save button with gradient and arrow */\n.skhema-save-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n background: var(--skhema-gradient);\n color: white;\n border: none;\n padding: 8px 16px;\n border-radius: var(--skhema-radius);\n font-size: 13px;\n font-weight: 500;\n text-decoration: none;\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n box-shadow: var(--skhema-shadow);\n white-space: nowrap;\n}\n\n.skhema-save-btn:hover {\n transform: translateY(-1px);\n box-shadow: var(--skhema-shadow-md);\n}\n\n.skhema-save-btn:active {\n transform: translateY(0);\n}\n\n.skhema-save-btn:focus {\n outline: 2px solid var(--skhema-primary);\n outline-offset: 2px;\n}\n\n.skhema-save-btn::after {\n content: '→';\n transition: transform 0.2s ease;\n}\n\n.skhema-save-btn:hover::after {\n transform: translateX(2px);\n}\n\n/* Error state */\n.skhema-error {\n background: hsl(0 93% 94%);\n border: 1px solid hsl(0 84% 60%);\n color: hsl(0 74% 42%);\n padding: 12px;\n border-radius: var(--skhema-radius);\n font-size: 13px;\n}\n\n.skhema-error-title {\n font-weight: 600;\n margin-bottom: 8px;\n}\n\n.skhema-error-list {\n margin: 0;\n padding-left: 16px;\n}\n\n/* Loading state */\n.skhema-loading {\n background: var(--skhema-accent);\n border: 1px solid var(--skhema-border);\n padding: 12px;\n border-radius: var(--skhema-radius);\n color: var(--skhema-text-muted);\n font-size: 13px;\n text-align: center;\n}\n\n.skhema-loading::after {\n content: '...';\n animation: loading 1.5s infinite;\n}\n\n@keyframes loading {\n 0%, 33% { content: '...'; }\n 66% { content: '..'; }\n 100% { content: '.'; }\n}\n\n/* Responsive design */\n@media (max-width: 640px) {\n .skhema-insight-card {\n margin: 4px 0;\n padding: 12px;\n }\n \n .skhema-header {\n flex-direction: column;\n align-items: flex-start;\n gap: 8px;\n }\n \n .skhema-footer {\n flex-direction: column;\n align-items: stretch;\n gap: 8px;\n }\n \n .skhema-save-btn {\n justify-content: center;\n }\n}\n\n/* Accessibility */\n@media (prefers-reduced-motion: reduce) {\n .skhema-insight-card,\n .skhema-save-btn {\n transition: none;\n }\n \n .skhema-save-btn::after {\n transition: none;\n }\n \n .skhema-save-btn:hover::after {\n transform: none;\n }\n}\n\n.skhema-structured-data {\n display: none !important;\n}\n`;\n\nexport class SkhemaElement extends HTMLElement {\n private shadow: ShadowRoot;\n private contentData: ContentData | null = null;\n private componentConnected = false;\n\n constructor() {\n super();\n this.shadow = this.attachShadow({ mode: 'closed' });\n }\n\n static get observedAttributes(): (keyof SkhemaElementAttributes)[] {\n return ['element-type', 'contributor-id', 'content', 'source-url', 'theme', 'track-analytics'];\n }\n\n connectedCallback() {\n if (this.componentConnected) return;\n this.componentConnected = true;\n \n try {\n this.render();\n this.trackLoad();\n } catch (error) {\n this.renderError('Failed to initialize component', error);\n }\n }\n\n attributeChangedCallback(_name: keyof SkhemaElementAttributes, oldValue: string | null, newValue: string | null) {\n if (oldValue !== newValue && this.componentConnected) {\n this.render();\n }\n }\n\n private render() {\n const validation = validateAttributes(this as HTMLElement);\n \n if (!validation.isValid) {\n this.renderError('Invalid component attributes', validation.errors);\n return;\n }\n\n const content = this.getContent();\n if (!content.trim()) {\n this.renderError('Component requires content', ['Add content between the opening and closing tags, or use the content attribute']);\n return;\n }\n\n this.contentData = {\n contributor_id: validation.contributorId!,\n element_type: validation.elementType!,\n content: content,\n content_hash: generateContentHash(content),\n source_url: this.getAttribute('source-url') || window.location.href,\n timestamp: new Date().toISOString(),\n page_title: document.title\n };\n\n this.renderContent();\n this.addStructuredData();\n }\n\n private getContent(): string {\n return this.getAttribute('content') || this.textContent || '';\n }\n\n private renderContent() {\n if (!this.contentData) return;\n\n const { element_type, contributor_id, content } = this.contentData;\n const label = getElementTypeLabel(element_type);\n const redirectUrl = generateRedirectUrl(content, element_type, contributor_id);\n const theme = this.getAttribute('theme') || 'auto';\n\n // Generate contributor display name and initials\n const displayName = this.formatContributorName(contributor_id);\n const initials = this.getInitials(displayName);\n\n // Set ARIA attributes on host element\n const ariaAttrs = createAriaAttributes(element_type);\n Object.entries(ariaAttrs).forEach(([key, value]) => {\n this.setAttribute(key, value);\n });\n\n this.shadow.innerHTML = `\n <style>${styles}</style>\n \n <div class=\"skhema-insight-card\" data-theme=\"${theme}\">\n <div class=\"skhema-header\">\n <div class=\"skhema-contributor\">\n <div class=\"skhema-avatar\" title=\"${displayName}\">\n ${initials}\n </div>\n <div class=\"skhema-contributor-info\">\n <div class=\"skhema-contributor-name\">${displayName}</div>\n <div class=\"skhema-contributor-role\">Strategy Insight</div>\n </div>\n </div>\n <div class=\"skhema-element-badge\" title=\"${label}\">\n ${label}\n </div>\n </div>\n \n <div class=\"skhema-content\">\n <div class=\"skhema-content-text\">${content}</div>\n </div>\n \n <div class=\"skhema-footer\">\n <div class=\"skhema-attribution\">\n Powered by <a href=\"https://skhema.com\" target=\"_blank\" rel=\"noopener noreferrer\">Skhema</a>\n </div>\n <a href=\"${redirectUrl}\" \n class=\"skhema-save-btn\" \n target=\"_blank\"\n rel=\"noopener noreferrer\"\n title=\"Save this insight to Skhema\">\n Save to Skhema\n </a>\n </div>\n </div>\n `;\n\n // Add click event listener\n const saveBtn = this.shadow.querySelector('.skhema-save-btn') as HTMLAnchorElement;\n if (saveBtn) {\n saveBtn.addEventListener('click', (event) => {\n this.handleSaveClick(event);\n });\n }\n }\n\n private formatContributorName(contributorId: string): string {\n // Convert contributor_id to display name\n return contributorId\n .split(/[_-]/)\n .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join(' ');\n }\n\n private getInitials(name: string): string {\n return name\n .split(' ')\n .map(word => word.charAt(0))\n .join('')\n .toUpperCase()\n .substring(0, 2);\n }\n\n private renderError(title: string, errors: string | string[] | any) {\n const errorList = Array.isArray(errors) ? errors : [String(errors)];\n \n this.shadow.innerHTML = `\n <style>${styles}</style>\n \n <div class=\"skhema-insight-card\">\n <div class=\"skhema-error\">\n <div class=\"skhema-error-title\">Skhema Component Error: ${title}</div>\n <ul class=\"skhema-error-list\">\n ${errorList.map(error => `<li>${error}</li>`).join('')}\n </ul>\n </div>\n </div>\n `;\n\n // Dispatch error event\n this.dispatchEvent(new CustomEvent('skhema:error', {\n detail: { error: title, details: errors },\n bubbles: true\n }));\n }\n\n private addStructuredData() {\n if (!this.contentData) return;\n\n const { content, element_type, contributor_id, source_url } = this.contentData;\n \n // Add structured data to the document head\n const structuredData = generateStructuredData(content, element_type, contributor_id, source_url);\n const script = document.createElement('script');\n script.type = 'application/ld+json';\n script.textContent = JSON.stringify(structuredData);\n script.className = 'skhema-structured-data';\n document.head.appendChild(script);\n\n // Add meta tags for SEO\n const metaDiv = document.createElement('div');\n metaDiv.innerHTML = createMetaTags(content, element_type, contributor_id);\n metaDiv.className = 'skhema-structured-data';\n document.body.appendChild(metaDiv);\n }\n\n private async trackLoad() {\n if (!shouldTrackAnalytics(this as HTMLElement) || !this.contentData) return;\n\n const analytics: EmbedAnalytics = {\n contributorId: this.contentData.contributor_id,\n elementType: this.contentData.element_type,\n contentHash: this.contentData.content_hash,\n pageUrl: window.location.href,\n pageTitle: document.title,\n timestamp: Date.now(),\n userAgent: navigator.userAgent\n };\n\n await trackEmbedLoad(analytics);\n\n // Dispatch load event\n this.dispatchEvent(new CustomEvent('skhema:load', {\n detail: analytics,\n bubbles: true\n }));\n }\n\n private async handleSaveClick(_event: Event) {\n if (!this.contentData) return;\n\n // Track click analytics\n if (shouldTrackAnalytics(this as HTMLElement)) {\n await trackClick(this.contentData);\n }\n\n // Dispatch click event\n this.dispatchEvent(new CustomEvent('skhema:click', {\n detail: this.contentData,\n bubbles: true\n }));\n }\n\n // Public API methods\n public getContentData(): ContentData | null {\n return this.contentData;\n }\n\n public refresh(): void {\n this.render();\n }\n}\n\n// Type augmentation for custom events and JSX elements\ndeclare global {\n interface HTMLElementEventMap extends SkhemaElementEventMap {}\n \n namespace JSX {\n interface IntrinsicElements {\n 'skhema-element': Partial<SkhemaElementAttributes> & {\n [key: string]: any;\n };\n }\n }\n}","import { SkhemaElement } from './components/SkhemaElement.js';\n\n// Export the component class\nexport { SkhemaElement };\n\n// Export types for TypeScript users\nexport type {\n SkhemaElementAttributes,\n EmbedAnalytics,\n ContentData,\n SkhemaElementEventMap\n} from './components/types.js';\n\n// Export utilities\nexport {\n isValidElementType,\n validateAttributes,\n getElementTypeLabel,\n getElementTypeAcronym\n} from './utils/validation.js';\n\nexport {\n // Removed generateContentHash\n shouldTrackAnalytics\n} from './utils/analytics.js';\n\nexport {\n generateStructuredData,\n generateRedirectUrl\n} from './utils/seo.js';\n\n// Manual registration function for consuming applications\nexport function registerSkhemaElement() {\n if (typeof window !== 'undefined' && !customElements.get('skhema-element')) {\n customElements.define('skhema-element', SkhemaElement as CustomElementConstructor);\n }\n}\n\n// Auto-register in browser environments (can be tree-shaken if not needed)\nif (typeof window !== 'undefined' && !customElements.get('skhema-element')) {\n customElements.define('skhema-element', SkhemaElement as CustomElementConstructor);\n}\n\n// Default export for convenience\nexport default SkhemaElement;"],"names":[],"mappings":"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AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;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"}
@@ -1,6 +1,5 @@
1
1
  import { EmbedAnalytics, ContentData } from '../components/types.js';
2
2
 
3
- export declare function generateContentHash(content: string): string;
4
3
  export declare function trackEmbedLoad(analytics: EmbedAnalytics): Promise<void>;
5
4
  export declare function trackClick(contentData: ContentData): Promise<void>;
6
5
  export declare function shouldTrackAnalytics(element: HTMLElement): boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"analytics.d.ts","sourceRoot":"","sources":["../../src/utils/analytics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAE1E,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAY3D;AAED,wBAAsB,cAAc,CAAC,SAAS,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CA6B7E;AAED,wBAAsB,UAAU,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CA+BxE;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAGlE"}
1
+ {"version":3,"file":"analytics.d.ts","sourceRoot":"","sources":["../../src/utils/analytics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAG1E,wBAAsB,cAAc,CAAC,SAAS,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CA8B7E;AAED,wBAAsB,UAAU,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAgCxE;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAGlE"}
@@ -0,0 +1,2 @@
1
+ export declare function generateContentHash(content: string): string;
2
+ //# sourceMappingURL=hash.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hash.d.ts","sourceRoot":"","sources":["../../src/utils/hash.ts"],"names":[],"mappings":"AAAA,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAY3D"}
@@ -1 +1 @@
1
- {"version":3,"file":"seo.d.ts","sourceRoot":"","sources":["../../src/utils/seo.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAGlD,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,YAAY,EACzB,aAAa,EAAE,MAAM,EACrB,SAAS,EAAE,MAAM,GAChB,MAAM,CAqBR;AAED,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,YAAY,EACzB,aAAa,EAAE,MAAM,EACrB,OAAO,GAAE;IACP,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACjB,GACL,MAAM,CAkBR;AASD,wBAAgB,cAAc,CAC5B,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,YAAY,EACzB,aAAa,EAAE,MAAM,GACpB,MAAM,CAYR;AAED,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAQtF"}
1
+ {"version":3,"file":"seo.d.ts","sourceRoot":"","sources":["../../src/utils/seo.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAIlD,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,YAAY,EACzB,aAAa,EAAE,MAAM,EACrB,SAAS,EAAE,MAAM,GAChB,MAAM,CAqBR;AAED,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,YAAY,EACzB,aAAa,EAAE,MAAM,EACrB,OAAO,GAAE;IACP,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACjB,GACL,MAAM,CAkBR;AAGD,wBAAgB,cAAc,CAC5B,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,YAAY,EACzB,aAAa,EAAE,MAAM,GACpB,MAAM,CAYR;AAED,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAQtF"}
@@ -1,2 +1,2 @@
1
- !function(n,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((n="undefined"!=typeof globalThis?globalThis:n||self).SkhemaWebComponent={})}(this,function(n){"use strict";const e={KEY_CHALLENGE:{value:"key_challenge",label:"Key Challenge",acronym:"KC"},SUPPORTING_FACT:{value:"supporting_fact",label:"Supporting Fact",acronym:"SF"},ASSOCIATED_IMPACT:{value:"associated_impact",label:"Associated Impact",acronym:"AI"},GUIDING_POLICY:{value:"guiding_policy",label:"Guiding Policy",acronym:"GP"},COMPETITOR_MOVE:{value:"competitor_move",label:"Competitor Move",acronym:"CM"},SCOPE:{value:"scope",label:"Scope",acronym:"SC"},CONSTRAINT:{value:"constraint",label:"Constraint",acronym:"CN"},SOLUTION_ALTERNATIVE:{value:"solution_alternative",label:"Solution Alternative",acronym:"SA"},ASSUMPTION_HYPOTHESIS:{value:"assumption_hypothesis",label:"Assumption Hypothesis",acronym:"AH"},EXPERIMENT:{value:"experiment",label:"Experiment",acronym:"EX"},ACTION:{value:"action",label:"Action",acronym:"AC"},INVESTMENT:{value:"investment",label:"Investment",acronym:"IN"},ESTIMATE:{value:"estimate",label:"Estimate",acronym:"ES"},BASELINE:{value:"baseline",label:"Baseline",acronym:"BL"},OUTCOME:{value:"outcome",label:"Outcome",acronym:"OC"},PERFORMANCE_VARIABLE:{value:"performance_variable",label:"Performance Variable",acronym:"PV"},CAPABILITY:{value:"capability",label:"Capability",acronym:"CP"},SYSTEM:{value:"system",label:"System",acronym:"SY"},PRINCIPLE:{value:"principle",label:"Principle",acronym:"PR"}};function t(n){return Object.values(e).map(n=>n.value).includes(n)}function a(n){const t=Object.values(e).find(e=>e.value===n);return(null==t?void 0:t.label)||n}function r(n){let e=0;const t=n.trim().substring(0,200);for(let a=0;a<t.length;a++){e=(e<<5)-e+t.charCodeAt(a),e&=e}return Math.abs(e).toString(36).substring(0,12)}function o(n){return"false"!==n.getAttribute("track-analytics")}function i(n,e,t,a={}){const r=a.baseUrl||"https://api.skhema.com/api:XGdoUqHx/component/redirect",o=function(n){return btoa(n.substring(0,50)).replace(/[^a-zA-Z0-9]/g,"").substring(0,12)}(n),i=encodeURIComponent(window.location.href),s=Date.now();return`${r}?contributor_id=${t}&element_type=${e}&content_hash=${o}&${new URLSearchParams({source:i,t:s.toString(),utm_source:a.utmSource||"web_component",utm_medium:a.utmMedium||"embedded",utm_campaign:a.utmCampaign||e,utm_content:t}).toString()}`}const s="\n:host {\n /* Skhema Brand Colors - matching UI library */\n --skhema-primary: hsl(344 57% 54%); /* #cd476a */\n --skhema-primary-hover: hsl(344 50% 47%); /* #b53d5e */\n --skhema-primary-pressed: hsl(343 50% 41%); /* #9d3552 */\n --skhema-secondary: hsl(345 100% 75%); /* #ff82a2 */\n --skhema-gradient: linear-gradient(135deg, hsl(344 57% 54%) 0%, hsl(345 100% 75%) 100%);\n \n /* Light mode colors */\n --skhema-bg: hsl(0 0% 100%);\n --skhema-card: hsl(0 0% 100%);\n --skhema-border: hsl(214.3 31.8% 91.4%);\n --skhema-text: hsl(222.2 84% 4.9%);\n --skhema-text-muted: hsl(215.4 16.3% 46.9%);\n --skhema-accent: hsl(210 40% 96%);\n \n /* Shadows matching UI library */\n --skhema-shadow: 0 1px 3px 0 hsl(0 0 0 / 0.1), 0 1px 2px -1px hsl(0 0 0 / 0.1);\n --skhema-shadow-md: 0 4px 6px -1px hsl(0 0 0 / 0.1), 0 2px 4px -2px hsl(0 0 0 / 0.1);\n --skhema-shadow-lg: 0 10px 15px -3px hsl(0 0 0 / 0.1), 0 4px 6px -4px hsl(0 0 0 / 0.1);\n --skhema-radius: 0.375rem;\n \n display: block;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Inter', sans-serif;\n line-height: 1.5;\n color: var(--skhema-text);\n}\n\n:host([theme=\"dark\"]) {\n /* Dark mode colors */\n --skhema-bg: hsl(222.2 84% 4.9%);\n --skhema-card: hsl(222.2 84% 4.9%);\n --skhema-border: hsl(217.2 32.6% 17.5%);\n --skhema-text: hsl(210 40% 98%);\n --skhema-text-muted: hsl(215 20.2% 65.1%);\n --skhema-accent: hsl(217.2 32.6% 17.5%);\n}\n\n/* Main component card - inspired by your design */\n.skhema-insight-card {\n position: relative;\n background: var(--skhema-card);\n border: 1px solid var(--skhema-border);\n border-radius: calc(var(--skhema-radius) * 2);\n padding: 16px;\n box-shadow: var(--skhema-shadow);\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n max-width: 600px;\n margin: 8px 0;\n}\n\n.skhema-insight-card:hover {\n box-shadow: var(--skhema-shadow-lg);\n border-color: var(--skhema-primary);\n transform: translateY(-1px);\n}\n\n/* Header section with contributor info */\n.skhema-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 12px;\n gap: 12px;\n}\n\n.skhema-contributor {\n display: flex;\n align-items: center;\n gap: 8px;\n flex: 1;\n}\n\n.skhema-avatar {\n width: 32px;\n height: 32px;\n border-radius: 50%;\n background: var(--skhema-gradient);\n display: flex;\n align-items: center;\n justify-content: center;\n font-weight: 600;\n font-size: 14px;\n color: white;\n flex-shrink: 0;\n}\n\n.skhema-contributor-info {\n min-width: 0;\n flex: 1;\n}\n\n.skhema-contributor-name {\n font-weight: 500;\n font-size: 14px;\n color: var(--skhema-text);\n margin: 0;\n line-height: 1.2;\n}\n\n.skhema-contributor-role {\n font-size: 12px;\n color: var(--skhema-text-muted);\n margin: 0;\n line-height: 1.2;\n}\n\n/* Element type badge */\n.skhema-element-badge {\n display: inline-flex;\n align-items: center;\n padding: 4px 8px;\n background: var(--skhema-accent);\n border: 1px solid var(--skhema-border);\n border-radius: var(--skhema-radius);\n font-size: 11px;\n font-weight: 500;\n color: var(--skhema-text-muted);\n text-transform: capitalize;\n white-space: nowrap;\n flex-shrink: 0;\n}\n\n/* Content section */\n.skhema-content {\n margin: 12px 0 16px 0;\n padding: 0;\n}\n\n.skhema-content-text {\n font-size: 15px;\n line-height: 1.6;\n color: var(--skhema-text);\n margin: 0;\n font-style: italic;\n position: relative;\n}\n\n.skhema-content-text::before {\n content: '\"';\n color: var(--skhema-primary);\n font-size: 20px;\n font-weight: 600;\n margin-right: 4px;\n}\n\n.skhema-content-text::after {\n content: '\"';\n color: var(--skhema-primary);\n font-size: 20px;\n font-weight: 600;\n margin-left: 4px;\n}\n\n/* Footer section */\n.skhema-footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n padding-top: 12px;\n border-top: 1px solid var(--skhema-border);\n}\n\n.skhema-attribution {\n font-size: 11px;\n color: var(--skhema-text-muted);\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.skhema-attribution a {\n color: var(--skhema-primary);\n text-decoration: none;\n font-weight: 500;\n}\n\n.skhema-attribution a:hover {\n text-decoration: underline;\n}\n\n/* Save button with gradient and arrow */\n.skhema-save-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n background: var(--skhema-gradient);\n color: white;\n border: none;\n padding: 8px 16px;\n border-radius: var(--skhema-radius);\n font-size: 13px;\n font-weight: 500;\n text-decoration: none;\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n box-shadow: var(--skhema-shadow);\n white-space: nowrap;\n}\n\n.skhema-save-btn:hover {\n transform: translateY(-1px);\n box-shadow: var(--skhema-shadow-md);\n}\n\n.skhema-save-btn:active {\n transform: translateY(0);\n}\n\n.skhema-save-btn:focus {\n outline: 2px solid var(--skhema-primary);\n outline-offset: 2px;\n}\n\n.skhema-save-btn::after {\n content: '→';\n transition: transform 0.2s ease;\n}\n\n.skhema-save-btn:hover::after {\n transform: translateX(2px);\n}\n\n/* Error state */\n.skhema-error {\n background: hsl(0 93% 94%);\n border: 1px solid hsl(0 84% 60%);\n color: hsl(0 74% 42%);\n padding: 12px;\n border-radius: var(--skhema-radius);\n font-size: 13px;\n}\n\n.skhema-error-title {\n font-weight: 600;\n margin-bottom: 8px;\n}\n\n.skhema-error-list {\n margin: 0;\n padding-left: 16px;\n}\n\n/* Loading state */\n.skhema-loading {\n background: var(--skhema-accent);\n border: 1px solid var(--skhema-border);\n padding: 12px;\n border-radius: var(--skhema-radius);\n color: var(--skhema-text-muted);\n font-size: 13px;\n text-align: center;\n}\n\n.skhema-loading::after {\n content: '...';\n animation: loading 1.5s infinite;\n}\n\n@keyframes loading {\n 0%, 33% { content: '...'; }\n 66% { content: '..'; }\n 100% { content: '.'; }\n}\n\n/* Responsive design */\n@media (max-width: 640px) {\n .skhema-insight-card {\n margin: 4px 0;\n padding: 12px;\n }\n \n .skhema-header {\n flex-direction: column;\n align-items: flex-start;\n gap: 8px;\n }\n \n .skhema-footer {\n flex-direction: column;\n align-items: stretch;\n gap: 8px;\n }\n \n .skhema-save-btn {\n justify-content: center;\n }\n}\n\n/* Accessibility */\n@media (prefers-reduced-motion: reduce) {\n .skhema-insight-card,\n .skhema-save-btn {\n transition: none;\n }\n \n .skhema-save-btn::after {\n transition: none;\n }\n \n .skhema-save-btn:hover::after {\n transform: none;\n }\n}\n\n.skhema-structured-data {\n display: none !important;\n}\n";class c extends HTMLElement{constructor(){super(),this.contentData=null,this.componentConnected=!1,this.shadow=this.attachShadow({mode:"closed"})}static get observedAttributes(){return["element-type","contributor-id","content","source-url","theme","track-analytics"]}connectedCallback(){if(!this.componentConnected){this.componentConnected=!0;try{this.render(),this.trackLoad()}catch(n){this.renderError("Failed to initialize component",n)}}}attributeChangedCallback(n,e,t){e!==t&&this.componentConnected&&this.render()}render(){const n=function(n){const a=[],r=n.getAttribute("element-type"),o=n.getAttribute("contributor-id");if(r){if(!t(r)){const n=Object.values(e).map(n=>n.value).join(", ");a.push(`Invalid element-type "${r}". Valid types: ${n}`)}}else a.push("Missing required attribute: element-type");return o?0===o.trim().length&&a.push("contributor-id cannot be empty"):a.push("Missing required attribute: contributor-id"),{isValid:0===a.length,errors:a,elementType:t(r||"")?r:void 0,contributorId:o||void 0}}(this);if(!n.isValid)return void this.renderError("Invalid component attributes",n.errors);const a=this.getContent();a.trim()?(this.contentData={contributor_id:n.contributorId,element_type:n.elementType,content:a,content_hash:r(a),source_url:this.getAttribute("source-url")||window.location.href,timestamp:(new Date).toISOString(),page_title:document.title},this.renderContent(),this.addStructuredData()):this.renderError("Component requires content",["Add content between the opening and closing tags, or use the content attribute"])}getContent(){return this.getAttribute("content")||this.textContent||""}renderContent(){if(!this.contentData)return;const{element_type:n,contributor_id:e,content:t}=this.contentData,r=a(n),o=i(t,n,e),c=this.getAttribute("theme")||"auto",l=this.formatContributorName(e),m=this.getInitials(l),h={role:"article","aria-label":`${a(n)} - Strategic insight`,"aria-describedby":"skhema-description"};Object.entries(h).forEach(([n,e])=>{this.setAttribute(n,e)}),this.shadow.innerHTML=`\n <style>${s}</style>\n \n <div class="skhema-insight-card" data-theme="${c}">\n <div class="skhema-header">\n <div class="skhema-contributor">\n <div class="skhema-avatar" title="${l}">\n ${m}\n </div>\n <div class="skhema-contributor-info">\n <div class="skhema-contributor-name">${l}</div>\n <div class="skhema-contributor-role">Strategy Insight</div>\n </div>\n </div>\n <div class="skhema-element-badge" title="${r}">\n ${r}\n </div>\n </div>\n \n <div class="skhema-content">\n <div class="skhema-content-text">${t}</div>\n </div>\n \n <div class="skhema-footer">\n <div class="skhema-attribution">\n Powered by <a href="https://skhema.com" target="_blank" rel="noopener noreferrer">Skhema</a>\n </div>\n <a href="${o}" \n class="skhema-save-btn" \n target="_blank"\n rel="noopener noreferrer"\n title="Save this insight to Skhema">\n Save to Skhema\n </a>\n </div>\n </div>\n `;const d=this.shadow.querySelector(".skhema-save-btn");d&&d.addEventListener("click",n=>{this.handleSaveClick(n)})}formatContributorName(n){return n.split(/[_-]/).map(n=>n.charAt(0).toUpperCase()+n.slice(1).toLowerCase()).join(" ")}getInitials(n){return n.split(" ").map(n=>n.charAt(0)).join("").toUpperCase().substring(0,2)}renderError(n,e){const t=Array.isArray(e)?e:[String(e)];this.shadow.innerHTML=`\n <style>${s}</style>\n \n <div class="skhema-insight-card">\n <div class="skhema-error">\n <div class="skhema-error-title">Skhema Component Error: ${n}</div>\n <ul class="skhema-error-list">\n ${t.map(n=>`<li>${n}</li>`).join("")}\n </ul>\n </div>\n </div>\n `,this.dispatchEvent(new CustomEvent("skhema:error",{detail:{error:n,details:e},bubbles:!0}))}addStructuredData(){if(!this.contentData)return;const{content:n,element_type:e,contributor_id:t,source_url:r}=this.contentData,o=function(n,e,t,r){return{"@context":"https://schema.org","@type":"AnalysisContent",text:n,analysisType:e,category:a(e),contributor:t,url:i(n,e,t),provider:{"@type":"Organization",name:"Skhema",url:"https://skhema.com"},isPartOf:{"@type":"WebPage",url:r},dateCreated:(new Date).toISOString(),platform:"Skhema"}}(n,e,t,r),s=document.createElement("script");s.type="application/ld+json",s.textContent=JSON.stringify(o),s.className="skhema-structured-data",document.head.appendChild(s);const c=document.createElement("div");c.innerHTML=function(n,e,t){return`\n <div itemscope itemtype="https://schema.org/AnalysisContent" style="display:none;">\n <meta itemprop="analysisType" content="${e}">\n <meta itemprop="text" content="${n}">\n <meta itemprop="contributor" content="${t}">\n <meta itemprop="category" content="${a(e)}">\n <meta itemprop="platform" content="Skhema">\n </div>\n `}(n,e,t),c.className="skhema-structured-data",document.body.appendChild(c)}async trackLoad(){if(!o(this)||!this.contentData)return;const n={contributorId:this.contentData.contributor_id,elementType:this.contentData.element_type,contentHash:this.contentData.content_hash,pageUrl:window.location.href,pageTitle:document.title,timestamp:Date.now(),userAgent:navigator.userAgent};await async function(n){try{const e=new URLSearchParams({contributor_id:n.contributorId,element_type:n.elementType,content_hash:n.contentHash,page_url:n.pageUrl,page_title:n.pageTitle||"",timestamp:n.timestamp.toString(),user_agent:n.userAgent||""});navigator.sendBeacon?navigator.sendBeacon("https://api.skhema.com/api:XGdoUqHx/component/embed",e):fetch("https://api.skhema.com/api:XGdoUqHx/component/embed",{method:"POST",body:e,keepalive:!0}).catch(()=>{})}catch(e){console.debug("Analytics tracking failed:",e)}}(n),this.dispatchEvent(new CustomEvent("skhema:load",{detail:n,bubbles:!0}))}async handleSaveClick(n){this.contentData&&(o(this)&&await async function(n){try{const e={contributor_id:n.contributor_id,element_type:n.element_type,content_hash:n.content_hash,source_url:n.source_url,timestamp:n.timestamp};if(navigator.sendBeacon){const n=new Blob([JSON.stringify(e)],{type:"application/json"});navigator.sendBeacon("https://api.skhema.com/api:XGdoUqHx/component/click",n)}else fetch("https://api.skhema.com/api:XGdoUqHx/component/click",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e),keepalive:!0}).catch(()=>{})}catch(e){console.debug("Click tracking failed:",e)}}(this.contentData),this.dispatchEvent(new CustomEvent("skhema:click",{detail:this.contentData,bubbles:!0})))}getContentData(){return this.contentData}refresh(){this.render()}}customElements.get("skhema-element")||customElements.define("skhema-element",c),"undefined"!=typeof window&&(window.SkhemaElement=c),n.SkhemaElement=c,Object.defineProperty(n,Symbol.toStringTag,{value:"Module"})});
1
+ !function(n,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((n="undefined"!=typeof globalThis?globalThis:n||self).SkhemaWebComponent={})}(this,function(n){"use strict";const e={KEY_CHALLENGE:{value:"key_challenge",label:"Key Challenge",acronym:"KC"},SUPPORTING_FACT:{value:"supporting_fact",label:"Supporting Fact",acronym:"SF"},ASSOCIATED_IMPACT:{value:"associated_impact",label:"Associated Impact",acronym:"AI"},GUIDING_POLICY:{value:"guiding_policy",label:"Guiding Policy",acronym:"GP"},COMPETITOR_MOVE:{value:"competitor_move",label:"Competitor Move",acronym:"CM"},SCOPE:{value:"scope",label:"Scope",acronym:"SC"},CONSTRAINT:{value:"constraint",label:"Constraint",acronym:"CN"},SOLUTION_ALTERNATIVE:{value:"solution_alternative",label:"Solution Alternative",acronym:"SA"},ASSUMPTION_HYPOTHESIS:{value:"assumption_hypothesis",label:"Assumption Hypothesis",acronym:"AH"},EXPERIMENT:{value:"experiment",label:"Experiment",acronym:"EX"},ACTION:{value:"action",label:"Action",acronym:"AC"},INVESTMENT:{value:"investment",label:"Investment",acronym:"IN"},ESTIMATE:{value:"estimate",label:"Estimate",acronym:"ES"},BASELINE:{value:"baseline",label:"Baseline",acronym:"BL"},OUTCOME:{value:"outcome",label:"Outcome",acronym:"OC"},PERFORMANCE_VARIABLE:{value:"performance_variable",label:"Performance Variable",acronym:"PV"},CAPABILITY:{value:"capability",label:"Capability",acronym:"CP"},SYSTEM:{value:"system",label:"System",acronym:"SY"},PRINCIPLE:{value:"principle",label:"Principle",acronym:"PR"}};function t(n){return Object.values(e).map(n=>n.value).includes(n)}function a(n){const t=Object.values(e).find(e=>e.value===n);return(null==t?void 0:t.label)||n}function r(n){return"false"!==n.getAttribute("track-analytics")}function o(n){let e=0;const t=n.trim().substring(0,200);for(let a=0;a<t.length;a++){e=(e<<5)-e+t.charCodeAt(a),e&=e}return Math.abs(e).toString(36).substring(0,12)}function i(n,e,t,a={}){const r=a.baseUrl||"https://app.skhema.com/save",i=o(n),s=encodeURIComponent(window.location.href),c=Date.now();return`${r}?contributor_id=${t}&element_type=${e}&content_hash=${i}&${new URLSearchParams({source:s,t:c.toString(),utm_source:a.utmSource||"web_component",utm_medium:a.utmMedium||"embedded",utm_campaign:a.utmCampaign||e,utm_content:t}).toString()}`}const s="\n:host {\n /* Skhema Brand Colors - matching UI library */\n --skhema-primary: hsl(344 57% 54%); /* #cd476a */\n --skhema-primary-hover: hsl(344 50% 47%); /* #b53d5e */\n --skhema-primary-pressed: hsl(343 50% 41%); /* #9d3552 */\n --skhema-secondary: hsl(345 100% 75%); /* #ff82a2 */\n --skhema-gradient: linear-gradient(135deg, hsl(344 57% 54%) 0%, hsl(345 100% 75%) 100%);\n \n /* Light mode colors */\n --skhema-bg: hsl(0 0% 100%);\n --skhema-card: hsl(0 0% 100%);\n --skhema-border: hsl(214.3 31.8% 91.4%);\n --skhema-text: hsl(222.2 84% 4.9%);\n --skhema-text-muted: hsl(215.4 16.3% 46.9%);\n --skhema-accent: hsl(210 40% 96%);\n \n /* Shadows matching UI library */\n --skhema-shadow: 0 1px 3px 0 hsl(0 0 0 / 0.1), 0 1px 2px -1px hsl(0 0 0 / 0.1);\n --skhema-shadow-md: 0 4px 6px -1px hsl(0 0 0 / 0.1), 0 2px 4px -2px hsl(0 0 0 / 0.1);\n --skhema-shadow-lg: 0 10px 15px -3px hsl(0 0 0 / 0.1), 0 4px 6px -4px hsl(0 0 0 / 0.1);\n --skhema-radius: 0.375rem;\n \n display: block;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Inter', sans-serif;\n line-height: 1.5;\n color: var(--skhema-text);\n}\n\n:host([theme=\"dark\"]) {\n /* Dark mode colors */\n --skhema-bg: hsl(222.2 84% 4.9%);\n --skhema-card: hsl(222.2 84% 4.9%);\n --skhema-border: hsl(217.2 32.6% 17.5%);\n --skhema-text: hsl(210 40% 98%);\n --skhema-text-muted: hsl(215 20.2% 65.1%);\n --skhema-accent: hsl(217.2 32.6% 17.5%);\n}\n\n/* Main component card - inspired by your design */\n.skhema-insight-card {\n position: relative;\n background: var(--skhema-card);\n border: 1px solid var(--skhema-border);\n border-radius: calc(var(--skhema-radius) * 2);\n padding: 16px;\n box-shadow: var(--skhema-shadow);\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n max-width: 600px;\n margin: 8px 0;\n}\n\n.skhema-insight-card:hover {\n box-shadow: var(--skhema-shadow-lg);\n border-color: var(--skhema-primary);\n transform: translateY(-1px);\n}\n\n/* Header section with contributor info */\n.skhema-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 12px;\n gap: 12px;\n}\n\n.skhema-contributor {\n display: flex;\n align-items: center;\n gap: 8px;\n flex: 1;\n}\n\n.skhema-avatar {\n width: 32px;\n height: 32px;\n border-radius: 50%;\n background: var(--skhema-gradient);\n display: flex;\n align-items: center;\n justify-content: center;\n font-weight: 600;\n font-size: 14px;\n color: white;\n flex-shrink: 0;\n}\n\n.skhema-contributor-info {\n min-width: 0;\n flex: 1;\n}\n\n.skhema-contributor-name {\n font-weight: 500;\n font-size: 14px;\n color: var(--skhema-text);\n margin: 0;\n line-height: 1.2;\n}\n\n.skhema-contributor-role {\n font-size: 12px;\n color: var(--skhema-text-muted);\n margin: 0;\n line-height: 1.2;\n}\n\n/* Element type badge */\n.skhema-element-badge {\n display: inline-flex;\n align-items: center;\n padding: 4px 8px;\n background: var(--skhema-accent);\n border: 1px solid var(--skhema-border);\n border-radius: var(--skhema-radius);\n font-size: 11px;\n font-weight: 500;\n color: var(--skhema-text-muted);\n text-transform: capitalize;\n white-space: nowrap;\n flex-shrink: 0;\n}\n\n/* Content section */\n.skhema-content {\n margin: 12px 0 16px 0;\n padding: 0;\n}\n\n.skhema-content-text {\n font-size: 15px;\n line-height: 1.6;\n color: var(--skhema-text);\n margin: 0;\n font-style: italic;\n position: relative;\n}\n\n.skhema-content-text::before {\n content: '\"';\n color: var(--skhema-primary);\n font-size: 20px;\n font-weight: 600;\n margin-right: 4px;\n}\n\n.skhema-content-text::after {\n content: '\"';\n color: var(--skhema-primary);\n font-size: 20px;\n font-weight: 600;\n margin-left: 4px;\n}\n\n/* Footer section */\n.skhema-footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n padding-top: 12px;\n border-top: 1px solid var(--skhema-border);\n}\n\n.skhema-attribution {\n font-size: 11px;\n color: var(--skhema-text-muted);\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.skhema-attribution a {\n color: var(--skhema-primary);\n text-decoration: none;\n font-weight: 500;\n}\n\n.skhema-attribution a:hover {\n text-decoration: underline;\n}\n\n/* Save button with gradient and arrow */\n.skhema-save-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n background: var(--skhema-gradient);\n color: white;\n border: none;\n padding: 8px 16px;\n border-radius: var(--skhema-radius);\n font-size: 13px;\n font-weight: 500;\n text-decoration: none;\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n box-shadow: var(--skhema-shadow);\n white-space: nowrap;\n}\n\n.skhema-save-btn:hover {\n transform: translateY(-1px);\n box-shadow: var(--skhema-shadow-md);\n}\n\n.skhema-save-btn:active {\n transform: translateY(0);\n}\n\n.skhema-save-btn:focus {\n outline: 2px solid var(--skhema-primary);\n outline-offset: 2px;\n}\n\n.skhema-save-btn::after {\n content: '→';\n transition: transform 0.2s ease;\n}\n\n.skhema-save-btn:hover::after {\n transform: translateX(2px);\n}\n\n/* Error state */\n.skhema-error {\n background: hsl(0 93% 94%);\n border: 1px solid hsl(0 84% 60%);\n color: hsl(0 74% 42%);\n padding: 12px;\n border-radius: var(--skhema-radius);\n font-size: 13px;\n}\n\n.skhema-error-title {\n font-weight: 600;\n margin-bottom: 8px;\n}\n\n.skhema-error-list {\n margin: 0;\n padding-left: 16px;\n}\n\n/* Loading state */\n.skhema-loading {\n background: var(--skhema-accent);\n border: 1px solid var(--skhema-border);\n padding: 12px;\n border-radius: var(--skhema-radius);\n color: var(--skhema-text-muted);\n font-size: 13px;\n text-align: center;\n}\n\n.skhema-loading::after {\n content: '...';\n animation: loading 1.5s infinite;\n}\n\n@keyframes loading {\n 0%, 33% { content: '...'; }\n 66% { content: '..'; }\n 100% { content: '.'; }\n}\n\n/* Responsive design */\n@media (max-width: 640px) {\n .skhema-insight-card {\n margin: 4px 0;\n padding: 12px;\n }\n \n .skhema-header {\n flex-direction: column;\n align-items: flex-start;\n gap: 8px;\n }\n \n .skhema-footer {\n flex-direction: column;\n align-items: stretch;\n gap: 8px;\n }\n \n .skhema-save-btn {\n justify-content: center;\n }\n}\n\n/* Accessibility */\n@media (prefers-reduced-motion: reduce) {\n .skhema-insight-card,\n .skhema-save-btn {\n transition: none;\n }\n \n .skhema-save-btn::after {\n transition: none;\n }\n \n .skhema-save-btn:hover::after {\n transform: none;\n }\n}\n\n.skhema-structured-data {\n display: none !important;\n}\n";class c extends HTMLElement{constructor(){super(),this.contentData=null,this.componentConnected=!1,this.shadow=this.attachShadow({mode:"closed"})}static get observedAttributes(){return["element-type","contributor-id","content","source-url","theme","track-analytics"]}connectedCallback(){if(!this.componentConnected){this.componentConnected=!0;try{this.render(),this.trackLoad()}catch(n){this.renderError("Failed to initialize component",n)}}}attributeChangedCallback(n,e,t){e!==t&&this.componentConnected&&this.render()}render(){const n=function(n){const a=[],r=n.getAttribute("element-type"),o=n.getAttribute("contributor-id");if(r){if(!t(r)){const n=Object.values(e).map(n=>n.value).join(", ");a.push(`Invalid element-type "${r}". Valid types: ${n}`)}}else a.push("Missing required attribute: element-type");return o?0===o.trim().length&&a.push("contributor-id cannot be empty"):a.push("Missing required attribute: contributor-id"),{isValid:0===a.length,errors:a,elementType:t(r||"")?r:void 0,contributorId:o||void 0}}(this);if(!n.isValid)return void this.renderError("Invalid component attributes",n.errors);const a=this.getContent();a.trim()?(this.contentData={contributor_id:n.contributorId,element_type:n.elementType,content:a,content_hash:o(a),source_url:this.getAttribute("source-url")||window.location.href,timestamp:(new Date).toISOString(),page_title:document.title},this.renderContent(),this.addStructuredData()):this.renderError("Component requires content",["Add content between the opening and closing tags, or use the content attribute"])}getContent(){return this.getAttribute("content")||this.textContent||""}renderContent(){if(!this.contentData)return;const{element_type:n,contributor_id:e,content:t}=this.contentData,r=a(n),o=i(t,n,e),c=this.getAttribute("theme")||"auto",l=this.formatContributorName(e),m=this.getInitials(l),h={role:"article","aria-label":`${a(n)} - Strategic insight`,"aria-describedby":"skhema-description"};Object.entries(h).forEach(([n,e])=>{this.setAttribute(n,e)}),this.shadow.innerHTML=`\n <style>${s}</style>\n \n <div class="skhema-insight-card" data-theme="${c}">\n <div class="skhema-header">\n <div class="skhema-contributor">\n <div class="skhema-avatar" title="${l}">\n ${m}\n </div>\n <div class="skhema-contributor-info">\n <div class="skhema-contributor-name">${l}</div>\n <div class="skhema-contributor-role">Strategy Insight</div>\n </div>\n </div>\n <div class="skhema-element-badge" title="${r}">\n ${r}\n </div>\n </div>\n \n <div class="skhema-content">\n <div class="skhema-content-text">${t}</div>\n </div>\n \n <div class="skhema-footer">\n <div class="skhema-attribution">\n Powered by <a href="https://skhema.com" target="_blank" rel="noopener noreferrer">Skhema</a>\n </div>\n <a href="${o}" \n class="skhema-save-btn" \n target="_blank"\n rel="noopener noreferrer"\n title="Save this insight to Skhema">\n Save to Skhema\n </a>\n </div>\n </div>\n `;const d=this.shadow.querySelector(".skhema-save-btn");d&&d.addEventListener("click",n=>{this.handleSaveClick(n)})}formatContributorName(n){return n.split(/[_-]/).map(n=>n.charAt(0).toUpperCase()+n.slice(1).toLowerCase()).join(" ")}getInitials(n){return n.split(" ").map(n=>n.charAt(0)).join("").toUpperCase().substring(0,2)}renderError(n,e){const t=Array.isArray(e)?e:[String(e)];this.shadow.innerHTML=`\n <style>${s}</style>\n \n <div class="skhema-insight-card">\n <div class="skhema-error">\n <div class="skhema-error-title">Skhema Component Error: ${n}</div>\n <ul class="skhema-error-list">\n ${t.map(n=>`<li>${n}</li>`).join("")}\n </ul>\n </div>\n </div>\n `,this.dispatchEvent(new CustomEvent("skhema:error",{detail:{error:n,details:e},bubbles:!0}))}addStructuredData(){if(!this.contentData)return;const{content:n,element_type:e,contributor_id:t,source_url:r}=this.contentData,o=function(n,e,t,r){return{"@context":"https://schema.org","@type":"AnalysisContent",text:n,analysisType:e,category:a(e),contributor:t,url:i(n,e,t),provider:{"@type":"Organization",name:"Skhema",url:"https://skhema.com"},isPartOf:{"@type":"WebPage",url:r},dateCreated:(new Date).toISOString(),platform:"Skhema"}}(n,e,t,r),s=document.createElement("script");s.type="application/ld+json",s.textContent=JSON.stringify(o),s.className="skhema-structured-data",document.head.appendChild(s);const c=document.createElement("div");c.innerHTML=function(n,e,t){return`\n <div itemscope itemtype="https://schema.org/AnalysisContent" style="display:none;">\n <meta itemprop="analysisType" content="${e}">\n <meta itemprop="text" content="${n}">\n <meta itemprop="contributor" content="${t}">\n <meta itemprop="category" content="${a(e)}">\n <meta itemprop="platform" content="Skhema">\n </div>\n `}(n,e,t),c.className="skhema-structured-data",document.body.appendChild(c)}async trackLoad(){if(!r(this)||!this.contentData)return;const n={contributorId:this.contentData.contributor_id,elementType:this.contentData.element_type,contentHash:this.contentData.content_hash,pageUrl:window.location.href,pageTitle:document.title,timestamp:Date.now(),userAgent:navigator.userAgent};await async function(n){try{const e=new URLSearchParams({contributor_id:n.contributorId,element_type:n.elementType,content_hash:n.contentHash,page_url:n.pageUrl,page_title:n.pageTitle||"",timestamp:n.timestamp.toString(),user_agent:n.userAgent||""});navigator.sendBeacon?navigator.sendBeacon("https://api.skhema.com/api:XGdoUqHx/component/embed",e):fetch("https://api.skhema.com/api:XGdoUqHx/component/embed",{method:"POST",body:e,credentials:"omit",keepalive:!0}).catch(()=>{})}catch(e){console.debug("Analytics tracking failed:",e)}}(n),this.dispatchEvent(new CustomEvent("skhema:load",{detail:n,bubbles:!0}))}async handleSaveClick(n){this.contentData&&(r(this)&&await async function(n){try{const e={contributor_id:n.contributor_id,element_type:n.element_type,content_hash:n.content_hash,source_url:n.source_url,timestamp:n.timestamp};if(navigator.sendBeacon){const n=new Blob([JSON.stringify(e)],{type:"application/json"});navigator.sendBeacon("https://api.skhema.com/api:XGdoUqHx/component/click",n)}else fetch("https://api.skhema.com/api:XGdoUqHx/component/click",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e),credentials:"omit",keepalive:!0}).catch(()=>{})}catch(e){console.debug("Click tracking failed:",e)}}(this.contentData),this.dispatchEvent(new CustomEvent("skhema:click",{detail:this.contentData,bubbles:!0})))}getContentData(){return this.contentData}refresh(){this.render()}}customElements.get("skhema-element")||customElements.define("skhema-element",c),"undefined"!=typeof window&&(window.SkhemaElement=c),n.SkhemaElement=c,Object.defineProperty(n,Symbol.toStringTag,{value:"Module"})});
2
2
  //# sourceMappingURL=web-component.min.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"web-component.min.js","sources":["../../skhema-types-library/dist/schema/elements.js","../src/utils/validation.ts","../src/utils/analytics.ts","../src/utils/seo.ts","../src/components/SkhemaElement.ts","../src/cdn.ts"],"sourcesContent":["export const ELEMENT_TYPES = {\n KEY_CHALLENGE: {\n value: \"key_challenge\",\n label: \"Key Challenge\",\n acronym: \"KC\"\n },\n SUPPORTING_FACT: {\n value: \"supporting_fact\",\n label: \"Supporting Fact\",\n acronym: \"SF\"\n },\n ASSOCIATED_IMPACT: {\n value: \"associated_impact\",\n label: \"Associated Impact\",\n acronym: \"AI\"\n },\n GUIDING_POLICY: {\n value: \"guiding_policy\",\n label: \"Guiding Policy\",\n acronym: \"GP\"\n },\n COMPETITOR_MOVE: {\n value: \"competitor_move\",\n label: \"Competitor Move\",\n acronym: \"CM\"\n },\n SCOPE: {\n value: \"scope\",\n label: \"Scope\",\n acronym: \"SC\"\n },\n CONSTRAINT: {\n value: \"constraint\",\n label: \"Constraint\",\n acronym: \"CN\"\n },\n SOLUTION_ALTERNATIVE: {\n value: \"solution_alternative\",\n label: \"Solution Alternative\",\n acronym: \"SA\"\n },\n ASSUMPTION_HYPOTHESIS: {\n value: \"assumption_hypothesis\",\n label: \"Assumption Hypothesis\",\n acronym: \"AH\"\n },\n EXPERIMENT: {\n value: \"experiment\",\n label: \"Experiment\",\n acronym: \"EX\"\n },\n ACTION: {\n value: \"action\",\n label: \"Action\",\n acronym: \"AC\"\n },\n INVESTMENT: {\n value: \"investment\",\n label: \"Investment\",\n acronym: \"IN\"\n },\n ESTIMATE: {\n value: \"estimate\",\n label: \"Estimate\",\n acronym: \"ES\"\n },\n BASELINE: {\n value: \"baseline\",\n label: \"Baseline\",\n acronym: \"BL\"\n },\n OUTCOME: {\n value: \"outcome\",\n label: \"Outcome\",\n acronym: \"OC\"\n },\n PERFORMANCE_VARIABLE: {\n value: \"performance_variable\",\n label: \"Performance Variable\",\n acronym: \"PV\"\n },\n CAPABILITY: {\n value: \"capability\",\n label: \"Capability\",\n acronym: \"CP\"\n },\n SYSTEM: {\n value: \"system\",\n label: \"System\",\n acronym: \"SY\"\n },\n PRINCIPLE: {\n value: \"principle\",\n label: \"Principle\",\n acronym: \"PR\"\n }\n};\n","import { ELEMENT_TYPES } from '@skhema/types';\nimport type { ElementValue } from '@skhema/types';\n\nexport function isValidElementType(elementType: string): elementType is ElementValue {\n const validTypes = Object.values(ELEMENT_TYPES).map(type => type.value);\n return validTypes.includes(elementType as ElementValue);\n}\n\nexport function validateAttributes(element: HTMLElement): {\n isValid: boolean;\n errors: string[];\n elementType?: ElementValue;\n contributorId?: string;\n} {\n const errors: string[] = [];\n \n const elementType = element.getAttribute('element-type');\n const contributorId = element.getAttribute('contributor-id');\n \n if (!elementType) {\n errors.push('Missing required attribute: element-type');\n } else if (!isValidElementType(elementType)) {\n const validTypes = Object.values(ELEMENT_TYPES).map(t => t.value).join(', ');\n errors.push(`Invalid element-type \"${elementType}\". Valid types: ${validTypes}`);\n }\n \n if (!contributorId) {\n errors.push('Missing required attribute: contributor-id');\n } else if (contributorId.trim().length === 0) {\n errors.push('contributor-id cannot be empty');\n }\n \n return {\n isValid: errors.length === 0,\n errors,\n elementType: isValidElementType(elementType || '') ? elementType as ElementValue : undefined,\n contributorId: contributorId || undefined\n };\n}\n\nexport function getElementTypeLabel(elementType: ElementValue): string {\n const type = Object.values(ELEMENT_TYPES).find(t => t.value === elementType);\n return type?.label || elementType;\n}\n\nexport function getElementTypeAcronym(elementType: ElementValue): string {\n const type = Object.values(ELEMENT_TYPES).find(t => t.value === elementType);\n return type?.acronym || elementType.substring(0, 2).toUpperCase();\n}","import type { EmbedAnalytics, ContentData } from '../components/types.js';\n\nexport function generateContentHash(content: string): string {\n // Simple hash function for content identification\n let hash = 0;\n const cleanContent = content.trim().substring(0, 200);\n \n for (let i = 0; i < cleanContent.length; i++) {\n const char = cleanContent.charCodeAt(i);\n hash = ((hash << 5) - hash) + char;\n hash = hash & hash; // Convert to 32bit integer\n }\n \n return Math.abs(hash).toString(36).substring(0, 12);\n}\n\nexport async function trackEmbedLoad(analytics: EmbedAnalytics): Promise<void> {\n try {\n const data = new URLSearchParams({\n contributor_id: analytics.contributorId,\n element_type: analytics.elementType,\n content_hash: analytics.contentHash,\n page_url: analytics.pageUrl,\n page_title: analytics.pageTitle || '',\n timestamp: analytics.timestamp.toString(),\n user_agent: analytics.userAgent || ''\n });\n\n // Use beacon for reliability\n if (navigator.sendBeacon) {\n navigator.sendBeacon('https://api.skhema.com/api:XGdoUqHx/component/embed', data);\n } else {\n // Fallback to fetch\n fetch('https://api.skhema.com/api:XGdoUqHx/component/embed', {\n method: 'POST',\n body: data,\n keepalive: true\n }).catch(() => {\n // Fail silently - analytics shouldn't break the component\n });\n }\n } catch (error) {\n // Fail silently\n console.debug('Analytics tracking failed:', error);\n }\n}\n\nexport async function trackClick(contentData: ContentData): Promise<void> {\n try {\n const data = {\n contributor_id: contentData.contributor_id,\n element_type: contentData.element_type,\n content_hash: contentData.content_hash,\n source_url: contentData.source_url,\n timestamp: contentData.timestamp\n };\n\n if (navigator.sendBeacon) {\n const blob = new Blob([JSON.stringify(data)], {\n type: 'application/json'\n });\n navigator.sendBeacon(\n 'https://api.skhema.com/api:XGdoUqHx/component/click',\n blob\n );\n } else {\n fetch('https://api.skhema.com/api:XGdoUqHx/component/click', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(data),\n keepalive: true\n }).catch(() => {\n // Fail silently\n });\n }\n } catch (error) {\n console.debug('Click tracking failed:', error);\n }\n}\n\nexport function shouldTrackAnalytics(element: HTMLElement): boolean {\n const trackAnalytics = element.getAttribute('track-analytics');\n return trackAnalytics !== 'false';\n}","import type { ElementValue } from '@skhema/types';\nimport { getElementTypeLabel } from './validation.js';\n\nexport function generateStructuredData(\n content: string,\n elementType: ElementValue,\n contributorId: string,\n sourceUrl: string\n): object {\n return {\n \"@context\": \"https://schema.org\",\n \"@type\": \"AnalysisContent\",\n \"text\": content,\n \"analysisType\": elementType,\n \"category\": getElementTypeLabel(elementType),\n \"contributor\": contributorId,\n \"url\": generateRedirectUrl(content, elementType, contributorId),\n \"provider\": {\n \"@type\": \"Organization\",\n \"name\": \"Skhema\",\n \"url\": \"https://skhema.com\"\n },\n \"isPartOf\": {\n \"@type\": \"WebPage\",\n \"url\": sourceUrl\n },\n \"dateCreated\": new Date().toISOString(),\n \"platform\": \"Skhema\"\n };\n}\n\nexport function generateRedirectUrl(\n content: string,\n elementType: ElementValue,\n contributorId: string,\n options: {\n baseUrl?: string;\n utmSource?: string;\n utmMedium?: string;\n utmCampaign?: string;\n } = {}\n): string {\n const baseUrl = options.baseUrl || 'https://api.skhema.com/api:XGdoUqHx/component/redirect'; // @TODO: change to actual redirect URL\n const contentHash = generateContentHash(content);\n const sourceUrl = encodeURIComponent(window.location.href);\n const timestamp = Date.now();\n \n const params = new URLSearchParams({\n source: sourceUrl,\n t: timestamp.toString(),\n utm_source: options.utmSource || 'web_component',\n utm_medium: options.utmMedium || 'embedded',\n utm_campaign: options.utmCampaign || elementType,\n utm_content: contributorId\n });\n \n \n return `${baseUrl}?contributor_id=${contributorId}&element_type=${elementType}&content_hash=${contentHash}&${params.toString()}`;\n // return `${baseUrl}/contributor_id=${contributorId}&element_type=${elementType}&content_hash=${contentHash}?${params.toString()}`;\n}\n\nfunction generateContentHash(content: string): string {\n // Simple hash for URL generation\n return btoa(content.substring(0, 50))\n .replace(/[^a-zA-Z0-9]/g, '')\n .substring(0, 12);\n}\n\nexport function createMetaTags(\n content: string,\n elementType: ElementValue,\n contributorId: string\n): string {\n const label = getElementTypeLabel(elementType);\n \n return `\n <div itemscope itemtype=\"https://schema.org/AnalysisContent\" style=\"display:none;\">\n <meta itemprop=\"analysisType\" content=\"${elementType}\">\n <meta itemprop=\"text\" content=\"${content}\">\n <meta itemprop=\"contributor\" content=\"${contributorId}\">\n <meta itemprop=\"category\" content=\"${label}\">\n <meta itemprop=\"platform\" content=\"Skhema\">\n </div>\n `;\n}\n\nexport function createAriaAttributes(elementType: ElementValue): Record<string, string> {\n const label = getElementTypeLabel(elementType);\n \n return {\n 'role': 'article',\n 'aria-label': `${label} - Strategic insight`,\n 'aria-describedby': 'skhema-description'\n };\n}","import type { SkhemaElementAttributes, EmbedAnalytics, ContentData, SkhemaElementEventMap } from './types.js';\nimport { validateAttributes, getElementTypeLabel } from '../utils/validation.js';\nimport { generateContentHash, trackEmbedLoad, trackClick, shouldTrackAnalytics } from '../utils/analytics.js';\nimport { generateStructuredData, generateRedirectUrl, createMetaTags, createAriaAttributes } from '../utils/seo.js';\n\n// Inline styles matching Skhema UI library design system\nconst styles = `\n:host {\n /* Skhema Brand Colors - matching UI library */\n --skhema-primary: hsl(344 57% 54%); /* #cd476a */\n --skhema-primary-hover: hsl(344 50% 47%); /* #b53d5e */\n --skhema-primary-pressed: hsl(343 50% 41%); /* #9d3552 */\n --skhema-secondary: hsl(345 100% 75%); /* #ff82a2 */\n --skhema-gradient: linear-gradient(135deg, hsl(344 57% 54%) 0%, hsl(345 100% 75%) 100%);\n \n /* Light mode colors */\n --skhema-bg: hsl(0 0% 100%);\n --skhema-card: hsl(0 0% 100%);\n --skhema-border: hsl(214.3 31.8% 91.4%);\n --skhema-text: hsl(222.2 84% 4.9%);\n --skhema-text-muted: hsl(215.4 16.3% 46.9%);\n --skhema-accent: hsl(210 40% 96%);\n \n /* Shadows matching UI library */\n --skhema-shadow: 0 1px 3px 0 hsl(0 0 0 / 0.1), 0 1px 2px -1px hsl(0 0 0 / 0.1);\n --skhema-shadow-md: 0 4px 6px -1px hsl(0 0 0 / 0.1), 0 2px 4px -2px hsl(0 0 0 / 0.1);\n --skhema-shadow-lg: 0 10px 15px -3px hsl(0 0 0 / 0.1), 0 4px 6px -4px hsl(0 0 0 / 0.1);\n --skhema-radius: 0.375rem;\n \n display: block;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Inter', sans-serif;\n line-height: 1.5;\n color: var(--skhema-text);\n}\n\n:host([theme=\"dark\"]) {\n /* Dark mode colors */\n --skhema-bg: hsl(222.2 84% 4.9%);\n --skhema-card: hsl(222.2 84% 4.9%);\n --skhema-border: hsl(217.2 32.6% 17.5%);\n --skhema-text: hsl(210 40% 98%);\n --skhema-text-muted: hsl(215 20.2% 65.1%);\n --skhema-accent: hsl(217.2 32.6% 17.5%);\n}\n\n/* Main component card - inspired by your design */\n.skhema-insight-card {\n position: relative;\n background: var(--skhema-card);\n border: 1px solid var(--skhema-border);\n border-radius: calc(var(--skhema-radius) * 2);\n padding: 16px;\n box-shadow: var(--skhema-shadow);\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n max-width: 600px;\n margin: 8px 0;\n}\n\n.skhema-insight-card:hover {\n box-shadow: var(--skhema-shadow-lg);\n border-color: var(--skhema-primary);\n transform: translateY(-1px);\n}\n\n/* Header section with contributor info */\n.skhema-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 12px;\n gap: 12px;\n}\n\n.skhema-contributor {\n display: flex;\n align-items: center;\n gap: 8px;\n flex: 1;\n}\n\n.skhema-avatar {\n width: 32px;\n height: 32px;\n border-radius: 50%;\n background: var(--skhema-gradient);\n display: flex;\n align-items: center;\n justify-content: center;\n font-weight: 600;\n font-size: 14px;\n color: white;\n flex-shrink: 0;\n}\n\n.skhema-contributor-info {\n min-width: 0;\n flex: 1;\n}\n\n.skhema-contributor-name {\n font-weight: 500;\n font-size: 14px;\n color: var(--skhema-text);\n margin: 0;\n line-height: 1.2;\n}\n\n.skhema-contributor-role {\n font-size: 12px;\n color: var(--skhema-text-muted);\n margin: 0;\n line-height: 1.2;\n}\n\n/* Element type badge */\n.skhema-element-badge {\n display: inline-flex;\n align-items: center;\n padding: 4px 8px;\n background: var(--skhema-accent);\n border: 1px solid var(--skhema-border);\n border-radius: var(--skhema-radius);\n font-size: 11px;\n font-weight: 500;\n color: var(--skhema-text-muted);\n text-transform: capitalize;\n white-space: nowrap;\n flex-shrink: 0;\n}\n\n/* Content section */\n.skhema-content {\n margin: 12px 0 16px 0;\n padding: 0;\n}\n\n.skhema-content-text {\n font-size: 15px;\n line-height: 1.6;\n color: var(--skhema-text);\n margin: 0;\n font-style: italic;\n position: relative;\n}\n\n.skhema-content-text::before {\n content: '\"';\n color: var(--skhema-primary);\n font-size: 20px;\n font-weight: 600;\n margin-right: 4px;\n}\n\n.skhema-content-text::after {\n content: '\"';\n color: var(--skhema-primary);\n font-size: 20px;\n font-weight: 600;\n margin-left: 4px;\n}\n\n/* Footer section */\n.skhema-footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n padding-top: 12px;\n border-top: 1px solid var(--skhema-border);\n}\n\n.skhema-attribution {\n font-size: 11px;\n color: var(--skhema-text-muted);\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.skhema-attribution a {\n color: var(--skhema-primary);\n text-decoration: none;\n font-weight: 500;\n}\n\n.skhema-attribution a:hover {\n text-decoration: underline;\n}\n\n/* Save button with gradient and arrow */\n.skhema-save-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n background: var(--skhema-gradient);\n color: white;\n border: none;\n padding: 8px 16px;\n border-radius: var(--skhema-radius);\n font-size: 13px;\n font-weight: 500;\n text-decoration: none;\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n box-shadow: var(--skhema-shadow);\n white-space: nowrap;\n}\n\n.skhema-save-btn:hover {\n transform: translateY(-1px);\n box-shadow: var(--skhema-shadow-md);\n}\n\n.skhema-save-btn:active {\n transform: translateY(0);\n}\n\n.skhema-save-btn:focus {\n outline: 2px solid var(--skhema-primary);\n outline-offset: 2px;\n}\n\n.skhema-save-btn::after {\n content: '→';\n transition: transform 0.2s ease;\n}\n\n.skhema-save-btn:hover::after {\n transform: translateX(2px);\n}\n\n/* Error state */\n.skhema-error {\n background: hsl(0 93% 94%);\n border: 1px solid hsl(0 84% 60%);\n color: hsl(0 74% 42%);\n padding: 12px;\n border-radius: var(--skhema-radius);\n font-size: 13px;\n}\n\n.skhema-error-title {\n font-weight: 600;\n margin-bottom: 8px;\n}\n\n.skhema-error-list {\n margin: 0;\n padding-left: 16px;\n}\n\n/* Loading state */\n.skhema-loading {\n background: var(--skhema-accent);\n border: 1px solid var(--skhema-border);\n padding: 12px;\n border-radius: var(--skhema-radius);\n color: var(--skhema-text-muted);\n font-size: 13px;\n text-align: center;\n}\n\n.skhema-loading::after {\n content: '...';\n animation: loading 1.5s infinite;\n}\n\n@keyframes loading {\n 0%, 33% { content: '...'; }\n 66% { content: '..'; }\n 100% { content: '.'; }\n}\n\n/* Responsive design */\n@media (max-width: 640px) {\n .skhema-insight-card {\n margin: 4px 0;\n padding: 12px;\n }\n \n .skhema-header {\n flex-direction: column;\n align-items: flex-start;\n gap: 8px;\n }\n \n .skhema-footer {\n flex-direction: column;\n align-items: stretch;\n gap: 8px;\n }\n \n .skhema-save-btn {\n justify-content: center;\n }\n}\n\n/* Accessibility */\n@media (prefers-reduced-motion: reduce) {\n .skhema-insight-card,\n .skhema-save-btn {\n transition: none;\n }\n \n .skhema-save-btn::after {\n transition: none;\n }\n \n .skhema-save-btn:hover::after {\n transform: none;\n }\n}\n\n.skhema-structured-data {\n display: none !important;\n}\n`;\n\nexport class SkhemaElement extends HTMLElement {\n private shadow: ShadowRoot;\n private contentData: ContentData | null = null;\n private componentConnected = false;\n\n constructor() {\n super();\n this.shadow = this.attachShadow({ mode: 'closed' });\n }\n\n static get observedAttributes(): (keyof SkhemaElementAttributes)[] {\n return ['element-type', 'contributor-id', 'content', 'source-url', 'theme', 'track-analytics'];\n }\n\n connectedCallback() {\n if (this.componentConnected) return;\n this.componentConnected = true;\n \n try {\n this.render();\n this.trackLoad();\n } catch (error) {\n this.renderError('Failed to initialize component', error);\n }\n }\n\n attributeChangedCallback(_name: keyof SkhemaElementAttributes, oldValue: string | null, newValue: string | null) {\n if (oldValue !== newValue && this.componentConnected) {\n this.render();\n }\n }\n\n private render() {\n const validation = validateAttributes(this as HTMLElement);\n \n if (!validation.isValid) {\n this.renderError('Invalid component attributes', validation.errors);\n return;\n }\n\n const content = this.getContent();\n if (!content.trim()) {\n this.renderError('Component requires content', ['Add content between the opening and closing tags, or use the content attribute']);\n return;\n }\n\n this.contentData = {\n contributor_id: validation.contributorId!,\n element_type: validation.elementType!,\n content: content,\n content_hash: generateContentHash(content),\n source_url: this.getAttribute('source-url') || window.location.href,\n timestamp: new Date().toISOString(),\n page_title: document.title\n };\n\n this.renderContent();\n this.addStructuredData();\n }\n\n private getContent(): string {\n return this.getAttribute('content') || this.textContent || '';\n }\n\n private renderContent() {\n if (!this.contentData) return;\n\n const { element_type, contributor_id, content } = this.contentData;\n const label = getElementTypeLabel(element_type);\n const redirectUrl = generateRedirectUrl(content, element_type, contributor_id);\n const theme = this.getAttribute('theme') || 'auto';\n\n // Generate contributor display name and initials\n const displayName = this.formatContributorName(contributor_id);\n const initials = this.getInitials(displayName);\n\n // Set ARIA attributes on host element\n const ariaAttrs = createAriaAttributes(element_type);\n Object.entries(ariaAttrs).forEach(([key, value]) => {\n this.setAttribute(key, value);\n });\n\n this.shadow.innerHTML = `\n <style>${styles}</style>\n \n <div class=\"skhema-insight-card\" data-theme=\"${theme}\">\n <div class=\"skhema-header\">\n <div class=\"skhema-contributor\">\n <div class=\"skhema-avatar\" title=\"${displayName}\">\n ${initials}\n </div>\n <div class=\"skhema-contributor-info\">\n <div class=\"skhema-contributor-name\">${displayName}</div>\n <div class=\"skhema-contributor-role\">Strategy Insight</div>\n </div>\n </div>\n <div class=\"skhema-element-badge\" title=\"${label}\">\n ${label}\n </div>\n </div>\n \n <div class=\"skhema-content\">\n <div class=\"skhema-content-text\">${content}</div>\n </div>\n \n <div class=\"skhema-footer\">\n <div class=\"skhema-attribution\">\n Powered by <a href=\"https://skhema.com\" target=\"_blank\" rel=\"noopener noreferrer\">Skhema</a>\n </div>\n <a href=\"${redirectUrl}\" \n class=\"skhema-save-btn\" \n target=\"_blank\"\n rel=\"noopener noreferrer\"\n title=\"Save this insight to Skhema\">\n Save to Skhema\n </a>\n </div>\n </div>\n `;\n\n // Add click event listener\n const saveBtn = this.shadow.querySelector('.skhema-save-btn') as HTMLAnchorElement;\n if (saveBtn) {\n saveBtn.addEventListener('click', (event) => {\n this.handleSaveClick(event);\n });\n }\n }\n\n private formatContributorName(contributorId: string): string {\n // Convert contributor_id to display name\n return contributorId\n .split(/[_-]/)\n .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join(' ');\n }\n\n private getInitials(name: string): string {\n return name\n .split(' ')\n .map(word => word.charAt(0))\n .join('')\n .toUpperCase()\n .substring(0, 2);\n }\n\n private renderError(title: string, errors: string | string[] | any) {\n const errorList = Array.isArray(errors) ? errors : [String(errors)];\n \n this.shadow.innerHTML = `\n <style>${styles}</style>\n \n <div class=\"skhema-insight-card\">\n <div class=\"skhema-error\">\n <div class=\"skhema-error-title\">Skhema Component Error: ${title}</div>\n <ul class=\"skhema-error-list\">\n ${errorList.map(error => `<li>${error}</li>`).join('')}\n </ul>\n </div>\n </div>\n `;\n\n // Dispatch error event\n this.dispatchEvent(new CustomEvent('skhema:error', {\n detail: { error: title, details: errors },\n bubbles: true\n }));\n }\n\n private addStructuredData() {\n if (!this.contentData) return;\n\n const { content, element_type, contributor_id, source_url } = this.contentData;\n \n // Add structured data to the document head\n const structuredData = generateStructuredData(content, element_type, contributor_id, source_url);\n const script = document.createElement('script');\n script.type = 'application/ld+json';\n script.textContent = JSON.stringify(structuredData);\n script.className = 'skhema-structured-data';\n document.head.appendChild(script);\n\n // Add meta tags for SEO\n const metaDiv = document.createElement('div');\n metaDiv.innerHTML = createMetaTags(content, element_type, contributor_id);\n metaDiv.className = 'skhema-structured-data';\n document.body.appendChild(metaDiv);\n }\n\n private async trackLoad() {\n if (!shouldTrackAnalytics(this as HTMLElement) || !this.contentData) return;\n\n const analytics: EmbedAnalytics = {\n contributorId: this.contentData.contributor_id,\n elementType: this.contentData.element_type,\n contentHash: this.contentData.content_hash,\n pageUrl: window.location.href,\n pageTitle: document.title,\n timestamp: Date.now(),\n userAgent: navigator.userAgent\n };\n\n await trackEmbedLoad(analytics);\n\n // Dispatch load event\n this.dispatchEvent(new CustomEvent('skhema:load', {\n detail: analytics,\n bubbles: true\n }));\n }\n\n private async handleSaveClick(_event: Event) {\n if (!this.contentData) return;\n\n // Track click analytics\n if (shouldTrackAnalytics(this as HTMLElement)) {\n await trackClick(this.contentData);\n }\n\n // Dispatch click event\n this.dispatchEvent(new CustomEvent('skhema:click', {\n detail: this.contentData,\n bubbles: true\n }));\n }\n\n // Public API methods\n public getContentData(): ContentData | null {\n return this.contentData;\n }\n\n public refresh(): void {\n this.render();\n }\n}\n\n// Type augmentation for custom events and JSX elements\ndeclare global {\n interface HTMLElementEventMap extends SkhemaElementEventMap {}\n \n namespace JSX {\n interface IntrinsicElements {\n 'skhema-element': Partial<SkhemaElementAttributes> & {\n [key: string]: any;\n };\n }\n }\n}","// CDN bundle entry point - automatically registers the component\nimport { SkhemaElement } from './components/SkhemaElement.js';\n\n// Register the custom element for CDN usage\nif (!customElements.get('skhema-element')) {\n customElements.define('skhema-element', SkhemaElement as CustomElementConstructor);\n}\n\n// Expose on global for UMD builds\nif (typeof window !== 'undefined') {\n (window as any).SkhemaElement = SkhemaElement;\n}\n\nexport { SkhemaElement };"],"names":["ELEMENT_TYPES","KEY_CHALLENGE","value","label","acronym","SUPPORTING_FACT","ASSOCIATED_IMPACT","GUIDING_POLICY","COMPETITOR_MOVE","SCOPE","CONSTRAINT","SOLUTION_ALTERNATIVE","ASSUMPTION_HYPOTHESIS","EXPERIMENT","ACTION","INVESTMENT","ESTIMATE","BASELINE","OUTCOME","PERFORMANCE_VARIABLE","CAPABILITY","SYSTEM","PRINCIPLE","isValidElementType","elementType","Object","values","map","type","includes","getElementTypeLabel","find","t","generateContentHash","content","hash","cleanContent","trim","substring","i","length","charCodeAt","Math","abs","toString","shouldTrackAnalytics","element","getAttribute","generateRedirectUrl","contributorId","options","baseUrl","contentHash","btoa","replace","sourceUrl","encodeURIComponent","window","location","href","timestamp","Date","now","URLSearchParams","source","utm_source","utmSource","utm_medium","utmMedium","utm_campaign","utmCampaign","utm_content","styles","SkhemaElement","HTMLElement","constructor","super","this","contentData","componentConnected","shadow","attachShadow","mode","observedAttributes","connectedCallback","render","trackLoad","error","renderError","attributeChangedCallback","_name","oldValue","newValue","validation","errors","validTypes","join","push","isValid","validateAttributes","getContent","contributor_id","element_type","content_hash","source_url","toISOString","page_title","document","title","renderContent","addStructuredData","textContent","redirectUrl","theme","displayName","formatContributorName","initials","getInitials","ariaAttrs","role","entries","forEach","key","setAttribute","innerHTML","saveBtn","querySelector","addEventListener","event","handleSaveClick","split","word","charAt","toUpperCase","slice","toLowerCase","name","errorList","Array","isArray","String","dispatchEvent","CustomEvent","detail","details","bubbles","structuredData","text","analysisType","category","contributor","url","provider","isPartOf","dateCreated","platform","generateStructuredData","script","createElement","JSON","stringify","className","head","appendChild","metaDiv","createMetaTags","body","analytics","pageUrl","pageTitle","userAgent","navigator","async","data","page_url","user_agent","sendBeacon","fetch","method","keepalive","catch","console","debug","trackEmbedLoad","_event","blob","Blob","headers","trackClick","getContentData","refresh","customElements","get","define"],"mappings":"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"}
1
+ {"version":3,"file":"web-component.min.js","sources":["../../skhema-types-library/dist/schema/elements.js","../src/utils/validation.ts","../src/utils/analytics.ts","../src/utils/hash.ts","../src/utils/seo.ts","../src/components/SkhemaElement.ts","../src/cdn.ts"],"sourcesContent":["export const ELEMENT_TYPES = {\n KEY_CHALLENGE: {\n value: \"key_challenge\",\n label: \"Key Challenge\",\n acronym: \"KC\"\n },\n SUPPORTING_FACT: {\n value: \"supporting_fact\",\n label: \"Supporting Fact\",\n acronym: \"SF\"\n },\n ASSOCIATED_IMPACT: {\n value: \"associated_impact\",\n label: \"Associated Impact\",\n acronym: \"AI\"\n },\n GUIDING_POLICY: {\n value: \"guiding_policy\",\n label: \"Guiding Policy\",\n acronym: \"GP\"\n },\n COMPETITOR_MOVE: {\n value: \"competitor_move\",\n label: \"Competitor Move\",\n acronym: \"CM\"\n },\n SCOPE: {\n value: \"scope\",\n label: \"Scope\",\n acronym: \"SC\"\n },\n CONSTRAINT: {\n value: \"constraint\",\n label: \"Constraint\",\n acronym: \"CN\"\n },\n SOLUTION_ALTERNATIVE: {\n value: \"solution_alternative\",\n label: \"Solution Alternative\",\n acronym: \"SA\"\n },\n ASSUMPTION_HYPOTHESIS: {\n value: \"assumption_hypothesis\",\n label: \"Assumption Hypothesis\",\n acronym: \"AH\"\n },\n EXPERIMENT: {\n value: \"experiment\",\n label: \"Experiment\",\n acronym: \"EX\"\n },\n ACTION: {\n value: \"action\",\n label: \"Action\",\n acronym: \"AC\"\n },\n INVESTMENT: {\n value: \"investment\",\n label: \"Investment\",\n acronym: \"IN\"\n },\n ESTIMATE: {\n value: \"estimate\",\n label: \"Estimate\",\n acronym: \"ES\"\n },\n BASELINE: {\n value: \"baseline\",\n label: \"Baseline\",\n acronym: \"BL\"\n },\n OUTCOME: {\n value: \"outcome\",\n label: \"Outcome\",\n acronym: \"OC\"\n },\n PERFORMANCE_VARIABLE: {\n value: \"performance_variable\",\n label: \"Performance Variable\",\n acronym: \"PV\"\n },\n CAPABILITY: {\n value: \"capability\",\n label: \"Capability\",\n acronym: \"CP\"\n },\n SYSTEM: {\n value: \"system\",\n label: \"System\",\n acronym: \"SY\"\n },\n PRINCIPLE: {\n value: \"principle\",\n label: \"Principle\",\n acronym: \"PR\"\n }\n};\n","import { ELEMENT_TYPES } from '@skhema/types';\nimport type { ElementValue } from '@skhema/types';\n\nexport function isValidElementType(elementType: string): elementType is ElementValue {\n const validTypes = Object.values(ELEMENT_TYPES).map(type => type.value);\n return validTypes.includes(elementType as ElementValue);\n}\n\nexport function validateAttributes(element: HTMLElement): {\n isValid: boolean;\n errors: string[];\n elementType?: ElementValue;\n contributorId?: string;\n} {\n const errors: string[] = [];\n \n const elementType = element.getAttribute('element-type');\n const contributorId = element.getAttribute('contributor-id');\n \n if (!elementType) {\n errors.push('Missing required attribute: element-type');\n } else if (!isValidElementType(elementType)) {\n const validTypes = Object.values(ELEMENT_TYPES).map(t => t.value).join(', ');\n errors.push(`Invalid element-type \"${elementType}\". Valid types: ${validTypes}`);\n }\n \n if (!contributorId) {\n errors.push('Missing required attribute: contributor-id');\n } else if (contributorId.trim().length === 0) {\n errors.push('contributor-id cannot be empty');\n }\n \n return {\n isValid: errors.length === 0,\n errors,\n elementType: isValidElementType(elementType || '') ? elementType as ElementValue : undefined,\n contributorId: contributorId || undefined\n };\n}\n\nexport function getElementTypeLabel(elementType: ElementValue): string {\n const type = Object.values(ELEMENT_TYPES).find(t => t.value === elementType);\n return type?.label || elementType;\n}\n\nexport function getElementTypeAcronym(elementType: ElementValue): string {\n const type = Object.values(ELEMENT_TYPES).find(t => t.value === elementType);\n return type?.acronym || elementType.substring(0, 2).toUpperCase();\n}","import type { EmbedAnalytics, ContentData } from '../components/types.js';\n\n\nexport async function trackEmbedLoad(analytics: EmbedAnalytics): Promise<void> {\n try {\n const data = new URLSearchParams({\n contributor_id: analytics.contributorId,\n element_type: analytics.elementType,\n content_hash: analytics.contentHash,\n page_url: analytics.pageUrl,\n page_title: analytics.pageTitle || '',\n timestamp: analytics.timestamp.toString(),\n user_agent: analytics.userAgent || ''\n });\n\n // Use beacon for reliability\n if (navigator.sendBeacon) {\n navigator.sendBeacon('https://api.skhema.com/api:XGdoUqHx/component/embed', data);\n } else {\n // Fallback to fetch\n fetch('https://api.skhema.com/api:XGdoUqHx/component/embed', {\n method: 'POST',\n body: data,\n credentials: 'omit',\n keepalive: true\n }).catch(() => {\n // Fail silently - analytics shouldn't break the component\n });\n }\n } catch (error) {\n // Fail silently\n console.debug('Analytics tracking failed:', error);\n }\n}\n\nexport async function trackClick(contentData: ContentData): Promise<void> {\n try {\n const data = {\n contributor_id: contentData.contributor_id,\n element_type: contentData.element_type,\n content_hash: contentData.content_hash,\n source_url: contentData.source_url,\n timestamp: contentData.timestamp\n };\n\n if (navigator.sendBeacon) {\n const blob = new Blob([JSON.stringify(data)], {\n type: 'application/json'\n });\n navigator.sendBeacon(\n 'https://api.skhema.com/api:XGdoUqHx/component/click',\n blob\n );\n } else {\n fetch('https://api.skhema.com/api:XGdoUqHx/component/click', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(data),\n credentials: 'omit',\n keepalive: true\n }).catch(() => {\n // Fail silently\n });\n }\n } catch (error) {\n console.debug('Click tracking failed:', error);\n }\n}\n\nexport function shouldTrackAnalytics(element: HTMLElement): boolean {\n const trackAnalytics = element.getAttribute('track-analytics');\n return trackAnalytics !== 'false';\n}","export function generateContentHash(content: string): string {\n // Simple hash function for content identification\n let hash = 0;\n const cleanContent = content.trim().substring(0, 200);\n \n for (let i = 0; i < cleanContent.length; i++) {\n const char = cleanContent.charCodeAt(i);\n hash = ((hash << 5) - hash) + char;\n hash = hash & hash; // Convert to 32bit integer\n }\n \n return Math.abs(hash).toString(36).substring(0, 12);\n}","import type { ElementValue } from '@skhema/types';\nimport { getElementTypeLabel } from './validation.js';\nimport { generateContentHash } from './hash.js';\n\nexport function generateStructuredData(\n content: string,\n elementType: ElementValue,\n contributorId: string,\n sourceUrl: string\n): object {\n return {\n \"@context\": \"https://schema.org\",\n \"@type\": \"AnalysisContent\",\n \"text\": content,\n \"analysisType\": elementType,\n \"category\": getElementTypeLabel(elementType),\n \"contributor\": contributorId,\n \"url\": generateRedirectUrl(content, elementType, contributorId),\n \"provider\": {\n \"@type\": \"Organization\",\n \"name\": \"Skhema\",\n \"url\": \"https://skhema.com\"\n },\n \"isPartOf\": {\n \"@type\": \"WebPage\",\n \"url\": sourceUrl\n },\n \"dateCreated\": new Date().toISOString(),\n \"platform\": \"Skhema\"\n };\n}\n\nexport function generateRedirectUrl(\n content: string,\n elementType: ElementValue,\n contributorId: string,\n options: {\n baseUrl?: string;\n utmSource?: string;\n utmMedium?: string;\n utmCampaign?: string;\n } = {}\n): string {\n const baseUrl = options.baseUrl || 'https://app.skhema.com/save'; // This page will handle the authentication and content saving\n const contentHash = generateContentHash(content);\n const sourceUrl = encodeURIComponent(window.location.href);\n const timestamp = Date.now();\n \n const params = new URLSearchParams({\n source: sourceUrl,\n t: timestamp.toString(),\n utm_source: options.utmSource || 'web_component',\n utm_medium: options.utmMedium || 'embedded',\n utm_campaign: options.utmCampaign || elementType,\n utm_content: contributorId\n });\n \n \n return `${baseUrl}?contributor_id=${contributorId}&element_type=${elementType}&content_hash=${contentHash}&${params.toString()}`;\n // return `${baseUrl}/contributor_id=${contributorId}&element_type=${elementType}&content_hash=${contentHash}?${params.toString()}`;\n}\n\n\nexport function createMetaTags(\n content: string,\n elementType: ElementValue,\n contributorId: string\n): string {\n const label = getElementTypeLabel(elementType);\n \n return `\n <div itemscope itemtype=\"https://schema.org/AnalysisContent\" style=\"display:none;\">\n <meta itemprop=\"analysisType\" content=\"${elementType}\">\n <meta itemprop=\"text\" content=\"${content}\">\n <meta itemprop=\"contributor\" content=\"${contributorId}\">\n <meta itemprop=\"category\" content=\"${label}\">\n <meta itemprop=\"platform\" content=\"Skhema\">\n </div>\n `;\n}\n\nexport function createAriaAttributes(elementType: ElementValue): Record<string, string> {\n const label = getElementTypeLabel(elementType);\n \n return {\n 'role': 'article',\n 'aria-label': `${label} - Strategic insight`,\n 'aria-describedby': 'skhema-description'\n };\n}","import type { SkhemaElementAttributes, EmbedAnalytics, ContentData, SkhemaElementEventMap } from './types.js';\nimport { validateAttributes, getElementTypeLabel } from '../utils/validation.js';\nimport { trackEmbedLoad, trackClick, shouldTrackAnalytics } from '../utils/analytics.js';\nimport { generateContentHash } from '../utils/hash.js';\nimport { generateStructuredData, generateRedirectUrl, createMetaTags, createAriaAttributes } from '../utils/seo.js';\n\n// Inline styles matching Skhema UI library design system\nconst styles = `\n:host {\n /* Skhema Brand Colors - matching UI library */\n --skhema-primary: hsl(344 57% 54%); /* #cd476a */\n --skhema-primary-hover: hsl(344 50% 47%); /* #b53d5e */\n --skhema-primary-pressed: hsl(343 50% 41%); /* #9d3552 */\n --skhema-secondary: hsl(345 100% 75%); /* #ff82a2 */\n --skhema-gradient: linear-gradient(135deg, hsl(344 57% 54%) 0%, hsl(345 100% 75%) 100%);\n \n /* Light mode colors */\n --skhema-bg: hsl(0 0% 100%);\n --skhema-card: hsl(0 0% 100%);\n --skhema-border: hsl(214.3 31.8% 91.4%);\n --skhema-text: hsl(222.2 84% 4.9%);\n --skhema-text-muted: hsl(215.4 16.3% 46.9%);\n --skhema-accent: hsl(210 40% 96%);\n \n /* Shadows matching UI library */\n --skhema-shadow: 0 1px 3px 0 hsl(0 0 0 / 0.1), 0 1px 2px -1px hsl(0 0 0 / 0.1);\n --skhema-shadow-md: 0 4px 6px -1px hsl(0 0 0 / 0.1), 0 2px 4px -2px hsl(0 0 0 / 0.1);\n --skhema-shadow-lg: 0 10px 15px -3px hsl(0 0 0 / 0.1), 0 4px 6px -4px hsl(0 0 0 / 0.1);\n --skhema-radius: 0.375rem;\n \n display: block;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Inter', sans-serif;\n line-height: 1.5;\n color: var(--skhema-text);\n}\n\n:host([theme=\"dark\"]) {\n /* Dark mode colors */\n --skhema-bg: hsl(222.2 84% 4.9%);\n --skhema-card: hsl(222.2 84% 4.9%);\n --skhema-border: hsl(217.2 32.6% 17.5%);\n --skhema-text: hsl(210 40% 98%);\n --skhema-text-muted: hsl(215 20.2% 65.1%);\n --skhema-accent: hsl(217.2 32.6% 17.5%);\n}\n\n/* Main component card - inspired by your design */\n.skhema-insight-card {\n position: relative;\n background: var(--skhema-card);\n border: 1px solid var(--skhema-border);\n border-radius: calc(var(--skhema-radius) * 2);\n padding: 16px;\n box-shadow: var(--skhema-shadow);\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n max-width: 600px;\n margin: 8px 0;\n}\n\n.skhema-insight-card:hover {\n box-shadow: var(--skhema-shadow-lg);\n border-color: var(--skhema-primary);\n transform: translateY(-1px);\n}\n\n/* Header section with contributor info */\n.skhema-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 12px;\n gap: 12px;\n}\n\n.skhema-contributor {\n display: flex;\n align-items: center;\n gap: 8px;\n flex: 1;\n}\n\n.skhema-avatar {\n width: 32px;\n height: 32px;\n border-radius: 50%;\n background: var(--skhema-gradient);\n display: flex;\n align-items: center;\n justify-content: center;\n font-weight: 600;\n font-size: 14px;\n color: white;\n flex-shrink: 0;\n}\n\n.skhema-contributor-info {\n min-width: 0;\n flex: 1;\n}\n\n.skhema-contributor-name {\n font-weight: 500;\n font-size: 14px;\n color: var(--skhema-text);\n margin: 0;\n line-height: 1.2;\n}\n\n.skhema-contributor-role {\n font-size: 12px;\n color: var(--skhema-text-muted);\n margin: 0;\n line-height: 1.2;\n}\n\n/* Element type badge */\n.skhema-element-badge {\n display: inline-flex;\n align-items: center;\n padding: 4px 8px;\n background: var(--skhema-accent);\n border: 1px solid var(--skhema-border);\n border-radius: var(--skhema-radius);\n font-size: 11px;\n font-weight: 500;\n color: var(--skhema-text-muted);\n text-transform: capitalize;\n white-space: nowrap;\n flex-shrink: 0;\n}\n\n/* Content section */\n.skhema-content {\n margin: 12px 0 16px 0;\n padding: 0;\n}\n\n.skhema-content-text {\n font-size: 15px;\n line-height: 1.6;\n color: var(--skhema-text);\n margin: 0;\n font-style: italic;\n position: relative;\n}\n\n.skhema-content-text::before {\n content: '\"';\n color: var(--skhema-primary);\n font-size: 20px;\n font-weight: 600;\n margin-right: 4px;\n}\n\n.skhema-content-text::after {\n content: '\"';\n color: var(--skhema-primary);\n font-size: 20px;\n font-weight: 600;\n margin-left: 4px;\n}\n\n/* Footer section */\n.skhema-footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n padding-top: 12px;\n border-top: 1px solid var(--skhema-border);\n}\n\n.skhema-attribution {\n font-size: 11px;\n color: var(--skhema-text-muted);\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.skhema-attribution a {\n color: var(--skhema-primary);\n text-decoration: none;\n font-weight: 500;\n}\n\n.skhema-attribution a:hover {\n text-decoration: underline;\n}\n\n/* Save button with gradient and arrow */\n.skhema-save-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n background: var(--skhema-gradient);\n color: white;\n border: none;\n padding: 8px 16px;\n border-radius: var(--skhema-radius);\n font-size: 13px;\n font-weight: 500;\n text-decoration: none;\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n box-shadow: var(--skhema-shadow);\n white-space: nowrap;\n}\n\n.skhema-save-btn:hover {\n transform: translateY(-1px);\n box-shadow: var(--skhema-shadow-md);\n}\n\n.skhema-save-btn:active {\n transform: translateY(0);\n}\n\n.skhema-save-btn:focus {\n outline: 2px solid var(--skhema-primary);\n outline-offset: 2px;\n}\n\n.skhema-save-btn::after {\n content: '→';\n transition: transform 0.2s ease;\n}\n\n.skhema-save-btn:hover::after {\n transform: translateX(2px);\n}\n\n/* Error state */\n.skhema-error {\n background: hsl(0 93% 94%);\n border: 1px solid hsl(0 84% 60%);\n color: hsl(0 74% 42%);\n padding: 12px;\n border-radius: var(--skhema-radius);\n font-size: 13px;\n}\n\n.skhema-error-title {\n font-weight: 600;\n margin-bottom: 8px;\n}\n\n.skhema-error-list {\n margin: 0;\n padding-left: 16px;\n}\n\n/* Loading state */\n.skhema-loading {\n background: var(--skhema-accent);\n border: 1px solid var(--skhema-border);\n padding: 12px;\n border-radius: var(--skhema-radius);\n color: var(--skhema-text-muted);\n font-size: 13px;\n text-align: center;\n}\n\n.skhema-loading::after {\n content: '...';\n animation: loading 1.5s infinite;\n}\n\n@keyframes loading {\n 0%, 33% { content: '...'; }\n 66% { content: '..'; }\n 100% { content: '.'; }\n}\n\n/* Responsive design */\n@media (max-width: 640px) {\n .skhema-insight-card {\n margin: 4px 0;\n padding: 12px;\n }\n \n .skhema-header {\n flex-direction: column;\n align-items: flex-start;\n gap: 8px;\n }\n \n .skhema-footer {\n flex-direction: column;\n align-items: stretch;\n gap: 8px;\n }\n \n .skhema-save-btn {\n justify-content: center;\n }\n}\n\n/* Accessibility */\n@media (prefers-reduced-motion: reduce) {\n .skhema-insight-card,\n .skhema-save-btn {\n transition: none;\n }\n \n .skhema-save-btn::after {\n transition: none;\n }\n \n .skhema-save-btn:hover::after {\n transform: none;\n }\n}\n\n.skhema-structured-data {\n display: none !important;\n}\n`;\n\nexport class SkhemaElement extends HTMLElement {\n private shadow: ShadowRoot;\n private contentData: ContentData | null = null;\n private componentConnected = false;\n\n constructor() {\n super();\n this.shadow = this.attachShadow({ mode: 'closed' });\n }\n\n static get observedAttributes(): (keyof SkhemaElementAttributes)[] {\n return ['element-type', 'contributor-id', 'content', 'source-url', 'theme', 'track-analytics'];\n }\n\n connectedCallback() {\n if (this.componentConnected) return;\n this.componentConnected = true;\n \n try {\n this.render();\n this.trackLoad();\n } catch (error) {\n this.renderError('Failed to initialize component', error);\n }\n }\n\n attributeChangedCallback(_name: keyof SkhemaElementAttributes, oldValue: string | null, newValue: string | null) {\n if (oldValue !== newValue && this.componentConnected) {\n this.render();\n }\n }\n\n private render() {\n const validation = validateAttributes(this as HTMLElement);\n \n if (!validation.isValid) {\n this.renderError('Invalid component attributes', validation.errors);\n return;\n }\n\n const content = this.getContent();\n if (!content.trim()) {\n this.renderError('Component requires content', ['Add content between the opening and closing tags, or use the content attribute']);\n return;\n }\n\n this.contentData = {\n contributor_id: validation.contributorId!,\n element_type: validation.elementType!,\n content: content,\n content_hash: generateContentHash(content),\n source_url: this.getAttribute('source-url') || window.location.href,\n timestamp: new Date().toISOString(),\n page_title: document.title\n };\n\n this.renderContent();\n this.addStructuredData();\n }\n\n private getContent(): string {\n return this.getAttribute('content') || this.textContent || '';\n }\n\n private renderContent() {\n if (!this.contentData) return;\n\n const { element_type, contributor_id, content } = this.contentData;\n const label = getElementTypeLabel(element_type);\n const redirectUrl = generateRedirectUrl(content, element_type, contributor_id);\n const theme = this.getAttribute('theme') || 'auto';\n\n // Generate contributor display name and initials\n const displayName = this.formatContributorName(contributor_id);\n const initials = this.getInitials(displayName);\n\n // Set ARIA attributes on host element\n const ariaAttrs = createAriaAttributes(element_type);\n Object.entries(ariaAttrs).forEach(([key, value]) => {\n this.setAttribute(key, value);\n });\n\n this.shadow.innerHTML = `\n <style>${styles}</style>\n \n <div class=\"skhema-insight-card\" data-theme=\"${theme}\">\n <div class=\"skhema-header\">\n <div class=\"skhema-contributor\">\n <div class=\"skhema-avatar\" title=\"${displayName}\">\n ${initials}\n </div>\n <div class=\"skhema-contributor-info\">\n <div class=\"skhema-contributor-name\">${displayName}</div>\n <div class=\"skhema-contributor-role\">Strategy Insight</div>\n </div>\n </div>\n <div class=\"skhema-element-badge\" title=\"${label}\">\n ${label}\n </div>\n </div>\n \n <div class=\"skhema-content\">\n <div class=\"skhema-content-text\">${content}</div>\n </div>\n \n <div class=\"skhema-footer\">\n <div class=\"skhema-attribution\">\n Powered by <a href=\"https://skhema.com\" target=\"_blank\" rel=\"noopener noreferrer\">Skhema</a>\n </div>\n <a href=\"${redirectUrl}\" \n class=\"skhema-save-btn\" \n target=\"_blank\"\n rel=\"noopener noreferrer\"\n title=\"Save this insight to Skhema\">\n Save to Skhema\n </a>\n </div>\n </div>\n `;\n\n // Add click event listener\n const saveBtn = this.shadow.querySelector('.skhema-save-btn') as HTMLAnchorElement;\n if (saveBtn) {\n saveBtn.addEventListener('click', (event) => {\n this.handleSaveClick(event);\n });\n }\n }\n\n private formatContributorName(contributorId: string): string {\n // Convert contributor_id to display name\n return contributorId\n .split(/[_-]/)\n .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join(' ');\n }\n\n private getInitials(name: string): string {\n return name\n .split(' ')\n .map(word => word.charAt(0))\n .join('')\n .toUpperCase()\n .substring(0, 2);\n }\n\n private renderError(title: string, errors: string | string[] | any) {\n const errorList = Array.isArray(errors) ? errors : [String(errors)];\n \n this.shadow.innerHTML = `\n <style>${styles}</style>\n \n <div class=\"skhema-insight-card\">\n <div class=\"skhema-error\">\n <div class=\"skhema-error-title\">Skhema Component Error: ${title}</div>\n <ul class=\"skhema-error-list\">\n ${errorList.map(error => `<li>${error}</li>`).join('')}\n </ul>\n </div>\n </div>\n `;\n\n // Dispatch error event\n this.dispatchEvent(new CustomEvent('skhema:error', {\n detail: { error: title, details: errors },\n bubbles: true\n }));\n }\n\n private addStructuredData() {\n if (!this.contentData) return;\n\n const { content, element_type, contributor_id, source_url } = this.contentData;\n \n // Add structured data to the document head\n const structuredData = generateStructuredData(content, element_type, contributor_id, source_url);\n const script = document.createElement('script');\n script.type = 'application/ld+json';\n script.textContent = JSON.stringify(structuredData);\n script.className = 'skhema-structured-data';\n document.head.appendChild(script);\n\n // Add meta tags for SEO\n const metaDiv = document.createElement('div');\n metaDiv.innerHTML = createMetaTags(content, element_type, contributor_id);\n metaDiv.className = 'skhema-structured-data';\n document.body.appendChild(metaDiv);\n }\n\n private async trackLoad() {\n if (!shouldTrackAnalytics(this as HTMLElement) || !this.contentData) return;\n\n const analytics: EmbedAnalytics = {\n contributorId: this.contentData.contributor_id,\n elementType: this.contentData.element_type,\n contentHash: this.contentData.content_hash,\n pageUrl: window.location.href,\n pageTitle: document.title,\n timestamp: Date.now(),\n userAgent: navigator.userAgent\n };\n\n await trackEmbedLoad(analytics);\n\n // Dispatch load event\n this.dispatchEvent(new CustomEvent('skhema:load', {\n detail: analytics,\n bubbles: true\n }));\n }\n\n private async handleSaveClick(_event: Event) {\n if (!this.contentData) return;\n\n // Track click analytics\n if (shouldTrackAnalytics(this as HTMLElement)) {\n await trackClick(this.contentData);\n }\n\n // Dispatch click event\n this.dispatchEvent(new CustomEvent('skhema:click', {\n detail: this.contentData,\n bubbles: true\n }));\n }\n\n // Public API methods\n public getContentData(): ContentData | null {\n return this.contentData;\n }\n\n public refresh(): void {\n this.render();\n }\n}\n\n// Type augmentation for custom events and JSX elements\ndeclare global {\n interface HTMLElementEventMap extends SkhemaElementEventMap {}\n \n namespace JSX {\n interface IntrinsicElements {\n 'skhema-element': Partial<SkhemaElementAttributes> & {\n [key: string]: any;\n };\n }\n }\n}","// CDN bundle entry point - automatically registers the component\nimport { SkhemaElement } from './components/SkhemaElement.js';\n\n// Register the custom element for CDN usage\nif (!customElements.get('skhema-element')) {\n customElements.define('skhema-element', SkhemaElement as CustomElementConstructor);\n}\n\n// Expose on global for UMD builds\nif (typeof window !== 'undefined') {\n (window as any).SkhemaElement = SkhemaElement;\n}\n\nexport { SkhemaElement };"],"names":["ELEMENT_TYPES","KEY_CHALLENGE","value","label","acronym","SUPPORTING_FACT","ASSOCIATED_IMPACT","GUIDING_POLICY","COMPETITOR_MOVE","SCOPE","CONSTRAINT","SOLUTION_ALTERNATIVE","ASSUMPTION_HYPOTHESIS","EXPERIMENT","ACTION","INVESTMENT","ESTIMATE","BASELINE","OUTCOME","PERFORMANCE_VARIABLE","CAPABILITY","SYSTEM","PRINCIPLE","isValidElementType","elementType","Object","values","map","type","includes","getElementTypeLabel","find","t","shouldTrackAnalytics","element","getAttribute","generateContentHash","content","hash","cleanContent","trim","substring","i","length","charCodeAt","Math","abs","toString","generateRedirectUrl","contributorId","options","baseUrl","contentHash","sourceUrl","encodeURIComponent","window","location","href","timestamp","Date","now","URLSearchParams","source","utm_source","utmSource","utm_medium","utmMedium","utm_campaign","utmCampaign","utm_content","styles","SkhemaElement","HTMLElement","constructor","super","this","contentData","componentConnected","shadow","attachShadow","mode","observedAttributes","connectedCallback","render","trackLoad","error","renderError","attributeChangedCallback","_name","oldValue","newValue","validation","errors","validTypes","join","push","isValid","validateAttributes","getContent","contributor_id","element_type","content_hash","source_url","toISOString","page_title","document","title","renderContent","addStructuredData","textContent","redirectUrl","theme","displayName","formatContributorName","initials","getInitials","ariaAttrs","role","entries","forEach","key","setAttribute","innerHTML","saveBtn","querySelector","addEventListener","event","handleSaveClick","split","word","charAt","toUpperCase","slice","toLowerCase","name","errorList","Array","isArray","String","dispatchEvent","CustomEvent","detail","details","bubbles","structuredData","text","analysisType","category","contributor","url","provider","isPartOf","dateCreated","platform","generateStructuredData","script","createElement","JSON","stringify","className","head","appendChild","metaDiv","createMetaTags","body","analytics","pageUrl","pageTitle","userAgent","navigator","async","data","page_url","user_agent","sendBeacon","fetch","method","credentials","keepalive","catch","console","debug","trackEmbedLoad","_event","blob","Blob","headers","trackClick","getContentData","refresh","customElements","get","define"],"mappings":"yPAAO,MAAMA,EAAgB,CACzBC,cAAe,CACXC,MAAO,gBACPC,MAAO,gBACPC,QAAS,MAEbC,gBAAiB,CACbH,MAAO,kBACPC,MAAO,kBACPC,QAAS,MAEbE,kBAAmB,CACfJ,MAAO,oBACPC,MAAO,oBACPC,QAAS,MAEbG,eAAgB,CACZL,MAAO,iBACPC,MAAO,iBACPC,QAAS,MAEbI,gBAAiB,CACbN,MAAO,kBACPC,MAAO,kBACPC,QAAS,MAEbK,MAAO,CACHP,MAAO,QACPC,MAAO,QACPC,QAAS,MAEbM,WAAY,CACRR,MAAO,aACPC,MAAO,aACPC,QAAS,MAEbO,qBAAsB,CAClBT,MAAO,uBACPC,MAAO,uBACPC,QAAS,MAEbQ,sBAAuB,CACnBV,MAAO,wBACPC,MAAO,wBACPC,QAAS,MAEbS,WAAY,CACRX,MAAO,aACPC,MAAO,aACPC,QAAS,MAEbU,OAAQ,CACJZ,MAAO,SACPC,MAAO,SACPC,QAAS,MAEbW,WAAY,CACRb,MAAO,aACPC,MAAO,aACPC,QAAS,MAEbY,SAAU,CACNd,MAAO,WACPC,MAAO,WACPC,QAAS,MAEba,SAAU,CACNf,MAAO,WACPC,MAAO,WACPC,QAAS,MAEbc,QAAS,CACLhB,MAAO,UACPC,MAAO,UACPC,QAAS,MAEbe,qBAAsB,CAClBjB,MAAO,uBACPC,MAAO,uBACPC,QAAS,MAEbgB,WAAY,CACRlB,MAAO,aACPC,MAAO,aACPC,QAAS,MAEbiB,OAAQ,CACJnB,MAAO,SACPC,MAAO,SACPC,QAAS,MAEbkB,UAAW,CACPpB,MAAO,YACPC,MAAO,YACPC,QAAS,OC3FV,SAASmB,EAAmBC,GAEjC,OADmBC,OAAOC,OAAO1B,GAAe2B,IAAIC,GAAQA,EAAK1B,OAC/C2B,SAASL,EAC7B,CAkCO,SAASM,EAAoBN,GAClC,MAAMI,EAAOH,OAAOC,OAAO1B,GAAe+B,KAAKC,GAAKA,EAAE9B,QAAUsB,GAChE,aAAOI,WAAMzB,QAASqB,CACxB,CC0BO,SAASS,EAAqBC,GAEnC,MAA0B,UADHA,EAAQC,aAAa,kBAE9C,CCxEO,SAASC,EAAoBC,GAElC,IAAIC,EAAO,EACX,MAAMC,EAAeF,EAAQG,OAAOC,UAAU,EAAG,KAEjD,IAAA,IAASC,EAAI,EAAGA,EAAIH,EAAaI,OAAQD,IAAK,CAE5CJ,GAASA,GAAQ,GAAKA,EADTC,EAAaK,WAAWF,GAErCJ,GAAcA,CAChB,CAEA,OAAOO,KAAKC,IAAIR,GAAMS,SAAS,IAAIN,UAAU,EAAG,GAClD,CCoBO,SAASO,EACdX,EACAb,EACAyB,EACAC,EAKI,CAAA,GAEJ,MAAMC,EAAUD,EAAQC,SAAW,8BAC7BC,EAAchB,EAAoBC,GAClCgB,EAAYC,mBAAmBC,OAAOC,SAASC,MAC/CC,EAAYC,KAAKC,MAYvB,MAAO,GAAGT,oBAA0BF,kBAA8BzB,kBAA4B4B,KAV/E,IAAIS,gBAAgB,CACjCC,OAAQT,EACRrB,EAAG0B,EAAUX,WACbgB,WAAYb,EAAQc,WAAa,gBACjCC,WAAYf,EAAQgB,WAAa,WACjCC,aAAcjB,EAAQkB,aAAe5C,EACrC6C,YAAapB,IAIqGF,YAEtH,CCrDA,MAAMuB,EAAS,ylNAwTR,MAAMC,UAAsBC,YAKjC,WAAAC,GACEC,QAJFC,KAAQC,YAAkC,KAC1CD,KAAQE,oBAAqB,EAI3BF,KAAKG,OAASH,KAAKI,aAAa,CAAEC,KAAM,UAC1C,CAEA,6BAAWC,GACT,MAAO,CAAC,eAAgB,iBAAkB,UAAW,aAAc,QAAS,kBAC9E,CAEA,iBAAAC,GACE,IAAIP,KAAKE,mBAAT,CACAF,KAAKE,oBAAqB,EAE1B,IACEF,KAAKQ,SACLR,KAAKS,WACP,OAASC,GACPV,KAAKW,YAAY,iCAAkCD,EACrD,CAR6B,CAS/B,CAEA,wBAAAE,CAAyBC,EAAsCC,EAAyBC,GAClFD,IAAaC,GAAYf,KAAKE,oBAChCF,KAAKQ,QAET,CAEQ,MAAAA,GACN,MAAMQ,EJxVH,SAA4BzD,GAMjC,MAAM0D,EAAmB,GAEnBpE,EAAcU,EAAQC,aAAa,gBACnCc,EAAgBf,EAAQC,aAAa,kBAE3C,GAAKX,GAEL,IAAYD,EAAmBC,GAAc,CAC3C,MAAMqE,EAAapE,OAAOC,OAAO1B,GAAe2B,IAAIK,GAAKA,EAAE9B,OAAO4F,KAAK,MACvEF,EAAOG,KAAK,yBAAyBvE,oBAA8BqE,IACrE,OAJED,EAAOG,KAAK,4CAYd,OANK9C,EAEsC,IAAhCA,EAAcT,OAAOG,QAC9BiD,EAAOG,KAAK,kCAFZH,EAAOG,KAAK,8CAKP,CACLC,QAA2B,IAAlBJ,EAAOjD,OAChBiD,SACApE,YAAaD,EAAmBC,GAAe,IAAMA,OAA8B,EACnFyB,cAAeA,QAAiB,EAEpC,CI0TuBgD,CAAmBtB,MAEtC,IAAKgB,EAAWK,QAEd,YADArB,KAAKW,YAAY,+BAAgCK,EAAWC,QAI9D,MAAMvD,EAAUsC,KAAKuB,aAChB7D,EAAQG,QAKbmC,KAAKC,YAAc,CACjBuB,eAAgBR,EAAW1C,cAC3BmD,aAAcT,EAAWnE,YACzBa,UACAgE,aAAcjE,EAAoBC,GAClCiE,WAAY3B,KAAKxC,aAAa,eAAiBoB,OAAOC,SAASC,KAC/DC,WAAA,IAAeC,MAAO4C,cACtBC,WAAYC,SAASC,OAGvB/B,KAAKgC,gBACLhC,KAAKiC,qBAfHjC,KAAKW,YAAY,6BAA8B,CAAC,kFAgBpD,CAEQ,UAAAY,GACN,OAAOvB,KAAKxC,aAAa,YAAcwC,KAAKkC,aAAe,EAC7D,CAEQ,aAAAF,GACN,IAAKhC,KAAKC,YAAa,OAEvB,MAAMwB,aAAEA,EAAAD,eAAcA,EAAA9D,QAAgBA,GAAYsC,KAAKC,YACjDzE,EAAQ2B,EAAoBsE,GAC5BU,EAAc9D,EAAoBX,EAAS+D,EAAcD,GACzDY,EAAQpC,KAAKxC,aAAa,UAAY,OAGtC6E,EAAcrC,KAAKsC,sBAAsBd,GACzCe,EAAWvC,KAAKwC,YAAYH,GAG5BI,EDxTD,CACLC,KAAQ,UACR,aAAc,GAJFvF,EC0T2BsE,yBDrTvC,mBAAoB,sBCsTpB3E,OAAO6F,QAAQF,GAAWG,QAAQ,EAAEC,EAAKtH,MACvCyE,KAAK8C,aAAaD,EAAKtH,KAGzByE,KAAKG,OAAO4C,UAAY,kBACbpD,yEAEsCyC,uIAGLC,sBAChCE,gIAGqCF,gLAIA7G,oBACvCA,mIAK+BkC,sQAOxByE,sPAYjB,MAAMa,EAAUhD,KAAKG,OAAO8C,cAAc,oBACtCD,GACFA,EAAQE,iBAAiB,QAAUC,IACjCnD,KAAKoD,gBAAgBD,IAG3B,CAEQ,qBAAAb,CAAsBhE,GAE5B,OAAOA,EACJ+E,MAAM,QACNrG,IAAIsG,GAAQA,EAAKC,OAAO,GAAGC,cAAgBF,EAAKG,MAAM,GAAGC,eACzDvC,KAAK,IACV,CAEQ,WAAAqB,CAAYmB,GAClB,OAAOA,EACJN,MAAM,KACNrG,IAAIsG,GAAQA,EAAKC,OAAO,IACxBpC,KAAK,IACLqC,cACA1F,UAAU,EAAG,EAClB,CAEQ,WAAA6C,CAAYoB,EAAed,GACjC,MAAM2C,EAAYC,MAAMC,QAAQ7C,GAAUA,EAAS,CAAC8C,OAAO9C,IAE3DjB,KAAKG,OAAO4C,UAAY,kBACbpD,qKAIqDoC,kEAEtD6B,EAAU5G,IAAI0D,GAAS,OAAOA,UAAcS,KAAK,2DAO3DnB,KAAKgE,cAAc,IAAIC,YAAY,eAAgB,CACjDC,OAAQ,CAAExD,MAAOqB,EAAOoC,QAASlD,GACjCmD,SAAS,IAEb,CAEQ,iBAAAnC,GACN,IAAKjC,KAAKC,YAAa,OAEvB,MAAMvC,QAAEA,EAAA+D,aAASA,EAAAD,eAAcA,EAAAG,WAAgBA,GAAe3B,KAAKC,YAG7DoE,ED1eH,SACL3G,EACAb,EACAyB,EACAI,GAEA,MAAO,CACL,WAAY,qBACZ,QAAS,kBACT4F,KAAQ5G,EACR6G,aAAgB1H,EAChB2H,SAAYrH,EAAoBN,GAChC4H,YAAenG,EACfoG,IAAOrG,EAAoBX,EAASb,EAAayB,GACjDqG,SAAY,CACV,QAAS,eACThB,KAAQ,SACRe,IAAO,sBAETE,SAAY,CACV,QAAS,UACTF,IAAOhG,GAETmG,aAAA,IAAmB7F,MAAO4C,cAC1BkD,SAAY,SAEhB,CCgd2BC,CAAuBrH,EAAS+D,EAAcD,EAAgBG,GAC/EqD,EAASlD,SAASmD,cAAc,UACtCD,EAAO/H,KAAO,sBACd+H,EAAO9C,YAAcgD,KAAKC,UAAUd,GACpCW,EAAOI,UAAY,yBACnBtD,SAASuD,KAAKC,YAAYN,GAG1B,MAAMO,EAAUzD,SAASmD,cAAc,OACvCM,EAAQxC,UDxbL,SACLrF,EACAb,EACAyB,GAIA,MAAO,2IAEsCzB,6CACRa,oDACOY,iDAN9BnB,EAAoBN,yEAWpC,CCwawB2I,CAAe9H,EAAS+D,EAAcD,GAC1D+D,EAAQH,UAAY,yBACpBtD,SAAS2D,KAAKH,YAAYC,EAC5B,CAEA,eAAc9E,GACZ,IAAKnD,EAAqB0C,QAAyBA,KAAKC,YAAa,OAErE,MAAMyF,EAA4B,CAChCpH,cAAe0B,KAAKC,YAAYuB,eAChC3E,YAAamD,KAAKC,YAAYwB,aAC9BhD,YAAauB,KAAKC,YAAYyB,aAC9BiE,QAAS/G,OAAOC,SAASC,KACzB8G,UAAW9D,SAASC,MACpBhD,UAAWC,KAAKC,MAChB4G,UAAWC,UAAUD,iBHngB3BE,eAAqCL,GACnC,IACE,MAAMM,EAAO,IAAI9G,gBAAgB,CAC/BsC,eAAgBkE,EAAUpH,cAC1BmD,aAAciE,EAAU7I,YACxB6E,aAAcgE,EAAUjH,YACxBwH,SAAUP,EAAUC,QACpB9D,WAAY6D,EAAUE,WAAa,GACnC7G,UAAW2G,EAAU3G,UAAUX,WAC/B8H,WAAYR,EAAUG,WAAa,KAIjCC,UAAUK,WACZL,UAAUK,WAAW,sDAAuDH,GAG5EI,MAAM,sDAAuD,CAC3DC,OAAQ,OACRZ,KAAMO,EACNM,YAAa,OACbC,WAAW,IACVC,MAAM,OAIb,OAAS9F,GAEP+F,QAAQC,MAAM,6BAA8BhG,EAC9C,CACF,CGweUiG,CAAejB,GAGrB1F,KAAKgE,cAAc,IAAIC,YAAY,cAAe,CAChDC,OAAQwB,EACRtB,SAAS,IAEb,CAEA,qBAAchB,CAAgBwD,GACvB5G,KAAKC,cAGN3C,EAAqB0C,aHnf7B+F,eAAiC9F,GAC/B,IACE,MAAM+F,EAAO,CACXxE,eAAgBvB,EAAYuB,eAC5BC,aAAcxB,EAAYwB,aAC1BC,aAAczB,EAAYyB,aAC1BC,WAAY1B,EAAY0B,WACxB5C,UAAWkB,EAAYlB,WAGzB,GAAI+G,UAAUK,WAAY,CACxB,MAAMU,EAAO,IAAIC,KAAK,CAAC5B,KAAKC,UAAUa,IAAQ,CAC5C/I,KAAM,qBAER6I,UAAUK,WACR,sDACAU,EAEJ,MACET,MAAM,sDAAuD,CAC3DC,OAAQ,OACRU,QAAS,CAAE,eAAgB,oBAC3BtB,KAAMP,KAAKC,UAAUa,GACrBM,YAAa,OACbC,WAAW,IACVC,MAAM,OAIb,OAAS9F,GACP+F,QAAQC,MAAM,yBAA0BhG,EAC1C,CACF,CGodYsG,CAAWhH,KAAKC,aAIxBD,KAAKgE,cAAc,IAAIC,YAAY,eAAgB,CACjDC,OAAQlE,KAAKC,YACbmE,SAAS,KAEb,CAGO,cAAA6C,GACL,OAAOjH,KAAKC,WACd,CAEO,OAAAiH,GACLlH,KAAKQ,QACP,ECpiBG2G,eAAeC,IAAI,mBACtBD,eAAeE,OAAO,iBAAkBzH,GAIpB,oBAAXhB,SACRA,OAAegB,cAAgBA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skhema/web-component",
3
- "version": "0.0.10",
3
+ "version": "0.0.12",
4
4
  "description": "Embeddable web component for integration with Skhema application.",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.es.js",