inesbedar commited on
Commit
e6cc26b
·
verified ·
1 Parent(s): d35cf0f

Delete app.py

Browse files
Files changed (1) hide show
  1. app.py +0 -1006
app.py DELETED
@@ -1,1006 +0,0 @@
1
- import streamlit as st
2
-
3
- # ─────────────────────────────────────────────
4
- # REGMAP — AI System ID Card
5
- # ─────────────────────────────────────────────
6
-
7
- st.set_page_config(
8
- page_title="RegMap — AI System ID Card",
9
- page_icon="◈",
10
- layout="centered",
11
- )
12
-
13
- # ── Visual Identity ──
14
- st.markdown("""
15
- <style>
16
- @import url('https://fonts.googleapis.com/css2?family=DM+Sans:ital,opsz,wght@0,9..40,100..1000;1,9..40,100..1000&display=swap');
17
- @import url('https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&display=swap');
18
-
19
- html, body, [class*="css"] { font-family: 'DM Sans', sans-serif; }
20
- .stApp { background-color: #F7F8FA; }
21
-
22
- /* ── Dark text override for HF Spaces dark mode ──
23
- Excludes .rmh (RegMap Header) elements */
24
- .stApp p:not(.rmh-el), .stApp span:not(.rmh-el), .stApp label,
25
- .stApp h1, .stApp h2, .stApp h3, .stApp h4,
26
- .stApp li, .stApp strong:not(.rmh-el), .stApp em,
27
- [data-testid="stMarkdownContainer"] p:not(.rmh-el),
28
- [data-testid="stMarkdownContainer"] h4,
29
- [data-testid="stMarkdownContainer"] strong:not(.rmh-el),
30
- [data-testid="stMarkdownContainer"] li {
31
- color: #1E293B !important;
32
- }
33
-
34
- /* ── Header ── */
35
- .rmh {
36
- background: linear-gradient(135deg, #0F2B46 0%, #143A5C 60%, #0F2B46 100%);
37
- padding: 2rem 2.2rem 1.6rem 2.2rem;
38
- border-radius: 14px;
39
- margin-bottom: 1.8rem;
40
- position: relative;
41
- overflow: hidden;
42
- border: 1px solid rgba(255,255,255,0.04);
43
- }
44
- .rmh::before {
45
- content: '';
46
- position: absolute;
47
- top: -50%; right: -20%;
48
- width: 60%; height: 200%;
49
- background: radial-gradient(ellipse, rgba(13,148,136,0.15) 0%, transparent 70%);
50
- pointer-events: none;
51
- }
52
- .rmh::after {
53
- content: '';
54
- position: absolute;
55
- bottom: 0; left: 0;
56
- width: 100%; height: 1px;
57
- background: linear-gradient(90deg, transparent, rgba(45,212,191,0.3), transparent);
58
- }
59
- .rmh-logo {
60
- font-family: 'Space Grotesk', sans-serif !important;
61
- font-size: 1.7rem !important; font-weight: 700 !important;
62
- letter-spacing: -0.02em !important;
63
- color: #FFFFFF !important;
64
- margin: 0 !important; position: relative; z-index: 1;
65
- line-height: 1.2 !important;
66
- }
67
- .rmh-accent { color: #2DD4BF !important; }
68
- .rmh-tagline {
69
- font-family: 'DM Sans', sans-serif !important;
70
- color: #8BA3BB !important;
71
- font-size: 0.82rem !important;
72
- font-weight: 400 !important;
73
- letter-spacing: 0.03em !important;
74
- margin: 0.35rem 0 0 0 !important;
75
- position: relative; z-index: 1;
76
- }
77
- .rmh-badges {
78
- display: flex; gap: 0.45rem;
79
- margin-top: 0.9rem;
80
- position: relative; z-index: 1;
81
- }
82
- .rmh-badge {
83
- background: rgba(45,212,191,0.08) !important;
84
- border: 1px solid rgba(45,212,191,0.2) !important;
85
- border-radius: 5px !important;
86
- padding: 0.18rem 0.55rem !important;
87
- font-family: 'Space Grotesk', sans-serif !important;
88
- font-size: 0.68rem !important;
89
- font-weight: 600 !important;
90
- color: #5EEAD4 !important;
91
- letter-spacing: 0.06em !important;
92
- text-transform: uppercase !important;
93
- }
94
-
95
- /* ── Progress ── */
96
- .progress-container {
97
- background: #E2E8F0; border-radius: 8px;
98
- height: 5px; margin-bottom: 0.4rem;
99
- }
100
- .progress-fill {
101
- background: linear-gradient(90deg, #0D9488, #2DD4BF);
102
- height: 5px; border-radius: 8px;
103
- transition: width 0.4s ease;
104
- }
105
- .progress-label {
106
- color: #64748B !important; font-size: 0.78rem;
107
- font-weight: 500; margin-bottom: 1.5rem;
108
- }
109
-
110
- /* ── Screen title ── */
111
- .screen-title {
112
- font-family: 'Space Grotesk', sans-serif;
113
- color: #0F2B46 !important; font-size: 1.15rem;
114
- font-weight: 700; letter-spacing: -0.01em;
115
- margin-bottom: 0.2rem;
116
- }
117
- .screen-subtitle {
118
- color: #64748B !important; font-size: 0.82rem;
119
- font-weight: 400; margin-bottom: 1.5rem;
120
- line-height: 1.4;
121
- }
122
-
123
- /* ── Buttons ── */
124
- .stButton > button {
125
- font-family: 'DM Sans', sans-serif;
126
- font-weight: 600; font-size: 0.85rem;
127
- border-radius: 8px; padding: 0.45rem 1.5rem;
128
- color: #FFFFFF !important;
129
- }
130
-
131
- /* ── Summary cards ── */
132
- .summary-section {
133
- background: #F8FAFB;
134
- border: 1px solid #E2E8F0;
135
- border-left: 3px solid #0D9488;
136
- border-radius: 8px;
137
- padding: 1rem 1.3rem;
138
- margin-bottom: 0.8rem;
139
- }
140
- .summary-section h4 {
141
- color: #0F2B46 !important;
142
- font-family: 'Space Grotesk', sans-serif;
143
- font-size: 0.88rem; font-weight: 700;
144
- margin: 0 0 0.5rem 0;
145
- }
146
- .summary-section p {
147
- color: #334155 !important; font-size: 0.85rem;
148
- margin: 0.15rem 0; line-height: 1.5;
149
- }
150
-
151
- /* ── Widget spacing ── */
152
- .stSelectbox, .stMultiSelect, .stTextInput, .stTextArea { margin-bottom: 0.6rem; }
153
-
154
- /* ── Widget labels (belt-and-suspenders) ── */
155
- .stSelectbox label, .stMultiSelect label, .stTextInput label, .stTextArea label,
156
- .stRadio label, .stCheckbox label, .stSlider label {
157
- color: #1E293B !important;
158
- }
159
- .stSelectbox label p, .stMultiSelect label p, .stTextInput label p, .stTextArea label p,
160
- .stRadio label p, .stCheckbox label p, .stSlider label p {
161
- color: #1E293B !important;
162
- }
163
- .stRadio div[role="radiogroup"] label p,
164
- .stRadio div[role="radiogroup"] label span,
165
- .stRadio div[role="radiogroup"] label,
166
- [data-testid="stRadio"] label p,
167
- [data-testid="stRadio"] label span,
168
- [data-testid="stRadio"] label,
169
- [data-testid="stWidgetLabel"] p,
170
- [data-testid="stWidgetLabel"] span {
171
- color: #1E293B !important;
172
- }
173
- .stMarkdown h4, .stMarkdown p:not(.rmh-el), .stMarkdown strong:not(.rmh-el), .stMarkdown em,
174
- .stMarkdown li, .stMarkdown span:not(.rmh-el),
175
- [data-testid="stMarkdownContainer"] span:not(.rmh-el) {
176
- color: #1E293B !important;
177
- }
178
- .stAlert p, .stAlert span,
179
- [data-testid="stAlert"] p,
180
- [data-testid="stAlert"] span {
181
- color: #1E293B !important;
182
- }
183
- [data-testid="stCaptionContainer"] p,
184
- [data-testid="stCaptionContainer"] span {
185
- color: #64748B !important;
186
- }
187
-
188
- /* ── Beta disclaimer ── */
189
- .beta-disclaimer {
190
- background: #FEF3C7;
191
- border: 1px solid #F59E0B;
192
- border-radius: 8px;
193
- padding: 0.8rem 1rem;
194
- margin-bottom: 1rem;
195
- color: #92400E !important;
196
- font-size: 0.82rem;
197
- line-height: 1.5;
198
- }
199
- .beta-disclaimer strong { color: #92400E !important; }
200
-
201
- /* ── Regulation banner ── */
202
- .reg-banner {
203
- background: linear-gradient(135deg, #0F2B46 0%, #143A5C 100%);
204
- border: 1px solid rgba(45,212,191,0.2);
205
- border-radius: 12px;
206
- padding: 1.5rem 1.8rem;
207
- margin: 1.5rem 0 1rem 0;
208
- }
209
- .reg-banner-title {
210
- font-family: 'Space Grotesk', sans-serif !important;
211
- font-size: 1rem !important;
212
- font-weight: 700 !important;
213
- color: #FFFFFF !important;
214
- margin: 0 0 0.8rem 0 !important;
215
- }
216
- .reg-banner-list {
217
- list-style: none !important;
218
- padding: 0 !important;
219
- margin: 0 0 1rem 0 !important;
220
- }
221
- .reg-banner-list li {
222
- color: #E2E8F0 !important;
223
- font-size: 0.85rem !important;
224
- padding: 0.35rem 0 !important;
225
- border-bottom: 1px solid rgba(255,255,255,0.06) !important;
226
- }
227
- .reg-banner-list li:last-child { border-bottom: none !important; }
228
- .reg-tag {
229
- display: inline-block !important;
230
- background: rgba(45,212,191,0.15) !important;
231
- color: #5EEAD4 !important;
232
- font-size: 0.65rem !important;
233
- font-weight: 600 !important;
234
- padding: 0.1rem 0.4rem !important;
235
- border-radius: 4px !important;
236
- margin-right: 0.5rem !important;
237
- vertical-align: middle !important;
238
- letter-spacing: 0.03em !important;
239
- }
240
- .reg-banner-cta {
241
- color: #E2E8F0 !important;
242
- font-size: 0.9rem !important;
243
- font-weight: 700 !important;
244
- margin: 0.5rem 0 0 0 !important;
245
- }
246
- .reg-section-label {
247
- color: #5EEAD4 !important;
248
- font-size: 0.7rem !important;
249
- font-weight: 700 !important;
250
- letter-spacing: 0.08em !important;
251
- text-transform: uppercase !important;
252
- margin: 0.8rem 0 0.3rem 0 !important;
253
- padding-top: 0.6rem !important;
254
- border-top: 1px solid rgba(255,255,255,0.08) !important;
255
- }
256
- .reg-section-label-first {
257
- color: #5EEAD4 !important;
258
- font-size: 0.7rem !important;
259
- font-weight: 700 !important;
260
- letter-spacing: 0.08em !important;
261
- text-transform: uppercase !important;
262
- margin: 0 0 0.3rem 0 !important;
263
- padding-top: 0 !important;
264
- border-top: none !important;
265
- }
266
-
267
- /* ── Hide branding ── */
268
- #MainMenu {visibility: hidden;}
269
- footer {visibility: hidden;}
270
- header {visibility: hidden;}
271
- </style>
272
- """, unsafe_allow_html=True)
273
-
274
-
275
- # ── Reference Data ──
276
-
277
- INDUSTRY_SECTORS = [
278
- "Agriculture & Food", "Automotive & Transportation",
279
- "Banking & Financial Services", "Construction & Real Estate",
280
- "Consulting & Professional Services", "Defence & Security",
281
- "Education & Training", "Energy & Utilities",
282
- "Entertainment & Media", "Environmental Services",
283
- "Government & Public Administration", "Healthcare & Life Sciences",
284
- "Hospitality & Tourism", "Human Resources & Recruitment",
285
- "Insurance", "Legal Services", "Logistics & Supply Chain",
286
- "Manufacturing", "Mining & Natural Resources", "Non-Profit & NGO",
287
- "Pharmaceuticals", "Retail & E-commerce", "Telecommunications",
288
- "Technology & Software", "Other",
289
- ]
290
-
291
- US_STATES = [
292
- "Alabama", "Alaska", "Arizona", "Arkansas", "California", "Colorado",
293
- "Connecticut", "Delaware", "Florida", "Georgia", "Hawaii", "Idaho",
294
- "Illinois", "Indiana", "Iowa", "Kansas", "Kentucky", "Louisiana",
295
- "Maine", "Maryland", "Massachusetts", "Michigan", "Minnesota",
296
- "Mississippi", "Missouri", "Montana", "Nebraska", "Nevada",
297
- "New Hampshire", "New Jersey", "New Mexico", "New York",
298
- "North Carolina", "North Dakota", "Ohio", "Oklahoma", "Oregon",
299
- "Pennsylvania", "Rhode Island", "South Carolina", "South Dakota",
300
- "Tennessee", "Texas", "Utah", "Vermont", "Virginia", "Washington",
301
- "West Virginia", "Wisconsin", "Wyoming", "District of Columbia",
302
- ]
303
-
304
- # States with specific AI regulation (for downstream analysis)
305
- US_STATES_WITH_AI_REGULATION = [
306
- "California", "Colorado", "Connecticut", "Illinois", "Texas", "Utah",
307
- ]
308
-
309
- EU_COUNTRIES = [
310
- "Austria", "Belgium", "Bulgaria", "Croatia", "Cyprus", "Czechia",
311
- "Denmark", "Estonia", "Finland", "France", "Germany", "Greece",
312
- "Hungary", "Ireland", "Italy", "Latvia", "Lithuania", "Luxembourg",
313
- "Malta", "Netherlands", "Poland", "Portugal", "Romania", "Slovakia",
314
- "Slovenia", "Spain", "Sweden",
315
- "Iceland (EEA)", "Liechtenstein (EEA)", "Norway (EEA)",
316
- ]
317
-
318
- UAE_EMIRATES = [
319
- "Dubai", "Abu Dhabi", "Sharjah", "Ajman",
320
- "Fujairah", "Ras Al Khaimah", "Umm Al Quwain",
321
- ]
322
-
323
- UAE_FREE_ZONES = {
324
- "Dubai": ["DIFC", "DMCC", "JAFZA", "Dubai Internet City",
325
- "Dubai Media City", "Dubai Silicon Oasis", "Dubai Healthcare City",
326
- "Dubai Design District (d3)", "Dubai South", "Dubai Knowledge Park",
327
- "DAFZA", "Dubai World Trade Centre", "Dubai Science Park",
328
- "Dubai Textile City", "DUCAMZ", "Dubai Maritime City",
329
- "Meydan Free Zone", "IFZA"],
330
- "Abu Dhabi": ["ADGM", "KIZAD", "Masdar City", "ADAFZ",
331
- "Khalifa Port Free Trade Zone", "Twofour54"],
332
- "Sharjah": ["Sharjah Media City (Shams)", "SAIF Zone",
333
- "Sharjah Publishing City", "Hamriyah Free Zone"],
334
- "Ras Al Khaimah": ["RAKEZ", "RAK Maritime City", "RAK Media City"],
335
- "Ajman": ["Ajman Free Zone"],
336
- "Fujairah": ["Fujairah Free Zone", "Fujairah Creative City"],
337
- "Umm Al Quwain": ["UAQ Free Trade Zone"],
338
- }
339
-
340
- ROLES = [
341
- "Provider — You develop or commission the AI system",
342
- "Deployer — You use an AI system in your operations (you did not build it)",
343
- "Authorised Representative (EU) — You act on behalf of a non-EU provider to fulfill EU AI Act obligations",
344
- "Importer (EU) — You place on the EU market an AI system from a non-EU provider",
345
- "Distributor (EU) — You make an AI system available on the EU market (neither provider nor importer)",
346
- ]
347
-
348
- AI_TYPES = ["Machine Learning (ML)", "Generative AI (GenAI)", "Agentic AI", "Rule-based", "Hybrid"]
349
-
350
- DATA_TYPE_OPTIONS = [
351
- "Personal data (name, email, ID)",
352
- "Sensitive/special category data (health, race, religion, political, sexual orientation)",
353
- "Biometric data",
354
- "Children's data (<18)",
355
- "Financial/credit data",
356
- "Employment/HR data",
357
- "Copyrighted content (text, images, audio, video)",
358
- "Publicly available data only",
359
- "No personal data",
360
- ]
361
-
362
- TRAINING_SOURCES = ["Public web", "Licensed datasets", "Proprietary data", "User-generated content"]
363
- INVOLVEMENT_LEVELS = ["Fully automated", "Human-assisted", "Human decides"]
364
-
365
- ALL_COUNTRIES = [
366
- "Afghanistan", "Albania", "Algeria", "Andorra", "Angola", "Argentina",
367
- "Armenia", "Australia", "Austria", "Azerbaijan", "Bahrain", "Bangladesh",
368
- "Belarus", "Belgium", "Bolivia", "Bosnia and Herzegovina", "Brazil",
369
- "Brunei", "Bulgaria", "Cambodia", "Cameroon", "Canada", "Chile", "China",
370
- "Colombia", "Costa Rica", "Croatia", "Cuba", "Cyprus", "Czechia",
371
- "Denmark", "Dominican Republic", "Ecuador", "Egypt", "El Salvador",
372
- "Estonia", "Ethiopia", "Finland", "France", "Georgia", "Germany",
373
- "Ghana", "Greece", "Guatemala", "Honduras", "Hong Kong", "Hungary",
374
- "Iceland", "India", "Indonesia", "Iran", "Iraq", "Ireland", "Israel",
375
- "Italy", "Jamaica", "Japan", "Jordan", "Kazakhstan", "Kenya", "Kuwait",
376
- "Latvia", "Lebanon", "Libya", "Liechtenstein", "Lithuania", "Luxembourg",
377
- "Malaysia", "Malta", "Mexico", "Moldova", "Monaco", "Mongolia",
378
- "Montenegro", "Morocco", "Mozambique", "Myanmar", "Nepal",
379
- "Netherlands", "New Zealand", "Nicaragua", "Nigeria", "North Korea",
380
- "North Macedonia", "Norway", "Oman", "Pakistan", "Panama",
381
- "Paraguay", "Peru", "Philippines", "Poland", "Portugal", "Qatar",
382
- "Romania", "Russia", "Rwanda", "Saudi Arabia", "Senegal", "Serbia",
383
- "Singapore", "Slovakia", "Slovenia", "Somalia", "South Africa",
384
- "South Korea", "Spain", "Sri Lanka", "Sudan", "Sweden", "Switzerland",
385
- "Syria", "Taiwan", "Tanzania", "Thailand", "Tunisia", "Turkey",
386
- "Uganda", "Ukraine", "United Arab Emirates", "United Kingdom",
387
- "United States", "Uruguay", "Uzbekistan", "Venezuela", "Vietnam",
388
- "Yemen", "Zambia", "Zimbabwe",
389
- ]
390
-
391
-
392
- # ── Session State ──
393
-
394
- TOTAL_SCREENS = 7
395
-
396
- if "screen" not in st.session_state:
397
- st.session_state.screen = 1
398
- if "data" not in st.session_state:
399
- st.session_state.data = {}
400
-
401
-
402
- def go_next():
403
- if st.session_state.screen < TOTAL_SCREENS + 1:
404
- st.session_state.screen += 1
405
-
406
- def go_back():
407
- if st.session_state.screen > 1:
408
- st.session_state.screen -= 1
409
-
410
- def go_to(n):
411
- st.session_state.screen = n
412
-
413
-
414
- # ── Header ──
415
- st.markdown("""
416
- <div class="rmh">
417
- <p class="rmh-logo rmh-el">Reg<span class="rmh-accent rmh-el">Map</span></p>
418
- <p class="rmh-tagline rmh-el">Navigate AI regulation across jurisdictions</p>
419
- <div class="rmh-badges">
420
- <span class="rmh-badge rmh-el">&#127466;&#127482; EU</span>
421
- <span class="rmh-badge rmh-el">&#127482;&#127480; US</span>
422
- <span class="rmh-badge rmh-el">&#127462;&#127466; UAE</span>
423
- </div>
424
- </div>
425
- """, unsafe_allow_html=True)
426
-
427
- # ── Progress ──
428
- current = st.session_state.screen
429
- progress_pct = min((current - 1) / TOTAL_SCREENS * 100, 100)
430
- screen_labels = {
431
- 1: "Screen 1/7 — AI System Identity",
432
- 2: "Screen 2/7 — Application Domain",
433
- 3: "Screen 3/7 — Company Location",
434
- 4: "Screen 4/7 — Geographic Scope",
435
- 5: "Screen 5/7 — Role in Value Chain",
436
- 6: "Screen 6/7 — Technology Profile",
437
- 7: "Screen 7/7 — Data Profile",
438
- 8: "Summary",
439
- }
440
- label = screen_labels.get(current, "")
441
-
442
- st.markdown(f"""
443
- <div class="progress-container"><div class="progress-fill" style="width:{progress_pct}%"></div></div>
444
- <div class="progress-label">{label}</div>
445
- """, unsafe_allow_html=True)
446
-
447
-
448
- # ═══════════════════════════════════════════════
449
- # SCREEN 1: AI System Identity
450
- # ═══════════════════════════════════════════════
451
-
452
- if current == 1:
453
- st.markdown('<p class="screen-title">AI System ID Card</p>', unsafe_allow_html=True)
454
- st.markdown('<p class="screen-subtitle">Basic information about your AI system</p>', unsafe_allow_html=True)
455
-
456
- st.markdown('<div class="beta-disclaimer"><strong>Beta version</strong> — This Space is public by default. We recommend not entering directly identifying data, especially in free text fields.</div>', unsafe_allow_html=True)
457
-
458
- name = st.text_input(
459
- "1.1 — AI system name",
460
- value=st.session_state.data.get("name", ""),
461
- placeholder="e.g. ResumeScreener, ChatAssist, FraudDetect",
462
- )
463
- description = st.text_area(
464
- "1.2 — Brief description",
465
- value=st.session_state.data.get("description", ""),
466
- placeholder="Describe what your AI system does in 1-2 sentences",
467
- height=100,
468
- )
469
-
470
- col1, col2 = st.columns([5, 1])
471
- with col2:
472
- if st.button("Next →", use_container_width=True, disabled=(not name.strip())):
473
- st.session_state.data["name"] = name.strip()
474
- st.session_state.data["description"] = description.strip()
475
- go_next()
476
- st.rerun()
477
-
478
-
479
- # ═══════════════════════════════════════════════
480
- # SCREEN 2: Application Domain
481
- # ═══════════════════════════════════════════════
482
-
483
- elif current == 2:
484
- st.markdown('<p class="screen-title">Application Domain</p>', unsafe_allow_html=True)
485
- st.markdown('<p class="screen-subtitle">Industry sectors where your AI system is used</p>', unsafe_allow_html=True)
486
-
487
- prev_sector = st.session_state.data.get("sector", [])
488
- sector = st.multiselect(
489
- "2.1 — Industry sector(s) (select all that apply)",
490
- INDUSTRY_SECTORS,
491
- default=[s for s in prev_sector if s in INDUSTRY_SECTORS],
492
- )
493
-
494
- col1, col2, col3 = st.columns([1, 3, 1])
495
- with col1:
496
- if st.button("← Back", use_container_width=True):
497
- go_back()
498
- st.rerun()
499
- with col3:
500
- if st.button("Next →", use_container_width=True, disabled=(not sector)):
501
- st.session_state.data["sector"] = sector
502
- go_next()
503
- st.rerun()
504
-
505
-
506
- # ═══════════════════════════════════════════════
507
- # SCREEN 3: Company Location
508
- # ═══════════════════════════════════════════════
509
-
510
- elif current == 3:
511
- st.markdown('<p class="screen-title">Company Location</p>', unsafe_allow_html=True)
512
- st.markdown('<p class="screen-subtitle">Legal establishment of your organization</p>', unsafe_allow_html=True)
513
-
514
- prev_base = st.session_state.data.get("company_base", None)
515
- base_idx = ALL_COUNTRIES.index(prev_base) if prev_base in ALL_COUNTRIES else 0
516
- company_base = st.selectbox(
517
- "3.1 — Country of legal establishment",
518
- ALL_COUNTRIES,
519
- index=base_idx,
520
- key="q_company_base",
521
- )
522
-
523
- col1, col2, col3 = st.columns([1, 3, 1])
524
- with col1:
525
- if st.button("← Back", use_container_width=True):
526
- go_back()
527
- st.rerun()
528
- with col3:
529
- if st.button("Next →", use_container_width=True):
530
- st.session_state.data["company_base"] = company_base
531
- go_next()
532
- st.rerun()
533
-
534
-
535
- # ═══════════════════════════════════════════════
536
- # SCREEN 4: Geographic Scope
537
- # ═══════════════════════════════════════════════
538
-
539
- elif current == 4:
540
- st.markdown('<p class="screen-title">Geographic Scope</p>', unsafe_allow_html=True)
541
- st.markdown('<p class="screen-subtitle">Countries where your AI system has a presence</p>', unsafe_allow_html=True)
542
-
543
- prev_countries = st.session_state.data.get("operating_countries", [])
544
- operating_countries = st.multiselect(
545
- "4.1 — Countries where the AI system is deployed, distributed, or has end users (select all that apply)",
546
- ALL_COUNTRIES,
547
- default=[c for c in prev_countries if c in ALL_COUNTRIES],
548
- key="q_operating_countries",
549
- )
550
-
551
- EU_COUNTRY_NAMES_CLEAN = [c.replace(" (EEA)", "") for c in EU_COUNTRIES]
552
- selected_eu = [c for c in operating_countries if c in EU_COUNTRY_NAMES_CLEAN or c in ["Iceland", "Liechtenstein", "Norway"]]
553
- has_us = "United States" in operating_countries
554
- has_uae = "United Arab Emirates" in operating_countries
555
-
556
- us_states = []
557
- if has_us:
558
- prev_states = st.session_state.data.get("us_states", [])
559
- us_states = st.multiselect(
560
- "4.2 — US states (select all that apply)",
561
- US_STATES,
562
- default=[s for s in prev_states if s in US_STATES],
563
- key="q_us_states",
564
- )
565
-
566
- uae_emirates = []
567
- if has_uae:
568
- prev_emirates = st.session_state.data.get("uae_emirates", [])
569
- uae_emirates = st.multiselect(
570
- "4.3 — UAE emirates (select all that apply)",
571
- UAE_EMIRATES,
572
- default=[e for e in prev_emirates if e in UAE_EMIRATES],
573
- key="q_uae_emirates",
574
- )
575
-
576
- # 4.4 — UAE free zones (if Dubai or Abu Dhabi selected)
577
- uae_free_zones = []
578
- emirates_with_fz = [e for e in uae_emirates if e in UAE_FREE_ZONES]
579
- if emirates_with_fz:
580
- available_fz = []
581
- for em in emirates_with_fz:
582
- available_fz.extend(UAE_FREE_ZONES[em])
583
- prev_fz = st.session_state.data.get("uae_free_zones", [])
584
- uae_free_zones = st.multiselect(
585
- "4.4 — UAE free zones (select all that apply, or leave empty if none)",
586
- available_fz,
587
- default=[f for f in prev_fz if f in available_fz],
588
- key="q_uae_free_zones",
589
- )
590
-
591
- can_proceed = len(operating_countries) > 0
592
- if has_us and not us_states:
593
- can_proceed = False
594
- if has_uae and not uae_emirates:
595
- can_proceed = False
596
-
597
- col1, col2, col3 = st.columns([1, 3, 1])
598
- with col1:
599
- if st.button("← Back", use_container_width=True):
600
- go_back()
601
- st.rerun()
602
- with col3:
603
- if st.button("Next →", use_container_width=True, disabled=(not can_proceed)):
604
- st.session_state.data["operating_countries"] = operating_countries
605
- st.session_state.data["us_states"] = us_states if has_us else []
606
- st.session_state.data["us_states_with_regulation"] = [s for s in us_states if s in US_STATES_WITH_AI_REGULATION] if has_us else []
607
- st.session_state.data["eu_countries"] = selected_eu
608
- st.session_state.data["uae_emirates"] = uae_emirates if has_uae else []
609
- st.session_state.data["uae_free_zones"] = uae_free_zones if has_uae else []
610
- regions = []
611
- if has_us:
612
- regions.append("United States")
613
- if selected_eu:
614
- regions.append("Europe")
615
- if has_uae:
616
- regions.append("UAE")
617
- st.session_state.data["regions"] = regions
618
- go_next()
619
- st.rerun()
620
-
621
-
622
- # ═══════════════════════════════════════════════
623
- # SCREEN 5: Role in Value Chain
624
- # ═══════════════════════════════════════════════
625
-
626
- elif current == 5:
627
- st.markdown('<p class="screen-title">Role in Value Chain</p>', unsafe_allow_html=True)
628
- st.markdown('<p class="screen-subtitle">Your organization\'s position in the AI value chain</p>', unsafe_allow_html=True)
629
-
630
- prev_roles = st.session_state.data.get("roles", [])
631
- roles = st.multiselect(
632
- "5.1 — Organization's role (select all that apply)",
633
- ROLES,
634
- default=[r for r in prev_roles if r in ROLES],
635
- key="q_roles",
636
- )
637
-
638
- col1, col2, col3 = st.columns([1, 3, 1])
639
- with col1:
640
- if st.button("← Back", use_container_width=True):
641
- go_back()
642
- st.rerun()
643
- with col3:
644
- if st.button("Next →", use_container_width=True, disabled=(not roles)):
645
- st.session_state.data["roles"] = roles
646
- go_next()
647
- st.rerun()
648
-
649
-
650
- # ═══════════════════════════════════════════════
651
- # SCREEN 6: Technology Profile
652
- # ═══════════════════════════════════════════════
653
-
654
- elif current == 6:
655
- st.markdown('<p class="screen-title">Technology Profile</p>', unsafe_allow_html=True)
656
- st.markdown('<p class="screen-subtitle">Technical characteristics of your AI system</p>', unsafe_allow_html=True)
657
-
658
- # 6.1 AI type
659
- prev_type = st.session_state.data.get("ai_type", AI_TYPES[0])
660
- type_idx = AI_TYPES.index(prev_type) if prev_type in AI_TYPES else 0
661
- ai_type = st.selectbox("6.1 — AI system type", AI_TYPES, index=type_idx, key="q_ai_type")
662
-
663
- # 6.2 Model type
664
- MODEL_TYPES = [
665
- "Foundation model — general-purpose, trained on broad data (e.g. GPT, Claude, Llama)",
666
- "Fine-tuned model — adapted from a foundation model for specific tasks",
667
- "Task-specific model — built and trained for a single purpose",
668
- ]
669
- prev_model = st.session_state.data.get("model_type", MODEL_TYPES[2])
670
- model_idx = MODEL_TYPES.index(prev_model) if prev_model in MODEL_TYPES else 2
671
- model_type = st.selectbox("6.2 — Model type", MODEL_TYPES, index=model_idx, key="q_model_type")
672
-
673
- # 6.3 Capabilities
674
- CAPABILITY_OPTIONS = [
675
- "Interacts directly with end users",
676
- "Makes or supports decisions that affect individuals",
677
- "Profiles individuals (builds user profiles based on behavior, preferences, or characteristics)",
678
- "Generates synthetic content (text, images, audio, video, code)",
679
- "Performs emotion recognition",
680
- ]
681
- prev_caps = st.session_state.data.get("capabilities", [])
682
- capabilities = st.multiselect(
683
- "6.3 — Capabilities (select all that apply)",
684
- CAPABILITY_OPTIONS,
685
- default=[c for c in prev_caps if c in CAPABILITY_OPTIONS],
686
- key="q_capabilities",
687
- )
688
-
689
- # 6.4 Human involvement — always shown
690
- prev_involvement = st.session_state.data.get("human_involvement", "N/A")
691
- INVOLVEMENT_WITH_NA = ["N/A — no decisions affecting individuals", "Fully automated", "Human-assisted", "Human decides"]
692
- if prev_involvement in INVOLVEMENT_LEVELS:
693
- inv_idx = INVOLVEMENT_WITH_NA.index(prev_involvement)
694
- else:
695
- inv_idx = 0
696
- human_involvement = st.selectbox(
697
- "6.4 — Human involvement in decisions",
698
- INVOLVEMENT_WITH_NA,
699
- index=inv_idx,
700
- key="q_involvement",
701
- )
702
-
703
- # 6.5 Synthetic content types — always shown
704
- SYNTHETIC_TYPES = ["Text", "Images", "Audio", "Video", "Code"]
705
- prev_content = st.session_state.data.get("synthetic_content", [])
706
- synthetic_content = st.multiselect(
707
- "6.5 — Synthetic content types (select all that apply)",
708
- SYNTHETIC_TYPES,
709
- default=[s for s in prev_content if s in SYNTHETIC_TYPES],
710
- key="q_content",
711
- )
712
-
713
- col1, col2, col3 = st.columns([1, 3, 1])
714
- with col1:
715
- if st.button("← Back", use_container_width=True):
716
- go_back()
717
- st.rerun()
718
- with col3:
719
- if st.button("Next →", use_container_width=True):
720
- st.session_state.data["ai_type"] = ai_type
721
- st.session_state.data["model_type"] = model_type
722
- st.session_state.data["gpai"] = model_type.startswith("Foundation model")
723
- st.session_state.data["capabilities"] = capabilities
724
- st.session_state.data["direct_interaction"] = "Interacts directly with end users" in capabilities
725
- st.session_state.data["decision_making"] = "Makes or supports decisions that affect individuals" in capabilities
726
- st.session_state.data["profiling"] = "Profiles individuals (builds user profiles based on behavior, preferences, or characteristics)" in capabilities
727
- is_decision = "Makes or supports decisions that affect individuals" in capabilities
728
- st.session_state.data["human_involvement"] = human_involvement if is_decision and not human_involvement.startswith("N/A") else "N/A"
729
- is_synthetic = "Generates synthetic content (text, images, audio, video, code)" in capabilities
730
- st.session_state.data["synthetic_content"] = synthetic_content if is_synthetic else []
731
- st.session_state.data["emotion_recognition"] = "Performs emotion recognition" in capabilities
732
- go_next()
733
- st.rerun()
734
-
735
-
736
- # ═══════════════════════════════════════════════
737
- # SCREEN 7: Data Profile
738
- # ═══════════════════════════════════════════════
739
-
740
- elif current == 7:
741
- st.markdown('<p class="screen-title">Data Profile</p>', unsafe_allow_html=True)
742
- st.markdown('<p class="screen-subtitle">Data processed and training sources</p>', unsafe_allow_html=True)
743
-
744
- prev_data_types = st.session_state.data.get("data_types", [])
745
- selected_data_types = st.multiselect(
746
- "7.1 — Data types processed (select all that apply)",
747
- DATA_TYPE_OPTIONS,
748
- default=[dt for dt in prev_data_types if dt in DATA_TYPE_OPTIONS],
749
- )
750
-
751
- st.divider()
752
-
753
- prev_sources = st.session_state.data.get("training_sources", [])
754
- training_sources = st.multiselect(
755
- "7.2 — Training data sources (select all that apply)",
756
- TRAINING_SOURCES,
757
- default=[s for s in prev_sources if s in TRAINING_SOURCES],
758
- )
759
-
760
- col1, col2, col3 = st.columns([1, 3, 1])
761
- with col1:
762
- if st.button("← Back", use_container_width=True):
763
- go_back()
764
- st.rerun()
765
- with col3:
766
- if st.button("View Summary →", use_container_width=True, disabled=(not selected_data_types)):
767
- st.session_state.data["data_types"] = selected_data_types
768
- st.session_state.data["training_sources"] = training_sources
769
- go_next()
770
- st.rerun()
771
-
772
-
773
- # ═══════════════════════════════════════════════
774
- # SCREEN 8: Summary
775
- # ═══════════════════════════════════════════════
776
-
777
- elif current == 8:
778
- d = st.session_state.data
779
-
780
- st.markdown('<p class="screen-title">AI System ID Card — Summary</p>', unsafe_allow_html=True)
781
- st.markdown(f'<p class="screen-subtitle">Review your inputs for <strong>{d.get("name", "")}</strong></p>', unsafe_allow_html=True)
782
-
783
- # Identity
784
- st.markdown(f'<div class="summary-section"><h4>AI System Identity</h4><p><strong>Name:</strong> {d.get("name", "—")}</p><p><strong>Description:</strong> {d.get("description", "—") or "—"}</p></div>', unsafe_allow_html=True)
785
-
786
- # Domain
787
- sectors = d.get("sector", [])
788
- sectors_display = ", ".join(sectors) if sectors else "—"
789
- st.markdown(f'<div class="summary-section"><h4>Application Domain</h4><p><strong>Sector(s):</strong> {sectors_display}</p></div>', unsafe_allow_html=True)
790
-
791
- # Geography
792
- geo_lines = f'<p><strong>Company base:</strong> {d.get("company_base", "—")}</p>'
793
- op_countries = d.get("operating_countries", [])
794
- if op_countries:
795
- geo_lines += f'<p><strong>Countries:</strong> {", ".join(op_countries)}</p>'
796
- if d.get("us_states"):
797
- regulated = d.get("us_states_with_regulation", [])
798
- non_regulated = [s for s in d["us_states"] if s not in regulated]
799
- geo_lines += f'<p><strong>US states:</strong> {", ".join(d["us_states"])}</p>'
800
- if regulated:
801
- geo_lines += f'<p><strong>States with AI regulation:</strong> {", ".join(regulated)}</p>'
802
- if non_regulated:
803
- geo_lines += f'<p><strong>States without specific AI regulation:</strong> {", ".join(non_regulated)}</p>'
804
- if d.get("eu_countries"):
805
- geo_lines += f'<p><strong>EU/EEA countries detected:</strong> {", ".join(d["eu_countries"])}</p>'
806
- if d.get("uae_emirates"):
807
- geo_lines += f'<p><strong>UAE emirates:</strong> {", ".join(d["uae_emirates"])}</p>'
808
- if d.get("uae_free_zones"):
809
- geo_lines += f'<p><strong>UAE free zones:</strong> {", ".join(d["uae_free_zones"])}</p>'
810
- st.markdown(f'<div class="summary-section"><h4>Geographic Scope</h4>{geo_lines}</div>', unsafe_allow_html=True)
811
-
812
- # Roles
813
- roles_display = ", ".join(d.get("roles", ["—"]))
814
- st.markdown(f'<div class="summary-section"><h4>Role in Value Chain</h4><p>{roles_display}</p></div>', unsafe_allow_html=True)
815
-
816
- # Technology
817
- model_type_display = d.get("model_type", "—")
818
- caps = d.get("capabilities", [])
819
- caps_display = ", ".join(caps) if caps else "None selected"
820
- synthetic = ", ".join(d.get("synthetic_content", [])) or "None"
821
- involvement = d.get("human_involvement", "N/A")
822
-
823
- tech_lines = f'<p><strong>AI type:</strong> {d.get("ai_type", "—")}</p>'
824
- tech_lines += f'<p><strong>Model:</strong> {model_type_display}</p>'
825
- tech_lines += f'<p><strong>Capabilities:</strong> {caps_display}</p>'
826
- if d.get("decision_making"):
827
- tech_lines += f'<p><strong>Human involvement in decisions:</strong> {involvement}</p>'
828
- if d.get("synthetic_content"):
829
- tech_lines += f'<p><strong>Synthetic content types:</strong> {synthetic}</p>'
830
- st.markdown(f'<div class="summary-section"><h4>Technology Profile</h4>{tech_lines}</div>', unsafe_allow_html=True)
831
-
832
- # Data
833
- data_types_display = ", ".join(d.get("data_types", ["—"]))
834
- sources_display = ", ".join(d.get("training_sources", ["—"]))
835
- st.markdown(f'<div class="summary-section"><h4>Data Profile</h4><p><strong>Data types:</strong> {data_types_display}</p><p><strong>Training sources:</strong> {sources_display}</p></div>', unsafe_allow_html=True)
836
-
837
- # ── Regulation detection ──
838
- # Tuples: (region_tag, regulation_name, category)
839
- # category: "ai" = AI-specific, "other" = related regulation
840
- detected_regs = []
841
-
842
- # Helper flags from ID card data
843
- data_types = d.get("data_types", [])
844
- sectors = d.get("sector", [])
845
- roles = d.get("roles", [])
846
- capabilities = d.get("capabilities", [])
847
-
848
- personal_data_types = [
849
- "Personal data (name, email, ID)",
850
- "Sensitive/special category data (health, race, religion, political, sexual orientation)",
851
- "Biometric data",
852
- "Children's data (<18)",
853
- "Financial/credit data",
854
- "Employment/HR data",
855
- ]
856
- has_personal_data = any(dt in data_types for dt in personal_data_types)
857
- has_copyrighted = "Copyrighted content (text, images, audio, video)" in data_types
858
- has_biometric = "Biometric data" in data_types
859
- has_financial_data = "Financial/credit data" in data_types
860
- has_employment_data = "Employment/HR data" in data_types
861
- has_children_data = "Children's data (<18)" in data_types
862
- has_decision_making = d.get("decision_making", False)
863
- has_direct_interaction = d.get("direct_interaction", False)
864
- is_provider = any("Provider" in r for r in roles)
865
- is_employment_sector = "Human Resources & Recruitment" in sectors
866
- is_financial_sector = any(s in sectors for s in ["Banking & Financial Services", "Insurance"])
867
- is_healthcare_sector = "Healthcare & Life Sciences" in sectors
868
- is_education_sector = "Education & Training" in sectors
869
- is_critical_sector = any(s in sectors for s in [
870
- "Energy & Utilities", "Healthcare & Life Sciences", "Banking & Financial Services",
871
- "Government & Public Administration", "Telecommunications", "Logistics & Supply Chain",
872
- ])
873
-
874
- # ── EU ──
875
- company_base = d.get("company_base", "")
876
- eu_countries = d.get("eu_countries", [])
877
- EU_BASE_NAMES = [c.replace(" (EEA)", "") for c in EU_COUNTRIES]
878
- has_eu = len(eu_countries) > 0 or company_base in EU_BASE_NAMES
879
-
880
- if has_eu:
881
- # AI-specific
882
- detected_regs.append(("EU", "EU AI Act (Regulation 2024/1689)", "ai"))
883
- if d.get("gpai", False):
884
- detected_regs.append(("EU", "EU AI Act — GPAI Framework (Chapter V)", "ai"))
885
- # Related
886
- if has_personal_data:
887
- detected_regs.append(("EU", "GDPR (Regulation 2016/679)", "other"))
888
- if has_copyrighted:
889
- detected_regs.append(("EU", "Copyright Directive (2019/790)", "other"))
890
- if is_critical_sector:
891
- detected_regs.append(("EU", "NIS2 Directive (2022/2555)", "other"))
892
- if is_provider:
893
- detected_regs.append(("EU", "Product Liability Directive (2024/2853)", "other"))
894
- if has_decision_making:
895
- detected_regs.append(("EU", "Equal Treatment Directives", "other"))
896
- if has_direct_interaction:
897
- detected_regs.append(("EU", "Consumer Rights Directive / GPSR", "other"))
898
- detected_regs.append(("EU", "ePrivacy Directive (2002/58/EC)", "other"))
899
- if is_healthcare_sector:
900
- detected_regs.append(("EU", "Medical Device Regulation (MDR 2017/745)", "other"))
901
-
902
- # ── US ──
903
- has_us = "United States" in d.get("operating_countries", [])
904
- us_regulated = d.get("us_states_with_regulation", [])
905
-
906
- # Federal laws first
907
- if has_us:
908
- detected_regs.append(("US", "FTC Act Section 5 (Unfair/Deceptive Practices)", "other"))
909
- if is_employment_sector or has_employment_data:
910
- detected_regs.append(("US", "Title VII (Civil Rights Act)", "other"))
911
- detected_regs.append(("US", "ADA (Americans with Disabilities Act)", "other"))
912
- if is_financial_sector or has_financial_data:
913
- detected_regs.append(("US", "ECOA (Equal Credit Opportunity Act)", "other"))
914
- detected_regs.append(("US", "FCRA (Fair Credit Reporting Act)", "other"))
915
- if "Construction & Real Estate" in sectors:
916
- detected_regs.append(("US", "Fair Housing Act", "other"))
917
- if is_healthcare_sector and has_personal_data:
918
- detected_regs.append(("US", "HIPAA (Health Insurance Portability and Accountability Act)", "other"))
919
- if has_children_data:
920
- detected_regs.append(("US", "COPPA (Children's Online Privacy Protection Act)", "other"))
921
- if is_education_sector and has_personal_data:
922
- detected_regs.append(("US", "FERPA (Family Educational Rights and Privacy Act)", "other"))
923
-
924
- # State-level laws
925
- if has_personal_data and has_us:
926
- detected_regs.append(("US", "State Data Protection Laws (CCPA, CTDPA, etc.)", "other"))
927
- # AI-specific state laws
928
- if "Colorado" in us_regulated:
929
- detected_regs.append(("US", "Colorado AI Act (SB 24-205)", "ai"))
930
- if "Connecticut" in us_regulated:
931
- detected_regs.append(("US", "Connecticut AI Act (SB 2)", "ai"))
932
- if "Texas" in us_regulated:
933
- detected_regs.append(("US", "Texas TRAIGA (HB 1709)", "ai"))
934
- if "Utah" in us_regulated:
935
- detected_regs.append(("US", "Utah AI Policy Act (SB 149)", "ai"))
936
- if "California" in us_regulated:
937
- detected_regs.append(("US", "California CCPA / ADMT Regulations", "ai"))
938
- if "Illinois" in us_regulated:
939
- detected_regs.append(("US", "Illinois AI Video Interview Act (HB 3773)", "ai"))
940
- if has_biometric:
941
- detected_regs.append(("US", "Illinois BIPA (Biometric Information Privacy Act)", "other"))
942
-
943
- # ── UAE ──
944
- uae_emirates = d.get("uae_emirates", [])
945
-
946
- if uae_emirates:
947
- # Federal laws first
948
- if has_personal_data:
949
- detected_regs.append(("UAE", "UAE Federal PDPL (Decree-Law 45/2021)", "other"))
950
- if has_copyrighted:
951
- detected_regs.append(("UAE", "Copyright Law (Decree-Law 38/2021) — No TDM exception", "other"))
952
- detected_regs.append(("UAE", "Cybercrime Law (Decree-Law 34/2021)", "other"))
953
- detected_regs.append(("UAE", "Civil Transactions Law (Federal Law 5/1985)", "other"))
954
- if has_direct_interaction:
955
- detected_regs.append(("UAE", "Consumer Protection (Federal Law 15/2020)", "other"))
956
- if has_decision_making or is_employment_sector or has_employment_data:
957
- detected_regs.append(("UAE", "Anti-Discrimination (Decree-Law 34/2023)", "other"))
958
- detected_regs.append(("UAE", "Labour Law (Decree-Law 33/2021)", "other"))
959
-
960
- # Free zone level — only if specific free zone selected
961
- uae_fz = d.get("uae_free_zones", [])
962
- if "DIFC" in uae_fz and has_personal_data:
963
- detected_regs.append(("UAE", "DIFC Data Protection Law + Regulation 10", "ai"))
964
- if "ADGM" in uae_fz and has_personal_data:
965
- detected_regs.append(("UAE", "ADGM Data Protection Regulations 2021", "other"))
966
-
967
- # ── Build banner ──
968
- ai_regs = [(t, n) for t, n, c in detected_regs if c == "ai"]
969
- other_regs = [(t, n) for t, n, c in detected_regs if c == "other"]
970
-
971
- if detected_regs:
972
- banner_content = ""
973
- if ai_regs:
974
- banner_content += '<p class="reg-section-label-first rmh-el">AI-Specific Regulations</p>'
975
- banner_content += '<ul class="reg-banner-list">'
976
- for tag, name in ai_regs:
977
- banner_content += f'<li><span class="reg-tag rmh-el">{tag}</span> {name}</li>'
978
- banner_content += '</ul>'
979
- if other_regs:
980
- label_class = "reg-section-label" if ai_regs else "reg-section-label-first"
981
- banner_content += f'<p class="{label_class} rmh-el">Related Regulations</p>'
982
- banner_content += '<ul class="reg-banner-list">'
983
- for tag, name in other_regs:
984
- banner_content += f'<li><span class="reg-tag rmh-el">{tag}</span> {name}</li>'
985
- banner_content += '</ul>'
986
-
987
- banner_html = f"""
988
- <div class="reg-banner">
989
- <p class="reg-banner-title rmh-el">&#9878;&#65039; Based on your AI System ID Card, these regulations could apply:</p>
990
- {banner_content}
991
- <p class="reg-banner-cta rmh-el">Phase 2 will provide a detailed requirements checklist for each regulation.</p>
992
- </div>
993
- """
994
- st.markdown(banner_html, unsafe_allow_html=True)
995
- else:
996
- st.info("No specific AI regulations detected based on your inputs. This may change as more jurisdictions are added.")
997
-
998
- # Navigation
999
- col1, col2, col3 = st.columns([1, 2, 2])
1000
- with col1:
1001
- if st.button("← Edit", use_container_width=True):
1002
- go_to(1)
1003
- st.rerun()
1004
- with col3:
1005
- if st.button("🤓 Deep dive into requirements — WIP", use_container_width=True, type="primary"):
1006
- st.toast("Phase 2 — Requirements deep dive coming soon!", icon="🚀")