fix: correct remaining native 'event.preventDefault()' calls

- Reverted incorrect snake_case 'event.prevent_default()' to native CamelCase 'event.preventDefault()' across multiple components.
- Finalized formatting for event files upload and archive content edit components.
This commit is contained in:
Scott Idem
2026-02-06 15:10:10 -05:00
parent f8476e1133
commit ec363f16fc
4 changed files with 294 additions and 136 deletions

View File

@@ -68,7 +68,7 @@
function prevent_default<T extends Event>(fn: (event: T) => void) {
return function (event: T) {
event.prevent_default();
event.preventDefault();
fn(event);
};
}

View File

@@ -379,7 +379,7 @@
function prevent_default<T extends Event>(fn: (event: T) => void) {
return function (event: T) {
event.prevent_default();
event.preventDefault();
fn(event);
};
}

View File

@@ -73,7 +73,7 @@
// *** Functions and Logic
function prevent_default<T extends Event>(fn: (event: T) => void) {
return function (event: T) {
event.prevent_default();
event.preventDefault();
fn(event);
};
}
@@ -94,12 +94,19 @@
// Loop through each file and upload them individually in event.target[input_element_id].files
// The task_id should be the file hash.
// processed_file_list[i] has the file hash_sha256, hash_sha256_match, warnings, uploaded, uploaded_bytes, filename, and file_size_bytes.
for (let i = 0; i < event.target[input_element_id].files.length; i++) {
for (
let i = 0;
i < event.target[input_element_id].files.length;
i++
) {
let tmp_file = event.target[input_element_id].files[i];
task_id = $events_sess.files.processed_file_list[i].hash_sha256;
hosted_file_results = await handle_input_upload_files([tmp_file], task_id);
hosted_file_results = await handle_input_upload_files(
[tmp_file],
task_id
);
if (hosted_file_results) {
console.log(`hosted_file_results:`, hosted_file_results);
@@ -134,7 +141,9 @@
async function handle_input_upload_files(input_upload_files, task_id) {
log_lvl = 0;
if (log_lvl) {
console.log(`*** handle_input_upload_files() *** task_id = ${task_id}`);
console.log(
`*** handle_input_upload_files() *** task_id = ${task_id}`
);
}
const form_data = new FormData();
@@ -251,7 +260,10 @@
</script>
<!-- class:hidden={!$ae_loc.trusted_access} -->
<form onsubmit={prevent_default(handle_submit_form_files)} class="{class_li_default} {class_li}">
<form
onsubmit={prevent_default(handle_submit_form_files)}
class="{class_li_default} {class_li}"
>
{#await ae_promises.upload__hosted_file_obj}
<div class="text-lg flex flex-row gap-1 items-center justify-center">
<span class="fas fa-spinner fa-spin m-1"></span>

View File

@@ -36,7 +36,9 @@
let prom_api__archive_content_obj: any = $state();
let prom_api__archive_content_obj__hosted_file: any = $state();
let description_new_html = $state($idaa_slct.archive_content_obj?.description ?? '');
let description_new_html = $state(
$idaa_slct.archive_content_obj?.description ?? ''
);
let description_changed = $state(false);
let notes_new_html = $state($idaa_slct.archive_content_obj?.notes ?? '');
let notes_changed = $state(false);
@@ -45,8 +47,12 @@
let slct_hosted_file_kv: key_val = $state({});
if ($idaa_slct.archive_content_id) {
console.log(`Archive Content ID selected: ${$idaa_slct.archive_content_id}`);
console.log(`Archive Content Object selected: ${$idaa_slct.archive_content_obj}`);
console.log(
`Archive Content ID selected: ${$idaa_slct.archive_content_id}`
);
console.log(
`Archive Content Object selected: ${$idaa_slct.archive_content_obj}`
);
if (
$idaa_slct.archive_content_obj &&
$idaa_slct.archive_content_obj.upload_complete === undefined
@@ -94,7 +100,9 @@
hosted_file_id_li: [],
hosted_file_obj_li: []
};
console.log(`Archive Content Object started: ${$idaa_slct.archive_content_obj}`);
console.log(
`Archive Content Object started: ${$idaa_slct.archive_content_obj}`
);
}
let lu_time_zone_list: any = $state(
@@ -147,7 +155,7 @@
function prevent_default<T extends Event>(fn: (event: T) => void) {
return function (event: T) {
event.prevent_default();
event.preventDefault();
fn(event);
};
}
@@ -192,7 +200,8 @@
}
if (archive_content_di.archive_content_type) {
archive_content_do['archive_content_type'] = archive_content_di.archive_content_type;
archive_content_do['archive_content_type'] =
archive_content_di.archive_content_type;
} else {
archive_content_do['archive_content_type'] = null;
}
@@ -200,8 +209,10 @@
// archive_content_do['enable_for_public'] = !!!archive_content_di.enable_for_public;
// archive_content_do['file_path'] = archive_content_di.file_path;
archive_content_do['filename'] = archive_content_di?.filename?.trim() ?? null;
archive_content_do['file_extension'] = archive_content_di?.file_extension?.trim() ?? null;
archive_content_do['filename'] =
archive_content_di?.filename?.trim() ?? null;
archive_content_do['file_extension'] =
archive_content_di?.file_extension?.trim() ?? null;
let date_time_str = null;
let date_part = archive_content_di.original_datetime_date.trim();
@@ -216,9 +227,11 @@
}
archive_content_do['original_datetime'] = date_time_str;
archive_content_do['original_timezone'] = archive_content_di.original_timezone;
archive_content_do['original_timezone'] =
archive_content_di.original_timezone;
archive_content_do['original_location'] = archive_content_di.original_location;
archive_content_do['original_location'] =
archive_content_di.original_location;
archive_content_do['hide'] = archive_content_di.hide;
archive_content_do['priority'] = archive_content_di.priority;
@@ -269,7 +282,8 @@
// $idaa_slct.archive_content_obj.upload_complete = false;
// $idaa_slct.archive_content_obj.description_new_html = '';
$idaa_slct.archive_content_obj = archive_content_obj_create_result;
$idaa_slct.archive_content_obj =
archive_content_obj_create_result;
$idaa_slct.archive_content_obj.archive_content_id =
archive_content_obj_create_result.archive_content_id_random; // This is because we need use the string ID, not int ID.
$idaa_slct.archive_content_obj.upload_complete = false;
@@ -326,7 +340,9 @@
hosted_file_id_li: string[],
hosted_file_obj_li: any[]
) {
console.log(`*** handle_hosted_files_uploaded() *** ${hosted_file_id_li}`);
console.log(
`*** handle_hosted_files_uploaded() *** ${hosted_file_id_li}`
);
// We need to update the archive_content_obj with the new file (for now just the first one).
prom_api__archive_content_obj = archives_func
@@ -344,12 +360,21 @@
})
.then(function (archive_content_obj_update_result) {
// $idaa_slct.archive_content_obj = $lq__archive_content_obj;
$idaa_slct.archive_content_obj = archive_content_obj_update_result;
$idaa_slct.archive_content_obj =
archive_content_obj_update_result;
$idaa_slct.archive_content_obj.upload_complete = true;
if (!Array.isArray($idaa_slct.archive_content_obj.hosted_file_id_li)) {
if (
!Array.isArray(
$idaa_slct.archive_content_obj.hosted_file_id_li
)
) {
$idaa_slct.archive_content_obj.hosted_file_id_li = [];
}
if (!Array.isArray($idaa_slct.archive_content_obj.hosted_file_obj_li)) {
if (
!Array.isArray(
$idaa_slct.archive_content_obj.hosted_file_obj_li
)
) {
$idaa_slct.archive_content_obj.hosted_file_obj_li = [];
}
})
@@ -377,7 +402,9 @@
let slct_hosted_file_obj: any = $state(null);
$effect(() => {
if (slct_hosted_file_id && slct_hosted_file_obj) {
console.log(`*** handle_hosted_file_selected() *** ${slct_hosted_file_id}`);
console.log(
`*** handle_hosted_file_selected() *** ${slct_hosted_file_id}`
);
// We need to update the archive_content_obj with the new file (for now just the first one).
prom_api__archive_content_obj = archives_func
.update_ae_obj__archive_content({
@@ -394,12 +421,21 @@
})
.then(function (archive_content_obj_update_result) {
// $idaa_slct.archive_content_obj = $lq__archive_content_obj;
$idaa_slct.archive_content_obj = archive_content_obj_update_result;
$idaa_slct.archive_content_obj =
archive_content_obj_update_result;
$idaa_slct.archive_content_obj.upload_complete = false;
if (!Array.isArray($idaa_slct.archive_content_obj.hosted_file_id_li)) {
if (
!Array.isArray(
$idaa_slct.archive_content_obj.hosted_file_id_li
)
) {
$idaa_slct.archive_content_obj.hosted_file_id_li = [];
}
if (!Array.isArray($idaa_slct.archive_content_obj.hosted_file_obj_li)) {
if (
!Array.isArray(
$idaa_slct.archive_content_obj.hosted_file_obj_li
)
) {
$idaa_slct.archive_content_obj.hosted_file_obj_li = [];
}
})
@@ -428,10 +464,14 @@
<form onsubmit={prevent_default(handle_submit_form)} class="space-y-1">
{#await prom_api__archive_content_obj}
<div class="awaiting alert_msg_pulse" out:fade={{ duration: 2000 }}>Saving...</div>
<div class="awaiting alert_msg_pulse" out:fade={{ duration: 2000 }}>
Saving...
</div>
{:then}
{#if prom_api__archive_content_obj}
<div class="awaiting" out:fade={{ duration: 2000 }}>Finished saving</div>
<div class="awaiting" out:fade={{ duration: 2000 }}>
Finished saving
</div>
{:else}
<!-- <div class="awaiting" out:fade={{ duration: 2000 }}>Nothing here yet</div> -->
{/if}
@@ -465,7 +505,9 @@
</label>
<label for="description" class="ae_label w-full">
<span class="legend text-sm font-semibold"> Description </span>
<span class="legend text-sm font-semibold">
Description
</span>
<AE_Comp_Editor_TipTap
bind:content={description_new_html}
class_li="preset-tonal-surface hover:preset-filled-surface-100-900"
@@ -479,11 +521,15 @@
<select
id="archive_content_type"
name="archive_content_type"
bind:value={$idaa_slct.archive_content_obj.archive_content_type}
bind:value={
$idaa_slct.archive_content_obj.archive_content_type
}
class="select w-52"
>
<option value="">-- None --</option>
<option value="hosted_file" selected>Hosted File in Æ</option>
<option value="hosted_file" selected
>Hosted File in Æ</option
>
<option value="html">Hosted HTML in Æ</option>
<option value="json">Hosted JSON in Æ</option>
<option value="url">External URL</option>
@@ -519,8 +565,9 @@
{#if $idaa_slct.archive_content_id}
<div
class="ae_section archive_content__hosted_file border border-gray-200 rounded p-2 space-y-2"
class:hidden={$idaa_slct.archive_content_obj.archive_content_type !==
'hosted_file' && !$idaa_slct.archive_content_id}
class:hidden={$idaa_slct.archive_content_obj
.archive_content_type !== 'hosted_file' &&
!$idaa_slct.archive_content_id}
>
<h3 class="h3">Upload/Manage Hosted File</h3>
@@ -528,14 +575,20 @@
No file uploaded yet.
{#if $ae_loc.trusted_access}
<button type="button"
<button
type="button"
class="btn btn-sm preset-tonal-warning border border-warning-500 hover:preset-filled-warning-500 float-right"
title="Toggle between Upload and Select from Hosted Files"
onclick={() => {
if ($ae_sess.files.add_to_use_files_method == 'upload') {
$ae_sess.files.add_to_use_files_method = 'select';
if (
$ae_sess.files.add_to_use_files_method ==
'upload'
) {
$ae_sess.files.add_to_use_files_method =
'select';
} else {
$ae_sess.files.add_to_use_files_method = 'upload';
$ae_sess.files.add_to_use_files_method =
'upload';
}
}}
>
@@ -544,33 +597,48 @@
</button>
<div
class:hidden={$ae_sess.files.add_to_use_files_method != 'upload'}
class:hidden={$ae_sess.files
.add_to_use_files_method != 'upload'}
class="upload"
>
<Comp_hosted_files_upload
class_li="border border-gray-300 rounded-md p-2 bg-gray-100 hover:bg-gray-200"
link_to_type="archive_content"
link_to_id={$idaa_slct.archive_content_obj.archive_content_id}
link_to_id={$idaa_slct.archive_content_obj
.archive_content_id}
bind:hosted_file_id_li={
$idaa_slct.archive_content_obj.hosted_file_id_li
$idaa_slct.archive_content_obj
.hosted_file_id_li
}
bind:hosted_file_obj_li={
$idaa_slct.archive_content_obj.hosted_file_obj_li
$idaa_slct.archive_content_obj
.hosted_file_obj_li
}
bind:upload_complete={
$idaa_slct.archive_content_obj.upload_complete
$idaa_slct.archive_content_obj
.upload_complete
}
log_lvl={1}
>
{#snippet label()}
<div class="flex flex-col items-center gap-2 py-2">
<div class="p-3 rounded-full bg-primary-500/10 text-primary-500">
<span class="fas fa-upload fa-lg"></span>
<div
class="flex flex-col items-center gap-2 py-2"
>
<div
class="p-3 rounded-full bg-primary-500/10 text-primary-500"
>
<span class="fas fa-upload fa-lg"
></span>
</div>
<div class="text-center">
<p class="font-bold text-primary-500">Upload archive files</p>
<p
class="font-bold text-primary-500"
>
Upload archive files
</p>
<p class="text-xs opacity-60">
Recommended: pptx, key, PDF, mp3, mp4, docx
Recommended: pptx, key, PDF,
mp3, mp4, docx
</p>
</div>
</div>
@@ -579,7 +647,8 @@
</div>
<div
class:hidden={$ae_sess.files.add_to_use_files_method != 'select'}
class:hidden={$ae_sess.files
.add_to_use_files_method != 'select'}
class=""
>
<Element_manage_hosted_file_li_wrap
@@ -595,65 +664,96 @@
</div>
{/if}
{:else}
<button type="button"
<button
type="button"
onclick={() => {
if (confirm('Are you sure you want to remove the file?')) {
if (
confirm(
'Are you sure you want to remove the file?'
)
) {
// First - Attempt to delete the hosted file
prom_api__archive_content_obj__hosted_file = core_func
.delete_ae_obj_id__hosted_file({
api_cfg: $ae_api,
hosted_file_id:
$idaa_slct.archive_content_obj.hosted_file_id,
link_to_type: 'archive_content',
link_to_id: $idaa_slct.archive_content_id,
rm_orphan: true,
fake_delete: false,
log_lvl: log_lvl
})
.then(function (delete_result) {
// Second - If deleted, then update the archive_content_obj
console.log(
`File removed. Now update the archive_content_obj`
);
prom_api__archive_content_obj = archives_func
.update_ae_obj__archive_content({
api_cfg: $ae_api,
archive_content_id: $idaa_slct.archive_content_id,
data_kv: {
hosted_file_id: null,
file_path: null,
filename: null,
file_extension: null,
archive_content_type: null
},
log_lvl: log_lvl
})
.then(function (archive_content_obj_update_result) {
// We need to do all of this since the DB object has changed and the SLCT object does automatically update (yet...??? Svelte 5?).
// $idaa_slct.archive_content_obj = $lq__archive_content_obj;
})
.catch(function (error: any) {
console.log('Something went wrong.');
console.log(error);
return false;
});
})
.catch(function (error: any) {
console.log('Something went wrong.');
console.log(error);
return false;
})
.finally(() => {
// We need to do all of this since the DB object has changed and the SLCT object does automatically update (yet...??? Svelte 5?).
$idaa_slct.archive_content_obj.hosted_file_id = null;
$idaa_slct.archive_content_obj.file_path = null;
$idaa_slct.archive_content_obj.filename = null;
$idaa_slct.archive_content_obj.file_extension = null;
prom_api__archive_content_obj__hosted_file =
core_func
.delete_ae_obj_id__hosted_file({
api_cfg: $ae_api,
hosted_file_id:
$idaa_slct.archive_content_obj
.hosted_file_id,
link_to_type: 'archive_content',
link_to_id:
$idaa_slct.archive_content_id,
rm_orphan: true,
fake_delete: false,
log_lvl: log_lvl
})
.then(function (delete_result) {
// Second - If deleted, then update the archive_content_obj
console.log(
`File removed. Now update the archive_content_obj`
);
prom_api__archive_content_obj =
archives_func
.update_ae_obj__archive_content(
{
api_cfg: $ae_api,
archive_content_id:
$idaa_slct.archive_content_id,
data_kv: {
hosted_file_id:
null,
file_path: null,
filename: null,
file_extension:
null,
archive_content_type:
null
},
log_lvl: log_lvl
}
)
.then(
function (
archive_content_obj_update_result
) {
// We need to do all of this since the DB object has changed and the SLCT object does automatically update (yet...??? Svelte 5?).
// $idaa_slct.archive_content_obj = $lq__archive_content_obj;
}
)
.catch(function (
error: any
) {
console.log(
'Something went wrong.'
);
console.log(error);
return false;
});
})
.catch(function (error: any) {
console.log(
'Something went wrong.'
);
console.log(error);
return false;
})
.finally(() => {
// We need to do all of this since the DB object has changed and the SLCT object does automatically update (yet...??? Svelte 5?).
$idaa_slct.archive_content_obj.hosted_file_id =
null;
$idaa_slct.archive_content_obj.file_path =
null;
$idaa_slct.archive_content_obj.filename =
null;
$idaa_slct.archive_content_obj.file_extension =
null;
$idaa_slct.archive_content_obj.upload_complete = false;
$idaa_slct.archive_content_obj.hosted_file_id_li = [];
$idaa_slct.archive_content_obj.hosted_file_obj_li = [];
});
$idaa_slct.archive_content_obj.upload_complete = false;
$idaa_slct.archive_content_obj.hosted_file_id_li =
[];
$idaa_slct.archive_content_obj.hosted_file_obj_li =
[];
});
}
}}
class="novi_btn btn btn-sm preset-tonal-error float-right"
@@ -700,9 +800,13 @@
<label for="file_extension"
>File Extension
{#if !$ae_loc.administrator_access}
<span class="fas fa-lock" title="Field is locked"></span>
<span class="fas fa-lock" title="Field is locked"
></span>
{:else}
<span class="fas fa-unlock" title="Field is unlocked"></span>
<span
class="fas fa-unlock"
title="Field is unlocked"
></span>
{/if}
<input
type="text"
@@ -768,8 +872,10 @@
<select
id="original_timezone"
name="original_timezone"
value={$idaa_slct.archive_content_obj.original_timezone
? $idaa_slct.archive_content_obj.original_timezone
value={$idaa_slct.archive_content_obj
.original_timezone
? $idaa_slct.archive_content_obj
.original_timezone
: $ae_loc.current_timezone}
class="select w-56"
title="Select the original timezone"
@@ -785,8 +891,10 @@
<input
type="text"
name="timezone"
value={$idaa_slct.archive_content_obj.original_timezone
? $idaa_slct.archive_content_obj.original_timezone
value={$idaa_slct.archive_content_obj
.original_timezone
? $idaa_slct.archive_content_obj
.original_timezone
: $ae_loc.current_timezone}
class="input w-56"
/>
@@ -807,13 +915,16 @@
</div>
{#if $ae_loc.trusted_access}
<button type="button"
<button
type="button"
class="
novi_btn
btn btn-sm float-right
"
class:preset-filled-success-200-800={$idaa_loc.archives.show__admin_options}
class:preset-filled-tertiary-200-800={!$idaa_loc.archives.show__admin_options}
class:preset-filled-success-200-800={$idaa_loc.archives
.show__admin_options}
class:preset-filled-tertiary-200-800={!$idaa_loc.archives
.show__admin_options}
onclick={() => {
$idaa_loc.archives.show__admin_options =
!$idaa_loc.archives.show__admin_options;
@@ -843,11 +954,14 @@
<span
class="flex flex-col md:flex-row flex-wrap gap-2 items-center justify-center md:justify-stretch w-full"
>
<span class="flex flex-row flex-wrap gap-1 items-center justify-evenly grow">
<span
class="flex flex-row flex-wrap gap-1 items-center justify-evenly grow"
>
<fieldset
class="flex flex-row gap-1 items-center justify-center form-check"
>
<legend class="legend text-sm font-semibold form-check-label"
<legend
class="legend text-sm font-semibold form-check-label"
>Hide</legend
>
<div>
@@ -856,7 +970,9 @@
id="hide_yes"
name="hide"
value={true}
bind:group={$idaa_slct.archive_content_obj.hide}
bind:group={
$idaa_slct.archive_content_obj.hide
}
class="radio form-check-input"
/>
<label for="hide_yes">Yes</label>
@@ -867,7 +983,9 @@
id="hide_no"
name="hide"
value={false}
bind:group={$idaa_slct.archive_content_obj.hide}
bind:group={
$idaa_slct.archive_content_obj.hide
}
class="radio form-check-input"
/>
<label for="hide_no">No</label>
@@ -877,7 +995,8 @@
<fieldset
class="flex flex-row gap-1 items-center justify-center form-check"
>
<legend class="legend text-sm font-semibold form-check-label"
<legend
class="legend text-sm font-semibold form-check-label"
>Priority</legend
>
<div>
@@ -886,7 +1005,9 @@
id="priority_yes"
name="priority"
value={true}
bind:group={$idaa_slct.archive_content_obj.priority}
bind:group={
$idaa_slct.archive_content_obj.priority
}
class="radio form-check-input"
/>
<label for="priority_yes">Yes</label>
@@ -897,7 +1018,9 @@
id="priority_no"
name="priority"
value={false}
bind:group={$idaa_slct.archive_content_obj.priority}
bind:group={
$idaa_slct.archive_content_obj.priority
}
class="radio form-check-input"
/>
<label for="priority_no">No</label>
@@ -925,7 +1048,8 @@
>Group <input
type="text"
name="group"
value={$idaa_slct.archive_content_obj.group ?? ''}
value={$idaa_slct.archive_content_obj.group ??
''}
max="100"
class="input w-40 preset-tonal-surface form-control"
/></label
@@ -939,7 +1063,8 @@
<fieldset
class="flex flex-row gap-1 items-center align-center form-check"
>
<legend class="legend text-sm font-semibold form-check-label"
<legend
class="legend text-sm font-semibold form-check-label"
>Enable</legend
>
<div>
@@ -948,7 +1073,10 @@
id="enable_yes"
name="enable"
value={true}
bind:group={$idaa_slct.archive_content_obj.enable}
bind:group={
$idaa_slct.archive_content_obj
.enable
}
class="radio form-check-input"
/>
<label for="enable_yes">Yes</label>
@@ -959,7 +1087,10 @@
id="enable_no"
name="enable"
value={false}
bind:group={$idaa_slct.archive_content_obj.enable}
bind:group={
$idaa_slct.archive_content_obj
.enable
}
class="radio form-check-input"
/>
<label for="enable_no">No</label>
@@ -977,7 +1108,8 @@
{#if $ae_loc.trusted_access}
<label for="notes" class="w-full">
<span class="legend text-sm font-semibold text-surface-600-400"
<span
class="legend text-sm font-semibold text-surface-600-400"
>Internal Staff Notes</span
>
<AE_Comp_Editor_TipTap
@@ -1026,9 +1158,14 @@
</button>
{#if $idaa_slct.archive_content_id && !$idaa_slct.archive_content_obj?.hosted_file_id}
<button type="button"
<button
type="button"
onclick={() => {
if (!confirm('Are you sure you want to remove this archive content?')) {
if (
!confirm(
'Are you sure you want to remove this archive content?'
)
) {
return false;
}
@@ -1037,7 +1174,8 @@
prom_api__archive_content_obj =
archives_func.delete_ae_obj_id__archive_content({
api_cfg: $ae_api,
archive_content_id: $idaa_slct.archive_content_id,
archive_content_id:
$idaa_slct.archive_content_id,
method: method as any,
log_lvl: log_lvl
});
@@ -1063,21 +1201,29 @@
</button>
{#if $ae_loc.administrator_access && $ae_loc.edit_mode}
<button type="button"
<button
type="button"
onclick={() => {
if (!confirm('Are you sure you want to delete this archive content?')) {
if (
!confirm(
'Are you sure you want to delete this archive content?'
)
) {
return false;
}
let method = 'delete';
prom_api__archive_content_obj =
archives_func.delete_ae_obj_id__archive_content({
api_cfg: $ae_api,
archive_content_id: $idaa_slct.archive_content_id,
method: method as any,
log_lvl: log_lvl
});
archives_func.delete_ae_obj_id__archive_content(
{
api_cfg: $ae_api,
archive_content_id:
$idaa_slct.archive_content_id,
method: method as any,
log_lvl: log_lvl
}
);
$idaa_slct.archive_content_id = null;
$idaa_slct.archive_content_obj = {};