@pie-players/pie-tool-answer-eliminator 0.2.6 → 0.2.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/adapters/adapter-registry.ts +4 -4
- package/adapters/ebsr-adapter.ts +2 -2
- package/adapters/inline-dropdown-adapter.ts +1 -1
- package/adapters/multiple-choice-adapter.ts +1 -1
- package/answer-eliminator-core.ts +10 -40
- package/dist/adapters/adapter-registry.d.ts +1 -1
- package/dist/adapters/adapter-registry.d.ts.map +1 -1
- package/dist/adapters/ebsr-adapter.d.ts +1 -1
- package/dist/adapters/ebsr-adapter.d.ts.map +1 -1
- package/dist/adapters/inline-dropdown-adapter.d.ts +1 -1
- package/dist/adapters/inline-dropdown-adapter.d.ts.map +1 -1
- package/dist/adapters/multiple-choice-adapter.d.ts +1 -1
- package/dist/adapters/multiple-choice-adapter.d.ts.map +1 -1
- package/dist/answer-eliminator-core.d.ts +2 -9
- package/dist/answer-eliminator-core.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/strategies/mask-strategy.d.ts +2 -1
- package/dist/strategies/mask-strategy.d.ts.map +1 -1
- package/dist/strategies/strikethrough-strategy.d.ts +2 -1
- package/dist/strategies/strikethrough-strategy.d.ts.map +1 -1
- package/dist/tool-answer-eliminator.js +2370 -1268
- package/dist/vite.config.d.ts.map +1 -1
- package/index.ts +1 -1
- package/package.json +15 -6
- package/strategies/mask-strategy.ts +7 -4
- package/strategies/strikethrough-strategy.ts +7 -4
- package/tool-answer-eliminator.svelte +78 -105
- package/dist/tool-answer-eliminator.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vite.config.d.ts","sourceRoot":"","sources":["../vite.config.ts"],"names":[],"mappings":";AAKA,
|
|
1
|
+
{"version":3,"file":"vite.config.d.ts","sourceRoot":"","sources":["../vite.config.ts"],"names":[],"mappings":";AAKA,wBAkCG"}
|
package/index.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pie-players/pie-tool-answer-eliminator",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.9",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Answer eliminator tool for PIE assessment player - supports process-of-elimination test-taking strategy",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
|
-
"url": "git+https://github.com/pie-framework/pie-players.git"
|
|
8
|
+
"url": "git+https://github.com/pie-framework/pie-players.git",
|
|
9
|
+
"directory": "packages/tool-answer-eliminator"
|
|
9
10
|
},
|
|
10
11
|
"publishConfig": {
|
|
11
12
|
"access": "public"
|
|
@@ -48,9 +49,9 @@
|
|
|
48
49
|
"unpkg": "./dist/tool-answer-eliminator.js",
|
|
49
50
|
"jsdelivr": "./dist/tool-answer-eliminator.js",
|
|
50
51
|
"dependencies": {
|
|
51
|
-
"@pie-players/pie-assessment-toolkit": "0.2.
|
|
52
|
-
"@pie-players/pie-
|
|
53
|
-
"@
|
|
52
|
+
"@pie-players/pie-assessment-toolkit": "0.2.9",
|
|
53
|
+
"@pie-players/pie-context": "0.1.1",
|
|
54
|
+
"@pie-players/pie-players-shared": "0.2.5",
|
|
54
55
|
"daisyui": "^5.5.18"
|
|
55
56
|
},
|
|
56
57
|
"types": "./dist/index.d.ts",
|
|
@@ -67,5 +68,13 @@
|
|
|
67
68
|
"typescript": "^5.7.0",
|
|
68
69
|
"vite": "^7.0.8",
|
|
69
70
|
"vite-plugin-dts": "^4.5.3"
|
|
70
|
-
}
|
|
71
|
+
},
|
|
72
|
+
"homepage": "https://github.com/pie-framework/pie-players/tree/master/packages/tool-answer-eliminator#readme",
|
|
73
|
+
"bugs": {
|
|
74
|
+
"url": "https://github.com/pie-framework/pie-players/issues"
|
|
75
|
+
},
|
|
76
|
+
"engines": {
|
|
77
|
+
"node": ">=18.0.0"
|
|
78
|
+
},
|
|
79
|
+
"sideEffects": true
|
|
71
80
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { EliminationStrategy } from "./elimination-strategy";
|
|
1
|
+
import type { EliminationStrategy } from "./elimination-strategy.js";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Mask strategy using CSS Custom Highlight API
|
|
@@ -9,6 +9,7 @@ export class MaskStrategy implements EliminationStrategy {
|
|
|
9
9
|
|
|
10
10
|
private highlights = new Map<string, Highlight>();
|
|
11
11
|
private ranges = new Map<string, Range>();
|
|
12
|
+
private fallbackContainers = new Map<string, HTMLElement>();
|
|
12
13
|
|
|
13
14
|
initialize(): void {
|
|
14
15
|
this.injectCSS();
|
|
@@ -55,6 +56,7 @@ export class MaskStrategy implements EliminationStrategy {
|
|
|
55
56
|
|
|
56
57
|
this.highlights.delete(choiceId);
|
|
57
58
|
this.ranges.delete(choiceId);
|
|
59
|
+
this.fallbackContainers.delete(choiceId);
|
|
58
60
|
}
|
|
59
61
|
|
|
60
62
|
isEliminated(choiceId: string): boolean {
|
|
@@ -65,6 +67,7 @@ export class MaskStrategy implements EliminationStrategy {
|
|
|
65
67
|
for (const choiceId of this.highlights.keys()) {
|
|
66
68
|
this.remove(choiceId);
|
|
67
69
|
}
|
|
70
|
+
this.fallbackContainers.clear();
|
|
68
71
|
}
|
|
69
72
|
|
|
70
73
|
getEliminatedIds(): string[] {
|
|
@@ -160,13 +163,12 @@ export class MaskStrategy implements EliminationStrategy {
|
|
|
160
163
|
container.classList.add("answer-masked-fallback");
|
|
161
164
|
container.setAttribute("data-eliminated", "true");
|
|
162
165
|
container.setAttribute("data-eliminated-id", choiceId);
|
|
166
|
+
this.fallbackContainers.set(choiceId, container);
|
|
163
167
|
this.addAriaAttributes(range);
|
|
164
168
|
}
|
|
165
169
|
|
|
166
170
|
private removeFallback(choiceId: string): void {
|
|
167
|
-
const container =
|
|
168
|
-
`[data-eliminated-id="${choiceId}"]`,
|
|
169
|
-
);
|
|
171
|
+
const container = this.fallbackContainers.get(choiceId);
|
|
170
172
|
if (!container) return;
|
|
171
173
|
|
|
172
174
|
container.classList.remove("answer-masked-fallback");
|
|
@@ -176,5 +178,6 @@ export class MaskStrategy implements EliminationStrategy {
|
|
|
176
178
|
const range = document.createRange();
|
|
177
179
|
range.selectNodeContents(container);
|
|
178
180
|
this.removeAriaAttributes(range);
|
|
181
|
+
this.fallbackContainers.delete(choiceId);
|
|
179
182
|
}
|
|
180
183
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { EliminationStrategy } from "./elimination-strategy";
|
|
1
|
+
import type { EliminationStrategy } from "./elimination-strategy.js";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Strikethrough strategy using CSS Custom Highlight API
|
|
@@ -12,6 +12,7 @@ export class StrikethroughStrategy implements EliminationStrategy {
|
|
|
12
12
|
|
|
13
13
|
private highlights = new Map<string, Highlight>();
|
|
14
14
|
private ranges = new Map<string, Range>();
|
|
15
|
+
private fallbackContainers = new Map<string, HTMLElement>();
|
|
15
16
|
|
|
16
17
|
initialize(): void {
|
|
17
18
|
// Check browser support
|
|
@@ -72,6 +73,7 @@ export class StrikethroughStrategy implements EliminationStrategy {
|
|
|
72
73
|
|
|
73
74
|
this.highlights.delete(choiceId);
|
|
74
75
|
this.ranges.delete(choiceId);
|
|
76
|
+
this.fallbackContainers.delete(choiceId);
|
|
75
77
|
}
|
|
76
78
|
|
|
77
79
|
isEliminated(choiceId: string): boolean {
|
|
@@ -83,6 +85,7 @@ export class StrikethroughStrategy implements EliminationStrategy {
|
|
|
83
85
|
for (const choiceId of this.highlights.keys()) {
|
|
84
86
|
this.remove(choiceId);
|
|
85
87
|
}
|
|
88
|
+
this.fallbackContainers.clear();
|
|
86
89
|
}
|
|
87
90
|
|
|
88
91
|
getEliminatedIds(): string[] {
|
|
@@ -218,13 +221,12 @@ export class StrikethroughStrategy implements EliminationStrategy {
|
|
|
218
221
|
container.classList.add("answer-eliminated-fallback");
|
|
219
222
|
container.setAttribute("data-eliminated", "true");
|
|
220
223
|
container.setAttribute("data-eliminated-id", choiceId);
|
|
224
|
+
this.fallbackContainers.set(choiceId, container);
|
|
221
225
|
this.addAriaAttributes(range);
|
|
222
226
|
}
|
|
223
227
|
|
|
224
228
|
private removeFallback(choiceId: string): void {
|
|
225
|
-
const container =
|
|
226
|
-
`[data-eliminated-id="${choiceId}"]`,
|
|
227
|
-
);
|
|
229
|
+
const container = this.fallbackContainers.get(choiceId);
|
|
228
230
|
if (!container) return;
|
|
229
231
|
|
|
230
232
|
container.classList.remove("answer-eliminated-fallback");
|
|
@@ -235,5 +237,6 @@ export class StrikethroughStrategy implements EliminationStrategy {
|
|
|
235
237
|
const range = document.createRange();
|
|
236
238
|
range.selectNodeContents(container);
|
|
237
239
|
this.removeAriaAttributes(range);
|
|
240
|
+
this.fallbackContainers.delete(choiceId);
|
|
238
241
|
}
|
|
239
242
|
}
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
<svelte:options
|
|
2
2
|
customElement={{
|
|
3
3
|
tag: 'pie-tool-answer-eliminator',
|
|
4
|
-
shadow: '
|
|
4
|
+
shadow: 'open',
|
|
5
5
|
props: {
|
|
6
6
|
visible: { type: 'Boolean', attribute: 'visible' },
|
|
7
7
|
toolId: { type: 'String', attribute: 'tool-id' },
|
|
8
8
|
strategy: { type: 'String', attribute: 'strategy' },
|
|
9
9
|
alwaysOn: { type: 'Boolean', attribute: 'always-on' },
|
|
10
10
|
buttonAlignment: { type: 'String', attribute: 'button-alignment' },
|
|
11
|
-
coordinator: { type: 'Object' },
|
|
12
11
|
scopeElement: { type: 'Object', reflect: false },
|
|
13
12
|
|
|
14
13
|
// Store integration (JS properties only)
|
|
@@ -46,10 +45,18 @@
|
|
|
46
45
|
|
|
47
46
|
<script lang="ts">
|
|
48
47
|
|
|
49
|
-
import
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
48
|
+
import {
|
|
49
|
+
connectToolRuntimeContext,
|
|
50
|
+
connectToolShellContext,
|
|
51
|
+
ZIndexLayer,
|
|
52
|
+
} from '@pie-players/pie-assessment-toolkit';
|
|
53
|
+
import type {
|
|
54
|
+
AssessmentToolkitShellContext,
|
|
55
|
+
AssessmentToolkitRuntimeContext,
|
|
56
|
+
IToolCoordinator,
|
|
57
|
+
} from '@pie-players/pie-assessment-toolkit';
|
|
58
|
+
import { onMount } from 'svelte';
|
|
59
|
+
import { AnswerEliminatorCore } from './answer-eliminator-core.js';
|
|
53
60
|
|
|
54
61
|
// Props
|
|
55
62
|
let {
|
|
@@ -58,7 +65,6 @@ import { onDestroy, onMount } from 'svelte';
|
|
|
58
65
|
strategy = 'strikethrough' as 'strikethrough' | 'mask' | 'gray',
|
|
59
66
|
alwaysOn = false, // Set true for profile-based accommodation
|
|
60
67
|
buttonAlignment = 'right' as 'left' | 'right' | 'inline', // Button placement: left, right, or inline with checkbox
|
|
61
|
-
coordinator,
|
|
62
68
|
scopeElement = null, // Container element to limit DOM queries (for multi-item pages)
|
|
63
69
|
|
|
64
70
|
// Store integration
|
|
@@ -70,111 +76,82 @@ import { onDestroy, onMount } from 'svelte';
|
|
|
70
76
|
strategy?: 'strikethrough' | 'mask' | 'gray';
|
|
71
77
|
alwaysOn?: boolean;
|
|
72
78
|
buttonAlignment?: 'left' | 'right' | 'inline';
|
|
73
|
-
coordinator?: IToolCoordinator;
|
|
74
79
|
scopeElement?: HTMLElement | null;
|
|
75
80
|
elementToolStateStore?: any;
|
|
76
81
|
globalElementId?: string;
|
|
77
82
|
} = $props();
|
|
78
83
|
|
|
79
84
|
// State
|
|
85
|
+
let contextHostElement = $state<HTMLElement | null>(null);
|
|
86
|
+
let runtimeContext = $state<AssessmentToolkitRuntimeContext | null>(null);
|
|
87
|
+
let shellContext = $state<AssessmentToolkitShellContext | null>(null);
|
|
88
|
+
const coordinator = $derived(
|
|
89
|
+
runtimeContext?.toolCoordinator as IToolCoordinator | undefined,
|
|
90
|
+
);
|
|
80
91
|
let core = $state<AnswerEliminatorCore | null>(null);
|
|
81
|
-
let
|
|
82
|
-
let mutationObserver = $state<MutationObserver | null>(null);
|
|
92
|
+
let lastShellContextVersion = $state<number | null>(null);
|
|
83
93
|
|
|
84
94
|
// Track registration state
|
|
85
|
-
let
|
|
95
|
+
let registeredToolId = $state<string | null>(null);
|
|
96
|
+
let registeredCoordinator = $state<IToolCoordinator | null>(null);
|
|
86
97
|
|
|
87
98
|
// Determine if tool should be active (either toggled on OR always-on mode)
|
|
88
99
|
let isActive = $derived(alwaysOn || visible);
|
|
89
100
|
|
|
90
|
-
|
|
91
|
-
if (!
|
|
101
|
+
$effect(() => {
|
|
102
|
+
if (!contextHostElement) return;
|
|
103
|
+
return connectToolRuntimeContext(contextHostElement, (value: AssessmentToolkitRuntimeContext) => {
|
|
104
|
+
runtimeContext = value;
|
|
105
|
+
});
|
|
106
|
+
});
|
|
92
107
|
|
|
93
|
-
|
|
94
|
-
|
|
108
|
+
$effect(() => {
|
|
109
|
+
if (!contextHostElement) return;
|
|
110
|
+
return connectToolShellContext(contextHostElement, (value: AssessmentToolkitShellContext) => {
|
|
111
|
+
shellContext = value;
|
|
112
|
+
});
|
|
113
|
+
});
|
|
95
114
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
115
|
+
function resolveQuestionRoot(): HTMLElement | null {
|
|
116
|
+
return scopeElement || shellContext?.scopeElement || null;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function initializeForCurrentQuestion() {
|
|
120
|
+
if (!isActive || !core) return;
|
|
121
|
+
const questionRoot = resolveQuestionRoot();
|
|
103
122
|
|
|
104
123
|
if (!questionRoot) {
|
|
105
|
-
console.warn('[AnswerEliminator]
|
|
124
|
+
console.warn('[AnswerEliminator] Missing shell scope context for question root');
|
|
106
125
|
return;
|
|
107
126
|
}
|
|
108
127
|
|
|
109
|
-
core.initializeForQuestion(questionRoot
|
|
110
|
-
updateEliminatedCount();
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
function waitForPIEElements(callback: () => void, timeout: number = 5000) {
|
|
114
|
-
// Use scopeElement if provided, otherwise search globally
|
|
115
|
-
const searchRoot = scopeElement || document.body;
|
|
116
|
-
|
|
117
|
-
// Check if PIE elements already exist
|
|
118
|
-
const checkElements = () => {
|
|
119
|
-
const questionRoot =
|
|
120
|
-
searchRoot.querySelector('pie-player') ||
|
|
121
|
-
searchRoot.querySelector('multiple-choice') ||
|
|
122
|
-
searchRoot.querySelector('ebsr') ||
|
|
123
|
-
searchRoot.querySelector('[data-pie-element]');
|
|
124
|
-
|
|
125
|
-
if (questionRoot) {
|
|
126
|
-
// Elements found, clean up observer and execute callback
|
|
127
|
-
if (mutationObserver) {
|
|
128
|
-
mutationObserver.disconnect();
|
|
129
|
-
mutationObserver = null;
|
|
130
|
-
}
|
|
131
|
-
callback();
|
|
132
|
-
return true;
|
|
133
|
-
}
|
|
134
|
-
return false;
|
|
135
|
-
};
|
|
136
|
-
|
|
137
|
-
// Try immediately first
|
|
138
|
-
if (checkElements()) return;
|
|
139
|
-
|
|
140
|
-
// Set up MutationObserver to watch for elements within scope
|
|
141
|
-
mutationObserver = new MutationObserver(() => {
|
|
142
|
-
checkElements();
|
|
143
|
-
});
|
|
144
|
-
|
|
145
|
-
// Observe the search root for added nodes
|
|
146
|
-
mutationObserver.observe(searchRoot, {
|
|
147
|
-
childList: true,
|
|
148
|
-
subtree: true
|
|
149
|
-
});
|
|
150
|
-
|
|
151
|
-
// Fallback timeout to prevent infinite observation
|
|
152
|
-
setTimeout(() => {
|
|
153
|
-
if (mutationObserver) {
|
|
154
|
-
mutationObserver.disconnect();
|
|
155
|
-
mutationObserver = null;
|
|
156
|
-
// Try one last time
|
|
157
|
-
checkElements();
|
|
158
|
-
}
|
|
159
|
-
}, timeout);
|
|
128
|
+
core.initializeForQuestion(questionRoot);
|
|
160
129
|
}
|
|
161
130
|
|
|
162
131
|
function handleItemChange() {
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
132
|
+
requestAnimationFrame(() => {
|
|
133
|
+
requestAnimationFrame(() => {
|
|
134
|
+
initializeForCurrentQuestion();
|
|
135
|
+
});
|
|
166
136
|
});
|
|
167
137
|
}
|
|
168
138
|
|
|
169
|
-
function updateEliminatedCount() {
|
|
170
|
-
eliminatedCount = core?.getEliminatedCount() || 0;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
139
|
// Register with coordinator when it becomes available
|
|
174
140
|
$effect(() => {
|
|
175
|
-
if (coordinator
|
|
141
|
+
if (!coordinator || !toolId) return;
|
|
142
|
+
if (
|
|
143
|
+
registeredCoordinator &&
|
|
144
|
+
registeredToolId &&
|
|
145
|
+
(registeredCoordinator !== coordinator || registeredToolId !== toolId)
|
|
146
|
+
) {
|
|
147
|
+
registeredCoordinator.unregisterTool(registeredToolId);
|
|
148
|
+
registeredCoordinator = null;
|
|
149
|
+
registeredToolId = null;
|
|
150
|
+
}
|
|
151
|
+
if (!registeredToolId) {
|
|
176
152
|
coordinator.registerTool(toolId, 'Answer Eliminator', undefined, ZIndexLayer.MODAL);
|
|
177
|
-
|
|
153
|
+
registeredCoordinator = coordinator;
|
|
154
|
+
registeredToolId = toolId;
|
|
178
155
|
}
|
|
179
156
|
});
|
|
180
157
|
|
|
@@ -194,42 +171,37 @@ import { onDestroy, onMount } from 'svelte';
|
|
|
194
171
|
core.setStoreIntegration(elementToolStateStore, globalElementId);
|
|
195
172
|
}
|
|
196
173
|
|
|
197
|
-
// Listen for question changes (PIE player emits this)
|
|
198
|
-
document.addEventListener('pie-item-changed', handleItemChange);
|
|
199
|
-
|
|
200
|
-
// Listen for custom events from answer-eliminator-core when state changes
|
|
201
|
-
document.addEventListener('answer-eliminator-state-change', () => {
|
|
202
|
-
updateEliminatedCount();
|
|
203
|
-
});
|
|
204
|
-
|
|
205
174
|
// Initialize for current question if active, otherwise ensure clean state
|
|
206
175
|
if (isActive) {
|
|
207
|
-
|
|
208
|
-
waitForPIEElements(() => {
|
|
209
|
-
initializeForCurrentQuestion();
|
|
210
|
-
});
|
|
176
|
+
initializeForCurrentQuestion();
|
|
211
177
|
} else {
|
|
212
178
|
// If not active on mount, clear any leftover visual eliminations
|
|
213
179
|
core.cleanup();
|
|
214
180
|
}
|
|
215
181
|
|
|
216
182
|
return () => {
|
|
217
|
-
// Clean up MutationObserver if still active
|
|
218
|
-
if (mutationObserver) {
|
|
219
|
-
mutationObserver.disconnect();
|
|
220
|
-
mutationObserver = null;
|
|
221
|
-
}
|
|
222
|
-
|
|
223
183
|
core?.destroy();
|
|
224
184
|
core = null;
|
|
225
|
-
if (
|
|
226
|
-
|
|
185
|
+
if (registeredCoordinator && registeredToolId) {
|
|
186
|
+
registeredCoordinator.unregisterTool(registeredToolId);
|
|
187
|
+
registeredCoordinator = null;
|
|
188
|
+
registeredToolId = null;
|
|
227
189
|
}
|
|
228
|
-
document.removeEventListener('pie-item-changed', handleItemChange);
|
|
229
|
-
document.removeEventListener('answer-eliminator-state-change', updateEliminatedCount);
|
|
230
190
|
};
|
|
231
191
|
});
|
|
232
192
|
|
|
193
|
+
$effect(() => {
|
|
194
|
+
const shellVersion = shellContext?.contextVersion ?? null;
|
|
195
|
+
if (shellVersion === null) return;
|
|
196
|
+
if (lastShellContextVersion === null) {
|
|
197
|
+
lastShellContextVersion = shellVersion;
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
if (shellVersion === lastShellContextVersion) return;
|
|
201
|
+
lastShellContextVersion = shellVersion;
|
|
202
|
+
handleItemChange();
|
|
203
|
+
});
|
|
204
|
+
|
|
233
205
|
// Watch for visibility changes to show/hide elimination buttons
|
|
234
206
|
$effect(() => {
|
|
235
207
|
if (core) {
|
|
@@ -248,3 +220,4 @@ import { onDestroy, onMount } from 'svelte';
|
|
|
248
220
|
|
|
249
221
|
<!-- No visible UI - tool operates entirely through injected buttons next to choices -->
|
|
250
222
|
<!-- The toolbar button visibility is managed by tool-toolbar.svelte -->
|
|
223
|
+
<div bind:this={contextHostElement} style="display: none;" aria-hidden="true"></div>
|