@scaleflex/uploader 0.2.7 → 0.2.8

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.
Files changed (110) hide show
  1. package/.claude/skills/integrate-uploader/SKILL.md +4 -3
  2. package/CHANGELOG.md +16 -1
  3. package/dist/components/actions-bar.d.ts +2 -0
  4. package/dist/components/actions-bar.d.ts.map +1 -1
  5. package/dist/components/file-item.d.ts +6 -0
  6. package/dist/components/file-item.d.ts.map +1 -1
  7. package/dist/components/toast.d.ts +18 -0
  8. package/dist/components/toast.d.ts.map +1 -0
  9. package/dist/define.cjs +1 -1
  10. package/dist/define.js +1 -1
  11. package/dist/engine/index.d.ts +1 -0
  12. package/dist/engine/index.d.ts.map +1 -1
  13. package/dist/engine/tus-upload.d.ts +52 -0
  14. package/dist/engine/tus-upload.d.ts.map +1 -0
  15. package/dist/engine/upload-engine.d.ts +14 -0
  16. package/dist/engine/upload-engine.d.ts.map +1 -1
  17. package/dist/engine/xhr-upload.d.ts.map +1 -1
  18. package/dist/events/public-events.d.ts +2 -0
  19. package/dist/events/public-events.d.ts.map +1 -1
  20. package/dist/index-D7hE18PK.js +3541 -0
  21. package/dist/index-DuX47Oy3.cjs +1625 -0
  22. package/dist/index.cjs +1 -1
  23. package/dist/index.d.ts +3 -2
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +1 -1
  26. package/dist/metadata/bulk/bulk-meta-diff-view.d.ts +17 -0
  27. package/dist/metadata/bulk/bulk-meta-diff-view.d.ts.map +1 -0
  28. package/dist/metadata/bulk/bulk-meta-op-bar.d.ts +38 -0
  29. package/dist/metadata/bulk/bulk-meta-op-bar.d.ts.map +1 -0
  30. package/dist/metadata/bulk/bulk-meta-row.d.ts +35 -0
  31. package/dist/metadata/bulk/bulk-meta-row.d.ts.map +1 -0
  32. package/dist/metadata/bulk/bulk-meta-sidebar.d.ts +20 -0
  33. package/dist/metadata/bulk/bulk-meta-sidebar.d.ts.map +1 -0
  34. package/dist/metadata/bulk/bulk-meta-table.d.ts +20 -0
  35. package/dist/metadata/bulk/bulk-meta-table.d.ts.map +1 -0
  36. package/dist/metadata/bulk/bulk-metadata-modal.d.ts +46 -0
  37. package/dist/metadata/bulk/bulk-metadata-modal.d.ts.map +1 -0
  38. package/dist/metadata/bulk/bulk-metadata.styles.d.ts +7 -0
  39. package/dist/metadata/bulk/bulk-metadata.styles.d.ts.map +1 -0
  40. package/dist/metadata/bulk/bulk-operations.d.ts +14 -0
  41. package/dist/metadata/bulk/bulk-operations.d.ts.map +1 -0
  42. package/dist/metadata/bulk/diff-utils.d.ts +19 -0
  43. package/dist/metadata/bulk/diff-utils.d.ts.map +1 -0
  44. package/dist/metadata/bulk/index.d.ts +3 -0
  45. package/dist/metadata/bulk/index.d.ts.map +1 -0
  46. package/dist/metadata/field-type-icons.d.ts +4 -0
  47. package/dist/metadata/field-type-icons.d.ts.map +1 -0
  48. package/dist/metadata/fields/boolean-field.d.ts +17 -0
  49. package/dist/metadata/fields/boolean-field.d.ts.map +1 -0
  50. package/dist/metadata/fields/date-field.d.ts +10 -0
  51. package/dist/metadata/fields/date-field.d.ts.map +1 -0
  52. package/dist/metadata/fields/field-base.d.ts +14 -0
  53. package/dist/metadata/fields/field-base.d.ts.map +1 -0
  54. package/dist/metadata/fields/geo-point-field.d.ts +10 -0
  55. package/dist/metadata/fields/geo-point-field.d.ts.map +1 -0
  56. package/dist/metadata/fields/multi-select-field.d.ts +23 -0
  57. package/dist/metadata/fields/multi-select-field.d.ts.map +1 -0
  58. package/dist/metadata/fields/number-field.d.ts +10 -0
  59. package/dist/metadata/fields/number-field.d.ts.map +1 -0
  60. package/dist/metadata/fields/select-field.d.ts +21 -0
  61. package/dist/metadata/fields/select-field.d.ts.map +1 -0
  62. package/dist/metadata/fields/tags-field.d.ts +29 -0
  63. package/dist/metadata/fields/tags-field.d.ts.map +1 -0
  64. package/dist/metadata/fields/text-field.d.ts +9 -0
  65. package/dist/metadata/fields/text-field.d.ts.map +1 -0
  66. package/dist/metadata/fields/textarea-field.d.ts +11 -0
  67. package/dist/metadata/fields/textarea-field.d.ts.map +1 -0
  68. package/dist/metadata/index.d.ts +9 -0
  69. package/dist/metadata/index.d.ts.map +1 -0
  70. package/dist/metadata/metadata-field-edit.d.ts +16 -0
  71. package/dist/metadata/metadata-field-edit.d.ts.map +1 -0
  72. package/dist/metadata/metadata-field-view.d.ts +10 -0
  73. package/dist/metadata/metadata-field-view.d.ts.map +1 -0
  74. package/dist/metadata/metadata-field.d.ts +22 -0
  75. package/dist/metadata/metadata-field.d.ts.map +1 -0
  76. package/dist/metadata/metadata-form.d.ts +15 -0
  77. package/dist/metadata/metadata-form.d.ts.map +1 -0
  78. package/dist/metadata/metadata-panel.d.ts +37 -0
  79. package/dist/metadata/metadata-panel.d.ts.map +1 -0
  80. package/dist/metadata/metadata.styles.d.ts +11 -0
  81. package/dist/metadata/metadata.styles.d.ts.map +1 -0
  82. package/dist/metadata/schema/required-fields.d.ts +24 -0
  83. package/dist/metadata/schema/required-fields.d.ts.map +1 -0
  84. package/dist/metadata/schema/schema-parser.d.ts +3 -0
  85. package/dist/metadata/schema/schema-parser.d.ts.map +1 -0
  86. package/dist/metadata/schema/schema-service.d.ts +5 -0
  87. package/dist/metadata/schema/schema-service.d.ts.map +1 -0
  88. package/dist/metadata/schema/schema.types.d.ts +112 -0
  89. package/dist/metadata/schema/schema.types.d.ts.map +1 -0
  90. package/dist/metadata/schema/validation.d.ts +4 -0
  91. package/dist/metadata/schema/validation.d.ts.map +1 -0
  92. package/dist/metadata/schema/value-transforms.d.ts +5 -0
  93. package/dist/metadata/schema/value-transforms.d.ts.map +1 -0
  94. package/dist/metadata/tags/tag-utils.d.ts +6 -0
  95. package/dist/metadata/tags/tag-utils.d.ts.map +1 -0
  96. package/dist/metadata/tags/tags-autocomplete.d.ts +7 -0
  97. package/dist/metadata/tags/tags-autocomplete.d.ts.map +1 -0
  98. package/dist/{provider-browser-CXFOnoRc.cjs → provider-browser-D9DOIUnq.cjs} +1 -1
  99. package/dist/{provider-browser-B33dyOPN.js → provider-browser-qRo0t4Wt.js} +1 -1
  100. package/dist/{search-provider-browser-gtlEKi5h.js → search-provider-browser-DarbREgH.js} +1 -1
  101. package/dist/{search-provider-browser-CIRU1j5X.cjs → search-provider-browser-xP28_tO-.cjs} +1 -1
  102. package/dist/sfx-uploader-BqMTQWrE.cjs +4913 -0
  103. package/dist/{sfx-uploader-BBQinsQB.js → sfx-uploader-D9z-E7SI.js} +4209 -1230
  104. package/dist/sfx-uploader.d.ts +53 -6
  105. package/dist/sfx-uploader.d.ts.map +1 -1
  106. package/dist/store/store.types.d.ts +3 -1
  107. package/dist/store/store.types.d.ts.map +1 -1
  108. package/dist/test-utils.d.ts.map +1 -1
  109. package/package.json +3 -2
  110. package/dist/sfx-uploader-DNjq8DwX.cjs +0 -4649
@@ -0,0 +1,1625 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("lit"),d=require("lit/decorators.js"),je=require("./sfx-uploader-BqMTQWrE.cjs");function ie(a,e){const t=(e==null?void 0:e.language)??"en",s=a.model??[],i=a.store??{},n=s.find(u=>u.applies_to==="FILES");let r=(n==null?void 0:n.groups)??[];if(Array.isArray(e==null?void 0:e.fields)){const u=new Set(e.fields);r=r.map(b=>({...b,fields:b.fields.filter(g=>u.has(g.ckey))})).filter(b=>b.fields.length>0)}r=r.map(u=>({...u,fields:u.fields.filter(b=>!b.hide)})).filter(u=>u.fields.length>0);const l=r.flatMap(u=>u.fields),c=new Map(l.map(u=>[u.key,u])),p=i.force_filling_metadata_on_upload===!0,h=i.regional_variants_groups??[];return{groups:r,fields:l,fieldsByKey:c,forceFillingOnUpload:p,regionalVariantsGroups:h,language:t}}const Re="https://hub.scaleflex.com/api",N=new Map,L=new Map;async function Ne(a,e,t,s){const i=N.get(t);if(i)return i;const n=L.get(t);if(n)return n;if(s!=null&&s.rawMetadata){const l=ie(s.rawMetadata,s);return N.set(t,l),l}const r=Ke(e,t,s);L.set(t,r);try{const l=await r;return N.set(t,l),l}finally{L.delete(t)}}async function Ke(a,e,t){var p,h,u;const i=`${(t==null?void 0:t.hubApiBase)??Re}/project/${encodeURIComponent(e)}`,n=(t==null?void 0:t.hubHeaders)??a,r=await fetch(i,{headers:n});if(!r.ok)throw new Error(`Failed to fetch metadata schema (HTTP ${r.status})`);const l=await r.json(),c=((h=(p=l.data)==null?void 0:p.project)==null?void 0:h.data)??((u=l.project)==null?void 0:u.data);if(!(c!=null&&c.metadata))throw new Error("No metadata in project response");return ie(c.metadata,t)}function Ve(a){var e;a?(N.delete(a),(e=L.get(a))==null||e.catch(()=>{}),L.delete(a)):(N.clear(),L.clear())}function se(a,e,t){let s=e;switch(a.regional_variants_group_uuid&&s!=null&&typeof s=="object"&&!Array.isArray(s)&&(s=s[t??"en"]),a.type){case"geopoint":return Me(s);case"boolean":return s===!0?"true":s===!1?"false":"null";case"date":return s?new Date(s):null;case"decimal2":return s!=null?String(s):"";case"tags":return Array.isArray(s)?s.map(i=>typeof i=="string"?{value:i,label:i}:i):[];case"multi-select":return s||[];default:return s??""}}function K(a,e,t,s){var n;let i;switch(a.type){case"geopoint":{const r=e;!r||r.latitude===""||r.latitude==null||r.longitude===""||r.longitude==null?i=null:i=`(${r.latitude},${r.longitude})`;break}case"boolean":e==="true"?i=!0:e==="false"?i=!1:i=null;break;case"date":{if(!e)i=null;else{const r=e instanceof Date?e:new Date(e),l=r.getFullYear(),c=String(r.getMonth()+1).padStart(2,"0"),p=String(r.getDate()).padStart(2,"0");i=`${l}-${c}-${p}`}break}case"tags":i=Array.isArray(e)?e.map(r=>(r==null?void 0:r.label)??""):[];break;case"select-one":i=e===""?null:e;break;case"numeric":{if(e===""||e==null){i=null;break}const r=Number(e);i=Number.isFinite(r)?Math.round(r):null;break}case"decimal2":{if(e===""||e==null){i=null;break}const r=Number(e);i=Number.isFinite(r)?r:null;break}default:i=e}if(a.regional_variants_group_uuid){const r=s??"en";return{...((n=t==null?void 0:t.meta)==null?void 0:n[a.key])??{},[r]:i}}return i}function Me(a){if(typeof a=="string"){const e=/\(([^)]+)\)/.exec(a);if(e){const t=e[1].split(",");if(t.length===2)return{latitude:t[0].trim(),longitude:t[1].trim()}}}return{latitude:"",longitude:""}}function re(a,e,t){var i;if((((i=t==null?void 0:t.requiredFields)==null?void 0:i.includes(a.ckey))||a.required===1)&&y(e))return`${a.title} is required`;if(y(e))return null;switch(a.type){case"numeric":{const n=Number(e);if(!Number.isFinite(n))return"Must be a valid number";if(!Number.isInteger(n))return"Must be an integer";if(n<-1999999999||n>1999999999)return"Value out of range (±1,999,999,999)";break}case"decimal2":{const n=Number(e);if(!Number.isFinite(n))return"Must be a valid number";if(!/^\-?\d*\.?\d{0,2}$/.test(String(e)))return"Maximum 2 decimal places";if(n<-999999999999e-2||n>999999999999e-2)return"Value out of range (±9,999,999,999.99)";break}case"geopoint":{const n=e,r=n.latitude!==""&&n.latitude!=null,l=n.longitude!==""&&n.longitude!=null;if(r!==l)return"Both latitude and longitude are required";if(r&&l){const c=Number(n.latitude),p=Number(n.longitude);if(!Number.isFinite(c)||c<-90||c>90)return"Latitude must be between -90 and 90";if(!Number.isFinite(p)||p<-180||p>180)return"Longitude must be between -180 and 180"}break}case"attachment-uri":{try{const n=new URL(e);if(!["http:","https:"].includes(n.protocol))return"Only http and https URLs are allowed"}catch{return"Invalid URI"}break}}if(a.validation&&typeof e=="string")try{if(!new RegExp(a.validation).test(e))return"Value does not match expected format"}catch{}return null}function y(a){return a==null?!0:Array.isArray(a)||typeof a=="string"?a.length===0:typeof a=="object"?!Object.values(a).some(e=>e!=null&&e!==""):!a}function qe(a){return!y(a)}function Je(a,e,t){const s=new Set(["idle","queued","rejected"]),i=[...a.values()].filter(c=>s.has(c.status));if(i.length===0)return{};const n=new Set((t==null?void 0:t.requiredFields)??[]),r=e.fields.filter(c=>c.required===1||n.has(c.ckey)),l={};for(const c of r){const p=i.filter(h=>!qe(h.meta[c.key]));p.length>0&&(l[c.key]=p)}return l}function He(a,e){const t={...a};for(const s of Object.keys(e)){const i=e[s];if(i==null||i==="")continue;const n=a[s];if(Array.isArray(i))if(Array.isArray(n)){const r=new Set(n.map(c=>JSON.stringify(c))),l=[...n];for(const c of i){const p=JSON.stringify(c);r.has(p)||(r.add(p),l.push(c))}t[s]=l}else t[s]=i;else t[s]=i}return t}function Ue(a,e){let t=null,s=null,i=!1;return{search(n,r,l){if(t&&clearTimeout(t),s&&s.abort(),i=!1,!r.trim()){l([]);return}t=setTimeout(async()=>{var c;s=new AbortController;try{const p=`${a}/v5/metadata/autocomplete?q=${encodeURIComponent(r.trim())}&meta_key=_${encodeURIComponent(n)}&limit=20`,h=await fetch(p,{headers:e,signal:s.signal});if(i)return;if(!h.ok){l([]);return}const u=await h.json();if(i)return;const b=((c=u.data)==null?void 0:c.tags)??u.tags??[];l(b.map(g=>({sid:g.sid||void 0,value:g.tag||g.value||g.label||"",label:g.tag||g.label||g.value||""})))}catch{i||l([])}},200)},cancel(){i=!0,t&&clearTimeout(t),s&&s.abort()}}}var Ye=Object.defineProperty,B=(a,e,t,s)=>{for(var i=void 0,n=a.length-1,r;n>=0;n--)(r=a[n])&&(i=r(e,t,i)||i);return i&&Ye(e,t,i),i};const de=class de extends o.LitElement{constructor(){super(...arguments),this.schema=null,this.meta={},this.config=null,this.disabled=!1,this._collapsed=new Set}_toggleGroup(e){const t=new Set(this._collapsed);t.has(e)?t.delete(e):t.add(e),this._collapsed=t}_renderGroup(e){const t=!this._collapsed.has(e.uuid);return o.html`
2
+ <div class="group">
3
+ <button class="group-header"
4
+ @click=${()=>this._toggleGroup(e.uuid)}
5
+ aria-expanded=${t}>
6
+ <span>${e.name}</span>
7
+ <svg class="chevron ${t?"open":""}" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
8
+ <polyline points="4 6 8 10 12 6"/>
9
+ </svg>
10
+ </button>
11
+ ${t?o.html`
12
+ <div class="group-content">
13
+ ${e.fields.map(s=>o.html`
14
+ <sfx-metadata-field
15
+ .field=${s}
16
+ .value=${this.meta[s.key]}
17
+ .config=${this.config}
18
+ .autocomplete=${this.autocomplete}
19
+ ?disabled=${this.disabled}
20
+ ></sfx-metadata-field>
21
+ `)}
22
+ </div>
23
+ `:o.nothing}
24
+ </div>
25
+ `}render(){return!this.schema||this.schema.groups.length===0?o.html`<div class="empty">No metadata fields configured</div>`:o.html`
26
+ ${this.schema.groups.map(e=>this._renderGroup(e))}
27
+ `}};de.styles=o.css`
28
+ :host { display: block; }
29
+
30
+ .group {
31
+ padding-bottom: 4px;
32
+ }
33
+ .group + .group {
34
+ border-top: 1px solid var(--sfx-up-border, #e2e8f0);
35
+ }
36
+
37
+ .group-header {
38
+ display: flex;
39
+ align-items: center;
40
+ justify-content: space-between;
41
+ width: 100%;
42
+ padding: 14px 0 8px;
43
+ border: none;
44
+ background: none;
45
+ cursor: pointer;
46
+ font-family: inherit;
47
+ font-size: 15px;
48
+ font-weight: 600;
49
+ color: var(--sfx-up-text, #1e293b);
50
+ transition: color 0.12s ease;
51
+ }
52
+ .group-header:hover {
53
+ color: var(--sfx-up-primary, #2563eb);
54
+ }
55
+ .group-header:focus-visible {
56
+ outline: 2px solid var(--sfx-up-ring, oklch(0.578 0.198 268.129 / 0.7));
57
+ outline-offset: 2px;
58
+ border-radius: 4px;
59
+ }
60
+
61
+ .chevron {
62
+ width: 16px;
63
+ height: 16px;
64
+ flex-shrink: 0;
65
+ color: var(--sfx-up-text-muted, #94a3b8);
66
+ transition: transform 0.18s ease;
67
+ }
68
+ .chevron.open {
69
+ transform: rotate(180deg);
70
+ }
71
+
72
+ .group-content {
73
+ padding: 0 0 4px;
74
+ }
75
+
76
+ .empty {
77
+ padding: 24px 16px;
78
+ text-align: center;
79
+ font-size: 14px;
80
+ color: var(--sfx-up-text-muted, #94a3b8);
81
+ }
82
+ `;let _=de;B([d.property({attribute:!1})],_.prototype,"schema");B([d.property({attribute:!1})],_.prototype,"meta");B([d.property({attribute:!1})],_.prototype,"config");B([d.property({attribute:!1})],_.prototype,"autocomplete");B([d.property({type:Boolean})],_.prototype,"disabled");B([d.state()],_.prototype,"_collapsed");customElements.define("sfx-metadata-form",_);const J=o.css`
83
+ input, textarea, select {
84
+ width: 100%;
85
+ height: 36px;
86
+ padding: 0 10px;
87
+ border: 1px solid var(--sfx-up-border, #e2e8f0);
88
+ border-radius: 6px;
89
+ font-size: 14px;
90
+ font-family: inherit;
91
+ color: var(--sfx-up-text, #1e293b);
92
+ background: var(--sfx-up-bg, #fff);
93
+ outline: none;
94
+ transition: border-color 0.15s ease, box-shadow 0.15s ease;
95
+ box-sizing: border-box;
96
+ }
97
+ input:focus, textarea:focus, select:focus {
98
+ border-color: var(--sfx-up-primary, #2563eb);
99
+ box-shadow: 0 0 0 3px var(--sfx-up-ring, oklch(0.578 0.198 268.129 / 0.15));
100
+ }
101
+ input:disabled, textarea:disabled, select:disabled {
102
+ opacity: 0.55;
103
+ cursor: not-allowed;
104
+ }
105
+ `,ne=o.css`
106
+ :host { display: block; position: relative; }
107
+
108
+ .trigger {
109
+ width: 100%;
110
+ height: 36px;
111
+ padding: 0 10px;
112
+ border: 1px solid var(--sfx-up-border, #e2e8f0);
113
+ border-radius: 6px;
114
+ font-size: 14px;
115
+ font-family: inherit;
116
+ color: var(--sfx-up-text, #1e293b);
117
+ background: var(--sfx-up-bg, #fff);
118
+ cursor: pointer;
119
+ text-align: left;
120
+ box-sizing: border-box;
121
+ display: flex;
122
+ align-items: center;
123
+ }
124
+ .trigger:focus-visible {
125
+ border-color: var(--sfx-up-primary, #2563eb);
126
+ box-shadow: 0 0 0 3px var(--sfx-up-ring, oklch(0.578 0.198 268.129 / 0.15));
127
+ outline: none;
128
+ }
129
+ .placeholder {
130
+ color: var(--sfx-up-text-muted, #94a3b8);
131
+ font-size: 14px;
132
+ }
133
+
134
+ .dropdown {
135
+ position: absolute;
136
+ top: calc(100% + 4px);
137
+ left: 0;
138
+ right: 0;
139
+ z-index: 10;
140
+ background: var(--sfx-up-bg, #fff);
141
+ border: 1px solid var(--sfx-up-border, #e2e8f0);
142
+ border-radius: 8px;
143
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
144
+ max-height: 200px;
145
+ overflow-y: auto;
146
+ }
147
+
148
+ .search {
149
+ width: 100%;
150
+ height: 34px;
151
+ padding: 0 10px;
152
+ border: none;
153
+ border-bottom: 1px solid var(--sfx-up-border, #e2e8f0);
154
+ font-size: 13px;
155
+ font-family: inherit;
156
+ color: var(--sfx-up-text, #1e293b);
157
+ background: transparent;
158
+ outline: none;
159
+ box-sizing: border-box;
160
+ }
161
+
162
+ .option {
163
+ padding: 8px 10px;
164
+ font-size: 14px;
165
+ cursor: pointer;
166
+ color: var(--sfx-up-text, #1e293b);
167
+ }
168
+ .option:hover, .option.active { background: var(--sfx-up-hover, #f1f5f9); }
169
+ .option.selected {
170
+ color: var(--sfx-up-primary, #2563eb);
171
+ font-weight: 500;
172
+ }
173
+
174
+ .empty {
175
+ padding: 8px 10px;
176
+ font-size: 13px;
177
+ color: var(--sfx-up-text-muted, #94a3b8);
178
+ }
179
+ `,Fe=o.css`
180
+ .chip {
181
+ display: inline-flex;
182
+ align-items: center;
183
+ gap: 4px;
184
+ padding: 2px 8px;
185
+ border-radius: 12px;
186
+ background: var(--sfx-up-primary-bg, #eff6ff);
187
+ font-size: 12px;
188
+ color: var(--sfx-up-text, #1e293b);
189
+ line-height: 1.4;
190
+ }
191
+ .chip-x {
192
+ cursor: pointer;
193
+ font-size: 14px;
194
+ line-height: 1;
195
+ color: var(--sfx-up-text-muted, #94a3b8);
196
+ background: none;
197
+ border: none;
198
+ padding: 0;
199
+ font-family: inherit;
200
+ }
201
+ .chip-x:hover { color: var(--sfx-up-error, #dc2626); }
202
+ `;o.css`
203
+ :host {
204
+ display: flex;
205
+ flex-direction: column;
206
+ height: 100%;
207
+ font-family: var(--sfx-up-font, inherit);
208
+ color: var(--sfx-up-text, #1e293b);
209
+ background: var(--sfx-up-bg, #fff);
210
+ }
211
+
212
+ .panel-header {
213
+ flex-shrink: 0;
214
+ display: flex;
215
+ align-items: center;
216
+ gap: 8px;
217
+ padding: 12px 16px;
218
+ border-bottom: 1px solid var(--sfx-up-border, #e2e8f0);
219
+ }
220
+
221
+ .panel-title {
222
+ flex: 1;
223
+ font-size: 15px;
224
+ font-weight: 600;
225
+ overflow: hidden;
226
+ text-overflow: ellipsis;
227
+ white-space: nowrap;
228
+ }
229
+
230
+ .panel-close {
231
+ width: 32px;
232
+ height: 32px;
233
+ border: none;
234
+ border-radius: 6px;
235
+ background: none;
236
+ cursor: pointer;
237
+ display: inline-flex;
238
+ align-items: center;
239
+ justify-content: center;
240
+ color: var(--sfx-up-text-muted, #94a3b8);
241
+ transition: background 0.15s ease, color 0.15s ease;
242
+ flex-shrink: 0;
243
+ }
244
+ .panel-close:hover {
245
+ background: var(--sfx-up-hover, #f1f5f9);
246
+ color: var(--sfx-up-text-secondary, #64748b);
247
+ }
248
+ .panel-close:focus-visible {
249
+ outline: 2px solid var(--sfx-up-ring, oklch(0.578 0.198 268.129 / 0.7));
250
+ outline-offset: 2px;
251
+ }
252
+
253
+ .progress-bar {
254
+ flex-shrink: 0;
255
+ padding: 8px 16px;
256
+ border-bottom: 1px solid var(--sfx-up-border-light, #f8faff);
257
+ }
258
+ .progress-label {
259
+ font-size: 12px;
260
+ color: var(--sfx-up-text-secondary, #64748b);
261
+ margin-bottom: 4px;
262
+ }
263
+ .progress-track {
264
+ height: 3px;
265
+ border-radius: 2px;
266
+ background: var(--sfx-up-border-light, #f8faff);
267
+ overflow: hidden;
268
+ }
269
+ .progress-fill {
270
+ height: 100%;
271
+ border-radius: 2px;
272
+ background: var(--sfx-up-primary, #2563eb);
273
+ transition: width 0.25s ease;
274
+ }
275
+
276
+ .panel-content {
277
+ flex: 1;
278
+ overflow-y: auto;
279
+ padding: 12px 16px;
280
+ }
281
+
282
+ .panel-footer {
283
+ flex-shrink: 0;
284
+ display: flex;
285
+ align-items: center;
286
+ gap: 8px;
287
+ padding: 12px 16px;
288
+ border-top: 1px solid var(--sfx-up-border, #e2e8f0);
289
+ }
290
+ .panel-footer .spacer { flex: 1; }
291
+
292
+ /* Shared button styles */
293
+ .btn,
294
+ .btn-ghost,
295
+ .btn-primary {
296
+ height: 36px;
297
+ padding: 0 16px;
298
+ border-radius: 6px;
299
+ border: none;
300
+ font-family: inherit;
301
+ font-size: 14px;
302
+ font-weight: 500;
303
+ cursor: pointer;
304
+ display: inline-flex;
305
+ align-items: center;
306
+ justify-content: center;
307
+ gap: 6px;
308
+ transition: all 0.15s ease;
309
+ white-space: nowrap;
310
+ }
311
+ .btn svg,
312
+ .btn-ghost svg,
313
+ .btn-primary svg {
314
+ width: 14px;
315
+ height: 14px;
316
+ }
317
+ .btn-ghost {
318
+ background: none;
319
+ color: var(--sfx-up-text-muted, #94a3b8);
320
+ border: 1.5px solid var(--sfx-up-border, #e2e8f0);
321
+ }
322
+ .btn-ghost:hover {
323
+ background: var(--sfx-up-border-light, #f8faff);
324
+ color: var(--sfx-up-text-secondary, #64748b);
325
+ border-color: var(--sfx-up-border, #d1dff0);
326
+ }
327
+ .btn-ghost:disabled {
328
+ opacity: 0.45;
329
+ cursor: not-allowed;
330
+ }
331
+ .btn-primary {
332
+ background: linear-gradient(135deg, var(--sfx-up-primary, #2563eb), var(--sfx-up-primary-mid, #3b82f6));
333
+ color: #fff;
334
+ box-shadow: 0 2px 10px var(--sfx-up-primary-glow, rgba(37, 99, 235, 0.28));
335
+ position: relative;
336
+ overflow: hidden;
337
+ }
338
+ .btn-primary:hover:not(:disabled) {
339
+ background: linear-gradient(135deg, var(--sfx-up-primary-hover, #1d4ed8), var(--sfx-up-primary, #2563eb));
340
+ box-shadow: 0 4px 16px var(--sfx-up-primary-glow, rgba(37, 99, 235, 0.38));
341
+ transform: translateY(-1px);
342
+ }
343
+ .btn-primary:active { transform: translateY(0); }
344
+ .btn-primary:disabled {
345
+ opacity: 0.55;
346
+ cursor: not-allowed;
347
+ }
348
+ button:focus-visible {
349
+ outline: 2px solid var(--sfx-up-ring, oklch(0.578 0.198 268.129 / 0.7));
350
+ outline-offset: 2px;
351
+ }
352
+ `;const Ge=o.css`
353
+ :host { display: block; }
354
+
355
+ .field-row {
356
+ display: flex;
357
+ align-items: baseline;
358
+ gap: 8px;
359
+ padding: 10px 0;
360
+ }
361
+
362
+ .field-label {
363
+ display: flex;
364
+ align-items: center;
365
+ gap: 3px;
366
+ width: 120px;
367
+ flex-shrink: 0;
368
+ }
369
+ .field-label-text {
370
+ font-size: 14px;
371
+ font-weight: 400;
372
+ color: var(--sfx-up-text-muted, #94a3b8);
373
+ }
374
+ .field-required {
375
+ color: var(--sfx-up-error, #dc2626);
376
+ font-size: 13px;
377
+ font-weight: 500;
378
+ }
379
+ .field-hint {
380
+ width: 14px;
381
+ height: 14px;
382
+ display: inline-flex;
383
+ align-items: center;
384
+ justify-content: center;
385
+ color: var(--sfx-up-text-muted, #94a3b8);
386
+ cursor: help;
387
+ flex-shrink: 0;
388
+ }
389
+ .field-hint svg {
390
+ width: 12px;
391
+ height: 12px;
392
+ }
393
+
394
+ .field-content {
395
+ flex: 1;
396
+ min-width: 0;
397
+ }
398
+
399
+ .field-error {
400
+ font-size: 11px;
401
+ color: var(--sfx-up-error, #dc2626);
402
+ margin-top: 2px;
403
+ }
404
+ `;var We=Object.defineProperty,j=(a,e,t,s)=>{for(var i=void 0,n=a.length-1,r;n>=0;n--)(r=a[n])&&(i=r(e,t,i)||i);return i&&We(e,t,i),i};const ce=class ce extends o.LitElement{constructor(){super(...arguments),this.config=null,this.disabled=!1,this._error=null,this._dispatching=!1,this._handleChildBlur=e=>{this._dispatching||(e.stopPropagation(),this._onFieldBlur(e))}}get _isRequired(){var e,t;return(t=(e=this.config)==null?void 0:e.requiredFields)!=null&&t.includes(this.field.ckey)?!0:this.field.required===1}_onFieldBlur(e){var r;const{key:t,value:s}=e.detail,i=re(this.field,s,this.config??void 0);if(i){this._error=i;return}this._error=null;const n=K(this.field,s,void 0,(r=this.config)==null?void 0:r.language);this._dispatching=!0,this.dispatchEvent(new CustomEvent("field-blur",{detail:{key:t,value:n},bubbles:!0,composed:!0})),this._dispatching=!1}connectedCallback(){super.connectedCallback(),this.addEventListener("field-blur",this._handleChildBlur)}disconnectedCallback(){super.disconnectedCallback(),this.removeEventListener("field-blur",this._handleChildBlur)}_renderField(e,t){const s=this.disabled;switch(e.type){case"text":case"attachment-uri":return o.html`<sfx-meta-text-field .field=${e} .value=${t} ?disabled=${s}></sfx-meta-text-field>`;case"textarea":return o.html`<sfx-meta-textarea-field .field=${e} .value=${t} ?disabled=${s}></sfx-meta-textarea-field>`;case"select-one":return o.html`<sfx-meta-select-field .field=${e} .value=${t} ?disabled=${s}></sfx-meta-select-field>`;case"multi-select":return o.html`<sfx-meta-multi-select-field .field=${e} .value=${t} ?disabled=${s}></sfx-meta-multi-select-field>`;case"tags":return o.html`<sfx-meta-tags-field .field=${e} .value=${t} .autocomplete=${this.autocomplete} ?disabled=${s}></sfx-meta-tags-field>`;case"boolean":return o.html`<sfx-meta-boolean-field .field=${e} .value=${t} ?disabled=${s}></sfx-meta-boolean-field>`;case"numeric":case"decimal2":return o.html`<sfx-meta-number-field .field=${e} .value=${t} ?disabled=${s}></sfx-meta-number-field>`;case"date":return o.html`<sfx-meta-date-field .field=${e} .value=${t} ?disabled=${s}></sfx-meta-date-field>`;case"geopoint":return o.html`<sfx-meta-geo-point-field .field=${e} .value=${t} ?disabled=${s}></sfx-meta-geo-point-field>`;default:return o.html`<sfx-meta-text-field .field=${e} .value=${t} ?disabled=${s}></sfx-meta-text-field>`}}render(){var s;const e=this.field;if(!e)return o.nothing;const t=se(e,this.value,(s=this.config)==null?void 0:s.language);return o.html`
405
+ <div class="field-row" aria-required=${this._isRequired?"true":"false"}>
406
+ <div class="field-label" id="label-${e.key}">
407
+ <span class="field-label-text">${e.title}</span>
408
+ ${this._isRequired?o.html`<span class="field-required" aria-hidden="true">*</span>`:o.nothing}
409
+ </div>
410
+ <div class="field-content">
411
+ ${this._renderField(e,t)}
412
+ ${this._error?o.html`<div class="field-error" id="error-${e.key}" role="alert">${this._error}</div>`:o.nothing}
413
+ </div>
414
+ </div>
415
+ `}};ce.styles=[Ge];let w=ce;j([d.property({attribute:!1})],w.prototype,"field");j([d.property({attribute:!1})],w.prototype,"value");j([d.property({attribute:!1})],w.prototype,"config");j([d.property({attribute:!1})],w.prototype,"autocomplete");j([d.property({type:Boolean})],w.prototype,"disabled");j([d.state()],w.prototype,"_error");customElements.define("sfx-metadata-field",w);var Ze=Object.defineProperty,oe=(a,e,t,s)=>{for(var i=void 0,n=a.length-1,r;n>=0;n--)(r=a[n])&&(i=r(e,t,i)||i);return i&&Ze(e,t,i),i};class m extends o.LitElement{constructor(){super(...arguments),this.value="",this.disabled=!1}_emit(e,t){this.dispatchEvent(new CustomEvent(e,{detail:{key:this.field.key,...t!==void 0?{value:t}:{}},bubbles:!0,composed:!0}))}}oe([d.property({attribute:!1})],m.prototype,"field");oe([d.property({attribute:!1})],m.prototype,"value");oe([d.property({type:Boolean})],m.prototype,"disabled");const pe=class pe extends m{_onInput(e){this._emit("field-change",e.target.value)}_onBlur(e){this._emit("field-blur",e.target.value)}_onKeydown(e){e.key==="Escape"&&this._emit("field-escape")}render(){var e;return o.html`
416
+ <input
417
+ type="text"
418
+ .value=${this.value??""}
419
+ placeholder=${((e=this.field)==null?void 0:e.placeholder)??""}
420
+ ?disabled=${this.disabled}
421
+ @input=${this._onInput}
422
+ @blur=${this._onBlur}
423
+ @keydown=${this._onKeydown}
424
+ />
425
+ `}};pe.styles=[J];let W=pe;customElements.define("sfx-meta-text-field",W);const ue=class ue extends m{firstUpdated(){const e=this.renderRoot.querySelector("textarea");e&&this._autoResize(e)}_autoResize(e){e.style.height="auto",e.style.height=`${Math.max(80,e.scrollHeight)}px`}_onInput(e){const t=e.target;this._autoResize(t),this._emit("field-change",t.value)}_onBlur(e){this._emit("field-blur",e.target.value)}_onKeydown(e){e.key==="Escape"&&this._emit("field-escape")}render(){var e;return o.html`
426
+ <textarea
427
+ .value=${this.value??""}
428
+ placeholder=${((e=this.field)==null?void 0:e.placeholder)??""}
429
+ ?disabled=${this.disabled}
430
+ @input=${this._onInput}
431
+ @blur=${this._onBlur}
432
+ @keydown=${this._onKeydown}
433
+ ></textarea>
434
+ `}};ue.styles=[J,o.css`
435
+ textarea {
436
+ height: auto;
437
+ min-height: 80px;
438
+ padding: 8px 10px;
439
+ resize: none;
440
+ }
441
+ `];let Z=ue;customElements.define("sfx-meta-textarea-field",Z);var Qe=Object.defineProperty,ae=(a,e,t,s)=>{for(var i=void 0,n=a.length-1,r;n>=0;n--)(r=a[n])&&(i=r(e,t,i)||i);return i&&Qe(e,t,i),i};const he=class he extends m{constructor(){super(...arguments),this._open=!1,this._search="",this._activeIndex=-1,this._boundOutsideClick=this._onOutsideClick.bind(this)}get _options(){var e;return(((e=this.field)==null?void 0:e.possible_values)??[]).map(t=>({id:t.internal_unique_value,label:t.label,value:t.internal_unique_value}))}get _filtered(){const e=this._search.toLowerCase();return this._options.filter(t=>t.label.toLowerCase().includes(e)).sort((t,s)=>t.label.localeCompare(s.label))}get _selectedLabel(){var e;return((e=this._options.find(t=>t.value===this.value))==null?void 0:e.label)??""}disconnectedCallback(){super.disconnectedCallback(),document.removeEventListener("mousedown",this._boundOutsideClick)}_openDropdown(){this._open=!0,this._search="";const t=this._filtered.findIndex(s=>s.value===this.value);this._activeIndex=t>=0?t:0,document.addEventListener("mousedown",this._boundOutsideClick),this.updateComplete.then(()=>{var s;(s=this.renderRoot.querySelector(".search"))==null||s.focus(),this._scrollActive()})}_closeAndSubmit(e=!1){this._open=!1,this._activeIndex=-1,document.removeEventListener("mousedown",this._boundOutsideClick),this._emit("field-blur",this.value),e&&this.updateComplete.then(()=>{var t;(t=this.renderRoot.querySelector(".trigger"))==null||t.focus()})}_onOutsideClick(e){e.composedPath().includes(this)||this._closeAndSubmit()}_onSelect(e,t=!1){this._emit("field-change",e.value),this.value=e.value,this._closeAndSubmit(t)}_scrollActive(){this.updateComplete.then(()=>{var e;(e=this.renderRoot.querySelector(".option.active"))==null||e.scrollIntoView({block:"nearest"})})}_onSearchInput(e){this._search=e.target.value,this._activeIndex=0}_onKeydown(e){var s;if(e.key==="Escape"){this._open=!1,this._activeIndex=-1,document.removeEventListener("mousedown",this._boundOutsideClick),this._emit("field-escape"),(s=this.renderRoot.querySelector(".trigger"))==null||s.focus();return}if(!this._open){(e.key==="ArrowDown"||e.key==="Enter"||e.key===" ")&&(e.preventDefault(),this._openDropdown());return}const t=this._filtered;if(t.length)switch(e.key){case"ArrowDown":e.preventDefault(),this._activeIndex=Math.min(this._activeIndex+1,t.length-1),this._scrollActive();break;case"ArrowUp":e.preventDefault(),this._activeIndex=Math.max(this._activeIndex-1,0),this._scrollActive();break;case"Home":e.preventDefault(),this._activeIndex=0,this._scrollActive();break;case"End":e.preventDefault(),this._activeIndex=t.length-1,this._scrollActive();break;case"Enter":this._activeIndex>=0&&this._activeIndex<t.length&&(e.preventDefault(),this._onSelect(t[this._activeIndex],!0));break}}render(){var e;return o.html`
442
+ <button class="trigger" ?disabled=${this.disabled}
443
+ role="combobox"
444
+ aria-expanded=${this._open}
445
+ aria-haspopup="listbox"
446
+ @click=${()=>!this._open&&this._openDropdown()}
447
+ @keydown=${this._onKeydown}>
448
+ ${this._selectedLabel?o.html`<span>${this._selectedLabel}</span>`:o.html`<span class="placeholder">${((e=this.field)==null?void 0:e.placeholder)??"Select..."}</span>`}
449
+ </button>
450
+
451
+ ${this._open?o.html`
452
+ <div class="dropdown" role="listbox" @keydown=${this._onKeydown}>
453
+ <input class="search" type="text" placeholder="Search..."
454
+ aria-label="Filter options"
455
+ .value=${this._search}
456
+ @input=${this._onSearchInput} />
457
+ ${this._filtered.length?this._filtered.map((t,s)=>o.html`
458
+ <div class="option ${t.value===this.value?"selected":""} ${s===this._activeIndex?"active":""}"
459
+ role="option" aria-selected=${t.value===this.value}
460
+ @mousedown=${i=>{i.preventDefault(),this._onSelect(t)}}
461
+ @mouseenter=${()=>{this._activeIndex=s}}>
462
+ ${t.label}
463
+ </div>`):o.html`<div class="empty">No options</div>`}
464
+ </div>
465
+ `:o.nothing}
466
+ `}};he.styles=[ne];let P=he;ae([d.state()],P.prototype,"_open");ae([d.state()],P.prototype,"_search");ae([d.state()],P.prototype,"_activeIndex");customElements.define("sfx-meta-select-field",P);var Xe=Object.defineProperty,le=(a,e,t,s)=>{for(var i=void 0,n=a.length-1,r;n>=0;n--)(r=a[n])&&(i=r(e,t,i)||i);return i&&Xe(e,t,i),i};const fe=class fe extends m{constructor(){super(...arguments),this._open=!1,this._search="",this._activeIndex=-1,this._boundOutsideClick=this._onOutsideClick.bind(this)}get _selected(){return Array.isArray(this.value)?this.value:[]}get _options(){var e;return(((e=this.field)==null?void 0:e.possible_values)??[]).map(t=>({id:t.internal_unique_value,label:t.label,value:t.internal_unique_value}))}get _filtered(){const e=this._search.toLowerCase();return this._options.filter(t=>t.label.toLowerCase().includes(e)).sort((t,s)=>t.label.localeCompare(s.label))}disconnectedCallback(){super.disconnectedCallback(),document.removeEventListener("mousedown",this._boundOutsideClick)}_openDropdown(){this._open=!0,this._search="",this._activeIndex=-1,document.addEventListener("mousedown",this._boundOutsideClick),this.updateComplete.then(()=>{var e;(e=this.renderRoot.querySelector(".search"))==null||e.focus()})}_closeAndSubmit(){this._open=!1,this._activeIndex=-1,document.removeEventListener("mousedown",this._boundOutsideClick),this._emit("field-blur",this._selected)}_onOutsideClick(e){e.composedPath().includes(this)||this._closeAndSubmit()}_toggle(e){const t=this._selected,s=t.includes(e.value)?t.filter(i=>i!==e.value):[...t,e.value];this.value=s,this._emit("field-change",s)}_remove(e){const t=this._selected.filter(s=>s!==e);this.value=t,this._emit("field-change",t)}_scrollActive(){this.updateComplete.then(()=>{var e;(e=this.renderRoot.querySelector(".option.active"))==null||e.scrollIntoView({block:"nearest"})})}_onSearchInput(e){this._search=e.target.value,this._activeIndex=-1}_onKeydown(e){var s;if(e.key==="Escape"){this._open=!1,this._activeIndex=-1,document.removeEventListener("mousedown",this._boundOutsideClick),this._emit("field-escape"),(s=this.renderRoot.querySelector(".trigger"))==null||s.focus();return}if(!this._open){(e.key==="ArrowDown"||e.key==="Enter"||e.key===" ")&&(e.preventDefault(),this._openDropdown());return}if(e.key==="Backspace"&&!this._search&&this._selected.length>0){this._remove(this._selected[this._selected.length-1]);return}const t=this._filtered;if(t.length)switch(e.key){case"ArrowDown":e.preventDefault(),this._activeIndex=Math.min(this._activeIndex+1,t.length-1),this._scrollActive();break;case"ArrowUp":e.preventDefault(),this._activeIndex=Math.max(this._activeIndex-1,0),this._scrollActive();break;case"Home":e.preventDefault(),this._activeIndex=0,this._scrollActive();break;case"End":e.preventDefault(),this._activeIndex=t.length-1,this._scrollActive();break;case"Enter":this._activeIndex>=0&&this._activeIndex<t.length&&(e.preventDefault(),this._toggle(t[this._activeIndex]));break;case" ":this._activeIndex>=0&&this._activeIndex<t.length&&!this._search&&(e.preventDefault(),this._toggle(t[this._activeIndex]));break}}_labelFor(e){var t;return((t=this._options.find(s=>s.value===e))==null?void 0:t.label)??e}render(){var t;const e=this._selected;return o.html`
467
+ <div class="trigger"
468
+ role="combobox" aria-expanded=${this._open} aria-haspopup="listbox"
469
+ tabindex="0"
470
+ @click=${()=>!this._open&&this._openDropdown()} @keydown=${this._onKeydown}>
471
+ ${e.length?e.map(s=>o.html`
472
+ <span class="chip">
473
+ ${this._labelFor(s)}
474
+ <button class="chip-x" aria-label="Remove ${this._labelFor(s)}" @click=${i=>{i.stopPropagation(),this._remove(s)}}>&times;</button>
475
+ </span>`):o.html`<span class="placeholder">${((t=this.field)==null?void 0:t.placeholder)??"Select..."}</span>`}
476
+ </div>
477
+
478
+ ${this._open?o.html`
479
+ <div class="dropdown" role="listbox" aria-multiselectable="true" @keydown=${this._onKeydown}>
480
+ <input class="search" type="text" placeholder="Search..."
481
+ aria-label="Filter options"
482
+ .value=${this._search}
483
+ @input=${this._onSearchInput} />
484
+ ${this._filtered.length?this._filtered.map((s,i)=>o.html`
485
+ <div class="option ${i===this._activeIndex?"active":""}" role="option" aria-selected=${e.includes(s.value)}
486
+ @mousedown=${n=>{n.preventDefault(),this._toggle(s)}}
487
+ @mouseenter=${()=>{this._activeIndex=i}}>
488
+ <span class="check ${e.includes(s.value)?"checked":""}">
489
+ ${e.includes(s.value)?"✓":""}
490
+ </span>
491
+ ${s.label}
492
+ </div>`):o.html`<div class="empty">No options</div>`}
493
+ </div>
494
+ `:o.nothing}
495
+ `}};fe.styles=[ne,Fe,o.css`
496
+ .trigger {
497
+ min-height: 36px;
498
+ height: auto;
499
+ padding: 4px 8px;
500
+ flex-wrap: wrap;
501
+ gap: 4px;
502
+ }
503
+ .check {
504
+ width: 16px;
505
+ height: 16px;
506
+ border: 1.5px solid var(--sfx-up-border, #e2e8f0);
507
+ border-radius: 3px;
508
+ display: flex;
509
+ align-items: center;
510
+ justify-content: center;
511
+ flex-shrink: 0;
512
+ font-size: 11px;
513
+ }
514
+ .check.checked {
515
+ background: var(--sfx-up-primary, #2563eb);
516
+ border-color: var(--sfx-up-primary, #2563eb);
517
+ color: #fff;
518
+ }
519
+ .option { display: flex; align-items: center; gap: 8px; }
520
+ `];let T=fe;le([d.state()],T.prototype,"_open");le([d.state()],T.prototype,"_search");le([d.state()],T.prototype,"_activeIndex");customElements.define("sfx-meta-multi-select-field",T);function I(a,e){var t,s;return((t=a.label)==null?void 0:t.trim().toLowerCase())===((s=e.label)==null?void 0:s.trim().toLowerCase())}function Le(a){return a.trim().replace(/\s+/g," ")}function et(a){return Le(a).replace(/\s/g,"-")}function U(a){return{label:Le(a),value:et(a)}}var tt=Object.defineProperty,R=(a,e,t,s)=>{for(var i=void 0,n=a.length-1,r;n>=0;n--)(r=a[n])&&(i=r(e,t,i)||i);return i&&tt(e,t,i),i};const me=class me extends m{constructor(){super(...arguments),this._query="",this._results=[],this._loading=!1,this._dropdownOpen=!1,this._activeIndex=-1,this._blurTimeout=null}get _tags(){return Array.isArray(this.value)?this.value:[]}disconnectedCallback(){var e;super.disconnectedCallback(),this._blurTimeout&&clearTimeout(this._blurTimeout),(e=this.autocomplete)==null||e.cancel()}_onInput(e){var s,i,n;const t=e.target.value;if(this._query=t,this._dropdownOpen=!0,this._activeIndex=-1,!t.trim()||!((s=this.field)!=null&&s.ckey)){this._results=[],this._loading=!1,(i=this.autocomplete)==null||i.cancel();return}this._loading=!0,(n=this.autocomplete)==null||n.search(this.field.ckey,t,r=>{this._results=r,this._loading=!1})}_addTag(e){if(this._tags.some(s=>I(s,e)))return;const t=[...this._tags,e];this.value=t,this._query="",this._results=[],this._dropdownOpen=!1,this._activeIndex=-1,this._emit("field-change",t),this.updateComplete.then(()=>{var s;(s=this.renderRoot.querySelector(".input"))==null||s.focus()})}_removeTag(e){const t=this._tags.filter(s=>!I(s,e));this.value=t,this._emit("field-change",t)}_onBlur(){this._blurTimeout&&clearTimeout(this._blurTimeout),this._blurTimeout=setTimeout(()=>{this._blurTimeout=null,this.renderRoot.querySelector(".dropdown:hover")||(this._dropdownOpen=!1,this._activeIndex=-1,this._emit("field-blur",this._tags))},150)}_scrollActive(){this.updateComplete.then(()=>{var e;(e=this.renderRoot.querySelector(".option.active"))==null||e.scrollIntoView({block:"nearest"})})}get _itemCount(){return this._suggestions.length+(this._canCreate?1:0)}_onKeydown(e){if(e.key==="Escape"){this._dropdownOpen=!1,this._activeIndex=-1,this._emit("field-escape");return}if(e.key==="Backspace"&&!this._query&&this._tags.length){this._removeTag(this._tags[this._tags.length-1]);return}if(!this._dropdownOpen)return;const t=this._itemCount;if(this._activeIndex>=t&&(this._activeIndex=Math.max(t-1,-1)),!(t===0&&e.key!=="Enter"))switch(e.key){case"ArrowDown":e.preventDefault(),this._activeIndex=Math.min(this._activeIndex+1,t-1),this._scrollActive();break;case"ArrowUp":e.preventDefault(),this._activeIndex=Math.max(this._activeIndex-1,-1),this._scrollActive();break;case"Home":e.preventDefault(),this._activeIndex=0,this._scrollActive();break;case"End":e.preventDefault(),this._activeIndex=t-1,this._scrollActive();break;case"Enter":{e.preventDefault();const s=this._suggestions;this._activeIndex>=0&&this._activeIndex<s.length?this._addTag(s[this._activeIndex]):this._activeIndex===s.length&&this._canCreate?this._addTag(U(this._query)):this._activeIndex===-1&&this._canCreate?this._addTag(U(this._query)):this._activeIndex===-1&&s.length&&this._addTag(s[0]);break}}}get _suggestions(){var n;const e=this._query.toLowerCase().trim(),t=this._tags,s=(((n=this.field)==null?void 0:n.possible_values)??[]).map(r=>({value:r.api_value||r.internal_unique_value,label:r.label})).filter(r=>!t.some(l=>I(l,r))).filter(r=>!e||r.label.toLowerCase().includes(e)),i=this._results.filter(r=>!t.some(l=>I(l,r))&&!s.some(l=>I(l,r)));return[...s,...i]}get _canCreate(){const e=this._query.trim();if(!e||this._loading)return!1;const t=U(e);return!this._tags.some(s=>I(s,t))&&!this._suggestions.some(s=>I(s,t))}render(){var i,n;const e=this._tags,t=this._suggestions,s=t.length;return o.html`
521
+ <div class="container" @click=${()=>{var r;return(r=this.renderRoot.querySelector(".input"))==null?void 0:r.focus()}}>
522
+ ${e.map(r=>o.html`
523
+ <span class="chip">
524
+ ${r.label}
525
+ <button class="chip-x" aria-label="Remove ${r.label}" @click=${l=>{l.stopPropagation(),this._removeTag(r)}}>&times;</button>
526
+ </span>`)}
527
+ <input class="input" type="text" .value=${this._query}
528
+ role="combobox" aria-expanded=${this._dropdownOpen} aria-haspopup="listbox"
529
+ aria-label=${((i=this.field)==null?void 0:i.title)??"Tags"}
530
+ placeholder=${e.length?"":((n=this.field)==null?void 0:n.placeholder)??"Add tags..."}
531
+ ?disabled=${this.disabled}
532
+ @input=${this._onInput} @blur=${this._onBlur} @keydown=${this._onKeydown} />
533
+ </div>
534
+
535
+ ${this._dropdownOpen&&(this._query.trim()||t.length)?o.html`
536
+ <div class="dropdown" role="listbox">
537
+ ${this._loading?o.html`<div class="loading">Loading...</div>`:o.nothing}
538
+ ${t.map((r,l)=>o.html`
539
+ <div class="option ${l===this._activeIndex?"active":""}" role="option"
540
+ @mousedown=${c=>{c.preventDefault(),this._addTag(r)}}
541
+ @mouseenter=${()=>{this._activeIndex=l}}>
542
+ ${r.label}
543
+ </div>`)}
544
+ ${this._canCreate?o.html`
545
+ <div class="option create ${s===this._activeIndex?"active":""}"
546
+ @mousedown=${r=>{r.preventDefault(),this._addTag(U(this._query))}}
547
+ @mouseenter=${()=>{this._activeIndex=s}}>
548
+ Create '${this._query.trim()}'
549
+ </div>`:o.nothing}
550
+ ${!this._loading&&!t.length&&!this._canCreate?o.html`<div class="empty">No results</div>`:o.nothing}
551
+ </div>
552
+ `:o.nothing}
553
+ `}};me.styles=[Fe,o.css`
554
+ :host { display: block; position: relative; }
555
+
556
+ .container {
557
+ display: flex;
558
+ flex-wrap: wrap;
559
+ align-items: center;
560
+ gap: 4px;
561
+ min-height: 36px;
562
+ padding: 4px 8px;
563
+ border: 1px solid var(--sfx-up-border, #e2e8f0);
564
+ border-radius: 6px;
565
+ background: var(--sfx-up-bg, #fff);
566
+ box-sizing: border-box;
567
+ cursor: text;
568
+ }
569
+ .container:focus-within {
570
+ border-color: var(--sfx-up-primary, #2563eb);
571
+ box-shadow: 0 0 0 3px var(--sfx-up-ring, oklch(0.578 0.198 268.129 / 0.15));
572
+ }
573
+
574
+ .input {
575
+ flex: 1;
576
+ min-width: 80px;
577
+ border: none;
578
+ outline: none;
579
+ font-size: 14px;
580
+ font-family: inherit;
581
+ color: var(--sfx-up-text, #1e293b);
582
+ background: transparent;
583
+ padding: 2px 0;
584
+ }
585
+
586
+ .dropdown {
587
+ position: absolute;
588
+ top: calc(100% + 4px);
589
+ left: 0;
590
+ right: 0;
591
+ z-index: 10;
592
+ background: var(--sfx-up-bg, #fff);
593
+ border: 1px solid var(--sfx-up-border, #e2e8f0);
594
+ border-radius: 8px;
595
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
596
+ max-height: 200px;
597
+ overflow-y: auto;
598
+ }
599
+
600
+ .option {
601
+ padding: 8px 10px;
602
+ font-size: 14px;
603
+ cursor: pointer;
604
+ color: var(--sfx-up-text, #1e293b);
605
+ }
606
+ .option:hover, .option.active { background: var(--sfx-up-hover, #f1f5f9); }
607
+ .option.create {
608
+ color: var(--sfx-up-primary, #2563eb);
609
+ font-weight: 500;
610
+ }
611
+
612
+ .loading, .empty {
613
+ padding: 8px 10px;
614
+ font-size: 13px;
615
+ color: var(--sfx-up-text-muted, #94a3b8);
616
+ }
617
+ `];let k=me;R([d.property({attribute:!1})],k.prototype,"autocomplete");R([d.state()],k.prototype,"_query");R([d.state()],k.prototype,"_results");R([d.state()],k.prototype,"_loading");R([d.state()],k.prototype,"_dropdownOpen");R([d.state()],k.prototype,"_activeIndex");customElements.define("sfx-meta-tags-field",k);var it=Object.defineProperty,Pe=(a,e,t,s)=>{for(var i=void 0,n=a.length-1,r;n>=0;n--)(r=a[n])&&(i=r(e,t,i)||i);return i&&it(e,t,i),i};const A=[{label:"True",value:"true"},{label:"False",value:"false"},{label:"None",value:"null"}],ge=class ge extends m{constructor(){super(...arguments),this._open=!1,this._activeIndex=-1,this._boundOutsideClick=this._onOutsideClick.bind(this)}get _currentLabel(){var t;const e=String(this.value??"null");return((t=A.find(s=>s.value===e))==null?void 0:t.label)??""}disconnectedCallback(){super.disconnectedCallback(),document.removeEventListener("mousedown",this._boundOutsideClick)}_openDropdown(){this._open=!0;const e=String(this.value??"null");this._activeIndex=Math.max(A.findIndex(t=>t.value===e),0),document.addEventListener("mousedown",this._boundOutsideClick),this.updateComplete.then(()=>{var t;(t=this.renderRoot.querySelector(".dropdown"))==null||t.focus()})}_closeAndSubmit(e=!1){this._open=!1,this._activeIndex=-1,document.removeEventListener("mousedown",this._boundOutsideClick),this._emit("field-blur",this.value),e&&this.updateComplete.then(()=>{var t;(t=this.renderRoot.querySelector(".trigger"))==null||t.focus()})}_onOutsideClick(e){e.composedPath().includes(this)||this._closeAndSubmit()}_onSelect(e,t=!1){this.value=e.value,this._emit("field-change",e.value),this._closeAndSubmit(t)}_scrollActive(){this.updateComplete.then(()=>{var e;(e=this.renderRoot.querySelector(".option.active"))==null||e.scrollIntoView({block:"nearest"})})}_onKeydown(e){var t;if(e.key==="Escape"){this._open=!1,this._activeIndex=-1,document.removeEventListener("mousedown",this._boundOutsideClick),this._emit("field-escape"),(t=this.renderRoot.querySelector(".trigger"))==null||t.focus();return}if(!this._open){(e.key==="ArrowDown"||e.key==="Enter"||e.key===" ")&&(e.preventDefault(),this._openDropdown());return}switch(e.key){case"ArrowDown":e.preventDefault(),this._activeIndex=Math.min(this._activeIndex+1,A.length-1),this._scrollActive();break;case"ArrowUp":e.preventDefault(),this._activeIndex=Math.max(this._activeIndex-1,0),this._scrollActive();break;case"Home":e.preventDefault(),this._activeIndex=0,this._scrollActive();break;case"End":e.preventDefault(),this._activeIndex=A.length-1,this._scrollActive();break;case"Enter":case" ":this._activeIndex>=0&&this._activeIndex<A.length&&(e.preventDefault(),this._onSelect(A[this._activeIndex],!0));break}}render(){const e=String(this.value??"null");return o.html`
618
+ <button class="trigger" ?disabled=${this.disabled}
619
+ role="combobox" aria-expanded=${this._open} aria-haspopup="listbox"
620
+ @click=${()=>!this._open&&this._openDropdown()}
621
+ @keydown=${this._onKeydown}>
622
+ ${this._currentLabel?o.html`<span>${this._currentLabel}</span>`:o.html`<span class="placeholder">Select...</span>`}
623
+ </button>
624
+
625
+ ${this._open?o.html`
626
+ <div class="dropdown" role="listbox" tabindex="-1" @keydown=${this._onKeydown}>
627
+ ${A.map((t,s)=>o.html`
628
+ <div class="option ${t.value===e?"selected":""} ${s===this._activeIndex?"active":""}"
629
+ role="option" aria-selected=${t.value===e}
630
+ @mousedown=${i=>{i.preventDefault(),this._onSelect(t)}}
631
+ @mouseenter=${()=>{this._activeIndex=s}}>
632
+ ${t.label}
633
+ </div>`)}
634
+ </div>
635
+ `:o.nothing}
636
+ `}};ge.styles=[ne];let V=ge;Pe([d.state()],V.prototype,"_open");Pe([d.state()],V.prototype,"_activeIndex");customElements.define("sfx-meta-boolean-field",V);const xe=class xe extends m{get _step(){var e;return((e=this.field)==null?void 0:e.type)==="decimal2"?"0.01":"1"}_onInput(e){this._emit("field-change",e.target.value)}_onBlur(e){this._emit("field-blur",e.target.value)}_onKeydown(e){e.key==="Escape"&&this._emit("field-escape")}render(){var e;return o.html`
637
+ <input
638
+ type="number"
639
+ step=${this._step}
640
+ .value=${String(this.value??"")}
641
+ placeholder=${((e=this.field)==null?void 0:e.placeholder)??""}
642
+ ?disabled=${this.disabled}
643
+ @input=${this._onInput}
644
+ @blur=${this._onBlur}
645
+ @keydown=${this._onKeydown}
646
+ />
647
+ `}};xe.styles=[J];let Q=xe;customElements.define("sfx-meta-number-field",Q);const be=class be extends m{get _dateStr(){const e=this.value;return e?e instanceof Date?e.toISOString().split("T")[0]:String(e):""}_onChange(e){const t=e.target.value;this._emit("field-change",t),this._emit("field-blur",t)}_onKeydown(e){e.key==="Escape"&&this._emit("field-escape")}render(){return o.html`
648
+ <input
649
+ type="date"
650
+ .value=${this._dateStr}
651
+ ?disabled=${this.disabled}
652
+ @change=${this._onChange}
653
+ @keydown=${this._onKeydown}
654
+ />
655
+ `}};be.styles=[J];let X=be;customElements.define("sfx-meta-date-field",X);const ve=class ve extends m{get _geo(){const e=this.value;return{latitude:(e==null?void 0:e.latitude)??"",longitude:(e==null?void 0:e.longitude)??""}}_onInput(e,t){const s=t.target.value,i={...this._geo,[e]:s};this.value=i,this._emit("field-change",i)}_onBlur(e){const t=e.relatedTarget;t&&this.renderRoot.contains(t)||this._emit("field-blur",this._geo)}_onKeydown(e){e.key==="Escape"&&this._emit("field-escape")}render(){const e=this._geo;return o.html`
656
+ <div class="grid">
657
+ <div>
658
+ <label>Latitude</label>
659
+ <input type="number" step="any" .value=${e.latitude}
660
+ ?disabled=${this.disabled}
661
+ @input=${t=>this._onInput("latitude",t)}
662
+ @blur=${this._onBlur} @keydown=${this._onKeydown} />
663
+ </div>
664
+ <div>
665
+ <label>Longitude</label>
666
+ <input type="number" step="any" .value=${e.longitude}
667
+ ?disabled=${this.disabled}
668
+ @input=${t=>this._onInput("longitude",t)}
669
+ @blur=${this._onBlur} @keydown=${this._onKeydown} />
670
+ </div>
671
+ </div>
672
+ `}};ve.styles=[J,o.css`
673
+ .grid {
674
+ display: grid;
675
+ grid-template-columns: 1fr 1fr;
676
+ gap: 12px;
677
+ }
678
+ label {
679
+ display: block;
680
+ font-size: 12px;
681
+ color: var(--sfx-up-text-secondary, #64748b);
682
+ margin-bottom: 4px;
683
+ }
684
+ `];let ee=ve;customElements.define("sfx-meta-geo-point-field",ee);var st=Object.defineProperty,Y=(a,e,t,s)=>{for(var i=void 0,n=a.length-1,r;n>=0;n--)(r=a[n])&&(i=r(e,t,i)||i);return i&&st(e,t,i),i};const ye=class ye extends o.LitElement{constructor(){super(...arguments),this.disabled=!1}render(){const e=this.field,t=this.value,s=this.disabled;switch(e.type){case"text":case"attachment-uri":return o.html`<sfx-meta-text-field .field=${e} .value=${t} ?disabled=${s}></sfx-meta-text-field>`;case"textarea":return o.html`<sfx-meta-textarea-field .field=${e} .value=${t} ?disabled=${s}></sfx-meta-textarea-field>`;case"select-one":return o.html`<sfx-meta-select-field .field=${e} .value=${t} ?disabled=${s}></sfx-meta-select-field>`;case"multi-select":return o.html`<sfx-meta-multi-select-field .field=${e} .value=${t} ?disabled=${s}></sfx-meta-multi-select-field>`;case"tags":return o.html`<sfx-meta-tags-field .field=${e} .value=${t} .autocomplete=${this.autocomplete} ?disabled=${s}></sfx-meta-tags-field>`;case"boolean":return o.html`<sfx-meta-boolean-field .field=${e} .value=${t} ?disabled=${s}></sfx-meta-boolean-field>`;case"numeric":case"decimal2":return o.html`<sfx-meta-number-field .field=${e} .value=${t} ?disabled=${s}></sfx-meta-number-field>`;case"date":return o.html`<sfx-meta-date-field .field=${e} .value=${t} ?disabled=${s}></sfx-meta-date-field>`;case"geopoint":return o.html`<sfx-meta-geo-point-field .field=${e} .value=${t} ?disabled=${s}></sfx-meta-geo-point-field>`;default:return o.html`<sfx-meta-text-field .field=${e} .value=${t} ?disabled=${s}></sfx-meta-text-field>`}}};ye.styles=o.css`
685
+ :host { display: block; }
686
+ `;let D=ye;Y([d.property({attribute:!1})],D.prototype,"field");Y([d.property({attribute:!1})],D.prototype,"value");Y([d.property({attribute:!1})],D.prototype,"autocomplete");Y([d.property({type:Boolean})],D.prototype,"disabled");customElements.define("sfx-metadata-field-edit",D);var rt=Object.defineProperty,Te=(a,e,t,s)=>{for(var i=void 0,n=a.length-1,r;n>=0;n--)(r=a[n])&&(i=r(e,t,i)||i);return i&&rt(e,t,i),i};const _e=class _e extends o.LitElement{_formatValue(){var s,i;const e=this.value,t=(s=this.field)==null?void 0:s.type;switch(t){case"boolean":return e==="true"?"True":e==="false"?"False":"";case"date":return e?e instanceof Date?e.toLocaleDateString(void 0,{year:"numeric",month:"short",day:"numeric"}):typeof e=="string"&&e.length>0?e:"":"";case"numeric":case"decimal2":{if(e==null||e==="")return"";const n=Number(e);return Number.isFinite(n)?n.toLocaleString(void 0,{maximumFractionDigits:t==="decimal2"?2:0}):String(e)}case"select-one":{if(e==null||e==="")return"";const n=(i=this.field.possible_values)==null?void 0:i.find(r=>r.internal_unique_value===e||r.api_value===e);return(n==null?void 0:n.label)??String(e)}case"multi-select":return!Array.isArray(e)||e.length===0?"":e.map(n=>{var l;const r=(l=this.field.possible_values)==null?void 0:l.find(c=>c.internal_unique_value===n||c.api_value===n);return(r==null?void 0:r.label)??String(n)}).join(", ");case"tags":return!Array.isArray(e)||e.length===0?"":e.map(n=>n.label||n.value).join(", ");case"geopoint":{const n=e;return!n||n.latitude===""||n.latitude==null||n.longitude===""||n.longitude==null?"":`(${n.latitude}, ${n.longitude})`}case"attachment-uri":return!e||typeof e=="string"&&e.length===0?"":String(e);case"text":case"textarea":default:return e==null||e===""?"":String(e)}}render(){var s;const e=this._formatValue(),t=e==="";return((s=this.field)==null?void 0:s.type)==="attachment-uri"&&!t?o.html`
687
+ <div class="value">
688
+ <a class="link" href=${e} target="_blank" rel="noopener noreferrer"
689
+ @click=${i=>i.stopPropagation()}
690
+ >${e}</a>
691
+ </div>
692
+ `:o.html`
693
+ <div class="value ${t?"empty":""}">${t?"—":e}</div>
694
+ `}};_e.styles=o.css`
695
+ :host { display: block; }
696
+ .value {
697
+ min-height: 28px;
698
+ padding: 6px 8px;
699
+ border-radius: 4px;
700
+ font-size: 14px;
701
+ color: var(--sfx-up-text, #1e293b);
702
+ word-break: break-word;
703
+ line-height: 1.4;
704
+ }
705
+ .empty {
706
+ color: var(--sfx-up-text-muted, #94a3b8);
707
+ }
708
+ .link {
709
+ color: var(--sfx-up-primary, #2563eb);
710
+ text-decoration: none;
711
+ max-width: 100%;
712
+ display: inline-block;
713
+ overflow: hidden;
714
+ text-overflow: ellipsis;
715
+ white-space: nowrap;
716
+ }
717
+ .link:hover {
718
+ text-decoration: underline;
719
+ }
720
+ `;let M=_e;Te([d.property({attribute:!1})],M.prototype,"field");Te([d.property({attribute:!1})],M.prototype,"value");customElements.define("sfx-metadata-field-view",M);const Ee={key:"SET",label:"Set"},nt={key:"ADD",label:"Add"},ot={key:"DELETE",label:"Delete"},at=new Set(["multi-select","tags","integer-list"]);function lt(a){return at.has(a)?[Ee,nt,ot]:[Ee]}function Be(a,e,t,s){switch(a){case"SET":return t;case"ADD":{const i=Array.isArray(e)?e:[],n=Array.isArray(t)?t:[];if(n.length===0)return i;if(s==="tags"){const c=new Set(i.map(h=>h)),p=[...i];for(const h of n){const u=typeof h=="string"?h:String(h);c.has(u)||(c.add(u),p.push(u))}return p}const r=new Set(i.map(c=>JSON.stringify(c))),l=[...i];for(const c of n){const p=JSON.stringify(c);r.has(p)||(r.add(p),l.push(c))}return l}case"DELETE":{const i=Array.isArray(e)?e:[],n=Array.isArray(t)?t:[];if(n.length===0)return i;if(s==="tags"){const l=new Set(n.map(c=>typeof c=="string"?c:String(c)));return i.filter(c=>!l.has(typeof c=="string"?c:String(c)))}const r=new Set(n.map(l=>JSON.stringify(l)));return i.filter(l=>!r.has(JSON.stringify(l)))}default:return t}}const dt=o.css`
721
+ :host {
722
+ display: block;
723
+ font-family: var(--sfx-up-font, inherit);
724
+ color: var(--sfx-up-text, #1e293b);
725
+ }
726
+
727
+ .fm-overlay {
728
+ position: fixed;
729
+ inset: 0;
730
+ z-index: 1010;
731
+ display: flex;
732
+ align-items: center;
733
+ justify-content: center;
734
+ background: rgba(17, 24, 39, 0.45);
735
+ backdrop-filter: blur(6px);
736
+ -webkit-backdrop-filter: blur(6px);
737
+ }
738
+
739
+ .fm-modal {
740
+ width: 980px;
741
+ max-width: calc(100vw - 40px);
742
+ height: 82vh;
743
+ max-height: calc(100vh - 40px);
744
+ background: var(--sfx-up-bg, #fff);
745
+ border-radius: 14px;
746
+ box-shadow: 0 24px 48px rgba(0, 0, 0, 0.18);
747
+ display: flex;
748
+ flex-direction: column;
749
+ overflow: hidden;
750
+ }
751
+
752
+ /* ---- Top bar ---- */
753
+ .fm-topbar {
754
+ height: 48px;
755
+ flex-shrink: 0;
756
+ display: flex;
757
+ align-items: center;
758
+ padding: 0 24px;
759
+ border-bottom: 1px solid var(--sfx-up-border, #e2e8f0);
760
+ }
761
+ .fm-topbar-title {
762
+ flex: 1;
763
+ font-size: 15px;
764
+ font-weight: 600;
765
+ white-space: nowrap;
766
+ overflow: hidden;
767
+ text-overflow: ellipsis;
768
+ }
769
+ .fm-topbar-close {
770
+ width: 32px;
771
+ height: 32px;
772
+ border: none;
773
+ border-radius: 6px;
774
+ background: none;
775
+ cursor: pointer;
776
+ display: inline-flex;
777
+ align-items: center;
778
+ justify-content: center;
779
+ color: var(--sfx-up-text-muted, #94a3b8);
780
+ transition: background 0.15s ease, color 0.15s ease;
781
+ flex-shrink: 0;
782
+ }
783
+ .fm-topbar-close:hover {
784
+ background: var(--sfx-up-hover, #f1f5f9);
785
+ color: var(--sfx-up-text-secondary, #64748b);
786
+ }
787
+
788
+ /* ---- Body ---- */
789
+ .fm-body {
790
+ flex: 1;
791
+ display: flex;
792
+ overflow: hidden;
793
+ }
794
+
795
+ .fm-main {
796
+ flex: 1;
797
+ display: flex;
798
+ flex-direction: column;
799
+ overflow: hidden;
800
+ }
801
+
802
+ /* ---- Table header ---- */
803
+ .fm-table-header {
804
+ display: flex;
805
+ align-items: center;
806
+ gap: 12px;
807
+ padding: 8px 24px;
808
+ border-bottom: 1px solid var(--sfx-up-border, #e2e8f0);
809
+ font-size: 12px;
810
+ font-weight: 500;
811
+ color: var(--sfx-up-text-muted, #94a3b8);
812
+ text-transform: uppercase;
813
+ letter-spacing: 0.03em;
814
+ flex-shrink: 0;
815
+ }
816
+ .fm-th-check { width: 20px; flex-shrink: 0; }
817
+ .fm-th-thumb { width: 52px; flex-shrink: 0; }
818
+ .fm-th-name {
819
+ width: 180px;
820
+ flex-shrink: 0;
821
+ cursor: pointer;
822
+ user-select: none;
823
+ display: flex;
824
+ align-items: center;
825
+ gap: 4px;
826
+ }
827
+ .fm-th-name:hover { color: var(--sfx-up-text-secondary, #64748b); }
828
+ .fm-th-size { width: 70px; flex-shrink: 0; text-align: right; }
829
+ .fm-th-field { flex: 1; min-width: 0; }
830
+
831
+ .fm-sort-arrow {
832
+ display: inline-block;
833
+ font-size: 11px;
834
+ line-height: 1;
835
+ }
836
+
837
+ /* ---- Table body (scrollable) ---- */
838
+ .fm-table-body {
839
+ flex: 1;
840
+ overflow-y: auto;
841
+ overflow-x: hidden;
842
+ }
843
+
844
+ /* ---- Footer ---- */
845
+ .fm-footer {
846
+ flex-shrink: 0;
847
+ display: flex;
848
+ align-items: center;
849
+ gap: 8px;
850
+ padding: 14px 24px;
851
+ border-top: 1px solid var(--sfx-up-border, #e2e8f0);
852
+ }
853
+ .fm-footer .spacer { flex: 1; }
854
+
855
+ /* ---- Shared buttons ---- */
856
+ .btn-ghost,
857
+ .btn-primary,
858
+ .btn-back {
859
+ height: 36px;
860
+ padding: 0 16px;
861
+ border-radius: 6px;
862
+ border: none;
863
+ font-family: inherit;
864
+ font-size: 14px;
865
+ font-weight: 500;
866
+ cursor: pointer;
867
+ display: inline-flex;
868
+ align-items: center;
869
+ justify-content: center;
870
+ gap: 6px;
871
+ transition: all 0.15s ease;
872
+ white-space: nowrap;
873
+ }
874
+ .btn-ghost {
875
+ background: none;
876
+ color: var(--sfx-up-text-muted, #94a3b8);
877
+ border: 1.5px solid var(--sfx-up-border, #e2e8f0);
878
+ }
879
+ .btn-ghost:hover {
880
+ background: var(--sfx-up-border-light, #f8faff);
881
+ color: var(--sfx-up-text-secondary, #64748b);
882
+ border-color: var(--sfx-up-border, #d1dff0);
883
+ }
884
+ .btn-ghost:disabled {
885
+ opacity: 0.45;
886
+ cursor: not-allowed;
887
+ }
888
+ .btn-primary {
889
+ background: linear-gradient(135deg, var(--sfx-up-primary, #2563eb), var(--sfx-up-primary-mid, #3b82f6));
890
+ color: #fff;
891
+ box-shadow: 0 2px 10px var(--sfx-up-primary-glow, rgba(37, 99, 235, 0.28));
892
+ position: relative;
893
+ overflow: hidden;
894
+ }
895
+ .btn-primary:hover:not(:disabled) {
896
+ background: linear-gradient(135deg, var(--sfx-up-primary-hover, #1d4ed8), var(--sfx-up-primary, #2563eb));
897
+ box-shadow: 0 4px 16px var(--sfx-up-primary-glow, rgba(37, 99, 235, 0.38));
898
+ transform: translateY(-1px);
899
+ }
900
+ .btn-primary:active { transform: translateY(0); }
901
+ .btn-primary:disabled {
902
+ opacity: 0.55;
903
+ cursor: not-allowed;
904
+ }
905
+ .btn-back {
906
+ background: none;
907
+ color: var(--sfx-up-text-muted, #94a3b8);
908
+ padding: 0 8px;
909
+ }
910
+ .btn-back:hover {
911
+ color: var(--sfx-up-text-secondary, #64748b);
912
+ }
913
+
914
+ button:focus-visible {
915
+ outline: 2px solid var(--sfx-up-ring, oklch(0.578 0.198 268.129 / 0.7));
916
+ outline-offset: 2px;
917
+ }
918
+
919
+ /* ---- Empty state ---- */
920
+ .fm-empty {
921
+ flex: 1;
922
+ display: flex;
923
+ align-items: center;
924
+ justify-content: center;
925
+ color: var(--sfx-up-text-muted, #94a3b8);
926
+ font-size: 14px;
927
+ }
928
+
929
+ /* ---- Checkbox ---- */
930
+ .fm-checkbox {
931
+ width: 16px;
932
+ height: 16px;
933
+ accent-color: var(--sfx-up-primary, #2563eb);
934
+ cursor: pointer;
935
+ margin: 0;
936
+ }
937
+ `,ct=o.css`
938
+ :host {
939
+ display: block;
940
+ width: 220px;
941
+ flex-shrink: 0;
942
+ border-right: 1px solid var(--sfx-up-border, #e2e8f0);
943
+ overflow-y: auto;
944
+ padding: 12px 0;
945
+ font-family: var(--sfx-up-font, inherit);
946
+ }
947
+
948
+ .group-label {
949
+ display: flex;
950
+ align-items: center;
951
+ gap: 4px;
952
+ width: 100%;
953
+ padding: 12px 16px 6px;
954
+ margin-top: 8px;
955
+ font-size: 11px;
956
+ font-weight: 600;
957
+ text-transform: uppercase;
958
+ letter-spacing: 0.06em;
959
+ color: var(--sfx-up-text-muted, #94a3b8);
960
+ border: none;
961
+ background: none;
962
+ cursor: pointer;
963
+ font-family: inherit;
964
+ text-align: left;
965
+ }
966
+ .group-label:first-child {
967
+ margin-top: 0;
968
+ }
969
+ .group-label:hover {
970
+ color: var(--sfx-up-text-secondary, #64748b);
971
+ }
972
+ .group-label-text {
973
+ flex: 1;
974
+ }
975
+ .group-chevron {
976
+ width: 14px;
977
+ height: 14px;
978
+ flex-shrink: 0;
979
+ transition: transform 0.18s ease;
980
+ }
981
+ .group-chevron.open {
982
+ transform: rotate(180deg);
983
+ }
984
+
985
+ .field-item {
986
+ display: flex;
987
+ align-items: center;
988
+ gap: 8px;
989
+ height: 36px;
990
+ padding: 0 16px;
991
+ cursor: pointer;
992
+ font-size: 14px;
993
+ color: var(--sfx-up-text, #1e293b);
994
+ transition: background 0.12s ease;
995
+ border: none;
996
+ background: none;
997
+ width: 100%;
998
+ text-align: left;
999
+ font-family: inherit;
1000
+ }
1001
+ .field-item:hover {
1002
+ background: var(--sfx-up-hover, #f1f5f9);
1003
+ }
1004
+ .field-item.active {
1005
+ background: var(--sfx-up-primary-bg, #eff6ff);
1006
+ color: var(--sfx-up-primary, #2563eb);
1007
+ font-weight: 500;
1008
+ }
1009
+
1010
+ .field-icon {
1011
+ width: 16px;
1012
+ height: 16px;
1013
+ flex-shrink: 0;
1014
+ display: inline-flex;
1015
+ align-items: center;
1016
+ justify-content: center;
1017
+ opacity: 0.55;
1018
+ }
1019
+ .field-icon svg {
1020
+ width: 16px;
1021
+ height: 16px;
1022
+ }
1023
+ .field-item.active .field-icon {
1024
+ opacity: 0.85;
1025
+ }
1026
+
1027
+ .field-name {
1028
+ flex: 1;
1029
+ min-width: 0;
1030
+ overflow: hidden;
1031
+ text-overflow: ellipsis;
1032
+ white-space: nowrap;
1033
+ }
1034
+
1035
+ .field-dot {
1036
+ width: 7px;
1037
+ height: 7px;
1038
+ border-radius: 50%;
1039
+ background: #22c55e;
1040
+ flex-shrink: 0;
1041
+ }
1042
+
1043
+ .field-required {
1044
+ color: var(--sfx-up-error, #dc2626);
1045
+ font-size: 13px;
1046
+ font-weight: 500;
1047
+ flex-shrink: 0;
1048
+ }
1049
+ `,pt=o.css`
1050
+ :host {
1051
+ display: block;
1052
+ font-family: var(--sfx-up-font, inherit);
1053
+ }
1054
+
1055
+ .op-bar {
1056
+ display: flex;
1057
+ align-items: center;
1058
+ gap: 12px;
1059
+ padding: 14px 24px;
1060
+ border-bottom: 1px solid var(--sfx-up-border, #e2e8f0);
1061
+ flex-shrink: 0;
1062
+ }
1063
+
1064
+ .op-label {
1065
+ font-size: 13px;
1066
+ font-weight: 500;
1067
+ color: var(--sfx-up-text-muted, #94a3b8);
1068
+ white-space: nowrap;
1069
+ flex-shrink: 0;
1070
+ }
1071
+
1072
+ /* Operation dropdown */
1073
+ .op-dropdown-wrap {
1074
+ position: relative;
1075
+ flex-shrink: 0;
1076
+ }
1077
+ .op-trigger {
1078
+ height: 34px;
1079
+ padding: 0 10px;
1080
+ border: 1px solid var(--sfx-up-border, #e2e8f0);
1081
+ border-radius: 6px;
1082
+ background: var(--sfx-up-bg, #fff);
1083
+ font-size: 14px;
1084
+ font-family: inherit;
1085
+ color: var(--sfx-up-text, #1e293b);
1086
+ cursor: pointer;
1087
+ display: flex;
1088
+ align-items: center;
1089
+ gap: 6px;
1090
+ min-width: 80px;
1091
+ }
1092
+ .op-trigger:hover {
1093
+ border-color: var(--sfx-up-primary, #2563eb);
1094
+ }
1095
+ .op-arrow {
1096
+ margin-left: auto;
1097
+ font-size: 10px;
1098
+ color: var(--sfx-up-text-muted, #94a3b8);
1099
+ }
1100
+ .op-menu {
1101
+ position: absolute;
1102
+ top: calc(100% + 4px);
1103
+ left: 0;
1104
+ right: 0;
1105
+ z-index: 20;
1106
+ background: var(--sfx-up-bg, #fff);
1107
+ border: 1px solid var(--sfx-up-border, #e2e8f0);
1108
+ border-radius: 8px;
1109
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
1110
+ overflow: hidden;
1111
+ }
1112
+ .op-option {
1113
+ padding: 8px 10px;
1114
+ font-size: 14px;
1115
+ cursor: pointer;
1116
+ color: var(--sfx-up-text, #1e293b);
1117
+ font-family: inherit;
1118
+ border: none;
1119
+ background: none;
1120
+ width: 100%;
1121
+ text-align: left;
1122
+ }
1123
+ .op-option:hover {
1124
+ background: var(--sfx-up-hover, #f1f5f9);
1125
+ }
1126
+ .op-option.active {
1127
+ color: var(--sfx-up-primary, #2563eb);
1128
+ font-weight: 500;
1129
+ }
1130
+
1131
+ /* Value input area */
1132
+ .op-value {
1133
+ flex: 1;
1134
+ min-width: 0;
1135
+ }
1136
+
1137
+ /* Clear button */
1138
+ .btn-clear {
1139
+ width: 28px;
1140
+ height: 28px;
1141
+ border: none;
1142
+ border-radius: 6px;
1143
+ background: none;
1144
+ cursor: pointer;
1145
+ display: inline-flex;
1146
+ align-items: center;
1147
+ justify-content: center;
1148
+ color: var(--sfx-up-text-muted, #94a3b8);
1149
+ flex-shrink: 0;
1150
+ transition: background 0.12s ease, color 0.12s ease;
1151
+ }
1152
+ .btn-clear:hover {
1153
+ background: var(--sfx-up-hover, #f1f5f9);
1154
+ color: var(--sfx-up-text-secondary, #64748b);
1155
+ }
1156
+
1157
+ /* Apply button */
1158
+ .btn-apply {
1159
+ height: 34px;
1160
+ padding: 0 16px;
1161
+ border-radius: 6px;
1162
+ border: none;
1163
+ font-family: inherit;
1164
+ font-size: 13px;
1165
+ font-weight: 500;
1166
+ cursor: pointer;
1167
+ white-space: nowrap;
1168
+ background: var(--sfx-up-primary, #2563eb);
1169
+ color: #fff;
1170
+ transition: all 0.15s ease;
1171
+ flex-shrink: 0;
1172
+ }
1173
+ .btn-apply:hover:not(:disabled) {
1174
+ background: var(--sfx-up-primary-hover, #1d4ed8);
1175
+ }
1176
+ .btn-apply:disabled {
1177
+ opacity: 0.45;
1178
+ cursor: not-allowed;
1179
+ }
1180
+ `,ut=o.css`
1181
+ :host {
1182
+ display: block;
1183
+ font-family: var(--sfx-up-font, inherit);
1184
+ }
1185
+
1186
+ .row {
1187
+ display: flex;
1188
+ align-items: center;
1189
+ gap: 12px;
1190
+ padding: 10px 24px;
1191
+ border-bottom: 1px solid var(--sfx-up-border-light, #f1f5f9);
1192
+ border-left: 3px solid transparent;
1193
+ transition: background 0.1s ease;
1194
+ }
1195
+ .row:hover {
1196
+ background: var(--sfx-up-hover, #f1f5f9);
1197
+ }
1198
+
1199
+ .row-check { width: 20px; flex-shrink: 0; }
1200
+
1201
+ .row-thumb {
1202
+ width: 52px;
1203
+ height: 38px;
1204
+ flex-shrink: 0;
1205
+ border-radius: 6px;
1206
+ object-fit: cover;
1207
+ background: var(--sfx-up-border-light, #f1f5f9);
1208
+ }
1209
+ .row-thumb-placeholder {
1210
+ width: 52px;
1211
+ height: 38px;
1212
+ flex-shrink: 0;
1213
+ border-radius: 6px;
1214
+ background: var(--sfx-up-border-light, #f1f5f9);
1215
+ display: flex;
1216
+ align-items: center;
1217
+ justify-content: center;
1218
+ color: var(--sfx-up-text-muted, #94a3b8);
1219
+ font-size: 11px;
1220
+ }
1221
+
1222
+ .row-name {
1223
+ width: 180px;
1224
+ flex-shrink: 0;
1225
+ overflow: hidden;
1226
+ text-overflow: ellipsis;
1227
+ white-space: nowrap;
1228
+ font-size: 14px;
1229
+ color: var(--sfx-up-text, #1e293b);
1230
+ }
1231
+
1232
+ .row-size {
1233
+ width: 70px;
1234
+ flex-shrink: 0;
1235
+ text-align: right;
1236
+ font-size: 13px;
1237
+ color: var(--sfx-up-text-muted, #94a3b8);
1238
+ }
1239
+
1240
+ .row-field {
1241
+ flex: 1;
1242
+ min-width: 0;
1243
+ position: relative;
1244
+ }
1245
+ .row-field-edit {
1246
+ min-width: 0;
1247
+ }
1248
+
1249
+ .row-error {
1250
+ font-size: 11px;
1251
+ color: var(--sfx-up-error, #dc2626);
1252
+ margin-top: 2px;
1253
+ }
1254
+
1255
+ .row--changed {
1256
+ border-left-color: var(--sfx-up-success, #16a34a);
1257
+ }
1258
+
1259
+ .fm-checkbox {
1260
+ width: 16px;
1261
+ height: 16px;
1262
+ accent-color: var(--sfx-up-primary, #2563eb);
1263
+ cursor: pointer;
1264
+ margin: 0;
1265
+ }
1266
+ `,ht=o.css`
1267
+ :host {
1268
+ display: block;
1269
+ font-family: var(--sfx-up-font, inherit);
1270
+ }
1271
+
1272
+ .diff-wrap {
1273
+ display: flex;
1274
+ flex-wrap: wrap;
1275
+ align-items: center;
1276
+ gap: 4px;
1277
+ min-height: 28px;
1278
+ padding: 4px 8px;
1279
+ border-radius: 6px;
1280
+ }
1281
+
1282
+ /* ---- Chips (array diff) ---- */
1283
+ .diff-chip {
1284
+ display: inline-flex;
1285
+ align-items: center;
1286
+ padding: 2px 8px;
1287
+ border-radius: 12px;
1288
+ font-size: 12px;
1289
+ line-height: 1.4;
1290
+ }
1291
+ .diff-chip--kept {
1292
+ background: var(--sfx-up-border-light, #f1f5f9);
1293
+ color: var(--sfx-up-text-secondary, #64748b);
1294
+ }
1295
+ .diff-chip--added {
1296
+ background: #dcfce7;
1297
+ color: #166534;
1298
+ font-weight: 500;
1299
+ }
1300
+ .diff-chip--removed {
1301
+ background: #fee2e2;
1302
+ color: #991b1b;
1303
+ }
1304
+ .diff-chip--removed s {
1305
+ text-decoration: line-through;
1306
+ }
1307
+
1308
+ /* ---- Scalar diff ---- */
1309
+ .diff-old {
1310
+ color: #991b1b;
1311
+ }
1312
+ .diff-old s {
1313
+ text-decoration: line-through;
1314
+ opacity: 0.7;
1315
+ }
1316
+ .diff-arrow {
1317
+ color: var(--sfx-up-text-muted, #94a3b8);
1318
+ font-size: 13px;
1319
+ flex-shrink: 0;
1320
+ }
1321
+ .diff-new {
1322
+ color: #166534;
1323
+ font-weight: 500;
1324
+ }
1325
+ .diff-scalar-text {
1326
+ font-size: 14px;
1327
+ }
1328
+
1329
+ /* ---- Accessibility ---- */
1330
+ .sr-only {
1331
+ position: absolute;
1332
+ width: 1px;
1333
+ height: 1px;
1334
+ padding: 0;
1335
+ margin: -1px;
1336
+ overflow: hidden;
1337
+ clip: rect(0, 0, 0, 0);
1338
+ white-space: nowrap;
1339
+ border-width: 0;
1340
+ }
1341
+ `,ft=o.css`
1342
+ :host {
1343
+ display: block;
1344
+ }
1345
+ `;var mt=Object.defineProperty,$=(a,e,t,s)=>{for(var i=void 0,n=a.length-1,r;n>=0;n--)(r=a[n])&&(i=r(e,t,i)||i);return i&&mt(e,t,i),i};const we=class we extends o.LitElement{constructor(){super(...arguments),this.files=[],this.config=null,this._activeFieldKey="",this._staged=new Map,this._selected=new Set,this._sortAsc=!0,this._pendingOp=null,this._originalFiles=new Map,this._onKeyDown=e=>{e.key!=="Escape"||e.composedPath().some(i=>i instanceof HTMLInputElement||i instanceof HTMLTextAreaElement||i instanceof HTMLSelectElement)||this._confirmDiscardPending()&&this._emitClose()},this._onPendingChange=e=>{const{operation:t,value:s}=e.detail;y(s)?this._pendingOp=null:this._pendingOp={operation:t,value:s}},this._onFieldSelect=e=>{this._confirmDiscardPending()&&(this._pendingOp=null,this._activeFieldKey=e.detail.fieldKey)},this._onBulkApply=e=>{var l;const t=this._activeField;if(!t)return;const{operation:s,value:i}=e.detail,n=(l=this.config)==null?void 0:l.language,r=[];for(const c of this._selected){const p=this._staged.get(c),h={meta:p?Object.fromEntries(p):{}},u=K(t,i,h,n),b=p==null?void 0:p.get(t.key),g=Be(s,b,u,t.type);r.push([c,t.key,g])}this._setStagedBulk(r)},this._onRowFieldChange=e=>{const t=this._activeField;t&&this._setStagedValue(e.detail.fileId,t.key,e.detail.value)},this._onRowToggle=e=>{const t=new Set(this._selected);t.has(e.detail.fileId)?t.delete(e.detail.fileId):t.add(e.detail.fileId),this._selected=t},this._onSelectAll=()=>{this._selected.size===this.files.length?this._selected=new Set:this._selected=new Set(this.files.map(e=>e.id))},this._onSortToggle=()=>{this._sortAsc=!this._sortAsc},this._onSave=()=>{if(!this._confirmDiscardPending())return;const e=[];for(const[t,s]of this._staged){const i=this._originalFiles.get(t);if(!i)continue;const n={};for(const[r,l]of s)JSON.stringify(l)!==JSON.stringify(i.meta[r])&&(n[r]=l);Object.keys(n).length>0&&e.push({fileId:t,meta:n})}this.dispatchEvent(new CustomEvent("metadata-save-batch",{detail:{changes:e},bubbles:!0,composed:!0})),this._emitClose()},this._onCancel=()=>{this._confirmDiscardPending()&&this._emitClose()},this._onClose=()=>{this._confirmDiscardPending()&&this._emitClose()}}connectedCallback(){super.connectedCallback(),this._initStaged(),document.addEventListener("keydown",this._onKeyDown)}disconnectedCallback(){super.disconnectedCallback(),document.removeEventListener("keydown",this._onKeyDown)}_initStaged(){var i,n;const e=new Map,t=new Set,s=new Map;for(const r of this.files){const l=new Map;if(r.meta)for(const[c,p]of Object.entries(r.meta))l.set(c,p);e.set(r.id,l),t.add(r.id),s.set(r.id,r)}this._staged=e,this._selected=t,this._originalFiles=s,((n=(i=this.schema)==null?void 0:i.fields)==null?void 0:n.length)>0&&(this._activeFieldKey=this.schema.fields[0].key)}_setStagedValue(e,t,s){const i=new Map(this._staged),n=new Map(i.get(e)??new Map);n.set(t,s),i.set(e,n),this._staged=i}_setStagedBulk(e){const t=new Map(this._staged);for(const[s,i,n]of e){const r=new Map(t.get(s)??new Map);r.set(i,n),t.set(s,r)}this._staged=t}get _activeField(){var e,t;return(t=(e=this.schema)==null?void 0:e.fieldsByKey)==null?void 0:t.get(this._activeFieldKey)}get _filledFields(){var t,s;const e=new Set;for(const i of((t=this.schema)==null?void 0:t.fields)??[])for(const[n,r]of this._staged){const l=r.get(i.key),c=(s=this._originalFiles.get(n))==null?void 0:s.meta[i.key];if(l!==void 0&&!y(l)&&JSON.stringify(l)!==JSON.stringify(c)){e.add(i.key);break}}return e}get _hasPendingValue(){return this._pendingOp!=null&&!y(this._pendingOp.value)}_confirmDiscardPending(){return this._hasPendingValue?confirm("You have unapplied bulk changes. Discard them?"):!0}_emitClose(){this.dispatchEvent(new CustomEvent("metadata-close",{bubbles:!0,composed:!0}))}get _sortedFiles(){const e=[...this.files];return e.sort((t,s)=>{const i=t.name.localeCompare(s.name)||t.id.localeCompare(s.id);return this._sortAsc?i:-i}),e}render(){var n,r;if(!((r=(n=this.schema)==null?void 0:n.fields)!=null&&r.length))return o.html`
1346
+ <div class="fm-overlay" @click=${this._onClose}>
1347
+ <div class="fm-modal" @click=${l=>l.stopPropagation()}>
1348
+ <div class="fm-topbar">
1349
+ <span class="fm-topbar-title">Fill multiple assets</span>
1350
+ <button class="fm-topbar-close" @click=${this._onClose} title="Close">
1351
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round">
1352
+ <line x1="18" y1="6" x2="6" y2="18" /><line x1="6" y1="6" x2="18" y2="18" />
1353
+ </svg>
1354
+ </button>
1355
+ </div>
1356
+ <div class="fm-empty">No metadata fields configured</div>
1357
+ </div>
1358
+ </div>
1359
+ `;const e=this._activeField,t=this._sortedFiles,s=this._selected.size===this.files.length&&this.files.length>0,i=this._selected.size>0&&!s;return o.html`
1360
+ <div class="fm-overlay" @click=${this._onClose}>
1361
+ <div class="fm-modal" @click=${l=>l.stopPropagation()}>
1362
+ <!-- Top bar -->
1363
+ <div class="fm-topbar">
1364
+ <span class="fm-topbar-title">Fill multiple assets</span>
1365
+ <button class="fm-topbar-close" @click=${this._onClose} title="Close">
1366
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round">
1367
+ <line x1="18" y1="6" x2="6" y2="18" /><line x1="6" y1="6" x2="18" y2="18" />
1368
+ </svg>
1369
+ </button>
1370
+ </div>
1371
+
1372
+ <!-- Body -->
1373
+ <div class="fm-body">
1374
+ <!-- Sidebar -->
1375
+ <sfx-bulk-meta-sidebar
1376
+ .schema=${this.schema}
1377
+ .activeFieldKey=${this._activeFieldKey}
1378
+ .filledFields=${this._filledFields}
1379
+ .config=${this.config}
1380
+ @field-select=${this._onFieldSelect}
1381
+ ></sfx-bulk-meta-sidebar>
1382
+
1383
+ <!-- Main area -->
1384
+ <div class="fm-main">
1385
+ <!-- Op bar -->
1386
+ ${e?o.html`
1387
+ <sfx-bulk-meta-op-bar
1388
+ .field=${e}
1389
+ .autocomplete=${this.autocomplete}
1390
+ .config=${this.config}
1391
+ .selectedCount=${this._selected.size}
1392
+ @bulk-apply=${this._onBulkApply}
1393
+ @pending-change=${this._onPendingChange}
1394
+ ></sfx-bulk-meta-op-bar>
1395
+ `:o.nothing}
1396
+
1397
+ <!-- Table header -->
1398
+ <div class="fm-table-header">
1399
+ <div class="fm-th-check">
1400
+ <input
1401
+ type="checkbox"
1402
+ class="fm-checkbox"
1403
+ .checked=${s}
1404
+ .indeterminate=${i}
1405
+ @change=${this._onSelectAll}
1406
+ />
1407
+ </div>
1408
+ <div class="fm-th-thumb">Thumb</div>
1409
+ <div class="fm-th-name" @click=${this._onSortToggle}>
1410
+ Name
1411
+ <span class="fm-sort-arrow">${this._sortAsc?"↑":"↓"}</span>
1412
+ </div>
1413
+ <div class="fm-th-size">Size</div>
1414
+ <div class="fm-th-field">${(e==null?void 0:e.title)??""}</div>
1415
+ </div>
1416
+
1417
+ <!-- Table body -->
1418
+ <div class="fm-table-body">
1419
+ ${e?o.html`
1420
+ <sfx-bulk-meta-table
1421
+ .files=${t}
1422
+ .field=${e}
1423
+ .staged=${this._staged}
1424
+ .selected=${this._selected}
1425
+ .config=${this.config}
1426
+ .autocomplete=${this.autocomplete}
1427
+ .pendingOp=${this._pendingOp}
1428
+ @row-field-change=${this._onRowFieldChange}
1429
+ @row-toggle=${this._onRowToggle}
1430
+ ></sfx-bulk-meta-table>
1431
+ `:o.nothing}
1432
+ </div>
1433
+ </div>
1434
+ </div>
1435
+
1436
+ <!-- Footer -->
1437
+ <div class="fm-footer">
1438
+ <button class="btn-back" @click=${this._onCancel}>
1439
+ \u2190 Back
1440
+ </button>
1441
+ <div class="spacer"></div>
1442
+ <button class="btn-ghost" @click=${this._onCancel}>Cancel</button>
1443
+ <button class="btn-primary" @click=${this._onSave}>Save</button>
1444
+ </div>
1445
+ </div>
1446
+ </div>
1447
+ `}};we.styles=[dt];let f=we;$([d.property({attribute:!1})],f.prototype,"schema");$([d.property({attribute:!1})],f.prototype,"files");$([d.property({attribute:!1})],f.prototype,"config");$([d.property({attribute:!1})],f.prototype,"autocomplete");$([d.state()],f.prototype,"_activeFieldKey");$([d.state()],f.prototype,"_staged");$([d.state()],f.prototype,"_selected");$([d.state()],f.prototype,"_sortAsc");$([d.state()],f.prototype,"_pendingOp");customElements.define("sfx-bulk-metadata-modal",f);const Ie={text:o.html`<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
1448
+ ${o.svg`<path d="M4 3h8M8 3v10"/>`}
1449
+ </svg>`,textarea:o.html`<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round">
1450
+ ${o.svg`<line x1="3" y1="4" x2="13" y2="4"/><line x1="3" y1="7" x2="13" y2="7"/><line x1="3" y1="10" x2="9" y2="10"/>`}
1451
+ </svg>`,"select-one":o.html`<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
1452
+ ${o.svg`<rect x="2" y="3" width="12" height="10" rx="2"/><polyline points="6 7 8 9.5 10 7"/>`}
1453
+ </svg>`,"multi-select":o.html`<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
1454
+ ${o.svg`<rect x="2" y="2" width="5" height="5" rx="1"/><polyline points="3 4.5 4.2 6 6 3"/><rect x="2" y="9" width="5" height="5" rx="1"/><line x1="9" y1="4.5" x2="14" y2="4.5"/><line x1="9" y1="11.5" x2="14" y2="11.5"/>`}
1455
+ </svg>`,boolean:o.html`<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
1456
+ ${o.svg`<rect x="2" y="4.5" width="12" height="7" rx="3.5"/><circle cx="10.5" cy="8" r="2" fill="currentColor" stroke="none"/>`}
1457
+ </svg>`,date:o.html`<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
1458
+ ${o.svg`<rect x="2" y="3" width="12" height="11" rx="2"/><line x1="2" y1="7" x2="14" y2="7"/><line x1="5.5" y1="1.5" x2="5.5" y2="4.5"/><line x1="10.5" y1="1.5" x2="10.5" y2="4.5"/>`}
1459
+ </svg>`,numeric:o.html`<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round">
1460
+ ${o.svg`<line x1="6" y1="2" x2="4.5" y2="14"/><line x1="11.5" y1="2" x2="10" y2="14"/><line x1="3" y1="6" x2="13" y2="6"/><line x1="3" y1="10" x2="13" y2="10"/>`}
1461
+ </svg>`,decimal2:o.html`<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round">
1462
+ ${o.svg`<circle cx="5.5" cy="8" r="3"/><circle cx="12" cy="11" r="1" fill="currentColor" stroke="none"/><line x1="10" y1="5" x2="13" y2="5"/><line x1="10" y1="8" x2="13" y2="8"/>`}
1463
+ </svg>`,geopoint:o.html`<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
1464
+ ${o.svg`<path d="M8 1.5a4.5 4.5 0 0 1 4.5 4.5c0 3.5-4.5 8.5-4.5 8.5S3.5 9.5 3.5 6A4.5 4.5 0 0 1 8 1.5Z"/><circle cx="8" cy="6" r="1.5"/>`}
1465
+ </svg>`,"integer-list":o.html`<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round">
1466
+ ${o.svg`<line x1="7" y1="4" x2="14" y2="4"/><line x1="7" y1="8" x2="14" y2="8"/><line x1="7" y1="12" x2="14" y2="12"/><text x="2" y="5.5" font-size="4.5" fill="currentColor" stroke="none" font-family="inherit">1</text><text x="2" y="9.5" font-size="4.5" fill="currentColor" stroke="none" font-family="inherit">2</text><text x="2" y="13.5" font-size="4.5" fill="currentColor" stroke="none" font-family="inherit">3</text>`}
1467
+ </svg>`,tags:o.html`<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
1468
+ ${o.svg`<path d="M1.5 2.5h5.6l7.4 5.5-5.5 5.5-7.5-5.4z"/><circle cx="5" cy="6" r="1" fill="currentColor" stroke="none"/>`}
1469
+ </svg>`,"attachment-uri":o.html`<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
1470
+ ${o.svg`<path d="M7 9l2-2"/><path d="M9.5 6.5l1.8-1.8a2.1 2.1 0 0 1 3 3L12.5 9.5"/><path d="M6.5 9.5L4.7 11.3a2.1 2.1 0 0 1-3-3L3.5 6.5"/>`}
1471
+ </svg>`};function gt(a){return Ie[a]??Ie.text}var xt=Object.defineProperty,H=(a,e,t,s)=>{for(var i=void 0,n=a.length-1,r;n>=0;n--)(r=a[n])&&(i=r(e,t,i)||i);return i&&xt(e,t,i),i};const ke=class ke extends o.LitElement{constructor(){super(...arguments),this.activeFieldKey="",this.filledFields=new Set,this.config=null,this._collapsed=new Set}_isRequired(e){var t,s;return(s=(t=this.config)==null?void 0:t.requiredFields)!=null&&s.includes(e.ckey)?!0:e.required===1}_toggleGroup(e){const t=new Set(this._collapsed);t.has(e)?t.delete(e):t.add(e),this._collapsed=t}_onFieldClick(e){this.dispatchEvent(new CustomEvent("field-select",{detail:{fieldKey:e},bubbles:!0,composed:!0}))}render(){return this.schema?o.html`
1472
+ ${this.schema.groups.map(e=>{const t=!this._collapsed.has(e.uuid);return o.html`
1473
+ <button
1474
+ class="group-label"
1475
+ @click=${()=>this._toggleGroup(e.uuid)}
1476
+ aria-expanded=${t}
1477
+ >
1478
+ <span class="group-label-text">${e.name}</span>
1479
+ <svg class="group-chevron ${t?"open":""}" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
1480
+ <polyline points="4 6 8 10 12 6"/>
1481
+ </svg>
1482
+ </button>
1483
+ ${t?e.fields.map(s=>o.html`
1484
+ <button
1485
+ class="field-item ${this.activeFieldKey===s.key?"active":""}"
1486
+ @click=${()=>this._onFieldClick(s.key)}
1487
+ >
1488
+ <span class="field-icon" aria-hidden="true">${gt(s.type)}</span>
1489
+ <span class="field-name">${s.title}</span>
1490
+ ${this.filledFields.has(s.key)?o.html`<span class="field-dot"></span>`:o.nothing}
1491
+ ${this._isRequired(s)?o.html`<span class="field-required" aria-hidden="true">*</span>`:o.nothing}
1492
+ </button>
1493
+ `):o.nothing}
1494
+ `})}
1495
+ `:o.nothing}};ke.styles=[ct];let C=ke;H([d.property({attribute:!1})],C.prototype,"schema");H([d.property({attribute:!1})],C.prototype,"activeFieldKey");H([d.property({attribute:!1})],C.prototype,"filledFields");H([d.property({attribute:!1})],C.prototype,"config");H([d.state()],C.prototype,"_collapsed");customElements.define("sfx-bulk-meta-sidebar",C);var bt=Object.defineProperty,q=(a,e,t,s)=>{for(var i=void 0,n=a.length-1,r;n>=0;n--)(r=a[n])&&(i=r(e,t,i)||i);return i&&bt(e,t,i),i},O;const S=(O=class extends o.LitElement{constructor(){super(...arguments),this.config=null,this.selectedCount=0,this._operation="SET",this._value=void 0,this._opDropdownOpen=!1,this._availableOps=[],this._onOpDropdownClose=e=>{e.composedPath().includes(this)||(this._opDropdownOpen=!1)},this._onFieldBlur=e=>{e.stopPropagation(),this._value=e.detail.value,this._emitPendingChange()},this._onFieldChange=e=>{e.stopPropagation(),this._value=e.detail.value,this._emitPendingChange()},this._onFieldEscape=e=>{e.stopPropagation()}}static _emptyValueForType(e){switch(e){case"multi-select":case"tags":case"integer-list":return[];case"boolean":return"null";case"geopoint":return{latitude:"",longitude:""};default:return""}}get _effectiveValue(){var e;return this._value??O._emptyValueForType((e=this.field)==null?void 0:e.type)}willUpdate(e){e.has("field")&&this.field&&(this._availableOps=lt(this.field.type),this._operation="SET",this._value=void 0,this._emitPendingChange())}_onOpSelect(e){this._operation=e,this._opDropdownOpen=!1,this._emitPendingChange()}_onOpToggle(){this._opDropdownOpen=!this._opDropdownOpen}connectedCallback(){super.connectedCallback(),document.addEventListener("click",this._onOpDropdownClose)}disconnectedCallback(){super.disconnectedCallback(),document.removeEventListener("click",this._onOpDropdownClose)}_emitPendingChange(){this.dispatchEvent(new CustomEvent("pending-change",{detail:{operation:this._operation,value:this._value},bubbles:!0,composed:!0}))}_onApply(){this._isApplyDisabled||(this.dispatchEvent(new CustomEvent("bulk-apply",{detail:{operation:this._operation,value:this._value},bubbles:!0,composed:!0})),this._value=void 0,this._emitPendingChange())}_onClear(){this._value=void 0,this._emitPendingChange()}get _isApplyDisabled(){return this.selectedCount===0?!0:this._operation==="DELETE"?!1:y(this._value)}render(){if(!this.field)return o.nothing;const e=this._availableOps.length>1,t=this._availableOps.find(s=>s.key===this._operation);return o.html`
1496
+ <div class="op-bar">
1497
+ <span class="op-label">Operation:</span>
1498
+
1499
+ ${e?o.html`
1500
+ <div class="op-dropdown-wrap">
1501
+ <button class="op-trigger" @click=${this._onOpToggle}>
1502
+ <span>${(t==null?void 0:t.label)??"Set"}</span>
1503
+ <span class="op-arrow">\u25BE</span>
1504
+ </button>
1505
+ ${this._opDropdownOpen?o.html`
1506
+ <div class="op-menu">
1507
+ ${this._availableOps.map(s=>o.html`
1508
+ <button
1509
+ class="op-option ${s.key===this._operation?"active":""}"
1510
+ @click=${()=>this._onOpSelect(s.key)}
1511
+ >
1512
+ ${s.label}
1513
+ </button>
1514
+ `)}
1515
+ </div>
1516
+ `:o.nothing}
1517
+ </div>
1518
+ `:o.html`<span class="op-label">${(t==null?void 0:t.label)??"Set"}</span>`}
1519
+
1520
+ <div
1521
+ class="op-value"
1522
+ @field-blur=${this._onFieldBlur}
1523
+ @field-change=${this._onFieldChange}
1524
+ @field-escape=${this._onFieldEscape}
1525
+ >
1526
+ <sfx-metadata-field-edit
1527
+ .field=${this.field}
1528
+ .value=${this._effectiveValue}
1529
+ .autocomplete=${this.autocomplete}
1530
+ ></sfx-metadata-field-edit>
1531
+ </div>
1532
+
1533
+ ${y(this._value)?o.nothing:o.html`
1534
+ <button
1535
+ class="btn-clear"
1536
+ @click=${this._onClear}
1537
+ title="Clear"
1538
+ aria-label="Clear input"
1539
+ >
1540
+ <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round">
1541
+ <line x1="18" y1="6" x2="6" y2="18" /><line x1="6" y1="6" x2="18" y2="18" />
1542
+ </svg>
1543
+ </button>
1544
+ `}
1545
+
1546
+ <button
1547
+ class="btn-apply"
1548
+ ?disabled=${this._isApplyDisabled}
1549
+ @click=${this._onApply}
1550
+ >
1551
+ Apply
1552
+ </button>
1553
+ </div>
1554
+ `}},O.styles=[pt],O);q([d.property({attribute:!1})],S.prototype,"field");q([d.property({attribute:!1})],S.prototype,"autocomplete");q([d.property({attribute:!1})],S.prototype,"config");q([d.property({type:Number})],S.prototype,"selectedCount");q([d.state()],S.prototype,"_operation");q([d.state()],S.prototype,"_value");q([d.state()],S.prototype,"_opDropdownOpen");let vt=S;customElements.define("sfx-bulk-meta-op-bar",vt);var yt=Object.defineProperty,F=(a,e,t,s)=>{for(var i=void 0,n=a.length-1,r;n>=0;n--)(r=a[n])&&(i=r(e,t,i)||i);return i&&yt(e,t,i),i};const $e=class $e extends o.LitElement{constructor(){super(...arguments),this.files=[],this.staged=new Map,this.selected=new Set,this.config=null,this.pendingOp=null}_getEffectiveValue(e){var t;return((t=this.staged.get(e.id))==null?void 0:t.get(this.field.key))??e.meta[this.field.key]}render(){return o.html`
1555
+ ${this.files.map(e=>o.html`
1556
+ <sfx-bulk-meta-row
1557
+ .file=${e}
1558
+ .field=${this.field}
1559
+ .value=${this._getEffectiveValue(e)}
1560
+ .selected=${this.selected.has(e.id)}
1561
+ .config=${this.config}
1562
+ .autocomplete=${this.autocomplete}
1563
+ .pendingOp=${this.selected.has(e.id)?this.pendingOp:null}
1564
+ ></sfx-bulk-meta-row>
1565
+ `)}
1566
+ `}};$e.styles=[ft];let v=$e;F([d.property({attribute:!1})],v.prototype,"files");F([d.property({attribute:!1})],v.prototype,"field");F([d.property({attribute:!1})],v.prototype,"staged");F([d.property({attribute:!1})],v.prototype,"selected");F([d.property({attribute:!1})],v.prototype,"config");F([d.property({attribute:!1})],v.prototype,"autocomplete");F([d.property({attribute:!1})],v.prototype,"pendingOp");customElements.define("sfx-bulk-meta-table",v);const _t=new Set(["multi-select","tags","integer-list"]);function Ae(a,e,t){return!e.regional_variants_group_uuid||a==null||typeof a!="object"||Array.isArray(a)?a:a[t??"en"]}function Oe(a){return Array.isArray(a)?a:[]}function De(a){return!!(a==null||a===""||Array.isArray(a)&&a.length===0)}function te(a,e){var s;const t=(s=a.possible_values)==null?void 0:s.find(i=>i.internal_unique_value===e||i.api_value===e);return(t==null?void 0:t.label)??String(e)}function ze(a,e){if(e==null||e==="")return"";switch(a.type){case"boolean":return e===!0?"True":e===!1?"False":"None";case"date":{if(typeof e!="string"||e.length===0)return"";try{return new Date(e+"T00:00").toLocaleDateString(void 0,{year:"numeric",month:"short",day:"numeric"})}catch{return e}}case"numeric":{const t=Number(e);return Number.isFinite(t)?t.toLocaleString(void 0,{maximumFractionDigits:0}):String(e)}case"decimal2":{const t=Number(e);return Number.isFinite(t)?t.toLocaleString(void 0,{maximumFractionDigits:2}):String(e)}case"select-one":return te(a,String(e));case"geopoint":{if(typeof e=="string"){const t=e.match(/^\((.+),(.+)\)$/);if(t)return`(${t[1].trim()}, ${t[2].trim()})`}return String(e)}default:return String(e)}}function wt(a,e){const t=a.map(l=>typeof l=="string"?l:String(l)),s=e.map(l=>typeof l=="string"?l:String(l)),i=new Set(t),n=new Set(s),r=[];for(const l of s)r.push({label:l,state:i.has(l)?"kept":"added"});for(const l of t)n.has(l)||r.push({label:l,state:"removed"});return r}function kt(a,e,t){const s=new Set(a.map(r=>JSON.stringify(r))),i=new Set(e.map(r=>JSON.stringify(r))),n=[];for(const r of e){const l=JSON.stringify(r),c=typeof r=="string"?te(t,r):String(r);n.push({label:c,state:s.has(l)?"kept":"added"})}for(const r of a){const l=JSON.stringify(r);if(!i.has(l)){const c=typeof r=="string"?te(t,r):String(r);n.push({label:c,state:"removed"})}}return n}function $t(a,e,t,s){const i=s==null?void 0:s.language,n=Ae(e,a,i),r=Ae(t,a,i);if(_t.has(a.type)){const l=Oe(n),c=Oe(r);return a.type==="tags"?{kind:"array",items:wt(l,c)}:{kind:"array",items:kt(l,c,a)}}return{kind:"scalar",oldDisplay:ze(a,n),newDisplay:ze(a,r),oldEmpty:De(n),newEmpty:De(r)}}var Ct=Object.defineProperty,G=(a,e,t,s)=>{for(var i=void 0,n=a.length-1,r;n>=0;n--)(r=a[n])&&(i=r(e,t,i)||i);return i&&Ct(e,t,i),i};const Ce=class Ce extends o.LitElement{constructor(){super(...arguments),this.config=null}_renderArrayDiff(e){return o.html`
1567
+ <div class="diff-wrap" aria-label="Bulk operation preview">
1568
+ ${e.items.length===0?o.html`<span class="diff-chip diff-chip--kept" style="opacity:0.5">\u2014</span>`:e.items.map(t=>o.html`
1569
+ <span
1570
+ class="diff-chip diff-chip--${t.state}"
1571
+ aria-label="${t.state==="added"?"Added":t.state==="removed"?"Removed":"Kept"}: ${t.label}"
1572
+ >
1573
+ ${t.state==="removed"?o.html`<s>${t.label}</s>`:t.label}
1574
+ </span>
1575
+ `)}
1576
+ </div>
1577
+ `}_renderScalarDiff(e){const t=`Will change from ${e.oldEmpty?"empty":e.oldDisplay} to ${e.newEmpty?"empty":e.newDisplay}`;return o.html`
1578
+ <div class="diff-wrap diff-scalar-text" aria-label="Bulk operation preview">
1579
+ <span class="sr-only">${t}</span>
1580
+ ${e.oldEmpty?o.nothing:o.html`
1581
+ <span class="diff-old" aria-hidden="true"><s>${e.oldDisplay}</s></span>
1582
+ ${e.newEmpty?o.nothing:o.html`<span class="diff-arrow" aria-hidden="true">\u2192</span>`}
1583
+ `}
1584
+ ${e.newEmpty?o.nothing:o.html`<span class="diff-new" aria-hidden="true">${e.newDisplay}</span>`}
1585
+ </div>
1586
+ `}render(){if(!this.field)return o.nothing;const e=$t(this.field,this.oldValue,this.newValue,this.config);return e.kind==="array"?this._renderArrayDiff(e):this._renderScalarDiff(e)}};Ce.styles=[ht];let z=Ce;G([d.property({attribute:!1})],z.prototype,"field");G([d.property({attribute:!1})],z.prototype,"oldValue");G([d.property({attribute:!1})],z.prototype,"newValue");G([d.property({attribute:!1})],z.prototype,"config");customElements.define("sfx-bulk-meta-diff-view",z);var St=Object.defineProperty,E=(a,e,t,s)=>{for(var i=void 0,n=a.length-1,r;n>=0;n--)(r=a[n])&&(i=r(e,t,i)||i);return i&&St(e,t,i),i};const Se=class Se extends o.LitElement{constructor(){super(...arguments),this.selected=!1,this.config=null,this.pendingOp=null,this._error=null,this._onFieldBlur=e=>{var r;e.stopPropagation();const{value:t}=e.detail,s=re(this.field,t,this.config??void 0);if(s){this._error=s;return}this._error=null;const i={meta:{...this.file.meta,[this.field.key]:this.value}},n=K(this.field,t,i,(r=this.config)==null?void 0:r.language);JSON.stringify(n)!==JSON.stringify(this.value)&&this.dispatchEvent(new CustomEvent("row-field-change",{detail:{fileId:this.file.id,value:n},bubbles:!0,composed:!0}))}}willUpdate(e){e.has("field")&&(this._error=null)}_onCheckboxChange(){this.dispatchEvent(new CustomEvent("row-toggle",{detail:{fileId:this.file.id},bubbles:!0,composed:!0}))}_getExtension(e){const t=e.lastIndexOf(".");return t>0?e.slice(t+1).toUpperCase():"?"}_computePreview(){var l;if(!this.pendingOp)return null;const{operation:e,value:t}=this.pendingOp,s=(l=this.config)==null?void 0:l.language,i={meta:{...this.file.meta,[this.field.key]:this.value}},n=K(this.field,t,i,s),r=Be(e,this.value,n,this.field.type);return JSON.stringify(r)===JSON.stringify(this.value)?null:r}render(){var i;const e=this.file,t=this._computePreview(),s=t!==null;return o.html`
1587
+ <div class="row ${s?"row--changed":""}">
1588
+ <div class="row-check">
1589
+ <input
1590
+ type="checkbox"
1591
+ class="fm-checkbox"
1592
+ .checked=${this.selected}
1593
+ @change=${this._onCheckboxChange}
1594
+ />
1595
+ </div>
1596
+
1597
+ ${e.previewUrl?o.html`<img class="row-thumb" src=${e.previewUrl} alt="" />`:o.html`<div class="row-thumb-placeholder">${this._getExtension(e.name)}</div>`}
1598
+
1599
+ <div class="row-name" title=${e.name}>${e.name}</div>
1600
+ <div class="row-size">${e.size?je.formatFileSize(e.size):"—"}</div>
1601
+
1602
+ <div
1603
+ class="row-field"
1604
+ @field-blur=${this._onFieldBlur}
1605
+ >
1606
+ ${s?o.html`
1607
+ <sfx-bulk-meta-diff-view
1608
+ .field=${this.field}
1609
+ .oldValue=${this.value}
1610
+ .newValue=${t}
1611
+ .config=${this.config}
1612
+ ></sfx-bulk-meta-diff-view>
1613
+ `:o.html`
1614
+ <div class="row-field-edit">
1615
+ <sfx-metadata-field-edit
1616
+ .field=${this.field}
1617
+ .value=${se(this.field,this.value,(i=this.config)==null?void 0:i.language)}
1618
+ .autocomplete=${this.autocomplete}
1619
+ ></sfx-metadata-field-edit>
1620
+ </div>
1621
+ `}
1622
+ ${this._error?o.html`<div class="row-error" role="alert">${this._error}</div>`:o.nothing}
1623
+ </div>
1624
+ </div>
1625
+ `}};Se.styles=[ut];let x=Se;E([d.property({attribute:!1})],x.prototype,"file");E([d.property({attribute:!1})],x.prototype,"field");E([d.property({attribute:!1})],x.prototype,"value");E([d.property({type:Boolean})],x.prototype,"selected");E([d.property({attribute:!1})],x.prototype,"config");E([d.property({attribute:!1})],x.prototype,"autocomplete");E([d.property({attribute:!1})],x.prototype,"pendingOp");E([d.state()],x.prototype,"_error");customElements.define("sfx-bulk-meta-row",x);exports.SfxBulkMetadataModal=f;exports.clearSchemaCache=Ve;exports.createTagsAutocomplete=Ue;exports.deepMergeMeta=He;exports.fetchMetadataSchema=Ne;exports.getFilesWithMissingRequired=Je;exports.isAssetHasMetadataValue=qe;exports.isEmpty=y;exports.mapValueFromBackend=se;exports.mapValueToBackend=K;exports.parseMetadataSchema=ie;exports.validateField=re;