Skip to content

Commit

Permalink
feat(brillig): foreign calls with dynamic-size objects (#1705)
Browse files Browse the repository at this point in the history
* disable mac tests

* feat: added support for modulo ops on brillig (#1621)

* feat: added support for modulo ops

* chore: use ACVM 0.14.3

* revert change as its unrelated

* small comment refactor

---------

Co-authored-by: kevaundray <kevtheappdev@gmail.com>

* feat(brillig): foreign call/oracle compilation (#1600)

* remove mac runner

* chore: generate brillig opcode for simple identity unconstrained function (#1536)

* feat(brillig): added arithmetic operations on brillig (#1565)

Co-authored-by: kevaundray <kevtheappdev@gmail.com>

* make ranges be polymorphic integers

* chore(brillig): Clean up handling of Binary operations (#1571)

* chore(ssa refactor): Rename Brillig example (#1563)

* chore(brillig): added tests for all field binary operations (#1586)

* chore(brillig): added tests for brillig integer operations (#1590)

* feat: process blocks and jumps when compiling brillig (#1591)

* process jumps between blocks

* fix jumps

* add doc comments

* cargo fmt

* code refactor

* update code comment

---------

Co-authored-by: kevaundray <kevtheappdev@gmail.com>

* feat: process blocks and jumps when compiling brillig (#1591)

* process jumps between blocks

* fix jumps

* add doc comments

* cargo fmt

* code refactor

* update code comment

---------

Co-authored-by: kevaundray <kevtheappdev@gmail.com>

* feat(brillig): start of oracles/foreign calls

* fix: broken tests

* feat(brillig): parsing oracles/foreign calls (#1596)

* feat(brillig): start of oracles/foreign calls

* fix: broken tests

* Update execute.rs

* feat: more foreign call work

* self.data -> self.vars

* chore(brillig): Add handling of the not instruction (#1609)

* test: brillig oracle

* Reinstate option

* make behavior consistent

* remove closure

* change index_type

* Update crates/noirc_frontend/src/hir/type_check/expr.rs

* feat(brillig): loops (#1610)

* make ranges be polymorphic integers

* feat: brillig loop support

* fix: fixed brillig returns and stop

* fix: do not apply constants folding to brillig fns

* chore: update acvm pointer, cleanup

* style: newline on cargo toml

* make behavior consistent

* remove closure

* change index_type

* Update crates/noirc_frontend/src/hir/type_check/expr.rs

* better debug information for unsupported instruction

* remove edge case for optimizations

* clippy fix

* patch infinite loop

---------

Co-authored-by: kevaundray <kevtheappdev@gmail.com>
Co-authored-by: jfecher <jake@aztecprotocol.com>

* feat: Foreign calls compiling and basic print executed in nargo (#1612)

* get foreign calls compiling and basic print executed in nargo

* cargo clipy and cargo fmt

* missing

* Update crates/noirc_evaluator/src/brillig/brillig_gen.rs

* add issue num for logging

---------

Co-authored-by: kevaundray <kevtheappdev@gmail.com>

* chore: resolve immutable array merge differences (#1617)

* chore(ssa refactor): Switch to immutable arrays (#1578)

* Represent SSA arrays with im::Vector

* Get tests passing

* Implement assign with immutable arrays

* Add constant folding pass

* Update comments

* Clippy

* Update comment

* Update type of array

* Update crates/noirc_evaluator/src/ssa_refactor/ir/instruction.rs

Co-authored-by: Tom French <15848336+TomAFrench@users.noreply.github.com>

* Undo formatting changes in instruction.rs

* Massive acir_gen update

* Refactor acir array operations into a shared function

* Appease clippy

* Update to_radix and to_bits in acir_gen to return arrays

* Disable assert

* Fix convert_type for arrays

* Include AcirType in AcirValue::Var variant

* Fix black box functions

* Appease clippy

* Fix simple_radix

* Add doc comments

---------

Co-authored-by: Tom French <15848336+TomAFrench@users.noreply.github.com>

* feat: Make for-loop range be a polymorphic integer instead of just Field in unconstrained functions (#1583)

* make ranges be polymorphic integers

* make behavior consistent

* remove closure

* change index_type

* Update crates/noirc_frontend/src/hir/type_check/expr.rs

---------

Co-authored-by: jfecher <jake@aztecprotocol.com>

* chore(ssa refactor): fix brillig post master merge

* chore(ssa refactor): accidental merge undelete

---------

Co-authored-by: jfecher <jake@aztecprotocol.com>
Co-authored-by: Tom French <15848336+TomAFrench@users.noreply.github.com>
Co-authored-by: kevaundray <kevtheappdev@gmail.com>

* chore(ssa refactor): Add more documentation for truncation  (#1607)

* add more documentation

* small change

* Update crates/noirc_evaluator/src/ssa_refactor/acir_gen/acir_ir/generated_acir.rs

* Update .github/workflows/test.yml

* Update .github/workflows/test.yml

* remove dbg

* change printer for foreign call

* Update crates/noirc_evaluator/src/ssa_refactor/ir/function.rs

* Update crates/noirc_evaluator/src/ssa_refactor/ir/instruction.rs

Co-authored-by: kevaundray <kevtheappdev@gmail.com>

* Update crates/noirc_evaluator/src/ssa_refactor/acir_gen/acir_ir/acir_variable.rs

---------

Co-authored-by: kevaundray <kevtheappdev@gmail.com>
Co-authored-by: guipublic <47281315+guipublic@users.noreply.github.com>
Co-authored-by: Álvaro Rodríguez <sirasistant@gmail.com>
Co-authored-by: jfecher <jake@aztecprotocol.com>
Co-authored-by: Maxim Vezenov <mvezenov@gmail.com>
Co-authored-by: joss-aztec <94053499+joss-aztec@users.noreply.github.com>
Co-authored-by: Tom French <15848336+TomAFrench@users.noreply.github.com>

* feat: add support for assert in brillig (#1603)

* remove mac runner

* chore: generate brillig opcode for simple identity unconstrained function (#1536)

* feat(brillig): added arithmetic operations on brillig (#1565)

Co-authored-by: kevaundray <kevtheappdev@gmail.com>

* make ranges be polymorphic integers

* chore(brillig): Clean up handling of Binary operations (#1571)

* chore(ssa refactor): Rename Brillig example (#1563)

* chore(brillig): added tests for all field binary operations (#1586)

* chore(brillig): added tests for brillig integer operations (#1590)

* feat: process blocks and jumps when compiling brillig (#1591)

* process jumps between blocks

* fix jumps

* add doc comments

* cargo fmt

* code refactor

* update code comment

---------

Co-authored-by: kevaundray <kevtheappdev@gmail.com>

* feat: process blocks and jumps when compiling brillig (#1591)

* process jumps between blocks

* fix jumps

* add doc comments

* cargo fmt

* code refactor

* update code comment

---------

Co-authored-by: kevaundray <kevtheappdev@gmail.com>

* feat(brillig): parsing oracles/foreign calls (#1596)

* feat(brillig): start of oracles/foreign calls

* fix: broken tests

* Update execute.rs

* support assert in brillig

* self.data -> self.vars

* Avoid not in the test

* chore(brillig): Add handling of the not instruction (#1609)

* make behavior consistent

* remove closure

* change index_type

* Update crates/noirc_frontend/src/hir/type_check/expr.rs

* feat(brillig): loops (#1610)

* make ranges be polymorphic integers

* feat: brillig loop support

* fix: fixed brillig returns and stop

* fix: do not apply constants folding to brillig fns

* chore: update acvm pointer, cleanup

* style: newline on cargo toml

* make behavior consistent

* remove closure

* change index_type

* Update crates/noirc_frontend/src/hir/type_check/expr.rs

* better debug information for unsupported instruction

* remove edge case for optimizations

* clippy fix

* patch infinite loop

---------

Co-authored-by: kevaundray <kevtheappdev@gmail.com>
Co-authored-by: jfecher <jake@aztecprotocol.com>

* chore: resolve immutable array merge differences (#1617)

* chore(ssa refactor): Switch to immutable arrays (#1578)

* Represent SSA arrays with im::Vector

* Get tests passing

* Implement assign with immutable arrays

* Add constant folding pass

* Update comments

* Clippy

* Update comment

* Update type of array

* Update crates/noirc_evaluator/src/ssa_refactor/ir/instruction.rs

Co-authored-by: Tom French <15848336+TomAFrench@users.noreply.github.com>

* Undo formatting changes in instruction.rs

* Massive acir_gen update

* Refactor acir array operations into a shared function

* Appease clippy

* Update to_radix and to_bits in acir_gen to return arrays

* Disable assert

* Fix convert_type for arrays

* Include AcirType in AcirValue::Var variant

* Fix black box functions

* Appease clippy

* Fix simple_radix

* Add doc comments

---------

Co-authored-by: Tom French <15848336+TomAFrench@users.noreply.github.com>

* feat: Make for-loop range be a polymorphic integer instead of just Field in unconstrained functions (#1583)

* make ranges be polymorphic integers

* make behavior consistent

* remove closure

* change index_type

* Update crates/noirc_frontend/src/hir/type_check/expr.rs

---------

Co-authored-by: jfecher <jake@aztecprotocol.com>

* chore(ssa refactor): fix brillig post master merge

* chore(ssa refactor): accidental merge undelete

---------

Co-authored-by: jfecher <jake@aztecprotocol.com>
Co-authored-by: Tom French <15848336+TomAFrench@users.noreply.github.com>
Co-authored-by: kevaundray <kevtheappdev@gmail.com>

* chore(ssa refactor): Add more documentation for truncation  (#1607)

* add more documentation

* small change

* Update crates/noirc_evaluator/src/ssa_refactor/acir_gen/acir_ir/generated_acir.rs

* Update .github/workflows/test.yml

* Update .github/workflows/test.yml

* Remove optimisation for handling assert

* add the assert jump to the list of jumps to fix

* add doc comment

---------

Co-authored-by: kevaundray <kevtheappdev@gmail.com>
Co-authored-by: Álvaro Rodríguez <sirasistant@gmail.com>
Co-authored-by: ludamad <adam.domurad@gmail.com>
Co-authored-by: jfecher <jake@aztecprotocol.com>
Co-authored-by: joss-aztec <94053499+joss-aztec@users.noreply.github.com>
Co-authored-by: Tom French <15848336+TomAFrench@users.noreply.github.com>

* chore(ssa refactor): Separate Brillig only logic from Brillig-SSA generation logic (#1631)

* separate brillig only logic from logic that combines both brillig and ssa

* move operations related to brillig-ssa conversion to brillig_gen

* intermediate step -- make build work by leaking the abstraction

* refactor return instruction -- all of the implementation details about brillig are no longer in brillig_gen

* fix clippy

* add TODO

* move `convert_integer_mod` into BrilligIr

* encapsulate modulo operation in brillig_gen

* process binary instruction

* refactor const instruction

* make code surrounding jumps satisfy the abstraction

* move not instruction

* add foreign call instruction

* move load and store instructions to brillig_ir

* move truncate instruction

* move `mov`, `stop` and `allocate_array` methods

* fix clippy

* remove push_code method in brillig_gen

* move jump and jmpif instructions to brillig_ir

* clean up terminator instruction

* remove allow(deprecated) lint

* refactor document for link and link_with

* use .into so we can get rid of Value import

* add docs

* Update crates/noirc_evaluator/src/brillig/brillig_ir/artifact.rs

Co-authored-by: Álvaro Rodríguez <sirasistant@gmail.com>

* Update crates/noirc_evaluator/src/brillig/brillig_gen.rs

* make code a bit clearer

* fix clippy

---------

Co-authored-by: Álvaro Rodríguez <sirasistant@gmail.com>

* chore(ssa_refactor): Improve foreign call compilation (#1644)

* remove ForeignCall instruction from SSA

* remove unnecessary Oracle RuntimeType

* remove old comment

* feat: Brillig array inputs and outputs (#1630)

* first attempt at brillig multiple array inptus

* working array identity function for brillig

* cleanup dbgs

* remove unused imports

* remove dbg

* a little cleanup

* fix up foreign calls for array inputs and outputs

* fix outputs clippy err

* move conversion to RegisterValueOrArray to its own method

* missing &mut and TODO link

* PR comment for brillig output array types

* cleanup comment

* enable struct inputs/outputs

* cargo clippy

* *WIP* call brillig function from brillig

* chore(brillig): master into brillig main (#1663)

* fix(ssa refactor): resolve replaced value ids for printing (#1535)

* fix(ssa refactor): resolve replaced value ids for printing

* fix(ssa refactor): Expand PR #1535 to resolve ValueIds in all SSA passes (#1642)

* Expand PR

* chore(ssa refactor): more value id resolving

* chore(ssa refactor): another value id resolve

---------

Co-authored-by: Joss <joss@aztecprotocol.com>

---------

Co-authored-by: jfecher <jake@aztecprotocol.com>

* chore(ssa refactor): enable_side_effects instruction (#1547)

* chore(ssa refactor): enable_side_effects instruction

* chore(ssa refactor): fix and document enable_side_effects insertions

* chore(ssa refactor): rm comments

* fix(ssa refactor): redundant EnableSideEffects

* chore(ssa refactor): cp working tests (#1619)

* chore(ssa gen): ssa gen truncate instruction

* chore(ssa refactor): max bit size for subtract

* Update crates/noirc_evaluator/src/ssa_refactor/ssa_gen/context.rs

Co-authored-by: jfecher <jake@aztecprotocol.com>

* chore(ssa refactor): truncate shift left

* chore(ssa refactor): Add integer modulus when truncating subtraction

* chore(ssa refactor): clippy

* chore(ssa refactor): fix left shift max bit size

* chore(ssa refactor): cp xor test

* chore(ssa refactor): cp working tests

* chore(ssa refactor): more working tests

* chore(ssa refactor): cp working test

---------

Co-authored-by: kevaundray <kevtheappdev@gmail.com>
Co-authored-by: jfecher <jake@aztecprotocol.com>

* chore(ssa refactor): Remove unit values from SSA IR (#1646)

* Remove unit values

* Fix test

* Fix comment

* chore: Upgrade codespan dependencies (#1647)

* chore(ssa refactor): Implement dead instruction elimination pass (#1595)

* Add dead instruction elimination pass

* Enable the pass

* chore(ssa refactor): simple mut test

* chore(ssa refactor): fixup and add doc comments

* chore(ssa refactor): post merge fix

---------

Co-authored-by: Joss <joss@aztecprotocol.com>

* chore(brillig): Update acvm dependency (#1653)

chore: update acvm dep

* refactor: remove unused assign

---------

Co-authored-by: joss-aztec <94053499+joss-aztec@users.noreply.github.com>
Co-authored-by: jfecher <jake@aztecprotocol.com>
Co-authored-by: kevaundray <kevtheappdev@gmail.com>
Co-authored-by: Blaine Bublitz <blaine.bublitz@gmail.com>
Co-authored-by: Joss <joss@aztecprotocol.com>

* discriminate labels per function

* initial changes to get noir building using adam/foreign-call-vectors acvm branch

* include fix for array output from foreign calls

* fixed commit to reference remote patch

* small cleanup

* do not save the special registers

* cargo clippy

* towards dynamic arrays

* chore: bump acvm for better acvm vectors

* Towards brillig vectors

* push fix for test_brillig_ir_foreign_call_return_vector

* fix pseudo-noir in test

* add Trap opcode to make Brillig IR test more accurate

* move code from Adams and Guillaume's branch for BrilligIR

Co-authored-by: guipublic <47281315+guipublic@users.noreply.github.com>
Co-authored-by: ludamad <adam.domurad@gmail.com>

* add used registers method

Co-authored-by: ludamad <adam.domurad@gmail.com>

* add method to handle calling normal functions and thread the function_id_to_block_id through necessary functions

* add unresolved_call method into artifact struct

* remove Vec::clone

* small clean-up:

- remove magic constant
- use mov_instruction method

* modify API for linking

* pass parameter length and return type length to BrilligContext

* move entry_point_instruction to artifact for now

* refactor API -- still has a lot of scaffolding

* remove pretty_print_opcode

* chore: high level brillig printorrr

* chore: move acvm

* feat: implement call semantics  (#1746)

* fix: entry point and exit point handling

* feat: function linking

* docs: added comments

* docs: more comments

* fix: correct_usize_op

* fix: fix moving registers to registers

* fix: fixed array handling across calls

* docs: improved error msgs

* Update

* post-merge fixes

* Post-merge brillig ir printer fixes

* fix: post-merge build

* chore: fixing diff. TODO not building

* Working build

* Foreign call test

* chore: fix deps

---------

Co-authored-by: kevaundray <kevtheappdev@gmail.com>
Co-authored-by: Álvaro Rodríguez <sirasistant@gmail.com>
Co-authored-by: guipublic <47281315+guipublic@users.noreply.github.com>
Co-authored-by: jfecher <jake@aztecprotocol.com>
Co-authored-by: Maxim Vezenov <mvezenov@gmail.com>
Co-authored-by: joss-aztec <94053499+joss-aztec@users.noreply.github.com>
Co-authored-by: Tom French <15848336+TomAFrench@users.noreply.github.com>
Co-authored-by: guipublic <guipublic@gmail.com>
Co-authored-by: Blaine Bublitz <blaine.bublitz@gmail.com>
Co-authored-by: Joss <joss@aztecprotocol.com>
  • Loading branch information
11 people authored Jun 22, 2023
1 parent 8888dc6 commit fe7bb99
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 16 deletions.
6 changes: 3 additions & 3 deletions crates/nargo/src/ops/execute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ pub fn execute_circuit(
// Execute foreign calls
// TODO(#1615): "oracle_print_impl" and "oracle_print_array_impl" are just identity funcs
if foreign_call_wait_info.function == "oracle_print_impl" {
let value = foreign_call_wait_info.inputs[0][0];
println!("{:?}", value.to_field().to_hex());
brillig.foreign_call_results.push(value.into());
let values = &foreign_call_wait_info.inputs[0];
println!("{:?}", values[0].to_field().to_hex());
brillig.foreign_call_results.push(foreign_call_wait_info.inputs[0][0].into());
} else if foreign_call_wait_info.function == "oracle_print_array_impl" {
let mut outputs_hex = Vec::new();
for values in foreign_call_wait_info.inputs.clone() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,3 @@ unconstrained fn oracle_print_array_wrapper(arr: [Field; 2]) {
oracle_print_array(arr);
}


87 changes: 85 additions & 2 deletions crates/noirc_evaluator/src/brillig/brillig_ir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,6 @@ impl BrilligContext {
/// the VM.
pub(crate) fn return_instruction(&mut self, return_registers: &[RegisterIndex]) {
debug_show::return_instruction(return_registers);

let mut sources = Vec::with_capacity(return_registers.len());
let mut destinations = Vec::with_capacity(return_registers.len());

Expand Down Expand Up @@ -452,7 +451,6 @@ impl BrilligContext {
outputs: &[RegisterOrMemory],
) {
debug_show::foreign_call_instruction(func_name.clone(), inputs, outputs);
// TODO(https://github.com/noir-lang/acvm/issues/366): Enable multiple inputs and outputs to a foreign call
let opcode = BrilligOpcode::ForeignCall {
function: func_name,
destinations: outputs.to_vec(),
Expand Down Expand Up @@ -598,7 +596,9 @@ impl BrilligContext {
}

/// Adds a unresolved external `Call` instruction to the bytecode.
/// This calls into another function compiled into this brillig artifact.
pub(crate) fn add_external_call_instruction<T: ToString>(&mut self, func_label: T) {
debug_show::add_external_call_instruction(func_label.to_string());
self.obj.add_unresolved_external_call(
BrilligOpcode::Call { location: 0 },
func_label.to_string(),
Expand Down Expand Up @@ -708,3 +708,86 @@ pub(crate) enum BrilligBinaryOp {
// Brillig.
Modulo { is_signed_integer: bool, bit_size: u32 },
}

#[cfg(test)]
mod tests {
use std::vec;

use acvm::acir::brillig_vm::{
BinaryIntOp, ForeignCallOutput, ForeignCallResult, RegisterIndex, RegisterOrMemory,
Registers, VMStatus, Value, VM,
};

use crate::brillig::brillig_ir::{BrilligContext, BRILLIG_MEMORY_ADDRESSING_BIT_SIZE};

use super::{BrilligBinaryOp, BrilligOpcode, ReservedRegisters};

/// Test a Brillig foreign call returning a vector
#[test]
fn test_brillig_ir_foreign_call_return_vector() {
// pseudo-noir:
//
// #[oracle(make_number_sequence)]
// unconstrained fn make_number_sequence(size: u32) -> Vec<u32> {
// }
//
// unconstrained fn main() -> Vec<u32> {
// let the_sequence = make_number_sequence(12);
// assert(the_sequence.len() == 12);
// }
let mut context = BrilligContext::new(vec![], vec![]);
let r_stack = ReservedRegisters::stack_pointer();
// Start stack pointer at 0
context.const_instruction(r_stack, Value::from(0_usize));
let r_input_size = RegisterIndex::from(ReservedRegisters::len());
let r_array_ptr = RegisterIndex::from(ReservedRegisters::len() + 1);
let r_output_size = RegisterIndex::from(ReservedRegisters::len() + 2);
let r_equality = RegisterIndex::from(ReservedRegisters::len() + 3);
context.const_instruction(r_input_size, Value::from(12_usize));
// copy our stack frame to r_array_ptr
context.mov_instruction(r_array_ptr, r_stack);
context.foreign_call_instruction(
"make_number_sequence".into(),
&[RegisterOrMemory::RegisterIndex(r_input_size)],
&[RegisterOrMemory::HeapVector(r_stack, r_output_size)],
);
// push stack frame by r_returned_size
context.binary_instruction(
r_stack,
r_output_size,
r_stack,
BrilligBinaryOp::Integer {
op: BinaryIntOp::Add,
bit_size: BRILLIG_MEMORY_ADDRESSING_BIT_SIZE,
},
);
// check r_input_size == r_output_size
context.binary_instruction(
r_input_size,
r_output_size,
r_equality,
BrilligBinaryOp::Integer {
op: BinaryIntOp::Equals,
bit_size: BRILLIG_MEMORY_ADDRESSING_BIT_SIZE,
},
);
// We push a JumpIf and Trap opcode directly as the constrain instruction
// uses unresolved jumps which requires a block to be constructed in SSA and
// we don't need this for Brillig IR tests
context.push_opcode(BrilligOpcode::JumpIf { condition: r_equality, location: 8 });
context.push_opcode(BrilligOpcode::Trap);

context.stop_instruction();

let bytecode = context.artifact().byte_code;
let number_sequence: Vec<Value> = (0_usize..12_usize).map(Value::from).collect();
let mut vm = VM::new(
Registers { inner: vec![] },
vec![],
bytecode,
vec![ForeignCallResult { values: vec![ForeignCallOutput::Array(number_sequence)] }],
);
let status = vm.process_opcodes();
assert_eq!(status, VMStatus::Finished);
}
}
21 changes: 11 additions & 10 deletions crates/noirc_evaluator/src/brillig/brillig_ir/debug_show.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,12 +103,8 @@ impl DebugToString for RegisterOrMemory {
RegisterOrMemory::HeapArray(index, size) => {
format!("{}[0..{}]", index.debug_to_string(), size)
}
RegisterOrMemory::HeapVector(location_index, length_index) => {
format!(
"{}[0..{}]",
location_index.debug_to_string(),
length_index.debug_to_string()
)
RegisterOrMemory::HeapVector(index, size_register) => {
format!("{}[0..*{}]", index.debug_to_string(), size_register.debug_to_string())
}
}
}
Expand All @@ -121,14 +117,14 @@ impl<T: DebugToString> DebugToString for [T] {
}

macro_rules! debug_println {
( $first:expr ) => {
( $literal:expr ) => {
if ENABLE_DEBUG_TRACE {
println!("{}", $first);
println!("{}", $literal);
}
};
( $first:expr, $( $x:expr ),* ) => {
( $format_message:expr, $( $x:expr ),* ) => {
if ENABLE_DEBUG_TRACE {
println!($first, $( $x.debug_to_string(), )*)
println!($format_message, $( $x.debug_to_string(), )*)
}
};
}
Expand Down Expand Up @@ -257,3 +253,8 @@ pub(crate) fn cast_instruction(
) {
debug_println!(" CAST {} FROM {} TO {} BITS", destination, source, target_bit_size);
}

/// Debug function for cast_instruction
pub(crate) fn add_external_call_instruction(func_label: String) {
debug_println!(" CALL {}", func_label);
}

0 comments on commit fe7bb99

Please sign in to comment.