diff --git a/Cargo.toml b/Cargo.toml index add5176fe..062b70d47 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,6 +18,7 @@ lambdaworks-math = { path = "./math", version = "0.5.0", default-features = fals stark-platinum-prover = { path = "./provers/stark" } cairo-platinum-prover = { path = "./provers/cairo" } lambdaworks-winterfell-adapter = { path = "./winterfell_adapter"} + [patch.crates-io] winter-air = { git = "https://github.com/lambdaclass/winterfell-for-lambdaworks.git", branch = "derive-clone-v6.4"} winter-prover = { git = "https://github.com/lambdaclass/winterfell-for-lambdaworks.git", branch = "derive-clone-v6.4"} diff --git a/Makefile b/Makefile index 54039858c..627feec6f 100644 --- a/Makefile +++ b/Makefile @@ -24,6 +24,7 @@ clippy: cargo clippy --workspace --all-targets -- -D warnings cargo clippy --workspace --all-targets --features wasm -- -D warnings cargo clippy --workspace --all-targets --features cli -- -D warnings + cargo clippy --workspace --all-targets --features parallel -- -D warnings cargo clippy --tests clippy-cuda: diff --git a/examples/prove-miden/Cargo.toml b/examples/prove-miden/Cargo.toml index e41506b92..c2af9514f 100644 --- a/examples/prove-miden/Cargo.toml +++ b/examples/prove-miden/Cargo.toml @@ -13,7 +13,7 @@ path = "src/main.rs" lambdaworks-crypto = { workspace = true } lambdaworks-math = { workspace = true, features = ["lambdaworks-serde-string"] } lambdaworks-winterfell-adapter = { workspace = true } -stark-platinum-prover = { workspace = true, features = ["instruments", "parallel"] } +stark-platinum-prover = { git = "https://github.com/lambdaclass/lambdaworks" , rev = "3da725de1e6f76c04ddbb3ccb67e6038a7663134", features = ["winter_compatibility"] } serde = { version = "1.0" } serde_json = "1" diff --git a/provers/cairo/proof.proof b/provers/cairo/proof.proof new file mode 100644 index 000000000..82d522cb2 Binary files /dev/null and b/provers/cairo/proof.proof differ diff --git a/provers/cairo/src/air.rs b/provers/cairo/src/air.rs index 1bc3bcd42..7ab877779 100644 --- a/provers/cairo/src/air.rs +++ b/provers/cairo/src/air.rs @@ -1,4 +1,8 @@ +use super::{cairo_mem::CairoMemory, register_states::RegisterStates}; +use crate::transition_constraints::*; use cairo_vm::{air_public_input::MemorySegmentAddresses, without_std::collections::HashMap}; +#[cfg(debug_assertions)] +use itertools::Itertools; use lambdaworks_math::{ errors::DeserializationError, field::{ @@ -12,95 +16,14 @@ use stark_platinum_prover::{ frame::Frame, proof::{options::ProofOptions, stark::StarkProof}, prover::{IsStarkProver, Prover, ProvingError}, - trace::{StepView, TraceTable}, + trace::TraceTable, traits::AIR, transcript::{IsStarkTranscript, StoneProverTranscript}, verifier::{IsStarkVerifier, Verifier}, + Felt252, }; +use stark_platinum_prover::{constraints::transition::TransitionConstraint, table::Table}; -use crate::Felt252; -use stark_platinum_prover::table::Table; - -use super::{cairo_mem::CairoMemory, register_states::RegisterStates}; - -/// Main constraint identifiers -const INST: usize = 16; -const DST_ADDR: usize = 17; -const OP0_ADDR: usize = 18; -const OP1_ADDR: usize = 19; -const NEXT_AP: usize = 20; -const NEXT_FP: usize = 21; -const NEXT_PC_1: usize = 22; -const NEXT_PC_2: usize = 23; -const T0: usize = 24; -const T1: usize = 25; -const MUL_1: usize = 26; -const MUL_2: usize = 27; -const CALL_1: usize = 28; -const CALL_2: usize = 29; -const ASSERT_EQ: usize = 30; - -// Auxiliary constraint identifiers -const MEMORY_INCREASING_0: usize = 31; -const MEMORY_INCREASING_1: usize = 32; -const MEMORY_INCREASING_2: usize = 33; -const MEMORY_INCREASING_3: usize = 34; -const MEMORY_INCREASING_4: usize = 35; - -const MEMORY_CONSISTENCY_0: usize = 36; -const MEMORY_CONSISTENCY_1: usize = 37; -const MEMORY_CONSISTENCY_2: usize = 38; -const MEMORY_CONSISTENCY_3: usize = 39; -const MEMORY_CONSISTENCY_4: usize = 40; - -const PERMUTATION_ARGUMENT_0: usize = 41; -const PERMUTATION_ARGUMENT_1: usize = 42; -const PERMUTATION_ARGUMENT_2: usize = 43; -const PERMUTATION_ARGUMENT_3: usize = 44; -const PERMUTATION_ARGUMENT_4: usize = 45; - -const RANGE_CHECK_INCREASING_0: usize = 46; -const RANGE_CHECK_INCREASING_1: usize = 47; -const RANGE_CHECK_INCREASING_2: usize = 48; -const RANGE_CHECK_INCREASING_3: usize = 49; - -const RANGE_CHECK_0: usize = 50; -const RANGE_CHECK_1: usize = 51; -const RANGE_CHECK_2: usize = 52; -const RANGE_CHECK_3: usize = 53; - -const FLAG_OP1_BASE_OP0_BIT: usize = 54; -const FLAG_RES_OP1_BIT: usize = 55; -const FLAG_PC_UPDATE_REGULAR_BIT: usize = 56; -const FLAG_FP_UPDATE_REGULAR_BIT: usize = 57; - -const OPCODES_CALL_OFF0: usize = 58; -const OPCODES_CALL_OFF1: usize = 59; -const OPCODES_CALL_FLAGS: usize = 60; - -const OPCODES_RET_OFF0: usize = 61; -const OPCODES_RET_OFF2: usize = 62; -const OPCODES_RET_FLAGS: usize = 63; - -// Frame row identifiers -// - Flags -const F_DST_FP: usize = 0; -const F_OP_0_FP: usize = 1; -const F_OP_1_VAL: usize = 2; -const F_OP_1_FP: usize = 3; -const F_OP_1_AP: usize = 4; -const F_RES_ADD: usize = 5; -const F_RES_MUL: usize = 6; -const F_PC_ABS: usize = 7; -const F_PC_REL: usize = 8; -const F_PC_JNZ: usize = 9; -const F_AP_ADD: usize = 10; -const F_AP_ONE: usize = 11; -const F_OPC_CALL: usize = 12; -const F_OPC_RET: usize = 13; -const F_OPC_AEQ: usize = 14; - -// - Others // TODO: These should probably be in the TraceTable module. pub const FRAME_RES: usize = 16; pub const FRAME_AP: usize = 17; @@ -199,6 +122,7 @@ impl Segment { stop_ptr, } } + pub fn segment_size(&self) -> usize { self.stop_ptr - self.begin_addr - 1 } @@ -502,17 +426,12 @@ impl Deserializable for PublicInputs { } } -#[derive(Clone)] pub struct CairoAIR { pub context: AirContext, pub trace_length: usize, pub pub_inputs: PublicInputs, -} - -pub struct CairoRAPChallenges { - pub alpha_memory: FieldElement, - pub z_memory: FieldElement, - pub z_range_check: FieldElement, + pub transition_constraints: + Vec>>, } /// Receives two slices corresponding to the accessed addresses and values, filled with @@ -568,10 +487,10 @@ fn generate_memory_permutation_argument_column( values_original: Vec, addresses_sorted: &[Felt252], values_sorted: &[Felt252], - rap_challenges: &CairoRAPChallenges, + rap_challenges: &[Felt252], ) -> Vec { - let z = &rap_challenges.z_memory; - let alpha = &rap_challenges.alpha_memory; + let z = &rap_challenges[1]; + let alpha = &rap_challenges[0]; let mut denom: Vec<_> = addresses_sorted .iter() @@ -595,9 +514,9 @@ fn generate_memory_permutation_argument_column( fn generate_range_check_permutation_argument_column( offset_column_original: &[Felt252], offset_column_sorted: &[Felt252], - rap_challenges: &CairoRAPChallenges, + rap_challenges: &[Felt252], ) -> Vec { - let z = &rap_challenges.z_range_check; + let z = rap_challenges[2]; let mut denom: Vec<_> = offset_column_sorted.iter().map(|x| z - x).collect(); FieldElement::inplace_batch_inverse(&mut denom).unwrap(); @@ -616,7 +535,6 @@ fn generate_range_check_permutation_argument_column( impl AIR for CairoAIR { type Field = Stark252PrimeField; type FieldExtension = Stark252PrimeField; - type RAPChallenges = CairoRAPChallenges; type PublicInputs = PublicInputs; const STEP_SIZE: usize = 1; @@ -628,45 +546,114 @@ impl AIR for CairoAIR { /// * `trace_length` - Length of the Cairo execution trace. Must be a power fo two. /// * `pub_inputs` - Public inputs sent by the Cairo runner. /// * `proof_options` - STARK proving configuration options. - #[rustfmt::skip] fn new( trace_length: usize, pub_inputs: &Self::PublicInputs, - proof_options: &ProofOptions + proof_options: &ProofOptions, ) -> Self { debug_assert!(trace_length.is_power_of_two()); - let trace_columns = 59; - let transition_exemptions = vec![ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // flags (16) - 0, // inst (1) - 0, 0, 0, // operand consraints (3) - 1, 1, 1, 1, 0, 0, // register constraints (6) - 0, 0, 0, 0, 0, // opcode constraints (5) - 0, 0, 0, 0, 1, // memory continuous (4) - 0, 0, 0, 0, 1, // memory value consistency (4) - 0, 0, 0, 0, 1, // memory permutation argument (4) - 0, 0, 0, 1, // range check continuous (3) - 0, 0, 0, 0, // range check permutation argument (3) - 0, // f_op1_imm_bit constraint - 0, // flag_res_op1_bit constraint - 0, // flag_pc_update_regular_bit constraint - 0, // flag_fp_update_regular_bit constraint - 0, // opcodes/call/off0 constraint - 0, // opcodes/call/off1 constraint - 0, // cpu/opcodes/call/flags - 0, // cpu/opcodes/ret/off0 - 0, // cpu/opcodes/ret/off2 - 0, // cpu/opcodes/ret/flags + + let transition_constraints: Vec< + Box>, + > = vec![ + Box::new(BitPrefixFlag0::new()), + Box::new(BitPrefixFlag1::new()), + Box::new(BitPrefixFlag2::new()), + Box::new(BitPrefixFlag3::new()), + Box::new(BitPrefixFlag4::new()), + Box::new(BitPrefixFlag5::new()), + Box::new(BitPrefixFlag6::new()), + Box::new(BitPrefixFlag7::new()), + Box::new(BitPrefixFlag8::new()), + Box::new(BitPrefixFlag9::new()), + Box::new(BitPrefixFlag10::new()), + Box::new(BitPrefixFlag11::new()), + Box::new(BitPrefixFlag12::new()), + Box::new(BitPrefixFlag13::new()), + Box::new(BitPrefixFlag14::new()), + Box::new(ZeroFlagConstraint::new()), + Box::new(InstructionUnpacking::new()), + Box::new(CpuOperandsMemDstAddr::new()), + Box::new(CpuOperandsMem0Addr::new()), + Box::new(CpuOperandsMem1Addr::new()), + Box::new(CpuUpdateRegistersApUpdate::new()), + Box::new(CpuUpdateRegistersFpUpdate::new()), + Box::new(CpuUpdateRegistersPcCondPositive::new()), + Box::new(CpuUpdateRegistersPcCondNegative::new()), + Box::new(CpuUpdateRegistersUpdatePcTmp0::new()), + Box::new(CpuUpdateRegistersUpdatePcTmp1::new()), + Box::new(CpuOperandsOpsMul::new()), + Box::new(CpuOperandsRes::new()), + Box::new(CpuOpcodesCallPushFp::new()), + Box::new(CpuOpcodesCallPushPc::new()), + Box::new(CpuOpcodesAssertEq::new()), + Box::new(MemoryDiffIsBit0::new()), + Box::new(MemoryDiffIsBit1::new()), + Box::new(MemoryDiffIsBit2::new()), + Box::new(MemoryDiffIsBit3::new()), + Box::new(MemoryDiffIsBit4::new()), + Box::new(MemoryIsFunc0::new()), + Box::new(MemoryIsFunc1::new()), + Box::new(MemoryIsFunc2::new()), + Box::new(MemoryIsFunc3::new()), + Box::new(MemoryIsFunc4::new()), + Box::new(MemoryMultiColumnPermStep0_0::new()), + Box::new(MemoryMultiColumnPermStep0_1::new()), + Box::new(MemoryMultiColumnPermStep0_2::new()), + Box::new(MemoryMultiColumnPermStep0_3::new()), + Box::new(MemoryMultiColumnPermStep0_4::new()), + Box::new(Rc16DiffIsBit0::new()), + Box::new(Rc16DiffIsBit1::new()), + Box::new(Rc16DiffIsBit2::new()), + Box::new(Rc16DiffIsBit3::new()), + Box::new(Rc16PermStep0_0::new()), + Box::new(Rc16PermStep0_1::new()), + Box::new(Rc16PermStep0_2::new()), + Box::new(Rc16PermStep0_3::new()), + Box::new(FlagOp1BaseOp0BitConstraint::new()), + Box::new(FlagResOp1BitConstraint::new()), + Box::new(FlagPcUpdateRegularBit::new()), + Box::new(FlagFpUpdateRegularBit::new()), + Box::new(CpuOpcodesCallOff0::new()), + Box::new(CpuOpcodesCallOff1::new()), + Box::new(CpuOpcodesCallFlags::new()), + Box::new(CpuOpcodesRetOff0::new()), + Box::new(CpuOpcodesRetOff2::new()), + Box::new(CpuOpcodesRetFlags::new()), ]; - let num_transition_constraints = 64; + + #[cfg(debug_assertions)] + { + use std::collections::HashSet; + let constraints_set: HashSet<_> = transition_constraints + .iter() + .map(|c| c.constraint_idx()) + .collect(); + debug_assert_eq!( + constraints_set.len(), + transition_constraints.len(), + "There are repeated constraint indexes" + ); + (0..transition_constraints.len()) + .for_each(|idx| debug_assert!(constraints_set.iter().contains(&idx))); + + assert_eq!(transition_constraints.len(), 64); + } + + assert_eq!(transition_constraints.len(), 64); + + let transition_exemptions = transition_constraints + .iter() + .map(|c| c.end_exemptions()) + .collect(); let context = AirContext { proof_options: proof_options.clone(), trace_columns, transition_exemptions, transition_offsets: vec![0, 1], - num_transition_constraints, + num_transition_constraints: transition_constraints.len(), }; // The number of the transition constraints @@ -680,13 +667,14 @@ impl AIR for CairoAIR { context, pub_inputs: pub_inputs.clone(), trace_length, + transition_constraints, } } fn build_auxiliary_trace( &self, main_trace: &TraceTable, - rap_challenges: &Self::RAPChallenges, + rap_challenges: &[Felt252], ) -> TraceTable { let addresses_original = main_trace.merge_columns(&[ FRAME_PC, @@ -762,10 +750,13 @@ impl AIR for CairoAIR { aux_data.push(range_check_permutation_col[4 * i + 3]); } - let aux_table = Table::new(aux_data, self.number_auxiliary_rap_columns()); + let aux_table = Table::new(aux_data, self.num_auxiliary_rap_columns()); + let (num_main_columns, num_aux_columns) = self.trace_layout(); TraceTable { table: aux_table, + num_main_columns, + num_aux_columns, step_size: Self::STEP_SIZE, } } @@ -773,38 +764,16 @@ impl AIR for CairoAIR { fn build_rap_challenges( &self, transcript: &mut impl IsStarkTranscript, - ) -> Self::RAPChallenges { - CairoRAPChallenges { - alpha_memory: transcript.sample_field_element(), - z_memory: transcript.sample_field_element(), - z_range_check: transcript.sample_field_element(), - } - } + ) -> Vec { + let alpha_memory = transcript.sample_field_element(); + let z_memory = transcript.sample_field_element(); + let z_rc = transcript.sample_field_element(); - fn number_auxiliary_rap_columns(&self) -> usize { - // RANGE_CHECK_COL_i + MEMORY_INCREASING_i + MEMORY_CONSISTENCY_i + PERMUTATION_ARGUMENT_COL_i + - // + PERMUTATION_ARGUMENT_RANGE_CHECK_COL_i - 23 + vec![alpha_memory, z_memory, z_rc] } - fn compute_transition_prover( - &self, - frame: &Frame, - _periodic_values: &[FieldElement], - rap_challenges: &Self::RAPChallenges, - ) -> Vec> { - let mut constraints: Vec> = - vec![Felt252::zero(); self.num_transition_constraints()]; - - compute_instr_constraints(&mut constraints, frame); - compute_operand_constraints(&mut constraints, frame); - compute_register_constraints(&mut constraints, frame); - compute_opcode_constraints(&mut constraints, frame); - memory_is_increasing(&mut constraints, frame); - permutation_argument(&mut constraints, frame, rap_challenges); - permutation_argument_range_check(&mut constraints, frame, rap_challenges); - - constraints + fn trace_layout(&self) -> (usize, usize) { + (36, 23) } /// From the Cairo whitepaper, section 9.10. @@ -815,10 +784,7 @@ impl AIR for CairoAIR { /// * ap_t = ap_f /// * pc_0 = pc_i /// * pc_t = pc_f - fn boundary_constraints( - &self, - rap_challenges: &Self::RAPChallenges, - ) -> BoundaryConstraints { + fn boundary_constraints(&self, rap_challenges: &[Felt252]) -> BoundaryConstraints { let initial_pc = BoundaryConstraint::new_main(MEM_A_TRACE_OFFSET, 0, self.pub_inputs.pc_init); let initial_ap = @@ -838,21 +804,21 @@ impl AIR for CairoAIR { // Auxiliary constraint: permutation argument final value let final_index = self.trace_length - 1; + let z_memory = rap_challenges[1]; + let alpha_memory = rap_challenges[0]; + let cumulative_product = self .pub_inputs .public_memory .iter() .fold(FieldElement::one(), |product, (address, value)| { - product - * (rap_challenges.z_memory - (address + rap_challenges.alpha_memory * value)) + product * (z_memory - (address + alpha_memory * value)) }) .inv() .unwrap(); - let permutation_final = rap_challenges - .z_memory - .pow(self.pub_inputs.public_memory.len()) - * cumulative_product; + let permutation_final = + z_memory.pow(self.pub_inputs.public_memory.len()) * cumulative_product; let permutation_final_constraint = BoundaryConstraint::new_aux(PERMUTATION_ARGUMENT_COL_4, final_index, permutation_final); @@ -887,6 +853,12 @@ impl AIR for CairoAIR { BoundaryConstraints::from_constraints(constraints) } + fn transition_constraints( + &self, + ) -> &Vec>> { + &self.transition_constraints + } + fn context(&self) -> &AirContext { &self.context } @@ -907,396 +879,12 @@ impl AIR for CairoAIR { &self, frame: &Frame, periodic_values: &[FieldElement], - rap_challenges: &Self::RAPChallenges, + rap_challenges: &[FieldElement], ) -> Vec> { self.compute_transition_prover(frame, periodic_values, rap_challenges) } } -/// From the Cairo whitepaper, section 9.10 -fn compute_instr_constraints( - constraints: &mut [Felt252], - frame: &Frame, -) { - // These constraints are only applied over elements of the same row. - let curr = frame.get_evaluation_step(0); - - // Bit-prefixes constraints. - // See section 9.4 of Cairo whitepaper https://eprint.iacr.org/2021/1063.pdf. - let flags: Vec<&Felt252> = (0..16) - .map(|col_idx| curr.get_main_evaluation_element(0, col_idx)) - .collect(); - - let one = Felt252::one(); - let two = Felt252::from(2); - - let bit_flags: Vec = (0..15) - .map(|idx| flags[idx] - two * flags[idx + 1]) - .collect(); - - (0..15).for_each(|idx| { - constraints[idx] = match idx { - 0..=14 => bit_flags[idx] * (bit_flags[idx] - one), - 15 => *flags[idx], - _ => panic!("Unknown flag offset"), - } - }); - - // flag_op1_base_op0_bit constraint - let f_op1_imm = bit_flags[2]; - let f_op1_fp = bit_flags[3]; - let f_op1_ap = bit_flags[4]; - let f_op1_base_op0_bit = one - f_op1_imm - f_op1_fp - f_op1_ap; - constraints[FLAG_OP1_BASE_OP0_BIT] = f_op1_base_op0_bit * (f_op1_base_op0_bit - one); - - // flag_res_op1_bit constraint - let f_res_add = bit_flags[5]; - let f_res_mul = bit_flags[6]; - let f_pc_jnz = bit_flags[9]; - let f_res_op1_bit = one - f_res_add - f_res_mul - f_pc_jnz; - constraints[FLAG_RES_OP1_BIT] = f_res_op1_bit * (f_res_op1_bit - one); - - // flag_pc_update_regular_bit constraint - let f_jump_abs = bit_flags[7]; - let f_jump_rel = bit_flags[8]; - let flag_pc_update_regular_bit = one - f_jump_abs - f_jump_rel - f_pc_jnz; - constraints[FLAG_PC_UPDATE_REGULAR_BIT] = - flag_pc_update_regular_bit * (flag_pc_update_regular_bit - one); - - // flag_fp_update_regular_bit constraint - let f_opcode_call = bit_flags[12]; - let f_opcode_ret = bit_flags[13]; - let flag_fp_update_regular_bit = one - f_opcode_call - f_opcode_ret; - constraints[FLAG_FP_UPDATE_REGULAR_BIT] = - flag_fp_update_regular_bit * (flag_fp_update_regular_bit - one); - - // Instruction unpacking - let b15 = two.pow(15u32); - let b16 = two.pow(16u32); - let b32 = two.pow(32u32); - let b48 = two.pow(48u32); - - // Named like this to match the Cairo whitepaper's notation. - let f0_squiggle = flags[0]; - - let off_dst = curr.get_main_evaluation_element(0, OFF_DST); - let off_op0 = curr.get_main_evaluation_element(0, OFF_OP0); - let off_op1 = curr.get_main_evaluation_element(0, OFF_OP1); - let instruction = curr.get_main_evaluation_element(0, FRAME_INST); - - constraints[INST] = off_dst + b16 * off_op0 + b32 * off_op1 + b48 * f0_squiggle - instruction; - - // cpu/opcodes/call/off0 constraint - constraints[OPCODES_CALL_OFF0] = f_opcode_call * (off_dst - b15); - // cpu/opcodes/call/off0 constraint - constraints[OPCODES_CALL_OFF1] = f_opcode_call * (off_op0 - b15 - one); - // cpu/opcodes/call/flags constraint - constraints[OPCODES_CALL_FLAGS] = - f_opcode_call * (two * f_opcode_call + one + one - bit_flags[0] - bit_flags[1] - two - two); - - // cpu/opcodes/ret/off0 constraint - constraints[OPCODES_RET_OFF0] = f_opcode_ret * (off_dst + two - b15); - // cpu/opcodes/ret/off2 constraint - constraints[OPCODES_RET_OFF2] = f_opcode_ret * (off_op1 + one - b15); - // cpu/opcodes/ret/flags constraint - constraints[OPCODES_RET_FLAGS] = - f_opcode_ret * (bit_flags[7] + bit_flags[0] + bit_flags[3] + f_res_op1_bit - two - two); -} - -fn compute_operand_constraints( - constraints: &mut [Felt252], - frame: &Frame, -) { - // These constraints are only applied over elements of the same row. - let curr = frame.get_evaluation_step(0); - - let ap = curr.get_main_evaluation_element(0, FRAME_AP); - let fp = curr.get_main_evaluation_element(0, FRAME_FP); - let pc = curr.get_main_evaluation_element(0, FRAME_PC); - - let dst_fp = into_bit_flag(curr, F_DST_FP); - let off_dst = curr.get_main_evaluation_element(0, OFF_DST); - let dst_addr = curr.get_main_evaluation_element(0, FRAME_DST_ADDR); - - let op0_fp = into_bit_flag(curr, F_OP_0_FP); - let off_op0 = curr.get_main_evaluation_element(0, OFF_OP0); - let op0_addr = curr.get_main_evaluation_element(0, FRAME_OP0_ADDR); - - let op1_val = into_bit_flag(curr, F_OP_1_VAL); - let op1_ap = into_bit_flag(curr, F_OP_1_AP); - let op1_fp = into_bit_flag(curr, F_OP_1_FP); - let op0 = curr.get_main_evaluation_element(0, FRAME_OP0); - let off_op1 = curr.get_main_evaluation_element(0, OFF_OP1); - let op1_addr = curr.get_main_evaluation_element(0, FRAME_OP1_ADDR); - - let one = Felt252::one(); - let b15 = Felt252::from(2).pow(15u32); - - constraints[DST_ADDR] = dst_fp * fp + (one - dst_fp) * ap + (off_dst - b15) - dst_addr; - - constraints[OP0_ADDR] = op0_fp * fp + (one - op0_fp) * ap + (off_op0 - b15) - op0_addr; - - constraints[OP1_ADDR] = op1_val * pc - + op1_ap * ap - + op1_fp * fp - + (one - op1_val - op1_ap - op1_fp) * op0 - + (off_op1 - b15) - - op1_addr; -} - -/// Given a step and the index of the bit-prefix format flag, gives the bit representation -/// of that flag, needed for the evaluation of some constraints. -#[inline(always)] -fn into_bit_flag( - step: &StepView, - element_idx: usize, -) -> Felt252 { - step.get_main_evaluation_element(0, element_idx) - - Felt252::from(2) * step.get_main_evaluation_element(0, element_idx + 1) -} - -fn compute_register_constraints( - constraints: &mut [Felt252], - frame: &Frame, -) { - let curr = frame.get_evaluation_step(0); - let next = frame.get_evaluation_step(1); - - let one = Felt252::one(); - let two = Felt252::from(2); - - let ap = curr.get_main_evaluation_element(0, FRAME_AP); - let next_ap = next.get_main_evaluation_element(0, FRAME_AP); - let ap_add = into_bit_flag(curr, F_AP_ADD); - let res = curr.get_main_evaluation_element(0, FRAME_RES); - let ap_one = into_bit_flag(curr, F_AP_ONE); - - let opc_ret = into_bit_flag(curr, F_OPC_RET); - let opc_call = into_bit_flag(curr, F_OPC_CALL); - let dst = curr.get_main_evaluation_element(0, FRAME_DST); - let fp = curr.get_main_evaluation_element(0, FRAME_FP); - let next_fp = next.get_main_evaluation_element(0, FRAME_FP); - - let t1 = curr.get_main_evaluation_element(0, FRAME_T1); - let pc_jnz = into_bit_flag(curr, F_PC_JNZ); - let pc = curr.get_main_evaluation_element(0, FRAME_PC); - let next_pc = next.get_main_evaluation_element(0, FRAME_PC); - - let t0 = curr.get_main_evaluation_element(0, FRAME_T0); - let op1 = curr.get_main_evaluation_element(0, FRAME_OP1); - let pc_abs = into_bit_flag(curr, F_PC_ABS); - let pc_rel = into_bit_flag(curr, F_PC_REL); - - // ap and fp constraints - constraints[NEXT_AP] = ap + ap_add * res + ap_one + opc_call * two - next_ap; - - constraints[NEXT_FP] = - opc_ret * dst + opc_call * (ap + two) + (one - opc_ret - opc_call) * fp - next_fp; - - // pc constraints - constraints[NEXT_PC_1] = (t1 - pc_jnz) * (next_pc - (pc + frame_inst_size(curr))); - - constraints[NEXT_PC_2] = t0 * (next_pc - (pc + op1)) + (one - pc_jnz) * next_pc - - ((one - pc_abs - pc_rel - pc_jnz) * (pc + frame_inst_size(curr)) - + pc_abs * res - + pc_rel * (pc + res)); - - constraints[T0] = pc_jnz * dst - t0; - constraints[T1] = t0 * res - t1; -} - -fn compute_opcode_constraints( - constraints: &mut [Felt252], - frame: &Frame, -) { - let curr = frame.get_evaluation_step(0); - let one = Felt252::one(); - - let mul = curr.get_main_evaluation_element(0, FRAME_MUL); - let op0 = curr.get_main_evaluation_element(0, FRAME_OP0); - let op1 = curr.get_main_evaluation_element(0, FRAME_OP1); - - let res_add = into_bit_flag(curr, F_RES_ADD); - let res_mul = into_bit_flag(curr, F_RES_MUL); - let pc_jnz = into_bit_flag(curr, F_PC_JNZ); - let res = curr.get_main_evaluation_element(0, FRAME_RES); - - let opc_call = into_bit_flag(curr, F_OPC_CALL); - let dst = curr.get_main_evaluation_element(0, FRAME_DST); - let fp = curr.get_main_evaluation_element(0, FRAME_FP); - let pc = curr.get_main_evaluation_element(0, FRAME_PC); - - let opc_aeq = into_bit_flag(curr, F_OPC_AEQ); - - constraints[MUL_1] = mul - op0 * op1; - - constraints[MUL_2] = - res_add * (op0 + op1) + res_mul * mul + (one - res_add - res_mul - pc_jnz) * op1 - - (one - pc_jnz) * res; - - constraints[CALL_1] = opc_call * (dst - fp); - - constraints[CALL_2] = opc_call * (op0 - (pc + frame_inst_size(curr))); - - constraints[ASSERT_EQ] = opc_aeq * (dst - res); -} - -fn memory_is_increasing( - constraints: &mut [Felt252], - frame: &Frame, -) { - let curr = frame.get_evaluation_step(0); - let next = frame.get_evaluation_step(1); - let one = FieldElement::one(); - - let mem_addr_sorted_0 = curr.get_aux_evaluation_element(0, MEMORY_ADDR_SORTED_0); - let mem_addr_sorted_1 = curr.get_aux_evaluation_element(0, MEMORY_ADDR_SORTED_1); - let mem_addr_sorted_2 = curr.get_aux_evaluation_element(0, MEMORY_ADDR_SORTED_2); - let mem_addr_sorted_3 = curr.get_aux_evaluation_element(0, MEMORY_ADDR_SORTED_3); - let mem_addr_sorted_4 = curr.get_aux_evaluation_element(0, MEMORY_ADDR_SORTED_4); - let next_mem_addr_sorted_0 = next.get_aux_evaluation_element(0, MEMORY_ADDR_SORTED_0); - - let mem_val_sorted_0 = curr.get_aux_evaluation_element(0, MEMORY_VALUES_SORTED_0); - let mem_val_sorted_1 = curr.get_aux_evaluation_element(0, MEMORY_VALUES_SORTED_1); - let mem_val_sorted_2 = curr.get_aux_evaluation_element(0, MEMORY_VALUES_SORTED_2); - let mem_val_sorted_3 = curr.get_aux_evaluation_element(0, MEMORY_VALUES_SORTED_3); - let mem_val_sorted_4 = curr.get_aux_evaluation_element(0, MEMORY_VALUES_SORTED_4); - let next_mem_val_sorted_0 = next.get_aux_evaluation_element(0, MEMORY_VALUES_SORTED_0); - - constraints[MEMORY_INCREASING_0] = - (mem_addr_sorted_0 - mem_addr_sorted_1) * (mem_addr_sorted_1 - mem_addr_sorted_0 - one); - - constraints[MEMORY_INCREASING_1] = - (mem_addr_sorted_1 - mem_addr_sorted_2) * (mem_addr_sorted_2 - mem_addr_sorted_1 - one); - - constraints[MEMORY_INCREASING_2] = - (mem_addr_sorted_2 - mem_addr_sorted_3) * (mem_addr_sorted_3 - mem_addr_sorted_2 - one); - - constraints[MEMORY_INCREASING_3] = - (mem_addr_sorted_3 - mem_addr_sorted_4) * (mem_addr_sorted_4 - mem_addr_sorted_3 - one); - - constraints[MEMORY_INCREASING_4] = (mem_addr_sorted_4 - next_mem_addr_sorted_0) - * (next_mem_addr_sorted_0 - mem_addr_sorted_4 - one); - - constraints[MEMORY_CONSISTENCY_0] = - (mem_val_sorted_0 - mem_val_sorted_1) * (mem_addr_sorted_1 - mem_addr_sorted_0 - one); - - constraints[MEMORY_CONSISTENCY_1] = - (mem_val_sorted_1 - mem_val_sorted_2) * (mem_addr_sorted_2 - mem_addr_sorted_1 - one); - - constraints[MEMORY_CONSISTENCY_2] = - (mem_val_sorted_2 - mem_val_sorted_3) * (mem_addr_sorted_3 - mem_addr_sorted_2 - one); - - constraints[MEMORY_CONSISTENCY_3] = - (mem_val_sorted_3 - mem_val_sorted_4) * (mem_addr_sorted_4 - mem_addr_sorted_3 - one); - - constraints[MEMORY_CONSISTENCY_4] = (mem_val_sorted_4 - next_mem_val_sorted_0) - * (next_mem_addr_sorted_0 - mem_addr_sorted_4 - one); -} - -fn permutation_argument( - constraints: &mut [Felt252], - frame: &Frame, - rap_challenges: &CairoRAPChallenges, -) { - let curr = frame.get_evaluation_step(0); - let next = frame.get_evaluation_step(1); - - let z = &rap_challenges.z_memory; - let alpha = &rap_challenges.alpha_memory; - - let p0 = curr.get_aux_evaluation_element(0, PERMUTATION_ARGUMENT_COL_0); - let next_p0 = next.get_aux_evaluation_element(0, PERMUTATION_ARGUMENT_COL_0); - let p1 = curr.get_aux_evaluation_element(0, PERMUTATION_ARGUMENT_COL_1); - let p2 = curr.get_aux_evaluation_element(0, PERMUTATION_ARGUMENT_COL_2); - let p3 = curr.get_aux_evaluation_element(0, PERMUTATION_ARGUMENT_COL_3); - let p4 = curr.get_aux_evaluation_element(0, PERMUTATION_ARGUMENT_COL_4); - - let next_ap0 = next.get_aux_evaluation_element(0, MEMORY_ADDR_SORTED_0); - let ap1 = curr.get_aux_evaluation_element(0, MEMORY_ADDR_SORTED_1); - let ap2 = curr.get_aux_evaluation_element(0, MEMORY_ADDR_SORTED_2); - let ap3 = curr.get_aux_evaluation_element(0, MEMORY_ADDR_SORTED_3); - let ap4 = curr.get_aux_evaluation_element(0, MEMORY_ADDR_SORTED_4); - - let next_vp0 = next.get_aux_evaluation_element(0, MEMORY_VALUES_SORTED_0); - let vp1 = curr.get_aux_evaluation_element(0, MEMORY_VALUES_SORTED_1); - let vp2 = curr.get_aux_evaluation_element(0, MEMORY_VALUES_SORTED_2); - let vp3 = curr.get_aux_evaluation_element(0, MEMORY_VALUES_SORTED_3); - let vp4 = curr.get_aux_evaluation_element(0, MEMORY_VALUES_SORTED_4); - - let next_a0 = next.get_main_evaluation_element(0, FRAME_PC); - let a1 = curr.get_main_evaluation_element(0, FRAME_DST_ADDR); - let a2 = curr.get_main_evaluation_element(0, FRAME_OP0_ADDR); - let a3 = curr.get_main_evaluation_element(0, FRAME_OP1_ADDR); - let a4 = curr.get_main_evaluation_element(0, EXTRA_ADDR); - - let next_v0 = next.get_main_evaluation_element(0, FRAME_INST); - let v1 = curr.get_main_evaluation_element(0, FRAME_DST); - let v2 = curr.get_main_evaluation_element(0, FRAME_OP0); - let v3 = curr.get_main_evaluation_element(0, FRAME_OP1); - let v4 = curr.get_main_evaluation_element(0, EXTRA_VAL); - - constraints[PERMUTATION_ARGUMENT_0] = - (z - (ap1 + alpha * vp1)) * p1 - (z - (a1 + alpha * v1)) * p0; - constraints[PERMUTATION_ARGUMENT_1] = - (z - (ap2 + alpha * vp2)) * p2 - (z - (a2 + alpha * v2)) * p1; - constraints[PERMUTATION_ARGUMENT_2] = - (z - (ap3 + alpha * vp3)) * p3 - (z - (a3 + alpha * v3)) * p2; - constraints[PERMUTATION_ARGUMENT_3] = - (z - (ap4 + alpha * vp4)) * p4 - (z - (a4 + alpha * v4)) * p3; - constraints[PERMUTATION_ARGUMENT_4] = - (z - (next_ap0 + alpha * next_vp0)) * next_p0 - (z - (next_a0 + alpha * next_v0)) * p4; -} - -fn permutation_argument_range_check( - constraints: &mut [Felt252], - frame: &Frame, - rap_challenges: &CairoRAPChallenges, -) { - let curr = frame.get_evaluation_step(0); - let next = frame.get_evaluation_step(1); - let one = FieldElement::one(); - let z = &rap_challenges.z_range_check; - - let rc_col_1 = curr.get_aux_evaluation_element(0, RANGE_CHECK_COL_1); - let rc_col_2 = curr.get_aux_evaluation_element(0, RANGE_CHECK_COL_2); - let rc_col_3 = curr.get_aux_evaluation_element(0, RANGE_CHECK_COL_3); - let rc_col_4 = curr.get_aux_evaluation_element(0, RANGE_CHECK_COL_4); - let next_rc_col_1 = next.get_aux_evaluation_element(0, RANGE_CHECK_COL_1); - - constraints[RANGE_CHECK_INCREASING_0] = (rc_col_1 - rc_col_2) * (rc_col_2 - rc_col_1 - one); - constraints[RANGE_CHECK_INCREASING_1] = (rc_col_2 - rc_col_3) * (rc_col_3 - rc_col_2 - one); - constraints[RANGE_CHECK_INCREASING_2] = (rc_col_3 - rc_col_4) * (rc_col_4 - rc_col_3 - one); - constraints[RANGE_CHECK_INCREASING_3] = - (rc_col_4 - next_rc_col_1) * (next_rc_col_1 - rc_col_4 - one); - - let p0 = curr.get_aux_evaluation_element(0, PERMUTATION_ARGUMENT_RANGE_CHECK_COL_1); - let next_p0 = next.get_aux_evaluation_element(0, PERMUTATION_ARGUMENT_RANGE_CHECK_COL_1); - let p1 = curr.get_aux_evaluation_element(0, PERMUTATION_ARGUMENT_RANGE_CHECK_COL_2); - let p2 = curr.get_aux_evaluation_element(0, PERMUTATION_ARGUMENT_RANGE_CHECK_COL_3); - let p3 = curr.get_aux_evaluation_element(0, PERMUTATION_ARGUMENT_RANGE_CHECK_COL_4); - - let next_ap0 = next.get_aux_evaluation_element(0, RANGE_CHECK_COL_1); - let ap1 = curr.get_aux_evaluation_element(0, RANGE_CHECK_COL_2); - let ap2 = curr.get_aux_evaluation_element(0, RANGE_CHECK_COL_3); - let ap3 = curr.get_aux_evaluation_element(0, RANGE_CHECK_COL_4); - - let a0_next = next.get_main_evaluation_element(0, OFF_DST); - let a1 = curr.get_main_evaluation_element(0, OFF_OP0); - let a2 = curr.get_main_evaluation_element(0, OFF_OP1); - let a3 = curr.get_main_evaluation_element(0, RC_HOLES); - - constraints[RANGE_CHECK_0] = (z - ap1) * p1 - (z - a1) * p0; - constraints[RANGE_CHECK_1] = (z - ap2) * p2 - (z - a2) * p1; - constraints[RANGE_CHECK_2] = (z - ap3) * p3 - (z - a3) * p2; - constraints[RANGE_CHECK_3] = (z - next_ap0) * next_p0 - (z - a0_next) * p3; -} - -fn frame_inst_size(step: &StepView) -> Felt252 { - let op1_val = into_bit_flag(step, F_OP_1_VAL); - op1_val + Felt252::one() -} - /// Wrapper function for generating Cairo proofs without the need to specify /// concrete types. /// The field is set to Stark252PrimeField and the AIR to CairoAIR. @@ -1392,11 +980,12 @@ mod test { FieldElement::from(2), FieldElement::from(5), ]; - let rap_challenges = CairoRAPChallenges { - alpha_memory: FieldElement::from(15), - z_memory: FieldElement::from(10), - z_range_check: FieldElement::zero(), - }; + let rap_challenges = vec![ + FieldElement::from(15), + FieldElement::from(10), + FieldElement::zero(), + ]; + let p = generate_memory_permutation_argument_column(a, v, &ap, &vp, &rap_challenges); assert_eq!( p, diff --git a/provers/cairo/src/execution_trace.rs b/provers/cairo/src/execution_trace.rs index 075aa86d7..eece1d28d 100644 --- a/provers/cairo/src/execution_trace.rs +++ b/provers/cairo/src/execution_trace.rs @@ -301,7 +301,7 @@ pub fn build_cairo_execution_trace( trace_cols.push(extra_vals); trace_cols.push(rc_holes); - TraceTable::from_columns(trace_cols, 1) + TraceTable::from_columns_main(trace_cols, 1) } /// Returns the vector of res values. @@ -523,7 +523,7 @@ fn update_values( } /// Utility function to change from a rows representation to a columns -/// representation of a slice of arrays. +/// representation of a slice of arrays. fn rows_to_cols(rows: &[[Felt252; N]]) -> Vec> { let n_cols = rows[0].len(); @@ -608,7 +608,7 @@ mod test { FieldElement::from(7), FieldElement::from(7), ]; - let table = TraceTable::::from_columns(columns, 1); + let table = TraceTable::::from_columns(columns, 3, 1); let (col, rc_min, rc_max) = get_rc_holes(&table, &[0, 1, 2]); assert_eq!(col, expected_col); @@ -625,6 +625,8 @@ mod test { let mut main_trace = TraceTable:: { table, + num_main_columns: 36, + num_aux_columns: 23, step_size: 1, }; @@ -737,12 +739,12 @@ mod test { trace_cols[FRAME_DST_ADDR][1] = Felt252::from(9); trace_cols[FRAME_OP0_ADDR][1] = Felt252::from(10); trace_cols[FRAME_OP1_ADDR][1] = Felt252::from(11); - let mut trace = TraceTable::from_columns(trace_cols, 1); + let mut trace = TraceTable::from_columns(trace_cols, 2, 1); let memory_holes = vec![Felt252::from(4), Felt252::from(7), Felt252::from(8)]; fill_memory_holes(&mut trace, &memory_holes); let extra_addr = &trace.columns()[EXTRA_ADDR]; - assert_eq!(extra_addr, &memory_holes) + assert_eq!(extra_addr, &memory_holes); } } diff --git a/provers/cairo/src/lib.rs b/provers/cairo/src/lib.rs index 117f74f8e..54384a63c 100644 --- a/provers/cairo/src/lib.rs +++ b/provers/cairo/src/lib.rs @@ -10,6 +10,7 @@ pub mod errors; pub mod execution_trace; pub mod register_states; pub mod runner; +pub mod transition_constraints; #[cfg(test)] pub mod tests; diff --git a/provers/cairo/src/main.rs b/provers/cairo/src/main.rs index 4ee33f362..d797e7ee3 100644 --- a/provers/cairo/src/main.rs +++ b/provers/cairo/src/main.rs @@ -230,7 +230,6 @@ fn write_proof( fn main() { let proof_options = ProofOptions::new_secure(SecurityLevel::Conjecturable100Bits, 3); - let args: commands::ProverArgs = commands::ProverArgs::parse(); match args.entity { commands::ProverEntity::Compile(args) => { diff --git a/provers/cairo/src/transition_constraints.rs b/provers/cairo/src/transition_constraints.rs new file mode 100644 index 000000000..c5a761622 --- /dev/null +++ b/provers/cairo/src/transition_constraints.rs @@ -0,0 +1,3219 @@ +use crate::Felt252; +use lambdaworks_math::field::fields::fft_friendly::stark_252_prime_field::Stark252PrimeField; +use stark_platinum_prover::{ + constraints::transition::TransitionConstraint, frame::Frame, table::TableView, +}; + +#[derive(Clone)] +pub struct BitPrefixFlag0; +impl BitPrefixFlag0 { + pub fn new() -> Self { + Self + } +} +impl Default for BitPrefixFlag0 { + fn default() -> Self { + Self::new() + } +} + +impl TransitionConstraint for BitPrefixFlag0 { + fn degree(&self) -> usize { + 2 + } + + fn constraint_idx(&self) -> usize { + 0 + } + + fn evaluate( + &self, + frame: &stark_platinum_prover::frame::Frame, + transition_evaluations: &mut [Felt252], + _periodic_values: &[Felt252], + _rap_challenges: &[Felt252], + ) { + let current_step = frame.get_evaluation_step(0); + + let constraint_idx = self.constraint_idx(); + + let current_flag = current_step.get_main_evaluation_element(0, constraint_idx); + let next_flag = current_step.get_main_evaluation_element(0, constraint_idx + 1); + + let one = Felt252::one(); + let two = Felt252::from(2); + + let bit = current_flag - two * next_flag; + + let res = bit * (bit - one); + + transition_evaluations[constraint_idx] = res; + } + + fn end_exemptions(&self) -> usize { + 0 + } +} + +#[derive(Clone)] +pub struct BitPrefixFlag1; +impl BitPrefixFlag1 { + pub fn new() -> Self { + Self + } +} +impl Default for BitPrefixFlag1 { + fn default() -> Self { + Self::new() + } +} + +impl TransitionConstraint for BitPrefixFlag1 { + fn degree(&self) -> usize { + 2 + } + + fn constraint_idx(&self) -> usize { + 1 + } + + fn evaluate( + &self, + frame: &stark_platinum_prover::frame::Frame, + transition_evaluations: &mut [Felt252], + _periodic_values: &[Felt252], + _rap_challenges: &[Felt252], + ) { + let current_step = frame.get_evaluation_step(0); + + let constraint_idx = self.constraint_idx(); + + let current_flag = current_step.get_main_evaluation_element(0, constraint_idx); + let next_flag = current_step.get_main_evaluation_element(0, constraint_idx + 1); + + let one = Felt252::one(); + let two = Felt252::from(2); + + let bit = current_flag - two * next_flag; + + let res = bit * (bit - one); + + transition_evaluations[constraint_idx] = res; + } + + fn end_exemptions(&self) -> usize { + 0 + } +} + +#[derive(Clone)] +pub struct BitPrefixFlag2; +impl BitPrefixFlag2 { + pub fn new() -> Self { + Self + } +} +impl Default for BitPrefixFlag2 { + fn default() -> Self { + Self::new() + } +} + +impl TransitionConstraint for BitPrefixFlag2 { + fn degree(&self) -> usize { + 2 + } + + fn constraint_idx(&self) -> usize { + 2 + } + + fn evaluate( + &self, + frame: &stark_platinum_prover::frame::Frame, + transition_evaluations: &mut [Felt252], + _periodic_values: &[Felt252], + _rap_challenges: &[Felt252], + ) { + let current_step = frame.get_evaluation_step(0); + + let constraint_idx = self.constraint_idx(); + + let current_flag = current_step.get_main_evaluation_element(0, constraint_idx); + let next_flag = current_step.get_main_evaluation_element(0, constraint_idx + 1); + + let one = Felt252::one(); + let two = Felt252::from(2); + + let bit = current_flag - two * next_flag; + + let res = bit * (bit - one); + + transition_evaluations[constraint_idx] = res; + } + + fn end_exemptions(&self) -> usize { + 0 + } +} + +#[derive(Clone)] +pub struct BitPrefixFlag3; +impl BitPrefixFlag3 { + pub fn new() -> Self { + Self + } +} +impl Default for BitPrefixFlag3 { + fn default() -> Self { + Self::new() + } +} + +impl TransitionConstraint for BitPrefixFlag3 { + fn degree(&self) -> usize { + 2 + } + + fn constraint_idx(&self) -> usize { + 3 + } + + fn evaluate( + &self, + frame: &stark_platinum_prover::frame::Frame, + transition_evaluations: &mut [Felt252], + _periodic_values: &[Felt252], + _rap_challenges: &[Felt252], + ) { + let current_step = frame.get_evaluation_step(0); + + let constraint_idx = self.constraint_idx(); + + let current_flag = current_step.get_main_evaluation_element(0, constraint_idx); + let next_flag = current_step.get_main_evaluation_element(0, constraint_idx + 1); + + let one = Felt252::one(); + let two = Felt252::from(2); + + let bit = current_flag - two * next_flag; + + let res = bit * (bit - one); + + transition_evaluations[constraint_idx] = res; + } + + fn end_exemptions(&self) -> usize { + 0 + } +} + +#[derive(Clone)] +pub struct BitPrefixFlag4; +impl BitPrefixFlag4 { + pub fn new() -> Self { + Self + } +} +impl Default for BitPrefixFlag4 { + fn default() -> Self { + Self::new() + } +} + +impl TransitionConstraint for BitPrefixFlag4 { + fn degree(&self) -> usize { + 2 + } + + fn constraint_idx(&self) -> usize { + 4 + } + + fn evaluate( + &self, + frame: &stark_platinum_prover::frame::Frame, + transition_evaluations: &mut [Felt252], + _periodic_values: &[Felt252], + _rap_challenges: &[Felt252], + ) { + let current_step = frame.get_evaluation_step(0); + + let constraint_idx = self.constraint_idx(); + + let current_flag = current_step.get_main_evaluation_element(0, constraint_idx); + let next_flag = current_step.get_main_evaluation_element(0, constraint_idx + 1); + + let one = Felt252::one(); + let two = Felt252::from(2); + + let bit = current_flag - two * next_flag; + + let res = bit * (bit - one); + + transition_evaluations[constraint_idx] = res; + } + + fn end_exemptions(&self) -> usize { + 0 + } +} + +#[derive(Clone)] +pub struct BitPrefixFlag5; +impl BitPrefixFlag5 { + pub fn new() -> Self { + Self + } +} +impl Default for BitPrefixFlag5 { + fn default() -> Self { + Self::new() + } +} + +impl TransitionConstraint for BitPrefixFlag5 { + fn degree(&self) -> usize { + 2 + } + + fn constraint_idx(&self) -> usize { + 5 + } + + fn evaluate( + &self, + frame: &stark_platinum_prover::frame::Frame, + transition_evaluations: &mut [Felt252], + _periodic_values: &[Felt252], + _rap_challenges: &[Felt252], + ) { + let current_step = frame.get_evaluation_step(0); + + let constraint_idx = self.constraint_idx(); + + let current_flag = current_step.get_main_evaluation_element(0, constraint_idx); + let next_flag = current_step.get_main_evaluation_element(0, constraint_idx + 1); + + let one = Felt252::one(); + let two = Felt252::from(2); + + let bit = current_flag - two * next_flag; + + let res = bit * (bit - one); + + transition_evaluations[constraint_idx] = res; + } + + fn end_exemptions(&self) -> usize { + 0 + } +} + +#[derive(Clone)] +pub struct BitPrefixFlag6; +impl BitPrefixFlag6 { + pub fn new() -> Self { + Self + } +} +impl Default for BitPrefixFlag6 { + fn default() -> Self { + Self::new() + } +} + +impl TransitionConstraint for BitPrefixFlag6 { + fn degree(&self) -> usize { + 2 + } + + fn constraint_idx(&self) -> usize { + 6 + } + + fn evaluate( + &self, + frame: &stark_platinum_prover::frame::Frame, + transition_evaluations: &mut [Felt252], + _periodic_values: &[Felt252], + _rap_challenges: &[Felt252], + ) { + let current_step = frame.get_evaluation_step(0); + + let constraint_idx = self.constraint_idx(); + + let current_flag = current_step.get_main_evaluation_element(0, constraint_idx); + let next_flag = current_step.get_main_evaluation_element(0, constraint_idx + 1); + + let one = Felt252::one(); + let two = Felt252::from(2); + + let bit = current_flag - two * next_flag; + + let res = bit * (bit - one); + + transition_evaluations[constraint_idx] = res; + } + + fn end_exemptions(&self) -> usize { + 0 + } +} + +#[derive(Clone)] +pub struct BitPrefixFlag7; +impl Default for BitPrefixFlag7 { + fn default() -> Self { + Self::new() + } +} + +impl BitPrefixFlag7 { + pub fn new() -> Self { + Self + } +} + +impl TransitionConstraint for BitPrefixFlag7 { + fn degree(&self) -> usize { + 2 + } + + fn constraint_idx(&self) -> usize { + 7 + } + + fn evaluate( + &self, + frame: &stark_platinum_prover::frame::Frame, + transition_evaluations: &mut [Felt252], + _periodic_values: &[Felt252], + _rap_challenges: &[Felt252], + ) { + let current_step = frame.get_evaluation_step(0); + + let constraint_idx = self.constraint_idx(); + + let current_flag = current_step.get_main_evaluation_element(0, constraint_idx); + let next_flag = current_step.get_main_evaluation_element(0, constraint_idx + 1); + + let one = Felt252::one(); + let two = Felt252::from(2); + + let bit = current_flag - two * next_flag; + + let res = bit * (bit - one); + + transition_evaluations[constraint_idx] = res; + } + + fn end_exemptions(&self) -> usize { + 0 + } +} + +#[derive(Clone)] +pub struct BitPrefixFlag8; +impl Default for BitPrefixFlag8 { + fn default() -> Self { + Self::new() + } +} + +impl BitPrefixFlag8 { + pub fn new() -> Self { + Self + } +} + +impl TransitionConstraint for BitPrefixFlag8 { + fn degree(&self) -> usize { + 2 + } + + fn constraint_idx(&self) -> usize { + 8 + } + + fn evaluate( + &self, + frame: &stark_platinum_prover::frame::Frame, + transition_evaluations: &mut [Felt252], + _periodic_values: &[Felt252], + _rap_challenges: &[Felt252], + ) { + let current_step = frame.get_evaluation_step(0); + + let constraint_idx = self.constraint_idx(); + + let current_flag = current_step.get_main_evaluation_element(0, constraint_idx); + let next_flag = current_step.get_main_evaluation_element(0, constraint_idx + 1); + + let one = Felt252::one(); + let two = Felt252::from(2); + + let bit = current_flag - two * next_flag; + + let res = bit * (bit - one); + + transition_evaluations[constraint_idx] = res; + } + + fn end_exemptions(&self) -> usize { + 0 + } +} + +#[derive(Clone)] +pub struct BitPrefixFlag9; +impl Default for BitPrefixFlag9 { + fn default() -> Self { + Self::new() + } +} + +impl BitPrefixFlag9 { + pub fn new() -> Self { + Self + } +} + +impl TransitionConstraint for BitPrefixFlag9 { + fn degree(&self) -> usize { + 2 + } + + fn constraint_idx(&self) -> usize { + 9 + } + + fn evaluate( + &self, + frame: &stark_platinum_prover::frame::Frame, + transition_evaluations: &mut [Felt252], + _periodic_values: &[Felt252], + _rap_challenges: &[Felt252], + ) { + let current_step = frame.get_evaluation_step(0); + + let constraint_idx = self.constraint_idx(); + + let current_flag = current_step.get_main_evaluation_element(0, constraint_idx); + let next_flag = current_step.get_main_evaluation_element(0, constraint_idx + 1); + + let one = Felt252::one(); + let two = Felt252::from(2); + + let bit = current_flag - two * next_flag; + + let res = bit * (bit - one); + + transition_evaluations[constraint_idx] = res; + } + + fn end_exemptions(&self) -> usize { + 0 + } +} + +#[derive(Clone)] +pub struct BitPrefixFlag10; +impl Default for BitPrefixFlag10 { + fn default() -> Self { + Self::new() + } +} + +impl BitPrefixFlag10 { + pub fn new() -> Self { + Self + } +} + +impl TransitionConstraint for BitPrefixFlag10 { + fn degree(&self) -> usize { + 2 + } + + fn constraint_idx(&self) -> usize { + 10 + } + + fn evaluate( + &self, + frame: &stark_platinum_prover::frame::Frame, + transition_evaluations: &mut [Felt252], + _periodic_values: &[Felt252], + _rap_challenges: &[Felt252], + ) { + let current_step = frame.get_evaluation_step(0); + + let constraint_idx = self.constraint_idx(); + + let current_flag = current_step.get_main_evaluation_element(0, constraint_idx); + let next_flag = current_step.get_main_evaluation_element(0, constraint_idx + 1); + + let one = Felt252::one(); + let two = Felt252::from(2); + + let bit = current_flag - two * next_flag; + + let res = bit * (bit - one); + + transition_evaluations[constraint_idx] = res; + } + + fn end_exemptions(&self) -> usize { + 0 + } +} + +pub struct BitPrefixFlag11; +impl Default for BitPrefixFlag11 { + fn default() -> Self { + Self::new() + } +} + +impl BitPrefixFlag11 { + pub fn new() -> Self { + Self + } +} + +impl TransitionConstraint for BitPrefixFlag11 { + fn degree(&self) -> usize { + 2 + } + + fn constraint_idx(&self) -> usize { + 11 + } + + fn evaluate( + &self, + frame: &stark_platinum_prover::frame::Frame, + transition_evaluations: &mut [Felt252], + _periodic_values: &[Felt252], + _rap_challenges: &[Felt252], + ) { + let current_step = frame.get_evaluation_step(0); + + let constraint_idx = self.constraint_idx(); + + let current_flag = current_step.get_main_evaluation_element(0, constraint_idx); + let next_flag = current_step.get_main_evaluation_element(0, constraint_idx + 1); + + let one = Felt252::one(); + let two = Felt252::from(2); + + let bit = current_flag - two * next_flag; + + let res = bit * (bit - one); + + transition_evaluations[constraint_idx] = res; + } + + fn end_exemptions(&self) -> usize { + 0 + } +} + +pub struct BitPrefixFlag12; +impl Default for BitPrefixFlag12 { + fn default() -> Self { + Self::new() + } +} + +impl BitPrefixFlag12 { + pub fn new() -> Self { + Self + } +} + +impl TransitionConstraint for BitPrefixFlag12 { + fn degree(&self) -> usize { + 2 + } + + fn constraint_idx(&self) -> usize { + 12 + } + + fn evaluate( + &self, + frame: &stark_platinum_prover::frame::Frame, + transition_evaluations: &mut [Felt252], + _periodic_values: &[Felt252], + _rap_challenges: &[Felt252], + ) { + let current_step = frame.get_evaluation_step(0); + + let constraint_idx = self.constraint_idx(); + + let current_flag = current_step.get_main_evaluation_element(0, constraint_idx); + let next_flag = current_step.get_main_evaluation_element(0, constraint_idx + 1); + + let one = Felt252::one(); + let two = Felt252::from(2); + + let bit = current_flag - two * next_flag; + + let res = bit * (bit - one); + + transition_evaluations[constraint_idx] = res; + } + + fn end_exemptions(&self) -> usize { + 0 + } +} + +pub struct BitPrefixFlag13; +impl Default for BitPrefixFlag13 { + fn default() -> Self { + Self::new() + } +} + +impl BitPrefixFlag13 { + pub fn new() -> Self { + Self + } +} + +impl TransitionConstraint for BitPrefixFlag13 { + fn degree(&self) -> usize { + 2 + } + + fn constraint_idx(&self) -> usize { + 13 + } + + fn evaluate( + &self, + frame: &Frame, + transition_evaluations: &mut [Felt252], + _periodic_values: &[Felt252], + _rap_challenges: &[Felt252], + ) { + let current_step = frame.get_evaluation_step(0); + + let constraint_idx = self.constraint_idx(); + + let current_flag = current_step.get_main_evaluation_element(0, constraint_idx); + let next_flag = current_step.get_main_evaluation_element(0, constraint_idx + 1); + + let one = Felt252::one(); + let two = Felt252::from(2); + + let bit = current_flag - two * next_flag; + + let res = bit * (bit - one); + + transition_evaluations[constraint_idx] = res; + } + + fn end_exemptions(&self) -> usize { + 0 + } +} + +pub struct BitPrefixFlag14; +impl Default for BitPrefixFlag14 { + fn default() -> Self { + Self::new() + } +} + +impl BitPrefixFlag14 { + pub fn new() -> Self { + Self + } +} + +impl TransitionConstraint for BitPrefixFlag14 { + fn degree(&self) -> usize { + 2 + } + + fn constraint_idx(&self) -> usize { + 14 + } + + fn evaluate( + &self, + frame: &stark_platinum_prover::frame::Frame, + transition_evaluations: &mut [Felt252], + _periodic_values: &[Felt252], + _rap_challenges: &[Felt252], + ) { + let current_step = frame.get_evaluation_step(0); + + let constraint_idx = self.constraint_idx(); + + let current_flag = current_step.get_main_evaluation_element(0, constraint_idx); + let next_flag = current_step.get_main_evaluation_element(0, constraint_idx + 1); + + let one = Felt252::one(); + let two = Felt252::from(2); + + let bit = current_flag - two * next_flag; + + let res = bit * (bit - one); + + transition_evaluations[constraint_idx] = res; + } + + fn end_exemptions(&self) -> usize { + 0 + } +} + +pub struct ZeroFlagConstraint; +impl Default for ZeroFlagConstraint { + fn default() -> Self { + Self::new() + } +} + +impl ZeroFlagConstraint { + pub fn new() -> Self { + Self + } +} + +impl TransitionConstraint for ZeroFlagConstraint { + fn degree(&self) -> usize { + 1 + } + + fn constraint_idx(&self) -> usize { + 15 + } + + fn evaluate( + &self, + frame: &stark_platinum_prover::frame::Frame, + transition_evaluations: &mut [Felt252], + _periodic_values: &[Felt252], + _rap_challenges: &[Felt252], + ) { + let current_step = frame.get_evaluation_step(0); + + let zero_flag = current_step.get_main_evaluation_element(0, 15); + + transition_evaluations[self.constraint_idx()] = *zero_flag; + } + + fn end_exemptions(&self) -> usize { + 0 + } +} + +pub struct FlagOp1BaseOp0BitConstraint; +impl Default for FlagOp1BaseOp0BitConstraint { + fn default() -> Self { + Self::new() + } +} + +impl FlagOp1BaseOp0BitConstraint { + pub fn new() -> Self { + Self + } +} + +impl TransitionConstraint for FlagOp1BaseOp0BitConstraint { + fn degree(&self) -> usize { + 2 + } + + fn constraint_idx(&self) -> usize { + 54 + } + + fn evaluate( + &self, + frame: &Frame, + transition_evaluations: &mut [Felt252], + _periodic_values: &[Felt252], + _rap_challenges: &[Felt252], + ) { + let current_step = frame.get_evaluation_step(0); + + let one = Felt252::one(); + let two = Felt252::from(2); + + let f_op1_imm = current_step.get_main_evaluation_element(0, 2) + - two * current_step.get_main_evaluation_element(0, 3); + let f_op1_fp = current_step.get_main_evaluation_element(0, 3) + - two * current_step.get_main_evaluation_element(0, 4); + let f_op1_ap = current_step.get_main_evaluation_element(0, 4) + - two * current_step.get_main_evaluation_element(0, 5); + + let f_op1_base_op0_bit = one - f_op1_imm - f_op1_fp - f_op1_ap; + + let res = f_op1_base_op0_bit * (f_op1_base_op0_bit - one); + + transition_evaluations[self.constraint_idx()] = res; + } + + fn end_exemptions(&self) -> usize { + 0 + } +} + +pub struct FlagResOp1BitConstraint; +impl Default for FlagResOp1BitConstraint { + fn default() -> Self { + Self::new() + } +} + +impl FlagResOp1BitConstraint { + pub fn new() -> Self { + Self + } +} + +impl TransitionConstraint for FlagResOp1BitConstraint { + fn degree(&self) -> usize { + 2 + } + + fn constraint_idx(&self) -> usize { + 55 + } + + fn evaluate( + &self, + frame: &Frame, + transition_evaluations: &mut [Felt252], + _periodic_values: &[Felt252], + _rap_challenges: &[Felt252], + ) { + let current_step = frame.get_evaluation_step(0); + + let one = Felt252::one(); + let two = Felt252::from(2); + + let f_res_add = current_step.get_main_evaluation_element(0, 5) + - two * current_step.get_main_evaluation_element(0, 6); + let f_res_mul = current_step.get_main_evaluation_element(0, 6) + - two * current_step.get_main_evaluation_element(0, 7); + let f_pc_jnz = current_step.get_main_evaluation_element(0, 9) + - two * current_step.get_main_evaluation_element(0, 10); + + let f_res_op1_bit = one - f_res_add - f_res_mul - f_pc_jnz; + + let res = f_res_op1_bit * (f_res_op1_bit - one); + + transition_evaluations[self.constraint_idx()] = res; + } + + fn end_exemptions(&self) -> usize { + 0 + } +} + +pub struct FlagPcUpdateRegularBit; +impl Default for FlagPcUpdateRegularBit { + fn default() -> Self { + Self::new() + } +} + +impl FlagPcUpdateRegularBit { + pub fn new() -> Self { + Self + } +} + +impl TransitionConstraint for FlagPcUpdateRegularBit { + fn degree(&self) -> usize { + 2 + } + + fn constraint_idx(&self) -> usize { + 56 + } + + fn evaluate( + &self, + frame: &Frame, + transition_evaluations: &mut [Felt252], + _periodic_values: &[Felt252], + _rap_challenges: &[Felt252], + ) { + let current_step = frame.get_evaluation_step(0); + + let one = Felt252::one(); + let two = Felt252::from(2); + + let f_jump_abs = current_step.get_main_evaluation_element(0, 7) + - two * current_step.get_main_evaluation_element(0, 8); + let f_jump_rel = current_step.get_main_evaluation_element(0, 8) + - two * current_step.get_main_evaluation_element(0, 9); + let f_pc_jnz = current_step.get_main_evaluation_element(0, 9) + - two * current_step.get_main_evaluation_element(0, 10); + + let flag_pc_update_regular_bit = one - f_jump_abs - f_jump_rel - f_pc_jnz; + + let res = flag_pc_update_regular_bit * (flag_pc_update_regular_bit - one); + + transition_evaluations[self.constraint_idx()] = res; + } + + fn end_exemptions(&self) -> usize { + 0 + } +} + +pub struct FlagFpUpdateRegularBit; +impl Default for FlagFpUpdateRegularBit { + fn default() -> Self { + Self::new() + } +} + +impl FlagFpUpdateRegularBit { + pub fn new() -> Self { + Self + } +} + +impl TransitionConstraint for FlagFpUpdateRegularBit { + fn degree(&self) -> usize { + 2 + } + + fn constraint_idx(&self) -> usize { + 57 + } + + fn evaluate( + &self, + frame: &Frame, + transition_evaluations: &mut [Felt252], + _periodic_values: &[Felt252], + _rap_challenges: &[Felt252], + ) { + let current_step = frame.get_evaluation_step(0); + + let one = Felt252::one(); + let two = Felt252::from(2); + + let f_opcode_call = current_step.get_main_evaluation_element(0, 12) + - two * current_step.get_main_evaluation_element(0, 13); + let f_opcode_ret = current_step.get_main_evaluation_element(0, 13) + - two * current_step.get_main_evaluation_element(0, 14); + + let flag_fp_update_regular_bit = one - f_opcode_call - f_opcode_ret; + + let res = flag_fp_update_regular_bit * (flag_fp_update_regular_bit - one); + + transition_evaluations[self.constraint_idx()] = res; + } + + fn end_exemptions(&self) -> usize { + 0 + } +} + +pub struct InstructionUnpacking; +impl Default for InstructionUnpacking { + fn default() -> Self { + Self::new() + } +} + +impl InstructionUnpacking { + pub fn new() -> Self { + Self + } +} + +impl TransitionConstraint for InstructionUnpacking { + fn degree(&self) -> usize { + 1 + } + + fn constraint_idx(&self) -> usize { + 16 + } + + fn evaluate( + &self, + frame: &Frame, + transition_evaluations: &mut [Felt252], + _periodic_values: &[Felt252], + _rap_challenges: &[Felt252], + ) { + let current_step = frame.get_evaluation_step(0); + + let two = Felt252::from(2); + let b16 = two.pow(16u32); + let b32 = two.pow(32u32); + let b48 = two.pow(48u32); + + // Named like this to match the Cairo whitepaper's notation. + let f0_squiggle = current_step.get_main_evaluation_element(0, 0); + + let instruction = current_step.get_main_evaluation_element(0, 23); + let off_dst = current_step.get_main_evaluation_element(0, 27); + let off_op0 = current_step.get_main_evaluation_element(0, 28); + let off_op1 = current_step.get_main_evaluation_element(0, 29); + + let res = off_dst + b16 * off_op0 + b32 * off_op1 + b48 * f0_squiggle - instruction; + + transition_evaluations[self.constraint_idx()] = res; + } + + fn end_exemptions(&self) -> usize { + 0 + } +} + +pub struct CpuOpcodesCallOff0; +impl Default for CpuOpcodesCallOff0 { + fn default() -> Self { + Self::new() + } +} + +impl CpuOpcodesCallOff0 { + pub fn new() -> Self { + Self + } +} + +impl TransitionConstraint for CpuOpcodesCallOff0 { + fn degree(&self) -> usize { + 2 + } + + fn constraint_idx(&self) -> usize { + 58 + } + + fn evaluate( + &self, + frame: &Frame, + transition_evaluations: &mut [Felt252], + _periodic_values: &[Felt252], + _rap_challenges: &[Felt252], + ) { + let current_step = frame.get_evaluation_step(0); + let two = Felt252::from(2); + let b15 = two.pow(15u32); + + let f_opcode_call = current_step.get_main_evaluation_element(0, 12) + - two * current_step.get_main_evaluation_element(0, 13); + + let off_dst = current_step.get_main_evaluation_element(0, 27); + + let res = f_opcode_call * (off_dst - b15); + + transition_evaluations[self.constraint_idx()] = res; + } + + fn end_exemptions(&self) -> usize { + 0 + } +} + +pub struct CpuOpcodesCallOff1; +impl Default for CpuOpcodesCallOff1 { + fn default() -> Self { + Self::new() + } +} + +impl CpuOpcodesCallOff1 { + pub fn new() -> Self { + Self + } +} + +impl TransitionConstraint for CpuOpcodesCallOff1 { + fn degree(&self) -> usize { + 2 + } + + fn constraint_idx(&self) -> usize { + 59 + } + + fn evaluate( + &self, + frame: &Frame, + transition_evaluations: &mut [Felt252], + _periodic_values: &[Felt252], + _rap_challenges: &[Felt252], + ) { + let current_step = frame.get_evaluation_step(0); + + let one = Felt252::one(); + let two = Felt252::from(2); + let b15 = two.pow(15u32); + + let f_opcode_call = current_step.get_main_evaluation_element(0, 12) + - two * current_step.get_main_evaluation_element(0, 13); + let off_op0 = current_step.get_main_evaluation_element(0, 28); + + let res = f_opcode_call * (off_op0 - b15 - one); + + transition_evaluations[self.constraint_idx()] = res; + } + + fn end_exemptions(&self) -> usize { + 0 + } +} + +pub struct CpuOpcodesCallFlags; +impl Default for CpuOpcodesCallFlags { + fn default() -> Self { + Self::new() + } +} + +impl CpuOpcodesCallFlags { + pub fn new() -> Self { + Self + } +} + +impl TransitionConstraint for CpuOpcodesCallFlags { + fn degree(&self) -> usize { + 2 + } + + fn constraint_idx(&self) -> usize { + 60 + } + + fn evaluate( + &self, + frame: &Frame, + transition_evaluations: &mut [Felt252], + _periodic_values: &[Felt252], + _rap_challenges: &[Felt252], + ) { + let current_step = frame.get_evaluation_step(0); + + let one = Felt252::one(); + let two = Felt252::from(2); + + let f_opcode_call = current_step.get_main_evaluation_element(0, 12) + - two * current_step.get_main_evaluation_element(0, 13); + + let bit_flag0 = current_step.get_main_evaluation_element(0, 0) + - two * current_step.get_main_evaluation_element(0, 1); + let bit_flag1 = current_step.get_main_evaluation_element(0, 1) + - two * current_step.get_main_evaluation_element(0, 2); + + let res = + f_opcode_call * (two * f_opcode_call + one + one - bit_flag0 - bit_flag1 - two - two); + + transition_evaluations[self.constraint_idx()] = res; + } + + fn end_exemptions(&self) -> usize { + 0 + } +} + +pub struct CpuOpcodesRetOff0; +impl Default for CpuOpcodesRetOff0 { + fn default() -> Self { + Self::new() + } +} + +impl CpuOpcodesRetOff0 { + pub fn new() -> Self { + Self + } +} + +impl TransitionConstraint for CpuOpcodesRetOff0 { + fn degree(&self) -> usize { + 2 + } + + fn constraint_idx(&self) -> usize { + 61 + } + + fn evaluate( + &self, + frame: &Frame, + transition_evaluations: &mut [Felt252], + _periodic_values: &[Felt252], + _rap_challenges: &[Felt252], + ) { + let current_step = frame.get_evaluation_step(0); + + let two = Felt252::from(2); + let b15 = two.pow(15u32); + + let f_opcode_ret = current_step.get_main_evaluation_element(0, 13) + - two * current_step.get_main_evaluation_element(0, 14); + let off_dst = current_step.get_main_evaluation_element(0, 27); + + let res = f_opcode_ret * (off_dst + two - b15); + + transition_evaluations[self.constraint_idx()] = res; + } + + fn end_exemptions(&self) -> usize { + 0 + } +} + +pub struct CpuOpcodesRetOff2; +impl Default for CpuOpcodesRetOff2 { + fn default() -> Self { + Self::new() + } +} + +impl CpuOpcodesRetOff2 { + pub fn new() -> Self { + Self + } +} + +impl TransitionConstraint for CpuOpcodesRetOff2 { + fn degree(&self) -> usize { + 2 + } + + fn constraint_idx(&self) -> usize { + 62 + } + + fn evaluate( + &self, + frame: &Frame, + transition_evaluations: &mut [Felt252], + _periodic_values: &[Felt252], + _rap_challenges: &[Felt252], + ) { + let current_step = frame.get_evaluation_step(0); + + let one = Felt252::one(); + let two = Felt252::from(2); + let b15 = two.pow(15u32); + + let f_opcode_ret = current_step.get_main_evaluation_element(0, 13) + - two * current_step.get_main_evaluation_element(0, 14); + let off_op1 = current_step.get_main_evaluation_element(0, 29); + + let res = f_opcode_ret * (off_op1 + one - b15); + + transition_evaluations[self.constraint_idx()] = res; + } + + fn end_exemptions(&self) -> usize { + 0 + } +} + +pub struct CpuOpcodesRetFlags; +impl Default for CpuOpcodesRetFlags { + fn default() -> Self { + Self::new() + } +} + +impl CpuOpcodesRetFlags { + pub fn new() -> Self { + Self + } +} + +impl TransitionConstraint for CpuOpcodesRetFlags { + fn degree(&self) -> usize { + 2 + } + + fn constraint_idx(&self) -> usize { + 63 + } + + fn evaluate( + &self, + frame: &Frame, + transition_evaluations: &mut [Felt252], + _periodic_values: &[Felt252], + _rap_challenges: &[Felt252], + ) { + let current_step = frame.get_evaluation_step(0); + + let one = Felt252::one(); + let two = Felt252::from(2); + + let f_opcode_ret = current_step.get_main_evaluation_element(0, 13) + - two * current_step.get_main_evaluation_element(0, 14); + let flag0 = current_step.get_main_evaluation_element(0, 0) + - two * current_step.get_main_evaluation_element(0, 1); + let flag3 = current_step.get_main_evaluation_element(0, 3) + - two * current_step.get_main_evaluation_element(0, 4); + let flag7 = current_step.get_main_evaluation_element(0, 7) + - two * current_step.get_main_evaluation_element(0, 8); + + let f_res_add = current_step.get_main_evaluation_element(0, 5) + - two * current_step.get_main_evaluation_element(0, 6); + let f_res_mul = current_step.get_main_evaluation_element(0, 6) + - two * current_step.get_main_evaluation_element(0, 7); + let f_pc_jnz = current_step.get_main_evaluation_element(0, 9) + - two * current_step.get_main_evaluation_element(0, 10); + + let f_res_op1_bit = one - f_res_add - f_res_mul - f_pc_jnz; + + let res = f_opcode_ret * (flag7 + flag0 + flag3 + f_res_op1_bit - two - two); + + transition_evaluations[self.constraint_idx()] = res; + } + + fn end_exemptions(&self) -> usize { + 0 + } +} + +pub struct CpuOperandsMemDstAddr; +impl Default for CpuOperandsMemDstAddr { + fn default() -> Self { + Self::new() + } +} + +impl CpuOperandsMemDstAddr { + pub fn new() -> Self { + Self + } +} + +impl TransitionConstraint for CpuOperandsMemDstAddr { + fn degree(&self) -> usize { + 2 + } + + fn constraint_idx(&self) -> usize { + 17 + } + + fn evaluate( + &self, + frame: &Frame, + transition_evaluations: &mut [Felt252], + _periodic_values: &[Felt252], + _rap_challenges: &[Felt252], + ) { + let current_step = frame.get_evaluation_step(0); + + let two = Felt252::from(2); + let one = Felt252::one(); + let b15 = two.pow(15u32); + let dst_fp = current_step.get_main_evaluation_element(0, 0) + - two * current_step.get_main_evaluation_element(0, 1); + let ap = current_step.get_main_evaluation_element(0, 17); + let fp = current_step.get_main_evaluation_element(0, 18); + let off_dst = current_step.get_main_evaluation_element(0, 27); + let dst_addr = current_step.get_main_evaluation_element(0, 20); + + let res = dst_fp * fp + (one - dst_fp) * ap + (off_dst - b15) - dst_addr; + + transition_evaluations[self.constraint_idx()] = res; + } + + fn end_exemptions(&self) -> usize { + 0 + } +} + +pub struct CpuOperandsMem0Addr; +impl Default for CpuOperandsMem0Addr { + fn default() -> Self { + Self::new() + } +} + +impl CpuOperandsMem0Addr { + pub fn new() -> Self { + Self + } +} + +impl TransitionConstraint for CpuOperandsMem0Addr { + fn degree(&self) -> usize { + 2 + } + + fn constraint_idx(&self) -> usize { + 18 + } + + fn evaluate( + &self, + frame: &Frame, + transition_evaluations: &mut [Felt252], + _periodic_values: &[Felt252], + _rap_challenges: &[Felt252], + ) { + let current_step = frame.get_evaluation_step(0); + + let two = Felt252::from(2); + let one = Felt252::one(); + let b15 = two.pow(15u32); + + let op0_fp = current_step.get_main_evaluation_element(0, 1) + - two * current_step.get_main_evaluation_element(0, 2); + + let ap = current_step.get_main_evaluation_element(0, 17); + let fp = current_step.get_main_evaluation_element(0, 18); + + let off_op0 = current_step.get_main_evaluation_element(0, 28); + let op0_addr = current_step.get_main_evaluation_element(0, 21); + + let res = op0_fp * fp + (one - op0_fp) * ap + (off_op0 - b15) - op0_addr; + + transition_evaluations[self.constraint_idx()] = res; + } + + fn end_exemptions(&self) -> usize { + 0 + } +} + +pub struct CpuOperandsMem1Addr; +impl Default for CpuOperandsMem1Addr { + fn default() -> Self { + Self::new() + } +} + +impl CpuOperandsMem1Addr { + pub fn new() -> Self { + Self + } +} + +impl TransitionConstraint for CpuOperandsMem1Addr { + fn degree(&self) -> usize { + 2 + } + + fn constraint_idx(&self) -> usize { + 19 + } + + fn evaluate( + &self, + frame: &Frame, + transition_evaluations: &mut [Felt252], + _periodic_values: &[Felt252], + _rap_challenges: &[Felt252], + ) { + let current_step = frame.get_evaluation_step(0); + + let one = Felt252::one(); + let two = Felt252::from(2); + let b15 = two.pow(15u32); + + let op1_val = current_step.get_main_evaluation_element(0, 2) + - two * current_step.get_main_evaluation_element(0, 3); + let op1_fp = current_step.get_main_evaluation_element(0, 3) + - two * current_step.get_main_evaluation_element(0, 4); + let op1_ap = current_step.get_main_evaluation_element(0, 4) + - two * current_step.get_main_evaluation_element(0, 5); + + let op0 = current_step.get_main_evaluation_element(0, 25); + let off_op1 = current_step.get_main_evaluation_element(0, 29); + let op1_addr = current_step.get_main_evaluation_element(0, 22); + + let ap = current_step.get_main_evaluation_element(0, 17); + let fp = current_step.get_main_evaluation_element(0, 18); + let pc = current_step.get_main_evaluation_element(0, 19); + + let res = op1_val * pc + + op1_ap * ap + + op1_fp * fp + + (one - op1_val - op1_ap - op1_fp) * op0 + + (off_op1 - b15) + - op1_addr; + + transition_evaluations[self.constraint_idx()] = res; + } + + fn end_exemptions(&self) -> usize { + 0 + } +} + +// cpu/update_registers/update_ap/ap_update +pub struct CpuUpdateRegistersApUpdate; +impl Default for CpuUpdateRegistersApUpdate { + fn default() -> Self { + Self::new() + } +} + +impl CpuUpdateRegistersApUpdate { + pub fn new() -> Self { + Self + } +} + +impl TransitionConstraint for CpuUpdateRegistersApUpdate { + fn degree(&self) -> usize { + 2 + } + + fn constraint_idx(&self) -> usize { + 20 + } + + fn evaluate( + &self, + frame: &Frame, + transition_evaluations: &mut [Felt252], + _periodic_values: &[Felt252], + _rap_challenges: &[Felt252], + ) { + let current_step = frame.get_evaluation_step(0); + let next_step = frame.get_evaluation_step(1); + + let two = Felt252::from(2); + + let ap = current_step.get_main_evaluation_element(0, 17); + let next_ap = next_step.get_main_evaluation_element(0, 17); + let res = current_step.get_main_evaluation_element(0, 16); + + let ap_one = current_step.get_main_evaluation_element(0, 11) + - two * current_step.get_main_evaluation_element(0, 12); + let opc_call = current_step.get_main_evaluation_element(0, 12) + - two * current_step.get_main_evaluation_element(0, 13); + let ap_add = current_step.get_main_evaluation_element(0, 10) + - two * current_step.get_main_evaluation_element(0, 11); + + let res = ap + ap_add * res + ap_one + opc_call * two - next_ap; + + transition_evaluations[self.constraint_idx()] = res; + } + + fn end_exemptions(&self) -> usize { + 1 + } +} + +pub struct CpuUpdateRegistersFpUpdate; +impl Default for CpuUpdateRegistersFpUpdate { + fn default() -> Self { + Self::new() + } +} + +impl CpuUpdateRegistersFpUpdate { + pub fn new() -> Self { + Self + } +} + +impl TransitionConstraint for CpuUpdateRegistersFpUpdate { + fn degree(&self) -> usize { + 2 + } + + fn constraint_idx(&self) -> usize { + 21 + } + + fn evaluate( + &self, + frame: &Frame, + transition_evaluations: &mut [Felt252], + _periodic_values: &[Felt252], + _rap_challenges: &[Felt252], + ) { + let current_step = frame.get_evaluation_step(0); + let next_step = frame.get_evaluation_step(1); + + let one = Felt252::one(); + let two = Felt252::from(2); + + let ap = current_step.get_main_evaluation_element(0, 17); + let fp = current_step.get_main_evaluation_element(0, 18); + let next_fp = next_step.get_main_evaluation_element(0, 18); + let dst = current_step.get_main_evaluation_element(0, 24); + + let opc_call = current_step.get_main_evaluation_element(0, 12) + - two * current_step.get_main_evaluation_element(0, 13); + let opc_ret = current_step.get_main_evaluation_element(0, 13) + - two * current_step.get_main_evaluation_element(0, 14); + + let res = opc_ret * dst + opc_call * (ap + two) + (one - opc_ret - opc_call) * fp - next_fp; + + transition_evaluations[self.constraint_idx()] = res; + } + + fn end_exemptions(&self) -> usize { + 1 + } +} + +// cpu/update_registers/update_pc/pc_cond_negative: +pub struct CpuUpdateRegistersPcCondNegative; +impl Default for CpuUpdateRegistersPcCondNegative { + fn default() -> Self { + Self::new() + } +} + +impl CpuUpdateRegistersPcCondNegative { + pub fn new() -> Self { + Self + } +} + +impl TransitionConstraint + for CpuUpdateRegistersPcCondNegative +{ + fn degree(&self) -> usize { + 2 + } + + fn constraint_idx(&self) -> usize { + 23 + } + + fn evaluate( + &self, + frame: &Frame, + transition_evaluations: &mut [Felt252], + _periodic_values: &[Felt252], + _rap_challenges: &[Felt252], + ) { + let current_step = frame.get_evaluation_step(0); + let next_step = frame.get_evaluation_step(1); + + let one = Felt252::one(); + let two = Felt252::from(2); + + let t0 = current_step.get_main_evaluation_element(0, 30); + let pc = current_step.get_main_evaluation_element(0, 19); + let next_pc = next_step.get_main_evaluation_element(0, 19); + let op1 = current_step.get_main_evaluation_element(0, 26); + + let pc_jnz = current_step.get_main_evaluation_element(0, 9) + - two * current_step.get_main_evaluation_element(0, 10); + let pc_abs = current_step.get_main_evaluation_element(0, 7) + - two * current_step.get_main_evaluation_element(0, 8); + let pc_rel = current_step.get_main_evaluation_element(0, 8) + - two * current_step.get_main_evaluation_element(0, 9); + let res = current_step.get_main_evaluation_element(0, 16); + + let res = t0 * (next_pc - (pc + op1)) + (one - pc_jnz) * next_pc + - ((one - pc_abs - pc_rel - pc_jnz) * (pc + frame_inst_size(current_step)) + + pc_abs * res + + pc_rel * (pc + res)); + transition_evaluations[self.constraint_idx()] = res; + } + + fn end_exemptions(&self) -> usize { + 1 + } +} + +pub struct CpuUpdateRegistersPcCondPositive; +impl Default for CpuUpdateRegistersPcCondPositive { + fn default() -> Self { + Self::new() + } +} + +impl CpuUpdateRegistersPcCondPositive { + pub fn new() -> Self { + Self + } +} + +impl TransitionConstraint + for CpuUpdateRegistersPcCondPositive +{ + fn degree(&self) -> usize { + 2 + } + + fn constraint_idx(&self) -> usize { + 22 + } + + fn evaluate( + &self, + frame: &Frame, + transition_evaluations: &mut [Felt252], + _periodic_values: &[Felt252], + _rap_challenges: &[Felt252], + ) { + let current_step = frame.get_evaluation_step(0); + let next_step = frame.get_evaluation_step(1); + + let two = Felt252::from(2); + + let t1 = current_step.get_main_evaluation_element(0, 31); + let pc_jnz = current_step.get_main_evaluation_element(0, 9) + - two * current_step.get_main_evaluation_element(0, 10); + let pc = current_step.get_main_evaluation_element(0, 19); + let next_pc = next_step.get_main_evaluation_element(0, 19); + + let res = (t1 - pc_jnz) * (next_pc - (pc + frame_inst_size(current_step))); + + transition_evaluations[self.constraint_idx()] = res; + } + + fn end_exemptions(&self) -> usize { + 1 + } +} + +//cpu/update_registers/update_pc/tmp0 +pub struct CpuUpdateRegistersUpdatePcTmp0; +impl Default for CpuUpdateRegistersUpdatePcTmp0 { + fn default() -> Self { + Self::new() + } +} + +impl CpuUpdateRegistersUpdatePcTmp0 { + pub fn new() -> Self { + Self + } +} + +impl TransitionConstraint + for CpuUpdateRegistersUpdatePcTmp0 +{ + fn degree(&self) -> usize { + 2 + } + + fn constraint_idx(&self) -> usize { + 24 + } + + fn evaluate( + &self, + frame: &Frame, + transition_evaluations: &mut [Felt252], + _periodic_values: &[Felt252], + _rap_challenges: &[Felt252], + ) { + let current_step = frame.get_evaluation_step(0); + + let two = Felt252::from(2); + let dst = current_step.get_main_evaluation_element(0, 24); + let t0 = current_step.get_main_evaluation_element(0, 30); + let pc_jnz = current_step.get_main_evaluation_element(0, 9) + - two * current_step.get_main_evaluation_element(0, 10); + + let res = pc_jnz * dst - t0; + + transition_evaluations[self.constraint_idx()] = res; + } + + fn end_exemptions(&self) -> usize { + 0 + } +} + +pub struct CpuUpdateRegistersUpdatePcTmp1; +impl Default for CpuUpdateRegistersUpdatePcTmp1 { + fn default() -> Self { + Self::new() + } +} + +impl CpuUpdateRegistersUpdatePcTmp1 { + pub fn new() -> Self { + Self + } +} + +impl TransitionConstraint + for CpuUpdateRegistersUpdatePcTmp1 +{ + fn degree(&self) -> usize { + 2 + } + + fn constraint_idx(&self) -> usize { + 25 + } + + fn evaluate( + &self, + frame: &Frame, + transition_evaluations: &mut [Felt252], + _periodic_values: &[Felt252], + _rap_challenges: &[Felt252], + ) { + let current_step = frame.get_evaluation_step(0); + + let t1 = current_step.get_main_evaluation_element(0, 31); + let t0 = current_step.get_main_evaluation_element(0, 30); + let res = current_step.get_main_evaluation_element(0, 16); + + let transition_res = t0 * res - t1; + + transition_evaluations[self.constraint_idx()] = transition_res; + } + + fn end_exemptions(&self) -> usize { + 0 + } +} + +pub struct CpuOperandsOpsMul; +impl Default for CpuOperandsOpsMul { + fn default() -> Self { + Self::new() + } +} + +impl CpuOperandsOpsMul { + pub fn new() -> Self { + Self + } +} + +impl TransitionConstraint for CpuOperandsOpsMul { + fn degree(&self) -> usize { + 2 + } + + fn constraint_idx(&self) -> usize { + 26 + } + + fn evaluate( + &self, + frame: &Frame, + transition_evaluations: &mut [Felt252], + _periodic_values: &[Felt252], + _rap_challenges: &[Felt252], + ) { + let current_step = frame.get_evaluation_step(0); + + let mul = current_step.get_main_evaluation_element(0, 32); + let op0 = current_step.get_main_evaluation_element(0, 25); + let op1 = current_step.get_main_evaluation_element(0, 26); + + transition_evaluations[self.constraint_idx()] = mul - op0 * op1; + } + + fn end_exemptions(&self) -> usize { + 0 + } +} + +// cpu/operands/res +pub struct CpuOperandsRes; +impl Default for CpuOperandsRes { + fn default() -> Self { + Self::new() + } +} + +impl CpuOperandsRes { + pub fn new() -> Self { + Self + } +} + +impl TransitionConstraint for CpuOperandsRes { + fn degree(&self) -> usize { + 2 + } + + fn constraint_idx(&self) -> usize { + 27 + } + + fn evaluate( + &self, + frame: &Frame, + transition_evaluations: &mut [Felt252], + _periodic_values: &[Felt252], + _rap_challenges: &[Felt252], + ) { + let current_step = frame.get_evaluation_step(0); + let one = Felt252::one(); + let two = Felt252::from(2); + + let mul = current_step.get_main_evaluation_element(0, 32); + let op0 = current_step.get_main_evaluation_element(0, 25); + let op1 = current_step.get_main_evaluation_element(0, 26); + let res = current_step.get_main_evaluation_element(0, 16); + + let res_add = current_step.get_main_evaluation_element(0, 5) + - two * current_step.get_main_evaluation_element(0, 6); + let res_mul = current_step.get_main_evaluation_element(0, 6) + - two * current_step.get_main_evaluation_element(0, 7); + let pc_jnz = current_step.get_main_evaluation_element(0, 9) + - two * current_step.get_main_evaluation_element(0, 10); + + let transition_res = + res_add * (op0 + op1) + res_mul * mul + (one - res_add - res_mul - pc_jnz) * op1 + - (one - pc_jnz) * res; + + transition_evaluations[self.constraint_idx()] = transition_res; + } + + fn end_exemptions(&self) -> usize { + 0 + } +} + +// cpu/opcodes/call/push_fp +pub struct CpuOpcodesCallPushFp; +impl Default for CpuOpcodesCallPushFp { + fn default() -> Self { + Self::new() + } +} + +impl CpuOpcodesCallPushFp { + pub fn new() -> Self { + Self + } +} + +impl TransitionConstraint for CpuOpcodesCallPushFp { + fn degree(&self) -> usize { + 2 + } + + fn constraint_idx(&self) -> usize { + 28 + } + + fn evaluate( + &self, + frame: &Frame, + transition_evaluations: &mut [Felt252], + _periodic_values: &[Felt252], + _rap_challenges: &[Felt252], + ) { + let current_step = frame.get_evaluation_step(0); + + let two = Felt252::from(2); + + let opc_call = current_step.get_main_evaluation_element(0, 12) + - two * current_step.get_main_evaluation_element(0, 13); + + let dst = current_step.get_main_evaluation_element(0, 24); + let fp = current_step.get_main_evaluation_element(0, 18); + + transition_evaluations[self.constraint_idx()] = opc_call * (dst - fp); + } + + fn end_exemptions(&self) -> usize { + 0 + } +} + +pub struct CpuOpcodesCallPushPc; +impl Default for CpuOpcodesCallPushPc { + fn default() -> Self { + Self::new() + } +} + +impl CpuOpcodesCallPushPc { + pub fn new() -> Self { + Self + } +} + +impl TransitionConstraint for CpuOpcodesCallPushPc { + fn degree(&self) -> usize { + 2 + } + + fn constraint_idx(&self) -> usize { + 29 + } + + fn evaluate( + &self, + frame: &Frame, + transition_evaluations: &mut [Felt252], + _periodic_values: &[Felt252], + _rap_challenges: &[Felt252], + ) { + let current_step = frame.get_evaluation_step(0); + + let two = Felt252::from(2); + + let opc_call = current_step.get_main_evaluation_element(0, 12) + - two * current_step.get_main_evaluation_element(0, 13); + + let op0 = current_step.get_main_evaluation_element(0, 25); + let pc = current_step.get_main_evaluation_element(0, 19); + + transition_evaluations[self.constraint_idx()] = + opc_call * (op0 - (pc + frame_inst_size(current_step))); + } + + fn end_exemptions(&self) -> usize { + 0 + } +} + +// cpu/opcodes/assert_eq/assert_eq +pub struct CpuOpcodesAssertEq; +impl Default for CpuOpcodesAssertEq { + fn default() -> Self { + Self::new() + } +} + +impl CpuOpcodesAssertEq { + pub fn new() -> Self { + Self + } +} + +impl TransitionConstraint for CpuOpcodesAssertEq { + fn degree(&self) -> usize { + 2 + } + + fn constraint_idx(&self) -> usize { + 30 + } + + fn evaluate( + &self, + frame: &Frame, + transition_evaluations: &mut [Felt252], + _periodic_values: &[Felt252], + _rap_challenges: &[Felt252], + ) { + let current_step = frame.get_evaluation_step(0); + + let two = Felt252::from(2); + + let opc_aeq = current_step.get_main_evaluation_element(0, 14) + - two * current_step.get_main_evaluation_element(0, 15); + let dst = current_step.get_main_evaluation_element(0, 24); + let res = current_step.get_main_evaluation_element(0, 16); + + transition_evaluations[self.constraint_idx()] = opc_aeq * (dst - res) + } + + fn end_exemptions(&self) -> usize { + 0 + } +} + +// memory/diff_is_bit +pub struct MemoryDiffIsBit0; +impl Default for MemoryDiffIsBit0 { + fn default() -> Self { + Self::new() + } +} + +impl MemoryDiffIsBit0 { + pub fn new() -> Self { + Self + } +} + +impl TransitionConstraint for MemoryDiffIsBit0 { + fn degree(&self) -> usize { + 2 + } + + fn constraint_idx(&self) -> usize { + 31 + } + + fn evaluate( + &self, + frame: &Frame, + transition_evaluations: &mut [Felt252], + _periodic_values: &[Felt252], + _rap_challenges: &[Felt252], + ) { + let current_step = frame.get_evaluation_step(0); + + let one = Felt252::one(); + + let mem_addr_sorted_0 = current_step.get_aux_evaluation_element(0, 4); + let mem_addr_sorted_1 = current_step.get_aux_evaluation_element(0, 5); + + transition_evaluations[self.constraint_idx()] = + (mem_addr_sorted_0 - mem_addr_sorted_1) * (mem_addr_sorted_1 - mem_addr_sorted_0 - one); + } + + fn end_exemptions(&self) -> usize { + 0 + } +} + +pub struct MemoryDiffIsBit1; +impl Default for MemoryDiffIsBit1 { + fn default() -> Self { + Self::new() + } +} + +impl MemoryDiffIsBit1 { + pub fn new() -> Self { + Self + } +} + +impl TransitionConstraint for MemoryDiffIsBit1 { + fn degree(&self) -> usize { + 2 + } + + fn constraint_idx(&self) -> usize { + 32 + } + + fn evaluate( + &self, + frame: &Frame, + transition_evaluations: &mut [Felt252], + _periodic_values: &[Felt252], + _rap_challenges: &[Felt252], + ) { + let current_step = frame.get_evaluation_step(0); + + let one = Felt252::one(); + + let mem_addr_sorted_1 = current_step.get_aux_evaluation_element(0, 5); + let mem_addr_sorted_2 = current_step.get_aux_evaluation_element(0, 6); + + transition_evaluations[self.constraint_idx()] = + (mem_addr_sorted_1 - mem_addr_sorted_2) * (mem_addr_sorted_2 - mem_addr_sorted_1 - one); + } + + fn end_exemptions(&self) -> usize { + 0 + } +} +pub struct MemoryDiffIsBit2; +impl Default for MemoryDiffIsBit2 { + fn default() -> Self { + Self::new() + } +} + +impl MemoryDiffIsBit2 { + pub fn new() -> Self { + Self + } +} + +impl TransitionConstraint for MemoryDiffIsBit2 { + fn degree(&self) -> usize { + 2 + } + + fn constraint_idx(&self) -> usize { + 33 + } + + fn evaluate( + &self, + frame: &Frame, + transition_evaluations: &mut [Felt252], + _periodic_values: &[Felt252], + _rap_challenges: &[Felt252], + ) { + let current_step = frame.get_evaluation_step(0); + + let one = Felt252::one(); + + let mem_addr_sorted_2 = current_step.get_aux_evaluation_element(0, 6); + let mem_addr_sorted_3 = current_step.get_aux_evaluation_element(0, 7); + + transition_evaluations[self.constraint_idx()] = + (mem_addr_sorted_2 - mem_addr_sorted_3) * (mem_addr_sorted_3 - mem_addr_sorted_2 - one); + } + + fn end_exemptions(&self) -> usize { + 0 + } +} +pub struct MemoryDiffIsBit3; +impl Default for MemoryDiffIsBit3 { + fn default() -> Self { + Self::new() + } +} + +impl MemoryDiffIsBit3 { + pub fn new() -> Self { + Self + } +} + +impl TransitionConstraint for MemoryDiffIsBit3 { + fn degree(&self) -> usize { + 2 + } + + fn constraint_idx(&self) -> usize { + 34 + } + + fn evaluate( + &self, + frame: &Frame, + transition_evaluations: &mut [Felt252], + _periodic_values: &[Felt252], + _rap_challenges: &[Felt252], + ) { + let current_step = frame.get_evaluation_step(0); + + let one = Felt252::one(); + + let mem_addr_sorted_3 = current_step.get_aux_evaluation_element(0, 7); + let mem_addr_sorted_4 = current_step.get_aux_evaluation_element(0, 8); + + transition_evaluations[self.constraint_idx()] = + (mem_addr_sorted_3 - mem_addr_sorted_4) * (mem_addr_sorted_4 - mem_addr_sorted_3 - one); + } + + fn end_exemptions(&self) -> usize { + 0 + } +} +pub struct MemoryDiffIsBit4; +impl Default for MemoryDiffIsBit4 { + fn default() -> Self { + Self::new() + } +} + +impl MemoryDiffIsBit4 { + pub fn new() -> Self { + Self + } +} + +impl TransitionConstraint for MemoryDiffIsBit4 { + fn degree(&self) -> usize { + 2 + } + + fn constraint_idx(&self) -> usize { + 35 + } + + fn evaluate( + &self, + frame: &Frame, + transition_evaluations: &mut [Felt252], + _periodic_values: &[Felt252], + _rap_challenges: &[Felt252], + ) { + let current_step = frame.get_evaluation_step(0); + let next_step = frame.get_evaluation_step(1); + + let one = Felt252::one(); + + let next_mem_addr_sorted_0 = next_step.get_aux_evaluation_element(0, 4); + let mem_addr_sorted_4 = current_step.get_aux_evaluation_element(0, 8); + + transition_evaluations[self.constraint_idx()] = (mem_addr_sorted_4 + - next_mem_addr_sorted_0) + * (next_mem_addr_sorted_0 - mem_addr_sorted_4 - one); + } + + fn end_exemptions(&self) -> usize { + 1 + } +} + +// memory/is_func (single-valued) +pub struct MemoryIsFunc0; +impl Default for MemoryIsFunc0 { + fn default() -> Self { + Self::new() + } +} + +impl MemoryIsFunc0 { + pub fn new() -> Self { + Self + } +} + +impl TransitionConstraint for MemoryIsFunc0 { + fn degree(&self) -> usize { + 2 + } + + fn constraint_idx(&self) -> usize { + 36 + } + + fn evaluate( + &self, + frame: &Frame, + transition_evaluations: &mut [Felt252], + _periodic_values: &[Felt252], + _rap_challenges: &[Felt252], + ) { + let current_step = frame.get_evaluation_step(0); + + let one = Felt252::one(); + + let mem_addr_sorted_0 = current_step.get_aux_evaluation_element(0, 4); + let mem_addr_sorted_1 = current_step.get_aux_evaluation_element(0, 5); + + let mem_val_sorted_0 = current_step.get_aux_evaluation_element(0, 9); + let mem_val_sorted_1 = current_step.get_aux_evaluation_element(0, 10); + + transition_evaluations[self.constraint_idx()] = + (mem_val_sorted_0 - mem_val_sorted_1) * (mem_addr_sorted_1 - mem_addr_sorted_0 - one); + } + + fn end_exemptions(&self) -> usize { + 0 + } +} + +pub struct MemoryIsFunc1; +impl Default for MemoryIsFunc1 { + fn default() -> Self { + Self::new() + } +} + +impl MemoryIsFunc1 { + pub fn new() -> Self { + Self + } +} + +impl TransitionConstraint for MemoryIsFunc1 { + fn degree(&self) -> usize { + 2 + } + + fn constraint_idx(&self) -> usize { + 37 + } + + fn evaluate( + &self, + frame: &Frame, + transition_evaluations: &mut [Felt252], + _periodic_values: &[Felt252], + _rap_challenges: &[Felt252], + ) { + let current_step = frame.get_evaluation_step(0); + + let one = Felt252::one(); + + let mem_addr_sorted_1 = current_step.get_aux_evaluation_element(0, 5); + let mem_addr_sorted_2 = current_step.get_aux_evaluation_element(0, 6); + + let mem_val_sorted_1 = current_step.get_aux_evaluation_element(0, 10); + let mem_val_sorted_2 = current_step.get_aux_evaluation_element(0, 11); + + transition_evaluations[self.constraint_idx()] = + (mem_val_sorted_1 - mem_val_sorted_2) * (mem_addr_sorted_2 - mem_addr_sorted_1 - one); + } + + fn end_exemptions(&self) -> usize { + 0 + } +} + +pub struct MemoryIsFunc2; +impl Default for MemoryIsFunc2 { + fn default() -> Self { + Self::new() + } +} + +impl MemoryIsFunc2 { + pub fn new() -> Self { + Self + } +} + +impl TransitionConstraint for MemoryIsFunc2 { + fn degree(&self) -> usize { + 2 + } + + fn constraint_idx(&self) -> usize { + 38 + } + + fn evaluate( + &self, + frame: &Frame, + transition_evaluations: &mut [Felt252], + _periodic_values: &[Felt252], + _rap_challenges: &[Felt252], + ) { + let current_step = frame.get_evaluation_step(0); + + let one = Felt252::one(); + + let mem_addr_sorted_2 = current_step.get_aux_evaluation_element(0, 6); + let mem_addr_sorted_3 = current_step.get_aux_evaluation_element(0, 7); + + let mem_val_sorted_2 = current_step.get_aux_evaluation_element(0, 11); + let mem_val_sorted_3 = current_step.get_aux_evaluation_element(0, 12); + + transition_evaluations[self.constraint_idx()] = + (mem_val_sorted_2 - mem_val_sorted_3) * (mem_addr_sorted_3 - mem_addr_sorted_2 - one); + } + + fn end_exemptions(&self) -> usize { + 0 + } +} + +pub struct MemoryIsFunc3; +impl Default for MemoryIsFunc3 { + fn default() -> Self { + Self::new() + } +} + +impl MemoryIsFunc3 { + pub fn new() -> Self { + Self + } +} + +impl TransitionConstraint for MemoryIsFunc3 { + fn degree(&self) -> usize { + 2 + } + + fn constraint_idx(&self) -> usize { + 39 + } + + fn evaluate( + &self, + frame: &Frame, + transition_evaluations: &mut [Felt252], + _periodic_values: &[Felt252], + _rap_challenges: &[Felt252], + ) { + let current_step = frame.get_evaluation_step(0); + + let one = Felt252::one(); + + let mem_addr_sorted_3 = current_step.get_aux_evaluation_element(0, 7); + let mem_addr_sorted_4 = current_step.get_aux_evaluation_element(0, 8); + + let mem_val_sorted_3 = current_step.get_aux_evaluation_element(0, 12); + let mem_val_sorted_4 = current_step.get_aux_evaluation_element(0, 13); + + transition_evaluations[self.constraint_idx()] = + (mem_val_sorted_3 - mem_val_sorted_4) * (mem_addr_sorted_4 - mem_addr_sorted_3 - one); + } + + fn end_exemptions(&self) -> usize { + 0 + } +} +pub struct MemoryIsFunc4; +impl Default for MemoryIsFunc4 { + fn default() -> Self { + Self::new() + } +} + +impl MemoryIsFunc4 { + pub fn new() -> Self { + Self + } +} + +impl TransitionConstraint for MemoryIsFunc4 { + fn degree(&self) -> usize { + 2 + } + + fn constraint_idx(&self) -> usize { + 40 + } + + fn evaluate( + &self, + frame: &Frame, + transition_evaluations: &mut [Felt252], + _periodic_values: &[Felt252], + _rap_challenges: &[Felt252], + ) { + let current_step = frame.get_evaluation_step(0); + let next_step = frame.get_evaluation_step(1); + + let one = Felt252::one(); + + let next_mem_addr_sorted_0 = next_step.get_aux_evaluation_element(0, 4); + let mem_addr_sorted_4 = current_step.get_aux_evaluation_element(0, 8); + + let next_mem_val_sorted_0 = next_step.get_aux_evaluation_element(0, 9); + let mem_val_sorted_4 = current_step.get_aux_evaluation_element(0, 13); + + transition_evaluations[self.constraint_idx()] = (mem_val_sorted_4 - next_mem_val_sorted_0) + * (next_mem_addr_sorted_0 - mem_addr_sorted_4 - one); + } + + fn end_exemptions(&self) -> usize { + 1 + } +} + +// memory/multi_column_perm/perm/step0 +pub struct MemoryMultiColumnPermStep0_0; +impl Default for MemoryMultiColumnPermStep0_0 { + fn default() -> Self { + Self::new() + } +} + +impl MemoryMultiColumnPermStep0_0 { + pub fn new() -> Self { + Self + } +} + +impl TransitionConstraint for MemoryMultiColumnPermStep0_0 { + fn degree(&self) -> usize { + 2 + } + + fn constraint_idx(&self) -> usize { + 41 + } + + fn evaluate( + &self, + frame: &Frame, + transition_evaluations: &mut [Felt252], + _periodic_values: &[Felt252], + rap_challenges: &[Felt252], + ) { + let current_step = frame.get_evaluation_step(0); + + let alpha = rap_challenges[0]; + let z = rap_challenges[1]; + + let a1 = current_step.get_main_evaluation_element(0, 20); + let v1 = current_step.get_main_evaluation_element(0, 24); + + let p0 = current_step.get_aux_evaluation_element(0, 14); + let ap1 = current_step.get_aux_evaluation_element(0, 5); + let vp1 = current_step.get_aux_evaluation_element(0, 10); + let p1 = current_step.get_aux_evaluation_element(0, 15); + + transition_evaluations[self.constraint_idx()] = + (z - (ap1 + alpha * vp1)) * p1 - (z - (a1 + alpha * v1)) * p0; + } + + fn end_exemptions(&self) -> usize { + 0 + } +} + +pub struct MemoryMultiColumnPermStep0_1; +impl Default for MemoryMultiColumnPermStep0_1 { + fn default() -> Self { + Self::new() + } +} + +impl MemoryMultiColumnPermStep0_1 { + pub fn new() -> Self { + Self + } +} + +impl TransitionConstraint for MemoryMultiColumnPermStep0_1 { + fn degree(&self) -> usize { + 2 + } + + fn constraint_idx(&self) -> usize { + 42 + } + + fn evaluate( + &self, + frame: &Frame, + transition_evaluations: &mut [Felt252], + _periodic_values: &[Felt252], + rap_challenges: &[Felt252], + ) { + let current_step = frame.get_evaluation_step(0); + + let alpha = rap_challenges[0]; + let z = rap_challenges[1]; + + let a2 = current_step.get_main_evaluation_element(0, 21); + let v2 = current_step.get_main_evaluation_element(0, 25); + + let p1 = current_step.get_aux_evaluation_element(0, 15); + let ap2 = current_step.get_aux_evaluation_element(0, 6); + let vp2 = current_step.get_aux_evaluation_element(0, 11); + let p2 = current_step.get_aux_evaluation_element(0, 16); + + transition_evaluations[self.constraint_idx()] = + (z - (ap2 + alpha * vp2)) * p2 - (z - (a2 + alpha * v2)) * p1; + } + + fn end_exemptions(&self) -> usize { + 0 + } +} + +pub struct MemoryMultiColumnPermStep0_2; +impl Default for MemoryMultiColumnPermStep0_2 { + fn default() -> Self { + Self::new() + } +} + +impl MemoryMultiColumnPermStep0_2 { + pub fn new() -> Self { + Self + } +} + +impl TransitionConstraint for MemoryMultiColumnPermStep0_2 { + fn degree(&self) -> usize { + 2 + } + + fn constraint_idx(&self) -> usize { + 43 + } + + fn evaluate( + &self, + frame: &Frame, + transition_evaluations: &mut [Felt252], + _periodic_values: &[Felt252], + rap_challenges: &[Felt252], + ) { + let current_step = frame.get_evaluation_step(0); + + let alpha = rap_challenges[0]; + let z = rap_challenges[1]; + let a3 = current_step.get_main_evaluation_element(0, 22); + let v3 = current_step.get_main_evaluation_element(0, 26); + + let p2 = current_step.get_aux_evaluation_element(0, 16); + let ap3 = current_step.get_aux_evaluation_element(0, 7); + let vp3 = current_step.get_aux_evaluation_element(0, 12); + let p3 = current_step.get_aux_evaluation_element(0, 17); + + transition_evaluations[self.constraint_idx()] = + (z - (ap3 + alpha * vp3)) * p3 - (z - (a3 + alpha * v3)) * p2; + } + + fn end_exemptions(&self) -> usize { + 0 + } +} + +pub struct MemoryMultiColumnPermStep0_3; +impl Default for MemoryMultiColumnPermStep0_3 { + fn default() -> Self { + Self::new() + } +} + +impl MemoryMultiColumnPermStep0_3 { + pub fn new() -> Self { + Self + } +} + +impl TransitionConstraint for MemoryMultiColumnPermStep0_3 { + fn degree(&self) -> usize { + 2 + } + + fn constraint_idx(&self) -> usize { + 44 + } + + fn evaluate( + &self, + frame: &Frame, + transition_evaluations: &mut [Felt252], + _periodic_values: &[Felt252], + rap_challenges: &[Felt252], + ) { + let current_step = frame.get_evaluation_step(0); + + let alpha = rap_challenges[0]; + let z = rap_challenges[1]; + let a4 = current_step.get_main_evaluation_element(0, 33); + let v4 = current_step.get_main_evaluation_element(0, 34); + + let p3 = current_step.get_aux_evaluation_element(0, 17); + let p4 = current_step.get_aux_evaluation_element(0, 18); + let ap4 = current_step.get_aux_evaluation_element(0, 8); + let vp4 = current_step.get_aux_evaluation_element(0, 13); + + transition_evaluations[self.constraint_idx()] = + (z - (ap4 + alpha * vp4)) * p4 - (z - (a4 + alpha * v4)) * p3; + } + + fn end_exemptions(&self) -> usize { + 0 + } +} + +pub struct MemoryMultiColumnPermStep0_4; +impl Default for MemoryMultiColumnPermStep0_4 { + fn default() -> Self { + Self::new() + } +} + +impl MemoryMultiColumnPermStep0_4 { + pub fn new() -> Self { + Self + } +} + +impl TransitionConstraint for MemoryMultiColumnPermStep0_4 { + fn degree(&self) -> usize { + 2 + } + + fn constraint_idx(&self) -> usize { + 45 + } + + fn evaluate( + &self, + frame: &Frame, + transition_evaluations: &mut [Felt252], + _periodic_values: &[Felt252], + rap_challenges: &[Felt252], + ) { + let current_step = frame.get_evaluation_step(0); + let next_step = frame.get_evaluation_step(1); + + let alpha = rap_challenges[0]; + let z = rap_challenges[1]; + let next_a0 = next_step.get_main_evaluation_element(0, 19); + let next_v0 = next_step.get_main_evaluation_element(0, 23); + + let next_ap0 = next_step.get_aux_evaluation_element(0, 4); + let next_vp0 = next_step.get_aux_evaluation_element(0, 9); + let next_p0 = next_step.get_aux_evaluation_element(0, 14); + let p4 = current_step.get_aux_evaluation_element(0, 18); + + transition_evaluations[self.constraint_idx()] = + (z - (next_ap0 + alpha * next_vp0)) * next_p0 - (z - (next_a0 + alpha * next_v0)) * p4; + } + + fn end_exemptions(&self) -> usize { + 1 + } +} + +// rc16/diff_is_bit +pub struct Rc16DiffIsBit0; +impl Default for Rc16DiffIsBit0 { + fn default() -> Self { + Self::new() + } +} + +impl Rc16DiffIsBit0 { + pub fn new() -> Self { + Self + } +} + +impl TransitionConstraint for Rc16DiffIsBit0 { + fn degree(&self) -> usize { + 2 + } + + fn constraint_idx(&self) -> usize { + 46 + } + + fn evaluate( + &self, + frame: &Frame, + transition_evaluations: &mut [Felt252], + _periodic_values: &[Felt252], + _rap_challenges: &[Felt252], + ) { + let current_step = frame.get_evaluation_step(0); + let one = Felt252::one(); + + let rc_col_1 = current_step.get_aux_evaluation_element(0, 0); + let rc_col_2 = current_step.get_aux_evaluation_element(0, 1); + + transition_evaluations[self.constraint_idx()] = + (rc_col_1 - rc_col_2) * (rc_col_2 - rc_col_1 - one); + } + + fn end_exemptions(&self) -> usize { + 0 + } +} + +pub struct Rc16DiffIsBit1; +impl Default for Rc16DiffIsBit1 { + fn default() -> Self { + Self::new() + } +} + +impl Rc16DiffIsBit1 { + pub fn new() -> Self { + Self + } +} + +impl TransitionConstraint for Rc16DiffIsBit1 { + fn degree(&self) -> usize { + 2 + } + + fn constraint_idx(&self) -> usize { + 47 + } + + fn evaluate( + &self, + frame: &Frame, + transition_evaluations: &mut [Felt252], + _periodic_values: &[Felt252], + _rap_challenges: &[Felt252], + ) { + let current_step = frame.get_evaluation_step(0); + let one = Felt252::one(); + + let rc_col_2 = current_step.get_aux_evaluation_element(0, 1); + let rc_col_3 = current_step.get_aux_evaluation_element(0, 2); + + transition_evaluations[self.constraint_idx()] = + (rc_col_2 - rc_col_3) * (rc_col_3 - rc_col_2 - one); + } + + fn end_exemptions(&self) -> usize { + 0 + } +} + +pub struct Rc16DiffIsBit2; +impl Default for Rc16DiffIsBit2 { + fn default() -> Self { + Self::new() + } +} + +impl Rc16DiffIsBit2 { + pub fn new() -> Self { + Self + } +} + +impl TransitionConstraint for Rc16DiffIsBit2 { + fn degree(&self) -> usize { + 2 + } + + fn constraint_idx(&self) -> usize { + 48 + } + + fn evaluate( + &self, + frame: &Frame, + transition_evaluations: &mut [Felt252], + _periodic_values: &[Felt252], + _rap_challenges: &[Felt252], + ) { + let current_step = frame.get_evaluation_step(0); + let one = Felt252::one(); + + let rc_col_3 = current_step.get_aux_evaluation_element(0, 2); + let rc_col_4 = current_step.get_aux_evaluation_element(0, 3); + + transition_evaluations[self.constraint_idx()] = + (rc_col_3 - rc_col_4) * (rc_col_4 - rc_col_3 - one); + } + + fn end_exemptions(&self) -> usize { + 0 + } +} + +pub struct Rc16DiffIsBit3; +impl Default for Rc16DiffIsBit3 { + fn default() -> Self { + Self::new() + } +} + +impl Rc16DiffIsBit3 { + pub fn new() -> Self { + Self + } +} + +impl TransitionConstraint for Rc16DiffIsBit3 { + fn degree(&self) -> usize { + 2 + } + + fn constraint_idx(&self) -> usize { + 49 + } + + fn evaluate( + &self, + frame: &Frame, + transition_evaluations: &mut [Felt252], + _periodic_values: &[Felt252], + _rap_challenges: &[Felt252], + ) { + let current_step = frame.get_evaluation_step(0); + let next_step = frame.get_evaluation_step(1); + let one = Felt252::one(); + + let rc_col_4 = current_step.get_aux_evaluation_element(0, 3); + let next_rc_col_1 = next_step.get_aux_evaluation_element(0, 0); + + transition_evaluations[self.constraint_idx()] = + (rc_col_4 - next_rc_col_1) * (next_rc_col_1 - rc_col_4 - one); + } + + fn end_exemptions(&self) -> usize { + 1 + } +} + +// rc16/perm/step0 +pub struct Rc16PermStep0_0; +impl Default for Rc16PermStep0_0 { + fn default() -> Self { + Self::new() + } +} + +impl Rc16PermStep0_0 { + pub fn new() -> Self { + Self + } +} + +impl TransitionConstraint for Rc16PermStep0_0 { + fn degree(&self) -> usize { + 2 + } + + fn constraint_idx(&self) -> usize { + 50 + } + + fn evaluate( + &self, + frame: &Frame, + transition_evaluations: &mut [Felt252], + _periodic_values: &[Felt252], + rap_challenges: &[Felt252], + ) { + let current_step = frame.get_evaluation_step(0); + + let z = rap_challenges[2]; + let a1 = current_step.get_main_evaluation_element(0, 28); + + let ap1 = current_step.get_aux_evaluation_element(0, 1); + let p1 = current_step.get_aux_evaluation_element(0, 20); + let p0 = current_step.get_aux_evaluation_element(0, 19); + + transition_evaluations[self.constraint_idx()] = (z - ap1) * p1 - (z - a1) * p0; + } + + fn end_exemptions(&self) -> usize { + 0 + } +} + +pub struct Rc16PermStep0_1; +impl Default for Rc16PermStep0_1 { + fn default() -> Self { + Self::new() + } +} + +impl Rc16PermStep0_1 { + pub fn new() -> Self { + Self + } +} + +impl TransitionConstraint for Rc16PermStep0_1 { + fn degree(&self) -> usize { + 2 + } + + fn constraint_idx(&self) -> usize { + 51 + } + + fn evaluate( + &self, + frame: &Frame, + transition_evaluations: &mut [Felt252], + _periodic_values: &[Felt252], + rap_challenges: &[Felt252], + ) { + let current_step = frame.get_evaluation_step(0); + + let z = rap_challenges[2]; + + let a2 = current_step.get_main_evaluation_element(0, 29); + + let ap2 = current_step.get_aux_evaluation_element(0, 2); + let p2 = current_step.get_aux_evaluation_element(0, 21); + let p1 = current_step.get_aux_evaluation_element(0, 20); + + transition_evaluations[self.constraint_idx()] = (z - ap2) * p2 - (z - a2) * p1; + } + + fn end_exemptions(&self) -> usize { + 0 + } +} + +pub struct Rc16PermStep0_2; +impl Default for Rc16PermStep0_2 { + fn default() -> Self { + Self::new() + } +} + +impl Rc16PermStep0_2 { + pub fn new() -> Self { + Self + } +} + +impl TransitionConstraint for Rc16PermStep0_2 { + fn degree(&self) -> usize { + 2 + } + + fn constraint_idx(&self) -> usize { + 52 + } + + fn evaluate( + &self, + frame: &Frame, + transition_evaluations: &mut [Felt252], + _periodic_values: &[Felt252], + rap_challenges: &[Felt252], + ) { + let current_step = frame.get_evaluation_step(0); + + let z = rap_challenges[2]; + let a3 = current_step.get_main_evaluation_element(0, 35); + + let ap3 = current_step.get_aux_evaluation_element(0, 3); + let p3 = current_step.get_aux_evaluation_element(0, 22); + let p2 = current_step.get_aux_evaluation_element(0, 21); + + transition_evaluations[self.constraint_idx()] = (z - ap3) * p3 - (z - a3) * p2; + } + + fn end_exemptions(&self) -> usize { + 0 + } +} + +pub struct Rc16PermStep0_3; +impl Default for Rc16PermStep0_3 { + fn default() -> Self { + Self::new() + } +} + +impl Rc16PermStep0_3 { + pub fn new() -> Self { + Self + } +} + +impl TransitionConstraint for Rc16PermStep0_3 { + fn degree(&self) -> usize { + 2 + } + + fn constraint_idx(&self) -> usize { + 53 + } + + fn evaluate( + &self, + frame: &Frame, + transition_evaluations: &mut [Felt252], + _periodic_values: &[Felt252], + rap_challenges: &[Felt252], + ) { + let current_step = frame.get_evaluation_step(0); + let next_step = frame.get_evaluation_step(1); + + let z = rap_challenges[2]; + + let p3 = current_step.get_aux_evaluation_element(0, 22); + + let next_a0 = next_step.get_main_evaluation_element(0, 27); + let next_ap0 = next_step.get_aux_evaluation_element(0, 0); + + let next_p0 = next_step.get_aux_evaluation_element(0, 19); + + transition_evaluations[self.constraint_idx()] = + (z - next_ap0) * next_p0 - (z - next_a0) * p3; + } + + fn end_exemptions(&self) -> usize { + 1 + } +} + +fn frame_inst_size(step: &TableView) -> Felt252 { + let op1_val = step.get_main_evaluation_element(0, 2) + - Felt252::from(2) * step.get_main_evaluation_element(0, 3); + op1_val + Felt252::one() +} diff --git a/provers/cairo/tests/wasm.rs b/provers/cairo/tests/wasm.rs index 0fd44a5e9..0e820a4e8 100644 --- a/provers/cairo/tests/wasm.rs +++ b/provers/cairo/tests/wasm.rs @@ -19,1222 +19,1220 @@ fn test_prove_cairo1_program_wasm() { // Test case is fibo5, with default test options #[cfg(feature = "wasm")] -static PROOF: [u8; 25531] = [ - 193, 90, 0, 0, 64, 34, 150, 252, 123, 41, 36, 58, 219, 76, 25, 24, 145, 52, 128, 169, 121, 212, +static PROOF: [u8; 25527] = [ + 189, 90, 0, 0, 64, 34, 150, 252, 123, 41, 36, 58, 219, 76, 25, 24, 145, 52, 128, 169, 121, 212, 127, 31, 128, 230, 237, 60, 212, 165, 171, 81, 190, 191, 157, 241, 200, 1, 77, 31, 232, 212, 215, 170, 34, 124, 137, 195, 171, 208, 228, 24, 74, 34, 237, 107, 135, 106, 205, 168, 33, 72, - 193, 202, 8, 15, 250, 12, 38, 185, 72, 32, 4, 171, 46, 46, 72, 149, 150, 106, 253, 54, 138, 21, - 229, 36, 56, 120, 99, 238, 141, 157, 240, 156, 48, 237, 33, 19, 160, 95, 129, 156, 230, 103, - 32, 5, 92, 56, 221, 221, 174, 163, 72, 227, 62, 104, 105, 67, 88, 2, 1, 167, 128, 234, 197, 5, - 19, 84, 237, 187, 255, 26, 202, 199, 198, 212, 123, 32, 6, 179, 252, 250, 97, 234, 175, 28, - 235, 179, 10, 3, 105, 223, 144, 217, 123, 180, 69, 201, 228, 37, 168, 76, 160, 177, 251, 61, 4, - 188, 206, 150, 32, 4, 35, 76, 126, 184, 197, 8, 44, 216, 227, 61, 246, 83, 23, 174, 189, 38, - 10, 238, 119, 48, 144, 139, 151, 205, 240, 162, 170, 38, 69, 32, 218, 32, 0, 78, 185, 188, 8, - 218, 190, 3, 120, 130, 120, 175, 57, 130, 249, 75, 60, 8, 193, 5, 209, 215, 185, 84, 20, 152, - 161, 136, 29, 105, 202, 146, 32, 1, 32, 251, 95, 208, 37, 117, 134, 77, 38, 169, 174, 238, 162, - 116, 104, 140, 208, 75, 38, 112, 222, 177, 176, 95, 20, 91, 133, 96, 134, 241, 165, 32, 5, 58, - 73, 111, 62, 133, 211, 177, 161, 47, 249, 216, 236, 145, 223, 222, 0, 208, 194, 218, 24, 115, - 204, 219, 46, 122, 185, 109, 97, 142, 6, 157, 32, 6, 157, 36, 183, 159, 66, 233, 225, 80, 151, - 252, 236, 118, 72, 239, 239, 0, 104, 97, 109, 12, 57, 230, 109, 151, 61, 92, 182, 176, 199, 3, - 79, 32, 1, 112, 61, 72, 192, 28, 241, 170, 208, 254, 139, 231, 7, 209, 54, 27, 192, 145, 224, - 147, 87, 46, 129, 150, 250, 105, 17, 146, 120, 238, 160, 242, 32, 6, 171, 57, 209, 156, 186, - 18, 81, 248, 81, 70, 231, 108, 187, 34, 194, 209, 111, 66, 41, 165, 196, 44, 203, 185, 199, 88, - 119, 146, 115, 47, 134, 32, 3, 253, 112, 171, 215, 178, 72, 192, 87, 190, 133, 240, 187, 7, - 161, 188, 230, 12, 255, 184, 120, 26, 25, 36, 123, 72, 169, 168, 139, 153, 157, 59, 32, 4, 66, - 223, 179, 251, 173, 74, 78, 2, 84, 31, 166, 43, 236, 208, 150, 145, 194, 243, 10, 118, 191, - 206, 20, 156, 165, 1, 69, 115, 4, 199, 206, 32, 7, 139, 31, 61, 86, 188, 154, 191, 165, 215, - 226, 86, 162, 70, 214, 134, 187, 31, 125, 208, 216, 59, 183, 54, 16, 82, 52, 237, 240, 126, 50, - 223, 32, 7, 191, 175, 19, 56, 74, 241, 8, 88, 216, 27, 92, 136, 239, 219, 106, 181, 155, 238, - 129, 10, 129, 221, 197, 69, 118, 172, 159, 87, 101, 181, 40, 32, 6, 1, 130, 118, 140, 160, 245, - 70, 213, 30, 155, 31, 17, 36, 171, 217, 155, 43, 167, 29, 86, 82, 125, 66, 209, 133, 185, 134, - 204, 61, 249, 223, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 32, 5, 5, 77, 210, 22, 240, 224, 140, 52, 197, 169, 11, 160, 21, 13, - 55, 239, 229, 66, 219, 125, 182, 6, 36, 172, 145, 58, 153, 209, 202, 52, 114, 32, 0, 148, 26, - 6, 89, 195, 227, 119, 6, 167, 12, 169, 231, 161, 188, 192, 231, 34, 181, 72, 158, 226, 167, - 181, 10, 160, 173, 188, 242, 236, 219, 152, 32, 0, 228, 51, 150, 138, 23, 240, 58, 239, 11, 11, - 49, 205, 232, 207, 77, 226, 183, 230, 217, 57, 64, 109, 196, 12, 39, 85, 255, 237, 18, 85, 193, - 32, 6, 85, 4, 87, 121, 137, 197, 38, 112, 136, 27, 230, 225, 169, 48, 102, 5, 84, 136, 250, 71, - 223, 219, 186, 104, 60, 135, 3, 128, 62, 106, 45, 32, 7, 56, 179, 166, 236, 231, 225, 176, 54, - 191, 5, 110, 209, 16, 229, 236, 73, 110, 41, 50, 90, 219, 209, 125, 93, 79, 197, 186, 92, 170, - 49, 219, 32, 3, 10, 93, 160, 62, 131, 106, 88, 66, 230, 41, 206, 250, 29, 161, 133, 102, 106, - 249, 221, 8, 97, 108, 255, 63, 67, 47, 168, 171, 220, 106, 41, 32, 0, 139, 66, 37, 71, 31, 54, - 72, 41, 206, 95, 73, 251, 212, 195, 255, 11, 100, 97, 24, 153, 43, 0, 48, 38, 167, 83, 93, 94, - 34, 210, 250, 32, 5, 109, 143, 37, 8, 2, 69, 20, 0, 152, 119, 96, 22, 198, 72, 166, 96, 100, - 110, 176, 22, 243, 142, 119, 221, 147, 218, 103, 40, 35, 46, 125, 32, 4, 188, 184, 9, 251, 140, - 5, 113, 122, 209, 130, 111, 194, 127, 208, 115, 60, 123, 105, 88, 5, 7, 234, 212, 115, 83, 139, - 114, 75, 218, 7, 70, 32, 1, 227, 195, 188, 203, 231, 139, 5, 12, 254, 39, 124, 95, 116, 106, - 12, 10, 179, 28, 165, 161, 182, 30, 11, 214, 138, 148, 228, 179, 58, 162, 36, 32, 5, 62, 149, - 75, 155, 0, 72, 204, 169, 3, 6, 65, 123, 194, 43, 245, 19, 54, 172, 21, 95, 53, 55, 148, 127, - 95, 27, 64, 184, 193, 216, 120, 32, 4, 27, 7, 54, 57, 150, 199, 162, 106, 136, 171, 108, 35, - 200, 0, 240, 225, 124, 114, 127, 192, 131, 131, 14, 216, 142, 47, 58, 30, 65, 127, 55, 32, 1, - 148, 91, 227, 154, 152, 80, 25, 52, 55, 158, 182, 187, 14, 180, 170, 20, 138, 197, 24, 175, - 230, 9, 219, 122, 144, 144, 61, 108, 215, 189, 250, 32, 7, 114, 120, 91, 223, 13, 219, 241, - 233, 217, 192, 111, 190, 224, 172, 246, 176, 182, 66, 142, 136, 226, 43, 54, 172, 53, 15, 59, - 142, 97, 211, 188, 32, 2, 132, 57, 150, 70, 49, 1, 8, 234, 246, 45, 249, 78, 230, 149, 128, - 150, 96, 213, 213, 11, 99, 63, 254, 93, 43, 187, 22, 231, 60, 154, 36, 32, 3, 63, 223, 107, 43, - 58, 72, 137, 1, 117, 86, 227, 189, 56, 81, 54, 68, 42, 58, 135, 219, 191, 103, 9, 82, 207, 206, - 34, 151, 38, 200, 153, 32, 1, 238, 242, 213, 113, 252, 6, 128, 90, 154, 103, 235, 16, 227, 37, - 91, 202, 212, 170, 172, 81, 1, 10, 69, 89, 136, 49, 193, 130, 176, 239, 60, 32, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 7, - 255, 255, 255, 254, 239, 253, 240, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 239, 255, 225, 32, 5, 164, 73, 93, 67, 178, 117, - 132, 236, 197, 104, 163, 216, 184, 202, 92, 66, 199, 96, 214, 233, 218, 106, 44, 172, 235, 112, - 136, 66, 249, 90, 126, 32, 3, 216, 209, 48, 53, 210, 164, 231, 47, 146, 117, 140, 11, 65, 169, - 131, 250, 39, 109, 15, 216, 66, 25, 51, 242, 199, 136, 251, 208, 55, 7, 38, 32, 0, 28, 192, - 139, 158, 30, 114, 208, 27, 253, 203, 86, 73, 93, 185, 133, 138, 151, 159, 169, 44, 150, 149, - 137, 211, 84, 61, 186, 3, 10, 45, 127, 32, 7, 151, 176, 122, 197, 209, 248, 208, 207, 146, 225, - 176, 196, 201, 153, 23, 74, 153, 165, 107, 70, 98, 205, 161, 122, 185, 108, 196, 218, 16, 169, - 168, 32, 3, 137, 111, 149, 102, 153, 147, 0, 104, 36, 138, 100, 191, 144, 237, 41, 233, 209, - 213, 131, 135, 16, 234, 103, 148, 243, 231, 86, 220, 198, 217, 201, 32, 2, 125, 208, 61, 184, - 217, 116, 160, 114, 35, 47, 160, 98, 129, 153, 162, 43, 22, 18, 93, 47, 145, 110, 192, 97, 211, - 116, 207, 38, 25, 85, 24, 32, 4, 152, 150, 235, 18, 135, 172, 152, 201, 60, 89, 181, 164, 133, - 155, 248, 226, 65, 214, 142, 49, 219, 216, 225, 220, 73, 222, 23, 153, 75, 82, 156, 32, 2, 76, - 75, 117, 137, 67, 214, 76, 100, 158, 44, 218, 210, 66, 205, 252, 113, 32, 235, 71, 24, 237, - 236, 112, 238, 36, 239, 11, 204, 165, 169, 78, 32, 6, 175, 201, 40, 59, 171, 43, 36, 172, 136, - 108, 255, 100, 80, 227, 10, 174, 193, 212, 112, 189, 11, 125, 254, 168, 172, 28, 240, 125, 57, - 253, 45, 32, 1, 255, 183, 117, 104, 114, 177, 68, 60, 194, 230, 255, 45, 181, 89, 233, 102, 27, - 100, 223, 222, 254, 63, 101, 162, 246, 68, 126, 58, 217, 87, 79, 32, 0, 114, 182, 113, 16, 115, - 168, 121, 94, 190, 154, 99, 70, 138, 167, 215, 132, 181, 223, 136, 147, 14, 148, 170, 167, 159, - 29, 60, 250, 92, 24, 190, 32, 7, 107, 94, 193, 123, 29, 115, 158, 67, 69, 79, 230, 88, 1, 84, - 42, 183, 6, 188, 186, 23, 202, 40, 94, 191, 211, 15, 171, 160, 230, 206, 22, 32, 4, 236, 198, - 161, 176, 103, 140, 241, 199, 93, 76, 39, 115, 254, 213, 231, 156, 64, 243, 38, 213, 147, 204, - 53, 0, 133, 24, 170, 120, 158, 49, 121, 32, 0, 70, 11, 93, 84, 254, 167, 35, 223, 122, 21, 131, - 118, 66, 134, 48, 64, 156, 144, 114, 42, 84, 93, 42, 166, 82, 19, 25, 33, 96, 110, 224, 32, 5, - 172, 169, 28, 33, 136, 147, 144, 105, 246, 97, 83, 182, 80, 191, 36, 150, 127, 167, 6, 69, 190, - 182, 91, 132, 194, 174, 247, 39, 151, 95, 246, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 3, 76, 211, 160, 97, 229, 52, 131, 185, - 195, 236, 105, 209, 142, 248, 93, 71, 33, 48, 49, 104, 170, 92, 146, 98, 174, 83, 1, 102, 205, - 200, 192, 32, 7, 21, 81, 39, 117, 159, 244, 252, 181, 175, 145, 237, 1, 23, 50, 219, 46, 206, - 97, 51, 195, 250, 165, 147, 122, 124, 78, 133, 234, 165, 212, 70, 32, 2, 178, 201, 123, 52, - 117, 122, 50, 239, 44, 197, 75, 38, 69, 125, 242, 79, 142, 17, 155, 233, 154, 65, 23, 28, 123, - 55, 181, 160, 88, 161, 235, 32, 2, 97, 38, 117, 200, 21, 124, 210, 53, 130, 17, 191, 250, 34, - 14, 52, 151, 68, 138, 131, 98, 249, 199, 148, 80, 56, 252, 154, 65, 213, 27, 192, 32, 0, 205, - 164, 83, 227, 233, 193, 236, 210, 30, 88, 170, 213, 13, 56, 163, 215, 160, 26, 150, 23, 215, - 32, 252, 71, 100, 125, 180, 18, 148, 175, 39, 32, 3, 45, 95, 106, 195, 89, 219, 152, 25, 57, - 128, 134, 236, 220, 170, 22, 10, 97, 237, 14, 147, 217, 20, 174, 29, 230, 46, 245, 87, 63, 10, - 9, 32, 3, 134, 64, 23, 104, 88, 168, 156, 44, 38, 141, 172, 137, 24, 124, 147, 215, 125, 196, - 252, 194, 131, 105, 70, 62, 139, 23, 141, 214, 75, 34, 196, 32, 7, 93, 19, 92, 57, 51, 193, - 163, 234, 57, 245, 251, 103, 204, 240, 215, 231, 38, 72, 197, 247, 151, 71, 191, 130, 143, 88, - 241, 1, 100, 102, 217, 32, 5, 43, 151, 202, 64, 35, 38, 41, 169, 58, 219, 96, 206, 11, 117, - 119, 84, 93, 194, 67, 15, 2, 242, 147, 229, 149, 91, 222, 249, 92, 31, 92, 32, 2, 89, 7, 44, - 73, 97, 6, 224, 231, 0, 56, 130, 53, 184, 253, 76, 88, 187, 244, 246, 33, 102, 42, 19, 92, 201, - 250, 169, 85, 234, 251, 36, 32, 5, 37, 89, 172, 166, 123, 192, 20, 204, 113, 206, 178, 126, - 109, 201, 135, 209, 180, 221, 30, 30, 97, 167, 219, 101, 162, 44, 245, 229, 176, 105, 184, 32, - 2, 209, 51, 25, 126, 164, 89, 205, 178, 219, 33, 106, 172, 156, 85, 134, 204, 144, 26, 171, - 220, 244, 133, 64, 46, 109, 7, 155, 135, 3, 196, 98, 32, 7, 168, 92, 40, 141, 187, 183, 115, - 78, 146, 156, 15, 97, 150, 45, 64, 224, 150, 100, 243, 178, 163, 219, 179, 111, 162, 215, 107, - 86, 87, 182, 159, 32, 0, 132, 167, 145, 122, 234, 98, 222, 154, 156, 118, 163, 208, 243, 48, - 51, 45, 24, 208, 224, 75, 117, 206, 138, 206, 103, 15, 227, 34, 57, 175, 135, 32, 5, 239, 184, - 156, 216, 201, 229, 236, 146, 243, 183, 254, 196, 139, 157, 236, 157, 30, 48, 142, 221, 118, - 118, 234, 33, 60, 254, 67, 243, 214, 168, 130, 32, 0, 46, 216, 103, 55, 129, 154, 253, 255, - 113, 23, 89, 175, 255, 179, 132, 214, 206, 245, 7, 52, 120, 138, 66, 122, 184, 203, 113, 156, - 214, 90, 65, 32, 0, 73, 33, 6, 193, 9, 222, 195, 71, 225, 131, 170, 231, 144, 206, 14, 16, 158, - 154, 184, 162, 0, 249, 182, 49, 74, 153, 197, 210, 39, 218, 148, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 7, 255, 255, - 255, 254, 239, 253, 240, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 239, 255, 225, 36, 2, 46, 32, 2, 91, 68, 30, 167, 149, 38, - 118, 145, 95, 148, 62, 85, 145, 230, 53, 55, 130, 176, 244, 48, 67, 173, 42, 214, 141, 102, - 245, 187, 90, 230, 19, 32, 5, 34, 69, 70, 141, 13, 255, 133, 225, 104, 55, 188, 22, 185, 42, - 245, 181, 99, 180, 84, 29, 89, 106, 130, 235, 89, 220, 87, 144, 176, 77, 60, 32, 5, 34, 69, 70, - 141, 13, 255, 133, 225, 104, 55, 188, 22, 185, 42, 245, 181, 99, 180, 84, 29, 89, 106, 130, - 235, 89, 220, 87, 144, 176, 77, 60, 32, 5, 34, 69, 70, 141, 13, 255, 133, 225, 104, 55, 188, - 22, 185, 42, 245, 181, 99, 180, 84, 29, 89, 106, 130, 235, 89, 220, 87, 144, 176, 77, 60, 32, - 4, 172, 50, 234, 18, 80, 78, 10, 45, 122, 188, 84, 165, 217, 106, 152, 186, 208, 180, 33, 157, - 178, 199, 196, 247, 86, 102, 162, 254, 117, 30, 72, 32, 0, 181, 233, 160, 243, 50, 209, 135, - 128, 205, 250, 37, 164, 203, 220, 42, 145, 194, 139, 44, 213, 121, 80, 254, 184, 153, 32, 79, - 69, 57, 83, 216, 32, 6, 19, 23, 214, 231, 29, 95, 179, 150, 132, 169, 32, 196, 217, 91, 169, - 163, 124, 152, 184, 237, 143, 180, 231, 117, 152, 167, 123, 83, 209, 158, 147, 32, 6, 53, 28, - 103, 222, 115, 121, 45, 17, 1, 207, 189, 245, 123, 206, 196, 83, 65, 169, 108, 164, 89, 160, - 91, 82, 95, 127, 247, 39, 181, 34, 110, 32, 3, 31, 236, 182, 13, 15, 107, 36, 19, 38, 250, 71, - 179, 208, 136, 106, 154, 173, 227, 31, 17, 152, 79, 12, 144, 63, 104, 61, 227, 164, 31, 228, - 32, 1, 159, 112, 153, 196, 243, 158, 187, 254, 28, 60, 241, 46, 105, 131, 157, 200, 26, 27, - 122, 61, 228, 124, 189, 29, 242, 143, 79, 146, 139, 250, 153, 32, 6, 193, 59, 12, 1, 213, 95, - 240, 123, 204, 211, 89, 91, 2, 87, 245, 137, 143, 166, 33, 52, 104, 219, 164, 137, 65, 209, 54, - 190, 218, 216, 212, 32, 3, 229, 249, 197, 153, 170, 217, 112, 20, 238, 233, 2, 174, 64, 10, - 149, 156, 93, 238, 183, 26, 131, 97, 252, 235, 129, 71, 6, 23, 175, 79, 173, 32, 6, 253, 237, - 190, 189, 104, 8, 118, 156, 19, 217, 149, 238, 165, 120, 5, 142, 216, 5, 93, 213, 251, 77, 5, - 153, 131, 157, 90, 222, 105, 122, 120, 32, 2, 129, 96, 22, 155, 203, 11, 182, 232, 185, 144, - 137, 252, 51, 123, 36, 247, 87, 64, 32, 96, 251, 255, 208, 25, 98, 57, 66, 175, 117, 176, 193, - 32, 3, 193, 122, 195, 109, 117, 12, 99, 231, 45, 239, 98, 138, 155, 65, 11, 130, 87, 253, 152, - 152, 204, 121, 224, 34, 239, 131, 187, 169, 165, 80, 147, 32, 4, 246, 117, 1, 253, 181, 210, - 144, 241, 105, 62, 229, 159, 173, 99, 208, 146, 160, 204, 225, 177, 13, 249, 172, 46, 189, 182, - 61, 154, 161, 37, 214, 32, 7, 204, 121, 1, 160, 97, 61, 117, 31, 237, 167, 240, 191, 56, 46, - 150, 73, 122, 206, 192, 102, 9, 94, 103, 110, 233, 248, 26, 236, 255, 132, 154, 32, 4, 137, - 131, 56, 170, 8, 125, 216, 70, 207, 87, 130, 132, 70, 1, 125, 242, 43, 121, 151, 176, 95, 112, - 189, 214, 242, 170, 214, 129, 55, 154, 128, 32, 4, 201, 114, 110, 175, 33, 250, 89, 22, 203, - 194, 137, 227, 107, 31, 82, 20, 62, 160, 204, 121, 71, 65, 18, 220, 240, 245, 105, 137, 65, - 104, 186, 32, 5, 73, 163, 150, 210, 209, 44, 45, 88, 147, 177, 140, 73, 245, 231, 52, 114, 8, - 113, 216, 127, 88, 253, 134, 215, 221, 35, 183, 71, 99, 55, 163, 32, 4, 183, 149, 133, 222, 16, - 181, 158, 187, 26, 112, 160, 13, 165, 89, 191, 175, 117, 135, 204, 186, 117, 164, 118, 218, - 181, 24, 248, 8, 182, 165, 181, 32, 5, 180, 94, 217, 181, 61, 240, 200, 208, 79, 68, 123, 238, - 236, 167, 131, 241, 128, 31, 247, 36, 252, 212, 75, 196, 240, 89, 232, 91, 20, 91, 209, 32, 4, - 44, 50, 77, 67, 251, 45, 217, 70, 42, 101, 206, 195, 184, 161, 10, 85, 151, 59, 51, 28, 208, - 81, 78, 247, 241, 88, 37, 195, 149, 151, 228, 32, 2, 97, 27, 155, 37, 146, 202, 43, 214, 62, - 62, 237, 12, 122, 139, 243, 242, 150, 242, 183, 49, 130, 122, 247, 48, 56, 106, 114, 143, 235, - 8, 79, 32, 2, 185, 124, 96, 183, 155, 14, 136, 208, 75, 114, 37, 245, 191, 178, 178, 63, 111, - 67, 60, 28, 27, 238, 221, 224, 240, 253, 47, 91, 239, 13, 179, 32, 2, 185, 124, 96, 183, 155, - 14, 136, 208, 75, 114, 37, 245, 191, 178, 178, 63, 111, 67, 60, 28, 27, 238, 221, 224, 240, - 253, 47, 91, 239, 13, 179, 32, 2, 185, 124, 96, 183, 155, 14, 136, 208, 75, 114, 37, 245, 191, - 178, 178, 63, 111, 67, 60, 28, 27, 238, 221, 224, 240, 253, 47, 91, 239, 13, 179, 32, 3, 81, - 15, 195, 103, 39, 66, 162, 136, 92, 92, 14, 153, 166, 21, 71, 131, 158, 181, 10, 33, 207, 138, - 191, 11, 61, 159, 8, 59, 196, 116, 206, 32, 6, 92, 174, 186, 3, 163, 232, 46, 142, 159, 231, - 236, 199, 52, 201, 253, 94, 196, 194, 27, 170, 65, 56, 3, 235, 54, 159, 71, 74, 224, 145, 194, - 32, 7, 37, 192, 191, 55, 232, 222, 163, 133, 119, 204, 154, 2, 252, 68, 204, 127, 35, 115, 18, - 255, 101, 92, 159, 113, 38, 148, 11, 88, 14, 188, 24, 32, 1, 185, 157, 208, 201, 232, 187, 167, - 69, 41, 191, 112, 20, 178, 90, 158, 106, 103, 187, 169, 152, 209, 138, 82, 222, 48, 151, 43, - 211, 122, 139, 62, 32, 0, 82, 151, 15, 254, 101, 72, 162, 180, 25, 122, 196, 91, 240, 198, 230, - 133, 210, 171, 61, 168, 31, 207, 166, 62, 126, 137, 58, 58, 215, 89, 196, 32, 7, 243, 45, 235, - 180, 10, 147, 108, 102, 148, 41, 190, 1, 4, 246, 173, 38, 149, 22, 241, 244, 63, 151, 200, 36, - 150, 99, 141, 148, 213, 170, 198, 32, 3, 127, 184, 40, 17, 194, 24, 186, 31, 167, 103, 162, - 171, 234, 52, 191, 197, 201, 175, 217, 230, 31, 216, 93, 227, 79, 185, 7, 14, 166, 193, 138, - 32, 5, 198, 163, 129, 217, 40, 49, 109, 212, 20, 113, 205, 18, 187, 6, 2, 41, 105, 178, 32, - 112, 127, 81, 84, 120, 159, 217, 95, 160, 16, 1, 38, 32, 0, 214, 196, 180, 99, 92, 89, 104, - 164, 35, 27, 6, 129, 63, 210, 196, 204, 72, 210, 247, 189, 173, 49, 236, 125, 2, 169, 73, 236, - 99, 59, 143, 32, 6, 118, 23, 240, 120, 81, 48, 50, 12, 164, 136, 237, 115, 2, 142, 1, 195, 49, - 183, 32, 18, 172, 59, 8, 81, 8, 54, 22, 129, 174, 149, 208, 32, 5, 235, 69, 63, 4, 2, 112, 82, - 71, 244, 130, 29, 243, 60, 199, 50, 242, 167, 231, 155, 160, 192, 217, 62, 149, 60, 73, 211, - 184, 175, 27, 199, 32, 4, 149, 42, 108, 215, 143, 62, 251, 86, 44, 43, 206, 24, 25, 153, 123, - 152, 228, 253, 246, 39, 29, 119, 101, 65, 112, 255, 188, 65, 104, 178, 152, 32, 1, 11, 198, - 183, 72, 20, 94, 168, 158, 4, 35, 255, 90, 48, 115, 225, 132, 79, 198, 112, 81, 250, 150, 205, - 240, 253, 74, 111, 40, 244, 118, 132, 32, 4, 34, 127, 238, 138, 239, 252, 226, 9, 107, 68, 128, - 80, 62, 242, 72, 177, 253, 112, 233, 34, 77, 129, 230, 247, 131, 60, 168, 117, 37, 255, 47, 32, - 1, 28, 189, 19, 230, 215, 229, 105, 97, 221, 162, 156, 153, 44, 128, 199, 191, 82, 91, 140, - 143, 108, 204, 195, 58, 240, 115, 225, 147, 155, 56, 110, 32, 0, 57, 219, 152, 51, 97, 31, 231, - 165, 105, 11, 92, 33, 44, 44, 210, 231, 255, 254, 124, 211, 208, 61, 253, 82, 136, 246, 114, - 193, 58, 71, 189, 32, 7, 89, 87, 211, 70, 169, 55, 121, 167, 147, 202, 221, 211, 140, 161, 36, - 161, 129, 74, 133, 100, 113, 62, 104, 54, 249, 65, 156, 152, 203, 181, 174, 32, 7, 10, 198, 8, - 71, 203, 123, 22, 215, 252, 95, 209, 228, 106, 1, 250, 148, 203, 149, 7, 35, 101, 250, 210, - 186, 174, 64, 246, 179, 223, 66, 30, 32, 5, 242, 65, 116, 15, 209, 144, 160, 137, 244, 39, 200, - 223, 20, 127, 84, 108, 194, 233, 203, 81, 191, 36, 35, 67, 165, 197, 81, 185, 130, 37, 193, 23, - 2, 1, 109, 191, 15, 222, 88, 251, 175, 15, 246, 130, 107, 105, 199, 118, 215, 241, 134, 76, - 221, 63, 47, 49, 81, 45, 0, 176, 60, 72, 117, 236, 249, 84, 2, 32, 3, 48, 127, 250, 48, 148, - 100, 159, 213, 218, 177, 58, 105, 139, 239, 218, 169, 185, 129, 164, 21, 88, 237, 88, 82, 191, - 111, 215, 137, 76, 223, 150, 32, 6, 16, 251, 113, 251, 35, 236, 142, 170, 88, 82, 203, 6, 0, - 233, 114, 105, 131, 238, 92, 207, 172, 58, 109, 219, 24, 246, 118, 55, 208, 230, 78, 5, 82, - 112, 121, 238, 185, 141, 1, 80, 168, 186, 34, 154, 225, 245, 139, 2, 123, 218, 190, 111, 15, - 255, 121, 41, 116, 227, 152, 42, 33, 168, 14, 1, 91, 35, 62, 84, 79, 132, 71, 170, 171, 23, - 112, 214, 190, 237, 191, 69, 250, 105, 10, 169, 108, 130, 87, 63, 201, 38, 178, 114, 139, 43, - 91, 113, 197, 141, 75, 213, 227, 174, 88, 250, 176, 106, 37, 76, 216, 107, 19, 138, 88, 156, - 239, 72, 27, 21, 218, 19, 60, 112, 156, 230, 158, 109, 190, 37, 168, 189, 205, 25, 14, 92, 102, - 145, 190, 239, 54, 179, 10, 15, 6, 103, 175, 66, 228, 134, 136, 118, 9, 64, 139, 92, 75, 55, - 96, 218, 229, 124, 227, 68, 31, 40, 194, 252, 219, 96, 27, 0, 152, 179, 217, 227, 210, 255, 77, - 23, 81, 166, 105, 218, 253, 13, 104, 220, 10, 192, 184, 18, 0, 193, 32, 1, 104, 12, 185, 205, - 138, 208, 244, 253, 33, 222, 248, 187, 128, 233, 27, 56, 12, 110, 239, 76, 137, 124, 240, 234, - 232, 103, 31, 240, 100, 98, 53, 3, 5, 6, 115, 121, 6, 85, 176, 150, 169, 85, 8, 57, 5, 144, - 154, 23, 153, 192, 202, 71, 43, 105, 225, 171, 19, 208, 87, 5, 6, 31, 239, 175, 229, 64, 33, - 47, 206, 7, 162, 188, 218, 42, 204, 87, 160, 251, 213, 62, 180, 7, 121, 99, 0, 211, 63, 30, - 254, 106, 31, 176, 41, 25, 175, 80, 100, 190, 111, 88, 75, 217, 188, 235, 191, 225, 117, 197, - 67, 219, 63, 231, 94, 69, 23, 155, 115, 39, 126, 66, 230, 232, 97, 65, 196, 47, 174, 63, 3, - 102, 12, 170, 97, 193, 165, 130, 39, 228, 52, 78, 243, 4, 108, 238, 148, 139, 4, 138, 220, 22, - 151, 90, 245, 199, 228, 126, 112, 63, 238, 140, 3, 100, 141, 244, 146, 128, 230, 70, 232, 217, - 250, 154, 27, 231, 23, 163, 61, 230, 124, 50, 221, 102, 196, 17, 93, 22, 222, 37, 204, 3, 54, - 252, 116, 208, 45, 93, 164, 82, 210, 92, 91, 63, 69, 76, 186, 185, 17, 78, 26, 238, 81, 20, - 223, 109, 188, 216, 28, 7, 139, 13, 241, 111, 119, 115, 3, 223, 5, 138, 86, 3, 251, 12, 37, 26, - 26, 37, 229, 31, 77, 213, 196, 29, 94, 132, 241, 23, 42, 110, 8, 144, 8, 241, 120, 250, 91, - 227, 24, 59, 118, 27, 166, 110, 151, 252, 42, 38, 13, 148, 178, 163, 7, 86, 243, 206, 99, 51, - 45, 174, 176, 2, 176, 222, 79, 185, 46, 239, 213, 231, 110, 203, 243, 231, 144, 68, 128, 118, - 48, 62, 253, 17, 89, 151, 143, 22, 34, 87, 213, 31, 37, 220, 227, 16, 247, 190, 214, 150, 187, - 105, 125, 102, 15, 145, 3, 159, 192, 79, 117, 81, 131, 127, 69, 145, 20, 160, 108, 209, 65, 86, - 163, 214, 220, 48, 231, 113, 225, 26, 192, 222, 215, 102, 154, 77, 26, 184, 181, 230, 178, 31, - 28, 242, 118, 216, 199, 237, 31, 119, 2, 113, 240, 112, 172, 197, 210, 98, 201, 91, 235, 196, - 125, 20, 119, 2, 25, 24, 146, 211, 241, 4, 74, 100, 162, 210, 220, 234, 124, 46, 120, 142, 236, - 102, 152, 212, 37, 114, 126, 89, 239, 119, 17, 248, 231, 171, 61, 108, 232, 175, 196, 62, 194, - 69, 13, 46, 84, 234, 17, 3, 21, 46, 232, 96, 9, 70, 128, 36, 230, 16, 165, 191, 254, 148, 41, - 202, 229, 89, 212, 233, 141, 168, 174, 229, 140, 224, 81, 97, 29, 1, 23, 2, 22, 151, 247, 233, - 81, 79, 170, 158, 249, 229, 199, 81, 89, 200, 216, 145, 38, 153, 216, 65, 34, 219, 99, 193, - 248, 36, 23, 36, 129, 51, 155, 81, 170, 123, 1, 59, 160, 203, 139, 28, 197, 58, 211, 230, 37, - 31, 85, 193, 140, 119, 108, 130, 78, 25, 191, 43, 91, 161, 3, 0, 250, 166, 193, 194, 161, 166, - 73, 214, 204, 218, 13, 80, 76, 118, 250, 79, 222, 128, 150, 252, 245, 253, 158, 102, 27, 172, - 50, 192, 131, 192, 147, 28, 23, 189, 214, 38, 116, 4, 248, 192, 87, 143, 63, 134, 25, 6, 201, - 48, 121, 23, 233, 211, 162, 185, 219, 176, 27, 21, 61, 121, 58, 228, 60, 47, 126, 131, 56, 51, - 84, 132, 13, 81, 124, 22, 98, 17, 50, 110, 109, 59, 181, 109, 154, 84, 88, 60, 188, 0, 191, 64, - 46, 229, 182, 32, 20, 2, 74, 42, 18, 235, 9, 249, 64, 116, 65, 54, 67, 1, 118, 34, 236, 213, - 63, 88, 202, 131, 114, 138, 154, 105, 29, 58, 106, 66, 201, 200, 74, 150, 27, 149, 159, 90, - 213, 12, 112, 252, 64, 244, 104, 220, 50, 128, 113, 201, 104, 20, 107, 144, 30, 58, 28, 189, - 44, 89, 107, 176, 167, 113, 52, 250, 5, 32, 2, 78, 97, 121, 127, 238, 47, 119, 199, 15, 200, - 125, 16, 150, 254, 168, 168, 59, 109, 247, 150, 38, 227, 91, 124, 212, 64, 194, 25, 127, 188, - 125, 32, 0, 113, 249, 249, 255, 228, 13, 136, 153, 122, 192, 187, 56, 42, 197, 101, 118, 59, - 124, 61, 95, 37, 92, 208, 123, 153, 43, 38, 94, 210, 169, 139, 32, 6, 167, 37, 185, 208, 123, - 36, 223, 152, 196, 150, 147, 157, 29, 252, 246, 66, 97, 248, 67, 241, 28, 215, 27, 63, 0, 229, - 114, 99, 207, 95, 21, 32, 2, 112, 59, 63, 171, 54, 166, 178, 221, 202, 101, 39, 130, 200, 103, - 184, 44, 166, 220, 246, 108, 106, 76, 54, 33, 134, 47, 117, 48, 240, 255, 173, 32, 5, 196, 143, - 35, 233, 0, 32, 54, 82, 255, 118, 12, 30, 80, 201, 187, 151, 120, 176, 215, 146, 164, 12, 194, - 190, 166, 214, 43, 224, 224, 149, 217, 5, 6, 168, 38, 220, 25, 149, 71, 84, 129, 64, 73, 73, - 59, 140, 69, 111, 67, 195, 15, 178, 147, 177, 105, 84, 186, 79, 63, 194, 33, 85, 112, 1, 213, - 33, 47, 206, 7, 162, 188, 218, 42, 204, 87, 160, 251, 213, 62, 180, 7, 121, 99, 0, 211, 63, 30, - 254, 106, 31, 176, 41, 25, 175, 80, 100, 190, 111, 88, 75, 217, 188, 235, 191, 225, 117, 197, - 67, 219, 63, 231, 94, 69, 23, 155, 115, 39, 126, 66, 230, 232, 97, 65, 196, 47, 174, 63, 3, - 102, 12, 170, 97, 193, 165, 130, 39, 228, 52, 78, 243, 4, 108, 238, 148, 139, 4, 138, 220, 22, - 151, 90, 245, 199, 228, 126, 112, 63, 238, 140, 3, 100, 141, 244, 146, 128, 230, 70, 232, 217, - 250, 154, 27, 231, 23, 163, 61, 230, 124, 50, 221, 102, 196, 17, 93, 22, 222, 37, 204, 3, 54, - 252, 116, 208, 45, 93, 164, 82, 210, 92, 91, 63, 69, 76, 186, 185, 17, 78, 26, 238, 81, 20, - 223, 109, 188, 216, 28, 7, 139, 13, 241, 111, 119, 115, 3, 223, 5, 138, 86, 3, 251, 12, 37, 26, - 26, 37, 229, 31, 77, 213, 196, 29, 94, 132, 241, 23, 42, 110, 8, 144, 8, 241, 120, 250, 91, - 227, 24, 59, 118, 27, 166, 110, 151, 252, 42, 38, 13, 148, 178, 163, 7, 86, 243, 206, 99, 51, - 45, 174, 176, 2, 176, 222, 79, 185, 46, 239, 213, 231, 110, 203, 243, 231, 144, 68, 128, 118, - 48, 62, 253, 17, 89, 151, 143, 22, 34, 87, 213, 31, 37, 220, 227, 16, 247, 190, 214, 150, 187, - 105, 125, 102, 15, 145, 3, 159, 192, 79, 117, 81, 131, 127, 69, 145, 20, 160, 108, 209, 65, 86, - 163, 214, 220, 48, 231, 113, 225, 26, 192, 222, 215, 102, 154, 77, 26, 184, 181, 230, 178, 31, - 28, 242, 118, 216, 199, 237, 31, 119, 2, 113, 240, 112, 172, 197, 210, 98, 201, 91, 235, 196, - 125, 20, 119, 2, 25, 24, 146, 211, 241, 4, 74, 100, 162, 210, 220, 234, 124, 46, 120, 142, 236, - 102, 152, 212, 37, 114, 126, 89, 239, 119, 17, 248, 231, 171, 61, 108, 232, 175, 196, 62, 194, - 69, 13, 46, 84, 234, 17, 3, 21, 46, 232, 96, 9, 70, 128, 36, 230, 16, 165, 191, 254, 148, 41, - 202, 229, 89, 212, 233, 141, 168, 174, 229, 140, 224, 81, 97, 29, 1, 23, 2, 22, 151, 247, 233, - 81, 79, 170, 158, 249, 229, 199, 81, 89, 200, 216, 145, 38, 153, 216, 65, 34, 219, 99, 193, - 248, 36, 23, 36, 129, 51, 155, 81, 170, 123, 1, 59, 160, 203, 139, 28, 197, 58, 211, 230, 37, - 31, 85, 193, 140, 119, 108, 130, 78, 25, 191, 43, 91, 161, 3, 0, 250, 166, 193, 194, 161, 166, - 73, 214, 204, 218, 13, 80, 76, 118, 250, 79, 222, 128, 150, 252, 245, 253, 158, 102, 27, 172, - 50, 192, 131, 192, 147, 28, 23, 189, 214, 38, 116, 4, 248, 192, 87, 143, 63, 134, 25, 6, 201, - 48, 121, 23, 233, 211, 162, 185, 219, 176, 27, 21, 61, 121, 58, 228, 60, 47, 126, 131, 56, 51, - 84, 132, 13, 81, 124, 22, 98, 17, 50, 110, 109, 59, 181, 109, 154, 84, 88, 60, 188, 0, 191, 64, - 46, 229, 182, 32, 20, 2, 74, 42, 18, 235, 9, 249, 64, 116, 65, 54, 67, 1, 118, 34, 236, 213, - 63, 88, 202, 131, 114, 138, 154, 105, 29, 58, 106, 66, 201, 200, 74, 150, 27, 149, 159, 90, - 213, 12, 112, 252, 64, 244, 104, 220, 50, 128, 113, 201, 104, 20, 107, 144, 30, 58, 28, 189, - 44, 89, 107, 176, 167, 113, 52, 250, 5, 32, 4, 87, 105, 19, 100, 49, 206, 121, 89, 252, 243, - 252, 225, 44, 180, 118, 113, 8, 186, 165, 2, 200, 56, 154, 176, 142, 73, 83, 118, 20, 113, 72, - 32, 6, 136, 174, 25, 103, 129, 228, 236, 152, 40, 59, 146, 249, 150, 237, 20, 81, 215, 10, 200, - 139, 59, 35, 133, 200, 43, 47, 215, 22, 184, 229, 2, 32, 6, 167, 37, 185, 208, 123, 36, 223, - 152, 196, 150, 147, 157, 29, 252, 246, 66, 97, 248, 67, 241, 28, 215, 27, 63, 0, 229, 114, 99, - 207, 95, 21, 32, 2, 112, 59, 63, 171, 54, 166, 178, 221, 202, 101, 39, 130, 200, 103, 184, 44, - 166, 220, 246, 108, 106, 76, 54, 33, 134, 47, 117, 48, 240, 255, 173, 32, 5, 196, 143, 35, 233, - 0, 32, 54, 82, 255, 118, 12, 30, 80, 201, 187, 151, 120, 176, 215, 146, 164, 12, 194, 190, 166, - 214, 43, 224, 224, 149, 217, 5, 6, 168, 38, 220, 25, 149, 71, 84, 129, 64, 73, 73, 59, 140, 69, - 111, 67, 195, 15, 178, 147, 177, 105, 84, 186, 79, 63, 194, 33, 85, 112, 1, 213, 33, 47, 206, - 7, 162, 188, 218, 42, 204, 87, 160, 251, 213, 62, 180, 7, 121, 99, 0, 211, 63, 30, 254, 106, - 31, 176, 41, 25, 175, 80, 100, 190, 111, 88, 75, 217, 188, 235, 191, 225, 117, 197, 67, 219, - 63, 231, 94, 69, 23, 155, 115, 39, 126, 66, 230, 232, 97, 65, 196, 47, 174, 63, 3, 102, 12, - 170, 97, 193, 165, 130, 39, 228, 52, 78, 243, 4, 108, 238, 148, 139, 4, 138, 220, 22, 151, 90, - 245, 199, 228, 126, 112, 63, 238, 140, 3, 100, 141, 244, 146, 128, 230, 70, 232, 217, 250, 154, - 27, 231, 23, 163, 61, 230, 124, 50, 221, 102, 196, 17, 93, 22, 222, 37, 204, 3, 54, 252, 116, - 208, 45, 93, 164, 82, 210, 92, 91, 63, 69, 76, 186, 185, 17, 78, 26, 238, 81, 20, 223, 109, - 188, 216, 28, 7, 139, 13, 241, 111, 119, 115, 3, 223, 5, 138, 86, 3, 251, 12, 37, 26, 26, 37, - 229, 31, 77, 213, 196, 29, 94, 132, 241, 23, 42, 110, 8, 144, 8, 241, 120, 250, 91, 227, 24, - 59, 118, 27, 166, 110, 151, 252, 42, 38, 13, 148, 178, 163, 7, 86, 243, 206, 99, 51, 45, 174, - 176, 2, 176, 222, 79, 185, 46, 239, 213, 231, 110, 203, 243, 231, 144, 68, 128, 118, 48, 62, - 253, 17, 89, 151, 143, 22, 34, 87, 213, 31, 37, 220, 227, 16, 247, 190, 214, 150, 187, 105, - 125, 102, 15, 145, 3, 159, 192, 79, 117, 81, 131, 127, 69, 145, 20, 160, 108, 209, 65, 86, 163, - 214, 220, 48, 231, 113, 225, 26, 192, 222, 215, 102, 154, 77, 26, 184, 181, 230, 178, 31, 28, - 242, 118, 216, 199, 237, 31, 119, 2, 113, 240, 112, 172, 197, 210, 98, 201, 91, 235, 196, 125, - 20, 119, 2, 25, 24, 146, 211, 241, 4, 74, 100, 162, 210, 220, 234, 124, 46, 120, 142, 236, 102, - 152, 212, 37, 114, 126, 89, 239, 119, 17, 248, 231, 171, 61, 108, 232, 175, 196, 62, 194, 69, - 13, 46, 84, 234, 17, 3, 21, 46, 232, 96, 9, 70, 128, 36, 230, 16, 165, 191, 254, 148, 41, 202, - 229, 89, 212, 233, 141, 168, 174, 229, 140, 224, 81, 97, 29, 1, 23, 2, 22, 151, 247, 233, 81, - 79, 170, 158, 249, 229, 199, 81, 89, 200, 216, 145, 38, 153, 216, 65, 34, 219, 99, 193, 248, - 36, 23, 36, 129, 51, 155, 81, 170, 123, 1, 59, 160, 203, 139, 28, 197, 58, 211, 230, 37, 31, - 85, 193, 140, 119, 108, 130, 78, 25, 191, 43, 91, 161, 3, 0, 250, 166, 193, 194, 161, 166, 73, - 214, 204, 218, 13, 80, 76, 118, 250, 79, 222, 128, 150, 252, 245, 253, 158, 102, 27, 172, 50, - 192, 131, 192, 147, 28, 23, 189, 214, 38, 116, 4, 248, 192, 87, 143, 63, 134, 25, 6, 201, 48, - 121, 23, 233, 211, 162, 185, 219, 176, 27, 21, 61, 121, 58, 228, 60, 47, 126, 131, 56, 51, 84, - 132, 13, 81, 124, 22, 98, 17, 50, 110, 109, 59, 181, 109, 154, 84, 88, 60, 188, 0, 191, 64, 46, - 229, 182, 32, 20, 2, 74, 42, 18, 235, 9, 249, 64, 116, 65, 54, 67, 1, 118, 34, 236, 213, 63, - 88, 202, 131, 114, 138, 154, 105, 29, 58, 106, 66, 201, 200, 74, 150, 27, 149, 159, 90, 213, - 12, 112, 252, 64, 244, 104, 220, 50, 128, 113, 201, 104, 20, 107, 144, 30, 58, 28, 189, 44, 89, - 107, 176, 167, 113, 52, 250, 5, 32, 4, 87, 105, 19, 100, 49, 206, 121, 89, 252, 243, 252, 225, - 44, 180, 118, 113, 8, 186, 165, 2, 200, 56, 154, 176, 142, 73, 83, 118, 20, 113, 72, 32, 6, - 136, 174, 25, 103, 129, 228, 236, 152, 40, 59, 146, 249, 150, 237, 20, 81, 215, 10, 200, 139, - 59, 35, 133, 200, 43, 47, 215, 22, 184, 229, 2, 32, 6, 167, 37, 185, 208, 123, 36, 223, 152, - 196, 150, 147, 157, 29, 252, 246, 66, 97, 248, 67, 241, 28, 215, 27, 63, 0, 229, 114, 99, 207, - 95, 21, 32, 2, 112, 59, 63, 171, 54, 166, 178, 221, 202, 101, 39, 130, 200, 103, 184, 44, 166, - 220, 246, 108, 106, 76, 54, 33, 134, 47, 117, 48, 240, 255, 173, 32, 5, 196, 143, 35, 233, 0, - 32, 54, 82, 255, 118, 12, 30, 80, 201, 187, 151, 120, 176, 215, 146, 164, 12, 194, 190, 166, - 214, 43, 224, 224, 149, 217, 3, 7, 126, 40, 243, 172, 167, 175, 234, 240, 174, 123, 250, 6, 48, - 63, 188, 203, 225, 130, 112, 128, 54, 46, 62, 66, 37, 235, 178, 113, 16, 113, 73, 110, 112, - 159, 196, 68, 95, 225, 214, 36, 29, 252, 221, 60, 143, 203, 240, 62, 161, 247, 182, 212, 232, - 10, 238, 65, 42, 138, 195, 155, 1, 255, 6, 12, 202, 146, 92, 237, 231, 92, 225, 161, 236, 140, - 152, 24, 136, 150, 9, 10, 132, 241, 33, 38, 195, 190, 159, 14, 216, 41, 128, 143, 188, 48, 251, - 239, 231, 102, 253, 245, 174, 171, 190, 149, 90, 248, 5, 170, 199, 101, 38, 205, 66, 24, 120, - 101, 195, 107, 199, 25, 191, 20, 195, 54, 3, 190, 149, 34, 232, 6, 174, 198, 153, 194, 67, 57, - 25, 13, 66, 10, 104, 202, 169, 248, 127, 114, 195, 29, 6, 232, 245, 21, 133, 119, 106, 167, 44, - 27, 8, 27, 237, 138, 226, 59, 242, 120, 11, 188, 127, 143, 128, 243, 155, 247, 151, 78, 29, - 103, 194, 98, 234, 250, 167, 255, 241, 154, 113, 186, 85, 108, 240, 84, 111, 163, 238, 222, 68, - 50, 217, 122, 69, 188, 177, 88, 171, 3, 59, 238, 53, 27, 39, 235, 53, 93, 13, 190, 107, 174, - 144, 238, 168, 55, 70, 208, 7, 126, 40, 243, 172, 167, 175, 234, 240, 174, 123, 250, 6, 48, 63, - 188, 203, 225, 130, 112, 128, 54, 46, 62, 66, 37, 235, 178, 113, 16, 113, 73, 110, 112, 159, - 196, 68, 95, 225, 214, 36, 29, 252, 221, 60, 143, 203, 240, 62, 161, 247, 182, 212, 232, 10, - 238, 65, 42, 138, 195, 155, 1, 255, 6, 12, 202, 146, 92, 237, 231, 92, 225, 161, 236, 140, 152, - 24, 136, 150, 9, 10, 132, 241, 33, 38, 195, 190, 159, 14, 216, 41, 128, 143, 188, 48, 251, 239, - 231, 102, 253, 245, 174, 171, 190, 149, 90, 248, 5, 170, 199, 101, 38, 205, 66, 24, 120, 101, - 195, 107, 199, 25, 191, 20, 195, 54, 3, 190, 149, 34, 232, 6, 174, 198, 153, 194, 67, 57, 25, - 13, 66, 10, 104, 202, 169, 248, 127, 114, 195, 29, 6, 232, 245, 21, 133, 119, 106, 167, 44, 27, - 8, 27, 237, 138, 226, 59, 242, 120, 11, 188, 127, 143, 128, 243, 155, 247, 151, 78, 29, 103, - 194, 98, 234, 250, 167, 255, 241, 154, 113, 186, 85, 108, 240, 84, 111, 163, 238, 222, 68, 50, - 217, 122, 69, 188, 177, 88, 171, 3, 59, 238, 53, 27, 39, 235, 53, 93, 13, 190, 107, 174, 144, - 238, 168, 55, 70, 208, 2, 32, 1, 233, 234, 212, 219, 245, 192, 123, 144, 73, 15, 40, 185, 48, - 206, 143, 33, 112, 161, 73, 157, 3, 160, 114, 210, 143, 56, 4, 8, 165, 17, 9, 32, 4, 13, 241, - 238, 159, 178, 110, 42, 17, 135, 191, 138, 114, 16, 117, 167, 46, 153, 106, 118, 27, 51, 83, - 133, 25, 221, 99, 241, 25, 41, 228, 94, 2, 32, 6, 97, 207, 224, 224, 82, 69, 83, 207, 133, 120, - 91, 161, 171, 39, 132, 249, 198, 104, 32, 25, 172, 171, 108, 226, 123, 235, 117, 51, 115, 30, - 157, 32, 4, 73, 249, 195, 252, 248, 178, 231, 139, 175, 74, 150, 185, 254, 59, 95, 235, 210, - 55, 3, 15, 131, 6, 156, 43, 249, 193, 136, 234, 229, 164, 33, 8, 209, 209, 231, 125, 217, 21, - 253, 56, 232, 148, 168, 235, 251, 35, 20, 86, 24, 135, 7, 4, 215, 13, 47, 207, 5, 74, 174, 31, - 140, 70, 195, 40, 227, 252, 46, 119, 163, 198, 19, 57, 229, 116, 112, 182, 233, 55, 59, 100, - 87, 119, 110, 130, 33, 131, 93, 13, 238, 17, 121, 187, 215, 36, 180, 136, 108, 178, 97, 88, 78, - 182, 228, 173, 17, 44, 182, 31, 7, 181, 38, 217, 220, 243, 61, 83, 119, 57, 169, 54, 207, 163, - 122, 191, 230, 12, 144, 114, 23, 142, 0, 23, 70, 116, 106, 121, 99, 128, 210, 78, 29, 19, 195, - 22, 35, 246, 10, 106, 109, 28, 115, 181, 223, 237, 182, 4, 20, 128, 109, 23, 191, 22, 144, 60, - 121, 121, 64, 190, 105, 81, 199, 185, 217, 98, 169, 242, 90, 255, 155, 197, 57, 106, 49, 93, - 166, 34, 146, 145, 252, 153, 151, 197, 90, 125, 16, 25, 41, 188, 114, 58, 89, 239, 63, 64, 105, - 4, 102, 211, 3, 43, 180, 109, 69, 210, 168, 47, 199, 3, 231, 17, 41, 201, 253, 197, 66, 155, - 36, 12, 34, 61, 169, 95, 84, 39, 35, 149, 250, 234, 76, 165, 17, 124, 40, 205, 185, 201, 27, - 71, 191, 77, 148, 228, 244, 148, 31, 91, 252, 89, 141, 6, 13, 139, 105, 158, 82, 26, 166, 148, - 184, 91, 40, 185, 45, 214, 150, 78, 230, 134, 109, 250, 24, 78, 249, 49, 197, 186, 141, 6, 8, - 118, 57, 168, 189, 244, 16, 138, 153, 83, 38, 111, 182, 217, 196, 52, 183, 62, 175, 249, 132, - 106, 145, 120, 20, 4, 174, 223, 62, 198, 85, 252, 125, 227, 252, 46, 119, 163, 198, 19, 57, - 229, 116, 112, 182, 233, 55, 59, 100, 87, 119, 110, 130, 33, 131, 93, 13, 238, 17, 121, 187, - 215, 36, 180, 136, 108, 178, 97, 88, 78, 182, 228, 173, 17, 44, 182, 31, 7, 181, 38, 217, 220, - 243, 61, 83, 119, 57, 169, 54, 207, 163, 122, 191, 230, 12, 144, 114, 23, 142, 0, 23, 70, 116, - 106, 121, 99, 128, 210, 78, 29, 19, 195, 22, 35, 246, 10, 106, 109, 28, 115, 181, 223, 237, - 182, 4, 20, 128, 109, 23, 191, 22, 144, 60, 121, 121, 64, 190, 105, 81, 199, 185, 217, 98, 169, - 242, 90, 255, 155, 197, 57, 106, 49, 93, 166, 34, 146, 145, 252, 153, 151, 197, 90, 125, 16, - 25, 41, 188, 114, 58, 89, 239, 63, 64, 105, 4, 102, 211, 3, 43, 180, 109, 69, 210, 168, 47, + 193, 202, 8, 15, 250, 12, 38, 185, 118, 32, 4, 121, 119, 154, 112, 215, 149, 181, 135, 19, 126, + 111, 29, 70, 31, 188, 18, 213, 57, 174, 39, 158, 20, 84, 21, 255, 108, 8, 130, 181, 210, 188, + 32, 6, 160, 9, 128, 25, 11, 118, 22, 20, 151, 71, 31, 175, 86, 16, 174, 137, 223, 219, 241, + 181, 35, 4, 196, 138, 91, 86, 112, 137, 228, 116, 81, 32, 7, 107, 149, 38, 34, 86, 96, 114, + 159, 34, 99, 135, 158, 58, 25, 31, 76, 30, 86, 40, 212, 147, 139, 195, 62, 99, 10, 139, 2, 32, + 214, 196, 32, 6, 108, 34, 191, 254, 254, 228, 247, 135, 134, 229, 235, 224, 97, 77, 120, 157, + 43, 153, 217, 41, 102, 201, 99, 134, 117, 228, 144, 48, 163, 25, 129, 32, 2, 20, 45, 228, 132, + 42, 246, 70, 86, 114, 189, 79, 91, 197, 193, 77, 249, 25, 48, 253, 126, 70, 191, 158, 197, 112, + 103, 222, 171, 146, 253, 45, 32, 7, 117, 162, 64, 207, 150, 67, 187, 96, 148, 96, 38, 49, 9, + 133, 44, 90, 236, 197, 169, 22, 115, 1, 96, 121, 62, 95, 14, 18, 245, 96, 28, 32, 5, 99, 63, + 92, 105, 2, 109, 50, 41, 189, 169, 18, 51, 142, 198, 244, 225, 45, 184, 128, 162, 195, 173, + 132, 26, 158, 29, 73, 185, 108, 189, 223, 32, 6, 177, 159, 174, 52, 129, 54, 161, 148, 222, + 212, 137, 25, 199, 99, 122, 112, 150, 220, 64, 81, 97, 214, 194, 13, 79, 14, 164, 220, 182, 94, + 240, 32, 7, 21, 63, 67, 83, 232, 93, 14, 9, 158, 191, 21, 234, 220, 250, 2, 20, 252, 77, 157, + 2, 107, 56, 219, 24, 198, 119, 137, 150, 248, 184, 108, 32, 6, 118, 104, 204, 170, 167, 72, 36, + 24, 28, 178, 178, 199, 153, 3, 48, 248, 109, 16, 177, 203, 221, 79, 51, 65, 123, 50, 17, 24, + 186, 245, 98, 32, 6, 53, 4, 218, 106, 98, 29, 135, 172, 151, 167, 87, 84, 29, 48, 173, 143, + 159, 203, 207, 109, 62, 43, 234, 243, 200, 173, 51, 81, 205, 214, 159, 32, 1, 192, 54, 174, + 176, 150, 192, 232, 159, 124, 165, 164, 227, 190, 10, 213, 99, 13, 175, 251, 178, 63, 130, 157, + 229, 200, 157, 4, 248, 245, 91, 170, 32, 3, 131, 77, 129, 155, 122, 112, 105, 14, 166, 108, 44, + 230, 88, 128, 192, 101, 208, 9, 193, 199, 170, 102, 165, 219, 33, 6, 149, 50, 190, 136, 4, 32, + 1, 166, 22, 90, 183, 236, 147, 229, 114, 124, 118, 30, 172, 157, 47, 152, 43, 185, 156, 176, + 233, 211, 41, 241, 244, 91, 35, 247, 220, 48, 167, 119, 32, 0, 143, 122, 153, 149, 158, 11, + 167, 120, 109, 143, 224, 180, 71, 224, 16, 242, 141, 173, 213, 78, 163, 226, 115, 12, 76, 130, + 51, 22, 181, 220, 175, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 2, 1, 253, 138, 34, 207, 195, 158, 101, 246, 72, 80, 69, 234, + 134, 69, 254, 0, 214, 200, 65, 117, 252, 210, 179, 241, 125, 139, 80, 132, 22, 88, 32, 5, 207, + 6, 122, 136, 121, 97, 74, 64, 92, 10, 82, 129, 253, 207, 93, 27, 141, 1, 155, 169, 154, 254, + 206, 37, 170, 143, 226, 127, 127, 197, 136, 32, 2, 82, 215, 180, 74, 233, 38, 140, 152, 162, + 68, 165, 53, 110, 9, 215, 1, 145, 213, 78, 167, 109, 84, 4, 109, 31, 245, 125, 198, 84, 65, + 158, 32, 6, 254, 118, 48, 225, 227, 141, 219, 18, 3, 186, 152, 178, 114, 191, 66, 55, 89, 219, + 95, 200, 151, 29, 176, 74, 41, 179, 109, 99, 230, 201, 88, 32, 6, 54, 190, 65, 189, 147, 32, + 77, 11, 90, 84, 204, 243, 122, 213, 92, 228, 209, 124, 145, 16, 62, 177, 252, 154, 93, 164, 93, + 254, 68, 192, 203, 32, 7, 146, 93, 121, 26, 128, 203, 73, 35, 188, 123, 51, 179, 189, 238, 11, + 106, 121, 76, 173, 19, 223, 23, 158, 122, 246, 192, 227, 134, 2, 231, 8, 32, 0, 158, 30, 24, + 198, 212, 205, 150, 208, 38, 174, 245, 134, 86, 168, 184, 120, 219, 209, 14, 217, 183, 243, + 240, 193, 102, 22, 97, 21, 230, 145, 150, 32, 4, 215, 231, 29, 42, 198, 22, 162, 226, 157, 128, + 71, 137, 216, 168, 228, 206, 159, 159, 52, 172, 88, 144, 103, 86, 202, 201, 230, 40, 78, 112, + 45, 32, 5, 235, 155, 127, 149, 142, 77, 54, 242, 17, 239, 182, 3, 107, 250, 74, 164, 113, 37, + 129, 249, 242, 46, 29, 220, 59, 254, 100, 15, 23, 32, 202, 32, 0, 100, 208, 10, 200, 88, 205, + 233, 28, 178, 96, 76, 200, 165, 11, 14, 9, 60, 200, 108, 74, 226, 251, 191, 116, 36, 106, 38, + 238, 105, 49, 59, 32, 3, 109, 137, 42, 78, 68, 171, 105, 86, 141, 182, 33, 18, 186, 138, 195, + 43, 158, 64, 240, 244, 44, 15, 82, 62, 95, 159, 208, 99, 128, 120, 166, 32, 6, 80, 221, 32, + 107, 188, 148, 20, 172, 97, 46, 213, 33, 96, 119, 194, 172, 209, 57, 171, 231, 161, 116, 77, + 146, 91, 127, 153, 116, 194, 6, 119, 32, 7, 95, 148, 33, 184, 38, 17, 124, 108, 165, 3, 157, + 11, 105, 123, 140, 78, 201, 252, 56, 201, 189, 40, 44, 160, 20, 181, 223, 97, 246, 63, 212, 32, + 4, 199, 196, 123, 36, 185, 76, 235, 127, 222, 243, 141, 18, 227, 51, 51, 179, 61, 186, 186, 17, + 65, 133, 204, 48, 129, 249, 79, 59, 212, 119, 134, 32, 1, 14, 184, 241, 108, 147, 105, 134, + 173, 126, 26, 113, 63, 210, 43, 210, 50, 231, 28, 98, 224, 126, 88, 254, 170, 63, 113, 191, + 174, 199, 229, 91, 32, 2, 188, 189, 236, 183, 2, 74, 99, 103, 10, 113, 112, 169, 116, 72, 218, + 15, 195, 180, 92, 244, 7, 8, 151, 187, 53, 116, 18, 145, 165, 235, 146, 32, 2, 213, 207, 119, + 50, 184, 15, 218, 181, 76, 123, 149, 88, 220, 220, 174, 163, 206, 82, 138, 209, 248, 253, 254, + 252, 104, 112, 41, 95, 243, 234, 85, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 7, 255, 255, 255, 254, 239, 253, 240, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 239, 255, 225, 32, 2, 58, 120, 103, 31, 144, 59, 36, 56, 216, 9, 143, 28, 152, 182, 24, + 101, 45, 40, 210, 92, 137, 3, 122, 137, 71, 129, 229, 131, 142, 200, 44, 32, 4, 95, 194, 144, + 22, 191, 76, 52, 100, 111, 16, 86, 25, 205, 60, 214, 40, 4, 73, 84, 53, 241, 111, 62, 89, 113, + 219, 34, 79, 171, 193, 213, 32, 4, 95, 194, 144, 22, 191, 76, 52, 100, 111, 16, 86, 25, 205, + 60, 214, 40, 4, 73, 84, 53, 241, 111, 62, 89, 113, 219, 34, 79, 171, 193, 213, 32, 4, 95, 194, + 144, 22, 191, 76, 52, 100, 111, 16, 86, 25, 205, 60, 214, 40, 4, 73, 84, 53, 241, 111, 62, 89, + 113, 219, 34, 79, 171, 193, 213, 32, 6, 170, 73, 20, 201, 41, 221, 95, 49, 88, 98, 198, 144, + 97, 178, 19, 20, 21, 54, 82, 199, 12, 45, 76, 215, 6, 123, 35, 238, 137, 202, 40, 32, 7, 100, + 98, 115, 53, 180, 216, 211, 207, 130, 160, 111, 216, 133, 121, 40, 24, 215, 122, 245, 214, 76, + 187, 71, 161, 160, 17, 97, 55, 180, 8, 5, 32, 2, 20, 170, 80, 81, 77, 23, 100, 85, 178, 255, + 127, 197, 138, 93, 120, 122, 114, 55, 153, 40, 18, 61, 181, 194, 255, 250, 174, 72, 182, 102, + 209, 32, 7, 20, 154, 141, 85, 62, 150, 185, 19, 107, 229, 104, 250, 70, 91, 203, 144, 9, 161, + 212, 234, 206, 29, 214, 118, 61, 199, 234, 111, 121, 255, 145, 32, 5, 113, 191, 41, 145, 51, + 220, 90, 222, 148, 12, 129, 249, 149, 236, 127, 207, 145, 201, 137, 53, 197, 218, 85, 9, 95, + 116, 43, 126, 1, 50, 243, 32, 7, 41, 143, 167, 119, 191, 45, 94, 57, 127, 51, 171, 183, 74, + 209, 143, 108, 123, 105, 127, 183, 37, 13, 103, 64, 232, 8, 200, 130, 138, 61, 78, 32, 7, 179, + 106, 203, 33, 8, 218, 190, 122, 33, 209, 80, 113, 38, 227, 184, 137, 24, 216, 11, 254, 221, + 197, 142, 70, 5, 141, 108, 0, 183, 75, 60, 32, 1, 117, 211, 84, 179, 151, 225, 227, 192, 48, + 144, 91, 223, 191, 221, 189, 250, 107, 130, 65, 174, 248, 46, 237, 4, 150, 1, 161, 15, 237, + 175, 140, 32, 7, 151, 193, 227, 109, 196, 148, 8, 12, 2, 93, 154, 254, 190, 168, 126, 115, 176, + 87, 244, 18, 245, 176, 255, 184, 74, 60, 134, 197, 64, 47, 198, 32, 1, 117, 234, 61, 180, 193, + 236, 53, 166, 68, 245, 7, 239, 133, 162, 169, 113, 184, 48, 142, 65, 35, 165, 252, 108, 157, + 51, 214, 79, 106, 127, 100, 32, 1, 55, 188, 132, 102, 25, 136, 86, 128, 254, 76, 150, 65, 68, + 67, 141, 141, 199, 5, 54, 5, 54, 193, 66, 219, 226, 231, 176, 237, 235, 86, 24, 32, 3, 13, 246, + 153, 18, 135, 58, 85, 177, 66, 112, 254, 233, 238, 154, 39, 78, 236, 149, 51, 145, 161, 115, + 190, 55, 59, 3, 153, 248, 255, 14, 59, 32, 4, 44, 148, 208, 135, 107, 26, 190, 55, 245, 96, + 224, 168, 146, 28, 132, 121, 112, 244, 136, 170, 187, 113, 14, 84, 158, 238, 144, 99, 64, 212, + 162, 32, 6, 3, 108, 124, 197, 209, 187, 234, 214, 106, 11, 99, 173, 24, 108, 50, 113, 93, 111, + 81, 184, 68, 126, 53, 149, 82, 4, 249, 241, 1, 38, 45, 32, 4, 99, 217, 80, 21, 33, 240, 160, + 192, 206, 148, 125, 201, 15, 226, 223, 205, 54, 196, 69, 238, 196, 211, 131, 106, 163, 155, 71, + 254, 69, 148, 35, 32, 2, 48, 20, 156, 33, 221, 241, 152, 186, 21, 217, 133, 210, 195, 96, 76, + 182, 89, 195, 57, 141, 140, 194, 34, 98, 73, 184, 74, 158, 222, 233, 204, 32, 2, 104, 146, 122, + 157, 155, 177, 23, 184, 43, 123, 16, 201, 28, 174, 245, 3, 129, 93, 122, 56, 72, 221, 119, 158, + 48, 136, 129, 156, 146, 129, 85, 32, 7, 204, 154, 228, 196, 116, 47, 11, 22, 136, 232, 70, 49, + 217, 80, 27, 27, 71, 148, 85, 106, 137, 239, 44, 60, 142, 255, 114, 199, 138, 131, 115, 32, 0, + 109, 148, 114, 107, 9, 10, 135, 133, 203, 14, 200, 143, 22, 176, 132, 91, 191, 120, 231, 4, 11, + 27, 29, 2, 144, 66, 74, 172, 180, 238, 173, 32, 5, 41, 106, 199, 66, 209, 86, 79, 26, 114, 96, + 115, 160, 206, 94, 45, 101, 109, 218, 61, 240, 250, 236, 254, 99, 11, 208, 173, 123, 237, 172, + 218, 32, 7, 195, 15, 52, 113, 31, 59, 106, 153, 94, 78, 59, 116, 234, 101, 79, 99, 50, 165, 71, + 164, 242, 93, 229, 173, 68, 76, 63, 130, 180, 245, 171, 32, 7, 178, 233, 172, 78, 145, 162, + 101, 232, 61, 41, 82, 127, 140, 193, 65, 50, 22, 164, 191, 140, 197, 45, 169, 27, 70, 249, 29, + 104, 25, 145, 54, 32, 5, 103, 27, 203, 24, 80, 17, 106, 37, 200, 66, 30, 240, 30, 10, 130, 161, + 220, 169, 53, 232, 88, 202, 248, 230, 100, 254, 37, 91, 86, 106, 130, 32, 1, 7, 154, 215, 176, + 200, 223, 248, 219, 75, 86, 84, 157, 153, 63, 218, 154, 146, 99, 255, 244, 68, 127, 59, 3, 133, + 63, 233, 75, 12, 125, 229, 32, 4, 162, 25, 132, 194, 188, 89, 153, 243, 148, 200, 111, 120, + 234, 187, 113, 250, 211, 203, 196, 216, 19, 241, 186, 152, 174, 93, 135, 96, 219, 84, 120, 32, + 3, 94, 57, 26, 147, 93, 208, 42, 251, 160, 44, 253, 234, 225, 221, 209, 83, 232, 56, 222, 73, + 86, 22, 34, 133, 66, 159, 217, 36, 198, 149, 248, 32, 1, 175, 28, 141, 73, 174, 232, 21, 125, + 208, 22, 126, 245, 112, 238, 232, 169, 244, 28, 111, 36, 171, 11, 17, 66, 161, 79, 236, 146, + 99, 74, 252, 32, 6, 105, 207, 161, 80, 227, 125, 57, 107, 219, 234, 242, 8, 57, 180, 6, 79, + 244, 114, 176, 90, 196, 160, 93, 93, 148, 250, 136, 178, 122, 77, 203, 32, 5, 170, 248, 163, + 232, 122, 43, 2, 147, 175, 63, 152, 67, 184, 111, 129, 199, 252, 147, 171, 35, 206, 159, 120, + 115, 29, 71, 80, 34, 233, 231, 67, 32, 5, 235, 92, 54, 78, 181, 54, 43, 197, 26, 242, 212, 164, + 133, 161, 32, 206, 244, 132, 107, 0, 119, 161, 192, 98, 107, 132, 45, 35, 61, 151, 241, 32, 1, + 52, 115, 199, 154, 130, 145, 138, 77, 44, 24, 92, 225, 232, 60, 191, 17, 133, 174, 225, 68, + 248, 253, 109, 190, 219, 85, 222, 106, 223, 199, 237, 32, 4, 65, 124, 175, 73, 120, 63, 43, 8, + 5, 100, 6, 79, 135, 103, 228, 149, 4, 66, 187, 228, 34, 215, 155, 81, 4, 227, 10, 152, 83, 210, + 90, 32, 2, 79, 92, 69, 142, 186, 27, 253, 104, 116, 175, 206, 98, 172, 37, 88, 202, 4, 207, 66, + 55, 197, 109, 23, 99, 221, 158, 135, 165, 106, 210, 221, 32, 2, 185, 239, 125, 115, 105, 23, + 36, 225, 46, 55, 153, 190, 215, 79, 62, 95, 252, 204, 25, 228, 81, 209, 96, 110, 51, 33, 214, + 59, 254, 17, 187, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 32, 6, 115, 185, 251, 251, 2, 194, 113, 34, 165, 158, 201, 2, 155, 58, + 231, 207, 183, 88, 168, 36, 176, 229, 83, 109, 5, 228, 104, 251, 149, 0, 169, 32, 0, 23, 30, + 73, 111, 138, 235, 54, 146, 59, 69, 100, 119, 174, 18, 9, 159, 47, 91, 41, 166, 49, 108, 197, + 98, 121, 163, 236, 57, 127, 71, 230, 32, 3, 135, 193, 17, 66, 204, 31, 13, 198, 104, 151, 87, + 201, 70, 48, 171, 93, 196, 213, 133, 72, 38, 70, 160, 168, 13, 131, 96, 7, 226, 139, 241, 32, + 0, 97, 102, 235, 176, 150, 14, 255, 3, 82, 45, 214, 73, 26, 71, 248, 125, 155, 45, 139, 124, + 80, 247, 214, 243, 124, 101, 179, 141, 154, 195, 162, 32, 6, 2, 0, 84, 32, 175, 214, 204, 21, + 56, 3, 253, 30, 16, 24, 127, 110, 182, 243, 196, 52, 84, 5, 188, 1, 231, 85, 219, 238, 138, + 212, 128, 32, 5, 41, 245, 43, 9, 88, 252, 140, 241, 50, 247, 88, 201, 134, 107, 10, 138, 185, + 129, 84, 20, 180, 247, 156, 48, 190, 41, 60, 144, 165, 148, 158, 32, 0, 128, 135, 202, 252, 45, + 176, 31, 143, 187, 108, 30, 148, 161, 37, 7, 111, 221, 225, 16, 14, 94, 38, 96, 113, 129, 116, + 34, 2, 216, 200, 159, 32, 6, 227, 189, 138, 109, 9, 174, 87, 133, 125, 196, 131, 133, 203, 175, + 233, 36, 232, 231, 106, 46, 254, 207, 133, 169, 31, 102, 114, 167, 133, 218, 49, 32, 0, 32, 35, + 156, 126, 100, 217, 21, 5, 4, 77, 161, 75, 187, 104, 12, 133, 33, 8, 191, 243, 252, 247, 101, + 117, 215, 71, 248, 98, 127, 216, 63, 32, 0, 115, 15, 50, 93, 55, 31, 152, 56, 32, 35, 75, 80, + 60, 95, 38, 34, 171, 102, 52, 111, 219, 210, 246, 116, 152, 47, 203, 146, 37, 25, 223, 32, 6, + 14, 95, 6, 196, 226, 244, 244, 239, 116, 1, 198, 58, 8, 219, 245, 5, 138, 203, 23, 67, 23, 84, + 232, 149, 164, 19, 227, 167, 195, 146, 206, 32, 7, 208, 64, 211, 244, 126, 177, 122, 187, 50, + 96, 64, 242, 176, 168, 204, 138, 69, 128, 232, 60, 106, 201, 93, 194, 23, 92, 253, 161, 90, 49, + 208, 32, 6, 0, 189, 207, 176, 242, 9, 66, 167, 122, 73, 10, 123, 39, 169, 19, 60, 103, 43, 164, + 118, 82, 94, 190, 127, 214, 40, 39, 73, 4, 49, 45, 32, 6, 144, 193, 234, 226, 255, 169, 98, + 233, 235, 134, 35, 35, 19, 131, 173, 15, 201, 217, 186, 130, 0, 141, 35, 195, 40, 10, 100, 18, + 7, 101, 159, 32, 2, 81, 151, 245, 177, 252, 226, 204, 173, 85, 24, 4, 95, 205, 23, 25, 251, 17, + 156, 214, 90, 28, 206, 86, 238, 192, 134, 49, 32, 50, 220, 6, 32, 1, 244, 205, 177, 90, 120, + 13, 60, 46, 86, 37, 234, 225, 106, 184, 139, 212, 169, 168, 244, 158, 52, 14, 135, 165, 147, + 70, 141, 255, 230, 132, 71, 32, 5, 82, 227, 139, 2, 40, 141, 165, 126, 161, 195, 112, 160, 172, + 14, 82, 222, 80, 169, 222, 77, 78, 246, 49, 169, 210, 143, 72, 95, 111, 245, 232, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 32, 7, 255, 255, 255, 254, 239, 253, 240, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 239, 255, 225, 32, 0, 85, 163, 31, 56, + 23, 227, 210, 35, 188, 95, 188, 220, 211, 243, 28, 54, 224, 187, 98, 102, 204, 33, 75, 193, + 122, 112, 91, 160, 41, 141, 89, 32, 4, 82, 203, 137, 115, 201, 150, 191, 166, 99, 222, 69, 222, + 149, 93, 212, 145, 31, 93, 65, 137, 126, 195, 126, 14, 129, 233, 26, 176, 49, 82, 127, 32, 4, + 82, 203, 137, 115, 201, 150, 191, 166, 99, 222, 69, 222, 149, 93, 212, 145, 31, 93, 65, 137, + 126, 195, 126, 14, 129, 233, 26, 176, 49, 82, 127, 32, 4, 82, 203, 137, 115, 201, 150, 191, + 166, 99, 222, 69, 222, 149, 93, 212, 145, 31, 93, 65, 137, 126, 195, 126, 14, 129, 233, 26, + 176, 49, 82, 127, 32, 1, 233, 68, 16, 26, 231, 26, 13, 224, 136, 35, 186, 24, 94, 164, 6, 24, + 215, 201, 121, 43, 164, 110, 63, 246, 152, 162, 110, 47, 24, 96, 170, 32, 3, 68, 254, 241, 184, + 31, 136, 240, 123, 184, 28, 56, 127, 116, 64, 6, 24, 157, 254, 225, 103, 224, 242, 60, 247, + 114, 65, 92, 85, 90, 123, 96, 32, 1, 10, 116, 233, 164, 250, 215, 87, 154, 28, 170, 97, 52, + 177, 105, 39, 86, 87, 202, 11, 143, 8, 136, 89, 112, 142, 108, 124, 64, 80, 51, 114, 32, 4, 21, + 88, 73, 189, 248, 220, 154, 103, 98, 52, 113, 214, 220, 147, 30, 108, 56, 18, 71, 125, 178, + 247, 106, 67, 91, 72, 195, 182, 228, 234, 65, 32, 3, 116, 200, 211, 20, 250, 150, 46, 138, 158, + 89, 97, 125, 50, 0, 184, 211, 5, 226, 38, 227, 131, 150, 173, 187, 92, 236, 2, 129, 165, 162, + 90, 32, 7, 246, 141, 58, 113, 220, 125, 16, 230, 82, 174, 150, 52, 27, 174, 148, 207, 155, 224, + 31, 47, 161, 188, 93, 245, 241, 130, 244, 30, 255, 124, 38, 32, 0, 135, 49, 230, 77, 253, 147, + 32, 220, 149, 28, 235, 161, 217, 174, 36, 68, 19, 159, 36, 83, 233, 51, 51, 186, 156, 127, 58, + 125, 30, 96, 122, 32, 7, 240, 8, 218, 58, 141, 142, 100, 113, 185, 80, 234, 52, 191, 204, 177, + 223, 215, 24, 78, 11, 179, 213, 100, 59, 147, 142, 164, 74, 151, 202, 69, 32, 1, 140, 105, 137, + 196, 179, 164, 211, 17, 24, 142, 88, 14, 86, 92, 225, 103, 24, 147, 40, 187, 235, 183, 55, 67, + 206, 227, 76, 204, 85, 184, 0, 32, 1, 135, 21, 139, 177, 98, 238, 207, 121, 193, 232, 92, 193, + 84, 9, 31, 216, 230, 39, 94, 172, 170, 159, 131, 182, 200, 138, 149, 14, 209, 206, 112, 32, 7, + 11, 30, 72, 239, 66, 212, 25, 127, 66, 185, 63, 122, 54, 102, 90, 179, 208, 114, 222, 205, 233, + 100, 158, 102, 46, 172, 22, 211, 50, 169, 25, 32, 5, 248, 84, 239, 52, 205, 176, 109, 244, 251, + 122, 75, 246, 35, 127, 128, 70, 49, 32, 115, 224, 197, 164, 76, 145, 73, 103, 249, 203, 3, 8, + 34, 32, 3, 182, 251, 2, 76, 2, 142, 40, 178, 93, 156, 100, 212, 170, 206, 213, 16, 219, 191, + 26, 30, 42, 165, 137, 226, 93, 53, 48, 171, 66, 68, 90, 32, 2, 86, 24, 111, 255, 37, 44, 8, 32, + 247, 101, 8, 1, 159, 181, 86, 5, 193, 11, 78, 116, 183, 128, 190, 11, 37, 228, 66, 246, 42, 97, + 110, 32, 4, 117, 243, 32, 94, 173, 84, 240, 137, 39, 233, 131, 234, 166, 202, 0, 236, 27, 207, + 132, 222, 66, 210, 98, 108, 171, 189, 246, 230, 47, 41, 26, 32, 1, 199, 163, 213, 238, 169, + 173, 178, 245, 231, 214, 11, 255, 224, 62, 111, 59, 172, 254, 158, 85, 74, 156, 10, 152, 165, + 56, 235, 116, 4, 108, 183, 32, 2, 170, 60, 84, 163, 133, 239, 248, 198, 183, 45, 151, 159, 73, + 224, 53, 124, 40, 72, 25, 104, 121, 11, 35, 168, 248, 70, 79, 138, 210, 80, 221, 32, 1, 40, 99, + 5, 136, 12, 170, 142, 106, 37, 14, 66, 49, 32, 54, 247, 127, 114, 170, 81, 249, 107, 55, 134, + 56, 187, 193, 158, 240, 253, 108, 80, 32, 5, 182, 30, 113, 205, 238, 106, 8, 90, 89, 34, 99, + 100, 150, 116, 249, 10, 180, 155, 11, 70, 101, 71, 184, 180, 231, 244, 181, 56, 64, 98, 130, + 59, 2, 81, 40, 194, 94, 50, 95, 48, 102, 131, 97, 175, 28, 49, 71, 186, 139, 175, 98, 168, 189, + 34, 246, 11, 62, 140, 164, 7, 236, 183, 220, 165, 23, 2, 32, 3, 59, 152, 143, 8, 230, 240, 130, + 56, 157, 110, 161, 54, 201, 38, 88, 116, 51, 223, 114, 113, 15, 169, 45, 163, 3, 70, 102, 109, + 19, 244, 104, 32, 0, 186, 60, 10, 233, 92, 232, 39, 29, 239, 122, 223, 0, 178, 158, 152, 250, + 205, 162, 150, 109, 186, 214, 94, 94, 177, 99, 135, 250, 5, 221, 183, 5, 191, 197, 255, 113, + 37, 76, 111, 0, 114, 147, 242, 154, 7, 31, 117, 190, 38, 136, 123, 37, 94, 212, 249, 107, 104, + 80, 4, 117, 47, 28, 126, 105, 100, 93, 30, 7, 47, 90, 129, 239, 158, 228, 34, 172, 127, 112, + 154, 50, 12, 80, 235, 240, 221, 100, 64, 218, 90, 178, 60, 166, 125, 246, 131, 68, 196, 7, 41, + 61, 53, 191, 99, 192, 168, 51, 141, 240, 195, 73, 136, 178, 77, 77, 171, 230, 34, 95, 63, 72, + 43, 244, 57, 163, 39, 196, 98, 156, 57, 136, 29, 175, 0, 243, 46, 77, 13, 125, 6, 114, 48, 71, + 249, 99, 8, 128, 225, 34, 110, 147, 55, 27, 63, 175, 194, 217, 227, 77, 218, 94, 36, 156, 0, + 179, 231, 72, 31, 255, 38, 212, 167, 10, 174, 191, 110, 250, 162, 207, 161, 168, 79, 19, 104, + 168, 119, 188, 151, 153, 175, 9, 106, 34, 32, 7, 89, 44, 91, 159, 254, 36, 38, 170, 34, 219, + 45, 217, 23, 164, 181, 224, 3, 112, 229, 190, 172, 251, 223, 99, 32, 86, 157, 216, 159, 150, + 134, 3, 5, 6, 246, 179, 126, 106, 191, 68, 175, 91, 52, 134, 173, 220, 51, 251, 208, 40, 255, + 118, 102, 190, 251, 93, 123, 255, 212, 245, 224, 113, 116, 137, 206, 87, 57, 244, 148, 152, 0, + 128, 157, 16, 56, 116, 99, 227, 198, 250, 122, 186, 236, 42, 50, 76, 9, 83, 241, 89, 4, 230, + 27, 247, 214, 211, 214, 51, 101, 38, 74, 72, 251, 114, 60, 34, 69, 106, 109, 151, 42, 19, 129, + 17, 81, 158, 13, 73, 210, 188, 86, 240, 151, 220, 230, 52, 216, 38, 80, 103, 198, 152, 20, 115, + 160, 242, 252, 109, 20, 133, 222, 45, 134, 88, 23, 53, 141, 242, 248, 15, 11, 233, 149, 220, 8, + 24, 184, 75, 145, 67, 83, 65, 38, 70, 80, 71, 140, 74, 31, 138, 79, 5, 128, 132, 58, 43, 187, + 35, 22, 21, 18, 103, 216, 32, 162, 130, 102, 175, 17, 149, 195, 87, 73, 219, 140, 227, 135, + 197, 119, 17, 126, 237, 56, 57, 61, 0, 204, 10, 66, 81, 3, 129, 39, 95, 45, 65, 40, 41, 56, 45, + 134, 5, 204, 210, 97, 78, 5, 38, 124, 9, 101, 142, 27, 84, 214, 74, 16, 193, 162, 40, 79, 83, + 118, 130, 252, 144, 216, 117, 20, 36, 197, 120, 236, 91, 6, 122, 117, 5, 112, 130, 41, 45, 144, + 152, 96, 9, 196, 129, 48, 16, 255, 225, 194, 146, 230, 3, 53, 10, 11, 140, 129, 168, 180, 93, + 205, 17, 231, 9, 178, 140, 111, 27, 159, 166, 190, 249, 104, 99, 61, 107, 11, 219, 187, 68, + 171, 121, 0, 216, 199, 162, 138, 56, 29, 97, 137, 103, 186, 71, 26, 99, 115, 20, 70, 113, 12, + 29, 203, 98, 47, 50, 42, 188, 136, 157, 159, 108, 58, 187, 27, 127, 128, 169, 115, 229, 0, 246, + 172, 193, 39, 151, 134, 244, 58, 180, 120, 43, 49, 21, 2, 128, 38, 87, 184, 224, 109, 146, 99, + 207, 186, 154, 49, 150, 19, 204, 201, 19, 234, 99, 213, 91, 151, 9, 196, 58, 87, 229, 152, 4, + 4, 126, 143, 216, 213, 112, 139, 15, 201, 95, 2, 36, 217, 63, 3, 105, 156, 95, 192, 51, 127, + 107, 106, 121, 210, 131, 78, 183, 183, 69, 25, 120, 44, 193, 12, 209, 45, 134, 135, 222, 241, + 166, 46, 114, 171, 24, 250, 218, 189, 180, 56, 88, 31, 14, 10, 88, 91, 149, 46, 96, 221, 211, + 22, 124, 81, 167, 63, 169, 248, 220, 97, 31, 195, 229, 74, 177, 27, 61, 77, 171, 136, 91, 82, + 220, 194, 82, 248, 99, 188, 73, 122, 16, 71, 237, 134, 1, 196, 199, 25, 78, 137, 117, 178, 73, + 206, 207, 21, 100, 255, 225, 230, 110, 174, 195, 238, 33, 12, 156, 193, 51, 0, 240, 58, 209, + 103, 211, 116, 115, 3, 170, 100, 105, 36, 129, 157, 209, 253, 124, 53, 241, 6, 182, 23, 7, 159, + 88, 62, 158, 115, 188, 253, 2, 170, 17, 70, 168, 52, 61, 68, 51, 253, 196, 42, 0, 254, 183, + 240, 250, 12, 238, 185, 121, 26, 184, 50, 44, 34, 3, 2, 220, 217, 35, 28, 228, 108, 234, 188, + 173, 162, 148, 6, 20, 215, 109, 161, 59, 133, 175, 155, 138, 223, 67, 58, 208, 208, 57, 184, + 255, 208, 223, 253, 96, 77, 82, 94, 162, 149, 202, 120, 84, 168, 8, 120, 5, 21, 2, 228, 224, + 251, 183, 51, 241, 205, 70, 71, 174, 39, 70, 44, 98, 213, 82, 247, 7, 238, 179, 81, 161, 63, + 253, 211, 240, 78, 26, 76, 138, 88, 174, 238, 69, 131, 238, 10, 18, 9, 29, 216, 100, 199, 207, + 12, 176, 207, 8, 112, 14, 218, 7, 227, 62, 90, 189, 46, 251, 64, 37, 198, 110, 193, 8, 5, 32, + 2, 53, 177, 181, 73, 30, 205, 173, 220, 83, 85, 163, 122, 76, 72, 209, 174, 204, 185, 68, 148, + 87, 57, 211, 21, 124, 77, 1, 138, 67, 232, 204, 32, 5, 190, 49, 41, 170, 42, 123, 189, 134, 59, + 109, 96, 132, 2, 113, 248, 182, 19, 95, 37, 38, 246, 165, 169, 167, 77, 234, 132, 114, 252, + 193, 202, 32, 4, 99, 225, 118, 96, 244, 206, 204, 17, 221, 132, 21, 229, 37, 141, 247, 211, 4, + 68, 142, 191, 195, 88, 152, 220, 88, 76, 4, 197, 177, 12, 214, 32, 5, 38, 255, 173, 131, 70, + 110, 116, 26, 128, 12, 98, 202, 124, 252, 80, 65, 8, 229, 49, 246, 78, 241, 67, 60, 23, 64, + 185, 65, 39, 206, 81, 32, 4, 25, 69, 22, 53, 127, 102, 201, 107, 148, 46, 230, 100, 85, 108, + 147, 141, 9, 174, 163, 116, 96, 182, 151, 135, 10, 113, 114, 236, 245, 181, 238, 5, 6, 35, 206, + 103, 148, 205, 117, 76, 61, 12, 48, 23, 5, 242, 56, 0, 215, 228, 225, 136, 53, 59, 169, 81, 8, + 40, 155, 103, 197, 99, 235, 16, 209, 178, 57, 5, 119, 238, 168, 13, 118, 11, 238, 238, 224, + 190, 249, 62, 193, 98, 60, 71, 89, 220, 228, 201, 68, 103, 220, 150, 109, 187, 47, 224, 77, + 196, 7, 66, 181, 5, 42, 122, 97, 187, 255, 117, 22, 153, 101, 77, 11, 139, 70, 191, 8, 251, 29, + 151, 211, 11, 0, 186, 240, 214, 153, 111, 90, 88, 71, 125, 201, 195, 48, 92, 86, 191, 88, 229, + 232, 219, 36, 59, 39, 114, 20, 132, 73, 45, 70, 209, 110, 10, 29, 36, 145, 114, 251, 67, 187, + 198, 56, 212, 81, 250, 16, 79, 103, 92, 154, 98, 38, 219, 99, 170, 32, 195, 125, 84, 232, 191, + 119, 194, 156, 205, 244, 79, 241, 78, 89, 141, 126, 26, 205, 114, 67, 180, 106, 213, 33, 106, + 197, 243, 69, 119, 34, 222, 128, 69, 79, 102, 182, 187, 255, 109, 118, 158, 221, 63, 140, 221, + 181, 100, 171, 5, 133, 145, 42, 78, 125, 28, 43, 70, 42, 186, 177, 41, 99, 205, 160, 88, 110, + 62, 192, 104, 20, 151, 182, 248, 160, 121, 133, 52, 4, 160, 118, 246, 116, 92, 46, 138, 126, + 248, 114, 8, 31, 247, 96, 127, 173, 15, 249, 167, 220, 38, 136, 204, 21, 6, 121, 161, 160, 170, + 182, 226, 186, 169, 22, 163, 69, 162, 168, 54, 117, 238, 54, 206, 179, 27, 90, 253, 221, 89, + 105, 212, 143, 173, 228, 71, 158, 186, 45, 166, 56, 3, 126, 48, 100, 210, 124, 189, 23, 14, + 128, 47, 97, 219, 227, 61, 143, 51, 202, 139, 93, 234, 28, 241, 172, 82, 17, 137, 229, 105, + 116, 130, 254, 8, 172, 3, 64, 131, 41, 219, 198, 75, 234, 228, 214, 85, 172, 171, 128, 249, + 187, 230, 112, 23, 37, 20, 157, 7, 27, 41, 84, 224, 191, 3, 23, 75, 240, 27, 100, 70, 210, 195, + 4, 191, 241, 3, 182, 94, 188, 246, 181, 59, 105, 212, 62, 227, 163, 12, 135, 24, 51, 112, 25, + 199, 64, 13, 77, 147, 139, 80, 0, 92, 130, 148, 26, 17, 247, 231, 121, 216, 41, 3, 10, 252, + 187, 119, 114, 164, 108, 234, 49, 175, 234, 231, 41, 45, 30, 39, 1, 190, 145, 201, 15, 8, 22, + 55, 53, 139, 155, 53, 18, 168, 188, 29, 162, 181, 3, 207, 53, 159, 91, 89, 96, 109, 77, 124, + 29, 240, 31, 46, 218, 129, 77, 115, 141, 91, 102, 234, 124, 198, 244, 147, 73, 94, 30, 79, 130, + 91, 218, 2, 130, 225, 38, 52, 218, 233, 69, 30, 157, 212, 66, 234, 171, 133, 143, 124, 183, 11, + 235, 31, 177, 3, 204, 32, 166, 100, 39, 193, 38, 248, 52, 4, 129, 217, 9, 220, 182, 49, 251, + 39, 107, 211, 0, 245, 201, 107, 242, 143, 71, 121, 51, 249, 165, 46, 23, 128, 11, 61, 175, 105, + 39, 37, 155, 204, 121, 212, 38, 230, 164, 115, 57, 156, 245, 171, 246, 232, 129, 6, 254, 141, + 215, 29, 141, 58, 47, 66, 43, 4, 254, 39, 139, 195, 145, 92, 32, 238, 239, 240, 50, 213, 218, + 68, 133, 46, 151, 110, 52, 2, 169, 49, 135, 165, 218, 89, 49, 237, 210, 243, 2, 14, 84, 56, 39, + 228, 229, 73, 77, 195, 22, 26, 100, 255, 181, 102, 59, 30, 163, 16, 139, 27, 85, 234, 67, 146, + 230, 156, 100, 127, 246, 127, 171, 148, 223, 151, 248, 153, 169, 41, 238, 236, 5, 236, 194, + 181, 156, 241, 35, 232, 9, 159, 4, 166, 114, 64, 17, 238, 81, 45, 149, 246, 230, 19, 206, 5, + 32, 5, 11, 127, 120, 224, 216, 11, 231, 157, 196, 26, 184, 246, 76, 29, 50, 215, 189, 157, 230, + 11, 54, 160, 49, 108, 231, 52, 99, 92, 194, 102, 207, 32, 1, 214, 182, 1, 138, 8, 244, 88, 230, + 8, 201, 161, 57, 243, 99, 19, 79, 63, 229, 54, 218, 119, 91, 204, 48, 115, 27, 238, 119, 64, + 172, 118, 32, 4, 207, 122, 49, 125, 13, 117, 161, 85, 171, 186, 253, 30, 163, 122, 5, 237, 245, + 144, 169, 104, 212, 7, 140, 51, 160, 138, 148, 16, 34, 249, 195, 32, 0, 71, 172, 162, 180, 200, + 209, 207, 156, 53, 1, 127, 200, 71, 88, 190, 236, 124, 110, 38, 123, 155, 251, 231, 114, 116, + 156, 53, 89, 208, 61, 151, 32, 4, 113, 153, 32, 192, 100, 22, 16, 201, 77, 239, 20, 86, 1, 235, + 53, 150, 98, 235, 96, 18, 233, 179, 164, 25, 193, 63, 21, 122, 3, 248, 105, 5, 6, 164, 12, 33, + 111, 122, 156, 1, 168, 199, 62, 164, 37, 109, 13, 28, 3, 127, 52, 192, 217, 20, 217, 54, 30, + 87, 115, 28, 245, 103, 74, 204, 0, 33, 202, 205, 4, 20, 17, 50, 16, 132, 83, 34, 132, 92, 235, + 201, 102, 52, 188, 200, 76, 18, 228, 92, 83, 175, 155, 103, 228, 215, 118, 159, 182, 42, 16, + 72, 162, 176, 102, 176, 177, 203, 127, 144, 107, 144, 163, 132, 11, 78, 241, 164, 167, 58, 193, + 114, 216, 171, 102, 38, 70, 53, 126, 61, 191, 34, 147, 34, 168, 7, 171, 42, 57, 249, 70, 123, + 175, 213, 73, 149, 142, 114, 23, 172, 114, 124, 202, 224, 28, 255, 135, 221, 159, 60, 24, 20, + 74, 200, 160, 22, 80, 246, 8, 128, 255, 119, 25, 125, 123, 242, 124, 209, 136, 143, 121, 34, + 111, 211, 122, 132, 110, 158, 250, 151, 69, 95, 234, 251, 130, 26, 205, 114, 67, 180, 106, 213, + 33, 106, 197, 243, 69, 119, 34, 222, 128, 69, 79, 102, 182, 187, 255, 109, 118, 158, 221, 63, + 140, 221, 181, 100, 171, 5, 76, 4, 146, 12, 139, 155, 4, 69, 46, 236, 79, 234, 143, 225, 193, + 76, 161, 84, 99, 142, 60, 88, 70, 75, 192, 217, 64, 11, 133, 46, 61, 183, 94, 146, 82, 29, 91, + 253, 170, 49, 236, 176, 134, 51, 185, 95, 198, 253, 19, 65, 164, 204, 219, 223, 36, 211, 74, + 208, 80, 100, 57, 142, 168, 132, 37, 147, 49, 205, 88, 172, 2, 224, 153, 28, 130, 48, 63, 67, + 23, 141, 110, 169, 137, 140, 14, 158, 178, 115, 42, 63, 15, 138, 144, 192, 134, 183, 2, 97, + 142, 39, 229, 55, 34, 94, 78, 5, 218, 84, 0, 30, 78, 76, 82, 4, 220, 16, 244, 123, 162, 2, 206, + 104, 149, 68, 211, 41, 53, 120, 198, 75, 234, 228, 214, 85, 172, 171, 128, 249, 187, 230, 112, + 23, 37, 20, 157, 7, 27, 41, 84, 224, 191, 3, 23, 75, 240, 27, 100, 70, 210, 195, 4, 36, 147, + 74, 215, 10, 150, 175, 201, 114, 187, 212, 216, 113, 108, 70, 126, 123, 34, 249, 1, 16, 138, + 44, 152, 22, 64, 197, 6, 214, 137, 190, 124, 209, 146, 155, 107, 173, 13, 115, 125, 79, 120, + 64, 145, 109, 4, 128, 230, 136, 148, 180, 64, 244, 246, 189, 144, 211, 133, 148, 22, 165, 229, + 189, 148, 245, 16, 104, 133, 160, 196, 74, 85, 185, 148, 61, 92, 177, 127, 14, 181, 231, 188, + 46, 27, 197, 25, 218, 197, 52, 57, 15, 211, 31, 26, 193, 124, 198, 244, 147, 73, 94, 30, 79, + 130, 91, 218, 2, 130, 225, 38, 52, 218, 233, 69, 30, 157, 212, 66, 234, 171, 133, 143, 124, + 183, 11, 235, 31, 177, 3, 181, 87, 26, 195, 234, 251, 110, 37, 94, 116, 176, 226, 137, 38, 150, + 183, 154, 99, 204, 62, 251, 0, 160, 251, 54, 167, 246, 16, 125, 152, 175, 87, 96, 226, 24, 189, + 180, 160, 122, 77, 21, 164, 175, 149, 249, 178, 201, 78, 33, 211, 7, 235, 1, 46, 34, 226, 21, + 209, 136, 255, 205, 21, 88, 139, 43, 4, 254, 39, 139, 195, 145, 92, 32, 238, 239, 240, 50, 213, + 218, 68, 133, 46, 151, 110, 52, 2, 169, 49, 135, 165, 218, 89, 49, 237, 210, 243, 2, 22, 16, + 32, 133, 38, 144, 148, 13, 159, 247, 18, 246, 110, 7, 144, 92, 69, 243, 171, 15, 68, 175, 124, + 39, 1, 27, 129, 52, 118, 71, 249, 245, 148, 223, 151, 248, 153, 169, 41, 238, 236, 5, 236, 194, + 181, 156, 241, 35, 232, 9, 159, 4, 166, 114, 64, 17, 238, 81, 45, 149, 246, 230, 19, 206, 5, + 32, 0, 229, 232, 96, 40, 27, 42, 229, 74, 187, 121, 137, 94, 87, 197, 134, 9, 128, 187, 209, + 125, 112, 130, 153, 34, 103, 150, 223, 78, 208, 76, 194, 32, 1, 100, 26, 54, 125, 116, 61, 194, + 159, 148, 251, 27, 155, 109, 210, 52, 127, 174, 154, 134, 79, 0, 141, 136, 16, 13, 211, 200, + 65, 58, 146, 239, 32, 7, 6, 136, 117, 146, 55, 105, 142, 209, 136, 219, 203, 115, 223, 180, + 210, 28, 11, 196, 55, 79, 90, 201, 103, 72, 12, 59, 45, 112, 201, 24, 65, 32, 0, 7, 94, 141, + 111, 191, 0, 195, 202, 200, 119, 6, 132, 212, 134, 216, 57, 227, 2, 221, 200, 201, 178, 143, + 58, 84, 219, 80, 220, 2, 253, 92, 32, 1, 50, 62, 152, 210, 206, 241, 144, 59, 40, 86, 111, 87, + 191, 90, 95, 229, 37, 203, 207, 141, 0, 20, 107, 249, 224, 98, 219, 39, 215, 89, 68, 3, 7, 71, + 144, 201, 240, 215, 250, 18, 240, 139, 173, 118, 113, 1, 120, 216, 213, 149, 8, 143, 89, 203, + 46, 33, 53, 71, 53, 253, 178, 194, 46, 59, 100, 171, 107, 164, 145, 127, 127, 217, 45, 10, 226, + 211, 248, 68, 149, 90, 192, 188, 192, 30, 254, 73, 35, 168, 255, 180, 188, 48, 68, 197, 148, + 222, 213, 42, 119, 202, 24, 60, 23, 71, 111, 65, 143, 210, 93, 54, 41, 77, 47, 122, 249, 201, + 154, 44, 97, 221, 116, 227, 181, 225, 50, 142, 87, 197, 106, 67, 105, 202, 95, 192, 177, 11, + 247, 91, 10, 64, 41, 240, 160, 50, 16, 165, 50, 96, 148, 30, 52, 10, 84, 26, 209, 100, 142, 24, + 51, 60, 35, 69, 6, 89, 219, 68, 130, 201, 173, 86, 12, 163, 244, 36, 211, 115, 211, 9, 223, + 146, 68, 41, 67, 173, 118, 97, 81, 9, 162, 13, 100, 154, 99, 129, 111, 221, 39, 86, 255, 239, + 138, 10, 47, 174, 101, 145, 166, 252, 152, 243, 80, 232, 77, 7, 203, 91, 247, 4, 116, 31, 134, + 174, 248, 93, 33, 95, 169, 207, 128, 27, 89, 1, 160, 211, 197, 106, 105, 8, 18, 198, 172, 47, + 142, 177, 111, 50, 53, 251, 44, 163, 208, 234, 221, 23, 2, 131, 243, 7, 71, 144, 201, 240, 215, + 250, 18, 240, 139, 173, 118, 113, 1, 120, 216, 213, 149, 8, 143, 89, 203, 46, 33, 53, 71, 53, + 253, 178, 194, 46, 59, 100, 171, 107, 164, 145, 127, 127, 217, 45, 10, 226, 211, 248, 68, 149, + 90, 192, 188, 192, 30, 254, 73, 35, 168, 255, 180, 188, 48, 68, 197, 148, 222, 213, 42, 119, + 202, 24, 60, 23, 71, 111, 65, 143, 210, 93, 54, 41, 77, 47, 122, 249, 201, 154, 44, 97, 221, + 116, 227, 181, 225, 50, 142, 87, 197, 106, 67, 105, 202, 95, 192, 177, 11, 247, 91, 10, 64, 41, + 240, 160, 50, 16, 165, 50, 96, 148, 30, 52, 10, 84, 26, 209, 100, 142, 24, 51, 60, 35, 69, 6, + 89, 219, 68, 130, 201, 173, 86, 12, 163, 244, 36, 211, 115, 211, 9, 223, 146, 68, 41, 67, 173, + 118, 97, 81, 9, 162, 13, 100, 154, 99, 129, 111, 221, 39, 86, 255, 239, 138, 10, 47, 174, 101, + 145, 166, 252, 152, 243, 80, 232, 77, 7, 203, 91, 247, 4, 116, 31, 134, 174, 248, 93, 33, 95, + 169, 207, 128, 27, 89, 1, 160, 211, 197, 106, 105, 8, 18, 198, 172, 47, 142, 177, 111, 50, 53, + 251, 44, 163, 208, 234, 221, 23, 2, 131, 243, 2, 32, 0, 121, 56, 250, 191, 145, 92, 188, 216, + 190, 101, 171, 195, 113, 99, 119, 186, 15, 113, 37, 206, 159, 148, 1, 23, 162, 196, 34, 66, + 103, 235, 2, 32, 1, 185, 21, 77, 118, 124, 60, 175, 74, 130, 102, 105, 31, 124, 163, 66, 180, + 173, 28, 124, 14, 110, 11, 98, 167, 60, 140, 179, 22, 255, 254, 168, 2, 32, 7, 93, 221, 51, + 199, 202, 203, 104, 105, 110, 183, 155, 74, 106, 124, 166, 229, 248, 123, 245, 231, 137, 153, + 69, 29, 164, 232, 54, 185, 177, 144, 156, 32, 6, 92, 247, 229, 32, 239, 44, 49, 110, 136, 183, + 170, 109, 161, 234, 43, 34, 77, 148, 180, 29, 121, 194, 196, 241, 24, 8, 254, 84, 31, 188, 206, + 8, 194, 103, 122, 106, 133, 250, 174, 125, 151, 130, 221, 8, 187, 134, 62, 93, 238, 46, 68, 61, + 167, 238, 72, 165, 138, 70, 15, 221, 227, 108, 159, 211, 131, 70, 125, 230, 181, 220, 27, 253, + 58, 252, 147, 128, 189, 210, 74, 207, 212, 17, 72, 163, 85, 131, 170, 38, 103, 189, 141, 248, + 61, 249, 136, 57, 241, 119, 208, 181, 134, 105, 21, 33, 166, 131, 235, 219, 32, 129, 118, 34, + 232, 235, 114, 0, 195, 67, 28, 186, 223, 56, 179, 11, 237, 203, 61, 182, 16, 240, 189, 10, 233, + 240, 239, 118, 135, 208, 4, 191, 121, 46, 76, 28, 224, 7, 202, 70, 81, 20, 212, 158, 154, 216, + 34, 129, 208, 84, 111, 9, 55, 77, 55, 213, 97, 55, 55, 220, 12, 76, 40, 77, 61, 52, 184, 157, + 58, 168, 66, 193, 21, 82, 135, 102, 126, 82, 211, 245, 178, 95, 90, 192, 177, 115, 174, 223, + 201, 148, 203, 101, 124, 93, 251, 60, 92, 6, 129, 157, 253, 12, 39, 179, 125, 49, 33, 231, 78, + 160, 206, 9, 108, 129, 86, 213, 205, 155, 79, 131, 108, 160, 52, 154, 213, 1, 2, 193, 57, 70, + 160, 111, 191, 152, 93, 207, 46, 157, 48, 185, 149, 118, 242, 43, 120, 37, 73, 122, 229, 1, + 245, 56, 5, 205, 93, 162, 166, 145, 96, 161, 33, 161, 65, 184, 51, 169, 25, 255, 44, 212, 36, + 131, 40, 81, 24, 243, 77, 184, 160, 102, 8, 80, 73, 236, 40, 41, 138, 13, 203, 77, 220, 39, + 192, 112, 219, 4, 167, 70, 28, 67, 119, 81, 103, 37, 40, 147, 203, 205, 85, 240, 83, 155, 176, + 131, 70, 125, 230, 181, 220, 27, 253, 58, 252, 147, 128, 189, 210, 74, 207, 212, 17, 72, 163, + 85, 131, 170, 38, 103, 189, 141, 248, 61, 249, 136, 57, 241, 119, 208, 181, 134, 105, 21, 33, + 166, 131, 235, 219, 32, 129, 118, 34, 232, 235, 114, 0, 195, 67, 28, 186, 223, 56, 179, 11, + 237, 203, 61, 182, 16, 240, 189, 10, 233, 240, 239, 118, 135, 208, 4, 191, 121, 46, 76, 28, + 224, 7, 202, 70, 81, 20, 212, 158, 154, 216, 34, 129, 208, 84, 111, 9, 55, 77, 55, 213, 97, 55, + 55, 220, 12, 76, 40, 77, 61, 52, 184, 157, 58, 168, 66, 193, 21, 82, 135, 102, 126, 82, 211, + 245, 178, 95, 90, 192, 177, 115, 174, 223, 201, 148, 203, 101, 124, 93, 251, 60, 92, 6, 129, + 157, 253, 12, 39, 179, 125, 49, 33, 231, 78, 160, 206, 9, 108, 129, 86, 213, 205, 155, 79, 131, + 108, 160, 52, 154, 213, 1, 2, 193, 57, 70, 160, 111, 191, 152, 93, 207, 46, 157, 48, 185, 149, + 118, 242, 43, 120, 37, 73, 122, 229, 1, 245, 56, 5, 205, 93, 162, 166, 145, 96, 161, 33, 161, + 65, 184, 51, 169, 25, 255, 44, 212, 36, 131, 40, 81, 24, 243, 77, 184, 160, 102, 36, 32, 3, + 129, 119, 190, 233, 95, 78, 6, 164, 208, 157, 160, 250, 100, 42, 203, 176, 155, 49, 231, 195, + 75, 98, 177, 115, 153, 74, 226, 248, 25, 241, 7, 32, 6, 30, 171, 74, 37, 11, 19, 154, 170, 254, + 51, 117, 130, 110, 115, 62, 192, 170, 139, 56, 62, 57, 158, 94, 28, 100, 88, 173, 48, 170, 207, + 140, 32, 5, 20, 146, 220, 46, 138, 162, 114, 98, 139, 169, 186, 205, 89, 171, 101, 133, 249, + 107, 248, 175, 10, 75, 108, 59, 159, 233, 43, 80, 213, 109, 94, 32, 3, 98, 145, 109, 12, 196, + 173, 204, 125, 79, 154, 75, 3, 29, 114, 109, 4, 145, 157, 223, 188, 165, 15, 192, 123, 214, + 165, 253, 55, 68, 28, 81, 32, 2, 10, 123, 248, 147, 236, 105, 36, 203, 106, 196, 189, 79, 212, + 58, 99, 118, 26, 109, 22, 220, 58, 70, 105, 25, 56, 26, 154, 2, 136, 245, 131, 32, 7, 211, 194, + 187, 70, 236, 198, 225, 140, 232, 165, 89, 61, 51, 255, 74, 133, 166, 176, 129, 11, 21, 122, + 161, 83, 72, 148, 74, 11, 132, 45, 214, 32, 0, 55, 64, 185, 27, 30, 92, 171, 102, 124, 242, + 227, 150, 231, 16, 104, 44, 2, 124, 152, 92, 159, 52, 70, 171, 219, 107, 38, 84, 198, 8, 37, + 32, 4, 27, 160, 92, 141, 143, 46, 94, 51, 62, 121, 113, 203, 115, 136, 52, 22, 1, 62, 76, 46, + 79, 154, 35, 85, 237, 181, 147, 42, 99, 4, 19, 32, 3, 75, 39, 32, 29, 166, 11, 219, 98, 39, + 181, 83, 161, 195, 143, 239, 231, 232, 8, 88, 81, 117, 221, 8, 36, 251, 170, 187, 80, 31, 93, + 194, 32, 3, 6, 149, 89, 255, 239, 143, 122, 54, 188, 9, 228, 199, 26, 104, 189, 59, 237, 133, + 253, 67, 140, 226, 103, 143, 213, 180, 223, 107, 159, 236, 170, 32, 3, 60, 210, 185, 66, 121, + 78, 183, 213, 211, 116, 101, 54, 192, 162, 238, 230, 148, 228, 44, 51, 70, 109, 7, 123, 71, + 213, 240, 152, 54, 164, 65, 32, 3, 159, 58, 200, 43, 22, 119, 51, 45, 204, 247, 143, 15, 4, 98, + 94, 200, 132, 49, 204, 255, 169, 167, 158, 72, 20, 54, 106, 231, 84, 92, 52, 32, 1, 218, 176, + 67, 127, 66, 251, 233, 84, 65, 226, 188, 240, 237, 20, 202, 237, 113, 7, 46, 155, 214, 62, 226, + 28, 23, 237, 26, 102, 55, 39, 176, 32, 6, 232, 26, 234, 163, 156, 102, 112, 157, 20, 97, 94, + 108, 84, 24, 159, 81, 20, 93, 58, 189, 253, 163, 51, 224, 158, 57, 184, 122, 155, 142, 81, 32, + 4, 177, 100, 103, 40, 172, 167, 228, 151, 18, 169, 73, 242, 51, 216, 37, 133, 113, 151, 207, + 153, 76, 225, 144, 106, 83, 236, 205, 248, 59, 162, 225, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 6, 71, 147, 94, 188, 32, + 176, 254, 19, 157, 26, 137, 172, 32, 163, 155, 79, 52, 255, 175, 229, 18, 186, 113, 105, 132, + 104, 52, 163, 248, 142, 208, 32, 4, 166, 238, 8, 11, 43, 74, 210, 63, 25, 67, 189, 207, 187, + 245, 253, 52, 248, 231, 14, 189, 154, 43, 250, 35, 76, 37, 215, 135, 65, 227, 22, 32, 4, 47, + 103, 10, 197, 213, 252, 162, 42, 145, 131, 167, 96, 151, 25, 47, 48, 38, 129, 163, 167, 107, + 249, 172, 38, 253, 151, 177, 87, 200, 173, 28, 32, 7, 186, 189, 130, 192, 153, 251, 2, 33, 229, + 165, 127, 180, 249, 35, 117, 112, 33, 115, 145, 147, 172, 33, 142, 187, 170, 4, 139, 29, 224, + 160, 210, 32, 4, 28, 184, 49, 152, 3, 85, 40, 119, 139, 199, 84, 181, 196, 60, 206, 122, 105, + 218, 219, 126, 46, 144, 52, 99, 90, 200, 68, 230, 112, 50, 7, 32, 0, 143, 89, 58, 248, 81, 33, + 199, 61, 217, 53, 87, 115, 72, 77, 3, 61, 95, 207, 90, 227, 78, 127, 46, 65, 119, 75, 251, 158, + 31, 6, 8, 32, 0, 1, 96, 195, 251, 88, 10, 103, 180, 61, 142, 122, 134, 133, 249, 113, 231, 174, + 231, 255, 139, 209, 47, 182, 98, 238, 34, 83, 54, 254, 99, 49, 32, 1, 82, 59, 58, 227, 77, 153, + 24, 209, 88, 85, 186, 180, 254, 171, 109, 253, 16, 57, 88, 219, 90, 239, 17, 0, 17, 100, 240, + 220, 183, 85, 182, 32, 1, 142, 178, 105, 92, 163, 212, 56, 242, 59, 143, 191, 116, 0, 215, 124, + 174, 173, 137, 49, 254, 194, 89, 242, 69, 21, 189, 14, 89, 248, 245, 88, 32, 2, 54, 63, 177, + 227, 177, 184, 102, 42, 51, 209, 207, 67, 54, 99, 26, 65, 219, 56, 113, 205, 38, 44, 209, 138, + 155, 63, 110, 28, 200, 151, 241, 32, 7, 229, 236, 148, 234, 123, 72, 117, 113, 139, 172, 110, + 99, 178, 167, 122, 62, 13, 136, 204, 74, 10, 226, 91, 173, 138, 154, 97, 151, 123, 223, 206, + 32, 5, 85, 34, 196, 27, 77, 181, 221, 26, 73, 1, 22, 10, 80, 110, 66, 21, 49, 199, 67, 162, + 116, 49, 144, 44, 61, 99, 198, 139, 76, 135, 36, 32, 4, 200, 179, 24, 128, 240, 75, 3, 198, + 248, 102, 12, 18, 182, 96, 105, 231, 198, 74, 33, 224, 93, 145, 21, 175, 17, 1, 237, 91, 204, + 229, 171, 32, 4, 227, 19, 99, 106, 229, 101, 222, 183, 158, 106, 45, 38, 55, 145, 83, 24, 92, + 146, 26, 59, 11, 30, 30, 92, 238, 22, 85, 224, 224, 21, 141, 32, 5, 161, 95, 191, 179, 148, 84, + 11, 254, 155, 247, 34, 140, 107, 99, 2, 47, 150, 238, 214, 74, 231, 255, 38, 86, 141, 136, 194, + 251, 152, 182, 131, 32, 5, 102, 212, 36, 93, 231, 48, 242, 148, 77, 217, 10, 122, 125, 133, + 208, 97, 3, 54, 255, 252, 0, 28, 14, 96, 187, 107, 212, 242, 23, 182, 175, 32, 7, 155, 119, + 145, 237, 64, 119, 216, 95, 27, 96, 211, 100, 166, 152, 172, 113, 70, 11, 18, 181, 196, 177, + 34, 236, 37, 32, 167, 27, 170, 157, 230, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 7, 255, 255, 255, 254, 239, 253, 240, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 239, 255, 225, 36, 32, 3, 199, 206, 107, 71, 236, 106, 177, 255, 227, 253, 123, 135, + 103, 188, 215, 62, 209, 46, 59, 208, 236, 108, 98, 191, 187, 157, 98, 142, 102, 121, 68, 32, 6, + 79, 95, 173, 160, 177, 131, 243, 161, 131, 164, 120, 178, 230, 68, 12, 56, 5, 13, 48, 171, 116, + 183, 133, 250, 53, 60, 106, 41, 207, 159, 70, 32, 3, 133, 132, 119, 163, 155, 63, 179, 68, 227, + 9, 34, 105, 250, 219, 126, 152, 35, 54, 6, 188, 215, 173, 99, 99, 246, 139, 178, 182, 111, 81, + 89, 32, 3, 16, 73, 63, 92, 193, 214, 229, 171, 227, 122, 234, 245, 100, 209, 126, 146, 63, 98, + 124, 212, 85, 39, 132, 238, 183, 145, 147, 71, 220, 109, 4, 32, 3, 194, 163, 50, 173, 39, 36, + 9, 15, 158, 149, 55, 207, 227, 100, 8, 83, 61, 204, 168, 66, 179, 54, 162, 168, 108, 22, 76, + 96, 202, 181, 204, 32, 2, 89, 76, 2, 204, 217, 35, 122, 196, 176, 124, 127, 210, 89, 82, 251, + 217, 83, 3, 112, 210, 231, 167, 157, 230, 105, 113, 233, 134, 228, 23, 85, 32, 3, 30, 155, 129, + 254, 166, 255, 133, 144, 179, 238, 60, 171, 69, 71, 87, 43, 120, 24, 0, 133, 178, 36, 127, 188, + 104, 76, 223, 203, 230, 99, 170, 32, 1, 143, 77, 192, 255, 83, 127, 194, 200, 89, 247, 30, 85, + 162, 163, 171, 149, 188, 12, 0, 66, 217, 18, 63, 222, 52, 38, 111, 229, 243, 49, 213, 32, 2, + 172, 109, 220, 174, 129, 204, 2, 220, 164, 38, 94, 136, 55, 130, 146, 75, 17, 206, 218, 3, 102, + 105, 224, 101, 153, 229, 87, 246, 68, 221, 135, 32, 1, 149, 198, 58, 96, 9, 49, 126, 79, 110, + 13, 207, 32, 134, 103, 226, 155, 88, 36, 213, 112, 46, 32, 203, 202, 12, 4, 107, 213, 240, 153, + 108, 32, 6, 193, 52, 80, 237, 249, 242, 12, 225, 6, 202, 166, 240, 255, 170, 218, 37, 43, 77, + 92, 142, 72, 136, 146, 178, 206, 145, 59, 149, 98, 224, 13, 32, 3, 83, 150, 131, 170, 224, 26, + 20, 11, 16, 234, 249, 188, 157, 51, 86, 97, 143, 44, 30, 124, 95, 47, 52, 177, 91, 85, 243, + 131, 66, 78, 105, 32, 1, 149, 172, 10, 54, 235, 79, 163, 113, 233, 57, 53, 160, 204, 17, 63, + 219, 80, 112, 152, 37, 92, 157, 224, 143, 148, 148, 85, 62, 136, 248, 71, 32, 4, 109, 1, 100, + 72, 51, 43, 48, 196, 211, 101, 180, 191, 222, 79, 39, 113, 135, 136, 221, 171, 144, 253, 79, + 224, 238, 92, 172, 253, 188, 250, 126, 32, 0, 27, 71, 174, 82, 241, 161, 177, 90, 224, 221, + 169, 189, 85, 88, 80, 56, 247, 141, 72, 183, 194, 95, 104, 102, 247, 0, 118, 130, 41, 193, 219, + 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 32, 4, 82, 54, 7, 49, 101, 106, 214, 102, 1, 233, 244, 193, 93, 130, 32, 168, 188, 230, + 188, 102, 61, 93, 127, 170, 101, 59, 128, 142, 1, 166, 157, 32, 5, 22, 159, 20, 167, 73, 185, + 156, 152, 182, 115, 119, 33, 171, 4, 130, 136, 241, 249, 169, 27, 145, 189, 187, 225, 208, 142, + 201, 30, 217, 49, 142, 32, 1, 216, 131, 104, 255, 119, 205, 58, 40, 87, 24, 234, 123, 77, 230, + 124, 147, 18, 242, 223, 147, 224, 14, 78, 131, 214, 46, 209, 231, 96, 118, 128, 32, 6, 14, 2, + 93, 58, 182, 69, 1, 144, 4, 105, 104, 4, 165, 212, 174, 81, 110, 147, 28, 86, 3, 222, 22, 192, + 82, 65, 67, 142, 232, 202, 154, 32, 0, 29, 182, 99, 6, 235, 18, 171, 131, 144, 6, 40, 124, 61, + 43, 49, 232, 111, 44, 32, 9, 31, 137, 242, 110, 97, 17, 83, 106, 154, 215, 208, 32, 3, 235, + 152, 197, 209, 31, 116, 249, 67, 15, 152, 183, 253, 89, 66, 168, 244, 218, 238, 163, 71, 220, + 170, 229, 51, 105, 118, 51, 218, 30, 54, 126, 32, 3, 85, 95, 59, 189, 104, 31, 126, 237, 244, + 220, 58, 232, 85, 74, 3, 57, 252, 91, 195, 83, 196, 252, 25, 226, 26, 141, 71, 67, 177, 5, 6, + 32, 0, 46, 64, 74, 73, 217, 110, 9, 7, 230, 209, 80, 169, 79, 124, 10, 37, 62, 144, 81, 146, + 215, 48, 78, 42, 83, 60, 74, 132, 253, 137, 146, 32, 5, 0, 131, 147, 109, 164, 234, 81, 154, + 201, 228, 8, 110, 246, 226, 165, 245, 22, 162, 158, 87, 9, 197, 77, 179, 233, 77, 181, 211, + 242, 158, 42, 32, 6, 224, 18, 1, 92, 0, 105, 103, 2, 32, 249, 162, 231, 161, 253, 97, 76, 1, + 125, 180, 142, 51, 60, 18, 236, 206, 224, 84, 246, 57, 248, 19, 32, 7, 190, 69, 246, 70, 79, + 127, 166, 210, 157, 182, 194, 131, 128, 118, 120, 81, 24, 111, 209, 9, 32, 207, 178, 229, 124, + 201, 148, 246, 246, 142, 205, 32, 4, 134, 186, 120, 56, 3, 243, 134, 229, 174, 74, 246, 217, + 210, 192, 228, 1, 148, 39, 70, 28, 154, 56, 232, 132, 11, 232, 154, 249, 112, 55, 217, 32, 7, + 56, 41, 190, 58, 231, 12, 246, 237, 190, 195, 110, 213, 75, 31, 17, 222, 134, 100, 120, 71, 69, + 72, 1, 230, 15, 217, 66, 4, 248, 16, 124, 32, 5, 188, 38, 77, 159, 63, 83, 169, 219, 60, 152, + 18, 161, 242, 114, 61, 130, 47, 11, 179, 82, 207, 98, 10, 144, 216, 130, 239, 83, 193, 199, + 178, 32, 7, 132, 124, 61, 241, 128, 83, 243, 79, 248, 74, 43, 81, 202, 182, 233, 133, 100, 14, + 57, 111, 26, 126, 150, 64, 165, 234, 134, 181, 34, 55, 165, 32, 3, 31, 73, 229, 68, 144, 202, + 228, 21, 130, 252, 252, 27, 80, 25, 50, 89, 42, 169, 99, 161, 108, 162, 154, 112, 242, 72, 137, + 122, 241, 112, 17, 32, 4, 243, 143, 69, 72, 200, 7, 170, 13, 200, 59, 116, 20, 205, 217, 246, + 128, 202, 68, 44, 142, 204, 203, 42, 76, 164, 238, 72, 153, 122, 75, 246, 32, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 7, 255, + 255, 255, 254, 239, 253, 240, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 239, 255, 225, 1, 8, 237, 179, 98, 88, 233, 51, 210, 6, + 167, 130, 93, 55, 232, 127, 156, 91, 76, 239, 68, 134, 208, 25, 99, 61, 106, 114, 100, 100, + 202, 115, 37, 44, 218, 2, 186, 144, 37, 166, 153, 158, 219, 68, 61, 12, 200, 233, 21, 123, 232, + 231, 149, 163, 253, 55, 215, 25, 161, 141, 13, 65, 220, 15, 139, 189, 37, 60, 56, 238, 45, 238, + 233, 34, 144, 42, 54, 124, 105, 102, 152, 94, 136, 247, 211, 162, 165, 228, 46, 138, 68, 134, + 151, 182, 34, 159, 199, 90, 226, 219, 154, 242, 175, 197, 229, 250, 42, 205, 231, 1, 122, 176, + 198, 108, 147, 169, 190, 77, 175, 107, 114, 43, 235, 227, 197, 214, 26, 158, 224, 83, 185, 9, + 104, 243, 92, 148, 83, 190, 60, 176, 106, 175, 140, 147, 73, 101, 237, 188, 108, 19, 65, 116, + 145, 149, 253, 252, 105, 5, 138, 211, 73, 79, 204, 232, 61, 172, 180, 83, 99, 114, 24, 173, + 181, 9, 249, 66, 244, 243, 28, 6, 22, 9, 93, 177, 36, 120, 20, 204, 68, 64, 7, 53, 234, 171, + 124, 38, 37, 149, 112, 6, 12, 208, 212, 253, 153, 162, 216, 88, 168, 5, 228, 76, 95, 190, 212, + 22, 65, 3, 76, 99, 63, 137, 25, 155, 214, 236, 74, 55, 153, 234, 37, 81, 232, 1, 225, 172, 216, + 197, 57, 78, 49, 214, 188, 52, 42, 124, 251, 8, 13, 109, 160, 212, 245, 228, 41, 239, 40, 109, + 8, 146, 194, 27, 204, 132, 238, 53, 16, 202, 207, 17, 239, 164, 33, 229, 252, 20, 224, 104, + 164, 17, 183, 14, 67, 59, 128, 223, 116, 189, 121, 132, 18, 218, 2, 186, 144, 37, 166, 153, + 158, 219, 68, 61, 12, 200, 233, 21, 123, 232, 231, 149, 163, 253, 55, 215, 25, 161, 141, 13, + 65, 220, 15, 139, 189, 37, 60, 56, 238, 45, 238, 233, 34, 144, 42, 54, 124, 105, 102, 152, 94, + 136, 247, 211, 162, 165, 228, 46, 138, 68, 134, 151, 182, 34, 159, 199, 90, 226, 219, 154, 242, + 175, 197, 229, 250, 42, 205, 231, 1, 122, 176, 198, 108, 147, 169, 190, 77, 175, 107, 114, 43, + 235, 227, 197, 214, 26, 158, 224, 83, 185, 9, 104, 243, 92, 148, 83, 190, 60, 176, 106, 175, + 140, 147, 73, 101, 237, 188, 108, 19, 65, 116, 145, 149, 253, 252, 105, 5, 138, 211, 73, 79, + 204, 232, 61, 172, 180, 83, 99, 114, 24, 173, 181, 9, 249, 66, 244, 243, 28, 6, 22, 9, 93, 177, + 36, 120, 20, 204, 68, 64, 7, 53, 234, 171, 124, 38, 37, 149, 112, 6, 12, 208, 212, 253, 153, + 162, 216, 88, 168, 5, 228, 76, 95, 190, 212, 22, 65, 3, 76, 99, 63, 137, 25, 155, 214, 236, 74, + 55, 153, 234, 37, 81, 232, 1, 225, 172, 216, 197, 57, 78, 49, 214, 188, 52, 42, 124, 251, 8, + 13, 109, 160, 212, 245, 228, 41, 239, 40, 109, 23, 32, 2, 17, 191, 13, 65, 119, 85, 249, 17, + 92, 237, 204, 127, 184, 15, 49, 197, 226, 130, 126, 99, 36, 96, 197, 179, 187, 31, 31, 233, + 160, 68, 241, 32, 7, 206, 4, 40, 55, 114, 159, 241, 252, 234, 135, 168, 67, 180, 39, 1, 141, + 115, 86, 91, 161, 177, 119, 16, 209, 235, 177, 203, 87, 86, 251, 228, 32, 7, 206, 4, 40, 55, + 114, 159, 241, 252, 234, 135, 168, 67, 180, 39, 1, 141, 115, 86, 91, 161, 177, 119, 16, 209, + 235, 177, 203, 87, 86, 251, 228, 32, 7, 206, 4, 40, 55, 114, 159, 241, 252, 234, 135, 168, 67, + 180, 39, 1, 141, 115, 86, 91, 161, 177, 119, 16, 209, 235, 177, 203, 87, 86, 251, 228, 32, 5, + 126, 4, 169, 71, 226, 140, 162, 112, 243, 69, 253, 126, 213, 128, 226, 16, 138, 133, 74, 70, + 108, 227, 47, 153, 174, 224, 203, 12, 147, 52, 200, 32, 6, 193, 153, 141, 245, 54, 105, 175, + 163, 190, 14, 56, 253, 228, 176, 47, 69, 123, 172, 229, 19, 43, 113, 9, 64, 97, 146, 143, 28, + 203, 68, 10, 32, 0, 122, 157, 210, 13, 110, 158, 52, 190, 198, 246, 219, 175, 7, 178, 97, 22, + 253, 39, 96, 202, 39, 176, 47, 88, 122, 181, 4, 80, 217, 224, 135, 32, 2, 1, 65, 165, 19, 156, + 3, 194, 188, 84, 56, 251, 199, 184, 63, 212, 35, 203, 230, 255, 53, 40, 165, 222, 102, 153, + 115, 131, 114, 111, 166, 151, 32, 3, 213, 7, 129, 95, 200, 126, 66, 11, 191, 185, 128, 148, 80, + 66, 169, 92, 172, 239, 52, 14, 53, 250, 103, 91, 190, 3, 234, 137, 149, 105, 144, 32, 3, 43, + 147, 169, 240, 19, 141, 49, 203, 199, 89, 254, 62, 221, 82, 120, 12, 34, 18, 249, 33, 53, 55, + 248, 38, 98, 227, 188, 150, 92, 244, 204, 32, 7, 27, 152, 244, 181, 72, 109, 103, 173, 57, 198, + 123, 161, 69, 99, 86, 52, 64, 81, 176, 204, 94, 127, 95, 69, 136, 164, 152, 230, 3, 174, 14, + 32, 3, 247, 63, 85, 225, 79, 59, 246, 5, 110, 6, 58, 2, 194, 174, 172, 211, 221, 136, 206, 6, + 136, 213, 91, 112, 25, 229, 153, 20, 36, 168, 27, 32, 6, 131, 91, 36, 183, 36, 123, 45, 244, + 20, 248, 176, 94, 105, 52, 114, 33, 67, 143, 103, 160, 49, 228, 190, 75, 52, 26, 237, 192, 77, + 15, 46, 32, 2, 168, 103, 36, 140, 83, 102, 213, 43, 88, 27, 226, 198, 236, 195, 184, 25, 176, + 119, 124, 140, 173, 36, 73, 154, 193, 159, 230, 137, 186, 29, 71, 32, 7, 168, 168, 94, 122, + 106, 150, 128, 222, 47, 144, 21, 246, 173, 13, 236, 165, 178, 44, 71, 216, 199, 138, 141, 122, + 226, 164, 156, 123, 246, 17, 134, 32, 5, 9, 164, 60, 239, 241, 202, 222, 129, 1, 170, 58, 6, + 68, 66, 5, 242, 35, 239, 58, 230, 242, 157, 55, 32, 42, 0, 5, 43, 3, 101, 213, 32, 4, 51, 23, + 189, 56, 46, 233, 132, 3, 173, 9, 115, 191, 198, 227, 211, 90, 195, 182, 222, 243, 230, 167, + 143, 52, 49, 35, 53, 200, 207, 120, 99, 32, 0, 251, 241, 177, 6, 220, 102, 123, 6, 27, 124, 19, + 183, 66, 27, 37, 6, 216, 64, 143, 188, 82, 19, 147, 145, 80, 221, 202, 191, 60, 91, 86, 32, 0, + 214, 134, 34, 147, 200, 13, 138, 217, 65, 115, 234, 191, 204, 190, 82, 70, 202, 191, 80, 101, + 118, 51, 178, 192, 62, 242, 200, 56, 54, 192, 9, 32, 1, 110, 27, 195, 98, 170, 43, 59, 217, + 232, 98, 32, 22, 139, 57, 70, 169, 63, 110, 250, 22, 236, 155, 154, 100, 47, 198, 140, 235, + 204, 111, 217, 32, 3, 75, 35, 91, 24, 169, 136, 139, 155, 133, 24, 28, 191, 73, 57, 143, 9, + 241, 206, 251, 36, 93, 85, 135, 152, 143, 37, 92, 177, 223, 15, 184, 32, 0, 250, 132, 115, 105, + 253, 239, 192, 45, 73, 230, 199, 246, 175, 224, 180, 183, 37, 138, 177, 98, 51, 90, 49, 103, + 207, 76, 68, 99, 22, 187, 176, 32, 3, 201, 205, 13, 7, 146, 33, 137, 199, 197, 4, 205, 247, 22, + 234, 67, 160, 44, 65, 218, 237, 87, 174, 145, 11, 246, 234, 123, 215, 163, 253, 153, 23, 32, 7, + 40, 186, 42, 229, 144, 128, 104, 28, 141, 143, 69, 147, 62, 158, 76, 84, 172, 75, 247, 6, 108, + 67, 166, 2, 173, 252, 132, 4, 108, 124, 8, 32, 7, 83, 140, 31, 122, 3, 69, 159, 7, 232, 129, + 164, 132, 12, 48, 240, 50, 12, 148, 235, 148, 110, 234, 156, 238, 71, 230, 119, 211, 1, 228, + 27, 32, 7, 83, 140, 31, 122, 3, 69, 159, 7, 232, 129, 164, 132, 12, 48, 240, 50, 12, 148, 235, + 148, 110, 234, 156, 238, 71, 230, 119, 211, 1, 228, 27, 32, 7, 83, 140, 31, 122, 3, 69, 159, 7, + 232, 129, 164, 132, 12, 48, 240, 50, 12, 148, 235, 148, 110, 234, 156, 238, 71, 230, 119, 211, + 1, 228, 27, 32, 6, 81, 4, 5, 187, 206, 59, 110, 65, 84, 150, 241, 236, 179, 248, 177, 175, 111, + 158, 196, 105, 92, 71, 203, 232, 52, 75, 138, 69, 207, 241, 248, 32, 2, 128, 65, 140, 233, 102, + 199, 198, 75, 33, 0, 137, 159, 117, 51, 62, 172, 159, 215, 245, 74, 173, 55, 140, 15, 213, 196, + 132, 85, 135, 141, 98, 32, 0, 79, 210, 136, 54, 105, 220, 119, 179, 48, 57, 215, 193, 250, 145, + 108, 224, 19, 203, 205, 248, 52, 89, 144, 152, 17, 12, 251, 207, 67, 78, 64, 32, 4, 68, 211, + 92, 201, 60, 140, 253, 162, 89, 86, 1, 183, 232, 242, 134, 180, 46, 79, 222, 180, 52, 206, 84, + 243, 126, 55, 22, 133, 20, 72, 199, 32, 6, 186, 118, 199, 147, 149, 206, 181, 154, 137, 217, + 96, 17, 196, 58, 155, 244, 155, 82, 24, 143, 113, 126, 35, 144, 132, 72, 183, 54, 130, 16, 139, + 32, 2, 82, 36, 138, 153, 216, 233, 108, 58, 21, 22, 112, 231, 100, 131, 225, 204, 114, 67, 87, + 249, 103, 22, 219, 175, 183, 229, 88, 61, 185, 173, 141, 32, 6, 50, 107, 206, 160, 16, 163, + 226, 125, 10, 148, 73, 7, 46, 253, 201, 6, 236, 13, 218, 23, 224, 219, 131, 165, 46, 231, 93, + 204, 232, 50, 131, 32, 0, 239, 92, 91, 87, 138, 39, 92, 122, 130, 163, 126, 38, 34, 40, 255, + 69, 139, 139, 45, 213, 190, 8, 87, 196, 235, 249, 168, 78, 37, 250, 199, 32, 5, 120, 113, 181, + 132, 210, 218, 53, 230, 246, 181, 76, 26, 15, 74, 72, 106, 31, 116, 173, 140, 91, 219, 183, 32, + 187, 142, 89, 110, 132, 88, 129, 32, 7, 155, 198, 105, 157, 249, 47, 37, 44, 97, 123, 71, 251, + 65, 204, 111, 111, 14, 173, 217, 223, 153, 105, 223, 201, 210, 231, 85, 189, 135, 196, 0, 32, + 6, 200, 219, 128, 22, 203, 43, 126, 142, 87, 15, 86, 37, 243, 106, 43, 56, 156, 131, 15, 81, + 72, 66, 124, 77, 59, 157, 7, 42, 60, 244, 124, 32, 6, 181, 126, 106, 82, 115, 69, 76, 107, 51, + 167, 68, 162, 210, 117, 215, 89, 58, 243, 130, 155, 21, 234, 183, 250, 129, 155, 85, 155, 108, + 151, 140, 32, 0, 166, 82, 192, 45, 78, 203, 142, 155, 201, 20, 171, 193, 107, 184, 156, 89, 2, + 19, 198, 85, 209, 81, 76, 180, 82, 156, 58, 224, 52, 205, 221, 32, 1, 196, 61, 126, 137, 240, + 148, 9, 9, 253, 171, 13, 92, 127, 29, 56, 205, 152, 45, 138, 62, 254, 193, 238, 205, 70, 57, + 121, 179, 242, 138, 251, 32, 4, 75, 100, 121, 255, 134, 223, 225, 177, 159, 210, 35, 241, 156, + 130, 95, 120, 173, 124, 47, 177, 97, 224, 57, 23, 25, 165, 108, 57, 1, 155, 35, 32, 7, 171, 44, + 251, 194, 49, 135, 254, 79, 91, 67, 109, 186, 188, 59, 243, 55, 145, 223, 165, 19, 66, 57, 205, + 129, 32, 175, 119, 209, 167, 220, 183, 32, 5, 212, 43, 29, 105, 249, 35, 186, 54, 219, 114, 24, + 170, 94, 3, 224, 223, 145, 70, 62, 32, 101, 203, 15, 120, 138, 130, 73, 207, 197, 29, 83, 32, + 3, 31, 248, 59, 171, 202, 243, 209, 210, 123, 161, 240, 53, 28, 192, 168, 254, 69, 157, 162, + 74, 58, 196, 12, 171, 253, 192, 65, 67, 179, 176, 37, 32, 2, 180, 24, 98, 175, 164, 83, 76, + 108, 48, 87, 254, 102, 209, 34, 235, 189, 202, 219, 31, 1, 250, 240, 170, 135, 21, 82, 2, 124, + 240, 29, 223, 7, 192, 156, 247, 205, 120, 212, 60, 245, 215, 170, 209, 61, 234, 57, 186, 21, 3, + 201, 140, 27, 79, 94, 235, 24, 172, 136, 92, 51, 137, 84, 9, 162, 91, 13, 118, 116, 9, 129, 94, + 37, 189, 55, 94, 221, 169, 97, 203, 178, 72, 137, 43, 10, 37, 137, 39, 19, 214, 251, 44, 76, + 119, 4, 28, 219, 57, 31, 20, 137, 195, 106, 191, 245, 220, 79, 189, 93, 101, 69, 139, 76, 115, + 50, 176, 17, 248, 92, 90, 164, 247, 161, 171, 5, 122, 189, 196, 196, 66, 244, 153, 153, 71, + 115, 77, 64, 170, 99, 107, 104, 247, 203, 194, 73, 39, 223, 114, 133, 173, 168, 188, 208, 144, + 230, 249, 24, 120, 52, 18, 144, 188, 164, 84, 194, 241, 223, 113, 165, 231, 181, 152, 254, 41, + 240, 73, 64, 234, 214, 216, 171, 198, 249, 179, 124, 117, 181, 227, 21, 88, 139, 201, 99, 94, + 182, 137, 64, 49, 209, 57, 79, 45, 174, 180, 237, 177, 0, 192, 84, 117, 162, 245, 229, 181, + 108, 139, 243, 210, 255, 152, 33, 0, 94, 234, 148, 90, 146, 42, 221, 95, 80, 55, 238, 93, 29, + 130, 15, 78, 32, 160, 44, 76, 21, 121, 200, 67, 65, 126, 167, 75, 214, 73, 208, 141, 214, 158, + 78, 7, 192, 156, 247, 205, 120, 212, 60, 245, 215, 170, 209, 61, 234, 57, 186, 21, 3, 201, 140, + 27, 79, 94, 235, 24, 172, 136, 92, 51, 137, 84, 9, 162, 91, 13, 118, 116, 9, 129, 94, 37, 189, + 55, 94, 221, 169, 97, 203, 178, 72, 137, 43, 10, 37, 137, 39, 19, 214, 251, 44, 76, 119, 4, 28, + 219, 57, 31, 20, 137, 195, 106, 191, 245, 220, 79, 189, 93, 101, 69, 139, 76, 115, 50, 176, 17, + 248, 92, 90, 164, 247, 161, 171, 5, 122, 189, 196, 196, 66, 244, 153, 153, 71, 115, 77, 64, + 170, 99, 107, 104, 247, 203, 194, 73, 39, 223, 114, 133, 173, 168, 188, 208, 144, 230, 249, 24, + 120, 52, 18, 144, 188, 164, 84, 194, 241, 223, 113, 165, 231, 181, 152, 254, 41, 240, 73, 64, + 234, 214, 216, 171, 198, 249, 179, 124, 117, 181, 227, 21, 88, 139, 201, 99, 94, 182, 137, 64, + 49, 209, 57, 79, 45, 174, 180, 237, 177, 0, 192, 84, 117, 162, 245, 229, 181, 108, 139, 243, + 210, 255, 152, 33, 0, 94, 234, 148, 90, 146, 42, 221, 95, 80, 55, 238, 93, 29, 130, 15, 78, 32, + 160, 44, 76, 21, 121, 200, 67, 65, 126, 167, 75, 214, 73, 208, 141, 214, 158, 78, 2, 32, 7, 73, + 235, 9, 96, 20, 1, 215, 159, 45, 71, 249, 155, 149, 166, 224, 99, 74, 236, 37, 102, 72, 166, + 58, 55, 21, 85, 217, 244, 243, 72, 75, 32, 1, 13, 36, 205, 80, 43, 186, 90, 203, 147, 164, 116, + 81, 229, 76, 201, 109, 212, 114, 48, 146, 182, 200, 118, 87, 75, 161, 243, 178, 37, 82, 101, 2, + 32, 6, 9, 177, 156, 115, 142, 155, 161, 253, 247, 214, 243, 170, 39, 98, 33, 204, 207, 94, 91, + 84, 148, 82, 246, 133, 44, 70, 182, 42, 226, 140, 51, 32, 6, 167, 188, 136, 203, 46, 86, 45, + 139, 104, 250, 207, 142, 220, 121, 120, 13, 77, 141, 173, 142, 98, 192, 211, 104, 115, 136, 43, + 207, 116, 81, 241, 8, 44, 69, 185, 80, 55, 3, 222, 29, 34, 112, 141, 158, 251, 32, 144, 58, + 236, 247, 40, 69, 163, 108, 139, 175, 154, 118, 150, 145, 155, 186, 129, 74, 156, 34, 239, 170, + 195, 232, 217, 4, 82, 144, 237, 128, 36, 75, 172, 149, 49, 83, 164, 176, 123, 255, 208, 155, + 144, 249, 250, 146, 255, 221, 62, 114, 94, 108, 213, 105, 135, 23, 255, 209, 119, 48, 26, 243, + 196, 116, 100, 241, 131, 127, 39, 175, 8, 157, 247, 51, 21, 63, 74, 243, 121, 94, 98, 189, 204, + 198, 43, 185, 179, 198, 237, 189, 24, 32, 140, 222, 145, 236, 159, 0, 98, 215, 209, 124, 33, + 167, 49, 213, 50, 139, 220, 60, 210, 221, 125, 168, 113, 133, 214, 212, 35, 65, 15, 46, 66, + 236, 230, 143, 236, 201, 133, 220, 194, 11, 113, 221, 162, 252, 140, 61, 144, 114, 7, 147, 163, + 59, 168, 74, 91, 20, 121, 18, 62, 47, 39, 126, 212, 24, 254, 178, 85, 161, 200, 242, 152, 12, + 170, 188, 64, 83, 185, 115, 79, 110, 157, 110, 36, 70, 237, 105, 66, 144, 121, 111, 142, 106, + 110, 205, 82, 243, 51, 105, 97, 181, 211, 187, 170, 237, 19, 228, 114, 218, 82, 26, 79, 205, + 42, 79, 159, 194, 210, 203, 252, 89, 141, 6, 13, 139, 105, 158, 82, 26, 166, 148, 184, 91, 40, + 185, 45, 214, 150, 78, 230, 134, 109, 250, 24, 78, 249, 49, 197, 186, 141, 6, 8, 146, 74, 18, + 85, 100, 13, 160, 41, 134, 108, 126, 43, 243, 252, 80, 45, 42, 32, 73, 154, 141, 94, 93, 87, + 230, 56, 40, 29, 54, 181, 100, 203, 156, 34, 239, 170, 195, 232, 217, 4, 82, 144, 237, 128, 36, + 75, 172, 149, 49, 83, 164, 176, 123, 255, 208, 155, 144, 249, 250, 146, 255, 221, 62, 114, 94, + 108, 213, 105, 135, 23, 255, 209, 119, 48, 26, 243, 196, 116, 100, 241, 131, 127, 39, 175, 8, + 157, 247, 51, 21, 63, 74, 243, 121, 94, 98, 189, 204, 198, 43, 185, 179, 198, 237, 189, 24, 32, + 140, 222, 145, 236, 159, 0, 98, 215, 209, 124, 33, 167, 49, 213, 50, 139, 220, 60, 210, 221, + 125, 168, 113, 133, 214, 212, 35, 65, 15, 46, 66, 236, 230, 143, 236, 201, 133, 220, 194, 11, + 113, 221, 162, 252, 140, 61, 144, 114, 7, 147, 163, 59, 168, 74, 91, 20, 121, 18, 62, 47, 39, + 126, 212, 24, 254, 178, 85, 161, 200, 242, 152, 12, 170, 188, 64, 83, 185, 115, 79, 110, 157, + 110, 36, 70, 237, 105, 66, 144, 121, 111, 142, 106, 110, 205, 82, 243, 51, 105, 97, 181, 211, + 187, 170, 237, 19, 228, 114, 218, 82, 26, 79, 205, 42, 79, 159, 194, 210, 203, 252, 89, 141, 6, + 13, 139, 105, 158, 82, 26, 166, 148, 184, 91, 40, 185, 45, 214, 150, 78, 230, 134, 109, 250, + 24, 78, 249, 49, 197, 186, 141, 6, 36, 32, 5, 67, 65, 187, 226, 147, 101, 55, 58, 16, 241, 10, + 222, 30, 122, 37, 116, 98, 22, 42, 33, 141, 241, 197, 84, 85, 235, 89, 96, 51, 5, 148, 32, 7, + 57, 166, 250, 191, 201, 145, 30, 36, 33, 78, 36, 110, 97, 41, 23, 14, 208, 158, 12, 171, 238, + 42, 24, 91, 244, 153, 174, 242, 29, 141, 238, 32, 3, 16, 204, 119, 247, 145, 22, 195, 161, 228, + 105, 160, 17, 110, 233, 99, 231, 165, 51, 57, 130, 189, 131, 150, 20, 207, 140, 114, 217, 190, + 119, 155, 32, 1, 84, 54, 105, 1, 55, 44, 91, 134, 14, 245, 124, 185, 191, 101, 16, 224, 223, + 52, 105, 164, 87, 116, 234, 252, 114, 221, 170, 210, 119, 197, 160, 32, 2, 121, 230, 186, 66, + 142, 126, 114, 149, 48, 233, 26, 133, 252, 126, 117, 215, 180, 161, 174, 109, 20, 244, 214, + 208, 85, 76, 221, 212, 76, 95, 87, 32, 7, 161, 87, 170, 89, 229, 183, 27, 195, 82, 69, 132, + 104, 217, 130, 238, 151, 136, 174, 144, 184, 168, 140, 234, 36, 3, 176, 245, 25, 125, 41, 99, + 32, 0, 88, 67, 92, 71, 241, 32, 23, 38, 147, 66, 114, 209, 11, 251, 35, 112, 6, 86, 246, 23, + 45, 18, 208, 40, 24, 7, 103, 142, 243, 208, 70, 32, 0, 44, 33, 174, 35, 248, 144, 11, 147, 73, + 161, 57, 104, 133, 253, 145, 184, 3, 43, 123, 11, 150, 137, 104, 20, 12, 3, 179, 199, 121, 232, + 35, 32, 0, 190, 153, 0, 87, 9, 24, 136, 55, 141, 84, 141, 190, 137, 98, 86, 14, 167, 124, 221, + 20, 103, 195, 105, 147, 214, 11, 57, 232, 95, 60, 79, 32, 7, 2, 75, 27, 144, 45, 141, 18, 17, + 197, 29, 209, 193, 41, 103, 212, 203, 69, 251, 58, 229, 64, 68, 251, 196, 233, 158, 44, 7, 57, + 77, 100, 32, 3, 206, 150, 159, 110, 197, 166, 239, 109, 88, 196, 252, 96, 243, 114, 21, 183, + 251, 127, 145, 101, 84, 97, 22, 11, 151, 10, 216, 49, 162, 201, 213, 32, 3, 114, 96, 155, 157, + 209, 179, 39, 101, 148, 71, 255, 233, 3, 119, 212, 135, 111, 200, 173, 68, 173, 210, 162, 34, + 207, 12, 33, 180, 115, 164, 222, 32, 5, 102, 58, 97, 209, 193, 218, 107, 34, 46, 13, 224, 179, + 255, 212, 219, 152, 247, 162, 11, 146, 32, 247, 155, 254, 13, 124, 237, 185, 121, 20, 46, 32, + 3, 63, 36, 54, 81, 52, 160, 17, 1, 67, 68, 98, 127, 193, 149, 149, 108, 62, 236, 210, 156, 74, + 13, 68, 24, 49, 126, 219, 124, 12, 217, 131, 32, 2, 72, 26, 68, 109, 167, 32, 138, 238, 138, + 38, 34, 74, 39, 46, 87, 232, 197, 93, 136, 220, 193, 133, 87, 149, 232, 200, 205, 194, 168, + 180, 255, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 32, 6, 157, 51, 20, 126, 24, 171, 219, 83, 113, 176, 134, 159, 213, 92, 150, + 133, 67, 235, 2, 44, 141, 134, 94, 252, 183, 45, 81, 178, 193, 187, 88, 32, 7, 39, 244, 27, + 175, 73, 179, 134, 107, 184, 136, 76, 211, 49, 69, 110, 221, 22, 113, 80, 88, 44, 157, 146, + 196, 227, 83, 126, 41, 3, 139, 54, 32, 1, 49, 232, 14, 7, 76, 32, 178, 247, 39, 65, 91, 29, + 231, 93, 9, 136, 36, 176, 72, 92, 63, 78, 121, 43, 48, 56, 66, 70, 133, 99, 48, 32, 0, 145, + 154, 219, 32, 156, 27, 197, 255, 214, 192, 230, 207, 33, 197, 55, 174, 39, 213, 138, 192, 238, + 173, 22, 247, 249, 93, 8, 176, 31, 109, 71, 32, 2, 243, 229, 117, 197, 255, 122, 250, 110, 201, + 31, 116, 254, 193, 241, 228, 98, 239, 97, 168, 95, 254, 50, 197, 37, 219, 228, 30, 1, 75, 37, + 146, 32, 2, 251, 95, 40, 126, 75, 198, 15, 89, 219, 83, 79, 188, 119, 46, 143, 32, 239, 124, + 60, 150, 0, 99, 126, 170, 74, 181, 237, 134, 110, 55, 6, 32, 6, 149, 5, 76, 142, 231, 0, 142, + 241, 181, 85, 73, 250, 247, 101, 96, 235, 88, 30, 55, 194, 36, 239, 22, 72, 194, 253, 245, 170, + 77, 86, 138, 32, 1, 130, 28, 118, 182, 141, 212, 15, 115, 26, 105, 190, 143, 91, 142, 125, 93, + 179, 212, 15, 84, 203, 43, 152, 249, 215, 69, 53, 127, 186, 4, 123, 32, 7, 188, 212, 79, 117, + 224, 48, 21, 132, 24, 203, 184, 43, 159, 57, 44, 102, 65, 62, 39, 35, 169, 155, 34, 206, 199, + 163, 103, 4, 20, 100, 230, 32, 7, 177, 217, 196, 41, 199, 253, 106, 197, 179, 235, 189, 122, + 190, 152, 124, 130, 168, 39, 48, 150, 172, 176, 249, 186, 184, 183, 153, 193, 183, 190, 48, 32, + 6, 90, 178, 87, 183, 16, 44, 145, 121, 253, 254, 45, 149, 160, 193, 42, 145, 252, 195, 180, + 150, 92, 184, 72, 197, 24, 248, 54, 251, 236, 40, 157, 32, 2, 20, 178, 102, 77, 107, 189, 105, + 174, 137, 145, 138, 75, 136, 55, 149, 196, 168, 35, 11, 98, 2, 184, 73, 172, 135, 147, 69, 196, + 45, 250, 210, 32, 1, 14, 10, 106, 98, 138, 75, 176, 118, 144, 9, 206, 43, 165, 78, 196, 34, + 253, 229, 32, 158, 41, 166, 34, 95, 227, 24, 235, 84, 92, 131, 172, 32, 4, 133, 28, 17, 71, + 214, 252, 106, 118, 134, 29, 190, 64, 157, 56, 44, 222, 229, 18, 91, 194, 37, 190, 132, 97, 76, + 179, 57, 46, 209, 5, 252, 32, 6, 99, 7, 73, 218, 173, 225, 144, 13, 237, 152, 82, 222, 52, 173, + 137, 235, 94, 44, 138, 79, 181, 153, 108, 186, 165, 54, 135, 8, 9, 242, 235, 32, 5, 48, 127, + 150, 223, 172, 207, 58, 53, 228, 107, 136, 242, 14, 98, 85, 248, 152, 107, 106, 155, 84, 180, + 62, 11, 170, 99, 26, 119, 0, 26, 152, 32, 5, 150, 111, 125, 40, 103, 113, 4, 198, 91, 120, 42, + 55, 194, 34, 156, 213, 118, 98, 226, 116, 37, 35, 58, 203, 240, 123, 124, 167, 27, 86, 117, 32, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 32, 7, 255, 255, 255, 254, 239, 253, 240, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 239, 255, 225, 36, 32, 5, 113, 4, + 132, 41, 62, 211, 190, 57, 115, 226, 29, 236, 84, 66, 103, 143, 107, 143, 132, 0, 189, 123, 89, + 115, 151, 114, 173, 78, 206, 16, 27, 32, 5, 178, 169, 38, 158, 45, 64, 176, 152, 162, 46, 4, + 130, 160, 119, 48, 93, 180, 26, 159, 93, 16, 75, 9, 55, 73, 82, 63, 231, 143, 90, 240, 32, 5, + 129, 28, 11, 54, 157, 116, 223, 41, 180, 53, 230, 180, 162, 192, 75, 115, 52, 231, 160, 198, + 165, 202, 235, 171, 121, 171, 248, 69, 239, 171, 165, 32, 4, 148, 123, 66, 220, 147, 249, 219, + 22, 50, 133, 191, 3, 46, 204, 32, 255, 78, 7, 216, 144, 240, 197, 105, 37, 253, 144, 63, 219, + 5, 224, 19, 32, 3, 60, 206, 209, 73, 124, 219, 99, 213, 107, 200, 77, 39, 69, 30, 196, 245, 99, + 97, 155, 149, 23, 235, 133, 94, 106, 143, 237, 20, 113, 57, 16, 32, 6, 215, 232, 251, 136, 70, + 80, 241, 31, 10, 243, 237, 69, 23, 106, 178, 191, 65, 191, 22, 80, 78, 140, 254, 147, 136, 197, + 229, 171, 60, 73, 82, 32, 2, 73, 154, 109, 136, 227, 115, 86, 25, 32, 98, 40, 10, 104, 153, + 159, 21, 207, 107, 83, 67, 122, 144, 110, 234, 176, 129, 215, 92, 124, 242, 167, 32, 5, 36, + 205, 54, 196, 113, 185, 179, 140, 144, 49, 20, 5, 52, 76, 207, 138, 231, 181, 169, 161, 189, + 72, 55, 117, 88, 64, 235, 174, 62, 121, 84, 32, 5, 68, 225, 208, 192, 61, 230, 9, 15, 223, 141, + 211, 67, 156, 13, 203, 95, 95, 222, 131, 139, 121, 135, 42, 245, 42, 225, 196, 87, 150, 110, + 215, 32, 0, 48, 249, 21, 152, 12, 29, 189, 81, 197, 24, 228, 71, 100, 241, 213, 176, 240, 172, + 174, 58, 244, 166, 105, 180, 141, 41, 211, 204, 144, 52, 119, 32, 4, 158, 53, 245, 127, 169, + 138, 163, 190, 77, 178, 159, 168, 221, 104, 97, 40, 84, 47, 51, 32, 182, 223, 132, 101, 228, + 253, 118, 155, 61, 39, 204, 32, 1, 218, 189, 154, 24, 70, 25, 7, 212, 212, 9, 239, 129, 206, + 195, 175, 250, 196, 246, 46, 161, 224, 5, 132, 160, 134, 49, 255, 101, 109, 171, 227, 32, 5, + 24, 157, 127, 103, 49, 148, 150, 136, 145, 89, 44, 171, 187, 246, 34, 174, 33, 106, 73, 106, + 110, 254, 60, 162, 243, 176, 254, 18, 117, 217, 51, 32, 3, 228, 135, 71, 204, 17, 246, 220, + 230, 229, 141, 177, 226, 139, 118, 94, 18, 181, 218, 211, 157, 25, 217, 183, 65, 164, 213, 166, + 183, 18, 238, 125, 32, 0, 164, 190, 217, 68, 14, 4, 149, 61, 10, 60, 34, 50, 71, 162, 146, 163, + 70, 241, 24, 137, 39, 207, 234, 219, 81, 44, 33, 220, 0, 169, 107, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 6, 149, 17, 221, + 202, 105, 0, 31, 33, 26, 217, 147, 78, 247, 103, 12, 128, 28, 193, 247, 88, 242, 51, 131, 79, + 111, 43, 121, 15, 105, 25, 22, 32, 7, 254, 27, 57, 67, 21, 121, 98, 12, 174, 115, 93, 211, 254, + 204, 55, 232, 22, 4, 49, 56, 27, 28, 183, 62, 74, 166, 103, 103, 84, 58, 71, 32, 3, 116, 89, + 217, 70, 248, 192, 197, 108, 66, 140, 160, 141, 248, 42, 92, 236, 59, 59, 118, 143, 222, 223, + 51, 13, 91, 20, 29, 2, 235, 222, 151, 32, 3, 233, 228, 245, 165, 212, 209, 212, 118, 120, 80, + 237, 22, 221, 66, 138, 123, 227, 47, 177, 61, 67, 228, 207, 198, 235, 236, 24, 167, 22, 69, 57, + 32, 0, 167, 220, 91, 5, 166, 130, 243, 38, 200, 208, 20, 171, 72, 125, 142, 242, 87, 141, 131, + 207, 224, 63, 172, 154, 165, 16, 140, 211, 85, 229, 155, 32, 1, 187, 10, 218, 105, 114, 29, 65, + 28, 236, 65, 201, 231, 214, 125, 89, 45, 16, 18, 67, 29, 220, 10, 134, 50, 174, 92, 75, 157, + 210, 25, 226, 32, 1, 162, 222, 29, 125, 140, 22, 50, 197, 50, 193, 120, 51, 189, 79, 43, 130, + 243, 16, 145, 195, 16, 89, 144, 212, 141, 96, 70, 233, 137, 71, 86, 32, 1, 53, 111, 177, 148, + 38, 252, 138, 106, 253, 254, 51, 189, 137, 67, 217, 198, 10, 50, 215, 34, 236, 120, 116, 86, + 141, 179, 242, 113, 190, 94, 149, 32, 7, 85, 179, 63, 144, 238, 1, 2, 243, 105, 223, 39, 168, + 36, 16, 104, 16, 101, 213, 7, 195, 16, 225, 251, 50, 116, 6, 54, 222, 193, 249, 106, 32, 1, + 243, 144, 133, 144, 53, 44, 106, 28, 171, 117, 167, 125, 229, 3, 94, 231, 111, 69, 162, 147, + 117, 120, 177, 130, 168, 13, 102, 120, 1, 68, 100, 32, 2, 115, 110, 122, 204, 241, 7, 97, 255, + 207, 137, 222, 176, 43, 103, 188, 223, 109, 97, 219, 46, 175, 66, 88, 158, 213, 204, 249, 182, + 122, 60, 32, 32, 4, 116, 237, 160, 162, 120, 154, 57, 103, 83, 24, 167, 167, 171, 109, 113, + 154, 127, 65, 11, 127, 101, 75, 54, 29, 191, 250, 131, 185, 132, 144, 113, 32, 6, 64, 89, 16, + 14, 28, 156, 232, 240, 95, 165, 200, 103, 135, 237, 37, 237, 54, 239, 7, 237, 0, 67, 167, 164, + 168, 224, 41, 173, 195, 93, 58, 32, 0, 163, 210, 15, 175, 253, 202, 171, 103, 170, 213, 57, 27, + 122, 238, 152, 153, 51, 232, 115, 193, 41, 145, 51, 237, 50, 57, 199, 72, 137, 185, 204, 32, 3, + 234, 223, 251, 69, 119, 7, 60, 185, 191, 161, 181, 126, 115, 59, 120, 53, 102, 193, 71, 170, + 44, 109, 9, 178, 70, 59, 85, 0, 43, 122, 23, 32, 1, 23, 143, 177, 10, 146, 76, 7, 182, 122, 8, + 57, 75, 111, 126, 122, 130, 218, 140, 246, 169, 115, 201, 66, 131, 194, 50, 179, 128, 32, 14, + 38, 32, 1, 17, 140, 170, 61, 218, 5, 177, 217, 117, 34, 160, 216, 36, 165, 117, 187, 250, 50, + 7, 187, 193, 228, 26, 4, 16, 182, 169, 164, 182, 255, 71, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 7, 255, 255, 255, 254, + 239, 253, 240, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 239, 255, 225, 1, 8, 53, 76, 190, 184, 244, 36, 126, 255, 134, 180, + 213, 61, 112, 41, 244, 182, 188, 22, 10, 147, 91, 158, 90, 131, 148, 157, 56, 245, 63, 60, 132, + 97, 179, 21, 130, 172, 74, 138, 253, 38, 56, 180, 102, 39, 111, 136, 166, 55, 53, 85, 254, 63, + 223, 5, 225, 253, 154, 57, 29, 217, 247, 8, 124, 152, 135, 34, 188, 151, 17, 187, 220, 0, 165, + 108, 251, 46, 107, 166, 181, 205, 71, 218, 163, 122, 119, 132, 70, 149, 13, 167, 45, 27, 16, + 248, 130, 246, 62, 140, 105, 159, 88, 38, 247, 37, 228, 16, 114, 143, 17, 195, 241, 138, 53, + 178, 151, 238, 26, 248, 33, 227, 5, 41, 194, 29, 250, 21, 194, 122, 94, 135, 249, 215, 243, 35, + 175, 188, 241, 148, 240, 29, 134, 150, 249, 169, 156, 239, 74, 76, 156, 247, 185, 194, 128, 66, + 214, 36, 211, 116, 90, 38, 107, 227, 92, 168, 83, 134, 109, 180, 211, 28, 204, 33, 14, 245, 72, + 86, 236, 114, 107, 238, 242, 209, 141, 32, 188, 207, 90, 66, 55, 99, 210, 105, 248, 192, 4, 62, + 145, 208, 140, 147, 51, 213, 13, 119, 168, 48, 157, 15, 196, 33, 110, 183, 87, 150, 74, 188, + 70, 155, 201, 215, 23, 246, 142, 253, 16, 200, 158, 124, 254, 165, 5, 73, 12, 53, 221, 137, + 122, 171, 78, 203, 75, 123, 4, 181, 50, 42, 37, 32, 13, 234, 176, 114, 190, 190, 94, 157, 8, + 34, 114, 134, 201, 115, 56, 140, 49, 142, 12, 86, 177, 21, 174, 54, 113, 237, 107, 139, 115, + 165, 7, 246, 48, 26, 84, 165, 99, 169, 89, 113, 30, 179, 21, 130, 172, 74, 138, 253, 38, 56, + 180, 102, 39, 111, 136, 166, 55, 53, 85, 254, 63, 223, 5, 225, 253, 154, 57, 29, 217, 247, 8, + 124, 152, 135, 34, 188, 151, 17, 187, 220, 0, 165, 108, 251, 46, 107, 166, 181, 205, 71, 218, + 163, 122, 119, 132, 70, 149, 13, 167, 45, 27, 16, 248, 130, 246, 62, 140, 105, 159, 88, 38, + 247, 37, 228, 16, 114, 143, 17, 195, 241, 138, 53, 178, 151, 238, 26, 248, 33, 227, 5, 41, 194, + 29, 250, 21, 194, 122, 94, 135, 249, 215, 243, 35, 175, 188, 241, 148, 240, 29, 134, 150, 249, + 169, 156, 239, 74, 76, 156, 247, 185, 194, 128, 66, 214, 36, 211, 116, 90, 38, 107, 227, 92, + 168, 83, 134, 109, 180, 211, 28, 204, 33, 14, 245, 72, 86, 236, 114, 107, 238, 242, 209, 141, + 32, 188, 207, 90, 66, 55, 99, 210, 105, 248, 192, 4, 62, 145, 208, 140, 147, 51, 213, 13, 119, + 168, 48, 157, 15, 196, 33, 110, 183, 87, 150, 74, 188, 70, 155, 201, 215, 23, 246, 142, 253, + 16, 200, 158, 124, 254, 165, 5, 73, 12, 53, 221, 137, 122, 171, 78, 203, 75, 123, 4, 181, 50, + 42, 37, 32, 13, 234, 176, 114, 190, 190, 94, 157, 23, 32, 5, 186, 158, 17, 4, 199, 30, 144, + 201, 38, 11, 250, 108, 122, 224, 128, 16, 54, 3, 22, 121, 52, 205, 27, 220, 62, 254, 5, 5, 96, + 103, 139, 32, 7, 59, 132, 58, 0, 159, 27, 9, 41, 149, 70, 135, 241, 46, 173, 1, 149, 22, 148, + 213, 68, 148, 155, 241, 153, 175, 198, 3, 251, 1, 177, 222, 32, 7, 59, 132, 58, 0, 159, 27, 9, + 41, 149, 70, 135, 241, 46, 173, 1, 149, 22, 148, 213, 68, 148, 155, 241, 153, 175, 198, 3, 251, + 1, 177, 222, 32, 7, 59, 132, 58, 0, 159, 27, 9, 41, 149, 70, 135, 241, 46, 173, 1, 149, 22, + 148, 213, 68, 148, 155, 241, 153, 175, 198, 3, 251, 1, 177, 222, 32, 0, 105, 212, 236, 199, + 239, 28, 54, 213, 225, 236, 74, 163, 155, 99, 70, 108, 178, 43, 245, 88, 11, 111, 170, 159, + 159, 33, 58, 96, 204, 29, 11, 32, 3, 206, 0, 174, 2, 104, 127, 150, 87, 237, 207, 22, 241, 3, + 9, 155, 152, 245, 234, 183, 232, 240, 217, 138, 46, 74, 161, 162, 39, 132, 23, 77, 32, 5, 208, + 70, 213, 49, 253, 16, 182, 213, 162, 3, 62, 154, 172, 201, 108, 198, 33, 9, 163, 29, 246, 138, + 142, 204, 208, 212, 219, 227, 218, 38, 125, 32, 5, 137, 156, 64, 105, 64, 51, 90, 199, 221, 86, + 116, 210, 235, 217, 67, 53, 99, 154, 234, 105, 110, 151, 32, 128, 61, 53, 240, 217, 19, 140, + 135, 32, 1, 32, 30, 162, 132, 42, 50, 45, 45, 82, 75, 169, 1, 127, 111, 8, 159, 37, 72, 164, + 217, 124, 74, 113, 81, 8, 196, 143, 85, 201, 211, 146, 32, 7, 192, 192, 46, 130, 184, 228, 219, + 107, 64, 19, 135, 51, 19, 38, 223, 184, 90, 194, 80, 30, 108, 99, 89, 69, 28, 35, 126, 196, 2, + 204, 98, 32, 1, 45, 221, 64, 177, 51, 59, 84, 97, 184, 119, 103, 199, 85, 35, 64, 59, 125, 12, + 239, 233, 77, 17, 59, 132, 59, 163, 179, 135, 199, 20, 223, 32, 1, 2, 251, 108, 216, 187, 36, + 189, 54, 162, 37, 18, 116, 131, 155, 30, 145, 213, 19, 36, 123, 201, 153, 119, 20, 216, 85, + 135, 36, 110, 185, 46, 32, 6, 123, 154, 60, 47, 212, 237, 207, 194, 253, 45, 101, 86, 179, 69, + 3, 34, 103, 64, 50, 131, 172, 22, 51, 87, 73, 218, 82, 220, 93, 150, 119, 32, 5, 120, 233, 13, + 54, 248, 167, 31, 72, 6, 136, 240, 245, 243, 230, 176, 66, 93, 46, 150, 109, 126, 60, 152, 221, + 91, 157, 136, 87, 139, 136, 234, 32, 4, 143, 65, 110, 148, 247, 167, 104, 3, 87, 209, 157, 58, + 96, 39, 81, 37, 2, 216, 55, 134, 215, 85, 47, 154, 183, 17, 242, 100, 50, 158, 95, 32, 0, 64, + 107, 195, 205, 225, 33, 232, 80, 95, 118, 77, 242, 68, 226, 166, 76, 13, 158, 58, 156, 126, 1, + 39, 113, 228, 237, 125, 194, 71, 219, 243, 32, 3, 203, 42, 99, 32, 148, 99, 137, 238, 191, 1, + 36, 39, 248, 146, 42, 50, 42, 150, 226, 174, 228, 246, 140, 163, 221, 70, 172, 9, 224, 161, + 141, 32, 1, 164, 166, 114, 98, 225, 94, 86, 220, 67, 159, 142, 200, 239, 158, 128, 59, 63, 244, + 200, 149, 178, 88, 122, 153, 159, 43, 229, 99, 130, 176, 213, 32, 6, 169, 97, 59, 109, 42, 177, + 241, 154, 69, 148, 121, 125, 6, 94, 174, 66, 175, 11, 229, 220, 249, 18, 34, 2, 160, 9, 239, + 122, 119, 121, 83, 32, 0, 113, 217, 179, 47, 12, 210, 21, 180, 101, 98, 32, 129, 125, 69, 23, + 156, 167, 69, 139, 17, 110, 127, 16, 32, 226, 158, 43, 211, 208, 95, 106, 32, 6, 66, 54, 132, + 34, 88, 227, 47, 71, 74, 74, 117, 11, 188, 95, 242, 236, 119, 26, 90, 56, 194, 126, 180, 87, + 48, 21, 155, 142, 228, 230, 211, 32, 1, 8, 232, 148, 173, 220, 235, 206, 152, 38, 185, 100, + 198, 14, 72, 189, 13, 12, 212, 47, 115, 244, 123, 221, 143, 219, 156, 97, 194, 199, 30, 182, + 32, 7, 142, 85, 159, 235, 76, 225, 193, 220, 214, 98, 183, 199, 106, 5, 128, 73, 21, 138, 21, + 133, 93, 23, 96, 224, 25, 220, 170, 83, 210, 66, 181, 23, 32, 2, 163, 37, 122, 174, 56, 142, + 216, 245, 244, 184, 125, 39, 223, 238, 134, 178, 190, 78, 68, 69, 240, 60, 60, 85, 185, 29, + 136, 8, 47, 77, 48, 32, 5, 134, 123, 84, 149, 88, 171, 143, 12, 2, 179, 5, 248, 244, 63, 61, + 250, 98, 223, 173, 74, 59, 42, 3, 141, 127, 106, 217, 226, 16, 176, 72, 32, 5, 134, 123, 84, + 149, 88, 171, 143, 12, 2, 179, 5, 248, 244, 63, 61, 250, 98, 223, 173, 74, 59, 42, 3, 141, 127, + 106, 217, 226, 16, 176, 72, 32, 5, 134, 123, 84, 149, 88, 171, 143, 12, 2, 179, 5, 248, 244, + 63, 61, 250, 98, 223, 173, 74, 59, 42, 3, 141, 127, 106, 217, 226, 16, 176, 72, 32, 4, 92, 215, + 77, 64, 206, 190, 217, 231, 204, 138, 52, 187, 225, 6, 195, 184, 148, 146, 98, 142, 10, 237, + 132, 238, 196, 103, 185, 79, 194, 106, 136, 32, 3, 46, 151, 117, 185, 146, 93, 232, 151, 44, + 106, 244, 141, 173, 239, 52, 56, 135, 91, 188, 25, 179, 249, 178, 233, 219, 75, 220, 85, 224, + 185, 209, 32, 2, 56, 187, 99, 96, 73, 48, 196, 162, 85, 121, 87, 137, 132, 0, 59, 48, 163, 133, + 42, 64, 251, 175, 198, 248, 130, 201, 199, 19, 56, 163, 114, 32, 2, 172, 72, 17, 36, 178, 144, + 116, 175, 221, 11, 124, 163, 187, 41, 241, 245, 235, 100, 187, 15, 172, 6, 189, 60, 251, 173, + 63, 2, 144, 176, 203, 32, 7, 194, 200, 168, 120, 214, 176, 202, 129, 184, 40, 234, 93, 192, 96, + 149, 93, 27, 207, 30, 82, 103, 197, 14, 57, 60, 237, 110, 40, 137, 127, 178, 32, 0, 146, 147, + 27, 150, 232, 183, 159, 61, 81, 156, 49, 23, 171, 214, 123, 84, 145, 61, 177, 155, 161, 247, + 107, 159, 235, 213, 8, 223, 170, 234, 88, 32, 3, 48, 147, 58, 168, 56, 95, 160, 86, 124, 159, + 140, 248, 6, 18, 224, 187, 96, 136, 232, 45, 215, 140, 153, 173, 36, 239, 28, 65, 147, 132, + 227, 32, 1, 39, 121, 52, 204, 102, 136, 60, 217, 100, 93, 56, 68, 161, 91, 53, 36, 118, 239, + 179, 199, 132, 39, 21, 134, 8, 127, 77, 214, 86, 1, 151, 32, 7, 15, 168, 86, 36, 5, 223, 136, + 141, 130, 114, 241, 60, 171, 135, 22, 64, 144, 76, 189, 171, 105, 238, 199, 215, 248, 15, 43, + 124, 82, 216, 100, 32, 6, 63, 121, 168, 212, 175, 97, 183, 41, 55, 6, 157, 118, 25, 237, 140, + 10, 226, 38, 108, 72, 133, 2, 20, 194, 105, 90, 234, 237, 127, 31, 135, 32, 3, 95, 90, 246, + 146, 220, 220, 126, 124, 221, 229, 120, 229, 121, 95, 66, 18, 111, 5, 39, 64, 234, 189, 232, + 60, 159, 0, 147, 67, 124, 160, 81, 32, 0, 128, 196, 177, 18, 102, 194, 247, 111, 5, 184, 24, + 121, 42, 79, 59, 157, 32, 59, 47, 201, 87, 49, 140, 36, 207, 154, 233, 55, 156, 85, 20, 32, 6, + 62, 129, 192, 53, 29, 18, 19, 220, 210, 210, 124, 2, 184, 146, 46, 63, 85, 62, 153, 96, 202, + 189, 179, 217, 249, 228, 208, 168, 157, 171, 85, 32, 4, 252, 20, 112, 128, 70, 142, 15, 151, + 58, 44, 107, 29, 87, 123, 89, 197, 199, 250, 144, 132, 224, 120, 23, 72, 171, 230, 249, 115, + 103, 168, 121, 32, 4, 60, 231, 255, 193, 168, 52, 217, 217, 202, 195, 20, 89, 217, 87, 29, 192, + 63, 88, 181, 124, 111, 98, 76, 244, 242, 19, 120, 128, 217, 152, 2, 32, 0, 191, 48, 142, 1, + 122, 139, 54, 112, 203, 106, 113, 208, 27, 51, 82, 50, 5, 74, 173, 182, 74, 138, 26, 102, 72, + 156, 187, 195, 46, 2, 64, 32, 6, 255, 188, 219, 98, 117, 141, 235, 142, 127, 232, 100, 141, + 181, 71, 41, 93, 30, 54, 159, 61, 216, 140, 181, 69, 141, 233, 175, 62, 217, 202, 156, 32, 4, + 99, 247, 11, 27, 207, 183, 69, 247, 182, 4, 61, 13, 223, 66, 13, 24, 87, 237, 199, 6, 87, 70, + 190, 204, 21, 255, 59, 202, 68, 204, 246, 32, 5, 225, 146, 39, 232, 171, 250, 119, 5, 75, 119, + 156, 34, 22, 69, 148, 221, 12, 244, 207, 17, 223, 208, 148, 99, 157, 19, 211, 91, 251, 107, + 184, 7, 252, 11, 21, 38, 31, 183, 75, 252, 11, 109, 101, 0, 223, 66, 171, 63, 19, 183, 139, + 142, 40, 174, 191, 87, 11, 222, 129, 124, 101, 75, 123, 70, 199, 158, 120, 185, 8, 172, 104, + 202, 129, 51, 166, 239, 100, 28, 87, 199, 146, 146, 226, 245, 22, 221, 52, 20, 178, 168, 107, + 218, 157, 192, 83, 17, 243, 148, 90, 0, 157, 43, 19, 77, 53, 64, 134, 77, 63, 197, 63, 243, 41, + 44, 218, 23, 127, 103, 9, 194, 201, 58, 143, 151, 62, 85, 75, 217, 143, 98, 74, 76, 140, 137, + 217, 143, 157, 127, 73, 13, 30, 154, 115, 104, 31, 52, 74, 172, 134, 205, 100, 44, 195, 181, + 60, 156, 125, 108, 163, 218, 226, 24, 112, 45, 211, 8, 154, 246, 16, 159, 237, 206, 177, 157, + 162, 154, 64, 186, 79, 84, 23, 81, 132, 104, 72, 66, 186, 25, 81, 168, 118, 233, 92, 41, 171, + 144, 132, 246, 76, 246, 142, 86, 209, 111, 24, 65, 183, 87, 141, 130, 215, 53, 217, 166, 72, + 61, 175, 41, 33, 248, 102, 55, 7, 57, 90, 146, 42, 221, 95, 80, 55, 238, 93, 29, 130, 15, 78, + 32, 160, 44, 76, 21, 121, 200, 67, 65, 126, 167, 75, 214, 73, 208, 141, 214, 158, 78, 7, 252, + 11, 21, 38, 31, 183, 75, 252, 11, 109, 101, 0, 223, 66, 171, 63, 19, 183, 139, 142, 40, 174, + 191, 87, 11, 222, 129, 124, 101, 75, 123, 70, 199, 158, 120, 185, 8, 172, 104, 202, 129, 51, + 166, 239, 100, 28, 87, 199, 146, 146, 226, 245, 22, 221, 52, 20, 178, 168, 107, 218, 157, 192, + 83, 17, 243, 148, 90, 0, 157, 43, 19, 77, 53, 64, 134, 77, 63, 197, 63, 243, 41, 44, 218, 23, + 127, 103, 9, 194, 201, 58, 143, 151, 62, 85, 75, 217, 143, 98, 74, 76, 140, 137, 217, 143, 157, + 127, 73, 13, 30, 154, 115, 104, 31, 52, 74, 172, 134, 205, 100, 44, 195, 181, 60, 156, 125, + 108, 163, 218, 226, 24, 112, 45, 211, 8, 154, 246, 16, 159, 237, 206, 177, 157, 162, 154, 64, + 186, 79, 84, 23, 81, 132, 104, 72, 66, 186, 25, 81, 168, 118, 233, 92, 41, 171, 144, 132, 246, + 76, 246, 142, 86, 209, 111, 24, 65, 183, 87, 141, 130, 215, 53, 217, 166, 72, 61, 175, 41, 33, + 248, 102, 55, 7, 57, 90, 146, 42, 221, 95, 80, 55, 238, 93, 29, 130, 15, 78, 32, 160, 44, 76, + 21, 121, 200, 67, 65, 126, 167, 75, 214, 73, 208, 141, 214, 158, 78, 2, 32, 0, 179, 251, 140, + 44, 139, 6, 94, 64, 141, 189, 35, 254, 12, 27, 211, 162, 142, 138, 211, 124, 152, 90, 62, 191, + 1, 150, 162, 11, 201, 237, 84, 32, 0, 5, 52, 81, 173, 157, 123, 17, 228, 220, 86, 223, 6, 220, + 169, 67, 186, 126, 121, 118, 203, 118, 138, 201, 72, 162, 221, 245, 67, 29, 54, 105, 2, 32, 4, + 59, 167, 10, 174, 78, 27, 164, 37, 184, 185, 58, 172, 94, 255, 217, 40, 43, 224, 65, 187, 205, + 196, 83, 218, 117, 172, 94, 162, 228, 116, 187, 32, 0, 59, 195, 41, 28, 105, 216, 158, 77, 47, + 61, 181, 95, 59, 232, 102, 220, 180, 100, 248, 53, 31, 84, 26, 212, 152, 188, 91, 145, 245, + 173, 130, 8, 72, 157, 52, 65, 131, 107, 51, 203, 161, 9, 236, 138, 220, 146, 47, 117, 159, 8, + 235, 198, 120, 15, 215, 252, 32, 210, 210, 40, 184, 17, 38, 68, 138, 172, 80, 210, 73, 228, + 117, 59, 0, 40, 28, 69, 91, 166, 191, 11, 97, 172, 37, 28, 174, 5, 94, 106, 50, 248, 229, 59, + 162, 89, 94, 231, 74, 147, 252, 163, 246, 133, 208, 151, 87, 189, 40, 208, 243, 159, 219, 5, + 173, 34, 96, 18, 158, 19, 99, 83, 193, 175, 94, 97, 238, 97, 169, 236, 150, 245, 207, 203, 230, + 180, 210, 239, 201, 38, 87, 47, 79, 103, 91, 115, 144, 169, 207, 195, 17, 196, 182, 226, 74, + 106, 171, 149, 236, 195, 101, 146, 225, 111, 62, 174, 168, 68, 214, 215, 129, 69, 23, 126, 173, + 62, 129, 192, 223, 180, 220, 93, 110, 122, 57, 46, 181, 95, 198, 39, 137, 90, 39, 24, 90, 125, + 16, 25, 41, 188, 114, 58, 89, 239, 63, 64, 105, 4, 102, 211, 3, 43, 180, 109, 69, 210, 168, 47, 199, 3, 231, 17, 41, 201, 253, 197, 66, 155, 36, 12, 34, 61, 169, 95, 84, 39, 35, 149, 250, 234, 76, 165, 17, 124, 40, 205, 185, 201, 27, 71, 191, 77, 148, 228, 244, 148, 31, 91, 252, 89, 141, 6, 13, 139, 105, 158, 82, 26, 166, 148, 184, 91, 40, 185, 45, 214, 150, 78, 230, 134, 109, - 250, 24, 78, 249, 49, 197, 186, 141, 6, 36, 32, 2, 86, 79, 48, 107, 126, 61, 24, 210, 237, 10, - 182, 195, 72, 125, 211, 70, 109, 185, 250, 240, 62, 4, 11, 187, 27, 143, 175, 57, 125, 94, 153, - 32, 4, 254, 53, 26, 124, 207, 53, 62, 121, 2, 88, 132, 0, 97, 194, 182, 196, 79, 153, 8, 70, - 245, 186, 240, 75, 93, 168, 248, 19, 186, 62, 103, 32, 5, 50, 131, 105, 65, 246, 226, 154, 89, - 66, 193, 219, 26, 205, 111, 208, 58, 45, 248, 251, 187, 199, 36, 32, 48, 190, 129, 96, 236, - 255, 27, 144, 32, 2, 126, 156, 56, 125, 48, 128, 55, 103, 124, 60, 236, 170, 251, 141, 254, 20, - 36, 194, 117, 113, 163, 84, 126, 60, 85, 40, 109, 188, 104, 8, 220, 32, 3, 126, 5, 243, 19, 15, - 100, 195, 248, 111, 24, 8, 66, 31, 206, 185, 250, 157, 253, 130, 250, 212, 215, 201, 109, 114, - 17, 77, 66, 30, 0, 249, 32, 3, 154, 240, 158, 216, 219, 127, 231, 252, 171, 182, 115, 22, 217, - 9, 140, 21, 181, 156, 129, 167, 167, 123, 236, 67, 123, 163, 210, 247, 60, 136, 238, 32, 0, - 254, 121, 218, 105, 91, 132, 149, 196, 172, 197, 116, 69, 212, 111, 22, 82, 149, 200, 67, 149, - 121, 140, 92, 64, 180, 116, 100, 77, 20, 67, 188, 32, 0, 127, 60, 237, 52, 173, 194, 74, 226, - 86, 98, 186, 34, 234, 55, 139, 41, 74, 228, 33, 202, 188, 198, 46, 32, 90, 58, 50, 38, 138, 33, - 222, 32, 1, 156, 125, 144, 121, 200, 214, 175, 83, 30, 242, 25, 116, 104, 215, 93, 104, 171, - 188, 133, 4, 42, 169, 117, 153, 138, 209, 222, 202, 208, 136, 242, 32, 6, 48, 159, 5, 1, 58, - 210, 88, 153, 24, 92, 235, 226, 37, 223, 99, 137, 6, 157, 34, 152, 232, 189, 224, 149, 31, 199, - 2, 151, 144, 185, 67, 32, 5, 206, 82, 119, 10, 68, 54, 55, 225, 149, 228, 6, 217, 106, 134, - 231, 90, 87, 223, 78, 249, 157, 89, 128, 203, 239, 34, 108, 70, 123, 85, 165, 32, 2, 145, 139, - 150, 155, 51, 193, 93, 125, 14, 213, 102, 125, 153, 114, 73, 183, 178, 229, 40, 208, 144, 116, - 237, 245, 160, 115, 173, 210, 176, 87, 209, 32, 0, 240, 122, 130, 165, 93, 45, 85, 72, 6, 20, - 188, 202, 113, 217, 76, 168, 135, 171, 184, 105, 187, 5, 233, 6, 170, 40, 143, 134, 226, 174, - 124, 32, 1, 196, 212, 101, 79, 31, 79, 200, 7, 65, 116, 197, 74, 156, 94, 49, 124, 61, 169, - 100, 156, 145, 60, 76, 120, 69, 103, 98, 224, 79, 90, 242, 32, 2, 63, 73, 76, 135, 1, 157, 109, - 229, 148, 123, 31, 8, 65, 234, 176, 146, 37, 31, 38, 109, 20, 228, 132, 197, 128, 104, 119, 39, - 179, 37, 124, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 32, 6, 139, 235, 255, 24, 24, 33, 103, 13, 72, 10, 211, 192, 220, 35, 80, - 251, 155, 139, 242, 230, 194, 24, 66, 255, 43, 225, 135, 94, 251, 253, 37, 32, 1, 79, 128, 11, - 14, 135, 225, 42, 145, 219, 39, 224, 255, 116, 61, 228, 148, 0, 243, 183, 243, 22, 179, 200, - 159, 244, 195, 212, 66, 113, 253, 139, 32, 6, 17, 100, 149, 214, 84, 144, 114, 104, 213, 128, - 180, 91, 168, 174, 4, 37, 176, 108, 92, 23, 212, 235, 10, 15, 53, 13, 233, 130, 249, 20, 35, - 32, 4, 83, 50, 27, 135, 53, 115, 119, 154, 213, 92, 213, 138, 24, 203, 214, 244, 25, 56, 3, - 133, 58, 148, 25, 255, 176, 224, 26, 54, 194, 200, 244, 32, 3, 213, 66, 151, 78, 219, 91, 212, - 110, 132, 197, 221, 39, 20, 141, 26, 60, 15, 173, 189, 139, 153, 167, 63, 2, 45, 177, 227, 31, - 255, 173, 165, 32, 3, 25, 13, 20, 144, 5, 177, 125, 69, 81, 86, 129, 196, 15, 169, 59, 79, 222, - 141, 94, 70, 91, 40, 246, 28, 73, 139, 76, 41, 210, 16, 101, 32, 0, 244, 217, 143, 120, 194, - 121, 76, 168, 204, 189, 77, 177, 162, 173, 32, 32, 193, 66, 161, 249, 145, 50, 88, 94, 224, 98, - 126, 164, 57, 51, 176, 32, 3, 230, 217, 81, 157, 54, 166, 224, 134, 217, 162, 132, 88, 91, 131, - 193, 92, 81, 218, 117, 236, 137, 37, 40, 30, 62, 5, 238, 210, 215, 155, 70, 32, 1, 127, 93, - 217, 48, 96, 65, 48, 106, 224, 86, 222, 228, 237, 0, 19, 219, 123, 119, 16, 121, 138, 249, 61, - 152, 169, 100, 100, 123, 165, 9, 242, 32, 4, 179, 94, 122, 0, 72, 6, 166, 115, 176, 37, 188, - 23, 240, 245, 124, 213, 186, 40, 198, 140, 102, 214, 140, 234, 197, 214, 116, 92, 4, 185, 26, - 32, 5, 192, 108, 139, 59, 1, 125, 224, 31, 75, 203, 90, 105, 3, 226, 101, 169, 51, 208, 195, - 151, 13, 53, 47, 165, 29, 63, 153, 29, 18, 100, 92, 32, 3, 169, 50, 79, 60, 7, 21, 201, 62, - 148, 46, 219, 133, 52, 176, 160, 22, 14, 190, 134, 31, 239, 109, 107, 22, 163, 225, 143, 229, - 1, 199, 164, 32, 0, 59, 200, 71, 79, 88, 64, 45, 134, 42, 27, 29, 120, 98, 25, 117, 212, 72, - 105, 114, 223, 119, 15, 194, 52, 248, 10, 33, 47, 71, 1, 148, 32, 1, 109, 133, 168, 234, 226, - 124, 40, 101, 236, 57, 226, 175, 84, 180, 216, 255, 182, 14, 154, 216, 196, 129, 93, 45, 40, - 73, 71, 158, 224, 63, 226, 32, 5, 160, 133, 29, 43, 68, 237, 171, 35, 4, 229, 78, 49, 111, 222, - 8, 152, 238, 210, 138, 215, 80, 218, 78, 181, 130, 230, 116, 254, 171, 145, 190, 32, 4, 87, - 170, 15, 89, 149, 175, 140, 133, 140, 106, 177, 191, 73, 245, 85, 147, 10, 30, 81, 104, 19, - 158, 112, 41, 149, 142, 181, 241, 115, 122, 248, 32, 2, 255, 253, 143, 178, 10, 253, 6, 181, - 113, 154, 36, 93, 242, 165, 18, 204, 157, 0, 73, 204, 95, 28, 235, 90, 13, 128, 113, 208, 35, - 110, 163, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 32, 7, 255, 255, 255, 254, 239, 253, 240, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 239, 255, 225, 36, - 32, 3, 84, 27, 87, 135, 15, 57, 172, 159, 3, 225, 109, 133, 42, 61, 83, 239, 131, 242, 200, - 160, 52, 87, 0, 181, 112, 46, 15, 194, 84, 77, 79, 32, 7, 188, 29, 48, 216, 71, 33, 24, 62, 97, - 7, 201, 197, 14, 255, 184, 35, 29, 162, 189, 156, 197, 76, 147, 189, 181, 145, 0, 192, 85, 120, - 140, 32, 4, 237, 117, 1, 36, 37, 198, 171, 163, 155, 46, 237, 50, 212, 159, 123, 185, 54, 50, - 139, 170, 38, 228, 93, 132, 37, 226, 7, 36, 24, 204, 146, 32, 2, 158, 107, 51, 60, 100, 199, - 69, 151, 241, 169, 217, 121, 125, 25, 189, 125, 73, 64, 140, 76, 137, 72, 48, 58, 239, 20, 108, - 177, 1, 42, 140, 32, 1, 27, 217, 253, 111, 140, 4, 203, 241, 56, 110, 161, 128, 74, 196, 11, - 182, 220, 79, 250, 214, 161, 124, 158, 229, 30, 51, 174, 44, 107, 72, 67, 32, 4, 153, 151, 232, - 60, 26, 126, 101, 141, 56, 139, 57, 28, 134, 96, 217, 66, 136, 81, 2, 67, 126, 15, 199, 50, 12, - 76, 246, 35, 86, 44, 242, 32, 3, 246, 142, 87, 128, 141, 14, 96, 192, 152, 44, 238, 57, 1, 104, - 95, 136, 108, 78, 158, 154, 235, 95, 208, 83, 70, 201, 93, 90, 51, 242, 224, 32, 1, 251, 71, - 43, 192, 70, 135, 48, 96, 76, 22, 119, 28, 128, 180, 47, 196, 54, 39, 79, 77, 117, 175, 232, - 41, 163, 100, 174, 173, 25, 249, 112, 32, 5, 142, 12, 152, 22, 101, 75, 87, 107, 36, 221, 184, - 156, 79, 103, 107, 54, 161, 252, 217, 43, 40, 176, 171, 17, 41, 79, 98, 12, 130, 33, 166, 32, - 2, 125, 144, 17, 30, 245, 147, 128, 169, 244, 237, 54, 193, 101, 235, 179, 161, 60, 54, 105, - 18, 238, 217, 113, 216, 65, 234, 4, 58, 249, 104, 149, 32, 4, 16, 135, 217, 85, 38, 82, 172, - 64, 178, 52, 209, 103, 45, 208, 116, 226, 72, 229, 214, 237, 246, 47, 101, 18, 24, 82, 9, 149, - 110, 125, 164, 32, 7, 242, 58, 112, 247, 159, 250, 25, 111, 180, 119, 101, 221, 251, 137, 188, - 136, 187, 207, 71, 129, 154, 222, 50, 212, 194, 77, 17, 131, 85, 58, 114, 32, 7, 242, 113, 171, - 124, 230, 188, 19, 112, 125, 108, 113, 249, 196, 21, 102, 26, 213, 94, 247, 45, 8, 49, 73, 70, - 202, 194, 115, 137, 241, 153, 130, 32, 2, 233, 210, 109, 6, 113, 40, 250, 51, 212, 11, 48, 172, - 148, 235, 19, 101, 195, 78, 78, 186, 191, 218, 144, 254, 26, 71, 179, 1, 10, 188, 133, 32, 2, - 5, 82, 56, 185, 122, 156, 51, 212, 232, 216, 21, 100, 89, 130, 221, 7, 104, 144, 88, 225, 205, - 197, 255, 123, 100, 192, 228, 54, 122, 131, 48, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 3, 9, 188, 25, 165, 212, 95, 130, 7, - 21, 107, 213, 216, 158, 56, 138, 38, 198, 134, 30, 23, 245, 212, 132, 231, 211, 138, 76, 59, - 129, 73, 152, 32, 6, 216, 91, 49, 138, 90, 228, 233, 118, 58, 26, 247, 71, 55, 137, 248, 148, - 211, 218, 94, 104, 141, 163, 120, 28, 78, 243, 38, 4, 144, 100, 218, 32, 1, 213, 30, 175, 120, - 136, 190, 30, 48, 198, 93, 127, 2, 167, 209, 159, 194, 197, 187, 42, 255, 152, 225, 10, 50, - 248, 236, 97, 168, 204, 36, 185, 32, 6, 116, 40, 157, 22, 58, 92, 233, 38, 170, 101, 43, 46, - 218, 197, 93, 104, 41, 210, 10, 37, 60, 43, 79, 149, 114, 172, 29, 190, 168, 251, 199, 32, 3, - 24, 39, 128, 93, 103, 196, 5, 79, 185, 117, 7, 146, 153, 90, 254, 5, 130, 12, 153, 185, 207, - 30, 14, 152, 200, 36, 42, 150, 145, 210, 27, 32, 1, 22, 73, 41, 59, 234, 26, 5, 135, 102, 92, - 167, 184, 165, 180, 231, 236, 178, 6, 250, 91, 234, 0, 126, 175, 131, 92, 216, 45, 119, 80, - 147, 32, 0, 24, 159, 203, 4, 157, 232, 213, 23, 28, 133, 127, 211, 180, 158, 133, 47, 30, 163, - 246, 49, 145, 99, 106, 178, 121, 228, 187, 189, 10, 235, 213, 32, 4, 99, 234, 125, 221, 33, - 133, 10, 52, 208, 236, 249, 75, 84, 168, 16, 251, 127, 242, 68, 20, 178, 122, 76, 88, 145, 157, - 217, 88, 247, 115, 214, 32, 2, 163, 178, 0, 139, 184, 59, 187, 162, 214, 144, 29, 205, 51, 123, - 107, 71, 190, 65, 51, 8, 57, 146, 214, 252, 83, 154, 220, 2, 107, 132, 195, 32, 4, 245, 208, - 72, 15, 125, 89, 230, 25, 67, 1, 21, 219, 221, 174, 195, 233, 136, 44, 168, 226, 226, 232, 109, - 145, 115, 34, 246, 46, 238, 31, 9, 32, 4, 5, 199, 250, 218, 169, 198, 26, 12, 113, 75, 31, 56, - 13, 183, 227, 40, 115, 178, 77, 19, 179, 62, 10, 22, 158, 203, 154, 28, 109, 3, 3, 32, 6, 147, - 245, 50, 239, 249, 33, 78, 188, 107, 146, 100, 193, 23, 35, 66, 146, 24, 208, 159, 121, 233, - 179, 230, 34, 79, 169, 107, 66, 239, 151, 71, 32, 2, 186, 75, 75, 101, 248, 183, 192, 47, 126, - 193, 171, 154, 78, 117, 212, 136, 151, 56, 73, 34, 108, 13, 84, 224, 233, 150, 212, 9, 223, - 221, 56, 32, 2, 225, 247, 82, 0, 223, 3, 14, 142, 45, 9, 147, 121, 101, 208, 194, 33, 160, 92, - 2, 218, 29, 73, 200, 95, 100, 35, 40, 82, 31, 85, 18, 32, 4, 209, 105, 159, 89, 180, 86, 117, - 227, 33, 207, 136, 30, 228, 226, 166, 27, 117, 209, 88, 34, 122, 137, 25, 36, 106, 240, 50, - 122, 131, 86, 26, 32, 1, 156, 156, 80, 200, 107, 146, 183, 124, 114, 132, 209, 146, 60, 127, - 13, 38, 239, 122, 154, 136, 79, 36, 20, 147, 163, 108, 55, 188, 107, 1, 218, 32, 1, 215, 126, - 4, 177, 226, 207, 95, 131, 141, 176, 153, 7, 39, 6, 7, 156, 2, 94, 137, 84, 5, 222, 197, 120, - 162, 201, 13, 50, 254, 47, 147, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 7, 255, 255, 255, 254, 239, 253, 240, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 239, 255, 225, 1, 8, 143, 175, 215, 219, 185, 111, 177, 75, 73, 66, 181, 115, 149, 60, 155, 36, - 64, 201, 97, 22, 44, 5, 199, 189, 156, 70, 107, 202, 123, 120, 195, 22, 53, 201, 115, 119, 123, - 31, 250, 105, 162, 10, 120, 21, 98, 82, 118, 173, 203, 237, 10, 153, 113, 191, 66, 88, 177, 10, - 231, 230, 41, 67, 192, 249, 207, 99, 1, 50, 32, 159, 23, 4, 177, 177, 25, 222, 245, 171, 142, - 54, 95, 204, 168, 62, 52, 171, 93, 250, 1, 204, 122, 117, 10, 52, 107, 186, 208, 168, 36, 249, - 140, 75, 236, 88, 39, 14, 52, 42, 174, 36, 186, 134, 137, 48, 43, 33, 53, 149, 217, 125, 46, - 95, 174, 91, 171, 36, 50, 83, 66, 229, 202, 144, 161, 214, 44, 14, 190, 143, 160, 9, 57, 35, - 119, 113, 194, 148, 35, 100, 168, 241, 151, 40, 203, 46, 56, 120, 109, 133, 0, 249, 165, 107, - 85, 164, 80, 243, 242, 36, 235, 226, 199, 191, 219, 14, 217, 84, 59, 78, 176, 165, 80, 100, - 218, 54, 140, 125, 197, 249, 99, 247, 17, 71, 160, 180, 121, 49, 249, 172, 16, 189, 110, 38, - 119, 42, 116, 95, 138, 195, 26, 201, 251, 87, 172, 17, 108, 168, 101, 136, 252, 118, 147, 242, - 33, 11, 16, 200, 158, 124, 254, 165, 5, 73, 12, 53, 221, 137, 122, 171, 78, 203, 75, 123, 4, - 181, 50, 42, 37, 32, 13, 234, 176, 114, 190, 190, 94, 157, 8, 225, 76, 17, 77, 187, 76, 17, - 108, 216, 38, 71, 160, 110, 32, 238, 61, 148, 165, 33, 215, 48, 170, 187, 219, 64, 213, 76, - 195, 223, 39, 9, 99, 53, 201, 115, 119, 123, 31, 250, 105, 162, 10, 120, 21, 98, 82, 118, 173, - 203, 237, 10, 153, 113, 191, 66, 88, 177, 10, 231, 230, 41, 67, 192, 249, 207, 99, 1, 50, 32, - 159, 23, 4, 177, 177, 25, 222, 245, 171, 142, 54, 95, 204, 168, 62, 52, 171, 93, 250, 1, 204, - 122, 117, 10, 52, 107, 186, 208, 168, 36, 249, 140, 75, 236, 88, 39, 14, 52, 42, 174, 36, 186, - 134, 137, 48, 43, 33, 53, 149, 217, 125, 46, 95, 174, 91, 171, 36, 50, 83, 66, 229, 202, 144, - 161, 214, 44, 14, 190, 143, 160, 9, 57, 35, 119, 113, 194, 148, 35, 100, 168, 241, 151, 40, - 203, 46, 56, 120, 109, 133, 0, 249, 165, 107, 85, 164, 80, 243, 242, 36, 235, 226, 199, 191, - 219, 14, 217, 84, 59, 78, 176, 165, 80, 100, 218, 54, 140, 125, 197, 249, 99, 247, 17, 71, 160, - 180, 121, 49, 249, 172, 16, 189, 110, 38, 119, 42, 116, 95, 138, 195, 26, 201, 251, 87, 172, - 17, 108, 168, 101, 136, 252, 118, 147, 242, 33, 11, 16, 200, 158, 124, 254, 165, 5, 73, 12, 53, - 221, 137, 122, 171, 78, 203, 75, 123, 4, 181, 50, 42, 37, 32, 13, 234, 176, 114, 190, 190, 94, - 157, 23, 32, 7, 142, 147, 6, 21, 123, 33, 253, 55, 126, 197, 126, 95, 171, 57, 134, 188, 164, - 221, 62, 106, 229, 100, 218, 190, 240, 169, 120, 192, 242, 21, 214, 32, 2, 101, 51, 207, 215, - 58, 21, 130, 193, 114, 124, 220, 41, 22, 255, 94, 247, 102, 86, 120, 184, 44, 249, 175, 191, - 29, 59, 152, 233, 95, 5, 160, 32, 2, 101, 51, 207, 215, 58, 21, 130, 193, 114, 124, 220, 41, - 22, 255, 94, 247, 102, 86, 120, 184, 44, 249, 175, 191, 29, 59, 152, 233, 95, 5, 160, 32, 2, - 101, 51, 207, 215, 58, 21, 130, 193, 114, 124, 220, 41, 22, 255, 94, 247, 102, 86, 120, 184, - 44, 249, 175, 191, 29, 59, 152, 233, 95, 5, 160, 32, 5, 198, 59, 14, 129, 9, 55, 157, 229, 85, - 214, 246, 241, 224, 2, 104, 97, 11, 102, 254, 74, 31, 2, 254, 77, 240, 254, 1, 102, 112, 220, - 7, 32, 1, 149, 3, 229, 123, 254, 53, 90, 180, 12, 177, 118, 229, 25, 101, 129, 174, 72, 233, - 55, 115, 47, 64, 99, 224, 87, 203, 224, 83, 2, 144, 43, 32, 0, 79, 20, 33, 32, 162, 37, 81, - 246, 73, 132, 117, 228, 12, 110, 16, 235, 7, 30, 180, 27, 160, 14, 240, 189, 46, 91, 21, 216, - 64, 203, 90, 32, 4, 207, 119, 72, 96, 117, 72, 171, 211, 147, 31, 198, 86, 198, 33, 202, 8, 6, - 63, 191, 98, 133, 58, 151, 176, 55, 207, 50, 174, 186, 248, 239, 32, 5, 102, 223, 99, 115, 159, - 58, 4, 232, 62, 106, 40, 104, 197, 201, 116, 203, 33, 53, 13, 177, 69, 201, 180, 236, 150, 241, - 181, 218, 146, 10, 116, 32, 1, 229, 236, 16, 65, 233, 5, 25, 255, 34, 148, 148, 207, 205, 111, - 18, 183, 183, 223, 158, 88, 223, 85, 195, 89, 193, 138, 56, 116, 139, 16, 214, 32, 2, 195, 67, - 230, 197, 69, 139, 144, 214, 26, 24, 185, 48, 100, 137, 109, 31, 149, 226, 191, 153, 160, 76, - 154, 187, 218, 196, 45, 88, 165, 156, 249, 32, 4, 150, 62, 232, 148, 88, 193, 152, 250, 109, - 51, 174, 177, 44, 230, 166, 218, 76, 178, 43, 40, 205, 68, 44, 145, 166, 158, 254, 174, 149, - 36, 242, 32, 3, 14, 240, 4, 89, 157, 192, 58, 248, 159, 116, 211, 142, 150, 142, 236, 73, 182, - 90, 7, 91, 87, 7, 107, 189, 244, 179, 122, 127, 12, 35, 200, 32, 0, 102, 8, 193, 109, 36, 67, - 152, 19, 67, 42, 213, 132, 150, 154, 75, 167, 254, 116, 92, 85, 7, 210, 141, 9, 152, 66, 190, - 21, 152, 91, 153, 32, 1, 91, 26, 194, 246, 49, 88, 141, 120, 56, 129, 221, 243, 22, 225, 191, - 169, 145, 249, 173, 166, 166, 109, 88, 242, 17, 47, 51, 59, 30, 66, 1, 32, 3, 232, 219, 46, 93, - 245, 81, 62, 168, 92, 214, 120, 226, 205, 59, 177, 47, 110, 187, 138, 89, 242, 38, 118, 227, - 133, 239, 79, 143, 41, 76, 195, 32, 6, 96, 42, 9, 76, 140, 157, 64, 61, 18, 171, 162, 200, 156, - 48, 30, 116, 232, 116, 105, 54, 195, 84, 138, 241, 187, 228, 228, 188, 169, 108, 50, 32, 3, - 242, 246, 201, 183, 94, 3, 21, 82, 94, 19, 165, 232, 178, 141, 204, 58, 254, 226, 79, 253, 255, - 197, 255, 106, 177, 227, 92, 44, 3, 16, 148, 32, 7, 172, 240, 10, 110, 252, 147, 209, 62, 144, - 69, 91, 110, 89, 49, 137, 243, 236, 80, 229, 176, 61, 77, 238, 156, 26, 209, 115, 132, 240, 40, - 37, 32, 5, 56, 62, 108, 119, 202, 132, 171, 82, 235, 152, 214, 103, 223, 3, 209, 46, 5, 142, - 250, 0, 208, 197, 29, 191, 211, 7, 115, 228, 33, 108, 220, 32, 4, 215, 67, 154, 69, 154, 135, - 111, 35, 73, 247, 166, 78, 184, 82, 69, 114, 206, 159, 233, 186, 58, 99, 189, 163, 35, 51, 194, - 129, 196, 70, 175, 32, 7, 143, 126, 248, 168, 217, 88, 140, 0, 12, 61, 63, 246, 166, 185, 11, - 35, 151, 132, 157, 153, 254, 16, 148, 180, 109, 175, 72, 53, 36, 149, 68, 32, 1, 236, 79, 252, - 134, 255, 218, 253, 131, 249, 54, 44, 115, 128, 13, 110, 84, 125, 169, 171, 149, 21, 25, 25, - 43, 50, 96, 96, 240, 46, 18, 209, 23, 32, 7, 123, 254, 206, 143, 220, 186, 173, 38, 118, 168, - 213, 206, 142, 252, 212, 241, 204, 119, 97, 230, 125, 163, 44, 15, 99, 53, 38, 247, 9, 221, 5, - 32, 6, 65, 81, 64, 213, 111, 197, 141, 191, 201, 239, 87, 166, 191, 113, 153, 69, 74, 58, 63, - 119, 180, 145, 88, 240, 125, 76, 249, 230, 100, 76, 33, 32, 6, 65, 81, 64, 213, 111, 197, 141, - 191, 201, 239, 87, 166, 191, 113, 153, 69, 74, 58, 63, 119, 180, 145, 88, 240, 125, 76, 249, - 230, 100, 76, 33, 32, 6, 65, 81, 64, 213, 111, 197, 141, 191, 201, 239, 87, 166, 191, 113, 153, - 69, 74, 58, 63, 119, 180, 145, 88, 240, 125, 76, 249, 230, 100, 76, 33, 32, 5, 127, 151, 0, - 195, 85, 156, 93, 220, 124, 93, 211, 199, 213, 219, 169, 232, 163, 164, 216, 153, 69, 217, 95, - 174, 160, 27, 153, 77, 255, 143, 195, 32, 4, 116, 170, 73, 12, 229, 17, 213, 164, 3, 80, 214, - 11, 225, 8, 113, 66, 120, 217, 249, 198, 26, 209, 159, 110, 255, 6, 156, 32, 8, 242, 30, 32, 7, - 26, 124, 12, 227, 29, 202, 131, 159, 181, 209, 82, 246, 47, 231, 207, 6, 85, 19, 192, 218, 191, - 52, 31, 181, 194, 26, 87, 121, 151, 59, 70, 32, 6, 200, 217, 53, 151, 217, 208, 244, 172, 30, - 181, 142, 206, 36, 5, 51, 32, 245, 208, 31, 16, 249, 47, 43, 56, 155, 151, 35, 209, 66, 61, - 201, 32, 6, 16, 20, 202, 32, 119, 52, 245, 191, 147, 160, 244, 114, 155, 169, 23, 156, 26, 161, - 0, 166, 196, 161, 182, 62, 6, 131, 246, 243, 86, 39, 221, 32, 5, 5, 163, 229, 128, 60, 138, - 169, 223, 143, 34, 170, 203, 110, 41, 108, 51, 90, 243, 113, 20, 215, 31, 32, 53, 113, 150, 0, - 195, 229, 198, 180, 32, 6, 44, 176, 222, 123, 156, 157, 231, 226, 48, 148, 190, 187, 175, 32, - 100, 111, 48, 114, 173, 212, 193, 168, 158, 31, 119, 154, 13, 145, 47, 219, 154, 32, 2, 113, - 130, 114, 142, 187, 124, 33, 124, 16, 20, 163, 7, 135, 128, 195, 232, 186, 201, 37, 31, 180, - 151, 145, 61, 119, 163, 98, 230, 222, 255, 131, 32, 4, 186, 228, 154, 64, 145, 17, 193, 44, - 173, 111, 162, 13, 97, 122, 140, 184, 126, 230, 252, 139, 174, 186, 116, 229, 185, 81, 167, - 227, 172, 78, 7, 32, 7, 240, 155, 140, 34, 182, 40, 232, 244, 88, 158, 211, 201, 54, 132, 55, - 150, 207, 180, 66, 185, 128, 54, 145, 39, 226, 7, 188, 8, 191, 147, 74, 32, 6, 134, 39, 224, - 177, 50, 236, 236, 153, 60, 185, 186, 40, 212, 76, 252, 143, 184, 252, 118, 71, 93, 162, 133, - 66, 219, 167, 72, 9, 242, 255, 32, 32, 1, 175, 41, 43, 235, 241, 178, 150, 134, 241, 2, 209, - 204, 164, 137, 113, 245, 194, 181, 3, 76, 210, 255, 165, 17, 108, 25, 255, 198, 149, 65, 57, - 32, 1, 37, 226, 94, 6, 217, 61, 207, 85, 133, 227, 150, 102, 59, 43, 254, 164, 172, 211, 111, - 135, 239, 44, 158, 9, 121, 176, 242, 38, 78, 211, 38, 32, 0, 241, 143, 25, 238, 182, 108, 169, - 79, 193, 187, 243, 204, 195, 168, 56, 11, 79, 106, 139, 211, 183, 216, 46, 199, 2, 17, 104, - 196, 30, 159, 3, 32, 7, 49, 117, 239, 61, 103, 243, 249, 84, 100, 93, 128, 212, 230, 191, 75, - 204, 66, 228, 160, 172, 95, 235, 108, 61, 50, 101, 122, 183, 172, 29, 135, 32, 1, 137, 98, 241, - 24, 90, 195, 105, 148, 86, 253, 61, 129, 148, 255, 117, 38, 9, 72, 11, 57, 196, 49, 184, 45, - 195, 139, 134, 127, 128, 122, 164, 32, 2, 51, 119, 88, 85, 182, 72, 99, 157, 75, 108, 161, 111, - 186, 148, 194, 23, 244, 174, 92, 16, 6, 2, 7, 195, 130, 59, 168, 128, 140, 224, 155, 32, 3, 32, - 246, 95, 74, 197, 162, 195, 50, 53, 214, 192, 20, 143, 82, 58, 124, 45, 255, 158, 204, 214, 62, - 53, 60, 204, 135, 216, 177, 141, 72, 119, 32, 1, 207, 226, 59, 11, 86, 156, 112, 88, 167, 104, - 228, 76, 20, 89, 3, 136, 180, 95, 81, 151, 169, 88, 234, 196, 64, 171, 110, 94, 18, 237, 93, 7, - 223, 176, 137, 56, 34, 20, 220, 117, 204, 42, 101, 37, 254, 127, 159, 184, 45, 146, 224, 216, - 213, 171, 14, 47, 51, 242, 104, 53, 159, 183, 189, 142, 20, 35, 156, 90, 14, 139, 81, 151, 85, - 223, 66, 250, 192, 71, 233, 46, 70, 17, 154, 249, 67, 242, 43, 218, 37, 219, 8, 233, 176, 45, - 219, 183, 202, 146, 92, 237, 231, 92, 225, 161, 236, 140, 152, 24, 136, 150, 9, 10, 132, 241, - 33, 38, 195, 190, 159, 14, 216, 41, 128, 143, 188, 48, 251, 239, 231, 102, 253, 245, 174, 171, - 190, 149, 90, 248, 5, 170, 199, 101, 38, 205, 66, 24, 120, 101, 195, 107, 199, 25, 191, 20, - 195, 54, 3, 190, 149, 34, 232, 6, 174, 198, 153, 194, 67, 57, 25, 13, 66, 10, 104, 202, 169, - 248, 127, 114, 195, 29, 6, 232, 245, 21, 133, 119, 106, 167, 44, 27, 8, 27, 237, 138, 226, 59, - 242, 120, 11, 188, 127, 143, 128, 243, 155, 247, 151, 78, 29, 103, 194, 98, 234, 250, 167, 255, - 241, 154, 113, 186, 85, 108, 240, 84, 111, 163, 238, 222, 68, 50, 217, 122, 69, 188, 177, 88, - 171, 3, 59, 238, 53, 27, 39, 235, 53, 93, 13, 190, 107, 174, 144, 238, 168, 55, 70, 208, 7, - 223, 176, 137, 56, 34, 20, 220, 117, 204, 42, 101, 37, 254, 127, 159, 184, 45, 146, 224, 216, - 213, 171, 14, 47, 51, 242, 104, 53, 159, 183, 189, 142, 20, 35, 156, 90, 14, 139, 81, 151, 85, - 223, 66, 250, 192, 71, 233, 46, 70, 17, 154, 249, 67, 242, 43, 218, 37, 219, 8, 233, 176, 45, - 219, 183, 202, 146, 92, 237, 231, 92, 225, 161, 236, 140, 152, 24, 136, 150, 9, 10, 132, 241, - 33, 38, 195, 190, 159, 14, 216, 41, 128, 143, 188, 48, 251, 239, 231, 102, 253, 245, 174, 171, - 190, 149, 90, 248, 5, 170, 199, 101, 38, 205, 66, 24, 120, 101, 195, 107, 199, 25, 191, 20, - 195, 54, 3, 190, 149, 34, 232, 6, 174, 198, 153, 194, 67, 57, 25, 13, 66, 10, 104, 202, 169, - 248, 127, 114, 195, 29, 6, 232, 245, 21, 133, 119, 106, 167, 44, 27, 8, 27, 237, 138, 226, 59, - 242, 120, 11, 188, 127, 143, 128, 243, 155, 247, 151, 78, 29, 103, 194, 98, 234, 250, 167, 255, - 241, 154, 113, 186, 85, 108, 240, 84, 111, 163, 238, 222, 68, 50, 217, 122, 69, 188, 177, 88, - 171, 3, 59, 238, 53, 27, 39, 235, 53, 93, 13, 190, 107, 174, 144, 238, 168, 55, 70, 208, 2, 32, - 3, 217, 169, 177, 240, 4, 196, 128, 119, 155, 197, 53, 156, 199, 129, 214, 199, 115, 49, 99, - 221, 93, 178, 149, 239, 66, 87, 206, 118, 3, 14, 60, 32, 6, 87, 144, 100, 92, 84, 221, 234, 68, - 28, 139, 255, 104, 182, 74, 187, 18, 52, 203, 153, 252, 214, 202, 207, 140, 188, 228, 92, 76, - 181, 68, 146, 2, 32, 7, 72, 105, 187, 61, 213, 88, 1, 200, 104, 118, 116, 175, 244, 180, 112, - 101, 129, 142, 225, 30, 53, 245, 14, 34, 102, 171, 248, 86, 76, 249, 145, 32, 0, 156, 162, 126, - 22, 103, 4, 195, 229, 54, 125, 189, 196, 218, 227, 45, 130, 192, 214, 57, 20, 131, 93, 239, - 121, 38, 1, 128, 14, 153, 174, 205, 8, 44, 48, 189, 171, 247, 67, 41, 148, 159, 94, 72, 103, - 197, 198, 82, 66, 242, 249, 236, 141, 6, 123, 74, 227, 249, 206, 124, 47, 6, 104, 38, 230, 94, - 67, 253, 217, 249, 92, 206, 177, 100, 149, 47, 9, 185, 213, 11, 122, 221, 185, 44, 217, 47, 88, - 67, 78, 150, 36, 16, 37, 108, 107, 8, 115, 164, 164, 228, 237, 174, 82, 103, 190, 174, 187, 38, - 84, 24, 36, 133, 6, 191, 42, 16, 136, 195, 125, 107, 122, 215, 96, 219, 72, 76, 145, 38, 227, - 23, 142, 0, 23, 70, 116, 106, 121, 99, 128, 210, 78, 29, 19, 195, 22, 35, 246, 10, 106, 109, - 28, 115, 181, 223, 237, 182, 4, 20, 128, 109, 23, 191, 22, 144, 60, 121, 121, 64, 190, 105, 81, - 199, 185, 217, 98, 169, 242, 90, 255, 155, 197, 57, 106, 49, 93, 166, 34, 146, 145, 252, 153, - 151, 197, 90, 125, 16, 25, 41, 188, 114, 58, 89, 239, 63, 64, 105, 4, 102, 211, 3, 43, 180, - 109, 69, 210, 168, 47, 199, 3, 231, 17, 41, 201, 253, 197, 66, 155, 36, 12, 34, 61, 169, 95, - 84, 39, 35, 149, 250, 234, 76, 165, 17, 124, 40, 205, 185, 201, 27, 71, 191, 77, 148, 228, 244, - 148, 31, 91, 252, 89, 141, 6, 13, 139, 105, 158, 82, 26, 166, 148, 184, 91, 40, 185, 45, 214, - 150, 78, 230, 134, 109, 250, 24, 78, 249, 49, 197, 186, 141, 6, 8, 6, 66, 38, 16, 51, 119, 153, - 33, 189, 204, 188, 70, 40, 192, 179, 242, 238, 41, 48, 183, 178, 43, 146, 114, 227, 246, 152, - 194, 231, 155, 121, 149, 94, 67, 253, 217, 249, 92, 206, 177, 100, 149, 47, 9, 185, 213, 11, - 122, 221, 185, 44, 217, 47, 88, 67, 78, 150, 36, 16, 37, 108, 107, 8, 115, 164, 164, 228, 237, - 174, 82, 103, 190, 174, 187, 38, 84, 24, 36, 133, 6, 191, 42, 16, 136, 195, 125, 107, 122, 215, - 96, 219, 72, 76, 145, 38, 227, 23, 142, 0, 23, 70, 116, 106, 121, 99, 128, 210, 78, 29, 19, - 195, 22, 35, 246, 10, 106, 109, 28, 115, 181, 223, 237, 182, 4, 20, 128, 109, 23, 191, 22, 144, - 60, 121, 121, 64, 190, 105, 81, 199, 185, 217, 98, 169, 242, 90, 255, 155, 197, 57, 106, 49, - 93, 166, 34, 146, 145, 252, 153, 151, 197, 90, 125, 16, 25, 41, 188, 114, 58, 89, 239, 63, 64, - 105, 4, 102, 211, 3, 43, 180, 109, 69, 210, 168, 47, 199, 3, 231, 17, 41, 201, 253, 197, 66, - 155, 36, 12, 34, 61, 169, 95, 84, 39, 35, 149, 250, 234, 76, 165, 17, 124, 40, 205, 185, 201, - 27, 71, 191, 77, 148, 228, 244, 148, 31, 91, 252, 89, 141, 6, 13, 139, 105, 158, 82, 26, 166, - 148, 184, 91, 40, 185, 45, 214, 150, 78, 230, 134, 109, 250, 24, 78, 249, 49, 197, 186, 141, 6, - 36, 32, 3, 93, 72, 164, 72, 101, 137, 91, 50, 183, 167, 161, 235, 151, 19, 164, 69, 67, 138, - 192, 137, 97, 219, 32, 20, 126, 228, 1, 243, 84, 45, 40, 32, 0, 158, 110, 8, 12, 109, 214, 114, - 60, 23, 15, 171, 234, 87, 10, 24, 85, 255, 37, 163, 17, 166, 2, 189, 34, 250, 167, 64, 199, - 231, 68, 55, 32, 5, 12, 1, 165, 225, 71, 142, 63, 199, 27, 214, 62, 4, 7, 215, 119, 29, 204, - 176, 115, 44, 72, 45, 87, 253, 79, 104, 116, 220, 180, 99, 147, 32, 4, 209, 23, 205, 180, 18, - 18, 5, 133, 190, 98, 214, 252, 241, 64, 183, 234, 66, 9, 110, 133, 133, 252, 73, 122, 227, 44, - 221, 238, 127, 5, 190, 32, 0, 205, 182, 86, 228, 119, 212, 109, 157, 248, 48, 151, 3, 27, 143, - 210, 167, 197, 226, 35, 215, 173, 105, 126, 98, 90, 144, 169, 200, 216, 4, 27, 32, 7, 182, 153, - 192, 164, 94, 213, 7, 81, 178, 161, 104, 1, 253, 131, 118, 69, 226, 98, 112, 103, 138, 99, 200, - 16, 8, 213, 118, 146, 174, 172, 238, 32, 3, 138, 128, 166, 158, 66, 88, 106, 238, 115, 17, 236, - 1, 17, 18, 205, 217, 56, 172, 81, 37, 107, 16, 246, 41, 64, 227, 56, 191, 103, 249, 87, 32, 5, - 197, 64, 83, 79, 33, 44, 61, 247, 57, 136, 246, 0, 136, 137, 102, 236, 156, 86, 40, 146, 181, - 136, 123, 20, 160, 113, 156, 95, 179, 252, 172, 32, 6, 97, 73, 120, 25, 217, 174, 109, 140, - 223, 119, 82, 47, 54, 201, 127, 136, 196, 162, 77, 83, 117, 2, 151, 62, 68, 58, 246, 118, 115, - 38, 101, 32, 2, 157, 38, 116, 98, 175, 2, 6, 138, 30, 94, 136, 19, 148, 154, 76, 125, 244, 11, - 40, 93, 81, 83, 119, 116, 203, 167, 224, 50, 191, 159, 159, 32, 0, 175, 156, 11, 75, 255, 239, - 88, 118, 72, 86, 193, 185, 17, 52, 234, 231, 153, 47, 173, 77, 247, 77, 216, 57, 191, 20, 5, - 200, 213, 74, 117, 32, 0, 62, 153, 65, 208, 118, 182, 23, 174, 164, 155, 159, 232, 5, 38, 51, - 63, 181, 127, 35, 243, 123, 219, 125, 192, 209, 221, 203, 76, 82, 98, 86, 32, 5, 22, 232, 170, - 86, 80, 89, 25, 218, 109, 61, 10, 143, 104, 0, 127, 160, 66, 115, 104, 106, 128, 168, 41, 111, - 29, 36, 98, 131, 0, 67, 246, 32, 1, 206, 169, 179, 80, 23, 138, 158, 196, 38, 80, 29, 56, 215, - 173, 212, 221, 84, 28, 18, 145, 203, 40, 27, 75, 188, 125, 92, 200, 191, 96, 148, 32, 4, 101, - 254, 40, 26, 84, 221, 157, 243, 85, 218, 229, 203, 94, 91, 182, 129, 32, 133, 66, 82, 255, 210, - 103, 89, 210, 64, 214, 170, 248, 216, 89, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 93, 83, 13, 39, 225, 51, 125, 213, 246, - 158, 232, 243, 193, 188, 211, 178, 58, 244, 128, 89, 225, 155, 190, 28, 228, 120, 50, 132, 29, - 234, 244, 32, 7, 219, 227, 185, 248, 229, 236, 137, 91, 50, 171, 67, 42, 191, 128, 161, 154, - 154, 107, 199, 194, 156, 33, 2, 143, 255, 67, 51, 24, 104, 133, 14, 32, 5, 146, 19, 155, 160, - 141, 85, 232, 35, 7, 21, 242, 138, 101, 227, 115, 172, 245, 197, 2, 96, 173, 89, 196, 94, 161, - 149, 172, 204, 213, 77, 241, 32, 7, 249, 80, 4, 89, 1, 199, 167, 27, 139, 62, 219, 86, 89, 72, - 123, 115, 154, 224, 30, 134, 235, 116, 44, 8, 144, 129, 32, 105, 174, 180, 51, 32, 3, 109, 79, - 177, 19, 59, 134, 178, 84, 88, 166, 192, 234, 24, 132, 50, 9, 52, 190, 175, 103, 0, 114, 130, - 129, 252, 85, 105, 80, 13, 215, 44, 32, 0, 65, 132, 220, 157, 57, 141, 161, 237, 95, 246, 72, - 187, 213, 187, 214, 26, 96, 82, 179, 52, 229, 229, 37, 214, 245, 159, 218, 49, 194, 193, 152, - 32, 3, 183, 108, 42, 159, 80, 215, 118, 17, 80, 122, 97, 61, 97, 29, 254, 39, 135, 228, 135, - 94, 107, 106, 221, 63, 255, 38, 138, 6, 196, 241, 139, 32, 4, 138, 187, 53, 147, 230, 88, 117, - 192, 126, 19, 155, 155, 156, 127, 50, 196, 43, 177, 64, 239, 117, 169, 171, 254, 53, 246, 1, 9, - 12, 34, 196, 32, 4, 160, 6, 194, 185, 109, 38, 218, 213, 228, 88, 0, 31, 246, 241, 176, 177, - 119, 122, 108, 5, 184, 189, 59, 198, 144, 139, 221, 103, 10, 165, 2, 32, 2, 111, 100, 250, 248, - 222, 100, 64, 48, 166, 146, 122, 2, 8, 68, 252, 92, 143, 51, 116, 45, 110, 98, 100, 44, 170, - 181, 38, 109, 65, 195, 204, 32, 1, 20, 223, 54, 185, 95, 217, 122, 110, 8, 220, 187, 76, 74, - 65, 22, 142, 193, 220, 144, 118, 178, 193, 68, 147, 34, 251, 2, 23, 86, 59, 84, 32, 4, 11, 211, - 18, 40, 27, 51, 227, 51, 84, 194, 0, 1, 238, 114, 180, 172, 52, 106, 108, 246, 211, 240, 67, - 31, 136, 195, 86, 130, 203, 152, 13, 32, 3, 59, 216, 203, 252, 156, 121, 46, 5, 129, 98, 56, - 105, 47, 215, 70, 255, 253, 194, 22, 92, 185, 162, 24, 189, 240, 19, 167, 129, 51, 118, 15, 32, - 6, 218, 40, 8, 230, 94, 223, 24, 55, 176, 253, 83, 23, 76, 163, 40, 55, 166, 131, 30, 122, 192, - 213, 155, 114, 135, 8, 36, 157, 222, 29, 33, 32, 7, 158, 22, 33, 155, 10, 170, 45, 59, 39, 103, - 96, 105, 160, 76, 244, 221, 24, 125, 27, 163, 37, 121, 209, 200, 87, 71, 74, 128, 187, 192, 77, - 32, 1, 233, 235, 60, 224, 219, 201, 97, 98, 250, 177, 160, 110, 194, 21, 88, 29, 170, 204, 12, - 223, 187, 86, 195, 43, 127, 188, 63, 33, 176, 119, 155, 32, 7, 144, 93, 56, 141, 120, 249, 210, - 19, 205, 141, 91, 105, 178, 112, 63, 196, 79, 204, 39, 17, 230, 127, 8, 93, 82, 101, 30, 208, - 100, 221, 55, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 32, 7, 255, 255, 255, 254, 239, 253, 240, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 239, 255, 225, 36, - 32, 4, 198, 99, 47, 102, 150, 146, 77, 205, 39, 228, 73, 208, 170, 131, 91, 229, 149, 154, 108, - 150, 155, 148, 154, 250, 98, 98, 240, 61, 154, 247, 24, 32, 4, 94, 5, 186, 86, 10, 188, 71, 33, - 154, 51, 118, 173, 32, 170, 225, 114, 150, 144, 214, 197, 235, 56, 211, 75, 119, 174, 112, 233, - 134, 174, 246, 32, 6, 214, 144, 50, 68, 104, 213, 16, 190, 137, 200, 55, 159, 110, 39, 163, 41, - 71, 7, 35, 94, 3, 92, 153, 218, 69, 52, 27, 30, 199, 213, 181, 32, 0, 116, 127, 190, 3, 87, - 233, 226, 70, 40, 211, 143, 245, 140, 24, 29, 26, 136, 122, 149, 187, 102, 54, 132, 255, 0, - 112, 16, 195, 254, 74, 70, 32, 3, 133, 116, 230, 181, 99, 254, 244, 122, 42, 252, 158, 208, - 173, 141, 214, 205, 60, 187, 213, 75, 112, 84, 154, 121, 184, 79, 230, 137, 204, 151, 160, 32, - 5, 110, 77, 198, 197, 214, 119, 53, 127, 26, 252, 4, 108, 154, 64, 215, 160, 192, 232, 92, 43, - 150, 104, 189, 48, 198, 58, 17, 232, 126, 121, 248, 32, 0, 96, 162, 110, 38, 151, 101, 178, 95, - 20, 2, 138, 205, 173, 58, 137, 128, 172, 7, 37, 18, 32, 29, 212, 234, 147, 6, 25, 14, 62, 61, - 42, 32, 0, 48, 81, 55, 19, 75, 178, 217, 47, 138, 1, 69, 102, 214, 157, 68, 192, 86, 3, 146, - 137, 16, 14, 234, 117, 73, 131, 12, 135, 31, 30, 149, 32, 0, 70, 215, 101, 166, 112, 230, 215, - 64, 31, 158, 62, 130, 47, 190, 212, 203, 151, 94, 13, 91, 191, 102, 229, 251, 161, 134, 218, - 86, 116, 251, 118, 32, 7, 148, 42, 133, 153, 156, 222, 114, 121, 161, 47, 246, 4, 104, 253, 82, - 143, 222, 175, 136, 17, 84, 9, 185, 73, 24, 157, 55, 77, 203, 206, 170, 32, 6, 95, 234, 173, - 56, 114, 7, 142, 82, 41, 132, 108, 170, 143, 82, 105, 193, 167, 44, 204, 178, 1, 244, 42, 127, - 140, 103, 23, 202, 169, 243, 42, 32, 2, 77, 249, 28, 214, 193, 240, 93, 31, 25, 106, 39, 150, - 196, 222, 90, 225, 108, 105, 128, 180, 141, 3, 101, 242, 62, 156, 7, 172, 206, 229, 231, 32, 3, - 46, 149, 238, 10, 122, 151, 202, 36, 91, 125, 53, 54, 22, 155, 163, 176, 198, 51, 163, 149, - 187, 117, 74, 51, 8, 165, 38, 14, 24, 245, 40, 32, 4, 239, 189, 161, 235, 217, 214, 24, 228, - 113, 16, 30, 82, 45, 123, 159, 104, 103, 91, 25, 207, 207, 250, 116, 228, 250, 245, 176, 93, 7, - 252, 107, 32, 2, 166, 141, 155, 18, 183, 248, 119, 26, 147, 37, 170, 247, 219, 46, 2, 31, 160, - 9, 208, 255, 31, 92, 171, 51, 122, 64, 44, 65, 105, 106, 97, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 2, 156, 46, 34, 115, 162, - 75, 166, 181, 116, 156, 220, 60, 49, 126, 243, 206, 46, 132, 61, 180, 42, 193, 57, 105, 171, - 49, 92, 216, 164, 255, 63, 32, 2, 111, 35, 213, 86, 255, 227, 39, 70, 26, 138, 73, 140, 112, - 19, 17, 180, 33, 56, 2, 82, 70, 96, 99, 52, 178, 58, 41, 184, 87, 179, 113, 32, 3, 147, 237, - 53, 138, 141, 166, 16, 37, 177, 164, 176, 191, 57, 129, 184, 47, 249, 237, 203, 85, 179, 192, - 68, 69, 59, 199, 14, 83, 181, 238, 61, 32, 1, 118, 29, 91, 8, 184, 237, 60, 139, 126, 142, 141, - 59, 114, 71, 146, 78, 93, 78, 242, 123, 222, 219, 252, 43, 225, 140, 28, 230, 172, 188, 58, 32, - 1, 84, 130, 32, 213, 78, 79, 117, 206, 162, 1, 8, 224, 147, 200, 238, 60, 27, 30, 226, 8, 3, - 71, 210, 50, 243, 97, 91, 91, 212, 126, 174, 32, 0, 224, 32, 20, 176, 200, 99, 47, 72, 141, 39, - 151, 121, 176, 140, 240, 31, 227, 173, 200, 71, 167, 168, 90, 97, 117, 3, 120, 21, 185, 211, - 224, 32, 1, 37, 68, 6, 241, 202, 81, 117, 47, 144, 18, 225, 165, 193, 17, 181, 203, 96, 21, - 248, 79, 44, 199, 18, 158, 228, 197, 98, 156, 192, 94, 80, 32, 5, 185, 214, 73, 108, 240, 134, - 9, 148, 89, 43, 205, 61, 124, 125, 98, 76, 85, 5, 182, 185, 175, 212, 9, 48, 201, 89, 45, 183, - 104, 130, 89, 32, 4, 230, 12, 106, 169, 13, 106, 222, 118, 104, 250, 215, 212, 230, 34, 131, 8, - 142, 71, 207, 35, 197, 114, 84, 3, 18, 90, 18, 92, 190, 198, 231, 32, 6, 129, 116, 116, 248, - 215, 104, 164, 63, 123, 158, 128, 206, 108, 34, 113, 238, 69, 104, 59, 68, 244, 166, 220, 58, - 209, 172, 56, 49, 246, 59, 251, 32, 5, 86, 230, 229, 219, 163, 126, 239, 151, 183, 79, 219, - 168, 206, 75, 82, 196, 130, 131, 63, 170, 158, 100, 118, 233, 237, 114, 173, 176, 238, 108, - 217, 32, 7, 244, 155, 40, 219, 168, 42, 187, 215, 244, 185, 179, 251, 71, 122, 223, 29, 143, - 140, 84, 83, 0, 21, 74, 227, 57, 248, 25, 153, 112, 255, 181, 32, 7, 207, 113, 72, 180, 24, - 231, 110, 224, 195, 157, 3, 64, 86, 79, 206, 101, 110, 184, 221, 7, 149, 11, 254, 197, 182, - 100, 80, 245, 58, 63, 147, 32, 5, 221, 109, 132, 218, 56, 223, 127, 0, 226, 252, 251, 156, 5, - 76, 45, 87, 250, 6, 120, 225, 77, 119, 106, 247, 192, 187, 108, 242, 39, 4, 167, 32, 5, 115, - 229, 56, 54, 6, 240, 24, 242, 136, 101, 92, 116, 84, 44, 239, 43, 133, 203, 167, 3, 81, 139, 9, - 192, 77, 237, 242, 251, 5, 68, 235, 32, 4, 114, 254, 69, 61, 206, 97, 32, 57, 35, 33, 228, 65, - 18, 161, 248, 118, 151, 197, 161, 100, 84, 220, 9, 162, 222, 214, 19, 5, 249, 5, 5, 32, 6, 72, - 194, 21, 30, 130, 163, 152, 41, 83, 40, 242, 19, 88, 251, 153, 240, 87, 52, 164, 156, 51, 138, - 64, 89, 145, 227, 141, 228, 120, 119, 186, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 7, 255, 255, 255, 254, 239, 253, 240, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 239, 255, 225, 1, 8, 198, 23, 84, 255, 151, 170, 24, 10, 205, 81, 45, 252, 78, 227, - 104, 43, 34, 71, 48, 21, 221, 59, 83, 55, 230, 173, 205, 23, 165, 63, 164, 81, 214, 5, 201, - 144, 116, 141, 237, 183, 99, 166, 133, 98, 237, 150, 237, 117, 64, 62, 158, 103, 219, 38, 180, - 159, 216, 51, 118, 132, 190, 36, 174, 82, 184, 132, 162, 205, 221, 202, 214, 145, 217, 167, 46, - 204, 125, 71, 164, 57, 104, 83, 60, 227, 147, 221, 50, 19, 127, 168, 46, 215, 74, 229, 109, - 113, 208, 168, 36, 249, 140, 75, 236, 88, 39, 14, 52, 42, 174, 36, 186, 134, 137, 48, 43, 33, - 53, 149, 217, 125, 46, 95, 174, 91, 171, 36, 50, 83, 66, 229, 202, 144, 161, 214, 44, 14, 190, - 143, 160, 9, 57, 35, 119, 113, 194, 148, 35, 100, 168, 241, 151, 40, 203, 46, 56, 120, 109, - 133, 0, 249, 165, 107, 85, 164, 80, 243, 242, 36, 235, 226, 199, 191, 219, 14, 217, 84, 59, 78, - 176, 165, 80, 100, 218, 54, 140, 125, 197, 249, 99, 247, 17, 71, 160, 180, 121, 49, 249, 172, - 16, 189, 110, 38, 119, 42, 116, 95, 138, 195, 26, 201, 251, 87, 172, 17, 108, 168, 101, 136, - 252, 118, 147, 242, 33, 11, 16, 200, 158, 124, 254, 165, 5, 73, 12, 53, 221, 137, 122, 171, 78, - 203, 75, 123, 4, 181, 50, 42, 37, 32, 13, 234, 176, 114, 190, 190, 94, 157, 8, 170, 178, 81, - 208, 81, 111, 31, 28, 126, 253, 70, 188, 190, 185, 39, 217, 50, 111, 70, 67, 107, 101, 179, 74, - 138, 102, 107, 71, 148, 178, 73, 169, 214, 5, 201, 144, 116, 141, 237, 183, 99, 166, 133, 98, - 237, 150, 237, 117, 64, 62, 158, 103, 219, 38, 180, 159, 216, 51, 118, 132, 190, 36, 174, 82, - 184, 132, 162, 205, 221, 202, 214, 145, 217, 167, 46, 204, 125, 71, 164, 57, 104, 83, 60, 227, - 147, 221, 50, 19, 127, 168, 46, 215, 74, 229, 109, 113, 208, 168, 36, 249, 140, 75, 236, 88, - 39, 14, 52, 42, 174, 36, 186, 134, 137, 48, 43, 33, 53, 149, 217, 125, 46, 95, 174, 91, 171, - 36, 50, 83, 66, 229, 202, 144, 161, 214, 44, 14, 190, 143, 160, 9, 57, 35, 119, 113, 194, 148, - 35, 100, 168, 241, 151, 40, 203, 46, 56, 120, 109, 133, 0, 249, 165, 107, 85, 164, 80, 243, - 242, 36, 235, 226, 199, 191, 219, 14, 217, 84, 59, 78, 176, 165, 80, 100, 218, 54, 140, 125, - 197, 249, 99, 247, 17, 71, 160, 180, 121, 49, 249, 172, 16, 189, 110, 38, 119, 42, 116, 95, - 138, 195, 26, 201, 251, 87, 172, 17, 108, 168, 101, 136, 252, 118, 147, 242, 33, 11, 16, 200, - 158, 124, 254, 165, 5, 73, 12, 53, 221, 137, 122, 171, 78, 203, 75, 123, 4, 181, 50, 42, 37, - 32, 13, 234, 176, 114, 190, 190, 94, 157, 23, 32, 1, 226, 90, 177, 34, 62, 201, 180, 249, 9, - 215, 203, 139, 66, 88, 169, 207, 196, 116, 47, 36, 127, 53, 131, 194, 0, 71, 133, 68, 125, 203, - 156, 32, 5, 84, 147, 243, 72, 44, 231, 137, 95, 82, 224, 204, 154, 206, 188, 12, 47, 68, 76, - 47, 63, 17, 175, 206, 61, 111, 0, 64, 60, 146, 23, 95, 32, 5, 84, 147, 243, 72, 44, 231, 137, - 95, 82, 224, 204, 154, 206, 188, 12, 47, 68, 76, 47, 63, 17, 175, 206, 61, 111, 0, 64, 60, 146, - 23, 95, 32, 5, 84, 147, 243, 72, 44, 231, 137, 95, 82, 224, 204, 154, 206, 188, 12, 47, 68, 76, - 47, 63, 17, 175, 206, 61, 111, 0, 64, 60, 146, 23, 95, 32, 3, 90, 112, 38, 248, 174, 225, 80, - 47, 99, 208, 220, 166, 201, 154, 71, 62, 141, 42, 104, 172, 207, 250, 140, 201, 249, 74, 88, - 26, 166, 127, 212, 32, 5, 134, 245, 233, 202, 185, 178, 113, 74, 59, 208, 205, 65, 8, 236, 118, - 243, 40, 83, 202, 162, 159, 83, 0, 191, 255, 58, 82, 220, 255, 23, 29, 32, 6, 227, 171, 139, - 219, 139, 164, 90, 41, 98, 199, 188, 177, 9, 186, 202, 145, 64, 5, 126, 143, 190, 146, 169, 7, - 143, 169, 218, 35, 68, 235, 128, 32, 0, 130, 168, 205, 202, 184, 230, 169, 214, 27, 165, 47, - 104, 18, 54, 173, 167, 144, 26, 11, 42, 182, 168, 131, 255, 193, 120, 81, 92, 85, 21, 9, 32, 0, - 198, 81, 52, 192, 76, 178, 36, 188, 172, 159, 24, 73, 243, 74, 123, 37, 10, 41, 255, 32, 109, - 116, 92, 255, 49, 76, 67, 28, 250, 217, 188, 32, 1, 236, 236, 188, 57, 240, 250, 49, 136, 157, - 51, 197, 131, 190, 82, 109, 93, 176, 233, 189, 132, 124, 15, 150, 83, 200, 212, 101, 116, 234, - 125, 71, 32, 2, 65, 199, 238, 237, 253, 238, 0, 191, 87, 58, 174, 152, 1, 151, 187, 90, 87, - 125, 195, 41, 103, 49, 189, 18, 125, 62, 190, 24, 62, 181, 83, 32, 4, 198, 36, 193, 246, 195, - 182, 251, 63, 57, 13, 176, 164, 25, 122, 253, 188, 150, 158, 106, 136, 241, 239, 75, 249, 173, - 62, 56, 58, 118, 253, 98, 32, 7, 152, 239, 4, 75, 94, 140, 52, 205, 198, 243, 9, 254, 146, 160, - 50, 36, 61, 193, 169, 85, 180, 218, 212, 66, 18, 232, 128, 75, 217, 49, 104, 32, 4, 150, 204, - 12, 168, 216, 22, 200, 19, 209, 117, 116, 14, 1, 6, 73, 199, 148, 170, 40, 201, 65, 239, 108, - 97, 54, 161, 208, 73, 96, 40, 77, 32, 0, 89, 1, 107, 47, 187, 250, 147, 133, 134, 49, 97, 130, - 198, 199, 203, 218, 83, 147, 96, 23, 159, 218, 246, 198, 194, 81, 13, 28, 75, 53, 47, 32, 1, - 28, 219, 187, 19, 102, 9, 144, 68, 190, 184, 76, 169, 190, 127, 131, 71, 71, 99, 157, 255, 174, - 167, 193, 86, 169, 29, 171, 160, 168, 87, 20, 32, 4, 220, 160, 34, 62, 11, 188, 248, 175, 118, - 70, 24, 125, 79, 86, 37, 114, 155, 49, 100, 78, 8, 48, 75, 159, 236, 21, 197, 193, 244, 118, - 250, 32, 3, 55, 131, 240, 131, 7, 226, 70, 14, 219, 44, 30, 186, 18, 176, 152, 179, 224, 211, - 175, 71, 201, 115, 172, 16, 8, 196, 103, 206, 249, 150, 82, 32, 1, 77, 168, 185, 25, 164, 38, - 14, 193, 137, 113, 154, 54, 217, 60, 156, 38, 138, 122, 105, 254, 17, 102, 164, 221, 43, 37, - 170, 221, 72, 232, 151, 32, 3, 37, 118, 187, 49, 235, 31, 41, 121, 145, 157, 107, 21, 174, 81, - 106, 253, 208, 11, 111, 44, 169, 123, 199, 86, 247, 34, 146, 159, 78, 78, 134, 32, 6, 25, 172, - 62, 68, 76, 1, 151, 154, 104, 86, 6, 130, 165, 106, 33, 176, 185, 58, 216, 16, 206, 236, 152, - 171, 90, 91, 42, 229, 248, 62, 237, 32, 4, 6, 28, 244, 157, 110, 212, 16, 249, 146, 113, 14, - 89, 246, 188, 124, 152, 104, 62, 116, 143, 17, 229, 77, 42, 21, 54, 36, 127, 143, 46, 180, 32, - 6, 213, 30, 201, 15, 161, 166, 224, 201, 122, 48, 53, 149, 96, 216, 206, 129, 31, 134, 225, 26, - 111, 0, 127, 54, 100, 16, 33, 24, 239, 169, 118, 23, 32, 6, 5, 152, 2, 28, 99, 252, 217, 4, - 193, 210, 48, 97, 240, 47, 63, 19, 117, 140, 245, 109, 151, 204, 220, 129, 39, 253, 49, 242, - 168, 120, 151, 32, 5, 174, 60, 34, 214, 147, 223, 113, 120, 155, 177, 195, 231, 225, 156, 129, - 231, 208, 52, 152, 129, 190, 176, 115, 224, 38, 54, 197, 65, 184, 142, 232, 32, 5, 174, 60, 34, - 214, 147, 223, 113, 120, 155, 177, 195, 231, 225, 156, 129, 231, 208, 52, 152, 129, 190, 176, - 115, 224, 38, 54, 197, 65, 184, 142, 232, 32, 5, 174, 60, 34, 214, 147, 223, 113, 120, 155, - 177, 195, 231, 225, 156, 129, 231, 208, 52, 152, 129, 190, 176, 115, 224, 38, 54, 197, 65, 184, - 142, 232, 32, 7, 121, 221, 240, 129, 105, 88, 243, 253, 201, 60, 90, 139, 168, 81, 179, 130, - 76, 9, 95, 160, 104, 0, 244, 217, 146, 66, 101, 158, 81, 168, 54, 32, 3, 213, 73, 227, 177, - 207, 252, 173, 28, 118, 100, 147, 55, 66, 251, 107, 88, 24, 5, 238, 106, 72, 82, 218, 80, 172, - 99, 216, 235, 159, 151, 50, 32, 7, 166, 82, 123, 107, 43, 164, 75, 210, 180, 109, 36, 0, 35, - 152, 37, 8, 141, 249, 252, 44, 138, 67, 152, 2, 224, 75, 38, 106, 110, 253, 236, 32, 4, 41, 74, - 94, 251, 100, 113, 67, 170, 6, 100, 54, 157, 118, 217, 101, 75, 145, 69, 14, 165, 142, 150, - 236, 107, 5, 130, 59, 182, 189, 116, 1, 32, 7, 53, 87, 13, 68, 248, 17, 250, 175, 182, 241, - 183, 220, 59, 172, 179, 118, 165, 111, 58, 136, 7, 230, 99, 169, 178, 182, 245, 120, 169, 158, - 50, 32, 2, 86, 206, 226, 81, 43, 2, 142, 153, 222, 85, 106, 197, 123, 159, 24, 79, 55, 128, 92, - 124, 80, 81, 214, 171, 62, 227, 253, 77, 143, 102, 42, 32, 0, 71, 65, 188, 141, 114, 57, 192, - 29, 15, 199, 3, 116, 181, 84, 185, 134, 76, 5, 81, 13, 253, 171, 180, 121, 221, 223, 175, 88, - 166, 11, 196, 32, 6, 57, 225, 140, 207, 235, 77, 232, 93, 0, 172, 133, 213, 23, 104, 96, 146, - 118, 242, 175, 33, 244, 78, 83, 99, 173, 165, 213, 204, 30, 253, 95, 32, 4, 83, 171, 84, 96, - 90, 141, 133, 240, 109, 239, 84, 166, 217, 236, 205, 142, 191, 73, 197, 45, 188, 207, 222, 60, - 225, 187, 184, 238, 102, 84, 103, 32, 0, 248, 88, 98, 94, 207, 141, 75, 237, 61, 234, 162, 40, - 176, 186, 22, 52, 93, 138, 100, 151, 157, 182, 64, 247, 146, 176, 157, 203, 35, 208, 185, 32, - 6, 178, 43, 190, 231, 177, 156, 59, 89, 32, 7, 140, 237, 213, 218, 119, 18, 186, 119, 179, 205, - 10, 76, 209, 60, 72, 173, 79, 129, 116, 34, 212, 32, 7, 232, 242, 81, 73, 173, 219, 223, 87, 6, - 238, 88, 194, 11, 217, 198, 236, 17, 49, 50, 99, 140, 203, 66, 62, 38, 52, 62, 34, 39, 73, 208, - 32, 7, 164, 100, 246, 243, 192, 242, 11, 3, 187, 235, 185, 48, 141, 142, 105, 234, 220, 67, - 207, 112, 68, 78, 196, 178, 224, 209, 7, 183, 12, 184, 178, 32, 7, 134, 217, 46, 19, 216, 242, - 5, 148, 52, 225, 134, 144, 179, 143, 210, 3, 36, 53, 103, 68, 180, 1, 170, 39, 27, 89, 253, 40, - 180, 186, 55, 32, 2, 51, 50, 203, 226, 167, 22, 7, 220, 184, 62, 60, 166, 91, 148, 101, 64, 96, - 252, 158, 211, 27, 103, 227, 108, 209, 86, 179, 120, 142, 108, 125, 32, 0, 214, 90, 141, 11, - 83, 126, 234, 160, 200, 182, 133, 217, 156, 187, 122, 199, 33, 63, 147, 194, 184, 189, 155, - 189, 176, 50, 183, 77, 239, 118, 65, 32, 2, 220, 62, 108, 245, 46, 101, 64, 164, 180, 143, 208, - 135, 122, 178, 73, 13, 227, 145, 18, 129, 86, 111, 249, 131, 202, 162, 107, 222, 148, 145, 90, - 32, 0, 220, 193, 44, 213, 8, 251, 223, 112, 251, 65, 71, 90, 159, 20, 177, 98, 21, 184, 150, - 66, 54, 11, 248, 231, 48, 118, 114, 29, 66, 143, 26, 32, 4, 89, 205, 230, 246, 77, 248, 106, - 59, 250, 124, 66, 250, 146, 104, 183, 83, 64, 79, 182, 76, 27, 7, 149, 119, 76, 145, 118, 129, - 21, 32, 98, 7, 223, 176, 137, 56, 34, 20, 220, 117, 204, 42, 101, 37, 254, 127, 159, 184, 45, - 146, 224, 216, 213, 171, 14, 47, 51, 242, 104, 53, 159, 183, 189, 142, 20, 35, 156, 90, 14, - 139, 81, 151, 85, 223, 66, 250, 192, 71, 233, 46, 70, 17, 154, 249, 67, 242, 43, 218, 37, 219, - 8, 233, 176, 45, 219, 183, 202, 146, 92, 237, 231, 92, 225, 161, 236, 140, 152, 24, 136, 150, - 9, 10, 132, 241, 33, 38, 195, 190, 159, 14, 216, 41, 128, 143, 188, 48, 251, 239, 231, 102, - 253, 245, 174, 171, 190, 149, 90, 248, 5, 170, 199, 101, 38, 205, 66, 24, 120, 101, 195, 107, - 199, 25, 191, 20, 195, 54, 3, 190, 149, 34, 232, 6, 174, 198, 153, 194, 67, 57, 25, 13, 66, 10, - 104, 202, 169, 248, 127, 114, 195, 29, 6, 232, 245, 21, 133, 119, 106, 167, 44, 27, 8, 27, 237, - 138, 226, 59, 242, 120, 11, 188, 127, 143, 128, 243, 155, 247, 151, 78, 29, 103, 194, 98, 234, - 250, 167, 255, 241, 154, 113, 186, 85, 108, 240, 84, 111, 163, 238, 222, 68, 50, 217, 122, 69, - 188, 177, 88, 171, 3, 59, 238, 53, 27, 39, 235, 53, 93, 13, 190, 107, 174, 144, 238, 168, 55, - 70, 208, 7, 223, 176, 137, 56, 34, 20, 220, 117, 204, 42, 101, 37, 254, 127, 159, 184, 45, 146, - 224, 216, 213, 171, 14, 47, 51, 242, 104, 53, 159, 183, 189, 142, 20, 35, 156, 90, 14, 139, 81, - 151, 85, 223, 66, 250, 192, 71, 233, 46, 70, 17, 154, 249, 67, 242, 43, 218, 37, 219, 8, 233, - 176, 45, 219, 183, 202, 146, 92, 237, 231, 92, 225, 161, 236, 140, 152, 24, 136, 150, 9, 10, - 132, 241, 33, 38, 195, 190, 159, 14, 216, 41, 128, 143, 188, 48, 251, 239, 231, 102, 253, 245, - 174, 171, 190, 149, 90, 248, 5, 170, 199, 101, 38, 205, 66, 24, 120, 101, 195, 107, 199, 25, - 191, 20, 195, 54, 3, 190, 149, 34, 232, 6, 174, 198, 153, 194, 67, 57, 25, 13, 66, 10, 104, - 202, 169, 248, 127, 114, 195, 29, 6, 232, 245, 21, 133, 119, 106, 167, 44, 27, 8, 27, 237, 138, - 226, 59, 242, 120, 11, 188, 127, 143, 128, 243, 155, 247, 151, 78, 29, 103, 194, 98, 234, 250, - 167, 255, 241, 154, 113, 186, 85, 108, 240, 84, 111, 163, 238, 222, 68, 50, 217, 122, 69, 188, - 177, 88, 171, 3, 59, 238, 53, 27, 39, 235, 53, 93, 13, 190, 107, 174, 144, 238, 168, 55, 70, - 208, 2, 32, 3, 217, 169, 177, 240, 4, 196, 128, 119, 155, 197, 53, 156, 199, 129, 214, 199, - 115, 49, 99, 221, 93, 178, 149, 239, 66, 87, 206, 118, 3, 14, 60, 32, 6, 87, 144, 100, 92, 84, - 221, 234, 68, 28, 139, 255, 104, 182, 74, 187, 18, 52, 203, 153, 252, 214, 202, 207, 140, 188, - 228, 92, 76, 181, 68, 146, 2, 32, 7, 72, 105, 187, 61, 213, 88, 1, 200, 104, 118, 116, 175, - 244, 180, 112, 101, 129, 142, 225, 30, 53, 245, 14, 34, 102, 171, 248, 86, 76, 249, 145, 32, 0, - 156, 162, 126, 22, 103, 4, 195, 229, 54, 125, 189, 196, 218, 227, 45, 130, 192, 214, 57, 20, - 131, 93, 239, 121, 38, 1, 128, 14, 153, 174, 205, 8, 44, 48, 189, 171, 247, 67, 41, 148, 159, - 94, 72, 103, 197, 198, 82, 66, 242, 249, 236, 141, 6, 123, 74, 227, 249, 206, 124, 47, 6, 104, - 38, 230, 94, 67, 253, 217, 249, 92, 206, 177, 100, 149, 47, 9, 185, 213, 11, 122, 221, 185, 44, - 217, 47, 88, 67, 78, 150, 36, 16, 37, 108, 107, 8, 115, 164, 164, 228, 237, 174, 82, 103, 190, - 174, 187, 38, 84, 24, 36, 133, 6, 191, 42, 16, 136, 195, 125, 107, 122, 215, 96, 219, 72, 76, - 145, 38, 227, 23, 142, 0, 23, 70, 116, 106, 121, 99, 128, 210, 78, 29, 19, 195, 22, 35, 246, - 10, 106, 109, 28, 115, 181, 223, 237, 182, 4, 20, 128, 109, 23, 191, 22, 144, 60, 121, 121, 64, - 190, 105, 81, 199, 185, 217, 98, 169, 242, 90, 255, 155, 197, 57, 106, 49, 93, 166, 34, 146, - 145, 252, 153, 151, 197, 90, 125, 16, 25, 41, 188, 114, 58, 89, 239, 63, 64, 105, 4, 102, 211, + 250, 24, 78, 249, 49, 197, 186, 141, 6, 8, 80, 32, 245, 250, 73, 182, 254, 224, 221, 201, 126, + 136, 9, 100, 226, 76, 104, 161, 124, 29, 227, 115, 194, 205, 218, 183, 229, 180, 154, 171, 16, + 114, 138, 172, 80, 210, 73, 228, 117, 59, 0, 40, 28, 69, 91, 166, 191, 11, 97, 172, 37, 28, + 174, 5, 94, 106, 50, 248, 229, 59, 162, 89, 94, 231, 74, 147, 252, 163, 246, 133, 208, 151, 87, + 189, 40, 208, 243, 159, 219, 5, 173, 34, 96, 18, 158, 19, 99, 83, 193, 175, 94, 97, 238, 97, + 169, 236, 150, 245, 207, 203, 230, 180, 210, 239, 201, 38, 87, 47, 79, 103, 91, 115, 144, 169, + 207, 195, 17, 196, 182, 226, 74, 106, 171, 149, 236, 195, 101, 146, 225, 111, 62, 174, 168, 68, + 214, 215, 129, 69, 23, 126, 173, 62, 129, 192, 223, 180, 220, 93, 110, 122, 57, 46, 181, 95, + 198, 39, 137, 90, 39, 24, 90, 125, 16, 25, 41, 188, 114, 58, 89, 239, 63, 64, 105, 4, 102, 211, 3, 43, 180, 109, 69, 210, 168, 47, 199, 3, 231, 17, 41, 201, 253, 197, 66, 155, 36, 12, 34, 61, 169, 95, 84, 39, 35, 149, 250, 234, 76, 165, 17, 124, 40, 205, 185, 201, 27, 71, 191, 77, 148, 228, 244, 148, 31, 91, 252, 89, 141, 6, 13, 139, 105, 158, 82, 26, 166, 148, 184, 91, 40, 185, - 45, 214, 150, 78, 230, 134, 109, 250, 24, 78, 249, 49, 197, 186, 141, 6, 8, 6, 66, 38, 16, 51, - 119, 153, 33, 189, 204, 188, 70, 40, 192, 179, 242, 238, 41, 48, 183, 178, 43, 146, 114, 227, - 246, 152, 194, 231, 155, 121, 149, 94, 67, 253, 217, 249, 92, 206, 177, 100, 149, 47, 9, 185, - 213, 11, 122, 221, 185, 44, 217, 47, 88, 67, 78, 150, 36, 16, 37, 108, 107, 8, 115, 164, 164, - 228, 237, 174, 82, 103, 190, 174, 187, 38, 84, 24, 36, 133, 6, 191, 42, 16, 136, 195, 125, 107, - 122, 215, 96, 219, 72, 76, 145, 38, 227, 23, 142, 0, 23, 70, 116, 106, 121, 99, 128, 210, 78, - 29, 19, 195, 22, 35, 246, 10, 106, 109, 28, 115, 181, 223, 237, 182, 4, 20, 128, 109, 23, 191, - 22, 144, 60, 121, 121, 64, 190, 105, 81, 199, 185, 217, 98, 169, 242, 90, 255, 155, 197, 57, - 106, 49, 93, 166, 34, 146, 145, 252, 153, 151, 197, 90, 125, 16, 25, 41, 188, 114, 58, 89, 239, - 63, 64, 105, 4, 102, 211, 3, 43, 180, 109, 69, 210, 168, 47, 199, 3, 231, 17, 41, 201, 253, - 197, 66, 155, 36, 12, 34, 61, 169, 95, 84, 39, 35, 149, 250, 234, 76, 165, 17, 124, 40, 205, - 185, 201, 27, 71, 191, 77, 148, 228, 244, 148, 31, 91, 252, 89, 141, 6, 13, 139, 105, 158, 82, - 26, 166, 148, 184, 91, 40, 185, 45, 214, 150, 78, 230, 134, 109, 250, 24, 78, 249, 49, 197, - 186, 141, 6, 36, 32, 3, 93, 72, 164, 72, 101, 137, 91, 50, 183, 167, 161, 235, 151, 19, 164, - 69, 67, 138, 192, 137, 97, 219, 32, 20, 126, 228, 1, 243, 84, 45, 40, 32, 0, 158, 110, 8, 12, - 109, 214, 114, 60, 23, 15, 171, 234, 87, 10, 24, 85, 255, 37, 163, 17, 166, 2, 189, 34, 250, - 167, 64, 199, 231, 68, 55, 32, 5, 12, 1, 165, 225, 71, 142, 63, 199, 27, 214, 62, 4, 7, 215, - 119, 29, 204, 176, 115, 44, 72, 45, 87, 253, 79, 104, 116, 220, 180, 99, 147, 32, 4, 209, 23, - 205, 180, 18, 18, 5, 133, 190, 98, 214, 252, 241, 64, 183, 234, 66, 9, 110, 133, 133, 252, 73, - 122, 227, 44, 221, 238, 127, 5, 190, 32, 0, 205, 182, 86, 228, 119, 212, 109, 157, 248, 48, - 151, 3, 27, 143, 210, 167, 197, 226, 35, 215, 173, 105, 126, 98, 90, 144, 169, 200, 216, 4, 27, - 32, 7, 182, 153, 192, 164, 94, 213, 7, 81, 178, 161, 104, 1, 253, 131, 118, 69, 226, 98, 112, - 103, 138, 99, 200, 16, 8, 213, 118, 146, 174, 172, 238, 32, 3, 138, 128, 166, 158, 66, 88, 106, - 238, 115, 17, 236, 1, 17, 18, 205, 217, 56, 172, 81, 37, 107, 16, 246, 41, 64, 227, 56, 191, - 103, 249, 87, 32, 5, 197, 64, 83, 79, 33, 44, 61, 247, 57, 136, 246, 0, 136, 137, 102, 236, - 156, 86, 40, 146, 181, 136, 123, 20, 160, 113, 156, 95, 179, 252, 172, 32, 6, 97, 73, 120, 25, - 217, 174, 109, 140, 223, 119, 82, 47, 54, 201, 127, 136, 196, 162, 77, 83, 117, 2, 151, 62, 68, - 58, 246, 118, 115, 38, 101, 32, 2, 157, 38, 116, 98, 175, 2, 6, 138, 30, 94, 136, 19, 148, 154, - 76, 125, 244, 11, 40, 93, 81, 83, 119, 116, 203, 167, 224, 50, 191, 159, 159, 32, 0, 175, 156, - 11, 75, 255, 239, 88, 118, 72, 86, 193, 185, 17, 52, 234, 231, 153, 47, 173, 77, 247, 77, 216, - 57, 191, 20, 5, 200, 213, 74, 117, 32, 0, 62, 153, 65, 208, 118, 182, 23, 174, 164, 155, 159, - 232, 5, 38, 51, 63, 181, 127, 35, 243, 123, 219, 125, 192, 209, 221, 203, 76, 82, 98, 86, 32, - 5, 22, 232, 170, 86, 80, 89, 25, 218, 109, 61, 10, 143, 104, 0, 127, 160, 66, 115, 104, 106, - 128, 168, 41, 111, 29, 36, 98, 131, 0, 67, 246, 32, 1, 206, 169, 179, 80, 23, 138, 158, 196, - 38, 80, 29, 56, 215, 173, 212, 221, 84, 28, 18, 145, 203, 40, 27, 75, 188, 125, 92, 200, 191, - 96, 148, 32, 4, 101, 254, 40, 26, 84, 221, 157, 243, 85, 218, 229, 203, 94, 91, 182, 129, 32, - 133, 66, 82, 255, 210, 103, 89, 210, 64, 214, 170, 248, 216, 89, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 93, 83, 13, 39, - 225, 51, 125, 213, 246, 158, 232, 243, 193, 188, 211, 178, 58, 244, 128, 89, 225, 155, 190, 28, - 228, 120, 50, 132, 29, 234, 244, 32, 7, 219, 227, 185, 248, 229, 236, 137, 91, 50, 171, 67, 42, - 191, 128, 161, 154, 154, 107, 199, 194, 156, 33, 2, 143, 255, 67, 51, 24, 104, 133, 14, 32, 5, - 146, 19, 155, 160, 141, 85, 232, 35, 7, 21, 242, 138, 101, 227, 115, 172, 245, 197, 2, 96, 173, - 89, 196, 94, 161, 149, 172, 204, 213, 77, 241, 32, 7, 249, 80, 4, 89, 1, 199, 167, 27, 139, 62, - 219, 86, 89, 72, 123, 115, 154, 224, 30, 134, 235, 116, 44, 8, 144, 129, 32, 105, 174, 180, 51, - 32, 3, 109, 79, 177, 19, 59, 134, 178, 84, 88, 166, 192, 234, 24, 132, 50, 9, 52, 190, 175, - 103, 0, 114, 130, 129, 252, 85, 105, 80, 13, 215, 44, 32, 0, 65, 132, 220, 157, 57, 141, 161, - 237, 95, 246, 72, 187, 213, 187, 214, 26, 96, 82, 179, 52, 229, 229, 37, 214, 245, 159, 218, - 49, 194, 193, 152, 32, 3, 183, 108, 42, 159, 80, 215, 118, 17, 80, 122, 97, 61, 97, 29, 254, - 39, 135, 228, 135, 94, 107, 106, 221, 63, 255, 38, 138, 6, 196, 241, 139, 32, 4, 138, 187, 53, - 147, 230, 88, 117, 192, 126, 19, 155, 155, 156, 127, 50, 196, 43, 177, 64, 239, 117, 169, 171, - 254, 53, 246, 1, 9, 12, 34, 196, 32, 4, 160, 6, 194, 185, 109, 38, 218, 213, 228, 88, 0, 31, - 246, 241, 176, 177, 119, 122, 108, 5, 184, 189, 59, 198, 144, 139, 221, 103, 10, 165, 2, 32, 2, - 111, 100, 250, 248, 222, 100, 64, 48, 166, 146, 122, 2, 8, 68, 252, 92, 143, 51, 116, 45, 110, - 98, 100, 44, 170, 181, 38, 109, 65, 195, 204, 32, 1, 20, 223, 54, 185, 95, 217, 122, 110, 8, - 220, 187, 76, 74, 65, 22, 142, 193, 220, 144, 118, 178, 193, 68, 147, 34, 251, 2, 23, 86, 59, - 84, 32, 4, 11, 211, 18, 40, 27, 51, 227, 51, 84, 194, 0, 1, 238, 114, 180, 172, 52, 106, 108, - 246, 211, 240, 67, 31, 136, 195, 86, 130, 203, 152, 13, 32, 3, 59, 216, 203, 252, 156, 121, 46, - 5, 129, 98, 56, 105, 47, 215, 70, 255, 253, 194, 22, 92, 185, 162, 24, 189, 240, 19, 167, 129, - 51, 118, 15, 32, 6, 218, 40, 8, 230, 94, 223, 24, 55, 176, 253, 83, 23, 76, 163, 40, 55, 166, - 131, 30, 122, 192, 213, 155, 114, 135, 8, 36, 157, 222, 29, 33, 32, 7, 158, 22, 33, 155, 10, - 170, 45, 59, 39, 103, 96, 105, 160, 76, 244, 221, 24, 125, 27, 163, 37, 121, 209, 200, 87, 71, - 74, 128, 187, 192, 77, 32, 1, 233, 235, 60, 224, 219, 201, 97, 98, 250, 177, 160, 110, 194, 21, - 88, 29, 170, 204, 12, 223, 187, 86, 195, 43, 127, 188, 63, 33, 176, 119, 155, 32, 7, 144, 93, - 56, 141, 120, 249, 210, 19, 205, 141, 91, 105, 178, 112, 63, 196, 79, 204, 39, 17, 230, 127, 8, - 93, 82, 101, 30, 208, 100, 221, 55, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 7, 255, 255, 255, 254, 239, 253, 240, 255, + 45, 214, 150, 78, 230, 134, 109, 250, 24, 78, 249, 49, 197, 186, 141, 6, 36, 32, 3, 11, 190, + 10, 245, 46, 197, 227, 241, 252, 227, 191, 255, 125, 8, 152, 30, 193, 129, 20, 117, 98, 43, + 205, 180, 85, 212, 192, 84, 108, 211, 147, 32, 6, 105, 154, 54, 32, 217, 251, 178, 189, 125, + 44, 74, 148, 158, 166, 35, 31, 32, 123, 202, 155, 237, 245, 244, 162, 130, 75, 66, 176, 19, 4, + 95, 32, 2, 53, 72, 92, 244, 10, 199, 85, 215, 98, 197, 202, 53, 55, 48, 73, 121, 142, 75, 201, + 211, 59, 249, 82, 99, 28, 177, 49, 24, 229, 179, 18, 32, 3, 147, 151, 167, 74, 59, 143, 23, + 251, 79, 191, 28, 36, 70, 115, 138, 125, 47, 234, 176, 10, 181, 87, 6, 92, 201, 241, 192, 251, + 131, 0, 88, 32, 4, 39, 97, 124, 163, 176, 81, 173, 238, 229, 62, 141, 71, 149, 157, 213, 58, + 29, 88, 81, 70, 210, 37, 247, 98, 32, 227, 122, 92, 107, 158, 25, 32, 1, 61, 39, 156, 131, 15, + 116, 96, 118, 150, 228, 16, 100, 173, 143, 116, 225, 32, 132, 100, 64, 218, 62, 42, 82, 24, + 237, 250, 224, 123, 138, 97, 32, 2, 146, 189, 233, 22, 145, 97, 183, 76, 47, 228, 86, 179, 24, + 44, 22, 187, 234, 165, 124, 212, 168, 28, 48, 170, 172, 113, 149, 59, 111, 126, 0, 32, 1, 73, + 94, 244, 139, 72, 176, 219, 166, 23, 242, 43, 89, 140, 22, 11, 93, 245, 82, 190, 106, 84, 14, + 24, 85, 86, 56, 202, 157, 183, 191, 0, 32, 7, 49, 84, 83, 237, 209, 73, 126, 221, 105, 98, 146, + 151, 69, 38, 138, 147, 197, 172, 158, 154, 130, 67, 143, 205, 176, 10, 185, 201, 66, 199, 20, + 32, 1, 75, 213, 109, 3, 8, 2, 241, 101, 42, 61, 134, 159, 48, 52, 142, 224, 44, 155, 89, 243, + 73, 37, 137, 11, 64, 126, 128, 131, 255, 70, 42, 32, 1, 104, 35, 95, 92, 228, 27, 175, 98, 140, + 205, 91, 31, 157, 252, 165, 220, 105, 251, 241, 140, 219, 12, 161, 65, 197, 62, 110, 124, 61, + 193, 122, 32, 1, 149, 72, 216, 225, 106, 116, 178, 76, 86, 77, 33, 43, 180, 163, 197, 44, 142, + 52, 198, 3, 206, 173, 228, 211, 204, 13, 227, 175, 28, 97, 231, 32, 2, 232, 98, 147, 59, 174, + 70, 149, 38, 167, 15, 131, 123, 149, 113, 85, 110, 221, 121, 170, 84, 232, 24, 79, 75, 130, 8, + 99, 192, 32, 16, 235, 32, 2, 115, 182, 7, 186, 57, 90, 222, 26, 175, 88, 28, 210, 226, 219, + 114, 205, 112, 174, 240, 165, 47, 13, 207, 147, 229, 120, 162, 31, 51, 215, 163, 32, 3, 198, + 127, 221, 133, 73, 158, 119, 151, 181, 21, 139, 83, 240, 137, 62, 75, 131, 90, 183, 183, 239, + 195, 107, 108, 247, 170, 165, 138, 0, 211, 101, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 6, 148, 216, 207, 2, 3, 139, 221, + 191, 137, 87, 81, 23, 179, 133, 145, 206, 30, 137, 32, 236, 3, 210, 246, 126, 171, 104, 57, + 139, 240, 51, 41, 32, 4, 36, 244, 60, 5, 202, 242, 129, 217, 68, 10, 21, 74, 144, 101, 2, 160, + 60, 17, 219, 171, 167, 13, 137, 161, 241, 186, 130, 225, 71, 234, 214, 32, 1, 120, 99, 212, 90, + 47, 150, 255, 235, 159, 211, 99, 64, 152, 122, 210, 217, 205, 190, 167, 6, 216, 51, 109, 66, + 132, 35, 200, 191, 124, 240, 108, 32, 0, 85, 76, 196, 128, 0, 235, 158, 110, 54, 224, 100, 184, + 2, 249, 168, 88, 22, 127, 135, 187, 9, 7, 183, 255, 194, 35, 136, 175, 95, 212, 5, 32, 6, 232, + 9, 192, 228, 11, 65, 179, 232, 87, 242, 201, 109, 203, 41, 107, 35, 226, 68, 234, 223, 245, 93, + 27, 222, 156, 178, 238, 17, 166, 94, 17, 32, 4, 211, 244, 238, 153, 155, 124, 251, 84, 27, 24, + 181, 30, 62, 39, 10, 205, 80, 36, 200, 169, 126, 135, 91, 34, 243, 59, 138, 71, 139, 81, 122, + 32, 4, 249, 127, 248, 99, 200, 239, 97, 58, 47, 101, 113, 234, 47, 153, 251, 99, 195, 238, 58, + 209, 62, 79, 82, 158, 246, 104, 189, 122, 227, 79, 141, 32, 4, 216, 135, 181, 159, 147, 233, + 118, 112, 189, 56, 66, 185, 24, 223, 247, 190, 251, 107, 14, 55, 253, 118, 20, 103, 13, 146, + 118, 84, 217, 114, 68, 32, 3, 55, 72, 118, 32, 193, 11, 90, 79, 171, 240, 210, 127, 212, 50, + 136, 202, 240, 242, 91, 53, 27, 176, 114, 48, 235, 25, 155, 191, 85, 215, 179, 32, 7, 60, 186, + 164, 44, 164, 3, 52, 158, 62, 202, 42, 164, 34, 156, 39, 97, 241, 242, 57, 98, 16, 0, 46, 234, + 50, 242, 103, 36, 5, 42, 220, 32, 3, 54, 237, 18, 222, 139, 112, 60, 46, 63, 108, 110, 174, 47, + 57, 160, 216, 32, 41, 246, 139, 129, 182, 57, 27, 28, 201, 29, 194, 2, 3, 166, 32, 1, 231, 166, + 140, 238, 19, 197, 108, 196, 234, 26, 189, 31, 111, 60, 13, 157, 180, 28, 203, 124, 18, 218, + 112, 151, 28, 237, 157, 142, 74, 234, 145, 32, 1, 222, 126, 43, 229, 237, 144, 32, 71, 228, + 134, 109, 56, 4, 9, 182, 82, 226, 22, 57, 57, 96, 237, 189, 201, 188, 250, 143, 228, 168, 242, + 134, 32, 3, 84, 196, 181, 38, 231, 130, 57, 41, 14, 217, 197, 28, 205, 198, 192, 14, 222, 219, + 165, 223, 64, 96, 139, 249, 108, 125, 122, 1, 206, 33, 168, 32, 4, 127, 37, 41, 40, 69, 83, + 115, 128, 57, 163, 238, 214, 120, 89, 132, 32, 75, 86, 205, 195, 101, 38, 142, 53, 46, 0, 96, + 56, 121, 245, 198, 32, 3, 131, 244, 217, 63, 35, 70, 189, 36, 185, 108, 151, 105, 132, 254, + 196, 196, 113, 57, 67, 7, 30, 248, 110, 177, 121, 138, 20, 4, 224, 60, 97, 32, 1, 53, 24, 227, + 221, 240, 49, 77, 110, 222, 152, 144, 32, 81, 121, 130, 16, 67, 138, 39, 2, 205, 235, 235, 21, + 253, 57, 139, 32, 242, 128, 248, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 7, 255, 255, 255, 254, 239, 253, 240, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 239, 255, 225, 36, 32, 4, 198, 99, 47, 102, 150, 146, 77, 205, 39, 228, 73, 208, 170, 131, - 91, 229, 149, 154, 108, 150, 155, 148, 154, 250, 98, 98, 240, 61, 154, 247, 24, 32, 4, 94, 5, - 186, 86, 10, 188, 71, 33, 154, 51, 118, 173, 32, 170, 225, 114, 150, 144, 214, 197, 235, 56, - 211, 75, 119, 174, 112, 233, 134, 174, 246, 32, 6, 214, 144, 50, 68, 104, 213, 16, 190, 137, - 200, 55, 159, 110, 39, 163, 41, 71, 7, 35, 94, 3, 92, 153, 218, 69, 52, 27, 30, 199, 213, 181, - 32, 0, 116, 127, 190, 3, 87, 233, 226, 70, 40, 211, 143, 245, 140, 24, 29, 26, 136, 122, 149, - 187, 102, 54, 132, 255, 0, 112, 16, 195, 254, 74, 70, 32, 3, 133, 116, 230, 181, 99, 254, 244, - 122, 42, 252, 158, 208, 173, 141, 214, 205, 60, 187, 213, 75, 112, 84, 154, 121, 184, 79, 230, - 137, 204, 151, 160, 32, 5, 110, 77, 198, 197, 214, 119, 53, 127, 26, 252, 4, 108, 154, 64, 215, - 160, 192, 232, 92, 43, 150, 104, 189, 48, 198, 58, 17, 232, 126, 121, 248, 32, 0, 96, 162, 110, - 38, 151, 101, 178, 95, 20, 2, 138, 205, 173, 58, 137, 128, 172, 7, 37, 18, 32, 29, 212, 234, - 147, 6, 25, 14, 62, 61, 42, 32, 0, 48, 81, 55, 19, 75, 178, 217, 47, 138, 1, 69, 102, 214, 157, - 68, 192, 86, 3, 146, 137, 16, 14, 234, 117, 73, 131, 12, 135, 31, 30, 149, 32, 0, 70, 215, 101, - 166, 112, 230, 215, 64, 31, 158, 62, 130, 47, 190, 212, 203, 151, 94, 13, 91, 191, 102, 229, - 251, 161, 134, 218, 86, 116, 251, 118, 32, 7, 148, 42, 133, 153, 156, 222, 114, 121, 161, 47, - 246, 4, 104, 253, 82, 143, 222, 175, 136, 17, 84, 9, 185, 73, 24, 157, 55, 77, 203, 206, 170, - 32, 6, 95, 234, 173, 56, 114, 7, 142, 82, 41, 132, 108, 170, 143, 82, 105, 193, 167, 44, 204, - 178, 1, 244, 42, 127, 140, 103, 23, 202, 169, 243, 42, 32, 2, 77, 249, 28, 214, 193, 240, 93, - 31, 25, 106, 39, 150, 196, 222, 90, 225, 108, 105, 128, 180, 141, 3, 101, 242, 62, 156, 7, 172, - 206, 229, 231, 32, 3, 46, 149, 238, 10, 122, 151, 202, 36, 91, 125, 53, 54, 22, 155, 163, 176, - 198, 51, 163, 149, 187, 117, 74, 51, 8, 165, 38, 14, 24, 245, 40, 32, 4, 239, 189, 161, 235, - 217, 214, 24, 228, 113, 16, 30, 82, 45, 123, 159, 104, 103, 91, 25, 207, 207, 250, 116, 228, - 250, 245, 176, 93, 7, 252, 107, 32, 2, 166, 141, 155, 18, 183, 248, 119, 26, 147, 37, 170, 247, - 219, 46, 2, 31, 160, 9, 208, 255, 31, 92, 171, 51, 122, 64, 44, 65, 105, 106, 97, 32, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 2, - 156, 46, 34, 115, 162, 75, 166, 181, 116, 156, 220, 60, 49, 126, 243, 206, 46, 132, 61, 180, - 42, 193, 57, 105, 171, 49, 92, 216, 164, 255, 63, 32, 2, 111, 35, 213, 86, 255, 227, 39, 70, - 26, 138, 73, 140, 112, 19, 17, 180, 33, 56, 2, 82, 70, 96, 99, 52, 178, 58, 41, 184, 87, 179, - 113, 32, 3, 147, 237, 53, 138, 141, 166, 16, 37, 177, 164, 176, 191, 57, 129, 184, 47, 249, - 237, 203, 85, 179, 192, 68, 69, 59, 199, 14, 83, 181, 238, 61, 32, 1, 118, 29, 91, 8, 184, 237, - 60, 139, 126, 142, 141, 59, 114, 71, 146, 78, 93, 78, 242, 123, 222, 219, 252, 43, 225, 140, - 28, 230, 172, 188, 58, 32, 1, 84, 130, 32, 213, 78, 79, 117, 206, 162, 1, 8, 224, 147, 200, - 238, 60, 27, 30, 226, 8, 3, 71, 210, 50, 243, 97, 91, 91, 212, 126, 174, 32, 0, 224, 32, 20, - 176, 200, 99, 47, 72, 141, 39, 151, 121, 176, 140, 240, 31, 227, 173, 200, 71, 167, 168, 90, - 97, 117, 3, 120, 21, 185, 211, 224, 32, 1, 37, 68, 6, 241, 202, 81, 117, 47, 144, 18, 225, 165, - 193, 17, 181, 203, 96, 21, 248, 79, 44, 199, 18, 158, 228, 197, 98, 156, 192, 94, 80, 32, 5, - 185, 214, 73, 108, 240, 134, 9, 148, 89, 43, 205, 61, 124, 125, 98, 76, 85, 5, 182, 185, 175, - 212, 9, 48, 201, 89, 45, 183, 104, 130, 89, 32, 4, 230, 12, 106, 169, 13, 106, 222, 118, 104, - 250, 215, 212, 230, 34, 131, 8, 142, 71, 207, 35, 197, 114, 84, 3, 18, 90, 18, 92, 190, 198, - 231, 32, 6, 129, 116, 116, 248, 215, 104, 164, 63, 123, 158, 128, 206, 108, 34, 113, 238, 69, - 104, 59, 68, 244, 166, 220, 58, 209, 172, 56, 49, 246, 59, 251, 32, 5, 86, 230, 229, 219, 163, - 126, 239, 151, 183, 79, 219, 168, 206, 75, 82, 196, 130, 131, 63, 170, 158, 100, 118, 233, 237, - 114, 173, 176, 238, 108, 217, 32, 7, 244, 155, 40, 219, 168, 42, 187, 215, 244, 185, 179, 251, - 71, 122, 223, 29, 143, 140, 84, 83, 0, 21, 74, 227, 57, 248, 25, 153, 112, 255, 181, 32, 7, - 207, 113, 72, 180, 24, 231, 110, 224, 195, 157, 3, 64, 86, 79, 206, 101, 110, 184, 221, 7, 149, - 11, 254, 197, 182, 100, 80, 245, 58, 63, 147, 32, 5, 221, 109, 132, 218, 56, 223, 127, 0, 226, - 252, 251, 156, 5, 76, 45, 87, 250, 6, 120, 225, 77, 119, 106, 247, 192, 187, 108, 242, 39, 4, - 167, 32, 5, 115, 229, 56, 54, 6, 240, 24, 242, 136, 101, 92, 116, 84, 44, 239, 43, 133, 203, - 167, 3, 81, 139, 9, 192, 77, 237, 242, 251, 5, 68, 235, 32, 4, 114, 254, 69, 61, 206, 97, 32, - 57, 35, 33, 228, 65, 18, 161, 248, 118, 151, 197, 161, 100, 84, 220, 9, 162, 222, 214, 19, 5, - 249, 5, 5, 32, 6, 72, 194, 21, 30, 130, 163, 152, 41, 83, 40, 242, 19, 88, 251, 153, 240, 87, - 52, 164, 156, 51, 138, 64, 89, 145, 227, 141, 228, 120, 119, 186, 32, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 7, 255, 255, - 255, 254, 239, 253, 240, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 239, 255, 225, 1, 8, 198, 23, 84, 255, 151, 170, 24, 10, - 205, 81, 45, 252, 78, 227, 104, 43, 34, 71, 48, 21, 221, 59, 83, 55, 230, 173, 205, 23, 165, - 63, 164, 81, 214, 5, 201, 144, 116, 141, 237, 183, 99, 166, 133, 98, 237, 150, 237, 117, 64, - 62, 158, 103, 219, 38, 180, 159, 216, 51, 118, 132, 190, 36, 174, 82, 184, 132, 162, 205, 221, - 202, 214, 145, 217, 167, 46, 204, 125, 71, 164, 57, 104, 83, 60, 227, 147, 221, 50, 19, 127, - 168, 46, 215, 74, 229, 109, 113, 208, 168, 36, 249, 140, 75, 236, 88, 39, 14, 52, 42, 174, 36, - 186, 134, 137, 48, 43, 33, 53, 149, 217, 125, 46, 95, 174, 91, 171, 36, 50, 83, 66, 229, 202, - 144, 161, 214, 44, 14, 190, 143, 160, 9, 57, 35, 119, 113, 194, 148, 35, 100, 168, 241, 151, - 40, 203, 46, 56, 120, 109, 133, 0, 249, 165, 107, 85, 164, 80, 243, 242, 36, 235, 226, 199, - 191, 219, 14, 217, 84, 59, 78, 176, 165, 80, 100, 218, 54, 140, 125, 197, 249, 99, 247, 17, 71, - 160, 180, 121, 49, 249, 172, 16, 189, 110, 38, 119, 42, 116, 95, 138, 195, 26, 201, 251, 87, - 172, 17, 108, 168, 101, 136, 252, 118, 147, 242, 33, 11, 16, 200, 158, 124, 254, 165, 5, 73, - 12, 53, 221, 137, 122, 171, 78, 203, 75, 123, 4, 181, 50, 42, 37, 32, 13, 234, 176, 114, 190, - 190, 94, 157, 8, 170, 178, 81, 208, 81, 111, 31, 28, 126, 253, 70, 188, 190, 185, 39, 217, 50, - 111, 70, 67, 107, 101, 179, 74, 138, 102, 107, 71, 148, 178, 73, 169, 214, 5, 201, 144, 116, - 141, 237, 183, 99, 166, 133, 98, 237, 150, 237, 117, 64, 62, 158, 103, 219, 38, 180, 159, 216, - 51, 118, 132, 190, 36, 174, 82, 184, 132, 162, 205, 221, 202, 214, 145, 217, 167, 46, 204, 125, - 71, 164, 57, 104, 83, 60, 227, 147, 221, 50, 19, 127, 168, 46, 215, 74, 229, 109, 113, 208, - 168, 36, 249, 140, 75, 236, 88, 39, 14, 52, 42, 174, 36, 186, 134, 137, 48, 43, 33, 53, 149, - 217, 125, 46, 95, 174, 91, 171, 36, 50, 83, 66, 229, 202, 144, 161, 214, 44, 14, 190, 143, 160, - 9, 57, 35, 119, 113, 194, 148, 35, 100, 168, 241, 151, 40, 203, 46, 56, 120, 109, 133, 0, 249, + 255, 239, 255, 225, 36, 32, 1, 95, 221, 207, 191, 219, 55, 97, 99, 251, 192, 205, 3, 114, 74, + 92, 4, 36, 106, 253, 169, 75, 241, 254, 245, 24, 64, 21, 99, 212, 158, 109, 32, 0, 168, 155, + 93, 165, 62, 251, 124, 91, 82, 159, 226, 74, 255, 187, 119, 61, 168, 110, 222, 26, 135, 252, + 101, 233, 211, 126, 44, 147, 141, 111, 220, 32, 5, 244, 149, 55, 66, 246, 81, 145, 22, 178, + 191, 85, 183, 29, 228, 251, 146, 44, 196, 156, 226, 189, 245, 232, 111, 128, 226, 94, 134, 161, + 94, 215, 32, 0, 124, 211, 136, 212, 237, 132, 89, 190, 157, 73, 240, 3, 81, 253, 127, 143, 159, + 153, 111, 44, 228, 127, 176, 196, 153, 73, 204, 148, 222, 43, 243, 32, 2, 41, 134, 84, 204, 74, + 209, 68, 173, 234, 92, 215, 26, 246, 3, 176, 88, 94, 125, 120, 106, 171, 106, 25, 227, 153, + 146, 168, 108, 130, 87, 102, 32, 1, 167, 29, 172, 208, 222, 255, 9, 85, 21, 140, 71, 76, 106, + 241, 229, 213, 23, 86, 218, 165, 151, 6, 14, 227, 167, 2, 244, 194, 160, 109, 207, 32, 4, 255, + 123, 163, 6, 56, 129, 72, 164, 9, 96, 223, 95, 8, 21, 6, 147, 165, 46, 5, 220, 82, 218, 95, 65, + 51, 106, 29, 31, 60, 158, 170, 32, 2, 127, 189, 209, 131, 28, 64, 164, 82, 4, 176, 111, 175, + 132, 10, 131, 73, 210, 151, 2, 238, 41, 109, 47, 160, 153, 181, 14, 143, 158, 79, 85, 32, 0, + 180, 83, 227, 153, 248, 117, 67, 240, 124, 101, 20, 41, 99, 46, 170, 12, 1, 89, 22, 76, 105, + 220, 131, 35, 133, 36, 67, 140, 78, 156, 196, 32, 7, 103, 245, 221, 83, 165, 245, 206, 121, + 240, 5, 30, 33, 100, 156, 91, 148, 19, 184, 179, 147, 241, 121, 17, 38, 224, 246, 100, 155, + 166, 20, 195, 32, 5, 78, 64, 59, 220, 248, 56, 206, 236, 165, 189, 155, 85, 14, 110, 172, 58, + 48, 178, 228, 63, 118, 241, 158, 35, 122, 56, 31, 125, 113, 108, 125, 32, 4, 226, 254, 215, + 177, 61, 91, 140, 61, 196, 148, 104, 63, 127, 119, 114, 0, 4, 21, 91, 215, 147, 158, 175, 142, + 12, 235, 253, 25, 228, 146, 119, 32, 0, 49, 226, 144, 38, 216, 177, 200, 182, 133, 44, 17, 153, + 251, 225, 40, 140, 62, 69, 147, 216, 223, 181, 69, 77, 206, 246, 108, 141, 251, 71, 52, 32, 2, + 120, 169, 191, 163, 21, 134, 50, 114, 57, 38, 164, 59, 95, 233, 84, 82, 198, 149, 156, 22, 245, + 226, 237, 44, 80, 87, 238, 10, 34, 252, 194, 32, 4, 176, 201, 218, 169, 245, 24, 19, 128, 150, + 160, 46, 111, 81, 30, 18, 144, 123, 88, 98, 224, 208, 23, 97, 233, 96, 117, 179, 73, 144, 243, + 123, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 32, 6, 173, 49, 21, 158, 122, 84, 204, 189, 120, 170, 50, 50, 9, 148, 55, 132, 167, + 68, 143, 159, 255, 247, 71, 172, 115, 243, 3, 155, 196, 167, 138, 32, 4, 217, 76, 180, 139, + 176, 217, 11, 243, 207, 252, 154, 192, 137, 41, 111, 57, 90, 135, 71, 231, 114, 174, 44, 36, + 171, 238, 221, 46, 44, 4, 212, 32, 3, 104, 235, 170, 158, 191, 37, 78, 41, 40, 108, 103, 133, + 159, 242, 130, 224, 242, 191, 52, 213, 37, 102, 143, 126, 151, 189, 193, 84, 210, 197, 175, 32, + 3, 89, 248, 104, 149, 197, 48, 181, 235, 34, 205, 235, 12, 240, 143, 145, 205, 250, 4, 236, 30, + 10, 92, 101, 252, 193, 159, 143, 180, 230, 6, 225, 32, 5, 136, 251, 4, 187, 109, 185, 93, 122, + 224, 220, 126, 200, 40, 109, 217, 39, 36, 21, 190, 240, 232, 250, 196, 91, 188, 89, 172, 80, + 121, 251, 197, 32, 1, 111, 83, 106, 97, 202, 254, 209, 6, 173, 240, 252, 164, 82, 7, 224, 97, + 43, 170, 100, 11, 116, 202, 231, 251, 250, 128, 242, 226, 82, 136, 48, 32, 4, 153, 150, 239, + 193, 196, 177, 132, 172, 200, 165, 223, 53, 24, 235, 76, 250, 245, 197, 80, 180, 170, 139, 2, + 254, 136, 131, 70, 46, 37, 49, 231, 32, 0, 86, 74, 64, 98, 112, 228, 198, 26, 65, 236, 91, 39, + 36, 6, 154, 69, 20, 124, 58, 213, 99, 176, 37, 229, 246, 236, 43, 208, 15, 23, 156, 32, 4, 103, + 120, 243, 154, 150, 52, 17, 243, 253, 106, 159, 106, 191, 121, 159, 177, 200, 92, 26, 253, 67, + 248, 230, 35, 16, 176, 38, 229, 139, 47, 217, 32, 6, 222, 171, 49, 136, 19, 201, 120, 131, 213, + 222, 1, 253, 81, 182, 155, 115, 141, 254, 169, 37, 142, 182, 74, 161, 16, 21, 243, 201, 239, + 166, 237, 32, 3, 194, 35, 118, 25, 203, 239, 88, 140, 107, 15, 136, 189, 11, 41, 196, 36, 17, + 147, 104, 53, 45, 41, 248, 175, 68, 242, 183, 160, 235, 76, 182, 32, 5, 17, 199, 242, 192, 147, + 65, 0, 240, 120, 32, 247, 227, 118, 152, 107, 93, 4, 25, 227, 81, 107, 67, 188, 206, 52, 204, + 225, 191, 11, 196, 128, 32, 6, 186, 164, 209, 236, 178, 225, 233, 6, 195, 82, 146, 237, 249, + 168, 60, 158, 33, 10, 76, 196, 40, 127, 22, 31, 165, 117, 101, 239, 29, 7, 76, 32, 1, 226, 126, + 209, 63, 20, 29, 90, 89, 251, 20, 179, 140, 218, 217, 69, 48, 115, 38, 193, 235, 196, 169, 22, + 196, 204, 232, 239, 3, 239, 92, 41, 32, 0, 5, 15, 121, 103, 3, 117, 142, 239, 173, 234, 237, + 79, 27, 214, 108, 5, 207, 244, 232, 195, 236, 211, 88, 66, 32, 141, 141, 132, 196, 193, 86, 32, + 7, 158, 68, 239, 145, 204, 224, 145, 205, 170, 63, 191, 196, 153, 22, 160, 11, 146, 44, 74, + 225, 60, 110, 38, 49, 152, 149, 191, 244, 145, 10, 194, 32, 5, 173, 0, 28, 169, 187, 187, 96, + 93, 152, 117, 4, 157, 177, 36, 34, 201, 16, 52, 49, 208, 136, 121, 107, 138, 228, 95, 165, 135, + 26, 69, 47, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 32, 7, 255, 255, 255, 254, 239, 253, 240, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 239, 255, 225, 1, 8, + 122, 107, 46, 123, 111, 34, 21, 230, 57, 88, 106, 172, 247, 89, 5, 135, 225, 209, 37, 8, 43, + 63, 196, 70, 132, 198, 92, 63, 41, 32, 3, 37, 79, 82, 161, 150, 171, 6, 235, 166, 230, 28, 75, + 255, 199, 173, 5, 64, 127, 243, 17, 216, 246, 121, 201, 242, 72, 71, 190, 113, 0, 94, 74, 254, + 1, 190, 5, 61, 96, 250, 121, 19, 39, 152, 157, 244, 3, 124, 85, 63, 93, 4, 173, 148, 68, 213, + 168, 183, 190, 219, 147, 115, 143, 161, 69, 180, 197, 73, 177, 234, 208, 27, 60, 41, 216, 97, + 7, 238, 84, 243, 112, 223, 124, 198, 87, 62, 100, 1, 182, 121, 114, 68, 57, 96, 130, 251, 242, + 178, 56, 157, 104, 149, 253, 46, 114, 210, 221, 95, 187, 154, 66, 26, 149, 116, 247, 66, 212, + 37, 90, 22, 88, 55, 4, 71, 127, 215, 53, 53, 16, 36, 165, 107, 85, 164, 80, 243, 242, 36, 235, + 226, 199, 191, 219, 14, 217, 84, 59, 78, 176, 165, 80, 100, 218, 54, 140, 125, 197, 249, 99, + 247, 17, 71, 160, 180, 121, 49, 249, 172, 16, 189, 110, 38, 119, 42, 116, 95, 138, 195, 26, + 201, 251, 87, 172, 17, 108, 168, 101, 136, 252, 118, 147, 242, 33, 11, 16, 200, 158, 124, 254, + 165, 5, 73, 12, 53, 221, 137, 122, 171, 78, 203, 75, 123, 4, 181, 50, 42, 37, 32, 13, 234, 176, + 114, 190, 190, 94, 157, 8, 119, 121, 78, 36, 5, 32, 246, 204, 151, 153, 10, 5, 249, 73, 32, + 144, 122, 132, 32, 190, 22, 176, 120, 255, 129, 202, 116, 185, 1, 55, 125, 178, 79, 82, 161, + 150, 171, 6, 235, 166, 230, 28, 75, 255, 199, 173, 5, 64, 127, 243, 17, 216, 246, 121, 201, + 242, 72, 71, 190, 113, 0, 94, 74, 254, 1, 190, 5, 61, 96, 250, 121, 19, 39, 152, 157, 244, 3, + 124, 85, 63, 93, 4, 173, 148, 68, 213, 168, 183, 190, 219, 147, 115, 143, 161, 69, 180, 197, + 73, 177, 234, 208, 27, 60, 41, 216, 97, 7, 238, 84, 243, 112, 223, 124, 198, 87, 62, 100, 1, + 182, 121, 114, 68, 57, 96, 130, 251, 242, 178, 56, 157, 104, 149, 253, 46, 114, 210, 221, 95, + 187, 154, 66, 26, 149, 116, 247, 66, 212, 37, 90, 22, 88, 55, 4, 71, 127, 215, 53, 53, 16, 36, 165, 107, 85, 164, 80, 243, 242, 36, 235, 226, 199, 191, 219, 14, 217, 84, 59, 78, 176, 165, 80, 100, 218, 54, 140, 125, 197, 249, 99, 247, 17, 71, 160, 180, 121, 49, 249, 172, 16, 189, 110, 38, 119, 42, 116, 95, 138, 195, 26, 201, 251, 87, 172, 17, 108, 168, 101, 136, 252, 118, 147, 242, 33, 11, 16, 200, 158, 124, 254, 165, 5, 73, 12, 53, 221, 137, 122, 171, 78, 203, 75, - 123, 4, 181, 50, 42, 37, 32, 13, 234, 176, 114, 190, 190, 94, 157, 23, 32, 1, 226, 90, 177, 34, - 62, 201, 180, 249, 9, 215, 203, 139, 66, 88, 169, 207, 196, 116, 47, 36, 127, 53, 131, 194, 0, - 71, 133, 68, 125, 203, 156, 32, 5, 84, 147, 243, 72, 44, 231, 137, 95, 82, 224, 204, 154, 206, - 188, 12, 47, 68, 76, 47, 63, 17, 175, 206, 61, 111, 0, 64, 60, 146, 23, 95, 32, 5, 84, 147, - 243, 72, 44, 231, 137, 95, 82, 224, 204, 154, 206, 188, 12, 47, 68, 76, 47, 63, 17, 175, 206, - 61, 111, 0, 64, 60, 146, 23, 95, 32, 5, 84, 147, 243, 72, 44, 231, 137, 95, 82, 224, 204, 154, - 206, 188, 12, 47, 68, 76, 47, 63, 17, 175, 206, 61, 111, 0, 64, 60, 146, 23, 95, 32, 3, 90, - 112, 38, 248, 174, 225, 80, 47, 99, 208, 220, 166, 201, 154, 71, 62, 141, 42, 104, 172, 207, - 250, 140, 201, 249, 74, 88, 26, 166, 127, 212, 32, 5, 134, 245, 233, 202, 185, 178, 113, 74, - 59, 208, 205, 65, 8, 236, 118, 243, 40, 83, 202, 162, 159, 83, 0, 191, 255, 58, 82, 220, 255, - 23, 29, 32, 6, 227, 171, 139, 219, 139, 164, 90, 41, 98, 199, 188, 177, 9, 186, 202, 145, 64, - 5, 126, 143, 190, 146, 169, 7, 143, 169, 218, 35, 68, 235, 128, 32, 0, 130, 168, 205, 202, 184, - 230, 169, 214, 27, 165, 47, 104, 18, 54, 173, 167, 144, 26, 11, 42, 182, 168, 131, 255, 193, - 120, 81, 92, 85, 21, 9, 32, 0, 198, 81, 52, 192, 76, 178, 36, 188, 172, 159, 24, 73, 243, 74, - 123, 37, 10, 41, 255, 32, 109, 116, 92, 255, 49, 76, 67, 28, 250, 217, 188, 32, 1, 236, 236, - 188, 57, 240, 250, 49, 136, 157, 51, 197, 131, 190, 82, 109, 93, 176, 233, 189, 132, 124, 15, - 150, 83, 200, 212, 101, 116, 234, 125, 71, 32, 2, 65, 199, 238, 237, 253, 238, 0, 191, 87, 58, - 174, 152, 1, 151, 187, 90, 87, 125, 195, 41, 103, 49, 189, 18, 125, 62, 190, 24, 62, 181, 83, - 32, 4, 198, 36, 193, 246, 195, 182, 251, 63, 57, 13, 176, 164, 25, 122, 253, 188, 150, 158, - 106, 136, 241, 239, 75, 249, 173, 62, 56, 58, 118, 253, 98, 32, 7, 152, 239, 4, 75, 94, 140, - 52, 205, 198, 243, 9, 254, 146, 160, 50, 36, 61, 193, 169, 85, 180, 218, 212, 66, 18, 232, 128, - 75, 217, 49, 104, 32, 4, 150, 204, 12, 168, 216, 22, 200, 19, 209, 117, 116, 14, 1, 6, 73, 199, - 148, 170, 40, 201, 65, 239, 108, 97, 54, 161, 208, 73, 96, 40, 77, 32, 0, 89, 1, 107, 47, 187, - 250, 147, 133, 134, 49, 97, 130, 198, 199, 203, 218, 83, 147, 96, 23, 159, 218, 246, 198, 194, - 81, 13, 28, 75, 53, 47, 32, 1, 28, 219, 187, 19, 102, 9, 144, 68, 190, 184, 76, 169, 190, 127, - 131, 71, 71, 99, 157, 255, 174, 167, 193, 86, 169, 29, 171, 160, 168, 87, 20, 32, 4, 220, 160, - 34, 62, 11, 188, 248, 175, 118, 70, 24, 125, 79, 86, 37, 114, 155, 49, 100, 78, 8, 48, 75, 159, - 236, 21, 197, 193, 244, 118, 250, 32, 3, 55, 131, 240, 131, 7, 226, 70, 14, 219, 44, 30, 186, - 18, 176, 152, 179, 224, 211, 175, 71, 201, 115, 172, 16, 8, 196, 103, 206, 249, 150, 82, 32, 1, - 77, 168, 185, 25, 164, 38, 14, 193, 137, 113, 154, 54, 217, 60, 156, 38, 138, 122, 105, 254, - 17, 102, 164, 221, 43, 37, 170, 221, 72, 232, 151, 32, 3, 37, 118, 187, 49, 235, 31, 41, 121, - 145, 157, 107, 21, 174, 81, 106, 253, 208, 11, 111, 44, 169, 123, 199, 86, 247, 34, 146, 159, - 78, 78, 134, 32, 6, 25, 172, 62, 68, 76, 1, 151, 154, 104, 86, 6, 130, 165, 106, 33, 176, 185, - 58, 216, 16, 206, 236, 152, 171, 90, 91, 42, 229, 248, 62, 237, 32, 4, 6, 28, 244, 157, 110, - 212, 16, 249, 146, 113, 14, 89, 246, 188, 124, 152, 104, 62, 116, 143, 17, 229, 77, 42, 21, 54, - 36, 127, 143, 46, 180, 32, 6, 213, 30, 201, 15, 161, 166, 224, 201, 122, 48, 53, 149, 96, 216, - 206, 129, 31, 134, 225, 26, 111, 0, 127, 54, 100, 16, 33, 24, 239, 169, 118, 23, 32, 6, 5, 152, - 2, 28, 99, 252, 217, 4, 193, 210, 48, 97, 240, 47, 63, 19, 117, 140, 245, 109, 151, 204, 220, - 129, 39, 253, 49, 242, 168, 120, 151, 32, 5, 174, 60, 34, 214, 147, 223, 113, 120, 155, 177, - 195, 231, 225, 156, 129, 231, 208, 52, 152, 129, 190, 176, 115, 224, 38, 54, 197, 65, 184, 142, - 232, 32, 5, 174, 60, 34, 214, 147, 223, 113, 120, 155, 177, 195, 231, 225, 156, 129, 231, 208, - 52, 152, 129, 190, 176, 115, 224, 38, 54, 197, 65, 184, 142, 232, 32, 5, 174, 60, 34, 214, 147, - 223, 113, 120, 155, 177, 195, 231, 225, 156, 129, 231, 208, 52, 152, 129, 190, 176, 115, 224, - 38, 54, 197, 65, 184, 142, 232, 32, 7, 121, 221, 240, 129, 105, 88, 243, 253, 201, 60, 90, 139, - 168, 81, 179, 130, 76, 9, 95, 160, 104, 0, 244, 217, 146, 66, 101, 158, 81, 168, 54, 32, 3, - 213, 73, 227, 177, 207, 252, 173, 28, 118, 100, 147, 55, 66, 251, 107, 88, 24, 5, 238, 106, 72, - 82, 218, 80, 172, 99, 216, 235, 159, 151, 50, 32, 7, 166, 82, 123, 107, 43, 164, 75, 210, 180, - 109, 36, 0, 35, 152, 37, 8, 141, 249, 252, 44, 138, 67, 152, 2, 224, 75, 38, 106, 110, 253, - 236, 32, 4, 41, 74, 94, 251, 100, 113, 67, 170, 6, 100, 54, 157, 118, 217, 101, 75, 145, 69, - 14, 165, 142, 150, 236, 107, 5, 130, 59, 182, 189, 116, 1, 32, 7, 53, 87, 13, 68, 248, 17, 250, - 175, 182, 241, 183, 220, 59, 172, 179, 118, 165, 111, 58, 136, 7, 230, 99, 169, 178, 182, 245, - 120, 169, 158, 50, 32, 2, 86, 206, 226, 81, 43, 2, 142, 153, 222, 85, 106, 197, 123, 159, 24, - 79, 55, 128, 92, 124, 80, 81, 214, 171, 62, 227, 253, 77, 143, 102, 42, 32, 0, 71, 65, 188, - 141, 114, 57, 192, 29, 15, 199, 3, 116, 181, 84, 185, 134, 76, 5, 81, 13, 253, 171, 180, 121, - 221, 223, 175, 88, 166, 11, 196, 32, 6, 57, 225, 140, 207, 235, 77, 232, 93, 0, 172, 133, 213, - 23, 104, 96, 146, 118, 242, 175, 33, 244, 78, 83, 99, 173, 165, 213, 204, 30, 253, 95, 32, 4, - 83, 171, 84, 96, 90, 141, 133, 240, 109, 239, 84, 166, 217, 236, 205, 142, 191, 73, 197, 45, - 188, 207, 222, 60, 225, 187, 184, 238, 102, 84, 103, 32, 0, 248, 88, 98, 94, 207, 141, 75, 237, - 61, 234, 162, 40, 176, 186, 22, 52, 93, 138, 100, 151, 157, 182, 64, 247, 146, 176, 157, 203, - 35, 208, 185, 32, 6, 178, 43, 190, 231, 177, 156, 59, 89, 32, 7, 140, 237, 213, 218, 119, 18, - 186, 119, 179, 205, 10, 76, 209, 60, 72, 173, 79, 129, 116, 34, 212, 32, 7, 232, 242, 81, 73, - 173, 219, 223, 87, 6, 238, 88, 194, 11, 217, 198, 236, 17, 49, 50, 99, 140, 203, 66, 62, 38, - 52, 62, 34, 39, 73, 208, 32, 7, 164, 100, 246, 243, 192, 242, 11, 3, 187, 235, 185, 48, 141, - 142, 105, 234, 220, 67, 207, 112, 68, 78, 196, 178, 224, 209, 7, 183, 12, 184, 178, 32, 7, 134, - 217, 46, 19, 216, 242, 5, 148, 52, 225, 134, 144, 179, 143, 210, 3, 36, 53, 103, 68, 180, 1, - 170, 39, 27, 89, 253, 40, 180, 186, 55, 32, 2, 51, 50, 203, 226, 167, 22, 7, 220, 184, 62, 60, - 166, 91, 148, 101, 64, 96, 252, 158, 211, 27, 103, 227, 108, 209, 86, 179, 120, 142, 108, 125, - 32, 0, 214, 90, 141, 11, 83, 126, 234, 160, 200, 182, 133, 217, 156, 187, 122, 199, 33, 63, - 147, 194, 184, 189, 155, 189, 176, 50, 183, 77, 239, 118, 65, 32, 2, 220, 62, 108, 245, 46, - 101, 64, 164, 180, 143, 208, 135, 122, 178, 73, 13, 227, 145, 18, 129, 86, 111, 249, 131, 202, - 162, 107, 222, 148, 145, 90, 32, 0, 220, 193, 44, 213, 8, 251, 223, 112, 251, 65, 71, 90, 159, - 20, 177, 98, 21, 184, 150, 66, 54, 11, 248, 231, 48, 118, 114, 29, 66, 143, 26, 32, 4, 89, 205, - 230, 246, 77, 248, 106, 59, 250, 124, 66, 250, 146, 104, 183, 83, 64, 79, 182, 76, 27, 7, 149, - 119, 76, 145, 118, 129, 21, 32, 98, 1, 1, 32, 7, 255, 255, 255, 255, 255, 253, 240, 255, 255, + 123, 4, 181, 50, 42, 37, 32, 13, 234, 176, 114, 190, 190, 94, 157, 23, 32, 2, 185, 190, 201, + 81, 118, 127, 96, 227, 30, 92, 42, 34, 163, 3, 82, 215, 27, 61, 147, 164, 148, 214, 45, 15, 93, + 249, 51, 219, 250, 115, 162, 32, 7, 41, 187, 255, 90, 251, 72, 136, 90, 235, 48, 9, 216, 9, 78, + 76, 17, 47, 221, 89, 51, 162, 235, 172, 239, 223, 131, 112, 12, 195, 222, 159, 32, 7, 41, 187, + 255, 90, 251, 72, 136, 90, 235, 48, 9, 216, 9, 78, 76, 17, 47, 221, 89, 51, 162, 235, 172, 239, + 223, 131, 112, 12, 195, 222, 159, 32, 7, 41, 187, 255, 90, 251, 72, 136, 90, 235, 48, 9, 216, + 9, 78, 76, 17, 47, 221, 89, 51, 162, 235, 172, 239, 223, 131, 112, 12, 195, 222, 159, 32, 4, + 25, 60, 113, 191, 207, 181, 53, 117, 122, 157, 0, 52, 14, 179, 224, 96, 126, 206, 249, 137, + 120, 223, 79, 77, 70, 102, 148, 246, 30, 58, 59, 32, 0, 13, 140, 11, 79, 101, 213, 145, 52, + 151, 147, 74, 78, 103, 93, 96, 173, 180, 60, 14, 117, 196, 252, 7, 85, 187, 0, 72, 233, 241, + 227, 226, 32, 5, 73, 104, 77, 54, 58, 127, 149, 22, 14, 148, 198, 175, 42, 217, 184, 24, 217, + 191, 17, 201, 39, 5, 212, 245, 108, 51, 110, 191, 153, 243, 73, 32, 2, 19, 137, 96, 155, 213, + 247, 87, 65, 5, 174, 150, 54, 6, 243, 229, 50, 214, 13, 128, 243, 254, 241, 107, 94, 56, 172, + 117, 35, 224, 76, 237, 32, 7, 165, 244, 153, 74, 91, 203, 107, 64, 211, 140, 180, 235, 183, 23, + 25, 98, 144, 119, 65, 0, 11, 136, 213, 221, 77, 186, 231, 81, 54, 204, 250, 32, 4, 234, 254, + 109, 135, 47, 223, 117, 85, 66, 213, 205, 86, 115, 126, 131, 201, 76, 195, 96, 235, 238, 108, + 170, 120, 240, 43, 149, 170, 111, 0, 202, 32, 3, 108, 248, 59, 224, 216, 59, 170, 178, 81, 36, + 101, 253, 115, 81, 14, 17, 134, 248, 147, 250, 14, 134, 171, 69, 10, 197, 67, 112, 96, 26, 248, + 32, 6, 11, 203, 39, 1, 5, 246, 221, 26, 247, 230, 248, 242, 187, 79, 151, 83, 135, 41, 139, 29, + 158, 127, 26, 249, 133, 73, 37, 39, 95, 41, 201, 32, 0, 245, 100, 132, 184, 51, 39, 115, 169, + 27, 16, 178, 240, 215, 220, 85, 146, 222, 3, 48, 155, 249, 104, 95, 142, 12, 146, 91, 23, 143, + 224, 32, 32, 5, 136, 91, 212, 33, 174, 9, 235, 179, 25, 47, 15, 159, 1, 199, 174, 64, 153, 78, + 210, 20, 183, 139, 87, 134, 132, 0, 77, 92, 31, 145, 68, 32, 4, 79, 182, 21, 112, 215, 33, 13, + 211, 20, 53, 56, 100, 79, 14, 49, 52, 108, 154, 163, 96, 203, 186, 242, 206, 132, 194, 83, 204, + 125, 206, 119, 32, 2, 47, 144, 43, 30, 233, 166, 165, 0, 216, 53, 137, 49, 126, 40, 117, 130, + 187, 14, 197, 190, 84, 5, 54, 119, 243, 71, 96, 254, 84, 174, 78, 32, 5, 172, 2, 122, 225, 228, + 225, 136, 13, 98, 203, 118, 42, 130, 102, 124, 29, 193, 182, 209, 61, 122, 87, 168, 75, 146, + 115, 225, 201, 185, 209, 185, 32, 2, 29, 234, 213, 87, 181, 6, 132, 210, 24, 41, 25, 13, 46, + 248, 241, 45, 101, 13, 194, 102, 214, 0, 251, 58, 130, 37, 67, 216, 247, 28, 192, 32, 4, 85, + 26, 129, 216, 192, 23, 218, 104, 224, 233, 37, 158, 65, 139, 21, 169, 239, 82, 54, 103, 184, + 61, 123, 239, 22, 53, 51, 25, 203, 56, 10, 32, 1, 197, 88, 69, 30, 42, 29, 232, 20, 113, 239, + 94, 203, 74, 129, 148, 18, 136, 8, 228, 174, 19, 89, 19, 99, 143, 33, 65, 121, 209, 186, 64, + 32, 1, 40, 249, 95, 107, 238, 241, 61, 121, 0, 251, 76, 248, 241, 141, 199, 14, 252, 192, 174, + 99, 252, 21, 125, 236, 237, 205, 31, 17, 122, 136, 65, 32, 3, 58, 205, 98, 230, 49, 144, 14, + 123, 71, 11, 32, 127, 229, 127, 214, 174, 17, 86, 204, 202, 214, 91, 189, 188, 173, 197, 42, + 131, 68, 53, 158, 32, 2, 148, 100, 44, 115, 248, 179, 128, 111, 48, 110, 86, 181, 103, 101, + 153, 25, 42, 122, 126, 63, 38, 39, 182, 68, 109, 62, 203, 152, 1, 182, 93, 23, 32, 0, 177, 112, + 221, 230, 64, 11, 164, 35, 3, 8, 65, 218, 108, 182, 90, 245, 190, 38, 24, 154, 229, 253, 43, + 142, 0, 130, 222, 131, 163, 199, 191, 32, 5, 253, 167, 130, 154, 76, 153, 7, 23, 68, 51, 154, + 166, 154, 10, 20, 9, 65, 61, 135, 73, 47, 129, 187, 29, 120, 18, 32, 204, 8, 228, 138, 32, 5, + 253, 167, 130, 154, 76, 153, 7, 23, 68, 51, 154, 166, 154, 10, 20, 9, 65, 61, 135, 73, 47, 129, + 187, 29, 120, 18, 32, 204, 8, 228, 138, 32, 5, 253, 167, 130, 154, 76, 153, 7, 23, 68, 51, 154, + 166, 154, 10, 20, 9, 65, 61, 135, 73, 47, 129, 187, 29, 120, 18, 32, 204, 8, 228, 138, 32, 4, + 204, 242, 235, 254, 170, 58, 180, 146, 175, 33, 98, 116, 149, 249, 198, 214, 176, 105, 176, 63, + 251, 152, 191, 49, 93, 107, 35, 141, 179, 214, 198, 32, 5, 88, 0, 73, 35, 11, 51, 169, 127, + 189, 228, 4, 80, 200, 106, 181, 180, 224, 42, 189, 206, 155, 93, 50, 70, 78, 17, 221, 63, 122, + 64, 87, 32, 0, 65, 187, 83, 167, 237, 79, 88, 148, 50, 180, 230, 202, 144, 62, 23, 152, 26, + 148, 150, 210, 159, 60, 162, 94, 88, 128, 241, 0, 62, 177, 87, 32, 6, 202, 120, 8, 33, 88, 198, + 76, 203, 241, 179, 83, 210, 208, 13, 97, 224, 119, 3, 192, 245, 59, 54, 140, 117, 59, 97, 76, + 216, 121, 67, 255, 32, 1, 218, 169, 233, 62, 98, 15, 85, 98, 119, 31, 162, 109, 182, 171, 175, + 155, 59, 166, 160, 232, 76, 98, 188, 118, 125, 117, 24, 130, 227, 157, 116, 32, 2, 10, 131, + 133, 220, 5, 113, 0, 251, 247, 79, 249, 46, 174, 45, 4, 106, 227, 192, 154, 202, 126, 111, 12, + 70, 49, 42, 138, 182, 129, 119, 206, 32, 2, 177, 236, 177, 120, 193, 106, 63, 83, 255, 158, 47, + 96, 53, 228, 187, 29, 82, 48, 98, 144, 58, 32, 181, 93, 166, 99, 160, 16, 147, 126, 205, 32, 3, + 124, 158, 193, 250, 134, 70, 161, 37, 180, 66, 215, 240, 91, 103, 81, 55, 119, 151, 240, 122, + 49, 152, 253, 21, 157, 194, 118, 204, 154, 50, 210, 32, 1, 130, 58, 19, 35, 168, 37, 175, 91, + 187, 4, 137, 46, 126, 147, 175, 240, 122, 106, 145, 247, 4, 6, 28, 219, 110, 6, 89, 106, 171, + 122, 46, 32, 7, 46, 219, 171, 86, 142, 56, 253, 17, 210, 82, 40, 178, 123, 251, 223, 224, 181, + 1, 51, 161, 211, 168, 142, 233, 27, 44, 173, 149, 68, 196, 148, 32, 2, 195, 209, 107, 42, 33, + 250, 250, 220, 20, 186, 72, 57, 139, 57, 243, 166, 239, 195, 172, 209, 146, 1, 198, 238, 81, + 17, 120, 140, 123, 53, 66, 32, 1, 89, 244, 9, 149, 65, 28, 145, 169, 192, 160, 50, 161, 195, + 170, 236, 161, 142, 62, 193, 177, 63, 71, 153, 208, 64, 177, 255, 91, 82, 10, 156, 32, 4, 243, + 116, 187, 26, 108, 113, 71, 86, 1, 14, 120, 31, 168, 141, 184, 220, 29, 214, 174, 245, 90, 149, + 208, 226, 238, 117, 214, 233, 212, 252, 241, 32, 7, 229, 192, 89, 78, 105, 2, 255, 174, 236, + 100, 177, 115, 255, 9, 182, 190, 4, 53, 118, 48, 193, 8, 237, 45, 177, 217, 202, 9, 79, 121, 7, + 32, 5, 90, 40, 57, 46, 10, 89, 140, 53, 199, 232, 129, 134, 25, 222, 218, 39, 42, 143, 83, 161, + 44, 6, 191, 133, 174, 201, 176, 207, 148, 97, 131, 32, 7, 132, 111, 173, 88, 120, 117, 200, + 143, 251, 234, 181, 34, 111, 125, 83, 133, 144, 97, 13, 6, 68, 53, 15, 112, 15, 45, 196, 240, + 246, 250, 24, 32, 7, 15, 67, 4, 99, 90, 199, 22, 114, 244, 176, 34, 72, 8, 195, 232, 234, 216, + 152, 130, 213, 75, 146, 49, 248, 226, 79, 226, 240, 28, 170, 55, 32, 6, 7, 240, 50, 223, 56, + 217, 122, 130, 10, 217, 101, 58, 143, 84, 234, 212, 3, 132, 11, 197, 138, 192, 188, 30, 131, + 169, 7, 245, 175, 161, 162, 32, 6, 232, 158, 56, 95, 230, 63, 244, 175, 237, 55, 162, 218, 226, + 159, 76, 184, 15, 30, 11, 204, 189, 241, 87, 181, 136, 203, 175, 53, 110, 126, 67, 1, 0, 32, 7, + 255, 255, 255, 255, 255, 253, 240, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 225, 32, 7, 255, 255, 255, 255, 255, + 185, 240, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 251, 225, 32, 7, 255, 255, 255, 255, 255, 185, 240, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 251, 225, 32, 7, 255, 255, 255, 255, 255, 245, 112, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 97, 32, 7, 255, 255, + 255, 255, 255, 103, 16, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 247, 1, 1, 251, 251, 127, 1, 251, 1, 128, 2, 2, 1, 5, + 3, 33, 72, 32, 32, 7, 255, 255, 255, 255, 255, 200, 208, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 252, 193, 32, 6, 47, + 252, 208, 5, 81, 69, 218, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 246, 251, 47, 255, 208, 0, 80, 19, 43, 32, 7, 255, 255, 255, 255, 255, 194, 112, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 225, 32, 7, 255, 255, 255, 255, 255, 185, 240, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 251, 225, 32, 7, - 255, 255, 255, 255, 255, 185, 240, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 251, 225, 32, 7, 255, 255, 255, 255, 255, - 245, 112, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 97, 32, 7, 255, 255, 255, 255, 255, 103, 16, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 247, - 1, 1, 251, 251, 127, 1, 251, 1, 128, 2, 2, 1, 5, 3, 33, 72, 32, 32, 7, 255, 255, 255, 255, 255, - 190, 48, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 252, 33, 32, 7, 255, 255, 255, 255, 255, 185, 240, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 251, - 225, 32, 7, 255, 255, 255, 255, 255, 239, 16, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 1, 32, 7, 255, 255, 255, 255, - 255, 253, 240, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 225, 32, 7, 255, 255, 255, 255, 255, 213, 144, 255, 255, + 255, 252, 97, 32, 0, 0, 0, 0, 0, 0, 21, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 64, 32, 7, 255, 255, 255, 255, 255, 209, 80, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 253, 65, 32, 7, + 144, 1, 16, 1, 16, 151, 69, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 251, 238, 144, 0, 16, 0, 16, 8, 230, 32, 7, 255, 255, 255, 255, 255, 243, 80, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 253, 129, 32, 1, 176, 7, 112, 1, 17, 69, 82, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 246, 254, 176, 0, 112, 0, 16, 19, 35, 32, 7, 255, 255, 255, 255, - 255, 194, 112, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 252, 97, 32, 0, 0, 0, 0, 0, 0, 21, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 32, 7, 255, 255, 255, 255, 255, 249, 176, 255, + 255, 255, 255, 65, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 32, 7, 255, 255, 255, 255, 255, 224, 48, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 33, 32, 2, + 47, 252, 208, 1, 17, 35, 65, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 247, 255, 47, 255, 208, 0, 16, 17, 34, 32, 7, 255, 255, 255, 255, 255, 213, 144, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 253, 129, 32, 1, 176, 7, 112, 1, 17, 69, 82, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 246, 254, 176, 0, 112, 0, 16, 19, 35, 32, 7, 255, 255, 255, + 255, 255, 192, 80, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 252, 65, 32, 7, 144, 1, 16, 1, 16, 151, 69, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 251, 238, 144, 0, 16, 0, 16, 8, + 230, 32, 7, 255, 255, 255, 255, 255, 205, 16, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 253, 1, 32, 1, 176, 7, 112, 1, 17, + 69, 82, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 246, 254, + 176, 0, 112, 0, 16, 19, 35, 32, 7, 255, 255, 255, 255, 255, 251, 208, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 193, + 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 32, 7, 255, 255, 255, 255, 255, 230, 144, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 129, 32, 7, 255, 255, + 255, 255, 255, 245, 112, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 97, 32, 7, 255, 255, 255, 255, 255, 249, 176, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 161, 32, 6, 111, 252, 207, 252, 208, 76, 229, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 253, 223, 111, 255, 207, 255, 208, 4, 134, 32, 7, 255, - 255, 255, 255, 255, 198, 176, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 252, 161, 32, 0, 0, 0, 0, 0, 0, 2, 32, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 32, 7, 255, 255, 255, 255, 255, - 196, 144, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 252, 129, 32, 6, 111, 252, 207, 252, 208, 76, 229, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 253, 223, 111, 255, 207, 255, 208, 4, - 134, 32, 7, 255, 255, 255, 255, 255, 219, 240, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 253, 225, 32, 7, 144, 1, 16, - 1, 16, 151, 69, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 251, - 238, 144, 0, 16, 0, 16, 8, 230, 32, 7, 255, 255, 255, 255, 255, 202, 240, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 252, - 225, 32, 0, 176, 3, 48, 1, 17, 69, 116, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 246, 253, 176, 0, 48, 0, 16, 19, 37, 32, 7, 255, 255, 255, 255, 255, 241, - 48, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 33, 32, 2, 47, 252, 208, 1, 17, 69, 65, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 246, 255, 47, 255, 208, 0, 16, 19, 34, 32, 7, 255, - 255, 255, 255, 255, 245, 112, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 97, 32, 0, 15, 252, 208, 1, 16, 6, 197, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 223, 15, 255, 208, - 0, 16, 0, 102, 32, 7, 255, 255, 255, 255, 255, 230, 144, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 129, 32, 7, - 255, 255, 255, 255, 255, 245, 112, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 97, 32, 7, 255, 255, 255, 255, 255, 200, - 208, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 252, 193, 32, 6, 47, 252, 208, 5, 81, 69, 218, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 246, 251, 47, 255, 208, 0, 80, 19, 43, 32, 7, - 255, 255, 255, 255, 255, 207, 48, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 253, 33, 32, 5, 176, 7, 112, 9, 145, 69, 235, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 246, 250, 176, 0, - 112, 0, 144, 19, 44, 32, 7, 255, 255, 255, 255, 255, 192, 80, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 252, 65, 32, 7, - 144, 1, 16, 1, 16, 151, 69, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 251, 238, 144, 0, 16, 0, 16, 8, 230, 32, 7, 255, 255, 255, 255, 255, 234, 208, 255, + 255, 255, 255, 255, 196, 144, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 252, 129, 32, 6, 111, 252, 207, 252, 208, 76, 229, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 253, 223, 111, 255, + 207, 255, 208, 4, 134, 32, 7, 255, 255, 255, 255, 255, 232, 176, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 161, 32, + 2, 47, 252, 208, 1, 17, 69, 65, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 246, 255, 47, 255, 208, 0, 16, 19, 34, 32, 7, 255, 255, 255, 255, 255, 226, 80, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 254, 193, 32, 7, 255, 255, 255, 255, 255, 253, 240, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 225, 32, - 7, 255, 255, 255, 255, 255, 222, 16, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 1, 32, 7, 255, 255, 255, 255, 255, - 228, 112, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 254, 97, 32, 7, 255, 255, 255, 255, 255, 224, 48, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, - 33, 32, 2, 47, 252, 208, 1, 17, 35, 65, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 247, 255, 47, 255, 208, 0, 16, 17, 34, 32, 7, 255, 255, 255, 255, 255, 247, - 144, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 129, 32, 7, 255, 255, 255, 255, 255, 247, 144, 255, 255, 255, 255, + 255, 255, 255, 254, 65, 32, 7, 255, 255, 255, 255, 255, 245, 112, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 97, 32, 7, + 255, 255, 255, 255, 255, 198, 176, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 252, 161, 32, 0, 0, 0, 0, 0, 0, 2, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 32, 7, 255, 255, 255, 255, + 255, 222, 16, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 254, 1, 32, 7, 255, 255, 255, 255, 255, 228, 112, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 129, 32, 7, 255, 255, 255, 255, 255, 253, 240, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 225, 32, 0, 15, 252, 208, - 1, 16, 20, 81, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 127, 15, 255, 208, 0, 16, 1, 50, 32, 7, 255, 255, 255, 255, 255, 243, 80, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 65, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 32, 7, 255, 255, 255, 255, 255, 232, 176, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 161, 32, 2, 47, 252, 208, + 254, 97, 32, 7, 255, 255, 255, 255, 255, 188, 16, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 252, 1, 32, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 7, 255, 255, + 255, 255, 255, 253, 240, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 225, 32, 0, 15, 252, 208, 1, 16, 20, 81, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 127, 15, 255, 208, 0, 16, + 1, 50, 32, 7, 255, 255, 255, 255, 255, 241, 48, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 33, 32, 2, 47, 252, 208, 1, 17, 69, 65, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 246, - 255, 47, 255, 208, 0, 16, 19, 34, 32, 7, 255, 255, 255, 255, 255, 205, 16, 255, 255, 255, 255, + 255, 47, 255, 208, 0, 16, 19, 34, 32, 7, 255, 255, 255, 255, 255, 219, 240, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 253, - 1, 32, 1, 176, 7, 112, 1, 17, 69, 82, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 246, 254, 176, 0, 112, 0, 16, 19, 35, 32, 7, 255, 255, 255, 255, 255, 211, - 112, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 253, 97, 32, 1, 176, 7, 112, 1, 17, 69, 82, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 246, 254, 176, 0, 112, 0, 16, 19, 35, 32, 7, 255, - 255, 255, 255, 255, 188, 16, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 252, 1, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 7, 255, 255, 255, 255, 255, 228, - 112, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 254, 97, 32, 6, 111, 252, 207, 252, 208, 76, 229, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 253, 223, 111, 255, 207, 255, 208, 4, 134, - 32, 7, 255, 255, 255, 255, 255, 236, 240, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 225, 32, 2, 47, 252, 208, 1, - 17, 69, 65, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 246, - 255, 47, 255, 208, 0, 16, 19, 34, 32, 7, 255, 255, 255, 255, 255, 226, 80, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, - 65, 32, 7, 255, 255, 255, 255, 255, 245, 112, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 97, 32, 7, 255, 255, 255, 255, - 255, 209, 80, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 253, 65, 32, 7, 144, 1, 16, 1, 16, 151, 69, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 251, 238, 144, 0, 16, 0, 16, 8, 230, 32, - 7, 255, 255, 255, 255, 255, 251, 208, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 193, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 7, 255, 255, 255, 255, - 255, 217, 208, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 253, 193, 32, 0, 15, 252, 208, 1, 16, 15, 137, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 191, 15, 255, 208, 0, 16, 0, - 234, 32, 7, 255, 255, 255, 255, 255, 215, 176, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 253, 161, 32, 7, 255, 255, - 255, 255, 255, 245, 112, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 97, 64, + 225, 32, 7, 144, 1, 16, 1, 16, 151, 69, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 251, 238, 144, 0, 16, 0, 16, 8, 230, 32, 7, 255, 255, 255, 255, 255, 217, + 208, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 253, 193, 32, 0, 15, 252, 208, 1, 16, 15, 137, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 191, 15, 255, 208, 0, 16, 0, 234, 32, 7, + 255, 255, 255, 255, 255, 211, 112, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 253, 97, 32, 1, 176, 7, 112, 1, 17, 69, 82, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 246, 254, 176, 0, + 112, 0, 16, 19, 35, 32, 7, 255, 255, 255, 255, 255, 234, 208, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 193, 32, + 7, 255, 255, 255, 255, 255, 253, 240, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 225, 32, 7, 255, 255, 255, 255, + 255, 215, 176, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 253, 161, 32, 7, 255, 255, 255, 255, 255, 245, 112, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 97, 32, 7, 255, 255, 255, 255, 255, 228, 112, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 97, 32, 6, 111, 252, + 207, 252, 208, 76, 229, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 253, 223, 111, 255, 207, 255, 208, 4, 134, 32, 7, 255, 255, 255, 255, 255, 202, 240, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 252, 225, 32, 0, 176, 3, 48, 1, 17, 69, 116, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 246, 253, 176, 0, 48, 0, 16, 19, 37, 32, 7, 255, 255, 255, + 255, 255, 247, 144, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 129, 32, 7, 255, 255, 255, 255, 255, 247, 144, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 129, 32, 7, 255, 255, 255, 255, 255, 245, 112, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 97, 32, 0, + 15, 252, 208, 1, 16, 6, 197, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 223, 15, 255, 208, 0, 16, 0, 102, 32, 7, 255, 255, 255, 255, 255, 236, 240, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 254, 225, 32, 2, 47, 252, 208, 1, 17, 69, 65, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 246, 255, 47, 255, 208, 0, 16, 19, 34, 32, 7, 255, 255, 255, + 255, 255, 190, 48, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 252, 33, 32, 7, 255, 255, 255, 255, 255, 185, 240, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 251, 225, 32, 7, 255, 255, 255, 255, 255, 239, 16, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 1, 32, 7, 255, 255, + 255, 255, 255, 253, 240, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 225, 32, 7, 255, 255, 255, 255, 255, 207, 48, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 253, 33, 32, 5, 176, 7, 112, 9, 145, 69, 235, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 246, 250, 176, 0, 112, 0, 144, 19, 44, 64, ]; diff --git a/provers/stark/src/constraints/evaluator.rs b/provers/stark/src/constraints/evaluator.rs index ed8a7b2ba..140a104ab 100644 --- a/provers/stark/src/constraints/evaluator.rs +++ b/provers/stark/src/constraints/evaluator.rs @@ -1,31 +1,27 @@ -use itertools::Itertools; -use lambdaworks_math::{ - fft::{cpu::roots_of_unity::get_powers_of_primitive_root_coset, errors::FFTError}, - field::{ - element::FieldElement, - traits::{IsFFTField, IsField, IsSubFieldOf}, - }, - polynomial::Polynomial, - traits::AsBytes, -}; - -#[cfg(feature = "parallel")] -use rayon::prelude::{ - IndexedParallelIterator, IntoParallelIterator, IntoParallelRefIterator, ParallelIterator, -}; - use super::boundary::BoundaryConstraints; #[cfg(all(debug_assertions, not(feature = "parallel")))] use crate::debug::check_boundary_polys_divisibility; +use crate::domain::Domain; +use crate::trace::LDETraceTable; use crate::traits::AIR; -use crate::{domain::Domain, table::EvaluationTable}; use crate::{frame::Frame, prover::evaluate_polynomial_on_lde_domain}; +use itertools::Itertools; +#[cfg(all(debug_assertions, not(feature = "parallel")))] +use lambdaworks_math::polynomial::Polynomial; +use lambdaworks_math::{fft::errors::FFTError, field::element::FieldElement, traits::AsBytes}; +#[cfg(feature = "parallel")] +use rayon::{ + iter::IndexedParallelIterator, + prelude::{IntoParallelIterator, ParallelIterator}, +}; +#[cfg(feature = "instruments")] +use std::time::Instant; pub struct ConstraintEvaluator { boundary_constraints: BoundaryConstraints, } impl ConstraintEvaluator { - pub fn new(air: &A, rap_challenges: &A::RAPChallenges) -> Self { + pub fn new(air: &A, rap_challenges: &[FieldElement]) -> Self { let boundary_constraints = air.boundary_constraints(rap_challenges); Self { @@ -36,17 +32,16 @@ impl ConstraintEvaluator { pub(crate) fn evaluate( &self, air: &A, - lde_table: &EvaluationTable, + lde_trace: &LDETraceTable, domain: &Domain, transition_coefficients: &[FieldElement], boundary_coefficients: &[FieldElement], - rap_challenges: &A::RAPChallenges, + rap_challenges: &[FieldElement], ) -> Vec> where FieldElement: AsBytes + Send + Sync, FieldElement: AsBytes + Send + Sync, A: Send + Sync, - A::RAPChallenges: Send + Sync, { let boundary_constraints = &self.boundary_constraints; let number_of_b_constraints = boundary_constraints.constraints.len(); @@ -66,11 +61,12 @@ impl ConstraintEvaluator { }) .collect::>>>(); - let trace_length = air.trace_length(); - #[cfg(all(debug_assertions, not(feature = "parallel")))] let boundary_polys: Vec>> = Vec::new(); + #[cfg(feature = "instruments")] + let timer = Instant::now(); + let lde_periodic_columns = air .get_periodic_column_polynomials() .iter() @@ -85,34 +81,48 @@ impl ConstraintEvaluator { .collect::>>, FFTError>>() .unwrap(); + #[cfg(feature = "instruments")] + println!( + " Evaluating periodic columns on lde: {:#?}", + timer.elapsed() + ); + + #[cfg(feature = "instruments")] + let timer = Instant::now(); + let boundary_polys_evaluations = boundary_constraints .constraints .iter() .map(|constraint| { if constraint.is_aux { - (0..lde_table.n_rows()) + (0..lde_trace.num_rows()) .map(|row| { - let v = lde_table.get_aux(row, constraint.col); + let v = lde_trace.get_aux(row, constraint.col); v - &constraint.value }) - .collect() + .collect_vec() } else { - (0..lde_table.n_rows()) + (0..lde_trace.num_rows()) .map(|row| { - let v = lde_table.get_main(row, constraint.col); + let v = lde_trace.get_main(row, constraint.col); v - &constraint.value }) - .collect() + .collect_vec() } }) - .collect::>>>(); + .collect_vec(); + + #[cfg(feature = "instruments")] + println!(" Created boundary polynomials: {:#?}", timer.elapsed()); + #[cfg(feature = "instruments")] + let timer = Instant::now(); #[cfg(feature = "parallel")] let boundary_eval_iter = (0..domain.lde_roots_of_unity_coset.len()).into_par_iter(); #[cfg(not(feature = "parallel"))] let boundary_eval_iter = 0..domain.lde_roots_of_unity_coset.len(); - let boundary_evaluation = boundary_eval_iter + let boundary_evaluation: Vec<_> = boundary_eval_iter .map(|domain_index| { (0..number_of_b_constraints) .zip(boundary_coefficients) @@ -123,7 +133,13 @@ impl ConstraintEvaluator { * &boundary_polys_evaluations[constraint_index][domain_index] }) }) - .collect::>>(); + .collect(); + + #[cfg(feature = "instruments")] + println!( + " Evaluated boundary polynomials on LDE: {:#?}", + timer.elapsed() + ); #[cfg(all(debug_assertions, not(feature = "parallel")))] let boundary_zerofiers = Vec::new(); @@ -131,156 +147,75 @@ impl ConstraintEvaluator { #[cfg(all(debug_assertions, not(feature = "parallel")))] check_boundary_polys_divisibility(boundary_polys, boundary_zerofiers); - let blowup_factor = air.blowup_factor(); - #[cfg(all(debug_assertions, not(feature = "parallel")))] let mut transition_evaluations = Vec::new(); - let transition_exemptions_polys = air.transition_exemptions(); - - let transition_exemptions_evaluations = - evaluate_transition_exemptions(transition_exemptions_polys, domain); - let num_exemptions = air.context().num_transition_exemptions(); - - let blowup_factor_order = u64::from(blowup_factor.trailing_zeros()); - - let offset = FieldElement::::from(air.context().proof_options.coset_offset); - let offset_pow = offset.pow(trace_length); - let one = FieldElement::one(); - let mut zerofier_evaluations = get_powers_of_primitive_root_coset::( - blowup_factor_order, - blowup_factor as usize, - &offset_pow, - ) - .unwrap() - .iter() - .map(|v| v - &one) - .collect::>(); + #[cfg(feature = "instruments")] + let timer = Instant::now(); + let zerofiers_evals = air.transition_zerofier_evaluations(domain); + #[cfg(feature = "instruments")] + println!( + " Evaluated transition zerofiers: {:#?}", + timer.elapsed() + ); + + // Iterate over all LDE domain and compute the part of the composition polynomial + // related to the transition constraints and add it to the already computed part of the + // boundary constraints. - FieldElement::inplace_batch_inverse(&mut zerofier_evaluations).unwrap(); + #[cfg(feature = "instruments")] + let timer = Instant::now(); + let evaluations_t_iter = 0..domain.lde_roots_of_unity_coset.len(); - // Iterate over trace and domain and compute transitions - let evaluations_t_iter; - let zerofier_iter; #[cfg(feature = "parallel")] - { - evaluations_t_iter = (0..domain.lde_roots_of_unity_coset.len()).into_par_iter(); - zerofier_iter = evaluations_t_iter - .clone() - .map(|i| zerofier_evaluations[i % zerofier_evaluations.len()].clone()); - } - #[cfg(not(feature = "parallel"))] - { - evaluations_t_iter = 0..domain.lde_roots_of_unity_coset.len(); - zerofier_iter = zerofier_evaluations.iter().cycle(); - } + let boundary_evaluation = boundary_evaluation.into_par_iter(); + #[cfg(feature = "parallel")] + let evaluations_t_iter = evaluations_t_iter.into_par_iter(); - // Iterate over all LDE domain and compute - // the part of the composition polynomial - // related to the transition constraints and - // add it to the already computed part of the - // boundary constraints. let evaluations_t = evaluations_t_iter - .zip(&boundary_evaluation) - .zip(zerofier_iter) - .map(|((i, boundary), zerofier)| { - let frame = Frame::::read_from_lde_table( - lde_table, - i, - blowup_factor, - &air.context().transition_offsets, - ); + .zip(boundary_evaluation) + .map(|(i, boundary)| { + let frame = Frame::read_from_lde(lde_trace, i, &air.context().transition_offsets); let periodic_values: Vec<_> = lde_periodic_columns .iter() .map(|col| col[i].clone()) .collect(); - // Compute all the transition constraints at this - // point of the LDE domain. + // Compute all the transition constraints at this point of the LDE domain. let evaluations_transition = air.compute_transition_prover(&frame, &periodic_values, rap_challenges); #[cfg(all(debug_assertions, not(feature = "parallel")))] transition_evaluations.push(evaluations_transition.clone()); - // Add each term of the transition constraints to the - // composition polynomial, including the zerofier, the - // challenge and the exemption polynomial if it is necessary. - let acc_transition = evaluations_transition - .iter() - .zip(&air.context().transition_exemptions) - .zip(transition_coefficients) - .fold(FieldElement::zero(), |acc, ((eval, exemption), beta)| { - #[cfg(feature = "parallel")] - let zerofier = zerofier.clone(); - - // If there's no exemption, then - // the zerofier remains as it was. - if *exemption == 0 { - acc + eval * zerofier * beta - } else { - //TODO: change how exemptions are indexed! - if num_exemptions == 1 { - acc + eval - * &transition_exemptions_evaluations[0][i] - * beta - * zerofier - } else { - // This case is not used for Cairo Programs, it can be improved in the future - let vector = air - .context() - .transition_exemptions - .iter() - .cloned() - .filter(|elem| elem > &0) - .unique_by(|elem| *elem) - .collect::>(); - let index = vector - .iter() - .position(|elem_2| elem_2 == exemption) - .expect("is there"); - - acc + eval - * &transition_exemptions_evaluations[index][i] - * zerofier - * beta - } - } - }); - // TODO: Remove clones + // Add each term of the transition constraints to the composition polynomial, including the zerofier, + // the challenge and the exemption polynomial if it is necessary. + let acc_transition = itertools::izip!( + evaluations_transition, + &zerofiers_evals, + transition_coefficients + ) + .fold(FieldElement::zero(), |acc, (eval, zerof_eval, beta)| { + // Zerofier evaluations are cyclical, so we only calculate one cycle. + // This means that here we have to wrap around + // Ex: Suppose the full zerofier vector is Z = [1,2,3,1,2,3] + // we will instead have calculated Z' = [1,2,3] + // Now if you need Z[4] this is equal to Z'[1] + let wrapped_idx = i % zerof_eval.len(); + acc + &zerof_eval[wrapped_idx] * eval * beta + }); acc_transition + boundary }) - .collect::>>(); + .collect(); + + #[cfg(feature = "instruments")] + println!( + " Evaluated transitions and accumulated results: {:#?}", + timer.elapsed() + ); evaluations_t } } - -fn evaluate_transition_exemptions, E: IsField>( - transition_exemptions: Vec>>, - domain: &Domain, -) -> Vec>> -where - FieldElement: Send + Sync + AsBytes, - FieldElement: Send + Sync + AsBytes, - Polynomial>: Send + Sync, -{ - #[cfg(feature = "parallel")] - let exemptions_iter = transition_exemptions.par_iter(); - #[cfg(not(feature = "parallel"))] - let exemptions_iter = transition_exemptions.iter(); - - exemptions_iter - .map(|exemption| { - evaluate_polynomial_on_lde_domain( - exemption, - domain.blowup_factor, - domain.interpolation_domain_size, - &domain.coset_offset, - ) - .unwrap() - }) - .collect() -} diff --git a/provers/stark/src/constraints/mod.rs b/provers/stark/src/constraints/mod.rs index 2087e3c79..3811523b5 100644 --- a/provers/stark/src/constraints/mod.rs +++ b/provers/stark/src/constraints/mod.rs @@ -1,2 +1,3 @@ pub mod boundary; pub mod evaluator; +pub mod transition; diff --git a/provers/stark/src/constraints/transition.rs b/provers/stark/src/constraints/transition.rs new file mode 100644 index 000000000..52fe0ba70 --- /dev/null +++ b/provers/stark/src/constraints/transition.rs @@ -0,0 +1,237 @@ +use crate::domain::Domain; +use crate::frame::Frame; +use crate::prover::evaluate_polynomial_on_lde_domain; +use itertools::Itertools; +use lambdaworks_math::field::element::FieldElement; +use lambdaworks_math::field::traits::{IsFFTField, IsField, IsSubFieldOf}; +use lambdaworks_math::polynomial::Polynomial; +use num_integer::Integer; +use std::ops::Div; +/// TransitionConstraint represents the behaviour that a transition constraint +/// over the computation that wants to be proven must comply with. +pub trait TransitionConstraint: Send + Sync +where + F: IsSubFieldOf + IsFFTField + Send + Sync, + E: IsField + Send + Sync, +{ + /// The degree of the constraint interpreting it as a multivariate polynomial. + fn degree(&self) -> usize; + + /// The index of the constraint. + /// Each transition constraint should have one index in the range [0, N), + /// where N is the total number of transition constraints. + fn constraint_idx(&self) -> usize; + + /// The function representing the evaluation of the constraint over elements + /// of the trace table. + /// + /// Elements of the trace table are found in the `frame` input, and depending on the + /// constraint, elements of `periodic_values` and `rap_challenges` may be used in + /// the evaluation. + /// Once computed, the evaluation should be inserted in the `transition_evaluations` + /// vector, in the index corresponding to the constraint as given by `constraint_idx()`. + fn evaluate( + &self, + frame: &Frame, + transition_evaluations: &mut [FieldElement], + periodic_values: &[FieldElement], + rap_challenges: &[FieldElement], + ); + + /// The periodicity the constraint is applied over the trace. + /// + /// Default value is 1, meaning that the constraint is applied to every + /// step of the trace. + fn period(&self) -> usize { + 1 + } + + /// The offset with respect to the first trace row, where the constraint + /// is applied. + /// For example, if the constraint has periodicity 2 and offset 1, this means + /// the constraint will be applied over trace rows of index 1, 3, 5, etc. + /// + /// Default value is 0, meaning that the constraint is applied from the first + /// element of the trace on. + fn offset(&self) -> usize { + 0 + } + + /// For a more fine-grained description of where the constraint should apply, + /// an exemptions period can be defined. + /// This specifies the periodicity of the row indexes where the constraint should + /// NOT apply, within the row indexes where the constraint applies, as specified by + /// `period()` and `offset()`. + /// + /// Default value is None. + fn exemptions_period(&self) -> Option { + None + } + + /// The offset value for periodic exemptions. Check documentation of `period()`, + /// `offset()` and `exemptions_period` for a better understanding. + fn periodic_exemptions_offset(&self) -> Option { + None + } + + /// The number of exemptions at the end of the trace. + /// + /// This method's output defines what trace elements should not be considered for + /// the constraint evaluation at the end of the trace. For example, for a fibonacci + /// computation that has to use the result 2 following steps, this method is defined + /// to return the value 2. + fn end_exemptions(&self) -> usize; + + /// Method for calculating the end exemptions polynomial. + /// + /// This polynomial is used to compute zerofiers of the constraint, and the default + /// implementation should normally not be changed. + fn end_exemptions_poly( + &self, + trace_primitive_root: &FieldElement, + trace_length: usize, + ) -> Polynomial> { + let one_poly = Polynomial::new_monomial(FieldElement::::one(), 0); + if self.end_exemptions() == 0 { + return one_poly; + } + let period = self.period(); + // FIXME: CHECK IF WE NEED TO CHANGE THE NEW MONOMIAL'S ARGUMENTS TO trace_root^(offset * trace_length / period) INSTEAD OF ONE!!!! + (1..=self.end_exemptions()) + .map(|exemption| trace_primitive_root.pow(trace_length - exemption * period)) + .fold(one_poly, |acc, offset| { + acc * (Polynomial::new_monomial(FieldElement::::one(), 1) - offset) + }) + } + + /// Compute evaluations of the constraints zerofier over a LDE domain. + fn zerofier_evaluations_on_extended_domain(&self, domain: &Domain) -> Vec> { + let blowup_factor = domain.blowup_factor; + let trace_length = domain.trace_roots_of_unity.len(); + let trace_primitive_root = &domain.trace_primitive_root; + let coset_offset = &domain.coset_offset; + let lde_root_order = u64::from((blowup_factor * trace_length).trailing_zeros()); + let lde_root = F::get_primitive_root_of_unity(lde_root_order).unwrap(); + + let end_exemptions_poly = self.end_exemptions_poly(trace_primitive_root, trace_length); + + // If there is an exemptions period defined for this constraint, the evaluations are calculated directly + // by computing P_exemptions(x) / Zerofier(x) + if let Some(exemptions_period) = self.exemptions_period() { + // FIXME: Rather than making this assertions here, it would be better to handle these + // errors or make these checks when the AIR is initialized. + debug_assert!(exemptions_period.is_multiple_of(&self.period())); + debug_assert!(self.periodic_exemptions_offset().is_some()); + + // The elements of the domain have order `trace_length * blowup_factor`, so the zerofier evaluations + // without the end exemptions, repeat their values after `blowup_factor * exemptions_period` iterations, + // so we only need to compute those. + let last_exponent = blowup_factor * exemptions_period; + + let evaluations: Vec<_> = (0..last_exponent) + .map(|exponent| { + let x = lde_root.pow(exponent); + let offset_times_x = coset_offset * &x; + let offset_exponent = trace_length * self.periodic_exemptions_offset().unwrap() + / exemptions_period; + + let numerator = offset_times_x.pow(trace_length / exemptions_period) + - trace_primitive_root.pow(offset_exponent); + let denominator = offset_times_x.pow(trace_length / self.period()) + - trace_primitive_root.pow(self.offset() * trace_length / self.period()); + + numerator.div(denominator) + }) + .collect(); + + // FIXME: Instead of computing this evaluations for each constraint, they can be computed + // once for every constraint with the same end exemptions (combination of end_exemptions() + // and period). + let end_exemption_evaluations = evaluate_polynomial_on_lde_domain( + &end_exemptions_poly, + blowup_factor, + domain.interpolation_domain_size, + coset_offset, + ) + .unwrap(); + + let cycled_evaluations = evaluations + .iter() + .cycle() + .take(end_exemption_evaluations.len()); + + std::iter::zip(cycled_evaluations, end_exemption_evaluations) + .map(|(eval, exemption_eval)| eval * exemption_eval) + .collect() + + // In this else branch, the zerofiers are computed as the numerator, then inverted + // using batch inverse and then multiplied by P_exemptions(x). This way we don't do + // useless divisions. + } else { + let last_exponent = blowup_factor * self.period(); + + let mut evaluations = (0..last_exponent) + .map(|exponent| { + let x = lde_root.pow(exponent); + (coset_offset * &x).pow(trace_length / self.period()) + - trace_primitive_root.pow(self.offset() * trace_length / self.period()) + }) + .collect_vec(); + + FieldElement::inplace_batch_inverse(&mut evaluations).unwrap(); + + // FIXME: Instead of computing this evaluations for each constraint, they can be computed + // once for every constraint with the same end exemptions (combination of end_exemptions() + // and period). + let end_exemption_evaluations = evaluate_polynomial_on_lde_domain( + &end_exemptions_poly, + blowup_factor, + domain.interpolation_domain_size, + coset_offset, + ) + .unwrap(); + + let cycled_evaluations = evaluations + .iter() + .cycle() + .take(end_exemption_evaluations.len()); + + std::iter::zip(cycled_evaluations, end_exemption_evaluations) + .map(|(eval, exemption_eval)| eval * exemption_eval) + .collect() + } + } + + /// Returns the evaluation of the zerofier corresponding to this constraint in some point + /// `z`, which could be in a field extension. + fn evaluate_zerofier( + &self, + z: &FieldElement, + trace_primitive_root: &FieldElement, + trace_length: usize, + ) -> FieldElement { + let end_exemptions_poly = self.end_exemptions_poly(trace_primitive_root, trace_length); + + if let Some(exemptions_period) = self.exemptions_period() { + debug_assert!(exemptions_period.is_multiple_of(&self.period())); + debug_assert!(self.periodic_exemptions_offset().is_some()); + + let periodic_exemptions_offset = self.periodic_exemptions_offset().unwrap(); + let offset_exponent = trace_length * periodic_exemptions_offset / exemptions_period; + + let numerator = -trace_primitive_root.pow(offset_exponent) + + z.pow(trace_length / exemptions_period); + let denominator = -trace_primitive_root + .pow(self.offset() * trace_length / self.period()) + + z.pow(trace_length / self.period()); + + return numerator.div(denominator) * end_exemptions_poly.evaluate(z); + } + + (-trace_primitive_root.pow(self.offset() * trace_length / self.period()) + + z.pow(trace_length / self.period())) + .inv() + .unwrap() + * end_exemptions_poly.evaluate(z) + } +} diff --git a/provers/stark/src/debug.rs b/provers/stark/src/debug.rs index 85fc3a1af..fc62257a4 100644 --- a/provers/stark/src/debug.rs +++ b/provers/stark/src/debug.rs @@ -1,7 +1,6 @@ -use crate::{frame::Frame, table::EvaluationTable}; - use super::domain::Domain; use super::traits::AIR; +use crate::{frame::Frame, trace::LDETraceTable}; use lambdaworks_math::{ field::{ element::FieldElement, @@ -17,7 +16,7 @@ pub fn validate_trace( main_trace_polys: &[Polynomial>], aux_trace_polys: &[Polynomial>], domain: &Domain, - rap_challenges: &A::RAPChallenges, + rap_challenges: &[FieldElement], ) -> bool { info!("Starting constraints validation over trace..."); let mut ret = true; @@ -33,6 +32,7 @@ pub fn validate_trace( .unwrap() }) .collect(); + let aux_trace_columns: Vec<_> = aux_trace_polys .iter() .map(|poly| { @@ -41,8 +41,8 @@ pub fn validate_trace( }) .collect(); - let lde_table = - EvaluationTable::from_columns(main_trace_columns, aux_trace_columns, A::STEP_SIZE); + let lde_trace = + LDETraceTable::from_columns(main_trace_columns, aux_trace_columns, A::STEP_SIZE, 1); let periodic_columns: Vec<_> = air .get_periodic_column_polynomials() @@ -67,9 +67,9 @@ pub fn validate_trace( let boundary_value = constraint.value.clone(); let trace_value = if !constraint.is_aux { - lde_table.get_main(step, col).clone().to_extension() + lde_trace.get_main(step, col).clone().to_extension() } else { - lde_table.get_aux(step, col).clone() + lde_trace.get_aux(step, col).clone() }; if boundary_value.clone().to_extension() != trace_value { @@ -82,17 +82,15 @@ pub fn validate_trace( let n_transition_constraints = air.context().num_transition_constraints(); let transition_exemptions = &air.context().transition_exemptions; - let exemption_steps: Vec = vec![lde_table.n_rows(); n_transition_constraints] + let exemption_steps: Vec = vec![lde_trace.num_rows(); n_transition_constraints] .iter() .zip(transition_exemptions) .map(|(trace_steps, exemptions)| trace_steps - exemptions) .collect(); // Iterate over trace and compute transitions - for step in 0..lde_table.num_steps() { - let frame = - Frame::read_from_lde_table(&lde_table, step, 1, &air.context().transition_offsets); - + for step in 0..lde_trace.num_steps() { + let frame = Frame::read_step_from_lde(&lde_trace, step, &air.context().transition_offsets); let periodic_values: Vec<_> = periodic_columns .iter() .map(|col| col[step].clone()) diff --git a/provers/stark/src/examples/bit_flags.rs b/provers/stark/src/examples/bit_flags.rs new file mode 100644 index 000000000..bec16ef60 --- /dev/null +++ b/provers/stark/src/examples/bit_flags.rs @@ -0,0 +1,211 @@ +use crate::{ + constraints::{boundary::BoundaryConstraints, transition::TransitionConstraint}, + context::AirContext, + frame::Frame, + proof::options::ProofOptions, + trace::TraceTable, + traits::AIR, + Felt252, +}; +use lambdaworks_math::field::{ + element::FieldElement, fields::fft_friendly::stark_252_prime_field::Stark252PrimeField, +}; +use std::iter; + +type StarkField = Stark252PrimeField; + +#[derive(Clone)] +pub struct BitConstraint; +impl BitConstraint { + fn new() -> Self { + Self + } +} + +impl TransitionConstraint for BitConstraint { + fn degree(&self) -> usize { + 2 + } + + fn constraint_idx(&self) -> usize { + 0 + } + + fn exemptions_period(&self) -> Option { + Some(16) + } + + fn periodic_exemptions_offset(&self) -> Option { + Some(15) + } + + fn end_exemptions(&self) -> usize { + 0 + } + + fn evaluate( + &self, + frame: &Frame, + transition_evaluations: &mut [Felt252], + _periodic_values: &[Felt252], + _rap_challenges: &[Felt252], + ) { + let step = frame.get_evaluation_step(0); + + let prefix_flag = step.get_main_evaluation_element(0, 0); + let next_prefix_flag = step.get_main_evaluation_element(1, 0); + + let two = Felt252::from(2); + let one = Felt252::one(); + let bit_flag = prefix_flag - two * next_prefix_flag; + + let bit_constraint = bit_flag * (bit_flag - one); + + transition_evaluations[self.constraint_idx()] = bit_constraint; + } +} + +#[derive(Clone)] +pub struct ZeroFlagConstraint; +impl ZeroFlagConstraint { + fn new() -> Self { + Self + } +} + +impl TransitionConstraint for ZeroFlagConstraint { + fn degree(&self) -> usize { + 1 + } + + fn constraint_idx(&self) -> usize { + 1 + } + + fn end_exemptions(&self) -> usize { + 0 + } + + fn period(&self) -> usize { + 16 + } + + fn offset(&self) -> usize { + 15 + } + + fn evaluate( + &self, + frame: &Frame, + transition_evaluations: &mut [FieldElement], + _periodic_values: &[FieldElement], + _rap_challenges: &[FieldElement], + ) { + let step = frame.get_evaluation_step(0); + let zero_flag = step.get_main_evaluation_element(15, 0); + + transition_evaluations[self.constraint_idx()] = *zero_flag; + } +} + +pub struct BitFlagsAIR { + context: AirContext, + constraints: Vec>>, + trace_length: usize, +} + +impl AIR for BitFlagsAIR { + type Field = StarkField; + type FieldExtension = StarkField; + type PublicInputs = (); + + const STEP_SIZE: usize = 16; + + fn new( + trace_length: usize, + _pub_inputs: &Self::PublicInputs, + proof_options: &ProofOptions, + ) -> Self { + let bit_constraint = Box::new(BitConstraint::new()); + let flag_constraint = Box::new(ZeroFlagConstraint::new()); + let constraints: Vec>> = + vec![bit_constraint, flag_constraint]; + // vec![flag_constraint]; + // vec![bit_constraint]; + + let num_transition_constraints = constraints.len(); + let transition_exemptions: Vec<_> = + constraints.iter().map(|c| c.end_exemptions()).collect(); + + let context = AirContext { + proof_options: proof_options.clone(), + trace_columns: 1, + transition_exemptions, + transition_offsets: vec![0], + num_transition_constraints, + }; + + Self { + context, + trace_length, + constraints, + } + } + + fn transition_constraints( + &self, + ) -> &Vec>> { + &self.constraints + } + + fn compute_transition_verifier( + &self, + frame: &Frame, + periodic_values: &[FieldElement], + rap_challenges: &[FieldElement], + ) -> Vec> { + self.compute_transition_prover(frame, periodic_values, rap_challenges) + } + + fn boundary_constraints( + &self, + _rap_challenges: &[FieldElement], + ) -> BoundaryConstraints { + BoundaryConstraints::from_constraints(vec![]) + } + + fn context(&self) -> &AirContext { + &self.context + } + + fn composition_poly_degree_bound(&self) -> usize { + self.trace_length * 2 + } + + fn trace_length(&self) -> usize { + self.trace_length + } + + fn trace_layout(&self) -> (usize, usize) { + (1, 0) + } + + fn pub_inputs(&self) -> &Self::PublicInputs { + &() + } +} + +pub fn bit_prefix_flag_trace(num_steps: usize) -> TraceTable { + debug_assert!(num_steps.is_power_of_two()); + let step: Vec = [ + 1031u64, 515, 257, 128, 64, 32, 16, 8, 4, 2, 1, 0, 0, 0, 0, 0, + ] + .iter() + .map(|t| Felt252::from(*t)) + .collect(); + + let mut data: Vec = iter::repeat(step).take(num_steps).flatten().collect(); + data[0] = Felt252::from(1030); + + TraceTable::new(data, 1, 0, 16) +} diff --git a/provers/stark/src/examples/dummy_air.rs b/provers/stark/src/examples/dummy_air.rs index b85c49e9c..1206ed153 100644 --- a/provers/stark/src/examples/dummy_air.rs +++ b/provers/stark/src/examples/dummy_air.rs @@ -1,28 +1,126 @@ -use lambdaworks_math::field::{ - element::FieldElement, fields::fft_friendly::stark_252_prime_field::Stark252PrimeField, - traits::IsFFTField, -}; +use std::marker::PhantomData; use crate::{ - constraints::boundary::{BoundaryConstraint, BoundaryConstraints}, + constraints::{ + boundary::{BoundaryConstraint, BoundaryConstraints}, + transition::TransitionConstraint, + }, context::AirContext, frame::Frame, proof::options::ProofOptions, trace::TraceTable, traits::AIR, - transcript::IsStarkTranscript, }; +use lambdaworks_math::field::{ + element::FieldElement, fields::fft_friendly::stark_252_prime_field::Stark252PrimeField, + traits::IsFFTField, +}; + +type StarkField = Stark252PrimeField; #[derive(Clone)] +struct FibConstraint { + phantom: PhantomData, +} +impl FibConstraint { + pub fn new() -> Self { + Self { + phantom: PhantomData, + } + } +} + +impl TransitionConstraint for FibConstraint +where + F: IsFFTField + Send + Sync, +{ + fn degree(&self) -> usize { + 1 + } + + fn constraint_idx(&self) -> usize { + 0 + } + + fn end_exemptions(&self) -> usize { + 2 + } + + fn evaluate( + &self, + frame: &Frame, + transition_evaluations: &mut [FieldElement], + _periodic_values: &[FieldElement], + _rap_challenges: &[FieldElement], + ) { + let first_step = frame.get_evaluation_step(0); + let second_step = frame.get_evaluation_step(1); + let third_step = frame.get_evaluation_step(2); + + let a0 = first_step.get_main_evaluation_element(0, 1); + let a1 = second_step.get_main_evaluation_element(0, 1); + let a2 = third_step.get_main_evaluation_element(0, 1); + + let res = a2 - a1 - a0; + + transition_evaluations[self.constraint_idx()] = res; + } +} + +#[derive(Clone)] +struct BitConstraint { + phantom: PhantomData, +} +impl BitConstraint { + pub fn new() -> Self { + Self { + phantom: PhantomData, + } + } +} + +impl TransitionConstraint for BitConstraint +where + F: IsFFTField + Send + Sync, +{ + fn degree(&self) -> usize { + 2 + } + + fn constraint_idx(&self) -> usize { + 1 + } + + fn end_exemptions(&self) -> usize { + 0 + } + + fn evaluate( + &self, + frame: &Frame, + transition_evaluations: &mut [FieldElement], + _periodic_values: &[FieldElement], + _rap_challenges: &[FieldElement], + ) { + let first_step = frame.get_evaluation_step(0); + + let bit = first_step.get_main_evaluation_element(0, 0); + + let res = bit * (bit - FieldElement::::one()); + + transition_evaluations[self.constraint_idx()] = res; + } +} + pub struct DummyAIR { context: AirContext, trace_length: usize, + transition_constraints: Vec>>, } impl AIR for DummyAIR { - type Field = Stark252PrimeField; - type FieldExtension = Stark252PrimeField; - type RAPChallenges = (); + type Field = StarkField; + type FieldExtension = StarkField; type PublicInputs = (); const STEP_SIZE: usize = 1; @@ -32,6 +130,13 @@ impl AIR for DummyAIR { _pub_inputs: &Self::PublicInputs, proof_options: &ProofOptions, ) -> Self { + let transition_constraints: Vec< + Box>, + > = vec![ + Box::new(FibConstraint::new()), + Box::new(BitConstraint::new()), + ]; + let context = AirContext { proof_options: proof_options.clone(), trace_columns: 2, @@ -43,47 +148,13 @@ impl AIR for DummyAIR { Self { context, trace_length, + transition_constraints, } } - fn build_auxiliary_trace( - &self, - _main_trace: &TraceTable, - _rap_challenges: &Self::RAPChallenges, - ) -> TraceTable { - TraceTable::empty() - } - - fn build_rap_challenges( - &self, - _transcript: &mut impl IsStarkTranscript, - ) -> Self::RAPChallenges { - } - fn compute_transition_prover( - &self, - frame: &Frame, - _periodic_values: &[FieldElement], - _rap_challenges: &Self::RAPChallenges, - ) -> Vec> { - let first_step = frame.get_evaluation_step(0); - let second_step = frame.get_evaluation_step(1); - let third_step = frame.get_evaluation_step(2); - - let flag = first_step.get_main_evaluation_element(0, 0); - let a0 = first_step.get_main_evaluation_element(0, 1); - let a1 = second_step.get_main_evaluation_element(0, 1); - let a2 = third_step.get_main_evaluation_element(0, 1); - - let f_constraint = flag * (flag - FieldElement::one()); - - let fib_constraint = a2 - a1 - a0; - - vec![f_constraint, fib_constraint] - } - fn boundary_constraints( &self, - _rap_challenges: &Self::RAPChallenges, + _rap_challenges: &[FieldElement], ) -> BoundaryConstraints { let a0 = BoundaryConstraint::new_main(1, 0, FieldElement::::one()); let a1 = BoundaryConstraint::new_main(1, 1, FieldElement::::one()); @@ -91,8 +162,10 @@ impl AIR for DummyAIR { BoundaryConstraints::from_constraints(vec![a0, a1]) } - fn number_auxiliary_rap_columns(&self) -> usize { - 0 + fn transition_constraints( + &self, + ) -> &Vec>> { + &self.transition_constraints } fn context(&self) -> &AirContext { @@ -100,7 +173,11 @@ impl AIR for DummyAIR { } fn composition_poly_degree_bound(&self) -> usize { - self.trace_length + self.trace_length * 2 + } + + fn trace_layout(&self) -> (usize, usize) { + (2, 0) } fn trace_length(&self) -> usize { @@ -115,7 +192,7 @@ impl AIR for DummyAIR { &self, frame: &Frame, periodic_values: &[FieldElement], - rap_challenges: &Self::RAPChallenges, + rap_challenges: &[FieldElement], ) -> Vec> { self.compute_transition_prover(frame, periodic_values, rap_challenges) } @@ -134,5 +211,9 @@ pub fn dummy_trace(trace_length: usize) -> TraceTable { ret.push(ret[i - 1].clone() + ret[i - 2].clone()); } - TraceTable::from_columns(vec![vec![FieldElement::::one(); trace_length], ret], 1) + TraceTable::from_columns( + vec![vec![FieldElement::::one(); trace_length], ret], + 2, + 1, + ) } diff --git a/provers/stark/src/examples/fibonacci_2_cols_shifted.rs b/provers/stark/src/examples/fibonacci_2_cols_shifted.rs index a0b5874fb..6d3eb76d1 100644 --- a/provers/stark/src/examples/fibonacci_2_cols_shifted.rs +++ b/provers/stark/src/examples/fibonacci_2_cols_shifted.rs @@ -1,17 +1,116 @@ -use lambdaworks_math::{ - field::{element::FieldElement, traits::IsFFTField}, - traits::AsBytes, -}; - use crate::{ - constraints::boundary::{BoundaryConstraint, BoundaryConstraints}, + constraints::{ + boundary::{BoundaryConstraint, BoundaryConstraints}, + transition::TransitionConstraint, + }, context::AirContext, frame::Frame, proof::options::ProofOptions, trace::TraceTable, traits::AIR, - transcript::IsStarkTranscript, }; +use lambdaworks_math::{ + field::{element::FieldElement, traits::IsFFTField}, + traits::AsBytes, +}; +use std::marker::PhantomData; + +#[derive(Clone)] +struct ShiftedFibTransition1 { + phantom: PhantomData, +} + +impl ShiftedFibTransition1 { + pub fn new() -> Self { + Self { + phantom: PhantomData, + } + } +} + +impl TransitionConstraint for ShiftedFibTransition1 +where + F: IsFFTField + Send + Sync, +{ + fn degree(&self) -> usize { + 1 + } + + fn constraint_idx(&self) -> usize { + 0 + } + + fn end_exemptions(&self) -> usize { + 1 + } + + fn evaluate( + &self, + frame: &Frame, + transition_evaluations: &mut [FieldElement], + _periodic_values: &[FieldElement], + _rap_challenges: &[FieldElement], + ) { + let first_row = frame.get_evaluation_step(0); + let second_row = frame.get_evaluation_step(1); + + let a0_1 = first_row.get_main_evaluation_element(0, 1); + let a1_0 = second_row.get_main_evaluation_element(0, 0); + + let res = a1_0 - a0_1; + + transition_evaluations[self.constraint_idx()] = res; + } +} + +#[derive(Clone)] +struct ShiftedFibTransition2 { + phantom: PhantomData, +} + +impl ShiftedFibTransition2 { + pub fn new() -> Self { + Self { + phantom: PhantomData, + } + } +} + +impl TransitionConstraint for ShiftedFibTransition2 +where + F: IsFFTField + Send + Sync, +{ + fn degree(&self) -> usize { + 1 + } + + fn constraint_idx(&self) -> usize { + 1 + } + + fn end_exemptions(&self) -> usize { + 1 + } + + fn evaluate( + &self, + frame: &Frame, + transition_evaluations: &mut [FieldElement], + _periodic_values: &[FieldElement], + _rap_challenges: &[FieldElement], + ) { + let first_row = frame.get_evaluation_step(0); + let second_row = frame.get_evaluation_step(1); + + let a0_0 = first_row.get_main_evaluation_element(0, 0); + let a0_1 = first_row.get_main_evaluation_element(0, 1); + let a1_1 = second_row.get_main_evaluation_element(0, 1); + + let res = a1_1 - a0_0 - a0_1; + + transition_evaluations[self.constraint_idx()] = res; + } +} #[derive(Clone, Debug)] pub struct PublicInputs @@ -34,7 +133,6 @@ where } } -#[derive(Clone, Debug)] pub struct Fibonacci2ColsShifted where F: IsFFTField, @@ -42,6 +140,7 @@ where context: AirContext, trace_length: usize, pub_inputs: PublicInputs, + transition_constraints: Vec>>, } /// The AIR for to a 2 column trace, where each column is a Fibonacci sequence and the @@ -50,11 +149,10 @@ where /// for all `i`. Also, `Col0_0` is constrained to be `1`. impl AIR for Fibonacci2ColsShifted where - F: IsFFTField, + F: IsFFTField + Send + Sync + 'static, { type Field = F; type FieldExtension = F; - type RAPChallenges = (); type PublicInputs = PublicInputs; const STEP_SIZE: usize = 1; @@ -64,6 +162,13 @@ where pub_inputs: &Self::PublicInputs, proof_options: &ProofOptions, ) -> Self { + let transition_constraints: Vec< + Box>, + > = vec![ + Box::new(ShiftedFibTransition1::new()), + Box::new(ShiftedFibTransition2::new()), + ]; + let context = AirContext { proof_options: proof_options.clone(), transition_exemptions: vec![1, 1], @@ -76,51 +181,13 @@ where trace_length, context, pub_inputs: pub_inputs.clone(), + transition_constraints, } } - fn build_auxiliary_trace( - &self, - _main_trace: &TraceTable, - _rap_challenges: &Self::RAPChallenges, - ) -> TraceTable { - TraceTable::empty() - } - - fn build_rap_challenges( - &self, - _transcript: &mut impl IsStarkTranscript, - ) -> Self::RAPChallenges { - } - - fn compute_transition_prover( - &self, - frame: &Frame, - _periodic_values: &[FieldElement], - _rap_challenges: &Self::RAPChallenges, - ) -> Vec> { - let first_row = frame.get_evaluation_step(0); - let second_row = frame.get_evaluation_step(1); - - let a0_0 = first_row.get_main_evaluation_element(0, 0); - let a0_1 = first_row.get_main_evaluation_element(0, 1); - - let a1_0 = second_row.get_main_evaluation_element(0, 0); - let a1_1 = second_row.get_main_evaluation_element(0, 1); - - let first_transition = a1_0 - a0_1; - let second_transition = a1_1 - a0_0 - a0_1; - - vec![first_transition, second_transition] - } - - fn number_auxiliary_rap_columns(&self) -> usize { - 0 - } - fn boundary_constraints( &self, - _rap_challenges: &Self::RAPChallenges, + _rap_challenges: &[FieldElement], ) -> BoundaryConstraints { let initial_condition = BoundaryConstraint::new_main(0, 0, FieldElement::one()); let claimed_value_constraint = BoundaryConstraint::new_main( @@ -132,6 +199,12 @@ where BoundaryConstraints::from_constraints(vec![initial_condition, claimed_value_constraint]) } + fn transition_constraints( + &self, + ) -> &Vec>> { + &self.transition_constraints + } + fn context(&self) -> &AirContext { &self.context } @@ -144,6 +217,10 @@ where self.trace_length } + fn trace_layout(&self) -> (usize, usize) { + (2, 0) + } + fn pub_inputs(&self) -> &Self::PublicInputs { &self.pub_inputs } @@ -152,7 +229,7 @@ where &self, frame: &Frame, periodic_values: &[FieldElement], - rap_challenges: &Self::RAPChallenges, + rap_challenges: &[FieldElement], ) -> Vec> { self.compute_transition_prover(frame, periodic_values, rap_challenges) } @@ -173,7 +250,7 @@ pub fn compute_trace( col1.push(y.clone()); } - TraceTable::from_columns(vec![col0, col1], 1) + TraceTable::from_columns(vec![col0, col1], 2, 1) } #[cfg(test)] diff --git a/provers/stark/src/examples/fibonacci_2_columns.rs b/provers/stark/src/examples/fibonacci_2_columns.rs index 98c93b72b..0cd2a789a 100644 --- a/provers/stark/src/examples/fibonacci_2_columns.rs +++ b/provers/stark/src/examples/fibonacci_2_columns.rs @@ -1,18 +1,119 @@ -use lambdaworks_math::field::{element::FieldElement, traits::IsFFTField}; +use std::marker::PhantomData; +use super::simple_fibonacci::FibonacciPublicInputs; use crate::{ - constraints::boundary::{BoundaryConstraint, BoundaryConstraints}, + constraints::{ + boundary::{BoundaryConstraint, BoundaryConstraints}, + transition::TransitionConstraint, + }, context::AirContext, frame::Frame, proof::options::ProofOptions, trace::TraceTable, traits::AIR, - transcript::IsStarkTranscript, }; +use lambdaworks_math::field::{element::FieldElement, traits::IsFFTField}; -use super::simple_fibonacci::FibonacciPublicInputs; +#[derive(Clone)] +struct FibTransition1 { + phantom: PhantomData, +} + +impl FibTransition1 { + pub fn new() -> Self { + Self { + phantom: PhantomData, + } + } +} + +impl TransitionConstraint for FibTransition1 +where + F: IsFFTField + Send + Sync, +{ + fn degree(&self) -> usize { + 1 + } + + fn constraint_idx(&self) -> usize { + 0 + } + + fn end_exemptions(&self) -> usize { + 1 + } + + fn evaluate( + &self, + frame: &Frame, + transition_evaluations: &mut [FieldElement], + _periodic_values: &[FieldElement], + _rap_challenges: &[FieldElement], + ) { + let first_step = frame.get_evaluation_step(0); + let second_step = frame.get_evaluation_step(1); + + // s_{0, i+1} = s_{0, i} + s_{1, i} + let s0_0 = first_step.get_main_evaluation_element(0, 0); + let s0_1 = first_step.get_main_evaluation_element(0, 1); + let s1_0 = second_step.get_main_evaluation_element(0, 0); + + let res = s1_0 - s0_0 - s0_1; + + transition_evaluations[self.constraint_idx()] = res; + } +} + +#[derive(Clone)] +struct FibTransition2 { + phantom: PhantomData, +} + +impl FibTransition2 { + pub fn new() -> Self { + Self { + phantom: PhantomData, + } + } +} + +impl TransitionConstraint for FibTransition2 +where + F: IsFFTField + Send + Sync, +{ + fn degree(&self) -> usize { + 1 + } + + fn constraint_idx(&self) -> usize { + 1 + } + + fn end_exemptions(&self) -> usize { + 1 + } + + fn evaluate( + &self, + frame: &Frame, + transition_evaluations: &mut [FieldElement], + _periodic_values: &[FieldElement], + _rap_challenges: &[FieldElement], + ) { + let first_step = frame.get_evaluation_step(0); + let second_step = frame.get_evaluation_step(1); + + // s_{1, i+1} = s_{1, i} + s_{0, i+1} + let s0_1 = first_step.get_main_evaluation_element(0, 1); + let s1_0 = second_step.get_main_evaluation_element(0, 0); + let s1_1 = second_step.get_main_evaluation_element(0, 1); + + let res = s1_1 - s0_1 - s1_0; + + transition_evaluations[self.constraint_idx()] = res; + } +} -#[derive(Clone, Debug)] pub struct Fibonacci2ColsAIR where F: IsFFTField, @@ -20,17 +121,17 @@ where context: AirContext, trace_length: usize, pub_inputs: FibonacciPublicInputs, + constraints: Vec>>, } /// The AIR for to a 2 column trace, where the columns form a Fibonacci sequence when /// stacked in row-major order. impl AIR for Fibonacci2ColsAIR where - F: IsFFTField, + F: IsFFTField + Send + Sync + 'static, { type Field = F; type FieldExtension = F; - type RAPChallenges = (); type PublicInputs = FibonacciPublicInputs; const STEP_SIZE: usize = 1; @@ -40,65 +141,30 @@ where pub_inputs: &Self::PublicInputs, proof_options: &ProofOptions, ) -> Self { + let constraints: Vec>> = vec![ + Box::new(FibTransition1::new()), + Box::new(FibTransition2::new()), + ]; + let context = AirContext { proof_options: proof_options.clone(), transition_exemptions: vec![1, 1], transition_offsets: vec![0, 1], - num_transition_constraints: 2, + num_transition_constraints: constraints.len(), trace_columns: 2, }; Self { trace_length, context, + constraints, pub_inputs: pub_inputs.clone(), } } - fn build_auxiliary_trace( - &self, - _main_trace: &TraceTable, - _rap_challenges: &Self::RAPChallenges, - ) -> TraceTable { - TraceTable::empty() - } - - fn build_rap_challenges( - &self, - _transcript: &mut impl IsStarkTranscript, - ) -> Self::RAPChallenges { - } - - fn compute_transition_prover( - &self, - frame: &Frame, - _periodic_values: &[FieldElement], - _rap_challenges: &Self::RAPChallenges, - ) -> Vec> { - let first_step = frame.get_evaluation_step(0); - let second_step = frame.get_evaluation_step(1); - - // constraints of Fibonacci sequence (2 terms per step): - // s_{0, i+1} = s_{0, i} + s_{1, i} - // s_{1, i+1} = s_{1, i} + s_{0, i+1} - let s0_0 = first_step.get_main_evaluation_element(0, 0); - let s0_1 = first_step.get_main_evaluation_element(0, 1); - let s1_0 = second_step.get_main_evaluation_element(0, 0); - let s1_1 = second_step.get_main_evaluation_element(0, 1); - - let first_transition = s1_0 - s0_0 - s0_1; - let second_transition = s1_1 - s0_1 - s1_0; - - vec![first_transition, second_transition] - } - - fn number_auxiliary_rap_columns(&self) -> usize { - 0 - } - fn boundary_constraints( &self, - _rap_challenges: &Self::RAPChallenges, + _rap_challenges: &[FieldElement], ) -> BoundaryConstraints { let a0 = BoundaryConstraint::new_main(0, 0, self.pub_inputs.a0.clone()); let a1 = BoundaryConstraint::new_main(1, 0, self.pub_inputs.a1.clone()); @@ -106,6 +172,10 @@ where BoundaryConstraints::from_constraints(vec![a0, a1]) } + fn transition_constraints(&self) -> &Vec>> { + &self.constraints + } + fn context(&self) -> &AirContext { &self.context } @@ -118,6 +188,10 @@ where self.trace_length } + fn trace_layout(&self) -> (usize, usize) { + (2, 0) + } + fn pub_inputs(&self) -> &Self::PublicInputs { &self.pub_inputs } @@ -126,7 +200,7 @@ where &self, frame: &Frame, periodic_values: &[FieldElement], - rap_challenges: &Self::RAPChallenges, + rap_challenges: &[FieldElement], ) -> Vec> { self.compute_transition_prover(frame, periodic_values, rap_challenges) } @@ -148,5 +222,5 @@ pub fn compute_trace( ret2.push(new_val + ret2[i - 1].clone()); } - TraceTable::from_columns(vec![ret1, ret2], 1) + TraceTable::from_columns(vec![ret1, ret2], 2, 1) } diff --git a/provers/stark/src/examples/fibonacci_rap.rs b/provers/stark/src/examples/fibonacci_rap.rs index b960ae97c..263bc3170 100644 --- a/provers/stark/src/examples/fibonacci_rap.rs +++ b/provers/stark/src/examples/fibonacci_rap.rs @@ -1,13 +1,10 @@ -use std::ops::Div; - -use lambdaworks_math::{ - field::{element::FieldElement, traits::IsFFTField}, - helpers::resize_to_next_power_of_two, - traits::ByteConversion, -}; +use std::{marker::PhantomData, ops::Div}; use crate::{ - constraints::boundary::{BoundaryConstraint, BoundaryConstraints}, + constraints::{ + boundary::{BoundaryConstraint, BoundaryConstraints}, + transition::TransitionConstraint, + }, context::AirContext, frame::Frame, proof::options::ProofOptions, @@ -15,8 +12,117 @@ use crate::{ traits::AIR, transcript::IsStarkTranscript, }; +use lambdaworks_math::{ + field::{element::FieldElement, traits::IsFFTField}, + helpers::resize_to_next_power_of_two, + traits::ByteConversion, +}; #[derive(Clone)] +struct FibConstraint { + phantom: PhantomData, +} + +impl FibConstraint { + pub fn new() -> Self { + Self { + phantom: PhantomData, + } + } +} + +impl TransitionConstraint for FibConstraint +where + F: IsFFTField + Send + Sync, +{ + fn degree(&self) -> usize { + 1 + } + + fn constraint_idx(&self) -> usize { + 0 + } + + fn end_exemptions(&self) -> usize { + // NOTE: This is hard-coded for the example of steps = 16 in the integration tests. + // If that number changes in the test, this should be changed too or the test will fail. + 3 + 32 - 16 - 1 + } + + fn evaluate( + &self, + frame: &Frame, + transition_evaluations: &mut [FieldElement], + _periodic_values: &[FieldElement], + _rap_challenges: &[FieldElement], + ) { + let first_step = frame.get_evaluation_step(0); + let second_step = frame.get_evaluation_step(1); + let third_step = frame.get_evaluation_step(2); + + let a0 = first_step.get_main_evaluation_element(0, 0); + let a1 = second_step.get_main_evaluation_element(0, 0); + let a2 = third_step.get_main_evaluation_element(0, 0); + + let res = a2 - a1 - a0; + + transition_evaluations[self.constraint_idx()] = res; + } +} + +#[derive(Clone)] +struct PermutationConstraint { + phantom: PhantomData, +} + +impl PermutationConstraint { + pub fn new() -> Self { + Self { + phantom: PhantomData, + } + } +} + +impl TransitionConstraint for PermutationConstraint +where + F: IsFFTField + Send + Sync, +{ + fn degree(&self) -> usize { + 2 + } + + fn constraint_idx(&self) -> usize { + 1 + } + + fn end_exemptions(&self) -> usize { + 1 + } + + fn evaluate( + &self, + frame: &Frame, + transition_evaluations: &mut [FieldElement], + _periodic_values: &[FieldElement], + rap_challenges: &[FieldElement], + ) { + let first_step = frame.get_evaluation_step(0); + let second_step = frame.get_evaluation_step(1); + + // Auxiliary constraints + let z_i = first_step.get_aux_evaluation_element(0, 0); + let z_i_plus_one = second_step.get_aux_evaluation_element(0, 0); + let gamma = &rap_challenges[0]; + + let a_i = first_step.get_main_evaluation_element(0, 0); + let b_i = first_step.get_main_evaluation_element(0, 1); + + let res = z_i_plus_one * (b_i + gamma) - z_i * (a_i + gamma); + + transition_evaluations[self.constraint_idx()] = res; + } +} + pub struct FibonacciRAP where F: IsFFTField, @@ -24,6 +130,7 @@ where context: AirContext, trace_length: usize, pub_inputs: FibonacciRAPPublicInputs, + transition_constraints: Vec>>, } #[derive(Clone, Debug)] @@ -38,12 +145,11 @@ where impl AIR for FibonacciRAP where - F: IsFFTField, + F: IsFFTField + Send + Sync + 'static, FieldElement: ByteConversion, { type Field = F; type FieldExtension = F; - type RAPChallenges = FieldElement; type PublicInputs = FibonacciRAPPublicInputs; const STEP_SIZE: usize = 1; @@ -53,6 +159,13 @@ where pub_inputs: &Self::PublicInputs, proof_options: &ProofOptions, ) -> Self { + let transition_constraints: Vec< + Box>, + > = vec![ + Box::new(FibConstraint::new()), + Box::new(PermutationConstraint::new()), + ]; + let exemptions = 3 + trace_length - pub_inputs.steps - 1; let context = AirContext { @@ -60,24 +173,26 @@ where trace_columns: 3, transition_offsets: vec![0, 1, 2], transition_exemptions: vec![exemptions, 1], - num_transition_constraints: 2, + num_transition_constraints: transition_constraints.len(), }; Self { context, trace_length, pub_inputs: pub_inputs.clone(), + transition_constraints, } } fn build_auxiliary_trace( &self, main_trace: &TraceTable, - gamma: &Self::RAPChallenges, + challenges: &[FieldElement], ) -> TraceTable { let main_segment_cols = main_trace.columns(); let not_perm = &main_segment_cols[0]; let perm = &main_segment_cols[1]; + let gamma = &challenges[0]; let trace_len = main_trace.n_rows(); @@ -93,62 +208,41 @@ where aux_col.push(z_i * n_p_term.div(p_term)); } } - TraceTable::from_columns(vec![aux_col], 1) + TraceTable::from_columns(vec![aux_col], 0, 1) } fn build_rap_challenges( &self, - transcript: &mut impl IsStarkTranscript, - ) -> Self::RAPChallenges { - transcript.sample_field_element() + transcript: &mut impl IsStarkTranscript, + ) -> Vec> { + vec![transcript.sample_field_element()] } - fn number_auxiliary_rap_columns(&self) -> usize { - 1 - } - - fn compute_transition_prover( - &self, - frame: &Frame, - _periodic_values: &[FieldElement], - gamma: &Self::RAPChallenges, - ) -> Vec> { - // Main constraints - let first_step = frame.get_evaluation_step(0); - let second_step = frame.get_evaluation_step(1); - let third_step = frame.get_evaluation_step(2); - - let a0 = first_step.get_main_evaluation_element(0, 0); - let a1 = second_step.get_main_evaluation_element(0, 0); - let a2 = third_step.get_main_evaluation_element(0, 0); - - let mut constraints = vec![a2 - a1 - a0]; - - // Auxiliary constraints - let z_i = first_step.get_aux_evaluation_element(0, 0); - let z_i_plus_one = second_step.get_aux_evaluation_element(0, 0); - - let a_i = first_step.get_main_evaluation_element(0, 0); - let b_i = first_step.get_main_evaluation_element(0, 1); - - let eval = z_i_plus_one * (b_i + gamma) - z_i * (a_i + gamma); - - constraints.push(eval); - constraints + fn trace_layout(&self) -> (usize, usize) { + (2, 1) } fn boundary_constraints( &self, - _rap_challenges: &Self::RAPChallenges, - ) -> BoundaryConstraints { + _rap_challenges: &[FieldElement], + ) -> BoundaryConstraints { // Main boundary constraints - let a0 = BoundaryConstraint::new_simple_main(0, FieldElement::::one()); - let a1 = BoundaryConstraint::new_simple_main(1, FieldElement::::one()); + let a0 = + BoundaryConstraint::new_simple_main(0, FieldElement::::one()); + let a1 = + BoundaryConstraint::new_simple_main(1, FieldElement::::one()); // Auxiliary boundary constraints - let a0_aux = BoundaryConstraint::new_aux(0, 0, FieldElement::::one()); + let a0_aux = BoundaryConstraint::new_aux(0, 0, FieldElement::::one()); BoundaryConstraints::from_constraints(vec![a0, a1, a0_aux]) + // BoundaryConstraints::from_constraints(vec![a0, a1]) + } + + fn transition_constraints( + &self, + ) -> &Vec>> { + &self.transition_constraints } fn context(&self) -> &AirContext { @@ -171,7 +265,7 @@ where &self, frame: &Frame, periodic_values: &[FieldElement], - rap_challenges: &Self::RAPChallenges, + rap_challenges: &[FieldElement], ) -> Vec> { self.compute_transition_prover(frame, periodic_values, rap_challenges) } @@ -200,7 +294,7 @@ pub fn fibonacci_rap_trace( let mut trace_cols = vec![fib_seq, fib_permuted]; resize_to_next_power_of_two(&mut trace_cols); - TraceTable::from_columns(trace_cols, 1) + TraceTable::from_columns(trace_cols, 2, 1) } #[cfg(test)] diff --git a/provers/stark/src/examples/mod.rs b/provers/stark/src/examples/mod.rs index e8c809c4b..6a8949f7a 100644 --- a/provers/stark/src/examples/mod.rs +++ b/provers/stark/src/examples/mod.rs @@ -1,3 +1,4 @@ +pub mod bit_flags; pub mod dummy_air; pub mod fibonacci_2_cols_shifted; pub mod fibonacci_2_columns; diff --git a/provers/stark/src/examples/quadratic_air.rs b/provers/stark/src/examples/quadratic_air.rs index ef7c29409..3d07d78e3 100644 --- a/provers/stark/src/examples/quadratic_air.rs +++ b/provers/stark/src/examples/quadratic_air.rs @@ -1,16 +1,66 @@ -use lambdaworks_math::field::{element::FieldElement, traits::IsFFTField}; +use std::marker::PhantomData; use crate::{ - constraints::boundary::{BoundaryConstraint, BoundaryConstraints}, + constraints::{ + boundary::{BoundaryConstraint, BoundaryConstraints}, + transition::TransitionConstraint, + }, context::AirContext, frame::Frame, proof::options::ProofOptions, trace::TraceTable, traits::AIR, - transcript::IsStarkTranscript, }; +use lambdaworks_math::field::{element::FieldElement, traits::IsFFTField}; #[derive(Clone)] +struct QuadraticConstraint { + phantom: PhantomData, +} + +impl QuadraticConstraint { + pub fn new() -> Self { + Self { + phantom: PhantomData, + } + } +} + +impl TransitionConstraint for QuadraticConstraint +where + F: IsFFTField + Send + Sync, +{ + fn degree(&self) -> usize { + 2 + } + + fn constraint_idx(&self) -> usize { + 0 + } + + fn end_exemptions(&self) -> usize { + 1 + } + + fn evaluate( + &self, + frame: &Frame, + transition_evaluations: &mut [FieldElement], + _periodic_values: &[FieldElement], + _rap_challenges: &[FieldElement], + ) { + let first_step = frame.get_evaluation_step(0); + let second_step = frame.get_evaluation_step(1); + + let x = first_step.get_main_evaluation_element(0, 0); + let x_squared = second_step.get_main_evaluation_element(0, 0); + + let res = x_squared - x * x; + + transition_evaluations[self.constraint_idx()] = res; + } +} + pub struct QuadraticAIR where F: IsFFTField, @@ -18,6 +68,7 @@ where context: AirContext, trace_length: usize, pub_inputs: QuadraticPublicInputs, + constraints: Vec>>, } #[derive(Clone, Debug)] @@ -30,11 +81,10 @@ where impl AIR for QuadraticAIR where - F: IsFFTField, + F: IsFFTField + Send + Sync + 'static, { type Field = F; type FieldExtension = F; - type RAPChallenges = (); type PublicInputs = QuadraticPublicInputs; const STEP_SIZE: usize = 1; @@ -44,63 +94,40 @@ where pub_inputs: &Self::PublicInputs, proof_options: &ProofOptions, ) -> Self { + let constraints: Vec>> = + vec![Box::new(QuadraticConstraint::new())]; + let context = AirContext { proof_options: proof_options.clone(), trace_columns: 1, transition_exemptions: vec![1], transition_offsets: vec![0, 1], - num_transition_constraints: 1, + num_transition_constraints: constraints.len(), }; Self { trace_length, context, pub_inputs: pub_inputs.clone(), + constraints, } } - fn build_auxiliary_trace( - &self, - _main_trace: &TraceTable, - _rap_challenges: &Self::RAPChallenges, - ) -> TraceTable { - TraceTable::empty() - } - - fn build_rap_challenges( - &self, - _transcript: &mut impl IsStarkTranscript, - ) -> Self::RAPChallenges { - } - - fn compute_transition_prover( - &self, - frame: &Frame, - _periodic_values: &[FieldElement], - _rap_challenges: &Self::RAPChallenges, - ) -> Vec> { - let first_step = frame.get_evaluation_step(0); - let second_step = frame.get_evaluation_step(1); - - let x = first_step.get_main_evaluation_element(0, 0); - let x_squared = second_step.get_main_evaluation_element(0, 0); - - vec![x_squared - x * x] - } - - fn number_auxiliary_rap_columns(&self) -> usize { - 0 - } - fn boundary_constraints( &self, - _rap_challenges: &Self::RAPChallenges, + _rap_challenges: &[FieldElement], ) -> BoundaryConstraints { let a0 = BoundaryConstraint::new_simple_main(0, self.pub_inputs.a0.clone()); BoundaryConstraints::from_constraints(vec![a0]) } + fn transition_constraints( + &self, + ) -> &Vec>> { + &self.constraints + } + fn context(&self) -> &AirContext { &self.context } @@ -109,6 +136,10 @@ where 2 * self.trace_length() } + fn trace_layout(&self) -> (usize, usize) { + (1, 0) + } + fn trace_length(&self) -> usize { self.trace_length } @@ -121,7 +152,7 @@ where &self, frame: &Frame, periodic_values: &[FieldElement], - rap_challenges: &Self::RAPChallenges, + rap_challenges: &[FieldElement], ) -> Vec> { self.compute_transition_prover(frame, periodic_values, rap_challenges) } @@ -139,5 +170,5 @@ pub fn quadratic_trace( ret.push(ret[i - 1].clone() * ret[i - 1].clone()); } - TraceTable::from_columns(vec![ret], 1) + TraceTable::from_columns(vec![ret], 1, 1) } diff --git a/provers/stark/src/examples/simple_fibonacci.rs b/provers/stark/src/examples/simple_fibonacci.rs index b255ee318..204aa938c 100644 --- a/provers/stark/src/examples/simple_fibonacci.rs +++ b/provers/stark/src/examples/simple_fibonacci.rs @@ -1,16 +1,67 @@ -use lambdaworks_math::field::{element::FieldElement, traits::IsFFTField}; - use crate::{ - constraints::boundary::{BoundaryConstraint, BoundaryConstraints}, + constraints::{ + boundary::{BoundaryConstraint, BoundaryConstraints}, + transition::TransitionConstraint, + }, context::AirContext, frame::Frame, proof::options::ProofOptions, trace::TraceTable, traits::AIR, - transcript::IsStarkTranscript, }; +use lambdaworks_math::field::{element::FieldElement, traits::IsFFTField}; +use std::marker::PhantomData; #[derive(Clone)] +struct FibConstraint { + phantom: PhantomData, +} + +impl FibConstraint { + pub fn new() -> Self { + Self { + phantom: PhantomData, + } + } +} + +impl TransitionConstraint for FibConstraint +where + F: IsFFTField + Send + Sync, +{ + fn degree(&self) -> usize { + 1 + } + + fn constraint_idx(&self) -> usize { + 0 + } + + fn end_exemptions(&self) -> usize { + 2 + } + + fn evaluate( + &self, + frame: &Frame, + transition_evaluations: &mut [FieldElement], + _periodic_values: &[FieldElement], + _rap_challenges: &[FieldElement], + ) { + let first_step = frame.get_evaluation_step(0); + let second_step = frame.get_evaluation_step(1); + let third_step = frame.get_evaluation_step(2); + + let a0 = first_step.get_main_evaluation_element(0, 0); + let a1 = second_step.get_main_evaluation_element(0, 0); + let a2 = third_step.get_main_evaluation_element(0, 0); + + let res = a2 - a1 - a0; + + transition_evaluations[self.constraint_idx()] = res; + } +} + pub struct FibonacciAIR where F: IsFFTField, @@ -18,6 +69,7 @@ where context: AirContext, trace_length: usize, pub_inputs: FibonacciPublicInputs, + constraints: Vec>>, } #[derive(Clone, Debug)] @@ -31,11 +83,10 @@ where impl AIR for FibonacciAIR where - F: IsFFTField, + F: IsFFTField + Send + Sync + 'static, { type Field = F; type FieldExtension = F; - type RAPChallenges = (); type PublicInputs = FibonacciPublicInputs; const STEP_SIZE: usize = 1; @@ -45,18 +96,22 @@ where pub_inputs: &Self::PublicInputs, proof_options: &ProofOptions, ) -> Self { + let constraints: Vec>> = + vec![Box::new(FibConstraint::new())]; + let context = AirContext { proof_options: proof_options.clone(), trace_columns: 1, transition_exemptions: vec![2], transition_offsets: vec![0, 1, 2], - num_transition_constraints: 1, + num_transition_constraints: constraints.len(), }; Self { pub_inputs: pub_inputs.clone(), context, trace_length, + constraints, } } @@ -64,40 +119,13 @@ where self.trace_length() } - fn build_auxiliary_trace( - &self, - _main_trace: &TraceTable, - _rap_challenges: &Self::RAPChallenges, - ) -> TraceTable { - TraceTable::empty() - } - - fn build_rap_challenges( - &self, - _transcript: &mut impl IsStarkTranscript, - ) -> Self::RAPChallenges { - } - - fn compute_transition_prover( - &self, - frame: &Frame, - _periodic_values: &[FieldElement], - _rap_challenges: &Self::RAPChallenges, - ) -> Vec> { - let first_step = frame.get_evaluation_step(0); - let second_step = frame.get_evaluation_step(1); - let third_step = frame.get_evaluation_step(2); - - let a0 = first_step.get_main_evaluation_element(0, 0); - let a1 = second_step.get_main_evaluation_element(0, 0); - let a2 = third_step.get_main_evaluation_element(0, 0); - - vec![a2 - a1 - a0] + fn transition_constraints(&self) -> &Vec>> { + &self.constraints } fn boundary_constraints( &self, - _rap_challenges: &Self::RAPChallenges, + _rap_challenges: &[FieldElement], ) -> BoundaryConstraints { let a0 = BoundaryConstraint::new_simple_main(0, self.pub_inputs.a0.clone()); let a1 = BoundaryConstraint::new_simple_main(1, self.pub_inputs.a1.clone()); @@ -105,10 +133,6 @@ where BoundaryConstraints::from_constraints(vec![a0, a1]) } - fn number_auxiliary_rap_columns(&self) -> usize { - 0 - } - fn context(&self) -> &AirContext { &self.context } @@ -117,6 +141,10 @@ where self.trace_length } + fn trace_layout(&self) -> (usize, usize) { + (1, 0) + } + fn pub_inputs(&self) -> &Self::PublicInputs { &self.pub_inputs } @@ -125,7 +153,7 @@ where &self, frame: &Frame, periodic_values: &[FieldElement], - rap_challenges: &Self::RAPChallenges, + rap_challenges: &[FieldElement], ) -> Vec> { self.compute_transition_prover(frame, periodic_values, rap_challenges) } @@ -144,5 +172,5 @@ pub fn fibonacci_trace( ret.push(ret[i - 1].clone() + ret[i - 2].clone()); } - TraceTable::from_columns(vec![ret], 1) + TraceTable::from_columns(vec![ret], 1, 1) } diff --git a/provers/stark/src/examples/simple_periodic_cols.rs b/provers/stark/src/examples/simple_periodic_cols.rs index 3ca7b68b2..369ff2dd0 100644 --- a/provers/stark/src/examples/simple_periodic_cols.rs +++ b/provers/stark/src/examples/simple_periodic_cols.rs @@ -1,14 +1,70 @@ -use lambdaworks_math::field::{element::FieldElement, traits::IsFFTField}; +use std::marker::PhantomData; use crate::{ - constraints::boundary::{BoundaryConstraint, BoundaryConstraints}, + constraints::{ + boundary::{BoundaryConstraint, BoundaryConstraints}, + transition::TransitionConstraint, + }, context::AirContext, frame::Frame, proof::options::ProofOptions, trace::TraceTable, traits::AIR, - transcript::IsStarkTranscript, }; +use lambdaworks_math::field::{element::FieldElement, traits::IsFFTField}; + +pub struct PeriodicConstraint { + phantom: PhantomData, +} +impl PeriodicConstraint { + pub fn new() -> Self { + Self { + phantom: PhantomData, + } + } +} +impl Default for PeriodicConstraint { + fn default() -> Self { + Self::new() + } +} + +impl TransitionConstraint for PeriodicConstraint +where + F: IsFFTField + Send + Sync, +{ + fn degree(&self) -> usize { + 1 + } + + fn constraint_idx(&self) -> usize { + 0 + } + + fn end_exemptions(&self) -> usize { + 2 + } + + fn evaluate( + &self, + frame: &Frame, + transition_evaluations: &mut [FieldElement], + periodic_values: &[FieldElement], + _rap_challenges: &[FieldElement], + ) { + let first_step = frame.get_evaluation_step(0); + let second_step = frame.get_evaluation_step(1); + let third_step = frame.get_evaluation_step(2); + + let a0 = first_step.get_main_evaluation_element(0, 0); + let a1 = second_step.get_main_evaluation_element(0, 0); + let a2 = third_step.get_main_evaluation_element(0, 0); + + let s = &periodic_values[0]; + + transition_evaluations[self.constraint_idx()] = s * (a2 - a1 - a0); + } +} /// A sequence that uses periodic columns. It has two columns /// - C1: at each step adds the last two values or does @@ -24,7 +80,6 @@ use crate::{ /// 4 | 1 Adds 2 + 2 /// 4 | 0 ... /// 8 | 1 -#[derive(Clone)] pub struct SimplePeriodicAIR where F: IsFFTField, @@ -32,6 +87,7 @@ where context: AirContext, trace_length: usize, pub_inputs: SimplePeriodicPublicInputs, + transition_constraints: Vec>>, } #[derive(Clone, Debug)] @@ -45,11 +101,10 @@ where impl AIR for SimplePeriodicAIR where - F: IsFFTField, + F: IsFFTField + Send + Sync + 'static, { type Field = F; type FieldExtension = F; - type RAPChallenges = (); type PublicInputs = SimplePeriodicPublicInputs; const STEP_SIZE: usize = 1; @@ -59,18 +114,23 @@ where pub_inputs: &Self::PublicInputs, proof_options: &ProofOptions, ) -> Self { + let transition_constraints: Vec< + Box>, + > = vec![Box::new(PeriodicConstraint::new())]; + let context = AirContext { proof_options: proof_options.clone(), trace_columns: 1, transition_exemptions: vec![2], transition_offsets: vec![0, 1, 2], - num_transition_constraints: 1, + num_transition_constraints: transition_constraints.len(), }; Self { pub_inputs: pub_inputs.clone(), context, trace_length, + transition_constraints, } } @@ -78,42 +138,9 @@ where self.trace_length() } - fn build_auxiliary_trace( - &self, - _main_trace: &TraceTable, - _rap_challenges: &Self::RAPChallenges, - ) -> TraceTable { - TraceTable::empty() - } - - fn build_rap_challenges( - &self, - _transcript: &mut impl IsStarkTranscript, - ) -> Self::RAPChallenges { - } - - fn compute_transition_prover( - &self, - frame: &Frame, - periodic_values: &[FieldElement], - _rap_challenges: &Self::RAPChallenges, - ) -> Vec> { - let first_step = frame.get_evaluation_step(0); - let second_step = frame.get_evaluation_step(1); - let third_step = frame.get_evaluation_step(2); - - let a0 = first_step.get_main_evaluation_element(0, 0); - let a1 = second_step.get_main_evaluation_element(0, 0); - let a2 = third_step.get_main_evaluation_element(0, 0); - - let s = &periodic_values[0]; - - vec![s * (a2 - a1 - a0)] - } - fn boundary_constraints( &self, - _rap_challenges: &Self::RAPChallenges, + _rap_challenges: &[FieldElement], ) -> BoundaryConstraints { let a0 = BoundaryConstraint::new_simple_main(0, self.pub_inputs.a0.clone()); let a1 = BoundaryConstraint::new_simple_main( @@ -124,8 +151,10 @@ where BoundaryConstraints::from_constraints(vec![a0, a1]) } - fn number_auxiliary_rap_columns(&self) -> usize { - 0 + fn transition_constraints( + &self, + ) -> &Vec>> { + &self.transition_constraints } fn get_periodic_column_values(&self) -> Vec>> { @@ -140,6 +169,10 @@ where self.trace_length } + fn trace_layout(&self) -> (usize, usize) { + (1, 0) + } + fn pub_inputs(&self) -> &Self::PublicInputs { &self.pub_inputs } @@ -148,7 +181,7 @@ where &self, frame: &Frame, periodic_values: &[FieldElement], - rap_challenges: &Self::RAPChallenges, + rap_challenges: &[FieldElement], ) -> Vec> { self.compute_transition_prover(frame, periodic_values, rap_challenges) } @@ -169,5 +202,5 @@ pub fn simple_periodic_trace(trace_length: usize) -> TraceTable, E: IsField> { - steps: Vec>, +pub struct Frame<'t, F: IsSubFieldOf, E: IsField> +where + E: IsField, + F: IsSubFieldOf, +{ + steps: Vec>, } impl<'t, F: IsSubFieldOf, E: IsField> Frame<'t, F, E> { - pub fn new(steps: Vec>) -> Self { + pub fn new(steps: Vec>) -> Self { Self { steps } } - pub fn get_evaluation_step(&self, step: usize) -> &StepView { + pub fn get_evaluation_step(&self, step: usize) -> &TableView<'t, F, E> { &self.steps[step] } - pub fn read_from_lde_table( - lde_table: &'t EvaluationTable, - step: usize, - blowup: u8, + pub fn read_from_lde( + lde_trace: &'t LDETraceTable, + row: usize, offsets: &[usize], ) -> Self { - // Get trace length to apply module with it when getting elements of - // the frame from the trace. - let trace_steps = lde_table.num_steps(); + let blowup_factor = lde_trace.blowup_factor; + let num_rows = lde_trace.num_rows(); + let step_size = lde_trace.lde_step_size; - let steps = offsets + let lde_steps = offsets .iter() - .map(|eval_offset| { - lde_table.step_view((step + (eval_offset * blowup as usize)) % trace_steps) + .map(|offset| { + let initial_step_row = row + offset * step_size; + let end_step_row = initial_step_row + step_size; + let (table_view_main_data, table_view_aux_data) = (initial_step_row..end_step_row) + .step_by(blowup_factor) + .map(|step_row| { + let step_row_idx = step_row % num_rows; + let main_row = lde_trace.get_main_row(step_row_idx); + let aux_row = lde_trace.get_aux_row(step_row_idx); + (main_row, aux_row) + }) + .unzip(); + + TableView::new(table_view_main_data, table_view_aux_data) }) - .collect(); + .collect_vec(); - Self::new(steps) + Frame::new(lde_steps) } -} -impl<'t, E: IsField> Frame<'t, E, E> { - pub fn read_from_ood_table(ood_table: &'t EvaluationTable, offsets: &[usize]) -> Self { - let steps: Vec<_> = offsets + pub fn read_step_from_lde( + lde_trace: &'t LDETraceTable, + step: usize, + offsets: &[usize], + ) -> Self { + let blowup_factor = lde_trace.blowup_factor; + let num_rows = lde_trace.num_rows(); + let step_size = lde_trace.lde_step_size; + let row = lde_trace.step_to_row(step); + + let lde_steps = offsets .iter() - .map(|offset| ood_table.step_view(*offset)) - .collect(); - Self::new(steps) + .map(|offset| { + let initial_step_row = row + offset * step_size; + let end_step_row = initial_step_row + step_size; + let (table_view_main_data, table_view_aux_data) = (initial_step_row..end_step_row) + .step_by(blowup_factor) + .map(|step_row| { + let step_row_idx = step_row % num_rows; + let main_row = lde_trace.get_main_row(step_row_idx); + let aux_row = lde_trace.get_aux_row(step_row_idx); + (main_row, aux_row) + }) + .unzip(); + + TableView::new(table_view_main_data, table_view_aux_data) + }) + .collect_vec(); + + Frame::new(lde_steps) } } diff --git a/provers/stark/src/proof/stark.rs b/provers/stark/src/proof/stark.rs index 98ff14a0a..f593d144d 100644 --- a/provers/stark/src/proof/stark.rs +++ b/provers/stark/src/proof/stark.rs @@ -14,7 +14,7 @@ use crate::{ config::Commitment, domain::Domain, fri::fri_decommit::FriDecommitment, - table::EvaluationTable, + table::Table, traits::AIR, transcript::StoneProverTranscript, verifier::{IsStarkVerifier, Verifier}, @@ -50,7 +50,7 @@ pub struct StarkProof, E: IsField> { // [tⱼ] pub lde_trace_aux_merkle_root: Option, // tⱼ(zgᵏ) - pub trace_ood_evaluations: EvaluationTable, + pub trace_ood_evaluations: Table, // Commitments to Hᵢ pub composition_poly_root: Commitment, // Hᵢ(z^N) @@ -131,10 +131,9 @@ impl StoneCompatibleSerializer { proof: &StarkProof, output: &mut Vec, ) { - for i in 0..proof.trace_ood_evaluations.n_cols() { - for j in 0..proof.trace_ood_evaluations.n_rows() { - output - .extend_from_slice(&proof.trace_ood_evaluations.get_row_main(j)[i].as_bytes()); + for i in 0..proof.trace_ood_evaluations.width { + for j in 0..proof.trace_ood_evaluations.height { + output.extend_from_slice(&proof.trace_ood_evaluations.get_row(j)[i].as_bytes()); } } diff --git a/provers/stark/src/prover.rs b/provers/stark/src/prover.rs index a166ed0b8..bb50d3fc8 100644 --- a/provers/stark/src/prover.rs +++ b/provers/stark/src/prover.rs @@ -20,7 +20,8 @@ use rayon::prelude::{IndexedParallelIterator, IntoParallelRefIterator, ParallelI use crate::debug::validate_trace; use crate::fri; use crate::proof::stark::{DeepPolynomialOpenings, PolynomialOpenings}; -use crate::table::{EvaluationTable, Table}; +use crate::table::Table; +use crate::trace::{columns2rows, LDETraceTable}; use crate::transcript::IsStarkTranscript; use super::config::{BatchedMerkleTree, Commitment}; @@ -68,13 +69,13 @@ where FieldElement: AsBytes + Sync + Send, { /// The table of evaluations over the LDE of the main and auxiliary trace tables. - pub(crate) lde_table: EvaluationTable, + pub(crate) lde_trace: LDETraceTable, /// The intermediate results of the commitment to the main trace table. pub(crate) main: Round1CommitmentData, /// The intermediate results of the commitment to the auxiliary trace table in case of RAP. pub(crate) aux: Option>, /// The challenges of the RAP round. - pub(crate) rap_challenges: A::RAPChallenges, + pub(crate) rap_challenges: Vec>, } impl Round1 @@ -121,7 +122,7 @@ where /// A container for the results of the third round of the STARK Prove protocol. pub struct Round3 { /// Evaluations of the trace polynomials, main ans auxiliary, at the out-of-domain challenge. - trace_ood_evaluations: EvaluationTable, + trace_ood_evaluations: Table, /// Evaluations of the composition polynomial parts at the out-of-domain challenge. composition_poly_parts_ood_evaluation: Vec>, } @@ -214,14 +215,14 @@ pub trait IsStarkProver { let lde_trace_evaluations = Self::compute_lde_trace_evaluations(&trace_polys, domain); let mut lde_trace_permuted = lde_trace_evaluations.clone(); - for col in lde_trace_permuted.iter_mut() { in_place_bit_reverse_permute(col); } // Compute commitment. - let lde_trace = TraceTable::from_columns(lde_trace_permuted, A::STEP_SIZE); - let (lde_trace_merkle_tree, lde_trace_merkle_root) = Self::batch_commit(&lde_trace.rows()); + let lde_trace_permuted_rows = columns2rows(lde_trace_permuted); + let (lde_trace_merkle_tree, lde_trace_merkle_root) = + Self::batch_commit(&lde_trace_permuted_rows); // >>>> Send commitment. transcript.append_bytes(&lde_trace_merkle_root); @@ -300,10 +301,16 @@ pub trait IsStarkProver { } else { (None, Vec::new()) }; - let lde_table = EvaluationTable::from_columns(evaluations, aux_evaluations, A::STEP_SIZE); + + let lde_trace = LDETraceTable::from_columns( + evaluations, + aux_evaluations, + A::STEP_SIZE, + domain.blowup_factor, + ); Ok(Round1 { - lde_table, + lde_trace, main, aux, rap_challenges, @@ -351,7 +358,6 @@ pub trait IsStarkProver { ) -> Round2 where A: Send + Sync, - A::RAPChallenges: Send + Sync, FieldElement: AsBytes + Send + Sync, FieldElement: AsBytes + Send + Sync, { @@ -359,7 +365,7 @@ pub trait IsStarkProver { let evaluator = ConstraintEvaluator::new(air, &round_1_result.rap_challenges); let constraint_evaluations = evaluator.evaluate( air, - &round_1_result.lde_table, + &round_1_result.lde_trace, domain, transition_coefficients, boundary_coefficients, @@ -427,19 +433,19 @@ pub trait IsStarkProver { // // In the fibonacci example, the ood frame is simply the evaluations `[t(z), t(z * g), t(z * g^2)]`, where `t` is the trace // polynomial and `g` is the primitive root of unity used when interpolating `t`. - - let trace_ood_evaluations = crate::trace::get_trace_evaluations( - &round_1_result.main.trace_polys, - round_1_result - .aux - .as_ref() - .map(|aux| &aux.trace_polys) - .unwrap_or(&vec![]), - z, - &air.context().transition_offsets, - &domain.trace_primitive_root, - A::STEP_SIZE, - ); + let trace_ood_evaluations = + crate::trace::get_trace_evaluations::( + &round_1_result.main.trace_polys, + round_1_result + .aux + .as_ref() + .map(|aux| &aux.trace_polys) + .unwrap_or(&vec![]), + z, + &air.context().transition_offsets, + &domain.trace_primitive_root, + A::STEP_SIZE, + ); Round3 { trace_ood_evaluations, @@ -587,7 +593,7 @@ pub trait IsStarkProver { // ∑ ⱼₖ [ 𝛾ₖ ( tⱼ − tⱼ(z) ) / ( X − zgᵏ )] // @@@ this could be const - let trace_frame_length = trace_frame_evaluations.n_rows(); + let trace_frame_length = trace_frame_evaluations.height; #[cfg(feature = "parallel")] let trace_terms = trace_polys @@ -751,7 +757,7 @@ pub trait IsStarkProver { let main_trace_opening = Self::open_trace_polys::( domain, &round_1_result.main.lde_trace_merkle_tree, - &round_1_result.lde_table.main_table, + &round_1_result.lde_trace.main_table, *index, ); @@ -765,7 +771,7 @@ pub trait IsStarkProver { Self::open_trace_polys::( domain, &aux.lde_trace_merkle_tree, - &round_1_result.lde_table.aux_table, + &round_1_result.lde_trace.aux_table, *index, ) }); @@ -791,7 +797,6 @@ pub trait IsStarkProver { ) -> Result, ProvingError> where A: Send + Sync, - A::RAPChallenges: Send + Sync, FieldElement: AsBytes + Send + Sync, FieldElement: AsBytes + Send + Sync, { @@ -997,6 +1002,7 @@ pub trait IsStarkProver { }) } } + #[cfg(test)] mod tests { use std::num::ParseIntError; @@ -1160,7 +1166,7 @@ mod tests { } fn stone_compatibility_case_1_challenges( - ) -> Challenges> { + ) -> Challenges> { let (proof, public_inputs, options, seed) = proof_parts_stone_compatibility_case_1(); let air = Fibonacci2ColsShifted::new(proof.trace_length, &public_inputs, &options); @@ -1237,25 +1243,25 @@ mod tests { let proof = stone_compatibility_case_1_proof(); assert_eq!( - proof.trace_ood_evaluations.get_row_main(0)[0], + proof.trace_ood_evaluations.get_row(0)[0], FieldElement::from_hex_unchecked( "70d8181785336cc7e0a0a1078a79ee6541ca0803ed3ff716de5a13c41684037", ) ); assert_eq!( - proof.trace_ood_evaluations.get_row_main(1)[0], + proof.trace_ood_evaluations.get_row(1)[0], FieldElement::from_hex_unchecked( "29808fc8b7480a69295e4b61600480ae574ca55f8d118100940501b789c1630", ) ); assert_eq!( - proof.trace_ood_evaluations.get_row_main(0)[1], + proof.trace_ood_evaluations.get_row(0)[1], FieldElement::from_hex_unchecked( "7d8110f21d1543324cc5e472ab82037eaad785707f8cae3d64c5b9034f0abd2", ) ); assert_eq!( - proof.trace_ood_evaluations.get_row_main(1)[1], + proof.trace_ood_evaluations.get_row(1)[1], FieldElement::from_hex_unchecked( "1b58470130218c122f71399bf1e04cf75a6e8556c4751629d5ce8c02cc4e62d", ) @@ -1556,7 +1562,7 @@ mod tests { } fn stone_compatibility_case_2_challenges( - ) -> Challenges> { + ) -> Challenges> { let (proof, public_inputs, options, seed) = proof_parts_stone_compatibility_case_2(); let air = Fibonacci2ColsShifted::new(proof.trace_length, &public_inputs, &options); diff --git a/provers/stark/src/table.rs b/provers/stark/src/table.rs index 87d3febc0..54a978a2c 100644 --- a/provers/stark/src/table.rs +++ b/provers/stark/src/table.rs @@ -1,10 +1,9 @@ +use crate::frame::Frame; use lambdaworks_math::field::{ element::FieldElement, traits::{IsField, IsSubFieldOf}, }; -use crate::trace::StepView; - /// A two-dimensional Table holding field elements, arranged in a row-major order. /// This is the basic underlying data structure used for any two-dimensional component in the /// the STARK protocol implementation, such as the `TraceTable` and the `EvaluationFrame`. @@ -17,25 +16,6 @@ pub struct Table { pub height: usize, } -/// A view of a contiguos subset of rows of a table. -#[derive(Clone, Debug, PartialEq, Eq)] -pub struct TableView<'t, F: IsField> { - pub data: &'t [FieldElement], - pub table_row_idx: usize, - pub width: usize, - pub height: usize, -} - -/// A pair of tables corresponding to evaluations of the main and auxiliary traces. -/// It supports main and auxiliary tables taking values in different fields. -/// Both tables must have the same number of rows. -#[derive(Clone, Default, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)] -pub struct EvaluationTable, E: IsField> { - pub(crate) main_table: Table, - pub(crate) aux_table: Table, - pub(crate) step_size: usize, -} - impl<'t, F: IsField> Table { /// Crates a new Table instance from a one-dimensional array in row major order /// and the intended width of the table. @@ -100,20 +80,6 @@ impl<'t, F: IsField> Table { &mut self.data[row_offset..row_offset + n_cols] } - /// Given a row index and a number of rows, returns a view of a subset of contiguous rows - /// of the table, starting from that index. - pub fn table_view(&'t self, from_idx: usize, num_rows: usize) -> TableView<'t, F> { - let from_offset = from_idx * self.width; - let data = &self.data[from_offset..from_offset + self.width * num_rows]; - - TableView { - data, - table_row_idx: from_idx, - width: self.width, - height: num_rows, - } - } - /// Given a slice of field elements representing a row, appends it to /// the end of the table. pub fn append_row(&mut self, row: &[FieldElement]) { @@ -144,158 +110,57 @@ impl<'t, F: IsField> Table { let idx = row * self.width + col; &self.data[idx] } -} - -impl EvaluationTable { - /// Returns a single vector of elements with the concatenation of the corresponding rows - /// in the main and auxiliary tables. - pub fn get_row(&self, row_idx: usize) -> Vec> { - let mut row: Vec<_> = self.get_row_main(row_idx).to_vec(); - row.extend_from_slice(self.get_row_aux(row_idx)); - row - } - - /// Returns the values of the tables as a single list of columns containing both main and - /// auxiliary tables. The first `self.n_main_cols()` are the columns of the main trace and the - /// rest are the auxiliary table columns. - pub fn columns(&self) -> Vec>> { - let mut columns = self.main_table.columns(); - let aux_columns = self.aux_table.columns(); - columns.extend(aux_columns); - columns - } -} - -impl, E: IsField> EvaluationTable { - /// Creates an EvaluationTable instance from a vector of columns. - pub fn from_columns( - main_columns: Vec>>, - aux_columns: Vec>>, - step_size: usize, - ) -> Self { - let main_table = Table::from_columns(main_columns); - let aux_table = Table::from_columns(aux_columns); - debug_assert!(aux_table.height == 0 || (main_table.height == aux_table.height)); - Self { - main_table, - aux_table, - step_size, - } - } - - /// Returns the number of columns of the main table. - pub fn n_main_cols(&self) -> usize { - self.main_table.width - } - - /// Returns the number of columns of the auxiliary table. - pub fn n_aux_cols(&self) -> usize { - self.aux_table.width - } - - /// Returns the total number of columns in both tables. - pub fn n_cols(&self) -> usize { - self.n_main_cols() + self.n_aux_cols() - } - - /// Returns the total number of rows. - pub fn n_rows(&self) -> usize { - debug_assert!( - self.aux_table.height == 0 || (self.main_table.height == self.aux_table.height) - ); - self.main_table.height - } - - /// Returns the total number of steps. - pub fn num_steps(&self) -> usize { - debug_assert!((self.main_table.height % self.step_size) == 0); - debug_assert!( - self.aux_table.height == 0 || (self.main_table.height == self.aux_table.height) - ); - self.main_table.height / self.step_size - } - /// Given a particular step of the computation represented on the trace, - /// returns the row of the underlying table. - pub fn step_to_row(&self, step: usize) -> usize { - self.step_size * step - } + /// Given a step size, converts the given table into a `Frame`. + pub fn into_frame(&'t self, main_trace_columns: usize, step_size: usize) -> Frame<'t, F, F> { + debug_assert!(self.height % step_size == 0); + let steps = (0..self.height) + .step_by(step_size) + .map(|initial_row_idx| { + let end_row_idx = initial_row_idx + step_size; - /// Given a step index, return the step view of the trace for that index - pub fn step_view(&self, step_idx: usize) -> StepView<'_, F, E> { - let row_idx = self.step_to_row(step_idx); - let main_table_view = self.main_table.table_view(row_idx, self.step_size); - let aux_table_view = self.aux_table.table_view(row_idx, self.step_size); + let mut step_main_data: Vec<&'t [FieldElement]> = Vec::new(); + let mut step_aux_data: Vec<&'t [FieldElement]> = Vec::new(); - StepView { - main_table_view, - aux_table_view, - step_idx, - } - } + (initial_row_idx..end_row_idx).for_each(|row_idx| { + let row = self.get_row(row_idx); + step_main_data.push(&row[..main_trace_columns]); + step_aux_data.push(&row[main_trace_columns..]); + }); - /// Given a row and a column index, gives stored value in that position - pub fn get_main(&self, row: usize, col: usize) -> &FieldElement { - self.main_table.get(row, col) - } - - /// Given a row and a column index, gives stored value in that position - pub fn get_aux(&self, row: usize, col: usize) -> &FieldElement { - self.aux_table.get(row, col) - } - - /// Given a row index, returns a reference to that row in the main table as a slice of field elements. - pub fn get_row_main(&self, row_idx: usize) -> &[FieldElement] { - let row_offset = row_idx * self.main_table.width; - &self.main_table.data[row_offset..row_offset + self.main_table.width] - } + TableView::new(step_main_data, step_aux_data) + }) + .collect(); - /// Given a row index, returns a reference to that row in the aux table as a slice of field elements. - pub fn get_row_aux(&self, row_idx: usize) -> &[FieldElement] { - let row_offset = row_idx * self.aux_table.width; - &self.aux_table.data[row_offset..row_offset + self.aux_table.width] + Frame::new(steps) } } -impl<'t, F: IsField> TableView<'t, F> { - pub fn new( - data: &'t [FieldElement], - table_row_idx: usize, - width: usize, - height: usize, - ) -> Self { - Self { - data, - width, - table_row_idx, - height, - } - } +/// A view of a contiguos subset of rows of a table. +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct TableView<'t, F, E> +where + E: IsField, + F: IsSubFieldOf, +{ + pub data: Vec<&'t [FieldElement]>, + pub aux_data: Vec<&'t [FieldElement]>, +} - pub fn get(&self, row: usize, col: usize) -> &FieldElement { - let idx = row * self.width + col; - &self.data[idx] +impl<'t, F, E> TableView<'t, F, E> +where + E: IsField, + F: IsSubFieldOf, +{ + pub fn new(data: Vec<&'t [FieldElement]>, aux_data: Vec<&'t [FieldElement]>) -> Self { + Self { data, aux_data } } - pub fn get_row(&self, row: usize) -> &[FieldElement] { - let first = row * self.width; - &self.data[first..first + self.width] + pub fn get_main_evaluation_element(&self, row: usize, col: usize) -> &FieldElement { + &self.data[row][col] } -} - -#[cfg(test)] -mod test { - use super::*; - use crate::Felt252; - - #[test] - fn get_rows_slice_works() { - let data: Vec = (0..=11).map(Felt252::from).collect(); - let table = Table::new(data, 3); - - let slice = table.table_view(1, 2); - let expected_data: Vec = (3..=8).map(Felt252::from).collect(); - assert_eq!(slice.data, expected_data); + pub fn get_aux_evaluation_element(&self, row: usize, col: usize) -> &FieldElement { + &self.aux_data[row][col] } } diff --git a/provers/stark/src/tests/integration_tests.rs b/provers/stark/src/tests/integration_tests.rs index 9cdafccf6..7febbd28a 100644 --- a/provers/stark/src/tests/integration_tests.rs +++ b/provers/stark/src/tests/integration_tests.rs @@ -4,6 +4,7 @@ use lambdaworks_math::field::{ use crate::{ examples::{ + bit_flags::{self, BitFlagsAIR}, dummy_air::{self, DummyAIR}, fibonacci_2_cols_shifted::{self, Fibonacci2ColsShifted}, fibonacci_2_columns::{self, Fibonacci2ColsAIR}, @@ -21,7 +22,7 @@ use crate::{ #[test_log::test] fn test_prove_fib() { - let trace = simple_fibonacci::fibonacci_trace([Felt252::from(1), Felt252::from(1)], 8); + let trace = simple_fibonacci::fibonacci_trace([Felt252::from(1), Felt252::from(1)], 1024); let proof_options = ProofOptions::default_test_options(); @@ -132,9 +133,7 @@ fn test_prove_simple_periodic_32() { #[test_log::test] fn test_prove_fib_2_cols() { let trace = fibonacci_2_columns::compute_trace([Felt252::from(1), Felt252::from(1)], 16); - let proof_options = ProofOptions::default_test_options(); - let pub_inputs = FibonacciPublicInputs { a0: Felt252::one(), a1: Felt252::one(), @@ -147,6 +146,7 @@ fn test_prove_fib_2_cols() { StoneProverTranscript::new(&[]), ) .unwrap(); + assert!(Verifier::>::verify( &proof, &pub_inputs, @@ -185,7 +185,7 @@ fn test_prove_fib_2_cols_shifted() { #[test_log::test] fn test_prove_quadratic() { - let trace = quadratic_air::quadratic_trace(Felt252::from(3), 4); + let trace = quadratic_air::quadratic_trace(Felt252::from(3), 32); let proof_options = ProofOptions::default_test_options(); @@ -246,6 +246,7 @@ fn test_prove_dummy() { let proof = Prover::::prove(&trace, &(), &proof_options, StoneProverTranscript::new(&[])) .unwrap(); + assert!(Verifier::::verify( &proof, &(), @@ -253,3 +254,20 @@ fn test_prove_dummy() { StoneProverTranscript::new(&[]) )); } + +#[test_log::test] +fn test_prove_bit_flags() { + let trace = bit_flags::bit_prefix_flag_trace(32); + let proof_options = ProofOptions::default_test_options(); + + let proof = + Prover::::prove(&trace, &(), &proof_options, StoneProverTranscript::new(&[])) + .unwrap(); + + assert!(Verifier::::verify( + &proof, + &(), + &proof_options, + StoneProverTranscript::new(&[]), + )); +} diff --git a/provers/stark/src/trace.rs b/provers/stark/src/trace.rs index e7ef297de..b9e3de0cf 100644 --- a/provers/stark/src/trace.rs +++ b/provers/stark/src/trace.rs @@ -1,4 +1,5 @@ -use crate::table::{EvaluationTable, Table, TableView}; +use crate::table::Table; +use itertools::Itertools; use lambdaworks_math::fft::errors::FFTError; use lambdaworks_math::field::traits::{IsField, IsSubFieldOf}; use lambdaworks_math::{ @@ -19,21 +20,59 @@ use rayon::prelude::{IntoParallelRefIterator, ParallelIterator}; pub struct TraceTable { pub table: Table, pub step_size: usize, + pub num_main_columns: usize, + pub num_aux_columns: usize, } impl TraceTable { - pub fn new(data: Vec>, n_columns: usize, step_size: usize) -> Self { - let table = Table::new(data, n_columns); - Self { table, step_size } + pub fn new( + data: Vec>, + num_main_columns: usize, + num_aux_columns: usize, + step_size: usize, + ) -> Self { + let num_columns = num_main_columns + num_aux_columns; + let table = Table::new(data, num_columns); + Self { + table, + num_main_columns, + num_aux_columns, + step_size, + } } - pub fn from_columns(columns: Vec>>, step_size: usize) -> Self { + pub fn from_columns( + columns: Vec>>, + num_main_columns: usize, + step_size: usize, + ) -> Self { + println!("COLUMNS LEN: {}", columns.len()); + println!("NUM MAIN COLUMNS: {}", num_main_columns); + let num_aux_columns = columns.len() - num_main_columns; let table = Table::from_columns(columns); - Self { table, step_size } + Self { + table, + num_main_columns, + num_aux_columns, + step_size, + } + } + + pub fn from_columns_main(columns: Vec>>, step_size: usize) -> Self { + let num_main_columns = columns.len(); + let num_aux_columns = 0; + let table = Table::from_columns(columns); + + Self { + table, + num_main_columns, + num_aux_columns, + step_size, + } } pub fn empty() -> Self { - Self::new(Vec::new(), 0, 0) + Self::new(Vec::new(), 0, 0, 0) } pub fn is_empty(&self) -> bool { @@ -95,10 +134,9 @@ impl TraceTable { data } - pub fn compute_trace_polys>( - &self, - ) -> Vec>> + pub fn compute_trace_polys(&self) -> Vec>> where + S: IsFFTField + IsSubFieldOf, FieldElement: Send + Sync, { let columns = self.columns(); @@ -146,49 +184,90 @@ impl TraceTable { } } } - -/// A view into a step of the trace. In general, a step over the trace -/// can be thought as a fixed size subset of trace rows -/// -/// The main purpose of this data structure is to have a way to -/// access the steps in a trace, in order to grab elements to calculate -/// constraint evaluations. -#[derive(Debug, Clone, PartialEq)] -pub struct StepView<'t, F: IsSubFieldOf, E: IsField> { - pub main_table_view: TableView<'t, F>, - pub aux_table_view: TableView<'t, E>, - pub step_idx: usize, +pub struct LDETraceTable +where + E: IsField, + F: IsSubFieldOf, +{ + pub(crate) main_table: Table, + pub(crate) aux_table: Table, + pub(crate) lde_step_size: usize, + pub(crate) blowup_factor: usize, } -impl<'t, F: IsSubFieldOf, E: IsField> StepView<'t, F, E> { +impl LDETraceTable +where + E: IsField, + F: IsSubFieldOf, +{ pub fn new( - main_table_view: TableView<'t, F>, - aux_table_view: TableView<'t, E>, - step_idx: usize, + main_data: Vec>, + aux_data: Vec>, + n_columns: usize, + trace_step_size: usize, + blowup_factor: usize, + ) -> Self { + let main_table = Table::new(main_data, n_columns); + let aux_table = Table::new(aux_data, n_columns); + let lde_step_size = trace_step_size * blowup_factor; + + Self { + main_table, + aux_table, + lde_step_size, + blowup_factor, + } + } + + pub fn from_columns( + main_columns: Vec>>, + aux_columns: Vec>>, + trace_step_size: usize, + blowup_factor: usize, ) -> Self { - StepView { - main_table_view, - aux_table_view, - step_idx, + let main_table = Table::from_columns(main_columns); + let aux_table = Table::from_columns(aux_columns); + let lde_step_size = trace_step_size * blowup_factor; + + Self { + main_table, + aux_table, + lde_step_size, + blowup_factor, } } - /// Gets the evaluation element of the main table specified by `row_idx` and `col_idx` of this step - pub fn get_main_evaluation_element(&self, row_idx: usize, col_idx: usize) -> &FieldElement { - self.main_table_view.get(row_idx, col_idx) + pub fn num_cols(&self) -> usize { + self.main_table.width + self.aux_table.width } - /// Gets the evaluation element of the aux table specified by `row_idx` and `col_idx` of this step - pub fn get_aux_evaluation_element(&self, row_idx: usize, col_idx: usize) -> &FieldElement { - self.aux_table_view.get(row_idx, col_idx) + pub fn num_rows(&self) -> usize { + self.main_table.height } - pub fn get_row_main(&self, row_idx: usize) -> &[FieldElement] { - self.main_table_view.get_row(row_idx) + pub fn get_main_row(&self, row_idx: usize) -> &[FieldElement] { + self.main_table.get_row(row_idx) } - pub fn get_row_aux(&self, row_idx: usize) -> &[FieldElement] { - self.aux_table_view.get_row(row_idx) + pub fn get_aux_row(&self, row_idx: usize) -> &[FieldElement] { + self.aux_table.get_row(row_idx) + } + + pub fn get_main(&self, row: usize, col: usize) -> &FieldElement { + self.main_table.get(row, col) + } + + pub fn get_aux(&self, row: usize, col: usize) -> &FieldElement { + self.aux_table.get(row, col) + } + + pub fn num_steps(&self) -> usize { + debug_assert!((self.main_table.height % self.lde_step_size) == 0); + self.main_table.height / self.lde_step_size + } + + pub fn step_to_row(&self, step: usize) -> usize { + self.lde_step_size * step } } @@ -198,38 +277,74 @@ impl<'t, F: IsSubFieldOf, E: IsField> StepView<'t, F, E> { /// compute a transition. /// Example: For a simple Fibonacci computation, if t(x) is the trace polynomial of /// the computation, this will output evaluations t(x), t(g * x), t(g^2 * z). -pub(crate) fn get_trace_evaluations, E: IsField>( +pub fn get_trace_evaluations( main_trace_polys: &[Polynomial>], aux_trace_polys: &[Polynomial>], x: &FieldElement, frame_offsets: &[usize], primitive_root: &FieldElement, step_size: usize, -) -> EvaluationTable { - let evaluation_points: Vec<_> = frame_offsets +) -> Table +where + F: IsSubFieldOf, + E: IsField, +{ + let evaluation_points = frame_offsets .iter() - .map(|offset| primitive_root.pow(*offset) * x) - .collect(); - let main_evaluations = main_trace_polys + .flat_map(|offset| { + let exponents_range_start = offset * step_size; + let exponents_range_end = (offset + 1) * step_size; + (exponents_range_start..exponents_range_end).collect_vec() + }) + .map(|exponent| primitive_root.pow(exponent) * x) + .collect_vec(); + + let main_evaluations = evaluation_points .iter() - .map(|poly| { - evaluation_points + .map(|eval_point| { + main_trace_polys .iter() - .map(|eval_point| poly.evaluate(eval_point)) - .collect() + .map(|main_poly| main_poly.evaluate(eval_point)) + .collect_vec() }) - .collect(); - let aux_evaluations = aux_trace_polys + .collect_vec(); + + let aux_evaluations = evaluation_points .iter() - .map(|poly| { - evaluation_points + .map(|eval_point| { + aux_trace_polys .iter() - .map(|eval_point| poly.evaluate(eval_point)) - .collect() + .map(|aux_poly| aux_poly.evaluate(eval_point)) + .collect_vec() }) - .collect(); + .collect_vec(); + + debug_assert_eq!(main_evaluations.len(), aux_evaluations.len()); + let mut main_evaluations = main_evaluations; + let mut table_data = Vec::new(); + for (main_row, aux_row) in main_evaluations.iter_mut().zip(aux_evaluations) { + main_row.extend_from_slice(&aux_row); + table_data.extend_from_slice(main_row); + } + + let main_trace_width = main_trace_polys.len(); + let aux_trace_width = aux_trace_polys.len(); + let table_width = main_trace_width + aux_trace_width; - EvaluationTable::from_columns(main_evaluations, aux_evaluations, step_size) + Table::new(table_data, table_width) +} + +pub fn columns2rows(columns: Vec>>) -> Vec>> { + let num_rows = columns[0].len(); + let num_cols = columns.len(); + + (0..num_rows) + .map(|row_index| { + (0..num_cols) + .map(|col_index| columns[col_index][row_index].clone()) + .collect() + }) + .collect() } #[cfg(test)] @@ -243,7 +358,7 @@ mod test { let col_1 = vec![FE::from(1), FE::from(2), FE::from(5), FE::from(13)]; let col_2 = vec![FE::from(1), FE::from(3), FE::from(8), FE::from(21)]; - let trace_table = TraceTable::from_columns(vec![col_1.clone(), col_2.clone()], 1); + let trace_table = TraceTable::from_columns(vec![col_1.clone(), col_2.clone()], 2, 1); let res_cols = trace_table.columns(); assert_eq!(res_cols, vec![col_1, col_2]); diff --git a/provers/stark/src/traits.rs b/provers/stark/src/traits.rs index 82efa6409..0c6dcb14c 100644 --- a/provers/stark/src/traits.rs +++ b/provers/stark/src/traits.rs @@ -1,6 +1,6 @@ -use itertools::Itertools; +use std::collections::HashMap; + use lambdaworks_math::{ - fft::cpu::roots_of_unity::get_powers_of_primitive_root_coset, field::{ element::FieldElement, traits::{IsFFTField, IsField, IsSubFieldOf}, @@ -8,18 +8,21 @@ use lambdaworks_math::{ polynomial::Polynomial, }; -use crate::transcript::IsStarkTranscript; +use crate::{ + constraints::transition::TransitionConstraint, domain::Domain, transcript::IsStarkTranscript, +}; use super::{ constraints::boundary::BoundaryConstraints, context::AirContext, frame::Frame, proof::options::ProofOptions, trace::TraceTable, }; +type ZerofierGroupKey = (usize, usize, Option, Option, usize); + /// AIR is a representation of the Constraints pub trait AIR { - type Field: IsFFTField + IsSubFieldOf; - type FieldExtension: IsField; - type RAPChallenges; + type Field: IsFFTField + IsSubFieldOf + Send + Sync; + type FieldExtension: IsField + Send + Sync; type PublicInputs; const STEP_SIZE: usize; @@ -32,16 +35,24 @@ pub trait AIR { fn build_auxiliary_trace( &self, - main_trace: &TraceTable, - rap_challenges: &Self::RAPChallenges, - ) -> TraceTable; + _main_trace: &TraceTable, + _rap_challenges: &[FieldElement], + ) -> TraceTable { + TraceTable::empty() + } fn build_rap_challenges( &self, - transcript: &mut impl IsStarkTranscript, - ) -> Self::RAPChallenges; + _transcript: &mut impl IsStarkTranscript, + ) -> Vec> { + Vec::new() + } - fn number_auxiliary_rap_columns(&self) -> usize; + fn trace_layout(&self) -> (usize, usize); + + fn num_auxiliary_rap_columns(&self) -> usize { + self.trace_layout().1 + } fn composition_poly_degree_bound(&self) -> usize; @@ -52,8 +63,21 @@ pub trait AIR { &self, frame: &Frame, periodic_values: &[FieldElement], - rap_challenges: &Self::RAPChallenges, - ) -> Vec>; + rap_challenges: &[FieldElement], + ) -> Vec> { + let mut evaluations = + vec![FieldElement::::zero(); self.num_transition_constraints()]; + self.transition_constraints() + .iter() + .for_each(|c| c.evaluate(frame, &mut evaluations, periodic_values, rap_challenges)); + + evaluations + } + + fn boundary_constraints( + &self, + rap_challenges: &[FieldElement], + ) -> BoundaryConstraints; /// The method called by the verifier to evaluate the transitions at the out of domain frame. /// In the case of the verifier, both main and auxiliary tables of the evaluation frame take @@ -65,45 +89,9 @@ pub trait AIR { &self, frame: &Frame, periodic_values: &[FieldElement], - rap_challenges: &Self::RAPChallenges, + rap_challenges: &[FieldElement], ) -> Vec>; - fn boundary_constraints( - &self, - rap_challenges: &Self::RAPChallenges, - ) -> BoundaryConstraints; - - fn transition_exemptions(&self) -> Vec>> { - let trace_length = self.trace_length(); - let roots_of_unity_order = trace_length.trailing_zeros(); - let roots_of_unity = get_powers_of_primitive_root_coset( - roots_of_unity_order as u64, - self.trace_length(), - &FieldElement::::one(), - ) - .unwrap(); - let root_of_unity_len = roots_of_unity.len(); - - let x = Polynomial::new_monomial(FieldElement::one(), 1); - - self.context() - .transition_exemptions - .iter() - .unique_by(|elem| *elem) - .filter(|v| *v > &0_usize) - .map(|cant_take| { - roots_of_unity - .iter() - .take(root_of_unity_len) - .rev() - .take(*cant_take) - .fold( - Polynomial::new_monomial(FieldElement::one(), 0), - |acc, root| acc * (&x - root), - ) - }) - .collect() - } fn context(&self) -> &AirContext; fn trace_length(&self) -> usize; @@ -116,35 +104,23 @@ pub trait AIR { self.options().blowup_factor } + fn coset_offset(&self) -> FieldElement { + FieldElement::from(self.options().coset_offset) + } + + fn trace_primitive_root(&self) -> FieldElement { + let trace_length = self.trace_length(); + let root_of_unity_order = u64::from(trace_length.trailing_zeros()); + + Self::Field::get_primitive_root_of_unity(root_of_unity_order).unwrap() + } + fn num_transition_constraints(&self) -> usize { self.context().num_transition_constraints } fn pub_inputs(&self) -> &Self::PublicInputs; - fn transition_exemptions_verifier( - &self, - root: &FieldElement, - ) -> Vec>> { - let x = - Polynomial::>::new_monomial(FieldElement::one(), 1); - - let max = self - .context() - .transition_exemptions - .iter() - .max() - .expect("has maximum"); - (1..=*max) - .map(|index| { - (1..=index).fold( - Polynomial::new_monomial(FieldElement::one(), 0), - |acc, k| acc * (&x - root.pow(k).to_extension()), - ) - }) - .collect() - } - fn get_periodic_column_values(&self) -> Vec>> { vec![] } @@ -165,4 +141,48 @@ pub trait AIR { } result } + + fn transition_constraints( + &self, + ) -> &Vec>>; + + /// Computes the unique zerofier evaluations for all transitions constraints. + /// Returns a vector of vectors, where each inner vector contains the unique zerofier evaluations for a given constraint + fn transition_zerofier_evaluations( + &self, + domain: &Domain, + ) -> Vec>> { + let mut evals = vec![Vec::new(); self.num_transition_constraints()]; + + let mut zerofier_groups: HashMap>> = + HashMap::new(); + + self.transition_constraints().iter().for_each(|c| { + let period = c.period(); + let offset = c.offset(); + let exemptions_period = c.exemptions_period(); + let periodic_exemptions_offset = c.periodic_exemptions_offset(); + let end_exemptions = c.end_exemptions(); + + // This hashmap is used to avoid recomputing with an fft the same zerofier evaluation + // If there are multiple domain and subdomains it can be further optimized + // as to share computation between them + + let zerofier_group_key = ( + period, + offset, + exemptions_period, + periodic_exemptions_offset, + end_exemptions, + ); + zerofier_groups + .entry(zerofier_group_key) + .or_insert_with(|| c.zerofier_evaluations_on_extended_domain(domain)); + + let zerofier_evaluations = zerofier_groups.get(&zerofier_group_key).unwrap(); + evals[c.constraint_idx()] = zerofier_evaluations.clone(); + }); + + evals + } } diff --git a/provers/stark/src/verifier.rs b/provers/stark/src/verifier.rs index 046f09b4d..daef144a5 100644 --- a/provers/stark/src/verifier.rs +++ b/provers/stark/src/verifier.rs @@ -1,16 +1,15 @@ -use std::marker::PhantomData; -#[cfg(feature = "instruments")] -use std::time::Instant; - -use lambdaworks_crypto::merkle_tree::proof::Proof; -//use itertools::multizip; -#[cfg(not(feature = "test_fiat_shamir"))] -use log::error; - +use super::{ + config::BatchedMerkleTreeBackend, + domain::Domain, + fri::fri_decommit::FriDecommitment, + grinding, + proof::{options::ProofOptions, stark::StarkProof}, + traits::AIR, +}; use crate::{ - config::Commitment, frame::Frame, proof::stark::DeepPolynomialOpening, - transcript::IsStarkTranscript, + config::Commitment, proof::stark::DeepPolynomialOpening, transcript::IsStarkTranscript, }; +use lambdaworks_crypto::merkle_tree::proof::Proof; use lambdaworks_math::{ fft::cpu::bit_reversing::reverse_index, field::{ @@ -19,15 +18,11 @@ use lambdaworks_math::{ }, traits::AsBytes, }; - -use super::{ - config::BatchedMerkleTreeBackend, - domain::Domain, - fri::fri_decommit::FriDecommitment, - grinding, - proof::{options::ProofOptions, stark::StarkProof}, - traits::AIR, -}; +#[cfg(not(feature = "test_fiat_shamir"))] +use log::error; +use std::marker::PhantomData; +#[cfg(feature = "instruments")] +use std::time::Instant; /// A default STARK verifier implementing `IsStarkVerifier`. pub struct Verifier { @@ -38,27 +33,26 @@ impl IsStarkVerifier for Verifier {} /// A container holding the complete list of challenges sent to the prover along with the seed used /// to validate the proof-of-work nonce. -pub struct Challenges +pub struct Challenges where - F: IsField, - A: AIR, + A: AIR, { /// The out-of-domain challenge. - pub z: FieldElement, + pub z: FieldElement, /// The composition polynomial coefficients corresponding to the boundary constraints terms. - pub boundary_coeffs: Vec>, + pub boundary_coeffs: Vec>, /// The composition polynomial coefficients corresponding to the transition constraints terms. - pub transition_coeffs: Vec>, + pub transition_coeffs: Vec>, /// The deep composition polynomial coefficients corresponding to the trace polynomial terms. - pub trace_term_coeffs: Vec>>, + pub trace_term_coeffs: Vec>>, /// The deep composition polynomial coefficients corresponding to the composition polynomial parts terms. - pub gammas: Vec>, + pub gammas: Vec>, /// The list of FRI commit phase folding challenges. - pub zetas: Vec>, + pub zetas: Vec>, /// The list of FRI query phase index challenges. pub iotas: Vec, /// The challenges used to build the auxiliary trace. - pub rap_challenges: A::RAPChallenges, + pub rap_challenges: Vec>, /// The seed used to verify the proof-of-work nonce. pub grinding_seed: [u8; 32], } @@ -85,7 +79,7 @@ pub trait IsStarkVerifier { proof: &StarkProof, domain: &Domain, transcript: &mut impl IsStarkTranscript, - ) -> Challenges + ) -> Challenges where FieldElement: AsBytes, FieldElement: AsBytes, @@ -223,7 +217,7 @@ pub trait IsStarkVerifier { air: &A, proof: &StarkProof, domain: &Domain, - challenges: &Challenges, + challenges: &Challenges, ) -> bool { let boundary_constraints = air.boundary_constraints(&challenges.rap_challenges); @@ -239,11 +233,12 @@ pub trait IsStarkVerifier { let step = boundary_constraints.constraints[index].step; let is_aux = boundary_constraints.constraints[index].is_aux; let point = &domain.trace_primitive_root.pow(step as u64); - let trace_idx = boundary_constraints.constraints[index].col; + let column_idx = boundary_constraints.constraints[index].col; let trace_evaluation = if is_aux { - &proof.trace_ood_evaluations.get_row_aux(0)[trace_idx] + let column_idx = air.trace_layout().0 + column_idx; + &proof.trace_ood_evaluations.get_row(0)[column_idx] } else { - &proof.trace_ood_evaluations.get_row_main(0)[trace_idx] + &proof.trace_ood_evaluations.get_row(0)[column_idx] }; let boundary_zerofier_challenges_z_den = -point + &challenges.z; @@ -275,39 +270,32 @@ pub trait IsStarkVerifier { .map(|poly| poly.evaluate(&challenges.z)) .collect::>>(); + let num_main_trace_columns = + proof.trace_ood_evaluations.width - air.num_auxiliary_rap_columns(); + + let ood_frame = + (proof.trace_ood_evaluations).into_frame(num_main_trace_columns, A::STEP_SIZE); let transition_ood_frame_evaluations = air.compute_transition_verifier( - &Frame::read_from_ood_table( - &proof.trace_ood_evaluations, - &air.context().transition_offsets, - ), + &ood_frame, &periodic_values, &challenges.rap_challenges, ); - let denominator = (-FieldElement::::one() + &challenges.z.pow(trace_length)) - .inv() - .unwrap(); - - let exemption = air - .transition_exemptions_verifier( - domain.trace_roots_of_unity.iter().last().expect("has last"), - ) - .iter() - .map(|poly| poly.evaluate(&challenges.z)) - .collect::>>(); - - let unity = &FieldElement::one(); - let transition_c_i_evaluations_sum = transition_ood_frame_evaluations - .iter() - .zip(&air.context().transition_exemptions) - .zip(&challenges.transition_coeffs) - .fold(FieldElement::zero(), |acc, ((eval, except), beta)| { - let except = except - .checked_sub(1) - .map(|i| &exemption[i]) - .unwrap_or(unity); - acc + eval * &denominator * beta * except - }); + let mut denominators = + vec![FieldElement::::zero(); air.num_transition_constraints()]; + air.transition_constraints().iter().for_each(|c| { + denominators[c.constraint_idx()] = + c.evaluate_zerofier(&challenges.z, &domain.trace_primitive_root, trace_length); + }); + + let transition_c_i_evaluations_sum = itertools::izip!( + transition_ood_frame_evaluations, + &challenges.transition_coeffs, + denominators + ) + .fold(FieldElement::zero(), |acc, (eval, beta, denominator)| { + acc + beta * eval * &denominator + }); let composition_poly_ood_evaluation = &boundary_quotient_ood_evaluation + transition_c_i_evaluations_sum; @@ -329,7 +317,7 @@ pub trait IsStarkVerifier { fn step_3_verify_fri( proof: &StarkProof, domain: &Domain, - challenges: &Challenges, + challenges: &Challenges, ) -> bool where FieldElement: AsBytes + Sync + Send, @@ -347,6 +335,7 @@ pub trait IsStarkVerifier { .map(|iota| Self::query_challenge_to_evaluation_point(*iota, domain)) .collect::>>(); FieldElement::inplace_batch_inverse(&mut evaluation_point_inverse).unwrap(); + proof .query_list .iter() @@ -486,7 +475,7 @@ pub trait IsStarkVerifier { /// index challenges. fn step_4_verify_trace_and_composition_openings( proof: &StarkProof, - challenges: &Challenges, + challenges: &Challenges, ) -> bool where FieldElement: AsBytes + Sync + Send, @@ -615,7 +604,7 @@ pub trait IsStarkVerifier { } fn reconstruct_deep_composition_poly_evaluations_for_all_queries( - challenges: &Challenges, + challenges: &Challenges, domain: &Domain, proof: &StarkProof, ) -> DeepPolynomialEvaluations { @@ -675,26 +664,27 @@ pub trait IsStarkVerifier { proof: &StarkProof, evaluation_point: &FieldElement, primitive_root: &FieldElement, - challenges: &Challenges, + challenges: &Challenges, lde_trace_evaluations: &[FieldElement], lde_composition_poly_parts_evaluation: &[FieldElement], ) -> FieldElement { - let mut denoms_trace = (0..proof.trace_ood_evaluations.n_rows()) + let mut denoms_trace = (0..proof.trace_ood_evaluations.height) .map(|row_idx| evaluation_point - primitive_root.pow(row_idx as u64) * &challenges.z) .collect::>>(); FieldElement::inplace_batch_inverse(&mut denoms_trace).unwrap(); - let trace_term = (0..proof.trace_ood_evaluations.n_cols()) + let trace_term = (0..proof.trace_ood_evaluations.width) .zip(&challenges.trace_term_coeffs) .fold(FieldElement::zero(), |trace_terms, (col_idx, coeff_row)| { - let trace_i = (0..proof.trace_ood_evaluations.n_rows()) - .zip(coeff_row) - .fold(FieldElement::zero(), |trace_t, (row_idx, coeff)| { + let trace_i = (0..proof.trace_ood_evaluations.height).zip(coeff_row).fold( + FieldElement::zero(), + |trace_t, (row_idx, coeff)| { let poly_evaluation = (lde_trace_evaluations[col_idx].clone() - proof.trace_ood_evaluations.get_row(row_idx)[col_idx].clone()) * &denoms_trace[row_idx]; trace_t + &poly_evaluation * coeff - }); + }, + ); trace_terms + trace_i }); diff --git a/winterfell_adapter/Cargo.toml b/winterfell_adapter/Cargo.toml index 833cbd5f7..00ed4d150 100644 --- a/winterfell_adapter/Cargo.toml +++ b/winterfell_adapter/Cargo.toml @@ -5,8 +5,8 @@ edition.workspace = true license.workspace = true [dependencies] -lambdaworks-math = { path = "../math", features=["winter_compatibility"] } -stark-platinum-prover = { path = "../provers/stark" , features=["winter_compatibility"]} +lambdaworks-math = { git = "https://github.com/lambdaclass/lambdaworks", rev = "3da725de1e6f76c04ddbb3ccb67e6038a7663134", features = ["winter_compatibility"] } +stark-platinum-prover = { git = "https://github.com/lambdaclass/lambdaworks" , rev = "3da725de1e6f76c04ddbb3ccb67e6038a7663134", features = ["winter_compatibility"] } rand = "0.8.5" winter-air = { package = "winter-air", version = "0.6.4", default-features = false } winter-prover = { package = "winter-prover", version = "0.6.4", default-features = false }