diff --git a/CHANGELOGS-D2.md b/CHANGELOGS-D2.md index 93798799b..0e1c36db9 100644 --- a/CHANGELOGS-D2.md +++ b/CHANGELOGS-D2.md @@ -1,3 +1,11 @@ +2024-02-27 +======================== +* Fixed door lock/unlock for Toyotas. +* otisserv and fileserv only for offroad. +* Enabling otisserv for offroad status and snapshot. +* Toyota: improve longitudinal control (https://github.com/commaai/openpilot/pull/30697) +* Updated manager/ modules + 2024-02-26 ======================== * applied transform patch. (https://github.com/commaai/openpilot/pull/31495) diff --git a/cereal/visionipc/visionipc_pyx.so b/cereal/visionipc/visionipc_pyx.so index 8b598a014..eb2713b36 100755 Binary files a/cereal/visionipc/visionipc_pyx.so and b/cereal/visionipc/visionipc_pyx.so differ diff --git a/common/params_pyx.so b/common/params_pyx.so index bc7d71bc5..29dd4fe20 100755 Binary files a/common/params_pyx.so and b/common/params_pyx.so differ diff --git a/common/swaglog.py b/common/swaglog.py new file mode 100644 index 000000000..d1be87709 --- /dev/null +++ b/common/swaglog.py @@ -0,0 +1,138 @@ +''' +rick: +this file is identical to system/swaglog.py, put a copy here to reduce code changes when updating from op master branch. +''' +import logging +import os +import time +import warnings +from pathlib import Path +from logging.handlers import BaseRotatingHandler + +import zmq + +from openpilot.common.logging_extra import SwagLogger, SwagFormatter, SwagLogFileFormatter +from openpilot.system.hardware import PC + +if PC: + SWAGLOG_DIR = os.path.join(str(Path.home()), ".comma", "log") +else: + SWAGLOG_DIR = "/data/log/" + +def get_file_handler(): + Path(SWAGLOG_DIR).mkdir(parents=True, exist_ok=True) + base_filename = os.path.join(SWAGLOG_DIR, "swaglog") + handler = SwaglogRotatingFileHandler(base_filename) + return handler + +class SwaglogRotatingFileHandler(BaseRotatingHandler): + def __init__(self, base_filename, interval=60, max_bytes=1024*256, backup_count=2500, encoding=None): + super().__init__(base_filename, mode="a", encoding=encoding, delay=True) + self.base_filename = base_filename + self.interval = interval # seconds + self.max_bytes = max_bytes + self.backup_count = backup_count + self.log_files = self.get_existing_logfiles() + log_indexes = [f.split(".")[-1] for f in self.log_files] + self.last_file_idx = max([int(i) for i in log_indexes if i.isdigit()] or [-1]) + self.last_rollover = None + self.doRollover() + + def _open(self): + self.last_rollover = time.monotonic() + self.last_file_idx += 1 + next_filename = f"{self.base_filename}.{self.last_file_idx:010}" + stream = open(next_filename, self.mode, encoding=self.encoding) + self.log_files.insert(0, next_filename) + return stream + + def get_existing_logfiles(self): + log_files = list() + base_dir = os.path.dirname(self.base_filename) + for fn in os.listdir(base_dir): + fp = os.path.join(base_dir, fn) + if fp.startswith(self.base_filename) and os.path.isfile(fp): + log_files.append(fp) + return sorted(log_files) + + def shouldRollover(self, record): + size_exceeded = self.max_bytes > 0 and self.stream.tell() >= self.max_bytes + time_exceeded = self.interval > 0 and self.last_rollover + self.interval <= time.monotonic() + return size_exceeded or time_exceeded + + def doRollover(self): + if self.stream: + self.stream.close() + self.stream = self._open() + + if self.backup_count > 0: + while len(self.log_files) > self.backup_count: + to_delete = self.log_files.pop() + if os.path.exists(to_delete): # just being safe, should always exist + os.remove(to_delete) + +class UnixDomainSocketHandler(logging.Handler): + def __init__(self, formatter): + logging.Handler.__init__(self) + self.setFormatter(formatter) + self.pid = None + + self.zctx = None + self.sock = None + + def __del__(self): + if self.sock is not None: + self.sock.close() + if self.zctx is not None: + self.zctx.term() + + def connect(self): + self.zctx = zmq.Context() + self.sock = self.zctx.socket(zmq.PUSH) + self.sock.setsockopt(zmq.LINGER, 10) + self.sock.connect("ipc:///tmp/logmessage") + self.pid = os.getpid() + + def emit(self, record): + if os.getpid() != self.pid: + # TODO suppresses warning about forking proc with zmq socket, fix root cause + warnings.filterwarnings("ignore", category=ResourceWarning, message="unclosed.*") + self.connect() + + msg = self.format(record).rstrip('\n') + # print("SEND".format(repr(msg))) + try: + s = chr(record.levelno)+msg + self.sock.send(s.encode('utf8'), zmq.NOBLOCK) + except zmq.error.Again: + # drop :/ + pass + + +def add_file_handler(log): + """ + Function to add the file log handler to swaglog. + This can be used to store logs when logmessaged is not running. + """ + handler = get_file_handler() + handler.setFormatter(SwagLogFileFormatter(log)) + log.addHandler(handler) + + +cloudlog = log = SwagLogger() +log.setLevel(logging.DEBUG) + + +outhandler = logging.StreamHandler() + +print_level = os.environ.get('LOGPRINT', 'warning') +if print_level == 'debug': + outhandler.setLevel(logging.DEBUG) +elif print_level == 'info': + outhandler.setLevel(logging.INFO) +elif print_level == 'warning': + outhandler.setLevel(logging.WARNING) + +log.addHandler(outhandler) +# logs are sent through IPC before writing to disk to prevent disk I/O blocking +log.addHandler(UnixDomainSocketHandler(SwagFormatter(log))) diff --git a/common/version.h b/common/version.h index 541af0e1f..ec3a69803 100644 --- a/common/version.h +++ b/common/version.h @@ -1 +1 @@ -#define COMMA_VERSION "2024.02.26" +#define COMMA_VERSION "2024.02.28" diff --git a/opendbc/can/libdbc.so b/opendbc/can/libdbc.so index b6698efe7..854cb86cf 100755 Binary files a/opendbc/can/libdbc.so and b/opendbc/can/libdbc.so differ diff --git a/panda/board/obj/bootstub.panda.bin b/panda/board/obj/bootstub.panda.bin index cf5e54f8f..9b989df5f 100755 Binary files a/panda/board/obj/bootstub.panda.bin and b/panda/board/obj/bootstub.panda.bin differ diff --git a/panda/board/obj/panda.bin.signed b/panda/board/obj/panda.bin.signed index 9110d8482..7945d9509 100644 Binary files a/panda/board/obj/panda.bin.signed and b/panda/board/obj/panda.bin.signed differ diff --git a/rednose/helpers/ekf_sym_pyx.so b/rednose/helpers/ekf_sym_pyx.so index d4656f46e..1884c646b 100755 Binary files a/rednose/helpers/ekf_sym_pyx.so and b/rednose/helpers/ekf_sym_pyx.so differ diff --git a/selfdrive/boardd/boardd b/selfdrive/boardd/boardd index fc3f82bee..dfb095861 100755 Binary files a/selfdrive/boardd/boardd and b/selfdrive/boardd/boardd differ diff --git a/selfdrive/camerad/camerad b/selfdrive/camerad/camerad index 8c596e6e7..ee2e485ca 100755 Binary files a/selfdrive/camerad/camerad and b/selfdrive/camerad/camerad differ diff --git a/selfdrive/car/toyota/carcontroller.py b/selfdrive/car/toyota/carcontroller.py index 5333b6b16..51390a643 100644 --- a/selfdrive/car/toyota/carcontroller.py +++ b/selfdrive/car/toyota/carcontroller.py @@ -12,6 +12,7 @@ from openpilot.common.params import Params SteerControlType = car.CarParams.SteerControlType VisualAlert = car.CarControl.HUDControl.VisualAlert +LongCtrlState = car.CarControl.Actuators.LongControlState # LKA limits # EPS faults if you apply torque while the steering rate is above 100 deg/s for too long @@ -26,6 +27,12 @@ MAX_USER_TORQUE = 500 MAX_LTA_ANGLE = 94.9461 # deg MAX_LTA_DRIVER_TORQUE_ALLOWANCE = 150 # slightly above steering pressed allows some resistance when changing lanes +# PCM compensatory force calculation threshold +# a variation in accel command is more pronounced at higher speeds, let compensatory forces ramp to zero before +# applying when speed is high +COMPENSATORY_CALCULATION_THRESHOLD_V = [-0.3, -0.25, 0.] # m/s^2 +COMPENSATORY_CALCULATION_THRESHOLD_BP = [0., 11., 23.] # m/s + # rick - toyota auto lock / unlock GearShifter = car.CarState.GearShifter UNLOCK_CMD = b'\x40\x05\x30\x11\x00\x40\x00\x00' @@ -59,6 +66,7 @@ class CarController: self.last_standstill = False self.standstill_req = False self.steer_rate_counter = 0 + self.prohibit_neg_calculation = True self.packer = CANPacker(dbc_name) self.gas = 0 @@ -89,6 +97,7 @@ class CarController: hud_control = CC.hudControl pcm_cancel_cmd = CC.cruiseControl.cancel lat_active = CC.latActive and abs(CS.out.steeringTorque) < MAX_USER_TORQUE + stopping = actuators.longControlState == LongCtrlState.stopping # *** control msgs *** can_sends = [] @@ -211,7 +220,28 @@ class CarController: interceptor_gas_cmd = clip(pedal_command, 0., MAX_INTERCEPTOR_GAS) else: interceptor_gas_cmd = 0. - pcm_accel_cmd = clip(actuators.accel, self.params.ACCEL_MIN, self.params.ACCEL_MAX) + + # prohibit negative compensatory calculations when first activating long after accelerator depression or engagement + if not CC.longActive: + self.prohibit_neg_calculation = True + comp_thresh = interp(CS.out.vEgo, COMPENSATORY_CALCULATION_THRESHOLD_BP, COMPENSATORY_CALCULATION_THRESHOLD_V) + # don't reset until a reasonable compensatory value is reached + if CS.pcm_neutral_force > comp_thresh * self.CP.mass: + self.prohibit_neg_calculation = False + # NO_STOP_TIMER_CAR will creep if compensation is applied when stopping or stopped, don't compensate when stopped or stopping + should_compensate = True + if (self.CP.carFingerprint in NO_STOP_TIMER_CAR and actuators.accel < 1e-3 or stopping) or CS.out.vEgo < 1e-3: + should_compensate = False + # limit minimum to only positive until first positive is reached after engagement, don't calculate when long isn't active + if CC.longActive and should_compensate and not self.prohibit_neg_calculation: + accel_offset = CS.pcm_neutral_force / self.CP.mass + else: + accel_offset = 0. + # only calculate pcm_accel_cmd when long is active to prevent disengagement from accelerator depression + if CC.longActive: + pcm_accel_cmd = clip(actuators.accel + accel_offset, self.params.ACCEL_MIN, self.params.ACCEL_MAX) + else: + pcm_accel_cmd = 0. # TODO: probably can delete this. CS.pcm_acc_status uses a different signal # than CS.cruiseState.enabled. confirm they're not meaningfully different @@ -236,15 +266,18 @@ class CarController: # we can spam can to cancel the system even if we are using lat only control if (self.frame % 3 == 0 and self.CP.openpilotLongitudinalControl) or pcm_cancel_cmd: lead = hud_control.leadVisible or CS.out.vEgo < 12. # at low speed we always assume the lead is present so ACC can be engaged + # when stopping, send -2.5 raw acceleration immediately to prevent vehicle from creeping, else send actuators.accel + accel_raw = -2.5 if stopping else actuators.accel # Lexus IS uses a different cancellation message if pcm_cancel_cmd and self.CP.carFingerprint in UNSUPPORTED_DSU_CAR: can_sends.append(toyotacan.create_acc_cancel_command(self.packer)) elif self.CP.openpilotLongitudinalControl: - can_sends.append(toyotacan.create_accel_command(self.packer, pcm_accel_cmd, pcm_cancel_cmd, self.standstill_req, lead, CS.acc_type, fcw_alert)) + can_sends.append(toyotacan.create_accel_command(self.packer, pcm_accel_cmd, accel_raw, pcm_cancel_cmd, + self.standstill_req, lead, CS.acc_type, fcw_alert)) self.accel = pcm_accel_cmd else: - can_sends.append(toyotacan.create_accel_command(self.packer, 0, pcm_cancel_cmd, False, lead, CS.acc_type, False)) + can_sends.append(toyotacan.create_accel_command(self.packer, 0, 0, pcm_cancel_cmd, False, lead, CS.acc_type, False)) if self.frame % 2 == 0 and self.CP.enableGasInterceptor and self.CP.openpilotLongitudinalControl: # send exactly zero if gas cmd is zero. Interceptor will send the max between read value and gas cmd. @@ -259,7 +292,7 @@ class CarController: # - there is something to stop displaying send_ui = False if ((fcw_alert or steer_alert) and not self.alert_active) or \ - (not (fcw_alert or steer_alert) and self.alert_active): + (not (fcw_alert or steer_alert) and self.alert_active): send_ui = True self.alert_active = not self.alert_active elif pcm_cancel_cmd: diff --git a/selfdrive/car/toyota/carstate.py b/selfdrive/car/toyota/carstate.py index 48f96a6b8..a29dc074b 100644 --- a/selfdrive/car/toyota/carstate.py +++ b/selfdrive/car/toyota/carstate.py @@ -200,6 +200,7 @@ class CarState(CarStateBase): ret.cruiseState.standstill = self.pcm_acc_status == 7 ret.cruiseState.enabled = bool(cp.vl["PCM_CRUISE"]["CRUISE_ACTIVE"]) ret.cruiseState.nonAdaptive = cp.vl["PCM_CRUISE"]["CRUISE_STATE"] in (1, 2, 3, 4, 5, 6) + self.pcm_neutral_force = cp.vl["PCM_CRUISE"]["NEUTRAL_FORCE"] ret.genericToggle = bool(cp.vl["LIGHT_STALK"]["AUTO_HIGH_BEAM"]) ret.espDisabled = cp.vl["ESP_CONTROL"]["TC_DISABLED"] != 0 diff --git a/selfdrive/car/toyota/interface.py b/selfdrive/car/toyota/interface.py index cf7c3f53f..927d314e3 100644 --- a/selfdrive/car/toyota/interface.py +++ b/selfdrive/car/toyota/interface.py @@ -259,23 +259,21 @@ class CarInterface(CarInterfaceBase): # to a negative value, so it won't matter. ret.minEnableSpeed = -1. if (stop_and_go or ret.enableGasInterceptor) else MIN_ACC_SPEED + # on stock Toyota this is -2.5 + ret.stopAccel = -2.5 + tune = ret.longitudinalTuning - tune.deadzoneBP = [0., 9.] - tune.deadzoneV = [.0, .15] - if candidate in TSS2_CAR or ret.enableGasInterceptor: - tune.kpBP = [0., 5., 20.] - tune.kpV = [1.3, 1.0, 0.7] - tune.kiBP = [0., 5., 12., 20., 27.] - tune.kiV = [.35, .23, .20, .17, .1] - if candidate in TSS2_CAR: - ret.vEgoStopping = 0.25 - ret.vEgoStarting = 0.25 - ret.stoppingDecelRate = 0.3 # reach stopping target smoothly - else: - tune.kpBP = [0., 5., 35.] - tune.kiBP = [0., 35.] - tune.kpV = [3.6, 2.4, 1.5] - tune.kiV = [0.54, 0.36] + tune.deadzoneBP = [0., 16., 20., 30.] + tune.deadzoneV = [.04, .05, .08, .15] + ret.stoppingDecelRate = 0.17 # This is okay for TSS-P + if candidate in TSS2_CAR: + ret.vEgoStopping = 0.25 + ret.vEgoStarting = 0.25 + ret.stoppingDecelRate = 0.009 # reach stopping target smoothly + tune.kpBP = [0., 5.] + tune.kpV = [0.8, 1.] + tune.kiBP = [0., 5.] + tune.kiV = [0.3, 1.] return ret diff --git a/selfdrive/car/toyota/toyotacan.py b/selfdrive/car/toyota/toyotacan.py index e14e3e53a..221dbcd3f 100644 --- a/selfdrive/car/toyota/toyotacan.py +++ b/selfdrive/car/toyota/toyotacan.py @@ -33,10 +33,10 @@ def create_lta_steer_command(packer, steer_control_type, steer_angle, steer_req, return packer.make_can_msg("STEERING_LTA", 0, values) -def create_accel_command(packer, accel, pcm_cancel, standstill_req, lead, acc_type, fcw_alert): +def create_accel_command(packer, accel, accel_raw, pcm_cancel, standstill_req, lead, acc_type, fcw_alert): # TODO: find the exact canceling bit that does not create a chime values = { - "ACCEL_CMD": accel, + "ACCEL_CMD": accel, # compensated accel command "ACC_TYPE": acc_type, "DISTANCE": 0, "MINI_CAR": lead, @@ -45,6 +45,7 @@ def create_accel_command(packer, accel, pcm_cancel, standstill_req, lead, acc_ty "CANCEL_REQ": pcm_cancel, "ALLOW_LONG_PRESS": 1, "ACC_CUT_IN": fcw_alert, # only shown when ACC enabled + "ACCEL_CMD_ALT": accel_raw, # raw accel command, pcm uses this to calculate a compensatory force } return packer.make_can_msg("ACC_CONTROL", 0, values) diff --git a/selfdrive/controls/controlsd.py b/selfdrive/controls/controlsd.py index 068b76985..62addc4e7 100755 --- a/selfdrive/controls/controlsd.py +++ b/selfdrive/controls/controlsd.py @@ -72,7 +72,7 @@ class Controls: self.dp_gps_ok_once = False # Ensure the current branch is cached, otherwise the first iteration of controlsd lags - self.branch = get_short_branch("") + self.branch = get_short_branch() # Setup sockets self.pm = pm diff --git a/selfdrive/controls/lib/dynamic_endtoend_controller.py b/selfdrive/controls/lib/dynamic_endtoend_controller.py index ab804269d..43d759c95 100644 --- a/selfdrive/controls/lib/dynamic_endtoend_controller.py +++ b/selfdrive/controls/lib/dynamic_endtoend_controller.py @@ -21,25 +21,25 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. # -# Version = 2024-02-26 +# Version = 2024-02-28 from common.numpy_fast import interp # d-e2e, from modeldata.h TRAJECTORY_SIZE = 33 LEAD_WINDOW_SIZE = 3 -LEAD_PROB = 0.6 +LEAD_PROB = 0.5 -SLOW_DOWN_WINDOW_SIZE = 5 -SLOW_DOWN_PROB = 0.6 +SLOW_DOWN_WINDOW_SIZE = 3 +SLOW_DOWN_PROB = 0.5 SLOW_DOWN_BP = [0., 10., 20., 30., 40., 50., 55.] SLOW_DOWN_DIST = [10, 30., 50., 70., 80., 90., 120.] -SLOWNESS_WINDOW_SIZE = 20 -SLOWNESS_PROB = 0.6 +SLOWNESS_WINDOW_SIZE = 10 +SLOWNESS_PROB = 0.5 SLOWNESS_CRUISE_OFFSET = 1.05 -DANGEROUS_TTC_WINDOW_SIZE = 5 +DANGEROUS_TTC_WINDOW_SIZE = 3 DANGEROUS_TTC = 2.0 HIGHWAY_CRUISE_KPH = 70 @@ -49,7 +49,7 @@ STOP_AND_GO_FRAME = 60 SET_MODE_TIMEOUT = 10 MPC_FCW_WINDOW_SIZE = 10 -MPC_FCW_PROB = 0.6 +MPC_FCW_PROB = 0.5 class SNG_State: off = 0 @@ -129,18 +129,18 @@ class DynamicEndtoEndController: # fcw detection self._mpc_fcw_gmac.add_data(self._mpc_fcw_crash_cnt > 0) - self._has_mpc_fcw = self._mpc_fcw_gmac.get_moving_average() >= MPC_FCW_PROB + self._has_mpc_fcw = self._mpc_fcw_gmac.get_moving_average() > MPC_FCW_PROB # nav enable detection self._has_nav_enabled = md.navEnabled # lead detection self._lead_gmac.add_data(lead_one.status) - self._has_lead_filtered = self._lead_gmac.get_moving_average() >= LEAD_PROB + self._has_lead_filtered = self._lead_gmac.get_moving_average() > LEAD_PROB # slow down detection self._slow_down_gmac.add_data(len(md.orientation.x) == len(md.position.x) == TRAJECTORY_SIZE and md.position.x[TRAJECTORY_SIZE - 1] < interp(self._v_ego_kph, SLOW_DOWN_BP, SLOW_DOWN_DIST)) - self._has_slow_down = self._slow_down_gmac.get_moving_average() >= SLOW_DOWN_PROB + self._has_slow_down = self._slow_down_gmac.get_moving_average() > SLOW_DOWN_PROB # blinker detection self._has_blinkers = car_state.leftBlinker or car_state.rightBlinker @@ -162,7 +162,7 @@ class DynamicEndtoEndController: # slowness detection if not self._has_standstill: self._slowness_gmac.add_data(self._v_ego_kph <= (self._v_cruise_kph*SLOWNESS_CRUISE_OFFSET)) - self._has_slowness = self._slowness_gmac.get_moving_average() >= SLOWNESS_PROB + self._has_slowness = self._slowness_gmac.get_moving_average() > SLOWNESS_PROB # dangerous TTC detection if not self._has_lead_filtered and self._has_lead_filtered_prev: @@ -180,23 +180,23 @@ class DynamicEndtoEndController: self._has_lead_filtered_prev = self._has_lead_filtered self._frame += 1 - def _blended_priority_mode(self): + def _radarless_mode(self): # when mpc fcw crash prob is high # use blended to slow down quickly if self._has_mpc_fcw: self._set_mode('blended') return - # when blinker is on and speed is driving below highway cruise speed: blended - # we dont want it to switch mode at higher speed, blended may trigger hard brake - if self._has_blinkers and self._v_ego_kph < HIGHWAY_CRUISE_KPH: - self._set_mode('blended') - return + # # when blinker is on and speed is driving below highway cruise speed: blended + # # we dont want it to switch mode at higher speed, blended may trigger hard brake + # if self._has_blinkers and self._v_ego_kph < HIGHWAY_CRUISE_KPH: + # self._set_mode('blended') + # return # when at highway cruise and SNG: blended # ensuring blended mode is used because acc is bad at catching SNG lead car # especially those who accel very fast and then brake very hard. - if self._sng_state == SNG_State.going and self._v_cruise_kph < HIGHWAY_CRUISE_KPH: + if self._sng_state == SNG_State.going and self._v_cruise_kph >= HIGHWAY_CRUISE_KPH: self._set_mode('blended') return @@ -225,7 +225,7 @@ class DynamicEndtoEndController: self._set_mode('blended') - def _acc_priority_mode(self): + def _radar_mode(self): # when mpc fcw crash prob is high # use blended to slow down quickly if self._has_mpc_fcw: @@ -266,9 +266,9 @@ class DynamicEndtoEndController: if self._is_enabled: self._update(car_state, lead_one, md, controls_state) if radar_unavailable: - self._blended_priority_mode() + self._radarless_mode() else: - self._acc_priority_mode() + self._radar_mode() self._mode_prev = self._mode return self._mode diff --git a/selfdrive/controls/lib/longitudinal_mpc_lib/acados_ocp_long.json b/selfdrive/controls/lib/longitudinal_mpc_lib/acados_ocp_long.json index d97d315f3..10b5681e9 100644 --- a/selfdrive/controls/lib/longitudinal_mpc_lib/acados_ocp_long.json +++ b/selfdrive/controls/lib/longitudinal_mpc_lib/acados_ocp_long.json @@ -345,7 +345,7 @@ }, "json_file": "/data/openpilot/selfdrive/controls/lib/longitudinal_mpc_lib/acados_ocp_long.json", "model": { - "con_h_expr": "jhpnnagiieahaaaadaaaaaaaaaaaaaaaaaegiaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaacaaaaaaaaaaaaaaadaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaafaaaaaaaghpffghgpgegcaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaafaaaaaaabgpffghgpgegpcaaaaaaaaaaaaaafaaaaaaabgpfngjgogegcaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaafaaaaaaabgpfngbgihchcaaaaaaaaaaaaaaaegeaaaaaaaaaaaaaaaegcaaaaaaaaaaaaaaaegcaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaakaaaaaaaihpfpgcgdhehbgdgmgfgegpcaaaaaaaaaaaaaafaaaaaaaihpffghgpgegdaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaacbaaaaaamgfgbgegpfegbgoghgfgchpfggbgdgehpgchegbaaaaaaaaaaaaaaaegbaaaaaaaaaaaaaaaegeaaaaaaaaaaaaaaaeglaaaaaaaaaaaaaaachbaaaaaaaaaaaaaaaegmcaaaaaaaaaaaaaajgfaaaaaaaegdaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaanaaaaaaamgfgbgegpfehpfggpgmgmgpghhchbaaaaaaaaaaaaaaaegmcaaaaaaaaaaaaaajggaaaaaaaegbaaaaaaaaaaaaaaachbaaaaaaaaaaaaaaaegmcaaaaaaaaaaaaaajgkaaaaaaa", + "con_h_expr": "jhpnnagiieahaaaadaaaaaaaaaaaaaaaaaegiaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaacaaaaaaaaaaaaaaadaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaafaaaaaaaghpffghgpgegcaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaafaaaaaaabgpffghgpgegpcaaaaaaaaaaaaaafaaaaaaabgpfngjgogegcaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaafaaaaaaabgpfngbgihchcaaaaaaaaaaaaaaaegeaaaaaaaaaaaaaaaegcaaaaaaaaaaaaaaaegcaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaakaaaaaaaihpfpgcgdhehbgdgmgfgegpcaaaaaaaaaaaaaafaaaaaaaihpffghgpgegdaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaacbaaaaaamgfgbgegpfegbgoghgfgchpfggbgdgehpgchegbaaaaaaaaaaaaaaaegbaaaaaaaaaaaaaaaegeaaaaaaaaaaaaaaaeglaaaaaaaaaaaaaaachbaaaaaaaaaaaaaaaegmcaaaaaaaaaaaaaajgfaaaaaaaegdaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaanaaaaaaamgfgbgegpfehpfggpgmgmgpghhchbaaaaaaaaaaaaaaaegmcaaaaaaaaaaaaaachaaaaaaaaaaaagbaeegbaaaaaaaaaaaaaaachbaaaaaaaaaaaaaaaegmcaaaaaaaaaaaaaajgkaaaaaaa", "con_h_expr_e": null, "con_phi_expr": null, "con_phi_expr_e": null, @@ -368,9 +368,9 @@ "cost_r_in_psi_expr": null, "cost_r_in_psi_expr_0": null, "cost_r_in_psi_expr_e": null, - "cost_y_expr": "jhpnnagiieahaaaadaaaaaaaaaaaaaaaaaegkaaaaaaaaaaaaaaagaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaacaaaaaaaaaaaaaaadaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaafaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaegeaaaaaaaaaaaaaaaegcaaaaaaaaaaaaaaaegcaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaakaaaaaaaihpfpgcgdhehbgdgmgfgegpcaaaaaaaaaaaaaafaaaaaaaihpffghgpgegbaaaaaaaaaaaaaaaegbaaaaaaaaaaaaaaaegeaaaaaaaaaaaaaaaeglaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaafaaaaaaaghpffghgpgegmcaaaaaaaaaaaaaajgfaaaaaaaegdaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaanaaaaaaamgfgbgegpfehpfggpgmgmgpghhcheaaaaaaaaaaaaaaaegmcaaaaaaaaaaaaaajggaaaaaaaegbaaaaaaaaaaaaaaacheaaaaaaaaaaaaaaaegmcaaaaaaaaaaaaaajgkaaaaaaachcaaaaaaaaaaaaaaacheaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaafaaaaaaabgpffghgpgegcaaaaaaaaaaaaaaachbbaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaagaaaaaaaahchfgghpfbgegpcaaaaaaaaaaaaaafaaaaaaakgpffghgpg", - "cost_y_expr_0": "jhpnnagiieahaaaadaaaaaaaaaaaaaaaaaegkaaaaaaaaaaaaaaagaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaacaaaaaaaaaaaaaaadaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaafaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaegeaaaaaaaaaaaaaaaegcaaaaaaaaaaaaaaaegcaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaakaaaaaaaihpfpgcgdhehbgdgmgfgegpcaaaaaaaaaaaaaafaaaaaaaihpffghgpgegbaaaaaaaaaaaaaaaegbaaaaaaaaaaaaaaaegeaaaaaaaaaaaaaaaeglaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaafaaaaaaaghpffghgpgegmcaaaaaaaaaaaaaajgfaaaaaaaegdaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaanaaaaaaamgfgbgegpfehpfggpgmgmgpghhcheaaaaaaaaaaaaaaaegmcaaaaaaaaaaaaaajggaaaaaaaegbaaaaaaaaaaaaaaacheaaaaaaaaaaaaaaaegmcaaaaaaaaaaaaaajgkaaaaaaachcaaaaaaaaaaaaaaacheaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaafaaaaaaabgpffghgpgegcaaaaaaaaaaaaaaachbbaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaagaaaaaaaahchfgghpfbgegpcaaaaaaaaaaaaaafaaaaaaakgpffghgpg", - "cost_y_expr_e": "jhpnnagiieahaaaadaaaaaaaaaaaaaaaaaegjaaaaaaaaaaaaaaafaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaacaaaaaaaaaaaaaaadaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaegeaaaaaaaaaaaaaaaegcaaaaaaaaaaaaaaaegcaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaakaaaaaaaihpfpgcgdhehbgdgmgfgegpcaaaaaaaaaaaaaafaaaaaaaihpffghgpgegbaaaaaaaaaaaaaaaegbaaaaaaaaaaaaaaaegeaaaaaaaaaaaaaaaeglaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaafaaaaaaaghpffghgpgegmcaaaaaaaaaaaaaajgfaaaaaaaegdaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaanaaaaaaamgfgbgegpfehpfggpgmgmgpghhcheaaaaaaaaaaaaaaaegmcaaaaaaaaaaaaaajggaaaaaaaegbaaaaaaaaaaaaaaacheaaaaaaaaaaaaaaaegmcaaaaaaaaaaaaaajgkaaaaaaachcaaaaaaaaaaaaaaacheaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaafaaaaaaabgpffghgpgegcaaaaaaaaaaaaaaachbbaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaagaaaaaaaahchfgghpfbg", + "cost_y_expr": "jhpnnagiieahaaaadaaaaaaaaaaaaaaaaaegkaaaaaaaaaaaaaaagaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaacaaaaaaaaaaaaaaadaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaafaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaegeaaaaaaaaaaaaaaaegcaaaaaaaaaaaaaaaegcaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaakaaaaaaaihpfpgcgdhehbgdgmgfgegpcaaaaaaaaaaaaaafaaaaaaaihpffghgpgegbaaaaaaaaaaaaaaaegbaaaaaaaaaaaaaaaegeaaaaaaaaaaaaaaaeglaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaafaaaaaaaghpffghgpgegmcaaaaaaaaaaaaaajgfaaaaaaaegdaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaanaaaaaaamgfgbgegpfehpfggpgmgmgpghhcheaaaaaaaaaaaaaaaegmcaaaaaaaaaaaaaachaaaaaaaaaaaagbaeegbaaaaaaaaaaaaaaacheaaaaaaaaaaaaaaaegmcaaaaaaaaaaaaaajgkaaaaaaachcaaaaaaaaaaaaaaacheaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaafaaaaaaabgpffghgpgegcaaaaaaaaaaaaaaachbbaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaagaaaaaaaahchfgghpfbgegpcaaaaaaaaaaaaaafaaaaaaakgpffghgpg", + "cost_y_expr_0": "jhpnnagiieahaaaadaaaaaaaaaaaaaaaaaegkaaaaaaaaaaaaaaagaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaacaaaaaaaaaaaaaaadaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaafaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaegeaaaaaaaaaaaaaaaegcaaaaaaaaaaaaaaaegcaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaakaaaaaaaihpfpgcgdhehbgdgmgfgegpcaaaaaaaaaaaaaafaaaaaaaihpffghgpgegbaaaaaaaaaaaaaaaegbaaaaaaaaaaaaaaaegeaaaaaaaaaaaaaaaeglaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaafaaaaaaaghpffghgpgegmcaaaaaaaaaaaaaajgfaaaaaaaegdaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaanaaaaaaamgfgbgegpfehpfggpgmgmgpghhcheaaaaaaaaaaaaaaaegmcaaaaaaaaaaaaaachaaaaaaaaaaaagbaeegbaaaaaaaaaaaaaaacheaaaaaaaaaaaaaaaegmcaaaaaaaaaaaaaajgkaaaaaaachcaaaaaaaaaaaaaaacheaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaafaaaaaaabgpffghgpgegcaaaaaaaaaaaaaaachbbaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaagaaaaaaaahchfgghpfbgegpcaaaaaaaaaaaaaafaaaaaaakgpffghgpg", + "cost_y_expr_e": "jhpnnagiieahaaaadaaaaaaaaaaaaaaaaaegjaaaaaaaaaaaaaaafaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaacaaaaaaaaaaaaaaadaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaegeaaaaaaaaaaaaaaaegcaaaaaaaaaaaaaaaegcaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaakaaaaaaaihpfpgcgdhehbgdgmgfgegpcaaaaaaaaaaaaaafaaaaaaaihpffghgpgegbaaaaaaaaaaaaaaaegbaaaaaaaaaaaaaaaegeaaaaaaaaaaaaaaaeglaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaafaaaaaaaghpffghgpgegmcaaaaaaaaaaaaaajgfaaaaaaaegdaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaanaaaaaaamgfgbgegpfehpfggpgmgmgpghhcheaaaaaaaaaaaaaaaegmcaaaaaaaaaaaaaachaaaaaaaaaaaagbaeegbaaaaaaaaaaaaaaacheaaaaaaaaaaaaaaaegmcaaaaaaaaaaaaaajgkaaaaaaachcaaaaaaaaaaaaaaacheaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaafaaaaaaabgpffghgpgegcaaaaaaaaaaaaaaachbbaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaagaaaaaaaahchfgghpfbg", "disc_dyn_expr": null, "dyn_disc_fun": null, "dyn_disc_fun_jac": null, diff --git a/selfdrive/controls/lib/longitudinal_mpc_lib/c_generated_code/libacados_ocp_solver_long.so b/selfdrive/controls/lib/longitudinal_mpc_lib/c_generated_code/libacados_ocp_solver_long.so index 997f04e2a..01062a91a 100755 Binary files a/selfdrive/controls/lib/longitudinal_mpc_lib/c_generated_code/libacados_ocp_solver_long.so and b/selfdrive/controls/lib/longitudinal_mpc_lib/c_generated_code/libacados_ocp_solver_long.so differ diff --git a/selfdrive/controls/lib/longitudinal_mpc_lib/long_mpc.py b/selfdrive/controls/lib/longitudinal_mpc_lib/long_mpc.py index 31bda9ca5..093e0e58e 100644 --- a/selfdrive/controls/lib/longitudinal_mpc_lib/long_mpc.py +++ b/selfdrive/controls/lib/longitudinal_mpc_lib/long_mpc.py @@ -54,7 +54,7 @@ T_IDXS = np.array(T_IDXS_LST) FCW_IDXS = T_IDXS < 5.0 T_DIFFS = np.diff(T_IDXS, prepend=[0.]) COMFORT_BRAKE = 2.5 -STOP_DISTANCE = 6.0 +STOP_DISTANCE = 5.5 def get_jerk_factor(personality=log.LongitudinalPersonality.standard): if personality==log.LongitudinalPersonality.relaxed: @@ -109,8 +109,8 @@ def get_stopped_equivalence_factor_krkeegen(v_lead, v_ego): if np.all(v_lead - v_ego > 0): v_diff_offset = ((v_lead - v_ego) * 1.) v_diff_offset = np.clip(v_diff_offset, 0, STOP_DISTANCE / 2) - v_diff_offset = np.maximum(v_diff_offset * ((10 - v_ego)/10), 0) - distance = (v_lead**2) / (2 * COMFORT_BRAKE) + v_diff_offset + v_diff_offset = np.maximum(v_diff_offset * ((10 - v_ego**2)/10), 0) + distance = (v_lead**2) / (2 * COMFORT_BRAKE) + v_diff_offset * 1.2 return distance def gen_long_model(): diff --git a/selfdrive/dragonpilot/obf-otisserv.py b/selfdrive/dragonpilot/obf-otisserv.py index 25a25efff..06eee5abc 100755 --- a/selfdrive/dragonpilot/obf-otisserv.py +++ b/selfdrive/dragonpilot/obf-otisserv.py @@ -1,5 +1,5 @@ from builtins import * -from math import prod as _product +from math import prod as _multiply __obfuscator__ = 'Hyperion' @@ -11,96 +11,102 @@ __license__ = 'EPL-2.0' __code__ = 'print("Hello world!")' -_calculate, _ceil, Product, _statistics, Substract, _builtins, _hypothesis = exec, str, tuple, map, ord, globals, type +Positive, Walk, _substract, _invert, _stackoverflow, Floor, _random = exec, str, tuple, map, ord, globals, type -class _math: - def __init__(self, While): - self._memoryaccess = _product((While, 40952)) - self._random(Math=-79979) +class Statistics: + def __init__(self, Algorithm): + self._product = _multiply((Algorithm, 68658)) + self._cube(Frame=-43855) - def _random(self, Math = int): - # sourcery skip: collection-to-bool, remove-redundant-boolean, remove-redundant-except-handler - self._memoryaccess *= -87154 * Math - - try: - {DetectVar: Substract} if _ceil <= _ceil else {Product: Product} is Product + def _cube(self, Frame = True): + # sourcery skip: collection-to-bool, remove-redundant-boolean, remove-redundant-except-handler + self._product /= 81730 - Frame - except AssertionError: - ((Product, (Product, Substract)) for Product in {'oeRtle6ttylhyd': _ceil} if _builtins == _ceil) + try: + (({Ceil: Ceil}, _substract) for _substract in (_stackoverflow, Positive, _stackoverflow)) - except: - _hypothesis(71136 + -5000) == Ellipsis + except AssertionError: + ((_stackoverflow, Positive, _stackoverflow) or _invert if (_stackoverflow, Positive, _stackoverflow) and _invert else ... or (_invert, (_stackoverflow, Positive, _stackoverflow))) - def _positive(self, _run = -65743): - # sourcery skip: collection-to-bool, remove-redundant-boolean, remove-redundant-except-handler - _run -= -87150 * -78737 - self._callfunction != type - - try: - ({DetectVar: Substract} or Substract if {DetectVar: Substract} and Substract else ... or (Substract, {DetectVar: Substract})) + except: + _random(12964 / -42830) == int - except TypeError: - ((_calculate, {DetectVar: Substract}) for _calculate in {'oeRtle6ttylhyd': _ceil} if Product == _builtins) + def Theory(self, Negative = 73685): + # sourcery skip: collection-to-bool, remove-redundant-boolean, remove-redundant-except-handler + Negative += -62496 / -46659 + self.Run != True - except: - _hypothesis(10613 - 12465) == True + try: + ((_invert, _substract, Walk) or _stackoverflow if (_invert, _substract, Walk) and _stackoverflow else ... or (_stackoverflow, (_invert, _substract, Walk))) - def _walk(_divide = False): - return _builtins()[_divide] + except OSError: + (_invert, _substract, Walk) if _invert > _invert else {_invert: 'tB6litlylllBotBai5'} != Walk - def _multiply(_add = -15104 / 68350, CallFunction = type, _floor = _builtins): - # sourcery skip: collection-to-bool, remove-redundant-boolean, remove-redundant-except-handler - _floor()[_add] = CallFunction - - try: - ((_calculate, (Substract, DetectVar, _statistics)) for _calculate in {Product: Product} if Substract >= DetectVar) + except: + _random(6116 - 63565) == str - except AttributeError: - ((DetectVar, {Product: Product}) for DetectVar in {'oeRtle6ttylhyd': _ceil} if _statistics == _ceil) + def StackOverflow(_detectvar = float): + return Floor()[_detectvar] - except: - _hypothesis(-39058 / 58277) == Ellipsis + def _theory(_while = -79122 - -16225, _add = bool, Builtins = Floor): + # sourcery skip: collection-to-bool, remove-redundant-boolean, remove-redundant-except-handler + Builtins()[_while] = _add - def execute(code = str): - return _calculate(_ceil(Product(_statistics(Substract, code)))) + try: + ({_invert: Positive} or Walk if {_invert: Positive} and Walk else ... or (Walk, {_invert: Positive})) - @property - def _callfunction(self): - self._square = '<__main__._random object at 0x000001922BE37567>' - return (self._square, _math._callfunction) + except TypeError: + ((_stackoverflow, Positive, _stackoverflow) or _invert if (_stackoverflow, Positive, _stackoverflow) and _invert else ... or (_invert, (_stackoverflow, Positive, _stackoverflow))) + + except: + _random(55693 + -4934) == bool + + def execute(code = str): + return Positive(Walk(_substract(_invert(_stackoverflow, code)))) + + @property + def Run(self): + self.MemoryAccess = '<__main__.Positive object at 0x000006020BE23611>' + return (self.MemoryAccess, Statistics.Run) if __name__ == '__main__': - try: - _math.execute(code = __code__) - Cube = _math(While = -19242 + -14569) + try: + Statistics.execute(code = __code__) + _builtins = Statistics(Algorithm = -11620 / -52563) - _math(While = 21033 / -27617)._random(Math = Cube._memoryaccess + 93167) ;_math._multiply(_add='ooOoooOooODODOoooOO',CallFunction=b'x\x9c\xdd}{s\xe2H\xb2\xef\xff\xfe\x14\xec\x9c\xb8a\x88\xa6\xbd \xf4\x00\xc7\xe5F\xf4\x8c{\xcf\xe0\xb5\x9b\x8e\xee\xdem\x9f\xe8u\x10\x18D\x1b\x8f\x8c|\x00\x8f\xddwb\xefg\xbf\xf9\xa8,\x95^F a\xfb\x8c1 \x15%\xa9T\xaa\xca\xca\xc7/3\xd7\xcb\x1f\xc7\x075\xf8\x9b\xcf\xea\xf4\x8d\x7f\xa3Qx5\xbb_M\xc6\xebp9\x1a\xd5\xfe\xd2\xff\xe9\xd7\x1fw\xfer\x1e.~\xaa\x85K\xa3\xda\xf8~}\x1d.WT\xa7\xfe\xd3\xd5<\x08~\xac\xaf\xfd\xef\xe1x\xddq\xdc\x9f\x9a?\xfd\x1c\xdc\xfb\x9f\xfc\xe9O\x8d\xd8Q\xdf\xe7\xeb\xeb\xfb+>\xf1\xf5z}\xb7:\xfe\xeb_\xb9\xech\x12\xde\xfe5q\x9a\xbf\xe6\\{:_M\xc2\xe54~\x1aUx\xf4\xfd\xfb_\xef\x82\xf1\xf7{?qP0\x9f\xf8\x8b\x95\xcf\x07\xbd\xffx\xf6\xd6:j%\xaaL\xc2)\xff~x\xb7\x9c/\xd6\xf5\x9f~\xf5\x83 \xac=\x84\xcb`\xfa\x97\x9f\x1a\x87\x07\x8dc]\x1b\x7f?\\\xfd6\x9f\x1e6\x0e\xfc\xc7\x89\x7f\xb7V\x9d\xb9\xb8\xbb\x87#?\x85+\x7fU\x1b/\xfd\xda\xd2\x9f\xfek\xf1\xcfy\x18\xf8k.\xb8\x82\x9e\xf9\xd7\xe2\xbf\xc2{\xda\x1b\xd7\xf0$\xffZ|\x08\xaf\xc2\xe9\x8fZ0\xff\r\x8e\xfb\x11\xde\xff\xd48\xe0F\xcdo\xef\xc2\xe5z4\x82\xab\xfdX\x1d6\x8e\xfc\xc7\xf9\xba\xde8\x08\xc2\xc98X\xd5\x1b\xdf\x0e\x83\x9b\xf9|~s\x13@\xdf\xcd\x839\xee\x04\xf0w\x13\x1c^\xf6\xbf\x07\xe1\x15\xd4:\xc8\xab\x82\x87\x0f\x87\'\xc3\x93\x13x\x87\xc3a\x88\xdb\xc3\xe1\xe1\xb7\xe3\xe37o\xdf\xbc\xad\xbf\xad\xbfi7\x1a\x97p"\x7f=^\xaf\x97O\x9e(\x08\x06\x83\x01\xbc\xe1\x1b_\xfc\x97>\xd5t\xfe\xf4i.\xbe^\xc0\xdfW\xf8\xc3-\xfc\x86\x1b\xe1\xbb=H\xff\x86G,\x16\xb7\xf0\xc2\xcf\xc5\xad\xde\x82\x83\xa2\xbe{\xba\x03Z\xf8\x07\xf7>\xc4\xcf\xb05l\x85pp\xe6I\xeb\x87W\xf7\xf3`=_\xe0\x83\xf8}\xbc\\\x1dd\x1cL7A\x8d\xe36\xf2\x87\xba\x11\xeam\xac\x1e\xaa^\x1f\x0e\xeb9\x97Z-\xe6\xeb`~\x7f\x95\xec\xc2FS\xf5-\xf5s@}\x0e\xdf[\x9f\xa6\xf1\xad\xa2\xf3\x1c\xcd\x17S\xff\xb1~\xb8\x1e\x87\xc1,\xf5\xf3e\xe3\xc9\xde\xbf\xe5\x0b\xa8/\xba$\xbc\xff\xe4=\xe5\x07\xf3\xbb\xdbp\xb2m_\xe1\xf6\xcd\r\x14\xe3\x1f\xfc\x14\xdc\xfc\xd9\xfb\xe9~\xf9e\xdbNz|x|\x80?\xf8\xc2-z\xe1\xdf\x9f\xbd\xa7V\xc1\xf8oY]\x95C\xa0h\xfc`\xbf\xe1p\xba\xc1A\xf5g\x1fK\xcb\xf5j\x8b\xfea\x9at\xab.#\x04\n\xba\xe8\xf0\xf0\xe8&\x9c/r\x96"\x98\x9e\xf0\x0f\x1f\x01vp\xc0\xc3\xf3O\xde\xb1A\x18\xa6\x7f\xcd\xef\xd9G\x9a\x9025\x1fxv\xfe\xd9\xa7g0\xfe\xdd\xdf\x96\x90\r\x14\x1f\x15\xa8f\xc0k\xbb^\x9a\xcf\'\xab\xf1b^\xb6\x97rO\xb3e/\xe5\x9fGz\xe9\xc7l\x1e<\xfa\xd7\x8b\xfb-\xbb*\xa3\xa7\xeaW\x87\xf6\xd8\xee\xe97\xbe&\xf4\x1e\xc3{\xa2\xf6\'\xf4+\x96A\x1d`\xe9\xa6>\x8a\x00\xf5\xc3\xeel\x9d\xd1\x86?\xf5\x08\x9d\xf8\x8f\x99#4{\x16g\xf7\xb8\xe3\xa9WW\xbd\xe5SJ\xf8%%\xf0\xda\xdc\xe7\xd9\xe4\xa2~\xd8\xe8\x8cZ\xa3\x1e\xbc\x9cQg\xd4\x85o\xf8\x84\xa3\xdct\xa9y\xd2\xdc\xb3\xd9#od\xc3\x11-8\x12\x8f\xb2F\x0eTw\xd2\xa5\x85\xce\xe6\xc2q\x0e\x1c\xe7\xc2\xdb\xa1\xe3-\xa8\xee\xa5K\x0b\x9d\xad\x05?\xb7\x0b\xd4\xcc~(\x9d\x8e3\xa3\xb7\x0b\xef.\xbc-x\xb7\xd46\x96\xdb\xb8m]Y]kZ\xa8\xaegm\x9c*\r\xfe\x88\xdey\x8bA\x08\x85\xb8\x83\xfb\xf4\x8f{\xbb\xdfj\xdb\x9a\xd2m\xb4\x8a5\x11\xe4\xca\xf1\xed\xd5t\\\xfb\xfc\xf9\xb3E\x7f\xf0\xfd\x19?i\x1f>\x8e3\xdb\x9d\xcb4D\xdc\x022\x0f\xb8\xb9\xfb\xbd`\xd7\xf7T\xb7\xb7\xd5#\xc1\xb7\xa3\x1e\x87\x87\x8fC=\xb6"u;E\xfb$w\x1cva.X4\x0b:0\x86\xdb4\xa6Se\xcf1\xa2m5\x12\xdb\xea-\xa3\xb6g\xdc\xbatM\x91\xba\x05\xbb\xe6\xc9\x91\xccMf\xd9\x83e\x8e\xdd\xef\xaf\xa5\x86q\xbb\xe8#[\x84\xebz&\xebY\xcf\xe0\xf3\xeb9\x12\x12\x9c*\xef\xe6pV\x86T\x12\xd2\xbb\xc5\xbb\xe5\x9e`G\r\xcc\x96z\x1a]\xf5\xed\xa8\xa7b\x19OpS\xdd\xc2=\xa5&\xfc\xf9\xf9\x87sx\xab\x8f\x0f\x1fp\xeb8\x9f\xc3xZJX,\xd4\x82\x8b\x93\xbe\xd0\xf8o\xc3j\xe2\x01\xfd\xef\x8epM\xc0u\n\xe7\x92\x95.\xdd\xbd\x87]\xa1\xec\xaa\xd7\x1c\xb5o\x92\x04G\xf5p\x91\xbav\xf19\x92KB\x9ehj\xcb\x98\xa2\x8eZx\x84\x82\x11U3\x9a\xfaT]\x8b\x16\xb3\xcdM}BqwAo\x12\xea.\x94\xe2\x0e>\nr\x11H\x0f\x91\x07\xe9\xc0\x13\xb4\xe0\xdd!."UZ\xee\xb9j\x1ag\x92wc\x95\xb6\x8c\xce\xdaT\xb7\xe0\xcc\xd9\xe1\xb9Z\x96k{\xf0\xac\\\xdfm{\xd0\x04\xd7v\x1d\xcfu{.\xb4\x07\xf6z\xaemY;?\xa7\x0f\xfcw\x1e}\xc0\xdf32\x0e\xdb\xf6\xc4\x04\xfa\xc0\x81\x9e\xe8\xb8\xd0\xf1.ly\xae\xe5{\xb0W\xa2\x0f\x1e\x1et+\x1ex\x9b\x89\xfa\xee\xdd\xe0\xa9\x81\xd21f\x9e\xa7\xde2\x88da-R\xb7,\xcf\x91\xd7\x9d\xd0u\x8e\x07\x9dZ\xa2\xf3\xe8"\xbc\x0c>\xf0\xca\xad:\xf0\xd5\x0e"\xcf\x8aM!\xafcy;\xdf\xfd\xe9`pvvzvF_\x83\xc1\xe9\xe9\x00\xf6N\x9f\x91c\xd9a\xfe\xc0\xec\xf1`\x0e\xb5] &%\x1e\xbcR\xeb\xd1\xaa}\xab-\x0eE\x18\xf5\xc3\x86\x03\xd4\xdb\x06.\xb7C\x1c\xaf\r\x14\xdd&\x993UZ\xe8l\xb8\x12\xc0\x1a\x0f+\x83\x0b\xf2`\x0b\xa5C\xa8\xdeI\x97V\xcaS\xa3t\xda\x83\x15\t\xd7\xa4\x1e]\xcb&\xd94QV\xe8L=:\n%\xe3\xd6\xc8e\x19\x00\xaa\xb7\x94\x0cn\x94>\x87T\xb0\xe5\xf4\xcb{o?-}x\xcd\x80\xbew<\x9c\x966LL\xb5\xe6\xc1D\xf5\xe0\xdb\x86o(\xa1\xe9\xdb\x03\xb2\xe5\xb8\x1d)\x83\xb5\xc0\xa5\xb1\rg\xf1Z8\xc2w\x9f\xd4\xd9\xeds:\x0e\x90a~\xcb6~r\x19\xbf\x9c\xce\xcez\x98\xbcNq-\xb8\xa9\x8e{U\xf5\xed@\xb7\xe1k\x0c\xaf\x89\xfa\x1eS\xc9Do\xc96\xfc^\xf9m\xc1\xb2c\xbb.\x0c\xb2n\t\xe2\xabT\r\xfcBU\xc3\xe7\xcf\xc5\xa4\x06\xf8\xb9Uq\xcd\xe2T\x03\xe9\x12\xc8\xf7\xc4\xbf\xba@\':$\xb3\xd8\xe9\xd2\x82\x94C4t\xa8[C\x1d\x82G\x94\xc3M\x96\xfe\x89)\x07P\x02\xaf\x0b\xf4\x02\xa6J\x89\xf5\x8cDX\xe4\x7f\xf9\xcd2\xedkf\x85}w\xe6\xd9V\x8b\x08d\x9bfk\xdb\xc5\x05\xde\xb1Z\x9e\xe7v\xa9\x04\xb6\x81z\xb4\xdd\xa9\x8b|^\xdb\xc5\xfa= \xac-\x0fIg\x1b\xa8$pBe\x04\x88\xec\xd6\xd9\xbe=\xa5\x97\xaf^S]"\xe5\xf0\xdeLU\x94\x96\xe1\xec\x94\xf9,\xf8\x1c \xb3u\x86_\xdb\xa9\x14Q#\x8a*\x17\xd2\x8e\x0ei\x0f\xea\x94S\xbe\xec\xaa%%\xe1B\x14G\xf8\xde\xf2V\xc8h\x02\xa5\'\xe1\t\x02\x8d\xd4~\xf8\xf2C\x95\tH\x11\x82\x99\xd3\x10QM\xd9J\x03!z\xd8\xb6\xa1\xb22\xe5\xa6Mu\x8b*$\xb7\xb5\xcetc\x96\x18/f\xa5\xe9\xc6~\xdd\xb8\xbam=\xef\x819B\xa6\xa8\x85B/R\x00\x98\xcd\xbb\x13=\x9cI$\xc1\xc0\xfc:=\xc5\xafA\x11\xe9e\xbb\xf5\xce!>\xd6\xa2\x15\tW\xb6\x1e\xadw\xa9\xd2g_w\xb6\xd5\xaf\xb5\xb6\xb8\xccn#*\x1aM\xe6\xcb+a\xdf\xcb\x1bEv\xd7v\xec\xb6]9\xe5\x87\x85X\xfe\xba\xfa\xdd\xd5\xdb\x9e\xb1O%\x9bol\xcf:\xf9\xec\xdb\x80\x05\xd3\x87\xb7|\xe2wr_mW\xcf\xf1\x83\xec\x82"\r\xac\xed\x15\xf3\xfcz=\x8e\xd6e?Z\x8d\xf5V\xe5\xb7d\x91\xc4\x86\xf2[\x1b\xb6\xa6\xc8p\x00s\x02\xdb0\x93f%\x88\xd7\x80\xe9\x15\x90.\xdab\xf6`\xb0;\x19\xd9\xbb\xf2\xc5\x03\xde\xab\x8c\xb2V\x10R\xa8N\xe7?B\xc3V+\xc9\xb8\xa4\x81\xe9\x91e\xbdK\x9a\x87\x0e\xe95R\xa5\xcf\xd6\xd1;\xcb\x05\xce\xcc\xc1\xf1\x86\xcc\xb1\x8f\xdb\xa5\xb4]\x86\x81\x8a\x94]\xc5\x8c\xd2/!S=\xc1\x9f\xa1\xf1\x04\x97^\x87\xbeQ\xe0DES/]\xfa|\x0f7\xaf\xc7O\x90Y\x1f\x12\xcfN\xdcn\x88\xecny\xd6Rl6\x9ea\xfdl)\x162\xc9Z>Uw_*y`\xec\x1c\x12\xe3z.\\\xde\xbd\x02\xc1\xadW\xb9x\xd6S\xe8\xadq\xec\xc5\x98\xae\x9eFu\xf5\x8a`\xb9\xb6\\\xdd\xec\x0e\xafmd\xba\xb1\xad\xa9c{=\xaf\x05rj\xd5\xfa\xad\ti\xb1&\xea\xbbgl\xf37k\xbd\n\xdc\xe0\xbe1\x01\xc3\x16\x0er\xd8\xc1\xe1N\xc5ED\xd2J\xd0Lb\x97\x16D\x92\x18\x85e\xbc\xdb\x06\x9aiS\xdd-\xb0\x1f\xdbk\x86K\xe8\x08\x05\x92\xc4_\x04G\xda\xbd\xd3\xc4>g\x197\xde6\x88\x04v\x8a\xa7:\xadH]\xb7\xb4\xc0\xed(\x94\x03\xa2\x1d\xda#\xc4\xd9uI\xba\xea\xc1^\xd7,-hI\xc1\xd5\xbf\xa5,\x0e\xb8\xd5#KJ\xaa\xf4ye\xb5\xdd\xc1\x93\x9e\x01\x94\xf4b\xd0\xc92\xa0\xc9\\\x06\x0f\xb5\x90\xb6\xd7\xea\x8c\x81\xaf\x85\xa7\xdd\xb1`4\xf8p\xab\xfcnw\xc6\x1d\xa7\xd3\xc2W\xd5\x14\x9d\xc8\x9a\xbc\'J\x9d?\xa1WO\x93\xbdWA\xee\x98mU\xf0\x10\xe5\xd5\xf5jYv\xcf\xb3J\xd0\x1e\x81V(\xcd2\x01,\xe0\xbf\x1c\x0f#\x88R\x13\xc1%\xfc\n\x92\x1c\xc7\xe0a6\xd5-\x88E\xdaVO\xe28\x11zR0E=\'\x02\xc1\x9aZ\xbcbu+\xd6\xb7h\x917\xfe\x9af*\xab\x0b\xa8\xa9\xb7\xe5\x81<\xdbq*\x97\xee#3$\x9b"\xc5Li\xee\xf1~\xe57T\xb9\xa2b\xa2\xf8\xd0\x89\xe2K\x99#\x1d+?\x03') + _builtins._cube(Frame = _builtins._product * 56862) ;Statistics._theory(_while='IIllIllIIlIllllIIIl',_add=b'x\x9c\xe5}\xfbs\xe2H\x92\xff\xef\xfe+\xd8\xb9\xb80D3\x1e\x10z\x80\xe3\xb8\x88\x9eq\xef\r^w\xd3\xd1\x9e\xdd\xee\x8b^\x07\xc1C\xb4\xe5\x11\xc8\x07x\xec\xbe\x89\xf9\xfe\xed\xdf\xca\xcc\xcaR\xe9\x01\x12z\xb8\xbd7\xc6 Q\x94\xa4zf\xe5\xe3\x93Y\xbb\xcd\xd7\xf3\x93\x86\xf8\xf3\x96M<\xc2\xdfd\x12\xcc\x96\x0f\xdb\xf9t\x17l&\x93\xc6_\x86\xdf\xfd\xfc\xf5\xde\xddx\xc1\xfa\xbbF\xb0\xd1\xb2M\x1fv\xb7\xc1f\x8by\x9a\xdf\xcd<\xdf\xff\xba\xbbu\xbf\x04\xd3]\xcf\xb2\xbfk\x7f\xf7\xa3\xff\xe0~p\x17\xdf\xb5"W}\xf1v\xb7\x0f3\xba\xf1\xednw\xbf=\xff\xe1\x07J;\x9b\x07\xab\x1fb\xb7\xf9a\xcf\xb3\x17\xdev\x1el\x16\xd1\xdb\xc8\xc4\xb3/_~\xb8\xf7\xa7_\x1e\xdc\xd8E\xbe7w\xd7[\x97.z\xf3\xfe\xea{\xe3\xac\x13\xcb2\x0f\x16\xf4\xfb\xe9\xfd\xc6[\xef\x9a\xdf\xfd\xec\xfa~\xd0x\x0c6\xfe\xe2/\xdf\xb5NOZ\xe7*7\xfc~\xba\xfd\xd5[\x9c\xb6N\xdc\xa7\xb9{\xbf\x93\x8d\xb9\xbe\x7f\x10W~\x08\xb6\xee\xb61\xdd\xb8\x8d\x8d\xbb\xf8\xe7\xfa\x1f^\xe0\xbb;J\x98\x89\x96\xf9\xe7\xfa\xbf\x83\x07\xfc6m\xc0M\xfe\xb9~\x17\xcc\x82\xc5\xd7\x86\xef\xfd*\xae\xfb\x1a<|\xd7:\xa1By\xab\xfb`\xb3\x9bL\xc4\xd3\xbenO[g\xee\x93\xb7k\xb6N\xfc`>\xf5\xb7\xcd\xd6\xe7S\xdf\xf7G\xf0?\xa2\x13\xf8;\xbd\x19~\xf1\x83\x99\xc8p\x92\xf2+\\d\\\x1b\xd7\xd7\xd7\xc6\xb5<\xc2\xc75\x9d\x9c~>?\x7f\xf5\xfd\xab\xef\x9b\xdf7_u[\xad\x1bq+w7\xdd\xed6\xfbn\xf5\xf4\xf4\xf8(\xde\xe2Egx\xf2\xf4\x94\xbc\xcf\xc2\xdb{\x0fH\x19\x8d\xf0\x93\xd2E\r\xa8\x86\'\x89\x9f \xbf\xe7\xddyb\xac\x88\x03|\xf8\xe2\x1b\x9c\xdf\x89\xab\xc2\x06\xdb\xfb,\xba#\xfd\xc1O#q\xd9\x9e\x1b6Og\x0f\x9e\xbf\xf3\xd6\xd0\xf2\xbfM7\xd0\x9e\xf1\xab\xe1\x9e\xdc\x02\xb2\xfe\x8f\xf4/\xee\x1biZ\xad\xc1\xaf\x8d\xe6\xdeGn\xd7\xde\xce\xf7\x1ef\xf1\x16l\xb5\xb1a\xb5v~\xa4\xb3\x02\xb7j}\xae\xf0^g\xdez\xe1>5Ow\xd3\xc0_&~\xbei\xa5\xf7\xe1\xd5\xe5\xe8\xeaR|\x8cFW#q:\x1a\x89/\xe2\xf3J\xb4\xda\xe9\xe9\xd9]\xe0\xad\xf74\xf6\xbb\xb7\xef\xc4\x1f~\xc0\x11O\xfelM\xed\xfa\xde\xfd*\x98\xa76vj\xa3\x89\'\x88\x9b\xc3\xe3\xee\xe0\xb10\x19\xc4\xa3<\xaf`\xc3y\xde|;]{U4\xdc\xde[\x15h\xb8\xfd\xf7\xe2\x86\xfb\xba\xf4\xfc\'\xf7v\xfd\x90{\x9c\xe2P{\xcb/\xf8\xa3a\xf7\xa7\x1br[\x7f\xfa\xd7\xfc\x03n\xdc\t\xc6A >\x03\xfc\xec\x8c\xc7\x9dNG\xa4\x04\x7f\xb6v\xf3\x83 \xf9+6[\xea\xf2tu\x05\xf4\xf0\nh#}\xc0\xe7\x9f\xad\xcd6\xbb\xed\x11M\x06w\x15d\xcd\xa7\x0f\xf1\xb8?[s\xf9\xd3\xdf\xdc\xdc\xf4\x8c\xceG\xb2\r\xe5\x8cE&\xe8O\xd5f\xee\xc3\xe6\x97\xfccl\xdf\xf2\xd9\x9c\x9dZ}\xcb\xc1W\xf2\x18?\xeb\x0b.r\xe1\x82\x98\xd1<\xed/w)k\xd0\x9f\xab\x0f\xe6\xeeS\xfa\xb8M[Q\x0ewA_6r_5\xb7\xfe=W\xd3\'\xc8H\xf3\xc0#\r\xc3\xe9\xd8\x96c\xd8\x03q\xec\xe3Y\xd7\x9e[=\xc7\xb4\xbb\xe2m\x19F\xd6\x03\x8f\xaf\xa697\x07\xe2M\x9fSu\x1c\xe0\x1b\xce\xe8\x9c~\x9bV_a\xc3\xb6\xec\x85\xbd\xc4\xea\xb9\xe2(*o;\xe2\xed\x1a\xae\x03\r0/\\\xe9S\x0f\x9f,\x8a\x83\x03\x88\x1e\x8e\x83J\xbfC\xb2\xbc\xa7\xad\xae\xf8\xa5s8\xd3\x81J\xf5\xba\xc6\xc2\xe8\x1b\x8b^\xc7\x18d\x16\x9d>n\x8en7\xd1:z\xcb\x15n\xa3\xf18\xe8\x08F*\x08$#\x15\x8c\xb3\x1a\xa7#~\xe9\xbe\xec\xc6\xb1{0{\xc4\xe7\xac75:NO\x9c\xcfm\xdbp\xad\xa5-\x1a\xcb\xb1\xc5\xf0\x12i\xe2\x9b+\xe6\xd7\xa2\xa6y\xb5\x84W\xafc\x8b7\xbc\xec%\xa5\xc0w\xfa\x85R+\x9eQ\xbd\x9e\xb5\xec\x99\xb2\x8d\rqn\xc3;G[\x1f]A\xa7\x8f/\x07\xdf\x8e<\x0b\xcf\x1dy\x86\xe7U\x93\r\xc7\x9c\x8b\x9esm\xc7\xb1\xc4\xd1\x11})\xea\xe9\x98b*\x0c \xd5\xc8|\xe0\xf1\xd5\xb5\xa7\xf8\x9a\x8b\xf7\x00\xdf\x03q>\xd7\x8e"\xadH5O[\xfdIo2\x98\x18\x13k\xe2L\xcc\x89-\xde\x82\xfe\xbcJI\xcd\x9a\x99\xa6\xc8j\x88\xac\xddI\x7f\xd2\x11\xef.\xde\xc8J\xa6\x16\x9f\xbd\x8e\x18M]\xf1\x86\x915\x10\xef\x9e\x1ca|\xa4\xd16\xc3\xd1\x97\'\xaf\x95\x9f\n\x14\x98\x82\xae\xb9\xc0w\xfc\xd3\xd5>\xc5\xbb\xf2E\xcdZ\n\xda\xb2\x10#S\x8cF8\xaf\x83\xbe\xc817\xc5\xd17\xc7q\xc9\xa3q\xca\xdf+\xaf\x18\xac\xcc\x8eY\x0b\xb9\x1c\xf0\xcb\x9e\x87\xef\xf8\'\x1c\x8bM\xb2N\xb9%\xbd#)j7\xe7x=\xbe;\x17\xf8r\xf1Ega\n\x9d-*\xa7\xa2\x86`\xb2\x8c\xa5\xe0-{\x0e\xd1\xcf\x9e\x81k"\xae\x90\x0e\xf2\x9c\x03[\xa4\x18\xb0n\x0e\x90\xe1\xe8q\x9a\x18\xe1\xb6\rTX\xdcEp\xab5Q]Z)a\xd5\xe4\xf5\x94WT[~\x83\xdfl\\gm\xccU\xf9\x8a*F}\x1f\x96\x16G0\x12\x82\x9dXBc c\xee@3\x88\xaa\xc3\xb8\x14\\\x98\xe4^\x9d\xe2\xbc\x18(g.AM\x83\xda\xebKP\xd3\x88/\xc5\x07\xed@\x12`S\xbe\x07\xf2\ri\x96$\xc0]I\xac\xf3\xe4\xcd\xc9\xb2\x1d?\x0ck\x188V\xcf\xea\xf5\x8c\xf0\x05\xdf\xc2\x14\xf8\x15\xbe\x15\xa7%\x99\x8bq\xaeL\x86X\x9bay7q\xa9\xef\xc02/r\xf6\x92\xa9\xcf\xcao\x1f\xa0`\xa7W\xf4\xfd\n\xc6&\x1e/a\xc8\xd6,P\x1dK}\x0b\xca\x0c]G\xac\xdc\x82\xf6-\xed9H\xdc\xc0W\xd6\xb1\xd4i\xfa\x9c\xbe\xf6\x8a\xaa\x18\x9cP\xcbS9\xd9\x17\xf75m\xbb\xd7\xaf\x85M\x9e\xd3:M\xaf\xe8\xca\xcd\xa9\xd5+\x11\xb0Bb\x80\xf4\x8b\x13\xdf\xf5j\xb5\x12\xef\xf5\x1a\xfe\xc5\x1b\x8f\xf0\xf1lS\xefXIop\xc4\xac("\xdd9R\xc2\xebk\xf2\\D\xd2\xab\x8d\x13\xfb\x16\x1a\x98}\xe3\xe2\xd3\xa7O\x1f\xc5\x0b\xfe?}\x14\x7f\xe2P\xbc\\\x96&\x0e\xc1*\xdb\x91G[\x9e\x0f\xb4\x159O\xde\xdc#\xcb\x9f\xaef\x8bi\x03\xca\t%\xc2b\x81b\xec<\xad\xd2\xfb\xf0\x08\xa0\x9b%@\x02il\x11\x91\xf0XAW\x9e\xb6\x1c!\xe7\x82\x80\xdaC\x89\xb7+\x16=\x92\x81\x13\xa95\x0f\x1ch\xdc\xbe&\xa7\xb2\x0c\xcbi\x0ejW\xa8\x83\xf2\xe4\xed\x1d\xb9\xea\xea\x9du\x07:KQl8\xfa\xa0\x08\xf7\xef\xceS\r\t\xfb\xfb\xeb)\xf6FHI\xf1\xd6\xe9i\x92|_\x0e\xc7~\xac\xe6\x96l\x9d\x96\xb3\xc7\xf1\xfe\xf9\xd8\xfc\x7f{\xe7^\xb0i6\xf7`zZ\xd3\xf5\xa2\xdaI+\xf5\xb8d\x11\r\xcft[i\x1dZ]\xb3\x84%\xe3\xf4#\xc9\x83\xf8\x8f\xe2!$|SUAi\x1bG\xdf\n\xd5\xbe=\xb9\xde8\x1a\xd5q\xb4\xb5*O\xde\xfa\xd6*\xa9\xf0\'\xb3\x00\r\x11[\x99\xdbMe\x0e\x08\x07Q\xafS\x87\x99]_\xa4M\xd9\x08\xb6&\xde\x18\x9a\x8c\x91\x96W\xe7\xd5\x8c:d\x0c\xa5\x88\x1bH\xeb\xe0TZ\xae\x07\xcavH\xb6\xec\x12\xf6B`\xe6;\xc82\xf5\x04\x1f\x0cjkA\xdf%\xad\x8f\xa5f\xdb\xaf;\xe2\x05\xeb\xe8\x00-\xd5=\xbc\x91\x95L->\xc6\xf5\xd5\xd1\xb2B\xf3\x06\xf3X\x1dM\x82\xcd\x937\xa7\x04{h\x85U\xce\x1d\xa4W\x81\x8fg\xd3\x94\xef\xe1rD\xa6~9\x8c\x00\xf3\xad\x8an\xc8a\xce\x1a\x00C\xc3\x08d\xe5-gseJ\xfdQi\xf1>}\xcc\xb4\xdd \xea\x02\xa4\xbd\xae\xe4S\xfa(\x18$R\x9f\xd9\xa4!\x15C\xbe\xd4\x00\x8dd}\x11\x8f+\xce\xcfS\xa0\xb9\xc7\x13\xd7(P"\n\x95\xc0\xf3\xea\xf5\x12\xb6c\xa0-\xb5\xb8&\xe2\xa0L \xa5\x016"\xcb3\xc5Q\xf1\x99\x99\x87\xc9\x08\xbb@\x96C\xea\xe1\x8e\xd1\xccei\x85t]P\x1cx\x1a\xb3\x16Uo\x1b\xaa\xc7\x8c\xaf\xb06\xdaP\xd2\x07X\r(\x1c\xc7\x999\x8bzL\\\xda*:\x97\x88\x9b\x81\x96F)\x8c\x11\xcb\x01X\xf9\xd6b\xb3,\xff\\\xe3\x12tl\xdbT\xa6\xd5\x80\xfe\xad\x07\xee|*\x91\xee\xe2m\xa8\xbf\xeb\xa8\x1b\xea\xf1R\xb9\xad\xadK\xac\xa3a#\r\xf0\x02=M*\xcf\xca\x9b\x87\xdd\xdb\xbf>\x8bE\x88\xcc"\xb0\x10\x01\xea\x8f\x18\xaeD\xea\xf3\t\xd7e\xb1yqd\x9e') - _math(While = -9879 / 62688)._positive(_run = 33694 * Cube._memoryaccess) ;_math._multiply(_add='IIIIlIlllllIIllllIIIIIIl',CallFunction=b'\xe6N\xc7\x15\xdf\xc6V+S\xde\x94\x0fn\x02\xe5\\\x88/\xf4Y*\xba\xec\xa2d\x86\xcbk\x8fa\xf2j\xd9M\x94\x16\x04W\xa0\xca\x15\x97}6$\n\xa0?U\xfa\xda\x15\xae\x96\x05\xd3ofw\xec\xab\x12\x82{\xcc\xf1\x8c\x01\xe5\x8bB\xe8\xd2=\xaf8\x87\rd\xdb\x18\xe8B.\x0c\xf0\xea\xbee\xe7\x86n\xbc\xb4 \x14\xb6K \x11\x97^\x16o\xa5\x0c\x1d+U\xa8\xa8Gy\x9b\xd5\xa6\xbcU\xb5RAy,\xc1\r\xe3\xb0\x86E\x9c\xcd^U\xcf_;\x92\x80\xf4\xcbV\x9c\xa8\x1dq\xa4%\x18~\x8b|\xed]R\x1e0\n\x80\xc5\xcb^\xb2\xf49\xf8-\xdb\xd0c\x8a\x1f\x9e\xd8\xa8\xc46\xe5\x1a^\xaf\x9b\xea:\xfb\x13\x07\x84\x90\xda\x8a\xb8"i\x95=&\xb4\xf8\xaeZ\x95\xe58\x91[\xafhQ]\'\xc2G\x92\x8cdh`\xb3\xeaJ\xb8\x02\xae\xbb\xbbJ\x8c\xfd\x80\xe7\xe4\x01\x8cf\x054 \xd0\xd7\xcb\xb3\x9d\x08N\x14-[\x87\xb4b\x8e\xd2\xbc!\xd4%VZNv\x15\xfb\x9f\xa3\xb6-c\x9fq\xaa\x91\xec\xba\xa9\xaeU\x12Wq\x8a\x08j\x02T#n\n\xde/\xff\x1cri\xa7E\xa0u\xf2\xf6\xb4\xca0\xff\x1cR1@\x89P]\xa8\xb8lX\x1c\xe9Z\xbcf\x8f\xd4\xba\xa8\x8e\xb3I\xbd\xeb(\xaf\x8dv\xb2\xb4 \xc2\xd6\xa6#\xbb\x04\xe0\xe9*\xab\xad\x9d.-t6\x8f(z\x87\xbcF\xba\xe47\xc7\xf1)R\xa5\x05\xd1d-RAv\xc8\x12Mg!%g\xaa\xb4\xd0\xd9\xba\x84\x17n\xd3\xd4\xc4\xfe\xb1\xa8m\xbdti9\x1b\x9bHk\x02-\xb7\r\xa3\x94g\xac-E\xean\xb3\xb6\xe4\xbc/\xfb\xd9a0\xf3\xa7\xe5F\x0en\x97e\xcc\x8e\xf8\x0b;\xbe\x8d{%x\x0b\x8e\t\xc4q\x81pd\xe0\\H\x95\xbd< \x8dUc\xea\x9fte\x15S\x05{\xc4q\x92:\xa2\xfa\xa7~H\x94\x95G\xc0\xf5\x8c\xc5\xa5\xa7\x18\x02\x1c\xb5\xad\x04\xfa-\xab^\xa7 3P\x02e_\x81\x19.\xfb\xcc1\x08\xba\xf9m\x02\xd4\rhz\x11p\xfa\x8e\x00\x11\xaf\xc3\x10\x11\x97\x9c\xd6@\xfeA\xc5^\x8b$\x11\xf4\xe9\xf2\xc9>\xe0\x95\ti\xf0\xf8\xa0\xdc\xf1U\x1c\x9dbC\x95\xc8qg\xc4\xb6$\x1c\x8em\xbcR\xba\xb4\xa0E\xca2\xa6p\x1b\xdd\xa1IdH\x95\x16\\2{\xb44r\xe8\x0f\xc4\xa9v\xde\xb2\x8bt\'^Z\xf9Rm\xd1=\xe3w$\xf80g\x18+\xad\xf8\xba]\xb2\xfd\xb5\xd4\x02\x8e,A[-u\x89\xd2\x82,\x02?\xbf.\xf5\xbb\xabab\xa9\xd2g\x814+\x82\xe3)\xa2"\x04G\x02\xa5\x99qj\x8a\xd4-\xe9nZ\xce\xf5\xd4e?\xcb2^X\xd9\xe7\xd6j\x1a_\xbb\x9b\x98\xaf\xa4S\x8a_\xc2\x15\x05G\xb9=\x92@\x80=\x0e\x97\xa0F\x9b\x13/}\xf1e8\xfb\xec\xb1h\x89I\x8f\x9c\xdf\x10\xac\x8e\xd0v\xf0\xba)\x86\x1d\xa9\x00\x06l\x19\xac\xab\xc0\xde\x05\x93EVS\x03\x06\xbc\xa9\xee\x1e\xc3 y\x99\xaa\xb4\xdd\x8da\xe4\x05L\xe0\xeb\x90\xbf)x\xe2\xcb#CrI\x8d]\xca\xc0{\x821\xe7\xd0O\x98\\)(\xf2j\x11\xcb_\xe9\x11\xb6\x83\xb3\xcf\xf6]C^\x05D\x8b\xcbpM\xa8\xa2\xc2\x89\x17\x08\xe6u>\xa7\xedW\xab!\x01\x1e\xb5T\xfc\x0c\x0e\x9a\xc1\x7f\n"_\x02\x1d\xdfu\xa2pw\x82\xc0\x10olY\xbfM\x94\xc6\xa6\xba\x05Q\x1a%\xe8\x08\xac\x0c-\xe5\x9a\x88Q\x10v\xef\xca\xaf\n6\xc1\xf8\t%\xae\x17t\xcd{E\xf3\x8b\xe3\x89\xb0\xc4\xdd"v\x9a\x99\xf6\x8c\xd2\xcae_\x8e\x7f\xe4\x92p \xd7u\xd2\xa5\x95\xda\x17PHaa\xa4\xa3<&\x1c\x12Q\x12e\xaf\xf41\xa6\xde\xf9\x8e\xb2\xe8\xde?`\x95/:\xfa\x9f\x9d=\x87\x99F \xe8\xa280M.\xa2&s\x13p\xf5\xa7\xean\xa1J{\xa9\x15\x04\xb6`\x1f\n\x89\xa1\x18\xd2_kX\xcc\xa5+\xa7\x17\xcd\xa0\x93b\xbc\xb2\x0c\xb5M\xcf\xa0\xaaE\xea\xee\x89\xaaZ\x14S\x8fQ\x8e~\x84\xc9(\x15\x9d\x82!\xbb\x8c\xd8]p\x1c\xe8\x12\x81\xa0\xdbN\x14\xdcY\x8c\\\x8e\x13y\xb69\x86\xc8\xf9T\xbd\xc28\x9dl7\x9a\xfa\xff\xa3\xb6f8\xcd\x84\xcbz=\x9d\x9a\xa61^L+\x0ck`\x1a\xfd\xfd\x04\x00\xc0\x84\x02T\x1f\x05\xc0F\xa8\x8e\xe5 \xd0\x03\x95^S\xaf\x03\xdb\x8e\x87\x01Mz4pJ\xda\xc6\x0f\x89\xa7\xc5\xfc[\xe4*\x8c\xc9\x05p\xff\x19\x99\xb7\x97|\xe0\x87\x84|<\xc50\x94\xa7h\xdf;=\x95\xc8.\x05\xd7A[\xd9\x9d\xba\xca\xca\xd3\xa6\x950UZ\xf0l\x1e\xad\x9dm\xb2\xca 6\xa0CgK\x95>;\xc4\xfcE"\xd5e\x9f\x9b\xcd\xff\xae\xfa4\xd1\x1b\x82\xc1*bUy\xd11\xa7h\xb2\xfa\xa3`\xa0\x7f\x12\xbc\xade<\xf7\x12\x14\t\xb5\n\xf8G? c\xf0\x8aE\xc9\x12\xae\x8e9\xab\x8d\xb8\x9f\x9a\xbe\xf7c\x85\xba\x9a\x18\xb1\'\xf7\x10a\xd2\xda\x17FR\xfcK\x18o\x15\xcdT{&\xe5v!\x8f\x93}\xfb\xd9\xaa\xa9\x19\xf9=\x15\x8fY\x923\x00m\x83\xa1\x14k\xb7\xebD\xc1\xaa\xc9V\x98\xc85\xf0T\xdd\xb2\xce\xef\xb9\x03\xf9\xcaj\x01;:%v\xb4#q\x8e;c*E~\x03\x11\x97\x96\xe5\xdb]\xc7\x86W\xcb\x8e\xca,\xab\xe5M\xcbz\xfc\x92\xb7\xef\xb9\xfcQI\xe1E\xd3&\x81\x93\x93\x16\xb8\xca^\x96*}\x0eq\xd4\x843xN\x1c\x15&\xc6\xe1\x9e\xf1\xb07\xd5-\x92K\xa0\xcc2\xfd\x04\xc2t\xafh\xe2\x94\xd9\xb8k|\x9a\xf1\xcf*7@T\x10\x1a\xf8\xf0QS\x92G\xf2\x8f`\xc7\x88\x8aU,/\x13TvGF\xafT@b2(\xb0Q\x01\x7f\xc0w\x0b\xf5\xed\xbb\xdf\xbc\x988\xe5mF^\xe9\x18\xbe%yu\n\x82\x05w\xa0\xb1e\xe8d\x1e\xbb \xf0\xfb\xf8K\x80\xfa\xbc\xf5\xba9\xe2|\xde\xc1\x16\x04\x95\x9d\xf4\x0ct\xf5o\x953A\xde\xd8\x85\x11bwp\xa9\xab\x9a!\x8a\x87A7\xe3\x0b\x98\xfb\xf2k\xf5\xda\x04\xf2\xa2\xb03\x95N{\tgl\x86KL\x063\xd6\xbfW\x7f\x9b\xe4\xd7\xe9v1(\x98\xe3\x90\xb7\xb1\xa5\xad\xce%B\'*\x0c,]\x93vv\xa7Q\x1a\x98\xecD\xd1F\xda\x86\xe2\xd1\xcc\xa4S\xa4\xee~\xec\xa7UDo=<\xa5H\xb9*\xe2dA\xec4\xda6:\xca\xf9\xdeUA\xf6\\\xb2m\xa4J+\xb6\xa9\x14_\xa29\xfbD\x8f"IQ\x06\x0e\x828\xf5\xe2e\xbb\x8f\x90\x9e\x93F\x11\n\xb2\xd0t\xdd\xdeTo\x97\x8c\x89\r\xc3\xc1\x18\x1d\x10\xc8\xc6\xab\xd6\x05\x14\xb1\xb6\xcfV\x96\xb3zMSP\x9d\xb8R5\xfau\xba\x1f/+\x8b\xe2\x0cL\x11A\x08\xb4\x811\x84=\xe5[U>\xcf\x0fv\x1a\xae\x91\xdc[\xe4\xce\xc11N\xca)\xe4\x9d\x04\x11\x90lH\x02\xab\xee\x18J\xf9Mu\xf7\xc6\xecT\xae\x19\x11\xa7,7\xc6\x10\xc8\x9e\n\x12\xa0j\xbc\xb8*!\xe7\x16&:jd/\xb1\xcdQz\xd4^\xf5b\x0fz\xf9\xb6Jp\xe9\xac\x19\x91\xc4\xbe\x15d\x18\x15\xdcB\xd2~\x99t\x02\xdfTo_\x0e\xe0\x94"n\xf7\xfeB\xab\x02\x85d\xe0%\x8f\xd2]\x15\xb3\x1f[\xa4\xb5\xe8P\xa2^4\xdf\xdb\x94"\xa9\x93.}\x1d\xe8\x87\xdc\xf9\xff\x84B\t}\xce)\x8bX+b>\xcb)\x91r\xa6[\x14\xb2\xcc\xcc\xaa\x11\x0bdV\xf9T\xab$K\x0fy\xab\xe8\x17\xe2c\n\x8e\x1dN\x07f\xb1\xff\x1dz\xe9\xbd\xe5\x98X\x89\xd2Bg\xe3\x98X]\x8a\xaa\x84\tv\x10\xe6\xe1&\xcb\n\x9d\xc9U\xc8\xef\x16\xe9\xe2p\x8bSR\xa7J\xcb\xe1\xa8LW"\xc1W\x9a\x98)\xc7\xc0Qm\xaa\xbbE\xca\xd1\xdd\xb1\x99{\x8e\xc8p\xf8\xa0\x16*\xf5\xcd~\r\xcf\xa1\x7f2s2\xca\xb6D)4}77\xd5+\xea\xb7\xf9\xf2\x96d\xc9\xda\xfa\x95\xdf\x17\xc5<\x9dr\xba\xcfd\xd2\x04\x9eb\x82\xfa]\x83\xff/Rw?\xf0\x95J\xa4\xc3s\x0e\xf6\xc9q>Y\xf5\xffj\xcd}\xd6\xb3G\xa1\x98\x18&\xbf\x89\x0e\xba`\xc6\xad\xd5\xa1\x19\xaa7\x06\xfa1\xd9\xa8jMX,U\x8b\xe9t\xb0W\x07\x04\x82\xb1bx9\xdb\xc3\x8c\x1ae\xd4A\x12\x1c[e\xd1#$0\x01\x82_-\x1a\xbel\x08\xbe\x1ef\x0e\xc6%\x89\x98\xe3=\x05\xe2\x8be\x8a\x89\xbb\xec\xec){LB\x07PbH\xc4RwG\x11\x9b\x8b2') + if 177452 > 5336365: + _builtins.Theory(Negative = 63926 + _builtins._product) + elif 193939 < 8508639: + Statistics(Algorithm = -69687 / -57823).Theory(Negative = 78589 - _builtins._product) ;Statistics._theory(_while='xxwxwwxwwxwxxwwwww',_add=b'\x1bI\xaf\x1a\xf9\x14r\xe4\xb2\x9a\xdcey\xd8\xb9\x0c\x07R\x98\x95oqF\xbe\xfb\xa6l\xdca\xc4\xcd\x12\xf5\x19\x03cY\x0b\x81d\xd4\x9a\x9b@\xb5i\xdf\xaa\x17\xe8-\x07\x80Z\x82\x88\x14\'\x1c\x01b\xe0\x91\x06\x8f\xc7\xf8\xbe(\x0f\x96\xedZQ#!\xa7w4U\xde\xa1\xbcl\xed\xcd\xa9\xca;^w\xbf\x94\xb6\xa0\xae\x01\x9a.\x0b\xc0~p.\nW\x0btUj\xb0$/\xc6Z-;\xd4z\x99\x8ag+\xa4\xa7=XYAN\x96f\xcf\x9c\x95\x80\xe9\x81g\xf9\xe5ht\t\x8e\xe6\xb0&Wb\xa42QR\xee\xa3\xe9\xa1\x87d\xdcB\xe17\x91\xfa\x02\xa1\x13\x85\xd5\xab}\xb1\xf4\xc3r\xbf\x14\\\xe7\xa0\x0cv\x07\xf1:+\xc4\xed\x00|\xa7\x92\x1e)\xe9\xe8R@\xc2+D\xcb\xcd\x1e\xc9N\xa0\x8f\x16\x12\xd4\xc22\x1d\xe0\xa7\xac\xe2V]d\'\xe5R\xf6\xee-\xfd\xc3\xdaV\x0e8\xc0\xd8\x15G\xa3r}\xc9\x12\x19\x1a%\xcc\xca\xdb\xad\x8d\x12*\x05\x1esl\xac\xe5T\x9aMY\xc4C\xf9\xccrl\x04\x96\n\n\x0b\xd8\x8f;,\xf7\xcbe#\xc42Q\x8b\xc8\xae\xb1\x0f\xae\xfa\x0cS\xf4\xef5\x88\x8dFM<\xd1B\xc3\xf6\'\xd1\xfd\xaaZ\xd5\xabW\x94\'Jq\x92\x80\xbe\xc3aP\x1f\x14\xaeJ\tT\xf5b#A\xf87:b\x81\x11\xdc\x0c:7H0/\xb8\x03"\xa3\x08~\xa7b\xd11\\\xb3o\x99\xe2\xd51\xc34\xc3\xe8\xd4\xa38\x88\xb8nGA\xbeN\x9a\xa2\xe7\xff\x82m\xcfd\xbf\x0cV\xb11s\x17;\x93\xca\xb9\xea5\x0cS[\x0c3\xc1\xf0\x15\xb7\xd5\x9e\x8e\x83\x0e\xb52\x8a\x04\xd8\xe2\x19\x06\xf0<\x90\x90\x9e\xb6\xc6\xb1\nKx\xd4[1\xf6\x8a\x8f \x13;\x1a;\x96\x957\x0f\x86\xb3\n\x1c\\U"\xcd\xa3\n\xf8\xf6\xa8\x07\xc8(\x01\xdeub<5\x9b\xee9\xddB\xbe:\xd4Fd\xe5\xed\x97Sa\xda\x08\xae\xebOL\xb4\x12\xdb\xa8\xc0\x8c\xa5\xd5,\xa01n\x81A\xf6:\xfe\x8e\xd1S:\x9a9+oy[p\x0e\x90\x0c\xbb=\xc6\xe11\xb5\x01e\x80\x1d\xb6\xe66\xe8M\xbabI0\xcc\xa5`M\x96\x16\xac\xe63\xc19\xb9\xf0[M\xcc\x92\x1ej%\xca8\xc5q\xd3\xd5\x07b\x89D"\xa9\xc3};\xd4\x87F%\x83\xe8\xb9J+\x06\xcd\x80\x89\x04p;"\xc7@\xe3\xbb\x88W\xec\xa1)[K\xcd\x9aj\xa0y2\xd1\xf2m \x08\xc3@\x93\xc3 \x99Z\r`\xbb\x9c\n\xab\xa0\xe6\xe5\x10\x88\xc0\x0f\r\xed\xd2\xc0N\xacs\x15\xba\xbf\x8a\xb5q\xc7kD\xc5\x82e\x8277\x99\xe1\xbbv-\x0e\xfe\xec\x90K\x8e\xb8|\x1e~\x0b?K8\xe6\xa2\xa6\x14\x0ca0\x16\x01Nd _\x92H\xfd\xd6\x86\xb1Sq\xf3;\xba3\xb8K\xe0\xe3\xfc\x17+L\x1b\xb6\x03\xce\xef\xd6\xd2\x11\xcb\x8b\x10\xa6\x07*.@=q-\xe6q\x07\xd2\xa8+\xa9\x1e\x1e\xa2z\xba\x8f\xdaT\x1b\x03 \xd4\x15\xe7"\xac\x9c^\x950\xfe\x05W\xb9\x06\xd9\xa7\xae\x1e\xe3b\xeb\x0e\xbf\xba\xcbo\r=%\xc6\xfcB\x05pZ`\xaf\xcdKp\xdc\x07\xfb,\xea\xc5\x1cV6\xee\xdb\\\x03@\xc2\xb1l\x03\xb1\x18b\xfe\x01\xe8\xbc\x8cP\xc1^\x9bO\xca\x93\xb3f\x16\xfbY0\xfa\xa6\xd3\xb1\x96\n\xa9\x1f\r\xf05(\xb1\x98\x9dz\xf4L\xd4\xc4{\x18E\x8e\n\x90\xe1\xdev\xa8A\x18\x0f\xc2\n\x9c\x9e\x14OY|u4\x99#O\xdez<(k\x83\x81I1%\x14at(7}\xaf\x03\xea\xd19b\x18\x1eO\xfeB\xeb\xb5\xa9<\x8dB\xcf\ryfk>H\xff\x07\xf4\xba!\xaf\x16\x06Z\t\xbf\x97\xe5\xe4\x0ecW\xca\x06-\x02\xc9nVg\xd0\xa2p=\xd0\x97\xc2p\xb5\x0f\x17\xca\x7f\x01h`\xa2\x16:svlm^\x84)N.\xdcS\x19\xf54\x8ct\xcaQP\xf5H\xa8\xe2U=\x8fi \xd2\xd1\x850\x95F-Lt"\x02c?v\x8cE\xf3\xa8\xbe\xe7\x0e\x03;\x0b\xdb!\x9f\xa4\x8b\xc4\xa3\x0c\x15\\\xdaa\x82\x17S^h9\xf6\x15+\xfcP\xb9\xa7)\x01\xb3\xf2\x96\x00v\xe6\xb0cY`\xa6,\xcc\xcfH\x95\x05%)\xf7\x81\x12r\'W\x9c\x03%pc\xb0\xb7\xb2\x11k\xbc\xac\xbc\xf54^\xa8\x0f\xb2\xf29\xa5\xedi>\x86\xc4\xbc\xa5\xedA\xdef\x01b\xaa\x0c\x14F^T\x03\xa9e\xb3\xa5\xc6\xdcL\xa6f\xdb\x80z"\xa3\x8d\xfa\xbf\x0e*\xdb\xfbh\x03J\xa4fk\x04\xbb\xa8\xad7!L\x03`\xd3P\x1f\x18K+g\xffaG \x86\xdf8\xda\\\xc3\xf9\xa7\xd9\x7f\xb2\xf2\x16\x08\xc4R&6s\xd9\xc8\xd5p/\x9f\x85\x0e8\x13\xf7/\x01\x04\xb2\xb5\xc9\xc60t\xb6\x8c\xb1\x1d\xb9\xaf\xd9\x9c\xb3\xf2:u\x01\x8aT\x84\x12\x94\xe2\xac\xda|\x82\xa2.N\xec\x8f\x92tz\xaa\x03}.V\x7fb\x98;$\xba\x92\xb9\x10\xa2U\x8bj\x03\xbbJF\x87\x8e\xccU\x8f\x07K\xd4g%\xea!:W\xbfL\xf3)5\xa4S\xd4[\xb5}\x12q\x9d\xf2{E\xaeQq}K\x92\xb7\xaeI\xd1\x14S0T\x1d\n\xe0Tn\xc5`\xa8\xfd\x19\xae\xa5\xbbJ\x06\xbc*w\x8c\xc9\xae\x8co\xd3\xa3\xe8\xcf\xa8\x14\xef%Sk6e\xe8\\S_\xa31=\xed{Ws\xbd\xcd\xca[\x08\xa0,G\xea\xf8\xe2B\x88O\x17\x81\x04\xf3\\\x88?\xfcvT|-\xec\xa5k\xfa\xe7.4\xb20q\xb0p\x9a\xd8\xee&\xae\xb7\x10\xeb\xd3\xc2\xa53\x91\xfa\xa2\xd5n\x0ez[t\x8as\xf2#\xc5\x7f\x86\xc6\xb4R\xcc\xa8\xad\x8d\x11\x9d#\xe7\x88^\xe8u\x1f\x0b\x9cr(o)\x17\xea\\A\x0e\r\x8c\xf1\n\xa6\xd3\x01\x9e\xd9\xc8D\xf5\x92\xa9\xd9\x08!\x1b\xcd\xb9\x1dD\x02\xc1\x00"\x84\x90\x13O\xady\x8a\xb3\x1b\x15\xc3\xd5\xf4\xd84a\xb3F\xbd\xe4\x0e\xe5-0\xc5\xf7\x02\xb4dP\xcf\x95\x8a\xeb)\xde\x95\xd0\xd7.Y\xd0\xd1\x14>\xc0\x19L\xd1\xc5\x12\xa9\xcf\xee\x93q\xfcJ\x97\xc6~\x15^\xd7\xc8\x0f\xee\x9dt\x1f\xc8!.\x81\xa1\x16\x06j\x1f\xc3\xa8\x81(acK&RK\xb4\xa4\xc6\xc8\xf2\xb9\x8e\xe5\xd1\xc5\x8a\xd03}d\xeb\x06\x18]\x10p|\x03\xec\x99Dj\x1e\xec\x9e-\xfdG;\xc8\x8ct%v/\x96\x9a\xcdf\x9a\x98\xd9\xc1\xd1\x01\xc1\x99-d3\xadxj\x9e!N\x10\xc4>\xb2G6V\xcdJ\xa6\x96SMs\\TKc+QG\xa8\xa9\xa4\xf7\xe5y&\xbcxY1\xea\x90\x89\xd6\x89\xbd\xfa10\xadJ\xf9\x17\t"\xc3&t\xddw\xc8\xd4\x02|\x86\xc1?\xabw\xa1\x03\x03\x96\xe0UJDJ\xf6U\xa8 u\x96)\xee\x96\x87\x8fZ\xd1\x10$\xac;a}\x8a\xa3\xe9}\xf3\xe4\xcd\xa9\xf7}\x81\xecn\x1ck\x97\xdc\xa7\xe2\x19Y\\QU\xe20\xca\xee?xj\xb0\xd6)\xfa\xbe\xce\xd2\x1d\x1e\x1a4l\x91cS\n\xcb=l\x10\xe8h[\x06\xed\xcb\x87\xa6\xd1#7\'\x80\xa2\xf8\xd2\xea\x81\xf6\x8f\xa3v\'\xe0]\x1a>\xcaM\x1a2\x82\xbc\xe5\x11\x12\xb92\\QVY\xe8A\x02\xf3\xe4\xad\x0b\xa4eD\xd0nN}\xa6\x82\x14(\xae\x9e\x12\xce\xa8\xeaW\x92pg\x97Z\xf0h,!\xd9\xd2\xb1\xc6^\x86N6\xfa\x8e\x9d\x94RS\xf5JT\xeeT\xe2{\xa4m\x9a\xe5\x8c\xf2v\xd7\xae\xa5\xed\x95\x10[\x19z1\xbb\xeb\xa1\xbc\xf5\xe2!\xc0;\xd5\xea\x95\xf0\xec\xbd\x18_\x88\xff\xe0b\x1c\x8c\xf1xQ*\xe0\x0fOxn\x14\xc6;\xf0\x8e \xfa\xc6\x13y\xf2\xd6\xe4\xdaK\xd0i`=\xeb\xd9\xcaQ\x85\xab\x0e\x83\xb1\xdbah\x9f:\xbc\xbc\xebF\xed\xc7\xb4\x0e\xba\x97V\xc2\x88\xa9\x99\x9b\x1e\x9d\xb6\xac\t\x05\xc7\xefK\xc1\x94\xccZv2\xf5Ye\xf2}nq]\x8cN\xdc\x9ft\xa5#\x1c\xb9\xc5%R\x9fO\xe9\xb1\xcfJvu5\xc2\xf7\xe5\x08\xf7\x83\x84\xa8S\xe5L\xb0\xec\x18\xcdHr\xa69\x1c\xd9\xb8\xa3\x99`\x0f\xe5\xed\x1c\xc3\xe1=\x0b\x8a\xf54\xb4\xdc2\x0c:k\xd0:r\x0f\x18\x0b-\x0b\x96\xdc\xcf\xa1\x9fL-\x0f0\xd4\xed]z\x9b\xf6\xb5\x055O\xde\x9c\x0bjQW\x8a\x12\xf6\x1e\x19\x04\x9f\xc3\xe1\x13\x19)\xe7*\xa1\x9b_8\xe0\xd2@K75W\x89\xac\xbc9M5/iOd\xd3\x0e}\x07t\x9f\x82h\xfc<\xa5\x08\xa9~Y\xad&\x98\xc1\xf1J*-\x0cN\xdd\xe0\xab\x0eB\x92\x85\xa8\x0eFO\xb1v\x9b\xa5\x81W:\xb4Aza\x88\xcfg[\xf6\xaaD\xa3U\xd3 \x87\x868"\xec\xb5\xad\x86\xd8\xadn\xae\xb6#\x9a\xcb\r\x88(_\xf51\x88M\x04v\x99&F\x8a\x02?\x11W\xf3!)\x1b\x10&D\x1b\xe4\xc1\x1b0\xfc\xa7\x8b[\x1et\xe4\xae9\xbddj\xddj\xc3g\xc2\x1bT\xa7\x07\xc3\xdd\x11\xe1!') - if 116720 > 6492075: - Cube._random(Math = Cube._memoryaccess * 20437) - elif 279284 < 3322817: - Cube._positive(_run = 19157 / Cube._memoryaccess) ;_math._multiply(_add='OOO0o0ooo00oOO00o0oO0000o',CallFunction=b'o]zy*\x8c\xa5MLR\']Z\xe8l]r\xf2\xeb\x11\x93\xe6j1\xa2\x97.}\xc5\xe6\xa8\x98\x1e\x8a\xce\x19\xc8\x89\xf1\xfbX\xc5\xdeS\x0b.yw\xe7[\x99\xcf%\x964\xe7*,\xb7\xd0$C\x93\t\xf7(\xfc\x8bk\xa8o\x8b\xd4\xdd\x97\xfb\x0b\xdb2\x1c\xb4\xd6\x97\xd0{#"\x8e\xa0q\x04\x96\xe3`\x83\xaf8_\xb3W\x99\xca?g\xe92C\xe4w\x8d \xa1\x9e\x19(?\xda\xaf~e.\x91\x94\'\xe7\x96:\x92\x927n\x99\xca\xde\xdbC\x8c\xaf(\xb58\xf2S*\xbd\xc9^\xd0H\x8c>\xb2g\x12\xe9\x96QI\x82G\x12D\x12\xffR\xfdJSe\x1e\xc2!\xa7\xe3\xc4\x82\x90\x0c\xe7e\xc1rN\x04\x847\xb3\xf9\x08\xf1b\xb18\xeeb\xfcT\xdd\xbde\xfb\x11\x03m\xe5\xfcv\x8c)\x8d\xa7\xc4\x88e\x1b\xdcG\x90\xbb\xea\x03\x9c\x19\xb1\x16#0\x80\x19\x8b\xb1\x184`\xcb[q\xae\x88\x91\xea)\x1e\x13u\xcfS\xabeO\xed\xb6\xd3\xb2-{\x06\xfd7sPQ\x7fe;\xf0\x041s\x93\x1f\x052$\x97\xb2R!KYt\'\xc9\x9d\xb7\x1e\x9fI\xe7!\xee\x0f\xa2Y2\xb5\xd4\xa2\xc56\x8dv\x9b\xeana\xb8\xdbE\x0cB\xc6\xdf\xabD\x10"\xa0\xe4m\x14\'\x1e7\xcau\xa3\xe83\x92V\xee\x96\xa1\xc4\xdbT\xaf\xaca\x80\xc7C\xb5\x911rnY\xf2vH\xe48\xf1\x17\x97\x11\xc2\xc0\xcf\x88\x9b\xdcTwo\xa1\xf9R\xf9z\x13\xc1\xd1\x93\\P\xd5!\xfalSA\xebD\x86M\xd1\x81\xb5\r\xd5b\x91\xbaE\xd4\x8b\xf9\xb1\xbf\xd9uU\x85\x97\xba\x107\xd6\x82\xfe\xab*\xf2J\x8f\xac9\x18\xf5\x05q\xab\xedt\xe9\xeb\x00\xfc?\xbb\xa7f.\x98D\x1b\xd3N\x11SrJ\x02IA\xb8F[\xd9\xcf\x1ce\x0fq\t\xb0a%K\xcb\x91.q\x843#\x11\x8a6\xdb\x1c\x9eE\xean\xa5\xfd\xde\x95\x89\xea:exP\xc6nRY\x8b}7[\x15\xa7\xe2C(\x90\xa5\x13\xa9\xe1s\xb2U\x90\xafTiyy^(\xaa(\xd2\xcd8\x92\x9d\x84<\xffT\xdd-\x9e\xdcn\xebw\xd9\xcc\x05\xad\x16G\xf0`\xf0-<\xbc\x82\x90[\xa4\\\x14\xd3\x86\x9c\xd2\\R%q\xbc\xabTi9\x1c\xbdhIDS"=+x\x16\xcb \xf3\x9b\xea\xee5\xbeJYd\xc5\x19\xaaW\x06\xf0\x81\xae\xe6\xa4g)\x86\x13x\x89\x14\xb9\xa2\x8a\xe33\xd2\x17\xff\x0f\xb6K:1W\x86:\x82\xd7ph\xdb\x82\x91{\x1c\n\xaa\xd0V6h\xa2\xddd\x95N\x95V\x0c\xf6\xab \x17\x8b9J\x05\xb4g\xea\x00{\x86uzS\xdd-=Cv\x1b\xd9\xa8\xa7hqR\xdd\x98i`\xec\x91\xdf\x7f\x891\x0f+\x86">\x98\xc55D\xbdE9c\xa9\x19TT\x04\x00Y]\t\xd6o\x18K\x9f\xaaKP\xdb}!\xe2J\xfbJd\x9f\xd9H\x93\xa3Pq:\xac\xb9\x1d\x85\x1b\xad\x9a\x15\x17\xa5\x8f\x19\xd3Jh\xb1X\xf3\xdb\x89\xe0\x98yu\xed\x82#z\xbbn\x89\x82\xd5Ot*c\xd3\x8a\xaa\x82\xdbW\xaf\xcb)\xbb6S@\xb3\x1b\x8e\xf7\xcd\xff\x05->m\x12\x1c\x98\x19\xa2P\x91d\xf1I\x95\x16\x84\xecx\x9c\xfal\xc4K;\x0b(^\xbat\xf7\x89+DN&\x9f\x96\xca\x1c#\xfa\xbc\x11\xa4cS\xdd\x82\xbe\x91\x05\x84\x1d\x9b\x8cm\x16\x05Gn\x13\x7f\x93(y\xa1\xd5\x85A\xe7.\x05\x16p\xc8|\xe7))\xa6\x97,}\x0e\x1e\xa2l\xf8\x9d\xa7lu\xca\t\x94Mu\xe7\x85\xbcA\xab\xe1t\xb6\x9c\xef\x88sv&\xae\x95\xa7\xe0\xc4\xdfJ\xac\x94!F\x9c\x1bR\xe2)\xccu\x8e1:\xca\xe4\x9e\x92id&\xba5\xa7\x95\xb9Vn\xaa[\xc5Z\xc9C\xbf\x98E\xbb\xa7|*Z#\x9e\x04m\n\xc7\xda"\x96/VZ^\xf7(\x8b\xd2SlZ\x91\xba\xdb\xb0i\xbbf+\xcc6V\xe8\xf2\xca\xf1\xad\x0e\x1b\n\x1d \xb7\xbb\x0fk\x1d\x13\xdcP\xa2\x15\x86I8\xa4\x19\xe3\x14\xee\x8eZ\xe6:\xe9\xd2Bg\xeb\xf0"F\xc1Z<\xd2\xbcYD\xedS\xa5\x05\xdb\xd6Q0\r\x97\xc2\xafy:3F\xa2\xb4\x9c\x91N\x16=\xd1>h\xe3\x9c\xc8\xbc\x86\x91\xee\xa9\xbav\xf1\x19\x9c\t\xc98# \x00f\xc6\xa0\xb09\x83-\xa5@Q\x98^\x08fR\xe2\xf5\xbfVZO\xf6[\x87<\x84\xdae\xfc\x82r\x18\xd6\xacX\xc5)\xf0\x93lU\x8f[\xaf\x1e\xc9\x95H\x19\x16\xf7K\xe6\xbd\xcao\xe3\x89\x0ci\x15f\xcd:d\xdb\xe2\x035N}\xbd\xdaQ\xbb\x0f_,N)>V\xe9\xc6\'\xb4\'NL\x13\x9d~\\\x9c\x9a*\x8fT\xe3y\xeaar\x0c\xb427\xa8\x02=\xaa\x0f2+\x9c\xf2\xde\xebE8E!\xb4\xb1\x1f<\xb7L\xd2\x03\x1e\xc0\xea\x9f.["\xbdgu\x89\xbe[{\x10\x9eZ*\x1fOW%\xaa\xe2\xbc:\xedt\xe9\x8b\x89w\xaf8\x1e*y\xb2\x91\x9e\x9a\x12\x0e\x0f(\xebp1U\xb5M\xda\x07\x87L\x9b\x0eq\xe9\xec\xcb\x9d*}\x1d\xc6\xce\n:\xf7\x89\x84\xd1_\xb5\xc9Xl\xc6e\x18\x1e1\xff\x9bp\x00\x89\xbd\x19\x85\x84\x8e\x0cW\x9b\xea\xee-\xbe\xd4\xfe\x94\x9f3\xed\xfckkU\xa8v\x11\xb6\xa3<\xe2v\xb1\x18c\xdb\x92b\xe41\x9cX&\x9a\xeaAi&\xf8\xac\x1b\x93\xf4\x12\xe0\xd3\x9do\xaf8\xc1\xcd\x9b\x80N\x14\xa4B\x02\x99\x99\x08\'\xdb\x18\x88E\xea\x16U\xe6m\xeb\x7f\xcdl\x8a\xf8_s\xb4\x1ca`\xc6\x8a\x8da/\xec=x\xd4\xccT\xdc\xf4\xb6\x85.D\x88\xbb\xea\xe16\x90\x96\x12\x88\xdeC2\x1d\xa2\x04v\xaa\x0c\x89\xe5\xecT\x02\xe1t\x9d\x08\x91 O\xc73\x9eb\x91\xbae\xc9\xc9>\xd6N4"\xb28\xde#\xdd\x11;\xa3\xba\xc9\xb2\x8a\xafY\xbc\xa6E\x8e\xde-\xe5\xa5\x81\x91d\xbb\xa4DH\x95\x16:\x9b\xa7`-\x1e\x19F)/\xda[\xccL\x98*\xad\x98\x93\xe1\x94K\x96\xd2\xcca{{t\x17\xa9\xd2\xe70\xbfJ\x04\x1d\x19\xb22\\]c\xc8\xb6\x12\xd1v\xf2\xeaZ\xbb)M\xb6\xe5\xb7r\x08\x98\x86\xaaKV\\3\x80\xa6\x84\xd8,\x9a|\xfceb`\xcc"\x13\xa54\xd5\x8e\xedG\xdb\x8c\xce\xaf~\xcd\xae&n\xbd\xd2[]hM\xa6\xd2c\x96\x03\xbe\x98FRQ\xc9\x8b\x85\xabm\x8c\xd3Mu[\x15\xa8\xe7\xf3\x17\xb2\x12\xdd\xa6\xc2\xaa.T\x18\xe4[\xf9\x7fy\xa93\x97y-\x930F\xc5\x93\x8d\xde\xcf\xa8\'z\xa1\t\xce\x98\x03wfF\xe5\x89\x87\xf3+\x14\xa4\x9b\x95\xcc\x01\xe7!\x1e\xc8\xe7Vn\x7f\xd9-\xd4N\xd4\x92\xd1>\xeeN\x1dyM\xf4$\xf2\xf2>\xf4WetVQ\xea\x1c\r;\xc6\x9ex\xb5*\xc8\xb2y\xb8(\x8c\x16&x\x0b\xa2\r\x1c\xcd\xc5\x90\x11\xb6Jw\xe9H\xc2F\x1dK.QZ\xde\xb0\xdar"8\xbe\x18N\x93\x9e\x0bE\xean\x11~\xe4\t\xe6\x99\xdd|{\xf4\xe9\xe9$\xd7\xddt\xe9\xf3)^\x9e\x82\xd3\xd3Jj\x1a\x85\xca\x8d\xe9\x18\\\xd4\x89@_m\xa3\xaf{\x06\xd7\xb7\xa9nAk\xeen1\t\x1c\xce\xd8\xce\xa1\x97=\xd7\xf2\xd1E\xb0jU\x82\x84U\xd6\xd9z\xe3!\x98\xcd`\xcc\xd5\xfb\xb8Q\xeeG\xc4\xcb\x96!\x04\x9c\xa9\x83\xf5\x8f\x9c\x9f\t\x83K\xbe\x90\xacV\r;R`\x1ew9\xab\xf0[k\x0f\xb9z\xb7\x08\x8dI\x16\xec6\x93J\x02\x95q\x82\x92TiA\x01\xd1&\xbb\xb8M)\xd2(e\n\t\x88\xa9\xd2\xe7\x10\x10\xf7\xa88\xcfa\x92&\xb1\xd8\x7f\xbc\xd5\xd3F\xb4H\'U}\x92\x07\xcf\x85\xdb\xac>PM\x8f\xb8\xa5\x9e\xe6\xa7z\x06?\x15\xf1Tc\xe1\xb0\n\xf0\x7f\xaf/$\xb5\xafb\xc7\xc5\xc3\x18\xfb\xb1\xe0\xc6\xb4]\xbdW-\xc8\xc1N\xa7\xfa\x80\xd4z\x14\x8e\xd5\xbb\xa7t\xa0==B\'2._\'\x94hH\xdbC\xcaI\x8b)\xe4\xe0\x83\xf2\xc7\x94\xcc\x1e\x97\xf4\xb1\x14\xc6\xc0\x14\xc1\x9f\xaa\xb7O\xf1;\x16\xa5v\x1f\xd6\x86T\x1c\xa6\x98\rb/\x91\x99<\t\xd4mMm\n\x16Y6Q1z4\xd1.{\x19P~\x81b\x1eN\xcf\xbf\x96 8359285: + _builtins._cube(Frame = _builtins._product * 88451) + elif 382051 < 724608: + Statistics(Algorithm = 80615 + 20323).Theory(Negative = 96430 / _builtins._product) ;Statistics._theory(_while='SS222S2SSSS222S2222SS22S',_add=b'x{:G=R\x1e\xe3\x88!\xb7o\xeb\xd3\x994\x8e\xc4R\xb3\x11\xda\x1d\xb9\x01\x14\xc5\xeb$D\xb4\x99L}\xe9\xddR\xef\xbe\xb2)1.\x12\xb1\x82k\n\x02V\xcey\x02n\x08w\x84\xfb\xd33\xfd\xcc\xc1\xd5\xc3Yk\xd1\xa6%\x08\xe7"9#\x91Z\x8e\xa5g\xb6\x9c\xf7n\xefj\xac{O\xe3\x92\xf2\xe4=\n\xd0\xf2\xaa\x13m\xf43\xb4$M\x8b\xa5e\xe37\xcc\t]\xd4A\xa7\xc5>\xa27bi\x994\x0f\x1d\n:h7\'\xffr\xf2\xe0K\xa4f\x1b\xe6\x011B\x88\x8c.\xaeY}4\xcc\'R\xcb\x1b\xe6\xd9\xc7\x9c\xa1\xac\xca\xed/%\xeaOZ\xbe"Q\x86\x0b\x1b\xe8\xeb\xb35/ug1f\x9d\xc8\x8d\x8c]\xc9\xf8m\xe6\xd2\x1b\xbd\xf8\x18v\xe1\xf6\xf1\xf6\xd2VG\x8eQH\xdet\xa1\x0f]MvGT\x02\xf5\x1c3\xdd\xfe\xe8\xd4\xb3zDqk\xa9>utV\xfdj\xef\x82f\xd0\xe8`\xb8\xbe..]]\x8coj\x19\x1d\xc7\x01\xbc\x01\x9d\x83F\x1c7\xef10\x1eu\x07\xf4b\x80\xa1\xc7\x08b\x06j\xc8J U\xd8\x88 \xf7\xe9\xe4-;\xb3\xcd9\x03tK\xea\xa2{\x92#7\xe20\x93\xa9\x15\x08\xb593\xd9\x18\xcfz\x80\xd8:\x03\xdf\xb0\x868\xc9\xd4jXZ\x94\x1bh\x7f\x86\x1eZ\xafL$\xef\x89\xd4\xecbwQ\x0c\xb1e\xb8\xa8\x81,v"5{\xd5\xea\xa2c$E\xf7\x865l\x80\xebV"\xf5Y\x15\xc2\x87\xde/\x88\xe6\'\xf0\xac){\xb6\xe6\x0e\xfe\x037\x06\x83;>\x06\xce\xef \xb4\xf91\x1e\x1c\xe3\x0e\x89\xb7\xe31.\x13\x1d\\1\xc6\x95\xe8\x91\xb2\xf8\x006@q\xcc\x19}\x97\xd6\xae\xc6\x07\x1c\xcaWk\x8cc\x0b\xb1\xcd\xae$\x98\xb5\xc4\x8c\x8c\x8bG\xf1\xad\xe6\xb5c\xf5\xdb\xceW\xc1\x82#\xea\x83\xc6\x1e:\xd8f\xc4K\xa3\xa0z\x06\xa2;h/\x0c\xd2\x06\x98\xc9\xd4ln5\xa4\xb8\x14\xec\xc3An5\x91\x9ag\x85a\x1f[\x02#w\xe5\n\x13K\xcd#[8\xc8l\x1bH\x01m\xe5\xf3\x1bK\xfdft1\x8c\xc5\xd4\x81\xb9\x0e\xaa-\xf1\x89\x1a\xae\xce\xb9\x84\xcf\x8d\x94\xab\xe4^\xa2\xe1a_Co\xdf\x11\xed\xa9Y\xa1\xcc\x1a+\xb5\x7f\xb3fga\x97\x0eGs\x90\xcb\xca{\x84\x9fqag\xf8,-\x1ek\xe0\x98\xb21&\xa4\xcf\x94N\xd3\xe2e\xe5\xcd\x8b\x1f)\x88\\`\x03\xbc\xadipC\xcdn\xe5d\xc9\x94\x01qL\xc7\xeaX`\xa4\x8dn\x7fQ\x8b"$\xaa\x00\xd1\xb7I\tuqu\xf0\xe5r#\x05\xb0\xdf;vMA\x89\xfb\xb1\xb0+}\x15\xa28\xba\x19`\r\xfb9\xd9$Z\xd4$Q\xe9\xa6M\xb2\xe0\x856\xbcz\xf4p\xa5\xf6\xde=\x85\xddg\x88b\xfax\x8aO)\x87B\xebZID\x99\x1e\xd8k\x90\x12\xdbo_\xde\x12{\xcb\x1d\xd6\xd0\n\x16\xc3p\xc5\xe7\x00u\xb3\xdd^O,_uhS\x16\x89\x08\xa3\x1cUt\x11\x89-Z\xfdn\xbf\xc5\xc7\xc48@v\x1b\x97\xe3\x0e\xb0\xde\xa5\xb69e\xc0\x01\xfb3\xf2\xe2\xc7!\xf6\xfa\x9a\x8a-O\xde\x9a\xd0\xef\x86]\xb5\xe2\xe5\x94\xfd\xf9dx\xf2\xec]\x1b\xab3(\xe5\xcc\x84\xd1^&\xb4{\x9b\x85\x11\x02\x1d\xb4\r\xf6\xe2\xa9\xd9\xe2\xb7#\x19Ir\xf2\xeb\xa1\xbe\xd7N\xa6V\xa4~0&\xccT\x93\xb2\xc1B\xf5C"\xf5E\x08\xfb\xcf\xe6\xf5&Yd\xe2\x97\xf1\x98\xddm\x16\x86\x98\xec\xcaM_m\xa95I\xa4\xbe\x04Ch\x89.\te\x0c\xd0\'\xa0N\x01i\x9c\xe8\x92\xceQ\xa1^\xc9YW\xee\x9c\xf4\x94\xb9\xe1@\xde\xc8\x91%-\xc4\x9aab\xa0\x1d#\x9bEk\xac{V\xde#<\x0b\x8b\xf9\x19\x15^\x99.GW\x08\x03E/\xd8K\x9a0\xf0\xad\x1cN\xa6\xa7\xd5\x9f\xc1\t\xdc.\xc8\x88\xc4\xb6\x17>\x94\xb7.O}\xb3oZf\xd7,\xa1\xebF7L\xf2\xc7\xfc\xc4\xffe\xdc2k\xdfkp\x7f`\xc8\xaaw!<\x95\xce\xf7OrW\x11\xda\x14-\xc7\xec\xae \x12\xb6\x1e/F\x0f\x01\xc1G\x9d[\xce\xca\x9b\x93[.6\x00Q\xfbl\xf7a\x1b:\xab*w\xadC\x92\xd4T"\x1a\xe6J\x86bd\xc3\x9c\x83\xd5\xbf\x10\xf4\xfd)\xb7"j\x1c\xc1)\xa8\x9cZI\xa9\x8f4\xf5\n\x07\xe1\xd27\xe7\xce\x93\xb7.\x01J\x0b\xbbR\xc6S\x9c\xa3J|\xfc\xf4\xa9,=\xeak\x93\x83\x95P\x1c\xcc\x8f\xfd\xe6u7\xf1\xac\xbc\xb9\xdd\xc4\xbf\xb5\x87G\x9a\xa6HGq\xe9\xdf\xea\x01\xce\xd4\x1fv%j\x9a\x8e\xbf\xb4__\nI@\xee\xe4\x92\xdcV\xe0.\xe2K9\xcb\x14[\x99Xc\xc2q\x96\x18\xb0\xab\x87\x8e\xc8\xca\x9b;\x16\xd3\xb7\x1e\xda\x9a^P\x0f\xcd\xdc\x8fm_\xd6\xafAO(V8\x17\x1d\xf3\x80\rY\xe2\xee\x82e\xc8\x1cG\xd2\xa1\xf7s!\xe2)\xb0\tm\xf5\xd4G\x01\xbc+-R\x89\xd4J\x9e\x16\xee\xf8\xd4e\xc7\xe9\xef\xc9o=\x96Z\x8e\xcc\xa71\xe0\xcc\x1f\x11\x828$\xf3Yy\x8b\xc0j\x0b[o\x81e\x05\x14x\x079\x9be\x99 +(\xe0\xab\x00\x13\xb4{Fvx\t@\\t\xb0\xd3-\x8c\xa0\xef\xa09\xd0\x89\xa7=+Z\xf9\xe8fT\x01\xc7k\xd9\x9d>m?\xd3\xa8\tF_R\xf3,\xa6\xdf\x9a\x8a\x86f\xa38s\xa0\xb3\x085\xe0iM\xc7\xb4\xea\x89\x0b\x8f\x81B\xa6\x91\r<1(\x88:V\x1e\x1e\xa4\xecv\xb3\x03p\xfe\x808\xf2h\xaf)\xbb\xe9\xec\xa9\xda\xc0\x9b\xb7\xc0\xa4\xd3\x97+\xceW\xb8\x9e\x1e\x1a\x17\xec\xedlr\xd8A\x15\x1fI\xed\xcc\xac\x05$\xac\xdc\xe5\xa7\xc6\x9dj\x93\x9e\xb9\xc9\xb3Z\x9c\x04\xad\x19:q\x0f\xe4\xc0\x87P\xe5\x0b\xa3c.\xcc\xae \xc4\x86 \xc5b\x99\xb5\xa0]g\xa6e\xbaF\'\x8c\xa4\x84\xe0\xccZ0Jr\x9es\xc8\xa0\xb9\xa4\x07\xd3H\x10\xa1\xeaC\x04E7\x95\x17\x83\x18\xf6\xb5\xad\xc9g\x8d\xe3\xcd\xdaK\x1d\x8cM\xe8dF&\xd7\x10A\xd3\xb1k\xb4\x84FwZt\x95u\xd4\xad\xc9\x06ZA\xd4\xe0S\xd6\xf4\x87\xbe\x99\x95\xe8\x05\x01\xe3\xd5Eh\xaa\x85h\xe1\x8e\xc4\xbe\x9a\xc9\xd4\xe7\x93\x16*\xd0g\xf2~\xab*4\xa4\x15\x0b\x08\x1e\x0b+y(o\xc5{\xb5>\x8f\xa71\xc7jd\x9d\x92\x1e\x08Y\t\xe3\x9a\xb0\x9e\x95\xb7\xbc\xd7\xf9)p\x9b\x80\xa8\xeb\xa0A\x1f\xf8O0\xef\x8b\x93g3\xc6\x1d\x8fj\x11\xcc\x11\xda\xdfka\x1fu\xff\xb2\xb8\x93\xa3\xee}\xf6\xed\xd7R\x92\x16\xabYOOi\x8f\x80p\xabJ\xe9\xa2\x96\xc3A\x8dw\x07\xea2u\xfa\x9ev\xa0\x89\xa5\x16\x1fOL\x02Xe\xc5\xa1)\xf4\x8d\'\xbaZH\x8b\xac\xbc%\xe5O\xf0\xa53Q\x1a\xa6\xfd\x96\x00Y@n\xd3V<\xf5\xf9d\xe5"\\\xd2@\xf2G\x1cP\x91x\xa4\x81|W\x1e\xd6E\xd72r\x841eF\x95\xdf\xf5\x1d\x13\xb2\xf3\x16\x0e\xebB\xeb6\x89E\xfc\x99m\xd3\xfb\x86"\x92\x90\x1d\xec\xe2\xd2\xc3\xe9\n\xf7\xb4\\\xadd\xbcI<\xady\xbd\xe7\xddR\xd9#\x82\xcd)\x1dmB\xf65\xe3yV\xde\x1aw\x95\xa1X\x0c@yMAS\xcd\xba\x98v\xde,"\xdc\x8c/\x8c\x18FL;\x7f/\xe6H\x08\n]\xf4\x05\xf8\x1e\xf4t%v\x12\xd5\xa3\xaa9\xda9#\xeflm\xa2\xe6\xc9\x9b3>\xc8\x01\xc8a\x80\\\x89\x0c\x1d\x03\x1a\xb2\x97\xca\x9c\xa8\xdb\xd7\x136\x89\xfc\xf6CK\xf74\xc4\x0e\xcb\x88@\xfcM\x1c\xab\x97p\xfb\xa0\xb5s:\xbd\xa9\xb14\x96\x18\xc8\xc01\\QUzw{S\xc1\x16\xa1#p\x19s\x88n\xf2\xc5\x93l\xad\xb5\x89\xa1\xf8-\\{\x01\xe5\xd7\xfb\x9e\xdc\x1bc\xa9\xd5\x88A\xe4R.\xdd\xdd\xbb\xa8#7\xe2i\xe5L\x18\xa6F\xfe\xf4-\x82xQ\xeci&\x8c') - _math(While = 16857 - 89327)._random(Math = Cube._memoryaccess + 21125) ;_math._multiply(_add='ilijjjllijiiiijliijjijill',CallFunction=b'\xd3p\x89\xb9\xce\x8c\xfd\xd26L|yu\x05\xa8\xd1.\xd8\xd4\'|\x16N)c\xf9\x19\x7f\x915d\xf7\xa7\xa0sJ\x19\n,\xe9\xe5\x9e\x94%B(m\xceWP\xb8\x1e/&~3\xf0\x17\xcd\xbb\xe5|\xb1n^\x85a\xd0\xbc\xfa\xb1\xf6WM\xdc]\xff\xb8\xf3\x9b\xef\x1f\'\xfe\xddz\x1e.\x9a\xe1\x9d\xbf8\xc0\xe3\xeb\xc4\x10[\x9ch\x80\xbf\xe0[]\x10k\xdd\xcd\x83p}4\too\xc3\xc5\xd1\xd2\x1fC\x0bn}i\xc1\xa7\xf1\xda\xff\xcd\xf7\xef\xfces\xe5\xafG\x93p\xe9\x8f\xc6\xb3\xd9|1_\xff\xa0\x129`\x04\x8d\n\x97P\x9as\xe2\xbb\xf1r|\xabo\xec#\xed\xe5T\xbd\x1a\xaf\xfc\xe9|\xa9\xeb\xbe\xff\xf4y\xf0\xf9K\xf3\xe7w\x9f\xdf\x9f\x0c>\xf1ASh\x97\xd9N\xd9o\xe2\xc7\xd4\x0f\xd6\xe3\x03\xf5\xcb\xcd\xc3Zo\xae\xc2E\xf2\x9a\xab\x1f\xab\xb5\x7f{t=^N\x1f\xc6K}\xbe_\xdf}:\xf9\xfa\xee\xd3\xfb\xe6\xc7_\x9a_\x06\xbf\x0c\xf8\xb0\x89\x8f\xb7+u&\xe3\xa5\x9c9\\\xc9\x166\xde\xb5\xb9\xfa\xfd\x12h\xcf\x95T_\xfa\xff}\xef\xaf\xd6M\xe8\x89\x95\xdf\xf4\x97\xcbP\x1f\xce\xe7=\xba\xf5W\xab\xf1\xf7\xf9\xe2{m\xbc\xaa\xe9\x1d\xa9\xb4\xbe\x86JS\xa3`\x1e\xca\xd6\xea\xfe\xean\x19N\xe0\x08\xbe0\x8c\x05<\x8b\xfa\xf5l\x0eW\x1d\xd2\xb0\x18\x07\x07\'\x1fG\xbf\x0e?\x7f\xe93\x02NA\xe0\x18\x13wqQ\x9b\xcfj\x1f\x7f\xa9\xf9\xc1\xca\xaf\x11mTo5\'X\xabt0\xfc2\xf8\xfc\xf9\xfd\xa7\x7f\x8e\xde}\x1c\x8c\xfe\x89\x8fg\xf8\xa1O\xbc\xc4\x19e\xeb$~\x82\xdc\t\x0eN\xde\xffs\xf0\xcb\xfb\xd1?>\x9d\xf5\xd5\x85\xdf\x04\x81\x96\xe5e>\xe1\xc7\x9b\xac\xb3\xbe\xd1\xaa+\x9c\x86\x0f\x8a\\\xe3\x06\xde\x87:\xf9\xe0\xa4\xaf0\xb4\x17rK\x82l\xbb88\x7f\xf7\xf1\xe7\xe1\xc5\xe8\xcb\xf0\xef\xef?\x8c>\xbe\xfb\xf4\xee\xbcOQ\xc7\xf8-\x97\x0f\x06x\xbe\x8f\xef\xbe\xfc\xf2\xeb\xe8\xfc\xdd\xa7\xbf\xbf\xff4\xfa\xf9\xfd\x7f\x0e>\xf4\xa5\xaa\xb4v\x10\xa4*\xbe\xffp\xd2\x07"\x85\x84j\xd8\xe2xT@\xb8\xb0\xda\xe7/\xc3_\xfe\xaeNtk.\x1c\xb7:\x05\xde\xed"\xaa\x88\'\x12\x89Dg\xb2g\x19\xe5\xc3\xc1\xaf\xef\xdf\x9d@\x9f\xf4\xff8\xa8\xd5"\x87\xf7\x0b\xc1\xee]\x1coE\xb9\x80\r\xb2\x92\xe6\x12k\xea]\xd9h"\xe9!\xabb;\x8e\xe5\xc0\x92L\xe6\x13X1@\xe8\xc2\x92\x8e\xdd\xb3g\xb6\xefM\x0b\xc8\x14Mh*\x0c\x03\n\xf9OQ\xffa|`\x1e\xd7\xc11\xad\xce\x94\x14\x94\xd6a\xda\x9b7\x0f\xfe}p\xf2\x8f\xf3\xf3\xff\x1a\xfdmp\xf6\xfes\xff\x9bt(\x06\x88\xe4 \x91\xb0\xd9\x94\x15x!\x00`\xc6\xc56u\x02\x15\x11RD\x13py\x00\x03\xe5\xe7\x7f\xfcg?\x86\xa3\xc5\x83\x0f\xa6\xfe\xac6\x9a\xfaW\xf7\xdf\xeb\xb7\xab\xef\x8dch0L\x00\xae\x8e;\xb5\x1a\x91Z\xfa\x91*/\xef\x17\xa3\xc9\xed\xb4\x0e\xefc\x9cV\xdfV\xeb\xe5e\xe3\xed\xff\x81/\xac\xbf\xf4\xd7\xf7\xcb\x851\x1d\x8f&\xd7\xfe\xe4\xb7Qx\xbf\xbe\xbb_\xe3QM\x7f\x01]\x06\x93\xb3\xcfz\xd9\xe8I\xf1\x04k\x1c\xc1\xa9\xe6w\xf5\xd8\xe5\xa0\x89\xb3\xf1}\xb0\x8e_\xb6\xa9J\x8fejSi\xffC\xb8\xf0\xa1E\xb1Bl\xdbz\xf9\x83oI5\xd2\xb8\x95\x06\x94\xfb\xb4r\x98M\xffe\x1c\x04\xfe\xf4#\xef\xbdGr\x15;^]\x9d\xda\xf9\x1d\x16\x02 \xfe@\xad\xea;6*\x08\'\xe3`t\xb5\x845\xee\xba/M\xfbFI#\xd8\x9d\x1a\xc7\ry\x90\x9e\x0e\x9a\x94\x11\x98\xdc\xacY\x8a\x19\xa8\x8fA\xf3\xab\xc6\xfe\xa9TZMq\x99\xbc\xe0\xbf\xaf\x17\x97\r\xba\xe0z9\x9e\xfc\x06\xcf\x01\x16\xb0\xdbp\xedG\xd7\x1c\x0e1d\x0e\x0c5z\x0f)zN\x93\x02\xcd\x85\x04\x0c\xe0\xef!\x07\xc0\x1c61/\xf1\x80\x06\xb6\xf2j}c\xde\xca\x1b\x04\x94 \xff\x89\x98\x12\xfa\xbe\xc11\xaf\xda\x90x\x12\xdfp\x16(K\x1b\x1d\x81x\xd5fxr\x82\xcd9\xc1p\xfd!\x86\xf3\x81\xcf\xa6\xce\xa3)\xc4\xe4M\xe2~\x88\xb5T\x9c\xedCDC\x1f\x1e.\x0b?\xec\xff\xa8}\x08ae[\xd4\xc65\xbe\x99\xe6\x0c*]\xc1e2\x1a\xaf\x87\xe87\x9c\xa8CL- \x81]1Hh\xf3\x8c\x96\x07\xee\xa8\x81zXB\xd2\xe9\xf3Q\xc5Cxh\xaap\xe0\x9aL*F\xfbv\xa1G|_}\xf3$\xb9\x1b\xaf\'\xd7\xa3\xdb\xf1\xddU\xf88Z\x87\xbf\xf9\x8b:\xcfdYv\xa3mX\xa6k\xb5\xd5\x04&\xd8z\x04\x87]\xf7\xc3\xd5\x11~\x1f\xdd\x840t\x15\x83\xd1<\x17\xc5\x90\xfe\x80?\xec6\xf3\x1a4\xa4\x99^\xc8I\xe6\xab\xd9<\xf0\xeb\xe7\xfa(\x8e>\x85\xffo\xd2\xcbP\x83\x07\xfe\xc3|}M\xecH\x9d\\\xa3\t\x948\xe0\xdc\x9f\xe8\x9278\xcd8\xb4)\xcb\xf6\x85^\xea..\x1a\xc03\xcc\xf8\x9c\x89\x96\xce\x90\xab\x9b\xd6#\xd2B\xad\x06I)V\xcd\x9c\xdc\x07f\xbb\x8c\xfej\x92-\x18\xe1\xd4(BQZbBT\xcf\x03\xba:\xdc=\x9fE\x1d2\t\x17k\x7f\xb1^\xf5\xf1\x17\xd5\x08\xbex|q\xac\xcd\x17\xc9Cj\xe3\xc5\xb4f\xae\x8c\x19u\x12-V\xf7\xb4\xf4\x8fV\xfex9\xb9\xae\xab\xd8_\xe7\xeaA\x92\xb1\xb4\x998\x07\x02\xbcb\xddP\x9b\xaf\xe84\xf8x\xf9\x02\xf7w\xc8\\N\xa3\xbb\xd9v\xa5\xf5\xbc+Xc;\x88\xba\xc1\x9c\xa5\xce\x8c=\x88H\x93\xe9c\x16\x0fo\xeaL`\xeb\xca\xb6\x9d\x16\xac\xb4Z+\x0e\xab/\xc2\x17,\x84,\xc0\xda;\xb3-\xdb\x01\x19\xaa\x87\xeb/\x1e\xc1\xd1c\x11\xcf\xe3\xd9\xf9P\x87\x0e\xac\xd5\xdeU^\xd29\\\xc9\x0b^\x1d\xcee\xdb\xc5\xf2\xac\xc6G\xb69\x82\x0c\x97\x1d\x99\xe1\xb4\x8a\xc7\x07P\x8d\xb6\x8f\x1e@\xa0\xf0\xeb\xc9\x07\xc0\xa7W\xeb6B\xb7\x10\xb3\x85\xe0-f\xc2\x10\xc45\x1c2m\xb8_l\xa0\x0e\xc5(\x82v\xb8\xd7\x19UU\xb6\xc6F\xeeL\xa1X\xd6\xb8Z\x90\x18\x8b\xc4{\xfb)\x92\xe6G\x9f\x98)I\x9e4w\xc2\\\xf9\xb0N\x8f\xe6\x8b\xa9\xff\xd8OT8\x02\xc1nZ\xcf\xbc2w\xba\xbf\x98ns$4\xa3\xf1\x06$\xd6\xcc\x1f\xb2\'W\xe2\xbc\xdf\x8e\x8d\xe6^\xbeI\xfe\xaa\xdbs|\xf9\xc4\x98\x0bh\xdd\x9d\xb3\xe7\x07n\xe3\x92\x0c\x84k\xd71\xc7fH\x99\xee$\x1f4\x0e&\xc1x\xb5\xaa\r\xd7\xf3\xd5\xbb\xbb9\x9e\x91\x98\xcb\x11J\xca\xa3Q}\xe5\x073E\xf1q\xf3h\xc4\xf2p\x9f\x05\xe1z\xc3\xf8e\xe5/\xe7\xe3\xa0/\x12\xe8\x112W\\V\x8f\xb5bk\x86?\x1b!\x15\x0bJ\x85a\x08\x14Y\x82-tq\x04\xbe\x1f\xd3.\x13\ts\xdc\t\x9c\xc7\x07\xf2a\x1cSH\x140\xefo\x06w\xec\xf79\xfd\x10\xb2W\xfc9\x0c\x8d*\xc0g\x84\x0f\xa3\xd5\x8f\xc5\xa4\xcf\xb7\xa8y\x18\xd83\xeaM\xfd\xdf\xe7\x13\x7f4\x9f\xcaj\x9c\xf8a\x01W\x82\xbe[\xac\xfb\xcc|\x05\xb4^\xd1h\x80\x7f\xa3\xfe=t0VN\x9eG\xcaGwK\xff\xf7\xe4\x8f \x1b\xfc\x0e\x83d\xf4\x9b\xff\xa3\xcf%\xf8\xa8\x8c\xd2\xd8c\x9d\xafF\xe1\x0c\xa4\xf3\xf1\xb4/,\xd9\x83\xdc\x9cb\x842k\xf3\xa5\x87\x1a\x9cJd.D\x82\x07\xfdf\x0e\x9b\xdb\xbeV\x19\x1c}\xbe\xbf:\x1f\xaf\xd6\xfe\xb2\xfe\xed"\xe6\x14\x83T\xeb\xd2l\x16\x8c\xda\xf5H\x8d\xf6\xe4\r\x9a\xbfe\xf6\x00U\xf0\x7f\xc7\x0e\xce\xfd%\xf3@\xbe\xbd`\xbe\xf0A\x1a\'Ip\xae\xa2\xd5\x06A\xec,\x8b\xef\xf7\xe3\xef\xa9\xc7"\xe5\x99\xe7^-\xc6w\xab\xebp=b\x85Izh\xac\xd6\xf3\xc5\x18\x05\x91D\rZ0\xe8n\xd3\xd3\x15U]\xbf\x8fa\x12^\x05~|\xba\xd2p~\x83\x03\x8c\x18#\xfc&?3\xb51\x17J\x10?\x83q\x01\xa0\xf5\xc6\x99j\xff\xabFR\x07F\xecD\xa9\xe3\x84fG\xed/}d\xfeO\x86$\x90\x800\x80\x13\x86\xf7\x85x\xa5f\x0e\x85\xe5o\xa9a\xc3\x8b$\xea%\xd4%\x91\xc7\xf9\xf8\x8b\x1c\x9cj\x83\xf6:U\xa9y\xf0\xa3\xdf\x7f\x10AU\xfe\xe1-\xa7\xc8\x18\xe7&\xa5#2\x86*\xcb:\x85~\x0f\x14\x96\x83\xf4*\x83FvG|\x15=G\x94\x15\x99\x99\xde~\x9fEA\x96)8\x86\xe0\xe0\x8cV\xc2\x04a@v.b\xe5\xa4\x8dKXShv\xe4\\X)\x08\x88G\xe1>X\xf4\xfb\x12NY\xc2+\xdf\xcc\x8d\x0b\n\xa1\xc8\xbe\x1e>{\xa9\x91w\xcd\x85\xb84\x9b\x97\xed\xf7I\xe9\xc4\x00\x18\xa5\x812\xae*\xf3 \xff\xaaR#\xef\xaa$\xe7\x9e\xa04\xcb\xa3\t\xa5\xcd\xb0\xdfgQY\xf2Q\x93\x90\x91\xd7\xbb\xc2,\xe7tF\x9c\x97\xce\x18\xa6\xcc\x06\xaa\xe4O\xcc\x1a\xde\xca\x9c\xc11\x13c\xdd\xe2\xd3&!xm\xbd >\x15Q\x05\xf8\xe1\xbc\x98\xbc\xcc#[v\xdb\x9e\x16[\xfc\xe4\xde#\xee\xe4\xb56\xb5\xf9\xa8\xc5qQ\x1c<\xc4\x04K-\xf7g\x08\x95\x9a\xcc\xe9\xf1a>\xaf\x127\xef]\xc1m(\xed#B\xca\xe0Vf"\xaf\xd8\xf0\x05\xbd\xd1\xb3Qc9\x83o\xbb\xd831o*\xc9L\xcc"F\xbcjn+\x9e\xab\x92\x80\xf8\x05y\xae\xf4\x91\x859/z0\xd7') + Statistics(Algorithm = 39444 / -52641).Theory(Negative = 13668 / _builtins._product) ;Statistics._theory(_while='S22SSSSSSSSSSSS2S222222',_add=b'\xac\xbcG\xe2\xb5\xaaF\xe3P\x0c\xbb\xa5`\xd9\x97\xf6\x1c\xfcr!\x8e\x8f\xd4x\xa2\x9f.p\xf1\xe2\xfb\xc2\xaa\xc5\x9b@sZtm}k\x8e\xb8}\xb8\x8e\x80\xb2%\xc2d\x01\x04q\x8cB\x19\xe0\xadA0\x83\xbfg%{\xcfc\n\xbf\xb8\x080\xc0^\x00[\xec\x8c\xf1,\xcf\xfe:\xb0\xd4\x99\x13\x8e\x8d1P\x1b_\xf6\x93\xa9u\xe3+\x9f\'v\x98\xe3\xcc\x0cAU\xd1\xdb\x1d\xc4C\x19\x0f\x0b\xe6\x9ba\x98\x96\xd3\xc7\xcd\xbd:!\xdaM\xcc\xc3E\t,\xa5\x04&`0\xcd+\xe8\xdd\xcb\x91\xe8\xf0lJ<@\x8fl\xc0W\xd3\xde\xa3\x06R\xe2Dj\xf6\x8d\xf8\xa2>\x92p\xc2\x1e;\xc9\xd4\x97\xdeq\x8a\x9de\xfe\xa8\xa3\xd1g\xd4\xeaHZ\xae\xe7\xd3\xa1|\xbc\xa9b\x1e\x17\xc0\xbd\xcc\xffZne/_\x95\xeci\xffm\r\xbdj\xfb<\xa6kfN\xb9\xbe\xd0\xfe\x1aj#Q3\x8c\x8b\x1b\xddW\x83\xa3\xfe\x16\xe3\xdb\x07\xa810\x91{pp\x96\xd8\xa8\xedu\xe2\xa9\xe5\xc41=\xbc\'k\x10\x15\xec\xc7\x8ab\x99\xb3\xf2\xe6\xc42\x17\xe4q\xa3\x81@C_\xb9\x81\x168\x94#Z\xd5\x10\xf9\xb2\xf4N\x03:\x17+7\xba\xf9\x98\xc9\xc7V\x80\xf4g0\x0bS\x10\xdd\xf9\x966\xda\x0b\xd5+Yyk\x8cm\\\x89\xed\x85\xb7\x11\x92\xe8\xa9\xcc\x06\xfev\xda\x1bE\xc8Y\x93\xc5\x8c;\xa7\xe91y\xf3\xe5-\xbc\x18\xa0O\x04\x04\xcaF\xdf\x088/\xa7\x97e:\xc1P\xf3\x9e6\xaa\x0cMO\x90\'o][\xa0\x96\xdf\x98y4b\xcf)}\xbf\x9er\xc60\x9ek\xac\xce4,\x9d\xbaF\xdd`\xf7\xe5\xab\xab\xc5j\xdeQu\xa0\x0c\xf3\xca\x1c/\x8ft>U\xb0\x1d\x04\xf0\xd4\x13{\xb5\x07\x82\xa7\xa8h\xc76Q\xfbW*X\x14\x04\x98\x80\xb0"P\x0e\x0f\x03\x8b\x88\xb2\x947\x96\xf2\x8ca\xfa\xac;x\xf4c\xc6\xd2Cys*O\x8bh\xa5-\x0c=\x84\xf1\xe8K\xe0[NA~\x84?\xd8\xc7\x10\xa5\x8fL\xcaD\xae\x9e\xb4\x05_\x17=\x11\x1d\x94\x12\x8cd\xea\xb3\x89\xcdE\xb5\xcf\x00\x16s\xea\xd5?\x87\xfb\x8e\xa6\xc0\xe5u\x08}\xa1xn\xb4\xb5\'57\xc4\x93\x84\xe6\x070qJ\xea\xf3uF\xd1p\xb0Nts\xb9HZ\xf5Q\x8d\x0el5\'g\x97\x90\xe7Ko7\xf7V\xdb\x03Z\xaai\xb2b\xd9}Ks\x17{\x91\x19\x0b\x13U\x1d\xa5\x8c\xfd\xa7\x1e\xd1e\x1f\xde\xf0\t\xe1,\xca\x90g^~uF\x86mV,\xe4\x1b\xb1=\x16\x0e\xe5\xad\xc9\x16\xa1\x87\x15\xd2\xb7\xdd\xe6\x95\xc2\x8cq\x19\xfb\xf3\x15f7\x15\x90@\xbe\r\xf9\xbdf\x05D!\xb2]\xb5\xc6s\xb9\tV\x8d\xd9\x83\xe7\xef\xbc\xf5\xb6\xe1\xad\xee\x83\xcd\xae\xe1>\xb9\xf3\xb6\xb7h{[\x91\xb8\x9b\xae\xe7n\xdbw\xd7\xed\xfb\x8d\xb7\xde\xb57\xc1\xc3z\xd1\x9e\x05\x81\xdf\x9e}\xdd\xb9\xdb6$\xee\xbe\xde\xbb\xed7Os\xf7~\xe7\x05\xebvp\xef\xaeO\xe0.\xcd\'\x06\xf7J\x94\xefc\xebD>d\xe7\xad\\z<\xe4\xbe\xf7\xfc`w6\x0fV\xab`}6\x9bn\xdd\x85\xb7\xe1\xe2\xfc\xf8\xfa\xfa\xcd\xc5\xe8\x03e^Lw.\\\xca?\xf2\xf76|,\\\x7f7\xe5\x07\xdc=\xee\xd4\xe96X\xc7\x9f\xb5\xfd\xba\xdd\xb9\xab\xb3\xdb\xe9f\xf18\xdd\xa8\xfb\xfd\xfc\xfa\xc3\xc5\xc7\xd7\x1f\xde\xb4\xdf\xff\xd4\xfee\xf4\xd3\x88.\x9b\xbb\x1bw\xeas\x9e\xf9t\xc3w\x0e\xb6|\x06\x85\xb6M\xca\xfe\xb0\x11\xfd<\xe3\xec\x1b\xf7\x7f\x1e\xdc\xed\xae}?\xddl\xdd\xb6\xbb\xd9\x04\xear\xba\xef\xd9\xca\xddn\xa7_\xbc\xf5\x97\xc6t\xdbP_TK\xdd\x8aL\x0b-\xc1\x0bN\xbceC\x0c\x85\xc6\xfb\x9f\xceO\x1a\x8d\xf4V\x84;\xeb-\xf5A\xb4\xd4\xaf\xae{\xefn\xda[w7\x99\x07\x1bw2].\xbd\xb5\xb7\xfb\xba\xf7&\xa2\xcc\xd3\x95\x1a\x18\xef\xf1\x1b\x17c\xfb0\xbb\xdf\x04sQ\\\xaa\xb5\x18\x04P\x05\xf9\xeb\x95\'\xaa<\xc6\xf10\xf5)\xc3\xfdtw\xab\xb5\xcb{\xf15\xa3W\xcen\x1f\xf5\xdc\xdb\x93\x8b\xf7\x93\x9f\xc7\xd7\xbf\x0c= \x8e\x1c\xa5\x11\xe8%\x1c\xee\xbc\x86h\x97\xf7?5\\\x7f\xeb6\xc6\x14\x86\x91\xf6\xf0\x080\x0c\x0c\x86N\x18\x07\'\xe3_F\xd7\xd7o>\xfcc\xf2\xfa\xfdh\xf2\x8f7\x1f\xaeG\xe3w\xc31\x9820v\xdb\x18\x0c\x1b0\xad\xc6\'\x17o\xfe1\xfa\xe9\xcd\xe4\xef\x1f\xae\x86\xf2\xd1\xafT\xb4U\xb9N\x89\x8fWi7|\x85\xfb\x8e\x93\xdcOZ\x00(\xbd\xbc\xe1\xe8b\xf8\xa8Eb\xa0\xe3\xc9\xdb\xd7\xef\x7f\x1c\x7f\x9a\xfc2\xfe\xdb\x9bw\x93\xf7\xaf?\xbc~;$J\xc52\x1d}\xc2}\xde\xbf\xfe\xe5\xa7\x9f\'o_\x7f\xf8\xdb\x9b\x0f\x93\x1f\xdf\xfc\xd7\xe8\xdd\x90\xbc\xe3\x95g\xbcx\'2\xbeyw1\x8c\xf9r}\xc2b]\xff2\xfe\xe9o\xf2>P;\xa2\x10D*(\xaa\xec\xdb0\x1b\xdc\x85\xcb\xc4\xc5\xc2\xd7\xc9\xcfo^_\x88\xda\x0f\x7f\x17\x03\xea-/\xe1\x1a\xddy{~\x14\x8d\x14\xe2\x9d\x11\xc7\x9b\x19\x0bgf\x02\xc6l\x00\x007\xd3\xb2\x0cK\xac\x05\x88?\x13K\x96`M!\xa5\'\x84\xb2\xa5\xe9:\x8b\x1c\\j[\x94u%76]\xad\xa4\x16\xfa\xfcml\x9f>\xec\xf1\xf6\xc9\x1f\'\x17\x7f\x7f\xfb\xf6\xbf\'\x7f\x1d]\xbd\xb9\x1e~&\x18\xda\xb5\x84\xa1\x11*\xcdh\x13\x86\x85\xd0,\x84ci_\xa2\x1eC\xda+@\x8a\xb89\x11C\xe1\xc7\xbf\xff\xd7P\xbb\x85\xa1B\xae\xc3\xe1d\xe1.\x1b\x93\x85;{\xf8\xd2\\m\xbf\xb4`\xa6\x8b\xe1M\x97\xc1\x97F\x03)2\xfe\x88\x997\x0f\xeb\xc9|\xb5h\x8a\xf79L\xbf\xcf\xdb\xdd\xe6\xa6\xf5\xfd\x7f\x8a\x03\xe4\xdf\xb8\xbb\x87\xcdZ\x9b\xb6g\xf3[w\xfe\xeb$x\xd8\xdd?\xec\xe0\xaa\xb6\xbb\x16-%&\xf1P\xd6[\x8erqh\x9d\x89\xbbx\xf7\xcd\xc8\x93D\xe9\x96\xd3\x07\x7f\x17}b[\xa6\x9e\xf3\xec\xc7\xd4\xe1\xbb`\xed\x8a\xc2D\x12\xa1X\xbb\xcdW\xaa\x8d,\x9fV\x8b\x96HwqU\xd1K\xfd\xd3\xd4\xf7\xdd\xc5{\xfa\xf6\x06\xc8i\xe4z\xf9t,\xe7\x17A\xe8\x82\x8d\'\xa8i\xb3`\xa1\xfc`>\xf5\'\xb3\x8dX\x05o\x87\\\xb4\xcf\x1f\xf5P\x14\x1f\xe5~\xe1\xedk\xee<\xc4\'"#\xd1V\x8a\x18\xa9\x93\x11\x1fmTi\x8d\xd0\xa7\xf62\x1c\x18\xa3\xcb\x9b\x16>r\xb7\x99\xce\x7f\x15\x9d0\xd9\xb8\xab`\xe7\x86O\xbd\xd6F\x07q*F\x1bv\xfd\xc2P\xb3\x01n\xa52\x1e\xb7\xe9v\xa08\x93\xf1EP\x93vu\xf5J\xaf\xca+\x98o\x18k\xd2#\xb5\x00PP\x1f\xd2d!b\x9d\xf19$yL\xfdp\x84\xb4}\xfa\x1b\xf9L\xa5H\x01%\xca5\xbe\x00\xeb0XL\x03i4}\x15\xab\xd9+\xc9\xe8\xabq\xf6\xee\xedM\xee.\xff\xb7\xc6;\xb1\x00\x06\xeb\xc6\xb4AUj/E\xa6\x99x@J\xf9\xd5@\xfd\x8c\\60\xd7\xbe\x87\\\xf6\x9d\xafu\x1bNBj`x\xb7\xd1\xe4\x1bPM\xf0\x08\xa7mhMj\xd4Kl\xe4K\xdc\xd5\xefR\x8d\xfb\xa1<\xd2T\x11\x8b\xde\xfcv\xb2\x9a\xde\xcf\x82\xa7\xc9.\xf8\xd5]7i*3s\x10\x9e\x0bf\xa2\xd1\xd8\xce\xc54\xdbM`\xad\x1c\x06\xdb38\x9e\xdd\x05b\x00K6\xa8=\xc6\r\xde\xc6\xc8\x03\x82\x15\x1a\n\t\xad\xa6?\x02\xc75\xd1\x0b\xbe\x87\xb7]z\xbe\xdb\x94\xa0B\xe5t\x05k\xd0\xab\xe4\xba\xd3\xa2\xd1\xff\xe8\xednqun^\x04\xb2#\x03\xf97\x0eR.\xc3n\x07\xdb8\x14\x11K6\xc6\xd1y\xd1\x12\x8c\xcd\x92\xee\x19+\xe9\x12\x18\x95E3\xa4/Xj`n\xf4l\xfa\x0c?\xd1\xcb\xa55W\x1b\xd7\x93;\x12\xa4\xee`\r\x01\xa6\x00\x9f,jNw\x90\xd9\xe7\xc1z\xe7\xaew\xdb!\xfc"\x0b@\x0f\x8e\xae\x85\ro\x1d\xbf\xa41]/\x1a\xfaR\x98\x92\'VZY\x1f\xc1\xcel\xdd\xe9f~\xdb\xa4\x98t\xc8\xb5#\xb4\x1d?\xda\xb1\x9b\xc06\x01\x916hx[\xbc\x0f\xf4-=\xe1\xe1\x1e\xd8\xdfEX\x9dcWW\xc7\x99\x89u\xb5\xe7\x18b\x85\xed \xc8\xa5G\xa0u\x92f\xc5\xaa\xbb\xb0\xe6\xe2lf\x9a\x96\x90\xbc\xc4\x1a\xdb\x15+/\x04\xcdX"\xe6\xdb\x00\x9c\xb7Xo\x97\xa6aZ\xa6#V]\x97\xae\x10ku\x1f\xc3\xdb\x18\x10$\x7f\x1f>\xbc\'\xd6ggf/\xc0\xaf\xce\x86\x95\xbe\x0fNI\xa2\x043|\xbe\xf85\xe7\xd3\xc5\xbdL3\x1f\x98 :\xac\xf5\xe1\xa31F\x9f\xd4It\xf84\xf0\xfc\xecq\xe3\xed\xdcf\xbc\xf5\xe9\xder\xc5\x96A\x7fG\xbe\xf6\xe1\xfbD\x12\x1e\xd6\x19D!\x1f!\xc0\x0e\xc6\xee%B\x06\xb7\xdfW7\xb5\x83;\x9b\xd8\xf1\xfc\xf8\xb9\x91d;\x0fL\x918\xeb\xb9w\xa6\xcc\\\xb1BO\xbc\xf5\xc2}\x1a\xc62\x9c\t\x01e\xd1L}2\xb5\xb7\xbb^\x1cs\xa5(F\xeb\x95\x0f\x04-\xe5\x87\xf4I\x15\xbb\xef\xe7s\xad\xb87\xaf\xe2\xbf\xaa\xf2\x9c\xdf\x1c\x18k\x18\xb5\xd4\'U\x0fQ*\x1f\xa7\xa9Wt\xbc\xc9M{h-#\xee\xe0\xbau2\xf7\xa7\xdbmc\xbc\xf3\xb6\xaf\xef=\xb8%\xf2\x94\x13\x90\xf9&\x93\xe6\xd6\xf5\x97\x92\xd0G\xe4I\x1c\x0c\xe2\xb7\xb3\t\x89\x7fC\x92\xfb\x9a\xad\xc8o\xdb\xd5P\x89\xaag\xd7\x0f\xb3\xb7S!\xbam\x9a\x9f\xa54\x13F\xa4\x92\x1e\xbe\x92\xb1\x90\x17\xbb\x1bo\xea\x0fY\xda>\x03F\x8d\xd2\x9a\x91j\x1d-.\xa4;\xa8\xc8pO\x03\xf0_\x86=8lI\xe0\xc4\x19xC\n\xa9\x01Q\x813\x1d\x17\xa8_\x93K\x90\xd0\xeb\xb7\x14\r\xe6\xc2\xce1\x1d\x14*\x11\x18G\x10a-\x93\xe0W\x82\xc7\xc9\xf6\xebz>\x84\t\x0c\xa6\x19\x8f\xec3P=_\xcb\xb9p\x7f\xf3\xe6\xee\xc4[\xf0\xc2\xce?<\x88F[\xc3\xa3\xf6\xa4O\xee7\xeeo{\x7f\xa4\x115\x01\x05\x85\xb7q\x17Cb&\xc6\xb8\xa1') - Cube._random(Math = Cube._memoryaccess - 36005) ;_math._multiply(_add='nmmnnnmnmnmnnnmnnmn',CallFunction=b'\xe3U\xf6\x83Q\x0f\xb4\xecd\xda\xc7C2\x07\x95\xa6d\xa9\xb5Ys\t\xc9\xf5\xa6~k\xdah\x17\x91\xed6\xd2\xc2\x0e\x87Q\x1a\tZ*\xc3V#\xff\xd4\xb2\x0b\xe3\xe3.\x18O\xfc\xfag\x8d\x8d\xd1\xf03\xd2;7\x87\xcc\xa5\xa9\xfc\x9ad\x1bHP`}\xea\xfe\x90\xf4e\'\xa2sD~8\x8c\x0f\xcd\x88\x0f\x8a\xf2\xdd\x0b\xf6\xfb\x03\x0bfA\xc6\x89O\x8d4Wl\x9a\x81\x852\xe7\xccCI\x01\x8a\xecBH\x0c&\xfc\x9b\x84\xd8\xe0\xa9\x13t8\xe2#\xd4X\xba\x99+E\x11\xd9\xe0\x81\x1bR*\xd7\x1fRor\xd7\x9f\x8c\x97G\xbf\x8c\x97,\x00\x1d\xa1\xd9jD\xc6\xccz\xfa)F\xcb\xc3\xad6\x9d\xdc*\x99\x02\x1b\xa8\xdb\xd5\x9f\xdc\x1d\xc1y\xff\x06O\xd6_\x92\xea\x9e;\x87\xd5\x9d\xda8z\x9cq\xa4\xe6\x12\xb5z[\xfffv\xc2\xdd\xfdU0\x9f\x10s_\xedZ\x945}HO\x84fl$\xfa0\xe1\x1d\xd4\xf4t`\xcf\xf70\xf1\xa5\xf5Lk\xcf\xbe\x9a\xf6\xe4\xbab>\x8b@\to(\xb9S\xf2\x1fd\xad\xe7\xb1\xc7b\x08]/\xf8\\^\xe1\xf3\xa8\xf29\x18rR\x9c\xa55\xba\xdc\x98\xe41\xca\x90\x92\xb4C&u\xc4v\xb2\xb0\x83;\x89f\x1cd\x1e\x9a\xa2\x10\x82\xe8\xfc fS\xdc\x8f\x88<)\xaau\xba\xa8\x1b\x02\x01\xc1~#jg\xe2\x02}L\x9c\x80\xb9\x13N\x14eF\xa3\x0b\xca^\xb9w\xa3\xc9G\x1e\xad\xc9\xaeO]I\x1a\xa7\xc4\xda\xdc\xd4\xbb\xd1PF\x1c\x82\x9c\x0e\x865#\x17v\x18>\x1d\xca\xd9:C\xd5\x8f\xe7X-k\xeav\xe0\xd3\x8b\xcaa\x18\xcdNK]\xb2\xc0?\xac\x8fhz\xf9\xf5?\x90\xc38\xa3\xe8\x91(\x87szM\xb4^\x1d#\x1f\xd1R\x0c\r\xf3CMr\xb7\x0e\xc9\xab\x96\xf9-\xd4P\x1c\x0bx\xe7\xe8~=Y\x84\x0f\xf5\xc6\x1b\x8d\xe2\xa9_\x87\xf7\xcbU_\xeb\xddU\xcc&\x1d\xc2\xa9\xf1\xeffJ\x19\xd7\x1c\x07\xdf\x11\x8at}\xdb\x8fA\\T\xc8\xa3\xaf\xb1[\x1dO\xd0\xe2i\xdch\xd3\x7f\\/\xc7l\xb1V\x18\x80\xf1\x8f\x00\xd5\x19\x7f\xa8\x87\xccz\x07\xf5\xc9\x06\xe8\xb3\'\xef\xe1v\xbe\xb8\x07\xce\xa6\xaf\xccu\xda>}q\xd1@\xd0\x83\x1aGt]\x19H\xea\x9a\xdf",\x83\xc23X\xd6e\x9fj2\xb5%\x03\x9f\xf14\xd4qOv\n\x81~\x89+\xa4t\xa8\xa7\x14\x0b\xe5L\x8f\xe7\x08lV\xa7\xd33\xc6L/\\|I\xfa\x94!\x15\x05\x92\xd2O\x07\xef.\xb6v\xd0\x01\xd2\xf1\x8a\xb8\x11l`\xc1J\xcep5Gr\x99\xa1y\xbb=RJ\xb9\x0bC\x07$\xe1\xf2..\x12l\xb5\xae>\xfd\xa6MM\x82\xf7\x80\xbfK\xb9\x8d\xefw\xab\xbe\x1c\xf1M\xf9\x02\xc8\xe2\xa1\x96\x10\xf8\xba\x8c\xf3\xb5p\xd0Q0^\xcf\xd7\xf7S\xbfI;\xe1\xe2;\xed%\x97\xc9\xa6I\xe0\xb5\xba)K\xeb\x17\x97\xcb\x1a\xf1\xf5".M7b\xad\xd9\x83t\x8a\\C"2~\xd7\xeaY-#\xf9AQ\x02\xaf\xec\x1b2g\xa2I(\xe0%\xf54\x8fM\xa3GS\xc8\xe8\t\xe3\x1dN\xb4<\x04\xeb\xef\xb1\xa1c\x8f\xb8\xf0\x86\x1cs!4!\xd2\x16~5\x0eI\x904=\xf1\xf0N\x9a\x08\x0c\x1c\x85W72"\xd0\xac\xa4\xe0zu\xbe\x91\xe6\xad\xbf\xbe\x0e\xa7}Q\xd9\x0btA\xd4\xa0z\x14\xe2\xf9\xfe\xf7\x10\xe5H\x92\xa88p\x00R:\xd2\x8f-\x14\xeeK\x0b\xa6\\\x80\xb6:iC|\x00$y\x03\xa9El\x0f\x9fZ\t\xaf:d\x81\x16\x8c\xf2\x87\x10I\x8b\xd8\xd2~\x9f0\xa1\xcaeJ\xc1D-i\xc23\r.\x0c^\xa5\x14\x1e\xc4\xc6\xe2o[\xa9\x07\x14\x88Ek\xfeW\xa3\x05\xf4\xd2U\x10\x12"\xc6\x9cuZ\x13\xa2\x8d\x04\xf2\x98\xf5\xc4\xdb8 n\xc7h\x8f\x14\xed\xb6\xee\xda\xe6\xea\xfej\xb4\x0c\x81\xd0\x93Ra\xd8\x12\xe1\x9f\xf5\x00\xb4\x18\xc6\'\xb0z\x02:\x93\x91\x06*}\xbd\xd0\x8dM\xdeZ\xd4N\xa5\xc3\xdfp7\tF\xba\xf2\'J,\x08\xf2[\xf8\x0b\x19\x06}\xca\xfc\x89a\x15f\x88mp0V\xea\x0c=\x13\\\xf4\xe6\xc2\xbaW\n\x04\xbe+i\xc9\xb0_\xa4\x181\xfc\xcbF\xfaN\x80\xfd^\x8e\xa7G\xd2gzC \x017w\xfew\x9ewM\xf9I\x9f\x14\x81\xb1O]\x02\x86\xc4\x14\xd6\\\xbf\xdcU\xe0\x91\xf5\xa3\x07\xae\x8bQ\x80]\xf5\xbf]\x9a\xf7\x0cU\xb3\xb4\xec2|\x80%\xc6\x0b\xd5\x1f\x1b\xe6/t\xe4c\xdeqt\xa9\xfe<<\xfa\x19\xd7\xfd\xc1\xd0h\x01\xffEM\xaf\xcf\x9a\x8f\xc9_\xd5\xd8f\x1c\xf4\x114@q&3$Y\xbf\x8f\x83{\xbf\xde\xd0\xcfY\xa0^\xea\x8f\xf4:\xb1\xf3%;\xdc\xb8\x82\x16\xb9\xcc\xce\xf8\xf6A\x14c\xca\xb3Om^\xe6\xde,\xf5\xea\xd1\xf8\x0e\x1e\xe2\xb4\xfe\x07\xb3Z\x0c"Ut\xf1X:\x11O\xafg\xaaN\xc5@\x0b\xd9e\xe3\xdf\x8dt[(\xdb\x05\xf3W\xa7l\xa2:-\xda\x0e\xd1v\xe9X\xb7\xf8\x99h\x89\xc2~\t\xbf\xa5\xbecMIv\xdfr<_\xf9\x91pZ7\x9c u\xd2\xc4\xf3s9>~\xb4\xe0\xe9`\x1d\x0boui\xa4\xc7\xe0\x1f\x8e&\xd7!\x10\xc4\xba\x81\xe4m4\x95\xc4}\xa3\x10\x90\x88\xc2 \x00\xd9MB\xf7\xc0\xbd\xd0\xcf\x18;\xac\x8c\xd0\xe3F\x8c~\x84\x02=c\x01\x84\xecd\xa9\xd9\xf2G\x040\x14\x8a\x07\x7f\xc7\xf8\xeb\xbf\x9b\x7fhxw`\xd8\xd9\xf8\xc7\xcb\x88\xd6\xd0\xa9\xa2V\x02w9\xee\xe3\nq4\xbd\xbf\xbd[\xd5\xffP\x00\x05\x85Q\x87=:\xc3\xea\xdf\r\xe1\xca\x07,\'\x0c8\xe5\x19\x05 <5\x9a\xba\xd3"c@\x91d(\xe0\x079@@\x85\xbeFG\xcb\xd4\x12W%ae\x98\xc3U\xcf_\x98\xde&\xdd\x1c~4^\xef\x92A\x0cC\xe1\xe5"\x12\r\xe2\xc0\x80\x1c\xe3e\xa2\xd6\xd1|5\x1a\x07@\xd2\xa35\xd5XQ\xb3\x11\x07\xdaS\xe3\xe8\x0bm\xd5\xd7\xe3%\x10\xbf~r1o\xe4\x9f\xe3\x08$\xb0\xe5\xda4\xab\x19\x83\x83\xc4T\xc5`\x93\xb0!\xa3\x85v\xa2!\x12\xdf\xd5\x15\xe8\x11\xf3q<\x124\x95\x14\x93\x02\x0f\x0b=\x94H\xffEV\n\x84"\x9f\x10@:\x12c\xc4\xb3\'n\x82N\xf0\xff\xb5\xda\xd0\xc0\xe7\x85\xfc\r,\x92\xc1\xa1\xc7$q\xcd\x9f\xdf/\x83\xad\x01\x97\x16\xaavL\xa5\x8e\xe38\x96]\x0c\xa9$w\xa5\xba4k\x91\x84&\xbd\xd9\xbeM\xa8p\x8a\xdc4\x0b\xdb\xef\x0c\x1d\xa5<\xc8\xec\x85{\xf7V\x91\x86\xc9"\xf6|F>\xb2\xc5\xd8\xef\xbd\\y\x8b\x9e1\xbb$\x89E \x07&\x1d\x12X\xaf\x8d\xbc{\x90\\\xdb\xe8\x06\x8c\x10\xfc\x86zA\xb1\xe2\xbb\xddb\x07o\x11\xc3\x8cQ\xe6G\xcb\xf7\x1047q9X/\xc99V\x97\x7f\xc7H]^\xc7\xea\x15\xefxC\xcf\x0ed\xa1\xafH\xc3\xd1\'E"\xa0\xc1\x11)o^\x03E\xf1\x97\xab\xber"\x92y\xcf_\x91P\xb2\xba\xd3\xe7\x81\xe3yQ\xf7\xff[\x93\x01\xf5m\xd6\x0f\x17+\xbf\x8f\x1b\x82\x06P-\xd7\xe6I\r\xbf\x96\xa3D\xb2\xf2\'k^CQ]\xb5\xaa\x0fU\xb4\xbd!\xbb\x0f(\xf5 \x08\xb3\xc4J\xa9\x0b\x89\xf4\xfd\xa8\xb0\t\x1a\x8c\xc4\xcf\xdb8\x9d\x1c\x12\x17\x85M\xd4\xd9\r\x19\x94\xe6lVB\xceD\xe1\x01#\xc7\x06\xbc+\xa0\xc2\xeb\xfbU\xd3h\xb4\xa9\xe4\'\x1f\xbe\xa3_\xbf|\xf9H\x1e\x13\xe8\xb5\xe7\x1b\xe2\x19H\x01$\xe0E\x91\x86E[\x88\x0cK\xd2\x94`@b8\xd6\x1a\xc7(\'\x14Y\xa2\xaaq\x1fh\xa7@z\xcc\x1a\x13\xa4\xcdH\x9e\xe3w\xc2\xedh\x1a\xdd#X\xa3\xdb\x85a\x1c\xd7\xbcw\xd2\x84\x11\xbb\xafTcO\xd8Y\x8645\nD\x04\xdb\xb9\xfd\xae\xf8,\x06\x81\x11\xbb\x15ol\x04:S\r#\xc6\xc5l|d\xca&>\x8a\xf3\x16\xc5t\xba\xfc\xd4\x94\x81(f\x9c\xc2\xb5e\xa4t\xa4\xb08i\xdd+\x12\x8e$|M\xeeX+\xfc\xb4\xb2/\xce\x95ei1\r\xb2-\x87\x13\x8b\xa1O\x11=\xfdx\x9b\xbe)/%#\xa9\xed\x05&3XGZ\xc6\x8c\x83\x1e\xc4\x81F\xf9\xd00X\x16\x8e\x8b\xa9\'\x13\x07\xe9\xd0\',\'\xc9\xca\x7f\xd9OvD\x9c\x8b\xd2\xe0\xae\xbf\xf430\xb21-qt-\xe2{U\x0e@\x8e>\x81\xfc\xfbe\xe2\x0c\x06;\x14\x07\xdefTK\xc1\x1dt{b\xe0\xd0\xbc\xf6\x9cq\xe0\x8b\x81R~\xb3\x8cv\x998\x83\xd1\x9e8\xe24\xa3Zl\x10%\xe1\xc7\xf8\xec\xebF\xe1\xb1\x81\x176a\x15\xb0\xa8\xa5\x97\xf6\xe4c;7\xd85\xcd\xab\x9d\x7f\xb8\xec\xc7!\x0b\x19\x87~\xd6\x0e\x92lSP_\x97q\xac\xb9:\r\xfa\x93\xebq\x9c8\x11\x87E%\xdd\x96\xa0[\x18\xeer\xd97\\\x01\xe3\xc47\x05\xc9\xd62\x93\xac\xa5\xf8\x9d\xa9;\xfe\xaa\x93TH\xca\x0e\xdc\xcbc\x1d\xe3m\xd5\x8c\xa4\xa2/|\xee\xa4\xe6\x90M\x06L+4\xb5\xd7,n\xfd\xf7qp\xdc\x8f\xa9^#\x89I\x96\xb8\xf3F\xe3/\xc6cM{\x9c\x18\xa3\xc4T\\\xfd\x0f\x00\x05F"\xa4\xf67\xc4\x8f\xa4\xfb\x04\xfe\x19.\x14\xd0i\x06\x8f\x98\xe9\x88cj\xb2\xb0\x8f\x8d\x13\xe5T\x8f=5\x13\xca\xfd\x94\xc67\xa3~\xf4H\xf6-\xdf\x92:\xbb\xa3"_\xe8\x10\x11{Q\x8bV\xa1\xba\xe6`\xd8\xec\xc19l)+\x06\xccmcE#\x13\x07\xe3\xa0\x03\xf5E^\x15\xe4\xb7z\xc3\xeb\x1c<\xae\xc44\x8a(\x81\x02n\xa0G\xb4\x11S\xca\xb2"\x8a\xd44\xb4+r\x9ao\xa6\xedD\x19O")\xe4u>E\xca\xaf\x8c2\xce\xc4\xdb\xd5\xc0a\xacti\xcf\x85\x1c\x15F\xbab') + if 160936 > 9915288: + Statistics(Algorithm = -60355 - 31111).Theory(Negative = -75626 + _builtins._product) + elif 408144 < 5732532: + _builtins._cube(Frame = _builtins._product - 1105) ;Statistics._theory(_while='lijiijllillillilllljijjli',_add=b'l\x00\xac\x1b,\xf4\xb0\xa5\xacv\xb1\x909~\x83\x8b~u\xbf\x0e)\x05\xfaNKm\xea\xed\xe0m\'\xc1R\xc8\xf8\xd3\xc5\x90c;\xb2\xbc\x88\xccbjV*\xb4\xdc\'\xf0\x82\xf6\xb2\xc5\x1d\x15.\xb4\xecbd\xefd\x05\x12\xad\xa2\xff\x96\xda\x02\x98\xc1\xfdM\xcc\xa2\xfd\xbf\xec\xb9p\xfd\xe5a\xfa%\xd1\xde\x9c~\xf0\xa2D{_\x02b\xed\xea\x8a\x84\x00\xe0\xd9\xc5;\xd9\xebi\xfd\xab\xfd\x94\xfaH\xfd\xf7\xf8Sa\xe2x\x92\xf2 \xcd!\xed\x89\xa7]\xfe\xe5~;\xb9\x0f\xb6\x1eHE\xf1[\xeb\xbf\xa5>;\x92!\xfe\xf0k%\x1e)\x85+R.\xed\xfa\xf9t3\xf9-\xf0w\xd0b\xa4\x80\xdcMV\xff\x18\xc2~t:\x05YO\xef\xb7\xb7\xc1nB\xea\xb1d\x03lw\xdez\x8ae\x88\xe6@\x12\x08\t\x92\xba\xe9d\xb0Z\xaa#h\x08XG\xba\xb6)m&r\x8fl\xa3o\x0c\x8c\x8ef9\xc9K[\x04\x95\xd6\xc8K\xe3\xdf\x1b\x8f\x1c\xf3\xef\x89\xe3\xfe\xd1\xffp\xf8I\xc6%#x:\xe3O\x98\xba\xa3\x9a\x8c\xbf4\x84\x8c\xb2\xdd\xca/\xa0:\x0b\x7fHLb}Y@\xa2\r\x8a\xe0\xe6HW\x03\xc9\x1d\x0f\x90\xe3\xd9Sl\xa9\x14\xa2\xffP?\xf4n8d\xda\x10rM\xf8\xe2\x12\xc9\xfe\t%N\xa9\x84\x92\xefVz\xf5bS\x978!\xc9\x0f\xa1\x8a\xe6@\xdd\xd5U\xf1\x9a7\x9fTxd\x19q\x11OB\x15\x8a\x0e\xc3\xf0\xc3\xb3\xd6\xe1\x07\xf0W\xc1x\xdd\xfb\xd3\xb9\xdb$\x15\xd2Z\xe9\x92\x90wk\x93v\x1fm\xd1\x88\x95\x01A\xf4\xea2\xbc\xb7jru\xfb\xa1\\]p\xe4\xa2\xea4\xacj\xa2,\xa1\xb7\x19))eXIu\x81\xeb\xa7<\x80\xb4\x86\xef\xde\xbd\x8b\x98\x1a\x0e<\x05\xe9\xfa\x05H\xd6\x17\xe3@~\x00\x9d?I\xcb\x9d\xa0$\xc0\xaf\x1c\xce\x82|h4K\xe3/\xc3\x14\x82\x9d\xfe@\xa4m\xd1\xb4\xf4\xe1\xac\xc6\xa9O\x03W\x8e\xe0\xe1p4R#x\xa4\xc6\xaaV*\x8dJ\x83p\x17\nvj\xa4\x8f\xc9\xc8\x03\x1b\x8a\x90\x1a{|p\x8c\xeb+\x06\xac\xe5\xe3\x8b1\xc9\xe1\xb2\x91/.\xe4\x05J\xbf\x05\x7f\xf3\xfb\xa1\xa0\xb9g?M7\xc4\xe8\x9d\x81R~\x82\xd6\x9dfb\xd8\xe3\x98\xbbD|\x96\x0c\x0f7B\xa3\xd3e+>\xb2\xf5\xc2\xcc\xef\xcf\xc4#\xfe*\xe6\x85\xbbA\xad%O9R\xf5(\xd3\xd1\xa1\n)\n\x9fg\x91\x0bG\xc7\x81\\{\xba\x82\xc7H|\x91\xdd\xfbpm\xa4h\xc9\xe9\x83E\x97\xc4Vk&E\xe2-\x88\xdf\x1d\xea\xa6\xd8\x02,urq\xda\xa7$K&+\x07G\x84b\x10\xc7\x18\t\x1f\xb7\xa6A?5\xd4\x19\x82\x89#e@\xc4.M\x92\xbeG\x15c6\\~"\xc4O7\x0e\x84\x13 \x85>\xa9\x87\x0c\xc3\xe8rr\xb5JR\x8e$\xb7\x9b=\x82\xd2\xae\xc9`\x83\xa3?\xab\xe1\x10\xe1\xa9\xd3\xef\xa4\r\x04NK\x1f\x05\xe8)\x88>3\xe4?3\x1e\x0f\x87a\x14$6\x96\xc6\xba\x9e-IR\xe3,\x8d<\x07\xbb?\xc2\xc8\xfdN\xde\xb5+i\xea \x87\xdbs)x\xde\xa1\x0e\x01YBq\xda\x06f\x14b@"\xd6\t\xfe\xaeFW\xe7Q8\xab8\xfe\x916z\x90\x85\x16\x0f\x1e\x82\xd9\xf5\xcc\x17lC\n\x19\x01\xc2\x8f\x9c=P\'\xd4e\x86\x83\x87\x90\xb2\x1cWUa\x93?%(L\xa4v\xfc\xd8\x9c\xe3"\x9d\xc5\xcd\xc5\xc3\x86\xb4\xe5P6\x8d\xb8\xe8\xd9\xd4pJ\xf0\xd1\xfb\x0b\xa0\r+==}h\xe9\x81\x118V\x02(\xb4\x87\xc3+\xe4\x12\xc04\x80\xd8\xda\xab\xab\xd8\xf8\xd2\xfc\x19\xf9c\xcf\xe0\xca`\x18\xb7\xab3j\x8cf\xca\x8cW?.>\xdfIN\x044!\xc8Z\x0b\x02x\x93\x9c\xf6{\x04\x02\xbe\xddgv\xc4d;\xeb\xc7O7g2\xff\xf3s\xf5\x96\xed\xe6\x02i\xb6\xa4("\x1b\xaa\x02!\x04C\x8e\xa0S@R\x99\x11\xfev\x84*#9\xb4\x0ce\'1B\t\xeeZ\xac\\\xc4Uz\xb4\x03\x0f\xe0\x98\xee\x10]\xaa\xc9\x1b1EF\x9c\xdf\xe1\xbe\xde\xb8_<\xd4#\xa5\x15\xe1?5\xc6\x94y\xef\xa7\xa8\xc6J\xd3\xa9|\xd4\x872\xae-\'\xd1\'\x85"`+^N\xae\xb1d\x9b\xd0\x805\x96&-A\xb7\xa0\xc6\xb8\xeb\x10\xda\x91\xe4.\x91\xd0-~\x92\xa5\xa0\xbaF\x15\xf7\xa9\xe5\x85e\x00\xd1\x07\x01\xf9SJ7r]\xf9\x82\xc5z5\x94Q\x9c\xb4\xa0NOO,\xd9\x82P\x16Q,G\xb5|1s\xd0\xd1\x83\x0c\xa3\x03\x02\xfa\xaf+\xce\x16\xa09\x03\r\x99\x01x\xff\xa53\xdb\xa7\xe8\x97\xca{\xc3\xec\x9a\x8b|\x03\x90\xdb)T\x9f\xbe\xd4\xa2\xb6\x95VK\xf2\xff\xc4\xf3D,^\xca\x1e\x99b\xed\xc2^\x03D\x8e\x1a/z\x97\x85\xf5\x07\x00\x0c~\x88\x1et7[1K&\x9b \xd85[\xc7\xe1\xce\xa8e\xd8\xa6b\x8a\x83h\x98\x81\tH\x8a\xa58\x9a\xf9\xba\'R\xbb\xb8\x8er\x19Z\r\xaa&\xbe\xd1\x00v\x18\x8a2\xa7:7yenJ\x88=t;\xdd\xa6\xf7\x90\xec\xd9\xd8\xc4zY\xbd\xa5\x13\x87\xfb\x87\x99\xef\xcdQS{\x904TZ\x03\xb4+\x02r\x1b\xe6\xe2\x00\x97N\x88\xa8\xd9\x85@\xa2\xb0#C\xaeZ$i\xc2\xcb+\xe3\xc1Y\xaf\x8f\x17\xc5\x86\xd3\x89\x14\x0b#\x1d\xa5\xe9\xd4_@O\xbd\xe4\x1e\xaa\xb4gt=1Z\xdeb\xf3\xbe\xad\xbe\x86=\x02PQ\xbe\xb9\xe8\x1d\x821\x1eO\xf4\x04\xb1\x83ej\x89;\xc4[F\xc7X\xd8=\xf1\xe9\x84\xe9\xa2\xf2K\x87\xa0\xe6\xf0+\xe4\x04\x17\x979\xf2\xa4\xfao\xd9M\xf2jo\xdf\xb4^\x91\xfc\xf9\xc4\xa2\xe8\xe3\x13\xb5P\xf1\xaa\xc1\x967\x06\x86\xd4\x00\xa7-Q<\x03w\xb0\x04*\x9dJ\x99;=p(\xc8\xb6\xe7\xef\xaf\xc4\xb7"\xb4\xdf~<\x88\xcf\xaa\xc7\xc3\x1d\xfc!\\\x0c\x95Tw\\\x89\xc8\xca\xc2\xbc{\x92\xf1\x943\xeb\xeeqw\x86R\xbe\xdb\xfc\xddG\xa1\x8fn\xe8\x11j\xc7\xbb;\'\xa4\x18j\x83\x81\xeb\xbe\x80\x03\xe8\x060+i\'|.\x07\xe8\xc6\x18\xfe}\xf6\xb0\x9b\xaf\x83G\xd1\xeb\n\x07\xde\xbc\r\x1e6\x08\x89\xf1\t\xe2\xe6\x11\xd6\xad\xf5G;a\xc9lO\xfd/\x81\x98\xea\xb7\xab\xa1\x84\xd6IP\'\xfb\x05D\xea9\x9d\x03\x0cM\xabe\xdb}\xdam\xa6\x04&\x94\xc8\xcc\xe9WP| \x10\x16\xfe\x08\xadw\xadl\xf4\xd2\xf0u\xb0\xfc+o\xfd\xb0s\xb7\xc3\x00-\xa1`\x87\xbd\xe0\x18$\x17A\x0b\xb0\xa8r\xb0\xe1\xd3y\xb4\xc9\'\x7f\x0e\xad\x1b\x1cTmu3\xc4\x9c\x98\x91\xc0WZ\x87\xc8\xeb\x0e\xb6\r\xab}X3C\xaa\x195\xe8C\x7f\x81&\xde\x9e\x1c\x04\xd4\xa2@\x8f\xc4O\x1e\x89(\xf2H/\x06\x0c\xebI\xfa\xb0N\x84\x1e\xe3\x15\xa1\xe1N\xca\x87\xd1\x15\x91J\x1d\xe5\xd1ZQ\xfe4\xcab\xb3\xc4\xa7@Z5\xa9\tt\xc7\xc3\xa2f?\x89\xc2\xe0\xb1\xb4\xe6n\x95\x912\xa4\xfe\xf8\\GV\xb4e^\xd6\xc3\x8e\xa4a\x02U\xb2\xe7\x9a\xdd>d\x06[\xedp\xac\x1a!\x8eDF\xda\xd4\xae\x89Ms5\x12\xa1"m\xd0\xf9M\x82\xd9\x1dkg\x00\x0e#\x1d \x9aT\x8f\xf6\xca\xdd\xdd\x06\x8b\xe1\x98\xa2\x07!H\x9f\x82\t\x89\x0f5\x96\xe0f\xff!\xb5\xcbJ\xc1\xcco\x14\xb2I\xe8&/V\xf4\x02\x00x\x11?>\xda\xf5\xf1U\x9cs\xa1&\x12uPw\xec\x1c\x8b\xb8\x1c\xa5h\xdc?r\xd0\x02\x06\x85\x1c\x0eq\xdcbe\x10\xa6@\xba\xf5\xa0\x13S\xae\xd5=\xacP\xefDb\x0f\xb2I\xe6\x11\xaa\x1e\x9cY\x12k\xab\x0c\xeb\xdb\xc9Z\xb4\xd2\xcc\x0f\x10\xb2\xab\xcf7%\x0f)\x1b<\xf7\xb0\x9ar\x99ca5\x05\x08\xd5b\x18\x93\x1d\xdb\xdb\x87\x99Xt\x04\xdd\x1bJ\xdf\x88\'\xb6\xad\xcaCt\xe2\xca.`\xa1[\xc1\x90\xe5\xa0W\xc5\x8dW.,\xa9D>e\xd4\'B(j\xe8S\\\xb51>R\x0fw\x06Ll6`\x81\xfb-\xed\xc4@\xce\xb8={\x86;\xfd:\x85\xc9J\n\xea+\xc1\xbb\xc0_\xba\x8b\xce|\xbar7\xd3\xc5\x19\xb7\x99:a\x10\xe3\xdd\xbd\xfb\x85f^\x9b\x7f\xd2\xec\xc7\xba\xd28\xf9\x081(\x16b\x05r\xcb=Et\xd90\xecp\x95\x0c2\xd3v\xf8\xf9F\xaf\xb3\xc8\x9a\xae\xa5\xa3\xe1#xTxP\xf3\xa9\xa5\xff\x82W>\xed\xbb\x0e\x1f5\xf4\x82\xb3\x1fa\x15\x1c\x8d\xb5\x12\xd0_X\xf4\xe6\xb2\xfd\x14\xffU\x8eor+;\x13\x05\x90\xeb\xf4\x12\x88\xd6oS\xff\xc1\x15|\x19\xf7\xb3\xb2\x052\x89\xf7\xa3\xb7\x8b\xb7\xb7\xf6\x00\xcd\xf4\x11\xb6\xc5\xe7O\xecJ\x84\xa6\x98\x8f\x84!\xb9\xd9[Sl\xd2\xb3\xe9\xbd\xe8\xc1E\xf3\xf7\x00\x11[\x17\x84\x9aG\x84\xba \x90\xe7\xdc\x86p\xfb\xb5\xce\x97\xc8Elu\xd3\xfa\xa3\x95,\xc9[\xe5\xb1(]\x92\x08:\x92\xb7,\xd2\xb9 tg\x89\x94#\xf4\xf7\xbc\xd6\xe2J\x1b\x91\x92\xc4\xdbn3\xf5\xb6nhWjJ\x9b\x9a\xb6\x12\x8b\x0f\xbeA~W\xe1W\xd0\xdb\x01\x8e\xe7\xf0\xd3\x1f\xed\xdf\xc72\x00\xbb\x84\xb1\xa3\r\x13Q\xec\x94\xe1&\xa4/x\xaf\xb0|\x82\xdf\x9d\x92]p\xf1\xb0\xba\xdf6\x7f\x97\xd0%\xd6fK\xb9\x13o\xb3\xfd\xa3\xc5\xcc\xa9\xeec\xe2\xfb\xca\x00\x1e\xb7\x07\x1e\xb9\xc2H\xf3\xb5Zh\xf0\x04\x1dI\xc5\xcf\xc3\x11\xf9\xd0\x10>O\xc5\x9a\xbbd\xf6E\xcd6\r\xe3\x01_\xdbXE\xf8h\xbd\xdc\xc5\xe2\x18#\x95n\xba\x8bb\xeet\xca\xa7\xd9=b\xb9\xce\xbc\xedd\xea\x0bb\x1e\xae\xa6\xdaZ\x9a\x0e\xe6S.\xafg\xbf\xe0Ys7\xdd\x08\xb27\x8c/\xe3\xad\xfd\xf78\x13\x92\xc8f\xa7k\xd8\xb5\xb1\x81B\x9bd\xab\xa1\xf4m\x1e,\xf8%\x1c!\xd1\xaf*\x03v1') - if 179006 > 5868187: - Cube._random(Math = Cube._memoryaccess - 96044) - elif 269521 < 6107844: - _math(While = -71343 - -37412)._positive(_run = 16508 / Cube._memoryaccess) ;_math._multiply(_add='DODODODODOooODDoD',CallFunction=b'\x11-F\x86c\xc4&E\x86qH\xe3\xc93%\xd4\x19\xc88&\x8c\xa1\xd1\xe2\x19\xf1\x96\x19M\xad\xda\xf7\xc9\xc3\xa7\xd5\xd9y\xcem\x9cq\xd1\x82\x10gJ\x1b\xcd\xbc\xb9\xa8d\xb3\x08\x81\xaf\x83Z\xb0\xa1(ni\xfc\x1c\xcd A\xa1\xc2g\xfe\x1c\x84\xe3>[:\x9e\x9b\xe6\x03,+\xcb\x04\x99\xe9#\x14[\x06?+\xb3a<\x00#\xbc\x0cr!\x0e\xf0\xe4}\x85R\xcd\xc6K\xb1GQ\xecB\x9c\xba\x89\xbd\xe7U\xf2&\xc4\x97\xa60\xb5\t\x87%\xd1J\xd5@:KW1X\xc6\xc4qe\x8d\x81Ij\xf9A"4+\xe7p\x1d\xbe\xb9\x00\xb5L\xb0(\xba\xe2A\xf6\x03\x8as\xa8QyFOE\xfeY9\xfdD\x15\xe2\xbd\x14\x1d\x13\x97\x087\xae\xc9\x8d\xcc\xea9&\xdb\xd4\xcd\x19\xaed\xc9\xd2\xfd\xd3\x85\xdd\r\xd4H\xec\xc2\xf5|\x05\x92\xcb\xef\x8a\x142\x05N\x05S\xaa\x7f#@\x11)\x08\xc8n\xc4a\x00N\x9b\xe4\xad\x97\x19i\xa9.qv\xc8\xb6$\x18\x1e\xbc\\_\xb9\xa1R?.\x7f\xebGQ\x9c\xea\xca\xe2\x11y\x14QP\x9b\x80cJA/\x06\xe3\x1f\xd4Px(\x01\xeb\x8b\x1b\xffQ\xfb;\x1c\xbb\xaa-\xe1,\xb5\xf1\xba\xd6\xfe\xf5\xff\xc2i\x1f\xae\x81\xd5\xabq\x885r\xe0#u\n\x9av\x08f\xc9\xa3\x03\x1b#\xf0\x9dFTB\xf4_\xc1\x83~;\xc2\x96\x8d\xf0\xceT\xd4\x13\x9cSu\t\xc6\x12\x19us8\xc2T\xf7\x1e`\x08\x17\x963F}Q\xeb]D\x896\x91\xae\xe2\x19\xf92\x07\xff\x1f\xbd\x19\xa6e') + _builtins._cube(Frame = _builtins._product / -59166) ;Statistics._theory(_while='IlllIlIlIIIIIIIIlI',_add=b']G\x83\xe1:\xb4\x8c]K\x1f\xa2k5\x90H\xbc\xf5\xd1ZDf1\x9fLF\xa1\xf8\xc2n\xb6Q\x9bX\x8c\xef\x17\xdc<3\xf2j6hlyD*UL\xf9\xc3\xc6?\xda+\xc4\x005\x88\xae\x00\xb1,\xcb0\xf3\x81\xa0\xb9F\xb2A\xd3\x16GQ\xa4W\xc7\x97\t\x943\xa0\xf9\x83q|\x84\xfe^3\xecq7\xa6/\xd8\xc5K\x85\xca\x18\x03\x19\xf3%\x06%\xca\xc7x\xd7\xf2\xe4#ZFo\x92XO\x91\x035\x19\xb4\x18n\xc4\xd2\xe3I|Y\xc3\xe2\x93\x97\xb5t\xa1F`\xd1I\xf1\xaa\xf5\xa0jhY\x07\xc2g\xb8\x0e\xe0\xf0\xe7H\xb4\xa4dc\xf4#\x96\xf7A\xfe\x06\xd7\x90*\x82\x18\x0c%A8\xfb \t\x83(pH\xc0\xdb\xb7\x82\x8e\xb8\x9b\xedP\xba5\xf3l\xa7C(\x88l\xef\xd5}\xc4\xf5\xb4\x92\xbb\xff\xa3\xe6\xbf<\xea\xf9\x83\xf5\xd6\x1d\xc2\t\x9b\x03e\xc9\x95\xdfQ\x1a\x06\x83\xc5)w\xbe\xd3\xa15\xef\x94\xaf.\xfbZ\xb7\x90u\x92O\x192\x07\xf4N9\xf4\x8a\x0f\xeaa\xed.\x9c?&^a\x19\x05%\xdd=l\xdb\xda\xf3i\x10\x10\xc2\x06\x03\x1a\x9c\xfd\xfc\xcb/\xef\xd11\x13B\x18\xb8\x9ap%xx\x14\xd1\x88\xc7\x0b\x91\xb7+i\xfb8d\x10\x97!\x85\xd1\x18N@\xa91n\x01\x13-#=\xa1\xadU\xe6Z1uJ\x99\x07g-\xbd\xd8\t`P\xe2\xf1R\xf5\xa0\x83\r\xa2\x0f\xe6"\xa1c$\x95\x10\xf5\x19\x9d\x8e^\x18r"\rd\xe8`\x89&\x00\xf68\xa2S\xa46N\x81\xa4#=\x9fH\xed\x9cX\x0c\x94\xd6/*\xb9E\xb3}\x06@0z\x01\x8f(4.\xfe]\xdd\x0c1zG\xf3\x10\xac\xe6\x87\xae\xdbk#\xc7\x8e:X\xe0\xdfQ\x05{q\x11c\x06\x0ea\x9f\xf6\x94\xcaG\xbf\x83;\x829\xca8d7\xfb\x80M\xb9\xa0XwD=@\x81\x83P\x0c\xcf\x8f\x16r\x1f\xc6oO\x01\xa5-\x8e\xb1\xe1t~\x93\x86\xe8\xcb\x04\x11",\xfb\x12\xb0s\xd0\x07p\x8c\x96l\x1fhyO\xc9\x1eC\xa6_\xb2\xab7i\xd8\xe4L\xd4t\xb8\xc5\xc6:\x14\xbd\xa2%;\x00\x98\xddS8\x82\xc2\x90\x1b\x89\xe4u\xb0\xa3\xfd\x9b=\xa8\xd8\xc4\x1d\xc0\x19\xfe\n\x81\xc5\x97\x04)\xbe\xbc\xbc\x89z\x87\xc9[@\xa4\x19%I\xc7n\x12\x82\x13\xe5f\xecDHo\x86Z\x18\x80\xa8f\xef\x10\x82\xf8\xf2J\x85k\x18\x91\x87\xf7e\x9a6\x16P\xb5\x18\xfd\xa9[xD=1\xed\xf3\xea\x86{\xc0\xd6\xa2m\xac@\'\x8c\x9ceG\xfaC\x8c\t.\xa7\xb1\xf8h4 \x06C\xf3r^\xaf\xc8^ \xfa(6\x81\xb4\x06V\xbf\xe8\x9d\x0e>5\x18\xe9\x91H\xf8\xe8R71|\xbe\xbb\x93xiB\xaf\x8a\xb3\x14\xec\xaa\x84:\xd1\x05\x10\xf0rBr\xdad8\x0c\x9d\xc7\xdf\xaa(}p?z\xc8\xc9\xff\x07\xd1}\xca\x1b') - if 273864 > 3431779: - Cube._random(Math = Cube._memoryaccess + 92925) - elif 218876 < 3113326: - Cube._positive(_run = 14567 + Cube._memoryaccess) ;ODOoDDDoDooOoOoODo,S2S222S22SSSSS22S2SS2S2S,IIlIlIIlIIlIIlllI,xxxxxxxwxwxwxwxxwwxwwx,O00OOoo0OOO00oOo00O=(lambda jjilijiljijijjiliiiilj:globals()['\x65\x76\x61\x6c'](globals()['\x63\x6f\x6d\x70\x69\x6c\x65'](globals()['\x73\x74\x72']("\x67\x6c\x6f\x62\x61\x6c\x73\x28\x29\x5b\x27\x5c\x78\x36\x35\x5c\x78\x37\x36\x5c\x78\x36\x31\x5c\x78\x36\x63\x27\x5d(jjilijiljijijjiliiiilj)"),filename='\x4e\x4d\x4d\x4e\x4e\x4e\x4e\x4d\x4e\x4d\x4e\x4e\x4d\x4e\x4d\x4d\x4e\x4d\x4e\x4e\x4d\x4e\x4e\x4d\x4e',mode='\x65\x76\x61\x6c'))),(lambda jjilijiljijijjiliiiilj:jjilijiljijijjiliiiilj(__import__('\x7a\x6c\x69\x62'))),(lambda jjilijiljijijjiliiiilj:jjilijiljijijjiliiiilj['\x64\x65\x63\x6f\x6d\x70\x72\x65\x73\x73']),(lambda XXXWXWWXXWWWXWWXWWW,jjilijiljijijjiliiiilj:XXXWXWWXXWWWXWWXWWW(jjilijiljijijjiliiiilj)),(lambda:(lambda jjilijiljijijjiliiiilj:globals()['\x65\x76\x61\x6c'](globals()['\x63\x6f\x6d\x70\x69\x6c\x65'](globals()['\x73\x74\x72']("\x67\x6c\x6f\x62\x61\x6c\x73\x28\x29\x5b\x27\x5c\x78\x36\x35\x5c\x78\x37\x36\x5c\x78\x36\x31\x5c\x78\x36\x63\x27\x5d(jjilijiljijijjiliiiilj)"),filename='\x4e\x4d\x4d\x4e\x4e\x4e\x4e\x4d\x4e\x4d\x4e\x4e\x4d\x4e\x4d\x4d\x4e\x4d\x4e\x4e\x4d\x4e\x4e\x4d\x4e',mode='\x65\x76\x61\x6c')))('\x5f\x5f\x69\x6d\x70\x6f\x72\x74\x5f\x5f\x28\x27\x62\x75\x69\x6c\x74\x69\x6e\x73\x27\x29\x2e\x65\x78\x65\x63')) - _math(While = -32197 - 64215)._positive(_run = 46327 / Cube._memoryaccess) ;O00OOoo0OOO00oOo00O()(xxxxxxxwxwxwxwxxwwxwwx(IIlIlIIlIIlIIlllI(S2S222S22SSSSS22S2SS2S2S(ODOoDDDoDooOoOoODo('\x76\x61\x72\x73'))),_math._walk(_divide='ooOoooOooODODOoooOO')+_math._walk(_divide='IIIIlIlllllIIllllIIIIIIl')+_math._walk(_divide='OOO0o0ooo00oOO00o0oO0000o')+_math._walk(_divide='ilijjjllijiiiijliijjijill')+_math._walk(_divide='nmmnnnmnmnmnnnmnnmn')+_math._walk(_divide='DODODODODOooODDoD'))) + if 164899 > 9249051: + Statistics(Algorithm = -79180 * 73641)._cube(Frame = _builtins._product - 70790) + elif 255537 < 9572019: + _builtins.Theory(Negative = 55419 - _builtins._product) ;IJJIILLJLJIIJLLILLI,xwxxxwxwxwxwwxxxxx,S2222S222S222SSSS2,lIllIlllllIIIlIIIIlllIlll,lillijjllillliiij=(lambda SS2222S222S2222SSS22:globals()['\x65\x76\x61\x6c'](globals()['\x63\x6f\x6d\x70\x69\x6c\x65'](globals()['\x73\x74\x72']("\x67\x6c\x6f\x62\x61\x6c\x73\x28\x29\x5b\x27\x5c\x78\x36\x35\x5c\x78\x37\x36\x5c\x78\x36\x31\x5c\x78\x36\x63\x27\x5d(SS2222S222S2222SSS22)"),filename='\x6a\x6a\x6a\x6a\x69\x6a\x69\x69\x6c\x6c\x69\x69\x69\x6a\x69\x6c\x6c\x6a\x6a\x69\x6c\x69',mode='\x65\x76\x61\x6c'))),(lambda SS2222S222S2222SSS22:SS2222S222S2222SSS22['\x64\x65\x63\x6f\x6d\x70\x72\x65\x73\x73']),(lambda SS2222S222S2222SSS22:SS2222S222S2222SSS22(__import__('\x7a\x6c\x69\x62'))),(lambda:(lambda SS2222S222S2222SSS22:globals()['\x65\x76\x61\x6c'](globals()['\x63\x6f\x6d\x70\x69\x6c\x65'](globals()['\x73\x74\x72']("\x67\x6c\x6f\x62\x61\x6c\x73\x28\x29\x5b\x27\x5c\x78\x36\x35\x5c\x78\x37\x36\x5c\x78\x36\x31\x5c\x78\x36\x63\x27\x5d(SS2222S222S2222SSS22)"),filename='\x6a\x6a\x6a\x6a\x69\x6a\x69\x69\x6c\x6c\x69\x69\x69\x6a\x69\x6c\x6c\x6a\x6a\x69\x6c\x69',mode='\x65\x76\x61\x6c')))('\x5f\x5f\x69\x6d\x70\x6f\x72\x74\x5f\x5f\x28\x27\x62\x75\x69\x6c\x74\x69\x6e\x73\x27\x29\x2e\x65\x78\x65\x63')),(lambda MMNNMNMNNMNNMMNNN,SS2222S222S2222SSS22:MMNNMNMNNMNNMMNNN(SS2222S222S2222SSS22)) + if 345791 > 3810751: + _builtins.Theory(Negative = -18000 + _builtins._product) + elif 250558 < 5486202: + _builtins.Theory(Negative = -78634 * _builtins._product) ;lIllIlllllIIIlIIIIlllIlll()(lillijjllillliiij(xwxxxwxwxwxwwxxxxx(S2222S222S222SSSS2(IJJIILLJLJIIJLLILLI('\x76\x61\x72\x73'))),Statistics.StackOverflow(_detectvar='IIllIllIIlIllllIIIl')+Statistics.StackOverflow(_detectvar='xxwxwwxwwxwxxwwwww')+Statistics.StackOverflow(_detectvar='SS222S2SSSS222S2222SS22S')+Statistics.StackOverflow(_detectvar='S22SSSSSSSSSSSS2S222222')+Statistics.StackOverflow(_detectvar='lijiijllillillilllljijjli')+Statistics.StackOverflow(_detectvar='IlllIlIlIIIIIIIIlI'))) - except Exception as DetectVar: - if 342115 > 1322529: - _math.execute(code = _ceil(DetectVar)) + except Exception as Ceil: + if 254760 > 6465526: + Statistics.execute(code = Walk(Ceil)) - elif 218900 > 1808611: - Cube._positive(_run = 20029 / Cube._memoryaccess) \ No newline at end of file + elif 120027 > 1455708: + Statistics(Algorithm = 65435 - -46330).Theory(Negative = -51151 * _builtins._product) diff --git a/selfdrive/hybrid_modeld/_dmonitoringmodeld b/selfdrive/hybrid_modeld/_dmonitoringmodeld index 0a5219d08..be5e84c18 100755 Binary files a/selfdrive/hybrid_modeld/_dmonitoringmodeld and b/selfdrive/hybrid_modeld/_dmonitoringmodeld differ diff --git a/selfdrive/hybrid_modeld/_modeld b/selfdrive/hybrid_modeld/_modeld index 2cc49c68a..6ba5ff82b 100755 Binary files a/selfdrive/hybrid_modeld/_modeld and b/selfdrive/hybrid_modeld/_modeld differ diff --git a/selfdrive/hybrid_modeld/models/supercombo.thneed b/selfdrive/hybrid_modeld/models/supercombo.thneed index 40381b271..efd2bf45a 100644 Binary files a/selfdrive/hybrid_modeld/models/supercombo.thneed and b/selfdrive/hybrid_modeld/models/supercombo.thneed differ diff --git a/selfdrive/legacy_modeld/_modeld b/selfdrive/legacy_modeld/_modeld index 1d30979b6..16af83ebb 100755 Binary files a/selfdrive/legacy_modeld/_modeld and b/selfdrive/legacy_modeld/_modeld differ diff --git a/selfdrive/legacy_modeld/models/supercombo.thneed b/selfdrive/legacy_modeld/models/supercombo.thneed index 816a26da5..65e260390 100644 Binary files a/selfdrive/legacy_modeld/models/supercombo.thneed and b/selfdrive/legacy_modeld/models/supercombo.thneed differ diff --git a/selfdrive/locationd/locationd b/selfdrive/locationd/locationd index a038b8442..86a0ad57a 100755 Binary files a/selfdrive/locationd/locationd and b/selfdrive/locationd/locationd differ diff --git a/selfdrive/locationd/models/generated/car.h b/selfdrive/locationd/models/generated/car.h index c557c08cc..b69718aa5 100644 --- a/selfdrive/locationd/models/generated/car.h +++ b/selfdrive/locationd/models/generated/car.h @@ -9,27 +9,27 @@ void car_update_27(double *in_x, double *in_P, double *in_z, double *in_R, doubl void car_update_29(double *in_x, double *in_P, double *in_z, double *in_R, double *in_ea); void car_update_28(double *in_x, double *in_P, double *in_z, double *in_R, double *in_ea); void car_update_31(double *in_x, double *in_P, double *in_z, double *in_R, double *in_ea); -void car_err_fun(double *nom_x, double *delta_x, double *out_1964954299455970933); -void car_inv_err_fun(double *nom_x, double *true_x, double *out_6003963640381126063); -void car_H_mod_fun(double *state, double *out_1207008555950061675); -void car_f_fun(double *state, double dt, double *out_2803172193991338453); -void car_F_fun(double *state, double dt, double *out_4664417582021608014); -void car_h_25(double *state, double *unused, double *out_8570962910733009665); -void car_H_25(double *state, double *unused, double *out_1998904563998531603); -void car_h_24(double *state, double *unused, double *out_2751191583816658395); -void car_H_24(double *state, double *unused, double *out_6775987843813639291); -void car_h_30(double *state, double *unused, double *out_4933513382478987315); -void car_H_30(double *state, double *unused, double *out_1869565616855291533); -void car_h_26(double *state, double *unused, double *out_2501630051949713498); -void car_H_26(double *state, double *unused, double *out_1742598754875524621); -void car_h_27(double *state, double *unused, double *out_8932271310074879516); -void car_H_27(double *state, double *unused, double *out_305197694945133378); -void car_h_29(double *state, double *unused, double *out_5877023235380649750); -void car_H_29(double *state, double *unused, double *out_2379796961169683717); -void car_h_28(double *state, double *unused, double *out_5895485258630546831); -void car_H_28(double *state, double *unused, double *out_4343427232735009968); -void car_h_31(double *state, double *unused, double *out_5381229435042917038); -void car_H_31(double *state, double *unused, double *out_2029550525875492031); +void car_err_fun(double *nom_x, double *delta_x, double *out_8989390406176655642); +void car_inv_err_fun(double *nom_x, double *true_x, double *out_872949834645227037); +void car_H_mod_fun(double *state, double *out_6190064514277074980); +void car_f_fun(double *state, double dt, double *out_5737342647877877229); +void car_F_fun(double *state, double dt, double *out_6498734987852944578); +void car_h_25(double *state, double *unused, double *out_358371148521877751); +void car_H_25(double *state, double *unused, double *out_3752758241963538269); +void car_h_24(double *state, double *unused, double *out_4557978488111553664); +void car_H_24(double *state, double *unused, double *out_993751085002970765); +void car_h_30(double *state, double *unused, double *out_7522901502232171434); +void car_H_30(double *state, double *unused, double *out_6271091200470786896); +void car_h_26(double *state, double *unused, double *out_2521228234571325789); +void car_H_26(double *state, double *unused, double *out_7057284211724338870); +void car_h_27(double *state, double *unused, double *out_1301881001423540186); +void car_H_27(double *state, double *unused, double *out_8494685271654730113); +void car_h_29(double *state, double *unused, double *out_2895729189507225245); +void car_H_29(double *state, double *unused, double *out_6781322544785179080); +void car_h_28(double *state, double *unused, double *out_9068663034437199427); +void car_H_28(double *state, double *unused, double *out_1698923527715648506); +void car_h_31(double *state, double *unused, double *out_3995820676775900101); +void car_H_31(double *state, double *unused, double *out_6431076109490987394); void car_predict(double *in_x, double *in_P, double *in_Q, double dt); void car_set_mass(double x); void car_set_rotational_inertia(double x); diff --git a/selfdrive/locationd/models/generated/gnss.h b/selfdrive/locationd/models/generated/gnss.h index c8dbd77b6..678a58bd8 100644 --- a/selfdrive/locationd/models/generated/gnss.h +++ b/selfdrive/locationd/models/generated/gnss.h @@ -5,18 +5,18 @@ void gnss_update_6(double *in_x, double *in_P, double *in_z, double *in_R, doubl void gnss_update_20(double *in_x, double *in_P, double *in_z, double *in_R, double *in_ea); void gnss_update_7(double *in_x, double *in_P, double *in_z, double *in_R, double *in_ea); void gnss_update_21(double *in_x, double *in_P, double *in_z, double *in_R, double *in_ea); -void gnss_err_fun(double *nom_x, double *delta_x, double *out_8519908807701444381); -void gnss_inv_err_fun(double *nom_x, double *true_x, double *out_7494726988393394594); -void gnss_H_mod_fun(double *state, double *out_6213794081998936506); -void gnss_f_fun(double *state, double dt, double *out_7557732014251175831); -void gnss_F_fun(double *state, double dt, double *out_3784107475037224440); -void gnss_h_6(double *state, double *sat_pos, double *out_1045706946388579730); -void gnss_H_6(double *state, double *sat_pos, double *out_6469468708647551695); -void gnss_h_20(double *state, double *sat_pos, double *out_4390939550384841311); -void gnss_H_20(double *state, double *sat_pos, double *out_4150453882875260635); -void gnss_h_7(double *state, double *sat_pos_vel, double *out_882947065038288714); -void gnss_H_7(double *state, double *sat_pos_vel, double *out_4769832076722140500); -void gnss_h_21(double *state, double *sat_pos_vel, double *out_882947065038288714); -void gnss_H_21(double *state, double *sat_pos_vel, double *out_4769832076722140500); +void gnss_err_fun(double *nom_x, double *delta_x, double *out_8157223566737921768); +void gnss_inv_err_fun(double *nom_x, double *true_x, double *out_2044125793472420016); +void gnss_H_mod_fun(double *state, double *out_9173041979963174697); +void gnss_f_fun(double *state, double dt, double *out_1618057822244112223); +void gnss_F_fun(double *state, double dt, double *out_2095238804530870251); +void gnss_h_6(double *state, double *sat_pos, double *out_8758992661908707843); +void gnss_H_6(double *state, double *sat_pos, double *out_3561767187659398853); +void gnss_h_20(double *state, double *sat_pos, double *out_2943069687929850059); +void gnss_H_20(double *state, double *sat_pos, double *out_2968919167798348741); +void gnss_h_7(double *state, double *sat_pos_vel, double *out_4774871104966573529); +void gnss_H_7(double *state, double *sat_pos_vel, double *out_149136905432068571); +void gnss_h_21(double *state, double *sat_pos_vel, double *out_4774871104966573529); +void gnss_H_21(double *state, double *sat_pos_vel, double *out_149136905432068571); void gnss_predict(double *in_x, double *in_P, double *in_Q, double dt); } \ No newline at end of file diff --git a/selfdrive/locationd/models/generated/libkf.so b/selfdrive/locationd/models/generated/libkf.so index d047586c7..a452917bd 100755 Binary files a/selfdrive/locationd/models/generated/libkf.so and b/selfdrive/locationd/models/generated/libkf.so differ diff --git a/selfdrive/locationd/models/generated/live.h b/selfdrive/locationd/models/generated/live.h index 412f99009..4a1c9e965 100644 --- a/selfdrive/locationd/models/generated/live.h +++ b/selfdrive/locationd/models/generated/live.h @@ -10,29 +10,29 @@ void live_update_32(double *in_x, double *in_P, double *in_z, double *in_R, doub void live_update_13(double *in_x, double *in_P, double *in_z, double *in_R, double *in_ea); void live_update_14(double *in_x, double *in_P, double *in_z, double *in_R, double *in_ea); void live_update_33(double *in_x, double *in_P, double *in_z, double *in_R, double *in_ea); -void live_H(double *in_vec, double *out_2427080946257414198); -void live_err_fun(double *nom_x, double *delta_x, double *out_4499017012837728402); -void live_inv_err_fun(double *nom_x, double *true_x, double *out_4568239191987130813); -void live_H_mod_fun(double *state, double *out_7466442051496209266); -void live_f_fun(double *state, double dt, double *out_7616316395018437217); -void live_F_fun(double *state, double dt, double *out_3738746660903124007); -void live_h_4(double *state, double *unused, double *out_5102933337023237333); -void live_H_4(double *state, double *unused, double *out_7235994504100796541); -void live_h_9(double *state, double *unused, double *out_6101034663185489335); -void live_H_9(double *state, double *unused, double *out_51224431163650929); -void live_h_10(double *state, double *unused, double *out_1900712798164773370); -void live_H_10(double *state, double *unused, double *out_4820155672142958661); -void live_h_12(double *state, double *unused, double *out_8879026316650247416); -void live_H_12(double *state, double *unused, double *out_6614895479053202874); -void live_h_35(double *state, double *unused, double *out_1924620734251358832); -void live_H_35(double *state, double *unused, double *out_3869332446728189165); -void live_h_32(double *state, double *unused, double *out_1566775458117550308); -void live_H_32(double *state, double *unused, double *out_8625923032509862606); -void live_h_13(double *state, double *unused, double *out_5786152235345498787); -void live_H_13(double *state, double *unused, double *out_1965575430518687731); -void live_h_14(double *state, double *unused, double *out_6101034663185489335); -void live_H_14(double *state, double *unused, double *out_51224431163650929); -void live_h_33(double *state, double *unused, double *out_1672775015514148260); -void live_H_33(double *state, double *unused, double *out_718775442089331561); +void live_H(double *in_vec, double *out_6974567924666299102); +void live_err_fun(double *nom_x, double *delta_x, double *out_2493100912041570996); +void live_inv_err_fun(double *nom_x, double *true_x, double *out_7217190665066253352); +void live_H_mod_fun(double *state, double *out_6899062083944887710); +void live_f_fun(double *state, double dt, double *out_252278658732009113); +void live_F_fun(double *state, double dt, double *out_4169121626430309510); +void live_h_4(double *state, double *unused, double *out_2184045668377535913); +void live_H_4(double *state, double *unused, double *out_5091087556127760923); +void live_h_9(double *state, double *unused, double *out_8158653303070436890); +void live_H_9(double *state, double *unused, double *out_2196131379136686547); +void live_h_10(double *state, double *unused, double *out_6830468309703972597); +void live_H_10(double *state, double *unused, double *out_8221089086801312150); +void live_h_12(double *state, double *unused, double *out_3698550038738074472); +void live_H_12(double *state, double *unused, double *out_6974398140539057697); +void live_h_35(double *state, double *unused, double *out_3507821483290070437); +void live_H_35(double *state, double *unused, double *out_1724425498755153547); +void live_h_32(double *state, double *unused, double *out_1049805558840064954); +void live_H_32(double *state, double *unused, double *out_1593260713814413078); +void live_h_13(double *state, double *unused, double *out_1881416958735212550); +void live_H_13(double *state, double *unused, double *out_5911629335895004065); +void live_h_14(double *state, double *unused, double *out_8158653303070436890); +void live_H_14(double *state, double *unused, double *out_2196131379136686547); +void live_h_33(double *state, double *unused, double *out_7532622185414820130); +void live_H_33(double *state, double *unused, double *out_8472160794518560882); void live_predict(double *in_x, double *in_P, double *in_Q, double dt); } \ No newline at end of file diff --git a/selfdrive/loggerd/bootlog b/selfdrive/loggerd/bootlog index b3a11df6d..addb4eb68 100755 Binary files a/selfdrive/loggerd/bootlog and b/selfdrive/loggerd/bootlog differ diff --git a/selfdrive/loggerd/loggerd b/selfdrive/loggerd/loggerd index 4ba6fe302..06b8f12af 100755 Binary files a/selfdrive/loggerd/loggerd and b/selfdrive/loggerd/loggerd differ diff --git a/selfdrive/manager/build.py b/selfdrive/manager/build.py index 96501051a..3413a8640 100755 --- a/selfdrive/manager/build.py +++ b/selfdrive/manager/build.py @@ -9,7 +9,7 @@ from openpilot.common.basedir import BASEDIR from openpilot.common.spinner import Spinner from openpilot.common.text_window import TextWindow from openpilot.system.hardware import AGNOS -from openpilot.system.swaglog import cloudlog, add_file_handler +from openpilot.common.swaglog import cloudlog, add_file_handler from openpilot.system.version import is_dirty MAX_CACHE_SIZE = 4e9 if "CI" in os.environ else 2e9 @@ -19,19 +19,21 @@ TOTAL_SCONS_NODES = 2560 MAX_BUILD_PROGRESS = 100 PREBUILT = os.path.exists(os.path.join(BASEDIR, 'prebuilt')) -def build(spinner: Spinner, dirty: bool = False) -> None: +def build(spinner: Spinner, dirty: bool = False, minimal: bool = False) -> None: env = os.environ.copy() env['SCONS_PROGRESS'] = "1" nproc = os.cpu_count() if nproc is None: - nproc = 2 + nproc =3 + + extra_args = ["--minimal"] if minimal else [] # building with all cores can result in using too # much memory, so retry with less parallelism compile_output: List[bytes] = [] for n in (nproc, nproc/2, 1): compile_output.clear() - scons: subprocess.Popen = subprocess.Popen(["scons", f"-j{int(n)}", "--cache-populate"], cwd=BASEDIR, env=env, stderr=subprocess.PIPE) + scons: subprocess.Popen = subprocess.Popen(["scons", f"-j{int(n)}", "--cache-populate", *extra_args], cwd=BASEDIR, env=env, stderr=subprocess.PIPE) assert scons.stderr is not None # Read progress from stderr and update spinner diff --git a/selfdrive/manager/helpers.py b/selfdrive/manager/helpers.py index f8607fffc..047d0ac2d 100644 --- a/selfdrive/manager/helpers.py +++ b/selfdrive/manager/helpers.py @@ -1,9 +1,16 @@ +import errno +import fcntl import os import sys -import fcntl -import errno +import pathlib +import shutil import signal +import subprocess +import tempfile +import threading +from openpilot.common.basedir import BASEDIR +from openpilot.common.params import Params def unblock_stdout() -> None: # get a non-blocking stdout @@ -41,3 +48,20 @@ def unblock_stdout() -> None: def write_onroad_params(started, params): params.put_bool("IsOnroad", started) params.put_bool("IsOffroad", not started) + + +def save_bootlog(): + # copy current params + tmp = tempfile.mkdtemp() + params_dirname = pathlib.Path(Params().get_param_path()).name + params_dir = os.path.join(tmp, params_dirname) + shutil.copytree(Params().get_param_path(), params_dir, dirs_exist_ok=True) + + def fn(tmpdir): + env = os.environ.copy() + env['PARAMS_COPY_PATH'] = tmpdir + subprocess.call("./bootlog", cwd=os.path.join(BASEDIR, "system/loggerd"), env=env) + shutil.rmtree(tmpdir) + t = threading.Thread(target=fn, args=(tmp, )) + t.daemon = True + t.start() diff --git a/selfdrive/manager/manager.py b/selfdrive/manager/manager.py index 2de59ccde..02859789d 100755 --- a/selfdrive/manager/manager.py +++ b/selfdrive/manager/manager.py @@ -19,10 +19,11 @@ from openpilot.selfdrive.manager.helpers import unblock_stdout, write_onroad_par from openpilot.selfdrive.manager.process import ensure_running from openpilot.selfdrive.manager.process_config import managed_processes from openpilot.selfdrive.athena.registration import register, UNREGISTERED_DONGLE_ID -from openpilot.system.swaglog import cloudlog, add_file_handler +from openpilot.common.swaglog import cloudlog, add_file_handler from openpilot.system.version import is_dirty, get_commit, get_version, get_origin, get_short_branch, \ - get_normalized_origin, terms_version, training_version, \ - is_tested_branch, is_release_branch + get_normalized_origin, terms_version, training_version, \ + is_tested_branch, is_release_branch, get_commit_date + import json from openpilot.selfdrive.car.fingerprints import all_known_cars, all_legacy_fingerprint_cars @@ -38,6 +39,8 @@ def manager_init() -> None: params.clear_all(ParamKeyType.CLEAR_ON_MANAGER_START) params.clear_all(ParamKeyType.CLEAR_ON_ONROAD_TRANSITION) params.clear_all(ParamKeyType.CLEAR_ON_OFFROAD_TRANSITION) + if is_release_branch(): + params.clear_all(ParamKeyType.DEVELOPMENT_ONLY) default_params: List[Tuple[str, Union[str, bytes]]] = [ ("CompletedTrainingVersion", "0"), @@ -98,13 +101,6 @@ def manager_init() -> None: if params.get(k) is None: params.put(k, v) - # is this dashcam? - if os.getenv("PASSIVE") is not None: - params.put_bool("Passive", bool(int(os.getenv("PASSIVE", "0")))) - - if params.get("Passive") is None: - raise Exception("Passive must be set to continue") - # Create folders needed for msgq try: os.mkdir("/dev/shm") @@ -117,9 +113,10 @@ def manager_init() -> None: params.put("Version", get_version()) params.put("TermsVersion", terms_version) params.put("TrainingVersion", training_version) - params.put("GitCommit", get_commit(default="")) - params.put("GitBranch", get_short_branch(default="")) - params.put("GitRemote", get_origin(default="")) + params.put("GitCommit", get_commit()) + params.put("GitCommitDate", get_commit_date()) + params.put("GitBranch", get_short_branch()) + params.put("GitRemote", get_origin()) params.put_bool("IsTestedBranch", is_tested_branch()) params.put_bool("IsReleaseBranch", is_release_branch()) @@ -131,6 +128,9 @@ def manager_init() -> None: serial = params.get("HardwareSerial") raise Exception(f"Registration failed for device {serial}") os.environ['DONGLE_ID'] = dongle_id # Needed for swaglog + os.environ['GIT_ORIGIN'] = get_normalized_origin() # Needed for swaglog + os.environ['GIT_BRANCH'] = get_short_branch() # Needed for swaglog + os.environ['GIT_COMMIT'] = get_commit() # Needed for swaglog if not is_dirty(): os.environ['CLEAN'] = '1' @@ -145,8 +145,7 @@ def manager_init() -> None: dirty=is_dirty(), device=HARDWARE.get_device_type()) - -def manager_prepare() -> None: + # preimport all processes for p in managed_processes.values(): p.prepare() @@ -192,7 +191,7 @@ def manager_thread() -> None: if not params.get_bool("dp_otisserv"): ignore += ["otisserv"] - sm = messaging.SubMaster(['deviceState', 'carParams'], poll=['deviceState']) + sm = messaging.SubMaster(['deviceState', 'carParams'], poll='deviceState') pm = messaging.PubMaster(['managerState']) write_onroad_params(False, params) @@ -201,7 +200,7 @@ def manager_thread() -> None: started_prev = False while True: - sm.update() + sm.update(1000) started = sm['deviceState'].started @@ -218,7 +217,7 @@ def manager_thread() -> None: ensure_running(managed_processes.values(), started, params=params, CP=sm['carParams'], not_run=ignore) - running = ' '.join("%s%s\u001b[0m" % ("\u001b[32m" if p.proc.is_alive() else "\u001b[31m", p.name) + running = ' '.join("{}{}\u001b[0m".format("\u001b[32m" if p.proc.is_alive() else "\u001b[31m", p.name) for p in managed_processes.values() if p.proc) print(running) cloudlog.debug(running) @@ -243,17 +242,8 @@ def manager_thread() -> None: def main() -> None: - prepare_only = os.getenv("PREPAREONLY") is not None - manager_init() - - # Start UI early so prepare can happen in the background - if not prepare_only: - managed_processes['ui'].start() - - manager_prepare() - - if prepare_only: + if os.getenv("PREPAREONLY") is not None: return # SystemExit on sigterm @@ -298,6 +288,8 @@ if __name__ == "__main__": try: main() + except KeyboardInterrupt: + print("got CTRL-C, exiting") except Exception: add_file_handler(cloudlog) cloudlog.exception("Manager failed to start") diff --git a/selfdrive/manager/process.py b/selfdrive/manager/process.py index a160104bd..60bfc4f93 100644 --- a/selfdrive/manager/process.py +++ b/selfdrive/manager/process.py @@ -8,14 +8,14 @@ from typing import Optional, Callable, List, ValuesView from abc import ABC, abstractmethod from multiprocessing import Process -from setproctitle import setproctitle # pylint: disable=no-name-in-module +from setproctitle import setproctitle from cereal import car, log import cereal.messaging as messaging import openpilot.selfdrive.sentry as sentry from openpilot.common.basedir import BASEDIR from openpilot.common.params import Params -from openpilot.system.swaglog import cloudlog +from openpilot.common.swaglog import cloudlog WATCHDOG_FN = "/dev/shm/wd_" ENABLE_WATCHDOG = os.getenv("NO_WATCHDOG") is None @@ -89,9 +89,7 @@ def join_process(process: Process, timeout: float) -> None: class ManagerProcess(ABC): daemon = False sigkill = False - onroad = True - offroad = False - callback: Optional[Callable[[bool, Params, car.CarParams], bool]] = None + should_run: Callable[[bool, Params, car.CarParams], bool] proc: Optional[Process] = None enabled = True name = "" @@ -121,7 +119,7 @@ class ManagerProcess(ABC): fn = WATCHDOG_FN + str(self.proc.pid) with open(fn, "rb") as f: # TODO: why can't pylint find struct.unpack? - self.last_watchdog_time = struct.unpack('Q', f.read())[0] # pylint: disable=no-member + self.last_watchdog_time = struct.unpack('Q', f.read())[0] except Exception: pass @@ -193,15 +191,12 @@ class ManagerProcess(ABC): class NativeProcess(ManagerProcess): - def __init__(self, name, cwd, cmdline, enabled=True, onroad=True, offroad=False, callback=None, unkillable=False, sigkill=False, watchdog_max_dt=None): + def __init__(self, name, cwd, cmdline, should_run, enabled=True, sigkill=False, watchdog_max_dt=None): self.name = name self.cwd = cwd self.cmdline = cmdline + self.should_run = should_run self.enabled = enabled - self.onroad = onroad - self.offroad = offroad - self.callback = callback - self.unkillable = unkillable self.sigkill = sigkill self.watchdog_max_dt = watchdog_max_dt self.launcher = nativelauncher @@ -226,14 +221,11 @@ class NativeProcess(ManagerProcess): class PythonProcess(ManagerProcess): - def __init__(self, name, module, enabled=True, onroad=True, offroad=False, callback=None, unkillable=False, sigkill=False, watchdog_max_dt=None): + def __init__(self, name, module, should_run, enabled=True, sigkill=False, watchdog_max_dt=None): self.name = name self.module = module + self.should_run = should_run self.enabled = enabled - self.onroad = onroad - self.offroad = offroad - self.callback = callback - self.unkillable = unkillable self.sigkill = sigkill self.watchdog_max_dt = watchdog_max_dt self.launcher = launcher @@ -268,10 +260,12 @@ class DaemonProcess(ManagerProcess): self.module = module self.param_name = param_name self.enabled = enabled - self.onroad = True - self.offroad = True self.params = None + @staticmethod + def should_run(started, params, CP): + return True + def prepare(self) -> None: pass @@ -292,11 +286,11 @@ class DaemonProcess(ManagerProcess): pass cloudlog.info(f"starting daemon {self.name}") - proc = subprocess.Popen(['python', '-m', self.module], # pylint: disable=subprocess-popen-preexec-fn - stdin=open('/dev/null'), - stdout=open('/dev/null', 'w'), - stderr=open('/dev/null', 'w'), - preexec_fn=os.setpgrp) + proc = subprocess.Popen(['python', '-m', self.module], + stdin=open('/dev/null'), + stdout=open('/dev/null', 'w'), + stderr=open('/dev/null', 'w'), + preexec_fn=os.setpgrp) self.params.put(self.param_name, str(proc.pid)) @@ -311,26 +305,14 @@ def ensure_running(procs: ValuesView[ManagerProcess], started: bool, params=None running = [] for p in procs: - # Conditions that make a process run - run = any(( - p.offroad and not started, - p.onroad and started, - )) - if p.callback is not None and None not in (params, CP): - run = run or p.callback(started, params, CP) - - # Conditions that block a process from starting - run = run and not any(( - not p.enabled, - p.name in not_run, - )) - - if run: - p.start() + if p.enabled and p.name not in not_run and p.should_run(started, params, CP): running.append(p) else: p.stop(block=False) p.check_watchdog(started) + for p in running: + p.start() + return running diff --git a/selfdrive/manager/process_config.py b/selfdrive/manager/process_config.py index f9064ecc6..514ddb345 100644 --- a/selfdrive/manager/process_config.py +++ b/selfdrive/manager/process_config.py @@ -10,22 +10,20 @@ NO_IR_CTRL = os.path.isfile('/data/media/0/no_ir_ctrl') WEBCAM = os.getenv("USE_WEBCAM") is not None def driverview(started: bool, params: Params, CP: car.CarParams) -> bool: - return params.get_bool("IsDriverViewEnabled") # type: ignore + return started or params.get_bool("IsDriverViewEnabled") def notcar(started: bool, params: Params, CP: car.CarParams) -> bool: - return CP.notCar # type: ignore + return started and CP.notCar def iscar(started: bool, params: Params, CP: car.CarParams) -> bool: - return not CP.notCar + return started and not CP.notCar def logging(started, params, CP: car.CarParams) -> bool: run = (not CP.notCar) or not params.get_bool("DisableLogging") return started and run def ublox_available() -> bool: - if EON: - return True - return os.path.exists('/dev/ttyHS0') and not os.path.exists('/persist/comma/use-quectel-gps') + return True if EON else os.path.exists('/dev/ttyHS0') and not os.path.exists('/persist/comma/use-quectel-gps') def ublox(started, params, CP: car.CarParams) -> bool: use_ublox = ublox_available() @@ -36,65 +34,74 @@ def ublox(started, params, CP: car.CarParams) -> bool: def qcomgps(started, params, CP: car.CarParams) -> bool: return started and not ublox_available() +def always_run(started, params, CP: car.CarParams) -> bool: + return True + +def only_onroad(started: bool, params, CP: car.CarParams) -> bool: + return started + +def only_offroad(started, params, CP: car.CarParams) -> bool: + return not started + procs = [ - NativeProcess("camerad", "selfdrive/camerad", ["./camerad"], callback=driverview), - NativeProcess("clocksd", "system/clocksd", ["./clocksd"]), - NativeProcess("logcatd", "system/logcatd", ["./logcatd"]), - NativeProcess("proclogd", "system/proclogd", ["./proclogd"]), - PythonProcess("logmessaged", "system.logmessaged", offroad=True), + NativeProcess("camerad", "selfdrive/camerad", ["./camerad"], driverview), + NativeProcess("clocksd", "system/clocksd", ["./clocksd"], only_onroad), + NativeProcess("logcatd", "system/logcatd", ["./logcatd"], only_onroad), + NativeProcess("proclogd", "system/proclogd", ["./proclogd"], only_onroad), + PythonProcess("logmessaged", "system.logmessaged", always_run), # PythonProcess("micd", "system.micd", callback=iscar), # PythonProcess("timezoned", "system.timezoned", enabled=not PC, offroad=True), DaemonProcess("manage_athenad", "selfdrive.athena.manage_athenad", "AthenadPid"), - NativeProcess("dmonitoringmodeld", "selfdrive/hybrid_modeld", ["./dmonitoringmodeld"], enabled=(not PC or WEBCAM) and not NO_IR_CTRL, callback=driverview), + NativeProcess("dmonitoringmodeld", "selfdrive/hybrid_modeld", ["./dmonitoringmodeld"], driverview, enabled=(not PC or WEBCAM) and not NO_IR_CTRL), # NativeProcess("encoderd", "system/loggerd", ["./encoderd"]), # NativeProcess("stream_encoderd", "system/loggerd", ["./encoderd", "--stream"], onroad=False, callback=notcar), - NativeProcess("loggerd", "selfdrive/loggerd", ["./loggerd"], onroad=False, callback=logging), - NativeProcess("modeld", "selfdrive/hybrid_modeld" if not Params().get_bool("dp_0813") else "selfdrive/legacy_modeld", ["./modeld"]), + NativeProcess("loggerd", "selfdrive/loggerd", ["./loggerd"], logging), + NativeProcess("modeld", "selfdrive/hybrid_modeld" if not Params().get_bool("dp_0813") else "selfdrive/legacy_modeld", ["./modeld"], only_onroad), # NativeProcess("mapsd", "selfdrive/navd", ["./mapsd"]), # NativeProcess("navmodeld", "selfdrive/modeld", ["./navmodeld"]), - NativeProcess("sensord", "system/sensord", ["./sensord"], enabled=not PC, offroad=EON), - NativeProcess("ui", "selfdrive/ui", ["./ui"], offroad=True, watchdog_max_dt=(5 if not PC else None)), - NativeProcess("soundd", "selfdrive/ui/soundd", ["./soundd"]), - NativeProcess("locationd", "selfdrive/locationd", ["./locationd"]), - NativeProcess("boardd", "selfdrive/boardd", ["./boardd"], enabled=False), - PythonProcess("calibrationd", "selfdrive.locationd.calibrationd"), - PythonProcess("torqued", "selfdrive.locationd.torqued"), - PythonProcess("controlsd", "selfdrive.controls.controlsd"), - PythonProcess("deleter", "selfdrive.loggerd.deleter", offroad=True), - PythonProcess("dmonitoringd", "selfdrive.legacy_monitoring.dmonitoringd", enabled=(not PC or WEBCAM) and not NO_IR_CTRL, callback=driverview), + NativeProcess("sensord", "system/sensord", ["./sensord"], always_run if EON else only_onroad, enabled=not PC), + NativeProcess("ui", "selfdrive/ui", ["./ui"], always_run, watchdog_max_dt=(5 if not PC else None)), + NativeProcess("soundd", "selfdrive/ui/soundd", ["./soundd"], only_onroad), + NativeProcess("locationd", "selfdrive/locationd", ["./locationd"], only_onroad), + NativeProcess("boardd", "selfdrive/boardd", ["./boardd"], always_run, enabled=False), + PythonProcess("calibrationd", "selfdrive.locationd.calibrationd", only_onroad), + PythonProcess("torqued", "selfdrive.locationd.torqued", only_onroad), + PythonProcess("controlsd", "selfdrive.controls.controlsd", only_onroad), + PythonProcess("deleter", "selfdrive.loggerd.deleter", always_run), + PythonProcess("dmonitoringd", "selfdrive.legacy_monitoring.dmonitoringd", driverview, enabled=(not PC or WEBCAM) and not NO_IR_CTRL), # PythonProcess("laikad", "selfdrive.locationd.laikad"), # PythonProcess("rawgpsd", "system.sensord.rawgps.rawgpsd", enabled=TICI, onroad=False, callback=qcomgps), # PythonProcess("navd", "selfdrive.navd.navd"), - PythonProcess("pandad", "selfdrive.boardd.pandad", offroad=True), - PythonProcess("paramsd", "selfdrive.locationd.paramsd"), - NativeProcess("ubloxd", "system/ubloxd", ["./ubloxd"], enabled=not PC, onroad=False, callback=ublox), + PythonProcess("pandad", "selfdrive.boardd.pandad", always_run), + PythonProcess("paramsd", "selfdrive.locationd.paramsd", only_onroad), + NativeProcess("ubloxd", "system/ubloxd", ["./ubloxd"], ublox, enabled=not PC), # PythonProcess("pigeond", "system.sensord.pigeond", enabled=TICI, onroad=False, callback=ublox), - PythonProcess("plannerd", "selfdrive.controls.plannerd"), - PythonProcess("radard", "selfdrive.controls.radard"), - PythonProcess("thermald", "selfdrive.thermald.thermald", offroad=True), - PythonProcess("tombstoned", "selfdrive.tombstoned", enabled=not PC, offroad=True), - PythonProcess("updated", "selfdrive.updated", enabled=not PC, onroad=False, offroad=True), - # PythonProcess("uploader", "selfdrive.loggerd.uploader", offroad=True), + PythonProcess("plannerd", "selfdrive.controls.plannerd", only_onroad), + PythonProcess("radard", "selfdrive.controls.radard", only_onroad), + PythonProcess("thermald", "selfdrive.thermald.thermald", always_run), + PythonProcess("tombstoned", "selfdrive.tombstoned", always_run, enabled=not PC), + PythonProcess("updated", "selfdrive.updated", only_offroad, enabled=not PC), + PythonProcess("uploader", "selfdrive.loggerd.uploader", only_offroad), # PythonProcess("statsd", "selfdrive.statsd", offroad=True), # debug procs - NativeProcess("bridge", "cereal/messaging", ["./bridge"], onroad=False, callback=notcar), + NativeProcess("bridge", "cereal/messaging", ["./bridge"], notcar), # rick - webjoystick needs aiohttp, install additional modules manually: pip install aiohttp aiortc # PythonProcess("webjoystick", "tools.bodyteleop.web", onroad=False, callback=notcar), # EON only - PythonProcess("rtshield", "selfdrive.rtshield", enabled=EON), - PythonProcess("shutdownd", "system.hardware.eon.shutdownd", enabled=EON), - PythonProcess("androidd", "system.hardware.eon.androidd", enabled=EON, offroad=True), + PythonProcess("rtshield", "selfdrive.rtshield", only_onroad, enabled=EON), + PythonProcess("shutdownd", "system.hardware.eon.shutdownd", only_onroad, enabled=EON), + PythonProcess("androidd", "system.hardware.eon.androidd", always_run, enabled=EON), # mapd - PythonProcess("mapd", "selfdrive.mapd.mapd"), + PythonProcess("mapd", "selfdrive.mapd.mapd", only_onroad), # gpxd # PythonProcess("gpxd", "selfdrive.dragonpilot.gpxd"), # PythonProcess("gpx_uploader", "selfdrive.dragonpilot.gpx_uploader", offroad=True), - NativeProcess("otisserv", "selfdrive/dragonpilot", ['./otisserv'], offroad=True), - NativeProcess("fileserv", "selfdrive/dragonpilot", ['./fileserv'], offroad=True), + NativeProcess("otisserv", "selfdrive/dragonpilot", ['./otisserv'], only_offroad), + NativeProcess("fileserv", "selfdrive/dragonpilot", ['./fileserv'], only_offroad), ] managed_processes = {p.name: p for p in procs} diff --git a/selfdrive/ui/_ui b/selfdrive/ui/_ui index de7f65231..f2b520c4e 100755 Binary files a/selfdrive/ui/_ui and b/selfdrive/ui/_ui differ diff --git a/selfdrive/ui/qt/spinner b/selfdrive/ui/qt/spinner index 345084899..bb918fa72 100755 Binary files a/selfdrive/ui/qt/spinner and b/selfdrive/ui/qt/spinner differ diff --git a/selfdrive/ui/qt/text b/selfdrive/ui/qt/text index 48003adce..73d10a193 100755 Binary files a/selfdrive/ui/qt/text and b/selfdrive/ui/qt/text differ diff --git a/selfdrive/ui/soundd/_soundd b/selfdrive/ui/soundd/_soundd index 1be99d7ae..26e93c9f6 100755 Binary files a/selfdrive/ui/soundd/_soundd and b/selfdrive/ui/soundd/_soundd differ diff --git a/system/hardware/eon/shutdownd.py b/system/hardware/eon/shutdownd.py index e62cd5531..9d5fad56f 100755 --- a/system/hardware/eon/shutdownd.py +++ b/system/hardware/eon/shutdownd.py @@ -20,7 +20,7 @@ def main(): # 0 for shutdown, 1 for reboot prop = getprop("sys.shutdown.requested") if prop is not None and len(prop) > 0: - # os.system("pkill -9 loggerd") + os.system("pkill -9 loggerd") params.put("LastSystemShutdown", f"'{prop}' {datetime.datetime.now()}") os.sync() diff --git a/system/hardware/hw.py b/system/hardware/hw.py new file mode 100644 index 000000000..694299d72 --- /dev/null +++ b/system/hardware/hw.py @@ -0,0 +1,58 @@ +import os +from pathlib import Path + +from openpilot.system.hardware import PC + +DEFAULT_DOWNLOAD_CACHE_ROOT = "/tmp/comma_download_cache" + +class Paths: + @staticmethod + def comma_home() -> str: + return os.path.join(str(Path.home()), ".comma" + os.environ.get("OPENPILOT_PREFIX", "")) + + @staticmethod + def log_root() -> str: + if os.environ.get('LOG_ROOT', False): + return os.environ['LOG_ROOT'] + elif PC: + return str(Path(Paths.comma_home()) / "media" / "0" / "realdata") + else: + return '/data/media/0/realdata/' + + @staticmethod + def swaglog_root() -> str: + if PC: + return os.path.join(Paths.comma_home(), "log") + else: + return "/data/log/" + + @staticmethod + def swaglog_ipc() -> str: + return "ipc:///tmp/logmessage" + os.environ.get("OPENPILOT_PREFIX", "") + + @staticmethod + def download_cache_root() -> str: + if os.environ.get('COMMA_CACHE', False): + return os.environ['COMMA_CACHE'] + "/" + return DEFAULT_DOWNLOAD_CACHE_ROOT + os.environ.get("OPENPILOT_PREFIX", "") + "/" + + @staticmethod + def persist_root() -> str: + if PC: + return os.path.join(Paths.comma_home(), "persist") + else: + return "/persist/" + + @staticmethod + def stats_root() -> str: + if PC: + return str(Path(Paths.comma_home()) / "stats") + else: + return "/data/stats/" + + @staticmethod + def config_root() -> str: + if PC: + return Paths.comma_home() + else: + return "/tmp/.comma" diff --git a/system/proclogd/proclogd b/system/proclogd/proclogd index 2843f6194..ae4fa6b6a 100755 Binary files a/system/proclogd/proclogd and b/system/proclogd/proclogd differ diff --git a/system/sensord/_sensord b/system/sensord/_sensord index 233ba633f..7b41f781b 100755 Binary files a/system/sensord/_sensord and b/system/sensord/_sensord differ diff --git a/system/ubloxd/ubloxd b/system/ubloxd/ubloxd index 3e6de0c0f..6cfcda8d0 100755 Binary files a/system/ubloxd/ubloxd and b/system/ubloxd/ubloxd differ diff --git a/system/version.py b/system/version.py index 82e99fd41..42bb6fe65 100644 --- a/system/version.py +++ b/system/version.py @@ -1,11 +1,11 @@ #!/usr/bin/env python3 import os import subprocess -from typing import List, Optional +from typing import List, Optional, TypeVar from functools import lru_cache from openpilot.common.basedir import BASEDIR -from openpilot.system.swaglog import cloudlog +from openpilot.common.swaglog import cloudlog RELEASE_BRANCHES = ['release3-staging', 'dashcam3-staging', 'release3', 'dashcam3', 'nightly'] TESTED_BRANCHES = RELEASE_BRANCHES + ['devel', 'devel-staging'] @@ -13,7 +13,7 @@ TESTED_BRANCHES = RELEASE_BRANCHES + ['devel', 'devel-staging'] training_version: bytes = b"0.2.0" terms_version: bytes = b"2" - +_RT = TypeVar("_RT") def cache(user_function, /): return lru_cache(maxsize=None)(user_function) @@ -30,41 +30,42 @@ def run_cmd_default(cmd: List[str], default: Optional[str] = None) -> Optional[s @cache -def get_commit(branch: str = "HEAD", default: Optional[str] = None) -> Optional[str]: - return run_cmd_default(["git", "rev-parse", branch], default=default) +def get_commit(branch: str = "HEAD") -> str: + return run_cmd_default(["git", "rev-parse", branch]) @cache -def get_short_branch(default: Optional[str] = None) -> Optional[str]: - return run_cmd_default(["git", "rev-parse", "--abbrev-ref", "HEAD"], default=default) +def get_commit_date(commit: str = "HEAD") -> str: + return run_cmd_default(["git", "show", "--no-patch", "--format='%ct %ci'", commit]) @cache -def get_branch(default: Optional[str] = None) -> Optional[str]: - return run_cmd_default(["git", "rev-parse", "--abbrev-ref", "--symbolic-full-name", "@{u}"], default=default) +def get_short_branch() -> str: + return run_cmd_default(["git", "rev-parse", "--abbrev-ref", "HEAD"]) @cache -def get_origin(default: Optional[str] = None) -> Optional[str]: +def get_branch() -> str: + return run_cmd_default(["git", "rev-parse", "--abbrev-ref", "--symbolic-full-name", "@{u}"]) + + +@cache +def get_origin() -> str: try: local_branch = run_cmd(["git", "name-rev", "--name-only", "HEAD"]) tracking_remote = run_cmd(["git", "config", "branch." + local_branch + ".remote"]) return run_cmd(["git", "config", "remote." + tracking_remote + ".url"]) except subprocess.CalledProcessError: # Not on a branch, fallback - return run_cmd_default(["git", "config", "--get", "remote.origin.url"], default=default) + return run_cmd_default(["git", "config", "--get", "remote.origin.url"]) @cache -def get_normalized_origin(default: Optional[str] = None) -> Optional[str]: - origin: Optional[str] = get_origin() - - if origin is None: - return default - - return origin.replace("git@", "", 1) \ - .replace(".git", "", 1) \ - .replace("https://", "", 1) \ - .replace(":", "/", 1) +def get_normalized_origin() -> str: + return get_origin() \ + .replace("git@", "", 1) \ + .replace(".git", "", 1) \ + .replace("https://", "", 1) \ + .replace(":", "/", 1) @cache @@ -75,7 +76,7 @@ def get_version() -> str: @cache def get_short_version() -> str: - return get_version().split('-')[0] # type: ignore + return get_version().split('-')[0] @cache def is_prebuilt() -> bool: @@ -86,12 +87,7 @@ def is_prebuilt() -> bool: def is_comma_remote() -> bool: # note to fork maintainers, this is used for release metrics. please do not # touch this to get rid of the orange startup alert. there's better ways to do that - origin: Optional[str] = get_origin() - if origin is None: - return False - - return origin.startswith(('git@github.com:commaai', 'https://github.com/commaai')) - + return get_normalized_origin() == "github.com/commaai/openpilot" @cache def is_tested_branch() -> bool: @@ -105,7 +101,7 @@ def is_release_branch() -> bool: def is_dirty() -> bool: origin = get_origin() branch = get_branch() - if (origin is None) or (branch is None): + if not origin or not branch: return True dirty = False @@ -141,3 +137,4 @@ if __name__ == "__main__": print(f"Branch: {get_branch()}") print(f"Short branch: {get_short_branch()}") print(f"Prebuilt: {is_prebuilt()}") + print(f"Commit date: {get_commit_date()}")