Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat!: storage_layout and #[aztec(storage)] #5387

Merged
merged 90 commits into from
Apr 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
90 commits
Select commit Hold shift + click to select a range
e1190bc
changed storage macro to look for attribute
Thunkar Mar 19, 2024
c41eba8
added abi exports to contract artifact
Thunkar Mar 22, 2024
6caea1e
changed storage macro to look for attribute
Thunkar Mar 19, 2024
01506c9
added abi exports to contract artifact
Thunkar Mar 22, 2024
3873a65
reverted change
Thunkar Mar 22, 2024
ce6b163
removed unused variable
Thunkar Mar 22, 2024
733f0ec
clippy pass
Thunkar Mar 22, 2024
9b6af4b
fixes and consistency
Thunkar Mar 22, 2024
ad2a62f
cleanup and test
Thunkar Mar 26, 2024
445b9e6
updated snapshots, types
Thunkar Mar 26, 2024
2124cfa
changed integer serialization
Thunkar Mar 26, 2024
3a388be
added abi exports to contract artifact
Thunkar Mar 22, 2024
85596ec
added abi exports to contract artifact
Thunkar Mar 22, 2024
46df9a5
reverted change
Thunkar Mar 22, 2024
0132139
clippy pass
Thunkar Mar 22, 2024
6545eec
wip
Thunkar Mar 22, 2024
7c6544f
wip
Thunkar Mar 22, 2024
efe757d
storage layout export and note ids
Thunkar Mar 26, 2024
82ca876
working storage layout and notes
Thunkar Mar 26, 2024
f367d15
updated snapshot
Thunkar Mar 26, 2024
84bf37a
better codegen and fixed test
Thunkar Mar 26, 2024
f1baaf0
Merge branch 'master' of github.com:AztecProtocol/aztec-packages into…
Thunkar Mar 26, 2024
614942a
Merge branch 'master' of github.com:AztecProtocol/aztec-packages into…
Thunkar Mar 26, 2024
3c0787c
Merge branch 'gj/contract_abi_exports' into gj/storage_layout
Thunkar Mar 26, 2024
e4cf336
Merge branch 'master' into gj/contract_abi_exports
Thunkar Mar 27, 2024
7b8eed6
Merge branch 'gj/contract_abi_exports' of github.com:AztecProtocol/az…
Thunkar Mar 27, 2024
9f94e95
removed macro pass, general cleanup and fixes
Thunkar Mar 27, 2024
1e238d8
used in e2e, clippy
Thunkar Mar 27, 2024
28ce5e6
fixed snapshot
Thunkar Mar 27, 2024
edba6f1
prettier run
Thunkar Mar 27, 2024
423537e
Merge branch 'master' of github.com:AztecProtocol/aztec-packages into…
Thunkar Mar 27, 2024
99c5128
yet another snapshot. fun
Thunkar Mar 27, 2024
7227650
Merge branch 'master' of github.com:AztecProtocol/aztec-packages into…
Thunkar Mar 27, 2024
be95f17
Merge branch 'master' into gj/contract_abi_exports
Thunkar Mar 27, 2024
a176860
Merge branch 'gj/contract_abi_exports' into gj/storage_layout
Thunkar Mar 27, 2024
92e4397
Merge branch 'master' into gj/contract_abi_exports
Thunkar Mar 27, 2024
04b7b19
Merge branch 'gj/contract_abi_exports' into gj/storage_layout
Thunkar Mar 27, 2024
ba59549
Merge branch 'master' into gj/contract_abi_exports
Thunkar Mar 27, 2024
08a3374
Merge branch 'gj/contract_abi_exports' into gj/storage_layout
Thunkar Mar 27, 2024
328108f
Merge branch 'master' of github.com:AztecProtocol/aztec-packages into…
Thunkar Apr 1, 2024
a75c843
updated snapshots
Thunkar Apr 1, 2024
1c1e156
Merge branch 'gj/contract_abi_exports' of github.com:AztecProtocol/az…
Thunkar Apr 1, 2024
e4f75eb
merge changes
Thunkar Apr 1, 2024
2859f5f
updated artifact hash
Thunkar Apr 1, 2024
53918d9
correct hash
Thunkar Apr 1, 2024
f16ec80
Merge branch 'master' of github.com:AztecProtocol/aztec-packages into…
Thunkar Apr 2, 2024
622ef04
Merge branch 'gj/contract_abi_exports' of github.com:AztecProtocol/az…
Thunkar Apr 2, 2024
e0f2ca2
Update noir/noir-repo/aztec_macros/src/lib.rs
Thunkar Apr 2, 2024
b0b796e
Merge branch 'gj/contract_abi_exports' into gj/storage_layout
Thunkar Apr 2, 2024
2d18874
guess what
Thunkar Apr 2, 2024
4b8464d
PR changes
Thunkar Apr 2, 2024
0c175fd
more pr improvements
Thunkar Apr 2, 2024
db649f8
Merge branch 'gj/contract_abi_exports' of github.com:AztecProtocol/az…
Thunkar Apr 2, 2024
c2febc9
reverted abi tag error
Thunkar Apr 2, 2024
95e5025
clippy pass
Thunkar Apr 2, 2024
93b6cb1
Merge branch 'master' into gj/contract_abi_exports
Thunkar Apr 2, 2024
8f7d587
Merge branch 'gj/contract_abi_exports' of github.com:AztecProtocol/az…
Thunkar Apr 2, 2024
ef571c9
pr comment
Thunkar Apr 2, 2024
3b7d7b5
added tuple values
Thunkar Apr 2, 2024
ce404c9
removed unused import
Thunkar Apr 2, 2024
31996d9
Merge branch 'gj/contract_abi_exports' of github.com:AztecProtocol/az…
Thunkar Apr 2, 2024
b673d1c
fixed integer conversion
Thunkar Apr 2, 2024
8feb6d4
Merge branch 'gj/contract_abi_exports' of github.com:AztecProtocol/az…
Thunkar Apr 2, 2024
ecd305b
changed approach
Thunkar Apr 3, 2024
45914ba
Merge branch 'master' of github.com:AztecProtocol/aztec-packages into…
Thunkar Apr 3, 2024
a586479
restrict abi tag again
Thunkar Apr 3, 2024
a8536aa
Merge branch 'master' of github.com:AztecProtocol/aztec-packages into…
Thunkar Apr 3, 2024
9479047
Merge branch 'gj/contract_abi_exports' of github.com:AztecProtocol/az…
Thunkar Apr 3, 2024
6455797
clippy pass
Thunkar Apr 3, 2024
defffbb
updated snapshot
Thunkar Apr 3, 2024
2ed4aaf
Merge branch 'master' of github.com:AztecProtocol/aztec-packages into…
Thunkar Apr 4, 2024
2e5d302
Merge branch 'gj/contract_abi_exports' of github.com:AztecProtocol/az…
Thunkar Apr 4, 2024
7a2d041
removed repeated block
Thunkar Apr 4, 2024
e7ee0c2
Merge branch 'gj/contract_abi_exports' of github.com:AztecProtocol/az…
Thunkar Apr 4, 2024
52c6db0
Merge branch 'master' of github.com:AztecProtocol/aztec-packages into…
Thunkar Apr 4, 2024
8e49bb5
Merge branch 'gj/contract_abi_exports' into gj/storage_layout
Thunkar Apr 4, 2024
5d1bdcc
Merge branch 'master' of github.com:AztecProtocol/aztec-packages into…
Thunkar Apr 4, 2024
3e7cf15
updated artifact hash
Thunkar Apr 4, 2024
8861e7d
Merge branch 'master' into gj/storage_layout
Thunkar Apr 4, 2024
0a18551
Merge branch 'master' of github.com:AztecProtocol/aztec-packages into…
Thunkar Apr 8, 2024
7674111
added docs
Thunkar Apr 8, 2024
88e6858
migration notes
Thunkar Apr 8, 2024
d08e7bb
updated hash
Thunkar Apr 8, 2024
8a4d9fe
just to see ci fail
Thunkar Apr 8, 2024
cd60d9b
fix
Thunkar Apr 8, 2024
d7e2e22
guess what
Thunkar Apr 8, 2024
efba461
pr review
Thunkar Apr 8, 2024
04f0ea5
Merge branch 'master' of github.com:AztecProtocol/aztec-packages into…
Thunkar Apr 8, 2024
9b9de51
Merge branch 'master' of github.com:AztecProtocol/aztec-packages into…
Thunkar Apr 8, 2024
a6009ed
hash
Thunkar Apr 8, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/docs/developers/contracts/references/storage/main.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Smart contracts rely on storage, acting as the persistent memory on the blockcha
To learn how to define a storage struct, read [this guide](../../writing_contracts/storage/define_storage.md).
To learn more about storage slots, read [this explainer](../../writing_contracts/storage/storage_slots.md).

You control this storage in Aztec using the `Storage` struct. This struct serves as the housing unit for all your smart contract's state variables - the data it needs to keep track of and maintain.
You control this storage in Aztec using a struct annotated with `#[aztec(storage)]`. This struct serves as the housing unit for all your smart contract's state variables - the data it needs to keep track of and maintain.

These state variables come in two forms: public and private. Public variables are visible to anyone, and private variables remain hidden within the contract.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@ struct Storage {
}
```

If you have defined a `Storage` struct following this naming scheme, then it will be made available to you through the reserved `storage` keyword within your contract functions.
If you have defined a struct and annotated it as `#[aztec(storage)]`, then it will be made available to you through the reserved `storage` keyword within your contract functions.
43 changes: 43 additions & 0 deletions docs/docs/misc/migration_notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,49 @@ Aztec is in full-speed development. Literally every version breaks compatibility

## TBD

### [Aztec.nr] Storage struct annotation

The storage struct now identified by the annotation `#[aztec(storage)]`, instead of having to rely on it being called `Storage`.

```diff
- struct Storage {
- ...
- }
+ #[aztec(storage)]
+ struct MyStorageStruct {
+ ...
+ }
```

### [Aztec.js] Storage layout and note info

Storage layout and note information are now exposed in the TS contract artifact

```diff
- const note = new Note([new Fr(mintAmount), secretHash]);
- const pendingShieldStorageSlot = new Fr(5n); // storage slot for pending_shields
- const noteTypeId = new Fr(84114971101151129711410111011678111116101n); // note type id for TransparentNote
- const extendedNote = new ExtendedNote(
- note,
- admin.address,
- token.address,
- pendingShieldStorageSlot,
- noteTypeId,
- receipt.txHash,
- );
- await pxe.addNote(extendedNote);
+ const note = new Note([new Fr(mintAmount), secretHash]);
+ const extendedNote = new ExtendedNote(
+ note,
+ admin.address,
+ token.address,
+ TokenContract.storage.pending_shields.slot,
+ TokenContract.notes.TransparentNote.id,
+ receipt.txHash,
+ );
+ await pxe.addNote(extendedNote);
```

### [Aztec.nr] rand oracle is now called unsafe_rand
`oracle::rand::rand` has been renamed to `oracle::unsafe_rand::unsafe_rand`.
This change was made to communicate that we do not constrain the value in circuit and instead we just trust our PXE.
Expand Down
2 changes: 1 addition & 1 deletion noir-projects/aztec-nr/aztec/src/prelude.nr
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::{
state_vars::{
map::Map, private_immutable::PrivateImmutable, private_mutable::PrivateMutable,
public_immutable::PublicImmutable, public_mutable::PublicMutable, private_set::PrivateSet,
shared_immutable::SharedImmutable
shared_immutable::SharedImmutable, storage::Storable
},
log::{emit_unencrypted_log, emit_encrypted_log}, context::PrivateContext,
note::{
Expand Down
9 changes: 9 additions & 0 deletions noir-projects/aztec-nr/aztec/src/state_vars/storage.nr
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,12 @@ trait Storage<T> where T: Serialize<N> + Deserialize<N> {
self.storage_slot
}
}

// Struct representing an exportable storage variable in the contract
// Every entry in the storage struct will be exported in the compilation artifact as a
// Storable entity, containing the storage slot and the type of the variable
struct Storable<N> {
Thunkar marked this conversation as resolved.
Show resolved Hide resolved
slot: Field,
typ: str<N>
}

48 changes: 13 additions & 35 deletions noir/noir-repo/aztec_macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,15 @@ use transforms::{
compute_note_hash_and_nullifier::inject_compute_note_hash_and_nullifier,
events::{generate_selector_impl, transform_events},
functions::{transform_function, transform_unconstrained},
note_interface::generate_note_interface_impl,
note_interface::{generate_note_interface_impl, inject_note_exports},
storage::{
assign_storage_slots, check_for_storage_definition, check_for_storage_implementation,
generate_storage_implementation,
generate_storage_implementation, generate_storage_layout,
},
};

use noirc_frontend::{
hir::def_collector::dc_crate::{UnresolvedFunctions, UnresolvedTraitImpl},
macros_api::{CrateId, FileId, HirContext, MacroError, MacroProcessor, SortedModule, Span},
use noirc_frontend::macros_api::{
CrateId, FileId, HirContext, MacroError, MacroProcessor, SortedModule, Span,
};

use utils::{
Expand All @@ -36,16 +35,6 @@ impl MacroProcessor for AztecMacro {
transform(ast, crate_id, file_id, context)
}

fn process_collected_defs(
&self,
crate_id: &CrateId,
context: &mut HirContext,
collected_trait_impls: &[UnresolvedTraitImpl],
collected_functions: &mut [UnresolvedFunctions],
) -> Result<(), (MacroError, FileId)> {
transform_collected_defs(crate_id, context, collected_trait_impls, collected_functions)
}

fn process_typed_ast(
&self,
crate_id: &CrateId,
Expand Down Expand Up @@ -95,6 +84,7 @@ fn transform_module(module: &mut SortedModule) -> Result<bool, AztecMacroError>
if !check_for_storage_implementation(module, &storage_struct_name) {
generate_storage_implementation(module, &storage_struct_name)?;
}
generate_storage_layout(module, storage_struct_name)?;
}

for structure in module.types.iter_mut() {
Expand Down Expand Up @@ -185,24 +175,6 @@ fn transform_module(module: &mut SortedModule) -> Result<bool, AztecMacroError>
Ok(has_transformed_module)
}

fn transform_collected_defs(
crate_id: &CrateId,
context: &mut HirContext,
collected_trait_impls: &[UnresolvedTraitImpl],
collected_functions: &mut [UnresolvedFunctions],
) -> Result<(), (MacroError, FileId)> {
if has_aztec_dependency(crate_id, context) {
inject_compute_note_hash_and_nullifier(
crate_id,
context,
collected_trait_impls,
collected_functions,
)
} else {
Ok(())
}
}

//
// Transform Hir Nodes for Aztec
//
Expand All @@ -212,6 +184,12 @@ fn transform_hir(
crate_id: &CrateId,
context: &mut HirContext,
) -> Result<(), (AztecMacroError, FileId)> {
transform_events(crate_id, context)?;
assign_storage_slots(crate_id, context)
if has_aztec_dependency(crate_id, context) {
transform_events(crate_id, context)?;
inject_compute_note_hash_and_nullifier(crate_id, context)?;
assign_storage_slots(crate_id, context)?;
inject_note_exports(crate_id, context)
} else {
Ok(())
}
}
Original file line number Diff line number Diff line change
@@ -1,48 +1,43 @@
use noirc_errors::{Location, Span};
use noirc_frontend::{
graph::CrateId,
hir::{
def_collector::dc_crate::{UnresolvedFunctions, UnresolvedTraitImpl},
def_map::{LocalModuleId, ModuleId},
},
macros_api::{FileId, HirContext, MacroError},
node_interner::FuncId,
parse_program, FunctionReturnType, ItemVisibility, NoirFunction, UnresolvedTypeData,
macros_api::{FileId, HirContext},
parse_program, FunctionReturnType, NoirFunction, Type, UnresolvedTypeData,
};

use crate::utils::hir_utils::fetch_struct_trait_impls;
use crate::utils::{
errors::AztecMacroError,
hir_utils::{collect_crate_functions, fetch_notes, get_contract_module_data, inject_fn},
};

// Check if "compute_note_hash_and_nullifier(AztecAddress,Field,Field,Field,[Field; N]) -> [Field; 4]" is defined
fn check_for_compute_note_hash_and_nullifier_definition(
functions_data: &[(LocalModuleId, FuncId, NoirFunction)],
module_id: LocalModuleId,
crate_id: &CrateId,
context: &HirContext,
) -> bool {
functions_data.iter().filter(|func_data| func_data.0 == module_id).any(|func_data| {
func_data.2.def.name.0.contents == "compute_note_hash_and_nullifier"
&& func_data.2.def.parameters.len() == 5
&& match &func_data.2.def.parameters[0].typ.typ {
UnresolvedTypeData::Named(path, _, _) => path.segments.last().unwrap().0.contents == "AztecAddress",
_ => false,
}
&& func_data.2.def.parameters[1].typ.typ == UnresolvedTypeData::FieldElement
&& func_data.2.def.parameters[2].typ.typ == UnresolvedTypeData::FieldElement
&& func_data.2.def.parameters[3].typ.typ == UnresolvedTypeData::FieldElement
// checks if the 5th parameter is an array and the Box<UnresolvedType> in
// Array(Option<UnresolvedTypeExpression>, Box<UnresolvedType>) contains only fields
&& match &func_data.2.def.parameters[4].typ.typ {
UnresolvedTypeData::Array(_, inner_type) => {
matches!(inner_type.typ, UnresolvedTypeData::FieldElement)
},
_ => false,
}
collect_crate_functions(crate_id, context).iter().any(|funct_id| {
let func_data = context.def_interner.function_meta(funct_id);
let func_name = context.def_interner.function_name(funct_id);
func_name == "compute_note_hash_and_nullifier"
&& func_data.parameters.len() == 5
&& func_data.parameters.0.first().is_some_and(| (_, typ, _) | match typ {
Type::Struct(struct_typ, _) => struct_typ.borrow().name.0.contents == "AztecAddress",
_ => false
})
&& func_data.parameters.0.get(1).is_some_and(|(_, typ, _)| typ.is_field())
&& func_data.parameters.0.get(2).is_some_and(|(_, typ, _)| typ.is_field())
&& func_data.parameters.0.get(3).is_some_and(|(_, typ, _)| typ.is_field())
// checks if the 5th parameter is an array and contains only fields
&& func_data.parameters.0.get(4).is_some_and(|(_, typ, _)| match typ {
Type::Array(_, inner_type) => inner_type.to_owned().is_field(),
_ => false
})
// We check the return type the same way as we did the 5th parameter
&& match &func_data.2.def.return_type {
&& match &func_data.return_type {
FunctionReturnType::Default(_) => false,
FunctionReturnType::Ty(unresolved_type) => {
match &unresolved_type.typ {
UnresolvedTypeData::Array(_, inner_type) => {
matches!(inner_type.typ, UnresolvedTypeData::FieldElement)
},
UnresolvedTypeData::Array(_, inner_type) => matches!(inner_type.typ, UnresolvedTypeData::FieldElement),
_ => false,
}
}
Expand All @@ -53,77 +48,33 @@ fn check_for_compute_note_hash_and_nullifier_definition(
pub fn inject_compute_note_hash_and_nullifier(
crate_id: &CrateId,
context: &mut HirContext,
unresolved_traits_impls: &[UnresolvedTraitImpl],
collected_functions: &mut [UnresolvedFunctions],
) -> Result<(), (MacroError, FileId)> {
// We first fetch modules in this crate which correspond to contracts, along with their file id.
let contract_module_file_ids: Vec<(LocalModuleId, FileId)> = context
.def_map(crate_id)
.expect("ICE: Missing crate in def_map")
.modules()
.iter()
.filter(|(_, module)| module.is_contract)
.map(|(idx, module)| (LocalModuleId(idx), module.location.file))
.collect();

// If the current crate does not contain a contract module we simply skip it.
if contract_module_file_ids.is_empty() {
return Ok(());
} else if contract_module_file_ids.len() != 1 {
panic!("Found multiple contracts in the same crate");
) -> Result<(), (AztecMacroError, FileId)> {
if let Some((module_id, file_id)) = get_contract_module_data(context, crate_id) {
// If compute_note_hash_and_nullifier is already defined by the user, we skip auto-generation in order to provide an
// escape hatch for this mechanism.
// TODO(#4647): improve this diagnosis and error messaging.
if check_for_compute_note_hash_and_nullifier_definition(crate_id, context) {
return Ok(());
}

// In order to implement compute_note_hash_and_nullifier, we need to know all of the different note types the
// contract might use. These are the types that are marked as #[aztec(note)].
let note_types = fetch_notes(context)
.iter()
.map(|(_, note)| note.borrow().name.0.contents.clone())
.collect::<Vec<_>>();

// We can now generate a version of compute_note_hash_and_nullifier tailored for the contract in this crate.
let func = generate_compute_note_hash_and_nullifier(&note_types);

// And inject the newly created function into the contract.

// TODO(#4373): We don't have a reasonable location for the source code of this autogenerated function, so we simply
// pass an empty span. This function should not produce errors anyway so this should not matter.
let location = Location::new(Span::empty(0), file_id);

inject_fn(crate_id, context, func, location, module_id, file_id);
}

let (module_id, file_id) = contract_module_file_ids[0];

// If compute_note_hash_and_nullifier is already defined by the user, we skip auto-generation in order to provide an
// escape hatch for this mechanism.
// TODO(#4647): improve this diagnosis and error messaging.
if collected_functions.iter().any(|coll_funcs_data| {
check_for_compute_note_hash_and_nullifier_definition(&coll_funcs_data.functions, module_id)
}) {
return Ok(());
}

// In order to implement compute_note_hash_and_nullifier, we need to know all of the different note types the
// contract might use. These are the types that implement the NoteInterface trait, which provides the
// get_note_type_id function.
let note_types = fetch_struct_trait_impls(context, unresolved_traits_impls, "NoteInterface");

// We can now generate a version of compute_note_hash_and_nullifier tailored for the contract in this crate.
let func = generate_compute_note_hash_and_nullifier(&note_types);

// And inject the newly created function into the contract.

// TODO(#4373): We don't have a reasonable location for the source code of this autogenerated function, so we simply
// pass an empty span. This function should not produce errors anyway so this should not matter.
let location = Location::new(Span::empty(0), file_id);

// These are the same things the ModCollector does when collecting functions: we push the function to the
// NodeInterner, declare it in the module (which checks for duplicate definitions), and finally add it to the list
// on collected but unresolved functions.

let func_id = context.def_interner.push_empty_fn();
context.def_interner.push_function(
func_id,
&func.def,
ModuleId { krate: *crate_id, local_id: module_id },
location,
);

context.def_map_mut(crate_id).unwrap()
.modules_mut()[module_id.0]
.declare_function(
func.name_ident().clone(), ItemVisibility::Public, func_id
).expect(
"Failed to declare the autogenerated compute_note_hash_and_nullifier function, likely due to a duplicate definition. See https://github.com/AztecProtocol/aztec-packages/issues/4647."
);

collected_functions
.iter_mut()
.find(|fns| fns.file_id == file_id)
.expect("ICE: no functions found in contract file")
.push_fn(module_id, func_id, func.clone());

Ok(())
}

Expand Down
2 changes: 1 addition & 1 deletion noir/noir-repo/aztec_macros/src/transforms/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ pub fn transform_events(
crate_id: &CrateId,
context: &mut HirContext,
) -> Result<(), (AztecMacroError, FileId)> {
for struct_id in collect_crate_structs(crate_id, context) {
for (_, struct_id) in collect_crate_structs(crate_id, context) {
let attributes = context.def_interner.struct_attributes(&struct_id);
if attributes.iter().any(|attr| is_custom_attribute(attr, "aztec(event)")) {
transform_event(struct_id, &mut context.def_interner)?;
Expand Down
Loading
Loading